1 package com.github.davidmoten.aws.lw.client.xml;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6
7 import java.io.IOException;
8 import java.io.Reader;
9 import java.io.StringReader;
10 import java.io.UncheckedIOException;
11 import java.io.Writer;
12 import java.util.NoSuchElementException;
13
14 import org.junit.Assert;
15 import org.junit.Test;
16
17 public class XmlElementTest {
18
19 @Test(expected = XmlParseException.class)
20 public void testBlank() {
21 XmlElement.parse("");
22 }
23
24 @Test(expected = XmlParseException.class)
25 public void testNotClosed() {
26 XmlElement.parse("<a>hello");
27 }
28
29 @Test(expected = XmlParseException.class)
30 public void testNoStartTag() {
31 XmlElement.parse("a");
32 }
33
34 @Test
35 public void testNoContent() {
36 XmlElement x = XmlElement.parse("<a/>");
37 assertEquals("a", x.name());
38 assertFalse(x.hasChildren());
39 assertTrue(x.attributeNames().isEmpty());
40 assertEquals("", x.content());
41 }
42
43 @Test(expected = UncheckedIOException.class)
44 public void testReaderThrows() {
45 XmlElement.parseUnchecked(new Reader() {
46
47 @Override
48 public int read(char[] cbuf, int off, int len) throws IOException {
49 throw new IOException("boo");
50 }
51
52 @Override
53 public void close() throws IOException {
54
55 }
56 }, true);
57 }
58
59 @Test
60 public void testWithPreamble() {
61 XmlElement x = XmlElement.parse("<?xml>\n<a/>");
62 assertEquals("a", x.name());
63 }
64
65 @Test
66 public void testLineNumber() {
67 try {
68 XmlElement.parse("<?xml>\n\n\n<a>");
69 } catch (XmlParseException e) {
70 assertEquals(4, e.lineNumber());
71 }
72 }
73
74 @Test(expected = XmlParseException.class)
75 public void testWithPreamble7() {
76 XmlElement x = XmlElement.parse("<?xml<>\n<a/>");
77 assertEquals("a", x.name());
78 }
79
80 @Test
81 public void testWithPreamble2() {
82 XmlElement x = XmlElement.parse("<?[xml]>\n<a/>");
83 assertEquals("a", x.name());
84 }
85
86 @Test(expected = XmlParseException.class)
87 public void testOnlyPreamble() {
88 XmlElement.parse("<?xml> ");
89 }
90
91 @Test(expected = XmlParseException.class)
92 public void testOnlyPreamble2() {
93 XmlElement.parse("<?xml> adfda");
94 }
95
96 @Test
97 public void testWithPreamble3() {
98 XmlElement x = XmlElement.parse("<?-xml>\n<a/>");
99 assertEquals("a", x.name());
100 }
101
102 @Test
103 public void testWithPreamble4() {
104 XmlElement x = XmlElement.parse("<?--xml-->\n<a/>");
105 assertEquals("a", x.name());
106 }
107
108 @Test
109 public void testWithPreamble5() {
110 XmlElement x = XmlElement.parse("<?-[xml*]>\n<a/>");
111 assertEquals("a", x.name());
112 }
113
114 @Test
115 public void testWithPreamble6() {
116 XmlElement x = XmlElement.parse("<?-]xml>\n<a/>");
117 assertEquals("a", x.name());
118 }
119
120 @Test
121 public void testWithPreambleAndVersionDoubleQuote() {
122 XmlElement x = XmlElement.parse("<?XML version=\"1.0\"?><a/>");
123 assertEquals("a", x.name());
124 }
125
126 @Test
127 public void testWithPreambleAndVersionSingleQuote() {
128 XmlElement x = XmlElement.parse("<?XML version='1.0'?><a/>");
129 assertEquals("a", x.name());
130 }
131
132 @Test
133 public void testWithPreambleAndDocType() {
134 XmlElement x = XmlElement.parse("<?XML version=\"1.0\"?>\n"
135 + "<!DOCTYPE greeting SYSTEM \"hello.dtd\">\n" + "<a>Hello, world!</a>");
136 assertEquals("a", x.name());
137 }
138
139 @Test
140 public void testWithPreambleAndDocType2() {
141 XmlElement x = XmlElement
142 .parse("<?XML version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<!DOCTYPE greeting [\n"
143 + " <!ELEMENT greeting (#PCDATA)>\n" + "]>\n" + "<a>Hello, world!</a>");
144 assertEquals("a", x.name());
145 }
146
147 @Test(expected = XmlParseException.class)
148 public void testSyntaxError1() {
149 XmlElement.parse("<a x+\"123\"/>");
150 }
151
152 @Test(expected = XmlParseException.class)
153 public void testSyntaxError2() {
154 XmlElement.parse("<a/+>");
155 }
156
157 @Test(expected = XmlParseException.class)
158 public void testSyntaxError3() {
159 XmlElement.parse("<a><b>boo</b><-- hi there --></a>");
160 }
161
162 @Test(expected = XmlParseException.class)
163 public void testSyntaxError4() {
164 XmlElement.parse("<a><b>boo</b>+</a>");
165 }
166
167 @Test(expected = XmlParseException.class)
168 public void testSyntaxError5() {
169 XmlElement.parse("<a><b>boo<+b></a>");
170 }
171
172 @Test(expected = XmlParseException.class)
173 public void testSyntaxError6() {
174 XmlElement.parse("<a><b>boo</c></a>");
175 }
176
177 @Test(expected = XmlParseException.class)
178 public void testSyntaxError7() {
179 XmlElement.parse("<a><b>boo</b z></a>");
180 }
181
182 @Test(expected = XmlParseException.class)
183 public void testSyntaxErrorBadComment() {
184 XmlElement.parse("<- hi there -->");
185 }
186
187 @Test(expected = XmlParseException.class)
188 public void testSyntaxErrorBadComment2() {
189 XmlElement.parse("<a><+ hi there --></a>");
190 }
191
192 @Test(expected = XmlParseException.class)
193 public void testSyntaxErrorBadComment3() {
194 XmlElement.parse("<a><b>boo</b><! hi there --></a>");
195 }
196
197 @Test(expected = XmlParseException.class)
198 public void testSyntaxErrorBadComment4() {
199 XmlElement.parse("<a><b>boo</b><!- hi there --></a>");
200 }
201
202 @Test(expected = XmlParseException.class)
203 public void testSyntaxErrorBadComment5() {
204 XmlElement.parse("<a><b>boo</b><!- hi there --> +</a>");
205 }
206
207 @Test(expected = XmlParseException.class)
208 public void testSyntaxErrorBadComment6() {
209 XmlElement.parse("<a><b>boo</b><!-- hi there ---Z +</a>");
210 }
211
212 @Test(expected = XmlParseException.class)
213 public void testSyntaxBadEntity() {
214 XmlElement.parse("<a>&#x^;</a>");
215 }
216
217 @Test(expected = XmlParseException.class)
218 public void testSyntaxBadEntity2() {
219 XmlElement.parse("<a>&#^;</a>");
220 }
221
222 @Test(expected = XmlParseException.class)
223 public void testUnsupportedEntity() {
224 XmlElement.parse("<a>£</a>");
225 }
226
227 @Test
228 public void testSyntaxGoodEntity() {
229 XmlElement x = XmlElement.parse("<a>d</a>");
230 assertEquals("d", x.content());
231 }
232
233 @Test
234 public void testSyntaxGoodEntityFollowedByComment() {
235 XmlElement x = XmlElement.parse("<a>d<!-- boo --></a>");
236 assertEquals("d", x.content());
237 }
238
239 @Test
240 public void testUnchecked() {
241 XmlElement x = XmlElement.parse("<a/>");
242 try {
243 x.writeUnchecked(new Writer() {
244
245 @Override
246 public void write(char[] cbuf, int off, int len) throws IOException {
247 throw new IOException("boo");
248
249 }
250
251 @Override
252 public void flush() throws IOException {
253
254
255 }
256
257 @Override
258 public void close() throws IOException {
259
260
261 }
262 });
263 Assert.fail();
264 } catch (UncheckedIOException e) {
265 assertEquals("boo", e.getCause().getMessage());
266 } catch (Throwable t) {
267 Assert.fail();
268 }
269 }
270
271 @Test
272 public void testUnchecked2() {
273 XmlElement x = XmlElement.parse("<a/>");
274 try {
275 x.writeUnchecked(new Writer() {
276
277 @Override
278 public void write(char[] cbuf, int off, int len) throws IOException {
279 throw new IOException("boo");
280
281 }
282
283 @Override
284 public void flush() throws IOException {
285
286
287 }
288
289 @Override
290 public void close() throws IOException {
291 throw new IOException("boo2");
292
293 }
294 });
295 Assert.fail();
296 } catch (UncheckedIOException e) {
297 assertEquals("boo2", e.getCause().getMessage());
298 } catch (Throwable t) {
299 Assert.fail();
300 }
301 }
302
303 @Test
304 public void testWriter() {
305 XmlElement x = XmlElement.parse("<a/>");
306 assertEquals("<a/>", x.toString());
307 }
308
309 @Test
310 public void testComment2() {
311 XmlElement x = XmlElement.parse("<a><b>boo</b><!-- hi there --></a>");
312 assertEquals(1, x.countChildren());
313 }
314
315 @Test
316 public void testEmptyContent() {
317 XmlElement x = XmlElement.parse("<a></a>");
318 assertEquals("a", x.name());
319 assertFalse(x.hasChildren());
320 assertTrue(x.attributeNames().isEmpty());
321 assertEquals("", x.content());
322 }
323
324 @Test
325 public void testEmptyContent2() {
326 XmlElement x = XmlElement.parse("<a><b></b></a>", false);
327 assertEquals("a", x.name());
328 assertTrue(x.hasChildren());
329 }
330
331 @Test
332 public void testParseReader() throws XmlParseException, IOException {
333 try (StringReader reader = new StringReader("<a> hi </a>")) {
334 XmlElement x = XmlElement.parse(reader);
335 assertEquals("hi", x.content());
336 }
337 }
338
339 @Test
340 public void testHasContentAndWhiteSpaceTrimmed() {
341 XmlElement x = XmlElement.parse("<a>\t\n hi there -> 1 \n\t</a>");
342 assertEquals("a", x.name());
343 assertFalse(x.hasChildren());
344 assertTrue(x.attributeNames().isEmpty());
345 assertEquals("hi there -> 1", x.content());
346 }
347
348 @Test
349 public void testHasChild() {
350 XmlElement x = XmlElement.parse("<a><b/></a>");
351 assertEquals("a", x.name());
352 assertTrue(x.hasChildren());
353 assertTrue(x.attributeNames().isEmpty());
354 assertEquals("b", x.firstChild().name());
355 assertEquals("", x.firstChild().content());
356 }
357
358 @Test
359 public void testChildrenWithName() {
360 XmlElement x = XmlElement.parse("<a><b/><b/><c/></a>");
361 assertEquals("a", x.name());
362 assertEquals(2, x.childrenWithName("b").size());
363 }
364
365 @Test
366 public void testHasTwoChildren() {
367 String xml = "<a><b>boo</b><c step=\"large\">bingo</c><d>&><"'İzz</d></a>";
368 XmlElement x = XmlElement.parse(xml);
369 assertEquals("a", x.name());
370 assertTrue(x.hasChildren());
371 assertEquals(3, x.countChildren());
372 assertEquals(3, x.children().size());
373 assertEquals("bingo", x.content("c"));
374 assertTrue(x.attributeNames().isEmpty());
375 assertEquals("b", x.firstChild().name());
376 assertEquals("boo", x.firstChild().content());
377 assertEquals("c", x.child("c").name());
378 assertEquals("bingo", x.child(1).content());
379 assertEquals("large", x.child("c").attribute("step"));
380 assertEquals(
381 "<a><b>boo</b><c step=\"large\">bingo</c><d>&><"'İzz</d></a>",
382 x.toString());
383 assertEquals(0, x.lineNumber());
384 }
385
386 @Test(expected = NoSuchElementException.class)
387 public void testNoChild() {
388 XmlElement x = XmlElement.parse("<a/>");
389 x.child("b");
390 }
391
392 @Test
393 public void testComment() {
394 XmlElement x = XmlElement.parse("<a><!-- hi there -->boo</a>");
395 assertEquals("boo", x.content());
396 }
397
398 @Test
399 public void testComment3() {
400 XmlElement x = XmlElement.parse("<a><![hi there]>boo</a>");
401 assertEquals("boo", x.content());
402 }
403
404 @Test(expected = XmlParseException.class)
405 public void testComment4() {
406 XmlElement.parse("<a><!<hey/><b></a>");
407 }
408
409 @Test(expected = XmlParseException.class)
410 public void testBadAttribute() {
411 XmlElement.parse("<a x={}/>");
412 }
413
414 @Test
415 public void testAttributeSingleQuote() {
416 XmlElement x = XmlElement.parse("<a x='hi'/>");
417 assertEquals("hi", x.attribute("x"));
418 }
419
420 @Test
421 public void testAttributeDoubleQuote() {
422 XmlElement x = XmlElement.parse("<a x=\"hi\"/>");
423 assertEquals("hi", x.attribute("x"));
424 }
425
426 @Test
427 public void testAttributeEntity() {
428 XmlElement x = XmlElement.parse("<a x='&'/>");
429 assertEquals("&", x.attribute("x"));
430 }
431
432 @Test
433 public void testCData() {
434 XmlElement x = XmlElement
435 .parse("<a><![CDATA[\n" + "Within this Character Data block I can\n"
436 + "use double dashes as much as I want (along with <, &, ', and \")\n"
437 + "*and* %MyParamEntity; will be expanded to the text\n"
438 + "\"Has been expanded\" ... however, I can't use\n"
439 + "the CEND sequence. If I need to use CEND I must escape one of the\n"
440 + "brackets or the greater-than sign using concatenated CDATA sections.\n"
441 + "]]></a>");
442 String s = x.content();
443 assertTrue(s.contains("as I want (along with <, &, '"));
444 }
445
446 @Test(expected = XmlParseException.class)
447 public void testCDataTooManyBracketLevels() {
448 XmlElement.parse("<a><![CDATA[[hi there]]]></a>");
449 }
450
451 @Test(expected = XmlParseException.class)
452 public void testCDataNotEnoughClosingBrackets() {
453 XmlElement.parse("<a><![CDATA[[hi there]></a>");
454 }
455
456 @Test(expected = XmlParseException.class)
457 public void testCDataNotEnoughClosingBrackets2() {
458 XmlElement.parse("<a><![CDATA[[hi there]aa></a>");
459 }
460
461 @Test
462 public void testPreserveWhitespace() {
463 XmlElement x = XmlElement.parse("<a> hi </a>", false);
464 assertEquals(" hi ", x.content());
465 }
466
467 @Test
468 public void testSkipWhitespace() {
469 XmlElement x = XmlElement.parse("<a> \r\t\nhi</a>");
470 assertEquals("hi", x.content());
471 }
472
473 @Test
474 public void testIsValidIdentifierChar() {
475 assertTrue(XmlElement.isValidIdentifierCharacter('A'));
476 assertTrue(XmlElement.isValidIdentifierCharacter('B'));
477 assertTrue(XmlElement.isValidIdentifierCharacter('Y'));
478 assertTrue(XmlElement.isValidIdentifierCharacter('Z'));
479 assertTrue(XmlElement.isValidIdentifierCharacter('a'));
480 assertTrue(XmlElement.isValidIdentifierCharacter('b'));
481 assertTrue(XmlElement.isValidIdentifierCharacter('y'));
482 assertTrue(XmlElement.isValidIdentifierCharacter('z'));
483 assertTrue(XmlElement.isValidIdentifierCharacter('0'));
484 assertTrue(XmlElement.isValidIdentifierCharacter('9'));
485 assertFalse(XmlElement.isValidIdentifierCharacter('@'));
486 assertTrue(XmlElement.isValidIdentifierCharacter('_'));
487 assertTrue(XmlElement.isValidIdentifierCharacter('-'));
488 assertTrue(XmlElement.isValidIdentifierCharacter(':'));
489 assertTrue(XmlElement.isValidIdentifierCharacter('.'));
490 assertFalse(XmlElement.isValidIdentifierCharacter('\u007E'));
491 assertTrue(XmlElement.isValidIdentifierCharacter('\u007F'));
492 }
493 }