// Copyright Josh Komoroske. All rights reserved.
// Use of this source code is governed by the MIT license,
// a copy of which can be found in the LICENSE.txt file.
package junit
import (
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestReparent(t *testing.T) {
tests := []struct {
title string
input []byte
expected string
}{
{
title: "nil input",
expected: "",
},
{
title: "empty input",
input: []byte(""),
expected: "",
},
{
title: "xml input",
input: []byte(``),
expected: ``,
},
}
for index, test := range tests {
name := fmt.Sprintf("#%d - %s", index+1, test.title)
t.Run(name, func(t *testing.T) {
reader := reparentXML(bytes.NewReader(test.input))
actual, err := ioutil.ReadAll(reader)
assert.NoError(t, err)
assert.Equal(t, test.expected, string(actual))
})
}
}
func TestParse(t *testing.T) {
tests := []struct {
title string
input []byte
expected []xmlNode
}{
{
title: "nil input",
},
{
title: "empty input",
input: []byte(``),
},
{
title: "plaintext input",
input: []byte(`This is some data that does not look like xml.`),
},
{
title: "json input",
input: []byte(`{"This is some data": "that looks like json"}`),
},
{
title: "single xml node",
input: []byte(``),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
},
},
},
{
title: "multiple xml nodes",
input: []byte(`
`),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
},
{
XMLName: xml.Name{
Local: "this-is-also-a-tag",
},
},
},
},
{
title: "single xml node with content",
input: []byte(`This is some content.`),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
Content: []byte("This is some content."),
},
},
},
{
title: "single xml node with encoded content",
input: []byte(`<sender>John Smith</sender>`),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
Content: []byte("John Smith"),
},
},
},
{
title: "single xml node with cdata content",
input: []byte(`John Smith]]>`),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
Content: []byte("John Smith"),
},
},
},
{
title: "single xml node with attributes",
input: []byte(``),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
Attrs: map[string]string{
"name": "my name",
"status": "passed",
},
},
},
},
{
title: "single xml node with encoded attributes",
input: []byte(``),
expected: []xmlNode{
{
XMLName: xml.Name{
Local: "this-is-a-tag",
},
Attrs: map[string]string{
"name": "John Smith",
},
},
},
},
}
for index, test := range tests {
name := fmt.Sprintf("#%d - %s", index+1, test.title)
t.Run(name, func(t *testing.T) {
actual, err := parse(bytes.NewReader(test.input))
require.Nil(t, err)
assert.Equal(t, test.expected, actual)
})
}
}
func TestExtract(t *testing.T) {
tests := []struct {
title string
input []byte
expected []byte
err string
}{
{
title: "nil content",
},
{
title: "empty content",
input: []byte(""),
},
{
title: "simple content",
input: []byte("hello world"),
expected: []byte("hello world"),
},
{
title: "complex content",
input: []byte("No bugs 🐜"),
expected: []byte("No bugs 🐜"),
},
{
title: "simple encoded content",
input: []byte("I </3 XML"),
expected: []byte("I 3 XML"),
},
{
title: "complex encoded content",
input: []byte(`<[['/\"]]>`),
expected: []byte(`<[['/\"]]>`),
},
{
title: "empty cdata content",
input: []byte(""),
},
{
title: "simple cdata content",
input: []byte(""),
expected: []byte("hello world"),
},
{
title: "complex cdata content",
input: []byte(""),
expected: []byte("I 3 XML"),
},
{
title: "complex encoded cdata content",
input: []byte(""),
expected: []byte("I </3 XML"),
},
{
title: "encoded content then cdata content",
input: []byte("I want to say that "),
expected: []byte("I want to say that I 3 XML"),
},
{
title: "cdata content then encoded content",
input: []byte(" a lot"),
expected: []byte("I 3 XML a lot"),
},
{
title: "mixture of encoded and cdata content",
input: []byte("I </3 XML . 🐜 You probably too."),
expected: []byte("I 3 XML a lot. 🐜 You probably 3 XML too."),
},
{
title: "unmatched cdata start tag",
input: []byte(""),
err: "unmatched CDATA end tag",
},
}
for index, test := range tests {
name := fmt.Sprintf("#%d - %s", index+1, test.title)
t.Run(name, func(t *testing.T) {
actual, err := extractContent(test.input)
checkError(t, test.err, err)
assert.Equal(t, test.expected, actual)
})
}
}
func checkError(t *testing.T, expected string, actual error) {
t.Helper()
switch {
case expected == "" && actual == nil:
return
case expected == "" && actual != nil:
t.Fatalf("expected no error but got %q", actual.Error())
case expected != "" && actual == nil:
t.Fatalf("expected %q but got nil", expected)
case expected == actual.Error():
return
default:
t.Fatalf("expected %q but got %q", expected, actual.Error())
}
}