Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to enable ingesting a reader directly. #34

Merged
merged 1 commit into from
Oct 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions ingesters.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
package junit

import (
"io/ioutil"
"bytes"
"io"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -55,23 +56,24 @@ func IngestFiles(filenames []string) ([]Suite, error) {
// IngestFile will parse the given XML file and return a slice of all contained
// JUnit test suite definitions.
func IngestFile(filename string) ([]Suite, error) {
data, err := ioutil.ReadFile(filename)
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()

return Ingest(data)
return IngestReader(file)
}

// Ingest will parse the given XML data and return a slice of all contained
// JUnit test suite definitions.
func Ingest(data []byte) ([]Suite, error) {
// IngestReader will parse the given XML reader and return a slice of all
// contained JUnit test suite definitions.
func IngestReader(reader io.Reader) ([]Suite, error) {
var (
suiteChan = make(chan Suite)
suites = make([]Suite, 0)
)

nodes, err := parse(data)
nodes, err := parse(reader)
if err != nil {
return nil, err
}
Expand All @@ -87,3 +89,9 @@ func Ingest(data []byte) ([]Suite, error) {

return suites, nil
}

// Ingest will parse the given XML data and return a slice of all contained
// JUnit test suite definitions.
func Ingest(data []byte) ([]Suite, error) {
return IngestReader(bytes.NewReader(data))
}
18 changes: 11 additions & 7 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,24 @@ import (
"encoding/xml"
"errors"
"html"
"io"
)

// reparentXML will wrap the given data (which is assumed to be valid XML), in
// a fake root nodeAlias.
// reparentXML will wrap the given reader (which is assumed to be valid XML),
// in a fake root nodeAlias.
//
// This action is useful in the event that the original XML document does not
// have a single root nodeAlias, which is required by the XML specification.
// Additionally, Go's XML parser will silently drop all nodes after the first
// that is encountered, which can lead to data loss from a parser perspective.
// This function also enables the ingestion of blank XML files, which would
// normally cause a parsing error.
func reparentXML(data []byte) []byte {
return append(append([]byte("<fake-root>"), data...), "</fake-root>"...)
func reparentXML(reader io.Reader) io.Reader {
return io.MultiReader(
bytes.NewReader([]byte("<fake-root>")),
reader,
bytes.NewReader([]byte("</fake-root>")),
)
}

// extractContent parses the raw contents from an XML node, and returns it in a
Expand Down Expand Up @@ -96,10 +101,9 @@ func extractContent(data []byte) ([]byte, error) {

// parse unmarshalls the given XML data into a graph of nodes, and then returns
// a slice of all top-level nodes.
func parse(data []byte) ([]xmlNode, error) {
func parse(reader io.Reader) ([]xmlNode, error) {
var (
buf = bytes.NewBuffer(reparentXML(data))
dec = xml.NewDecoder(buf)
dec = xml.NewDecoder(reparentXML(reader))
root xmlNode
)

Expand Down
9 changes: 6 additions & 3 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
package junit

import (
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -39,7 +41,9 @@ func TestReparent(t *testing.T) {
name := fmt.Sprintf("#%d - %s", index+1, test.title)

t.Run(name, func(t *testing.T) {
actual := reparentXML(test.input)
reader := reparentXML(bytes.NewReader(test.input))
actual, err := ioutil.ReadAll(reader)
assert.NoError(t, err)

assert.Equal(t, test.expected, string(actual))
})
Expand Down Expand Up @@ -168,8 +172,7 @@ func TestParse(t *testing.T) {
name := fmt.Sprintf("#%d - %s", index+1, test.title)

t.Run(name, func(t *testing.T) {
actual, err := parse(test.input)

actual, err := parse(bytes.NewReader(test.input))
require.Nil(t, err)

assert.Equal(t, test.expected, actual)
Expand Down