1
2
3
4
5 package junit
6
7 import (
8 "bytes"
9 "encoding/xml"
10 "fmt"
11 "io/ioutil"
12 "testing"
13
14 "github.com/stretchr/testify/assert"
15 "github.com/stretchr/testify/require"
16 )
17
18 func TestReparent(t *testing.T) {
19 tests := []struct {
20 title string
21 input []byte
22 expected string
23 }{
24 {
25 title: "nil input",
26 expected: "<fake-root></fake-root>",
27 },
28 {
29 title: "empty input",
30 input: []byte(""),
31 expected: "<fake-root></fake-root>",
32 },
33 {
34 title: "xml input",
35 input: []byte(`<testcase name="unit tests" />`),
36 expected: `<fake-root><testcase name="unit tests" /></fake-root>`,
37 },
38 }
39
40 for index, test := range tests {
41 name := fmt.Sprintf("#%d - %s", index+1, test.title)
42
43 t.Run(name, func(t *testing.T) {
44 reader := reparentXML(bytes.NewReader(test.input))
45 actual, err := ioutil.ReadAll(reader)
46 assert.NoError(t, err)
47
48 assert.Equal(t, test.expected, string(actual))
49 })
50 }
51 }
52
53 func TestParse(t *testing.T) {
54 tests := []struct {
55 title string
56 input []byte
57 expected []xmlNode
58 }{
59 {
60 title: "nil input",
61 },
62 {
63 title: "empty input",
64 input: []byte(``),
65 },
66 {
67 title: "plaintext input",
68 input: []byte(`This is some data that does not look like xml.`),
69 },
70 {
71 title: "json input",
72 input: []byte(`{"This is some data": "that looks like json"}`),
73 },
74 {
75 title: "single xml node",
76 input: []byte(`<this-is-a-tag/>`),
77 expected: []xmlNode{
78 {
79 XMLName: xml.Name{
80 Local: "this-is-a-tag",
81 },
82 },
83 },
84 },
85 {
86 title: "multiple xml nodes",
87 input: []byte(`
88 <this-is-a-tag/>
89 <this-is-also-a-tag/>
90 `),
91 expected: []xmlNode{
92 {
93 XMLName: xml.Name{
94 Local: "this-is-a-tag",
95 },
96 },
97 {
98 XMLName: xml.Name{
99 Local: "this-is-also-a-tag",
100 },
101 },
102 },
103 },
104 {
105 title: "single xml node with content",
106 input: []byte(`<this-is-a-tag>This is some content.</this-is-a-tag>`),
107 expected: []xmlNode{
108 {
109 XMLName: xml.Name{
110 Local: "this-is-a-tag",
111 },
112 Content: []byte("This is some content."),
113 },
114 },
115 },
116 {
117 title: "single xml node with encoded content",
118 input: []byte(`<this-is-a-tag><sender>John Smith</sender></this-is-a-tag>`),
119 expected: []xmlNode{
120 {
121 XMLName: xml.Name{
122 Local: "this-is-a-tag",
123 },
124 Content: []byte("<sender>John Smith</sender>"),
125 },
126 },
127 },
128 {
129 title: "single xml node with cdata content",
130 input: []byte(`<this-is-a-tag><![CDATA[<sender>John Smith</sender>]]></this-is-a-tag>`),
131 expected: []xmlNode{
132 {
133 XMLName: xml.Name{
134 Local: "this-is-a-tag",
135 },
136 Content: []byte("<sender>John Smith</sender>"),
137 },
138 },
139 },
140 {
141 title: "single xml node with attributes",
142 input: []byte(`<this-is-a-tag name="my name" status="passed"></this-is-a-tag>`),
143 expected: []xmlNode{
144 {
145 XMLName: xml.Name{
146 Local: "this-is-a-tag",
147 },
148 Attrs: map[string]string{
149 "name": "my name",
150 "status": "passed",
151 },
152 },
153 },
154 },
155 {
156 title: "single xml node with encoded attributes",
157 input: []byte(`<this-is-a-tag name="<sender>John Smith</sender>"></this-is-a-tag>`),
158 expected: []xmlNode{
159 {
160 XMLName: xml.Name{
161 Local: "this-is-a-tag",
162 },
163 Attrs: map[string]string{
164 "name": "<sender>John Smith</sender>",
165 },
166 },
167 },
168 },
169 }
170
171 for index, test := range tests {
172 name := fmt.Sprintf("#%d - %s", index+1, test.title)
173
174 t.Run(name, func(t *testing.T) {
175 actual, err := parse(bytes.NewReader(test.input))
176 require.Nil(t, err)
177
178 assert.Equal(t, test.expected, actual)
179 })
180 }
181 }
182
183 func TestExtract(t *testing.T) {
184 tests := []struct {
185 title string
186 input []byte
187 expected []byte
188 err string
189 }{
190 {
191 title: "nil content",
192 },
193 {
194 title: "empty content",
195 input: []byte(""),
196 },
197 {
198 title: "simple content",
199 input: []byte("hello world"),
200 expected: []byte("hello world"),
201 },
202 {
203 title: "complex content",
204 input: []byte("No bugs 🐜"),
205 expected: []byte("No bugs 🐜"),
206 },
207 {
208 title: "simple encoded content",
209 input: []byte("I </3 XML"),
210 expected: []byte("I </3 XML"),
211 },
212 {
213 title: "complex encoded content",
214 input: []byte(`<[['/\"]]>`),
215 expected: []byte(`<[['/\"]]>`),
216 },
217 {
218 title: "empty cdata content",
219 input: []byte("<![CDATA[]]>"),
220 },
221 {
222 title: "simple cdata content",
223 input: []byte("<![CDATA[hello world]]>"),
224 expected: []byte("hello world"),
225 },
226 {
227 title: "complex cdata content",
228 input: []byte("<![CDATA[I </3 XML]]>"),
229 expected: []byte("I </3 XML"),
230 },
231 {
232 title: "complex encoded cdata content",
233 input: []byte("<![CDATA[I </3 XML]]>"),
234 expected: []byte("I </3 XML"),
235 },
236 {
237 title: "encoded content then cdata content",
238 input: []byte("I want to say that <![CDATA[I </3 XML]]>"),
239 expected: []byte("I want to say that I </3 XML"),
240 },
241 {
242 title: "cdata content then encoded content",
243 input: []byte("<![CDATA[I </3 XML]]> a lot"),
244 expected: []byte("I </3 XML a lot"),
245 },
246 {
247 title: "mixture of encoded and cdata content",
248 input: []byte("I </3 XML <![CDATA[a lot]]>. 🐜 You probably <![CDATA[</3 XML]]> too."),
249 expected: []byte("I </3 XML a lot. 🐜 You probably </3 XML too."),
250 },
251 {
252 title: "unmatched cdata start tag",
253 input: []byte("<![CDATA["),
254 err: "unmatched CDATA start tag",
255 },
256 {
257 title: "unmatched cdata end tag",
258 input: []byte("]]>"),
259 err: "unmatched CDATA end tag",
260 },
261 }
262
263 for index, test := range tests {
264 name := fmt.Sprintf("#%d - %s", index+1, test.title)
265
266 t.Run(name, func(t *testing.T) {
267 actual, err := extractContent(test.input)
268
269 checkError(t, test.err, err)
270 assert.Equal(t, test.expected, actual)
271 })
272 }
273 }
274
275 func checkError(t *testing.T, expected string, actual error) {
276 t.Helper()
277
278 switch {
279 case expected == "" && actual == nil:
280 return
281 case expected == "" && actual != nil:
282 t.Fatalf("expected no error but got %q", actual.Error())
283 case expected != "" && actual == nil:
284 t.Fatalf("expected %q but got nil", expected)
285 case expected == actual.Error():
286 return
287 default:
288 t.Fatalf("expected %q but got %q", expected, actual.Error())
289 }
290 }
291
View as plain text