1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 package org.jaxen.saxpath.base;
64
65 import javax.xml.parsers.DocumentBuilder;
66 import javax.xml.parsers.DocumentBuilderFactory;
67
68 import junit.framework.TestCase;
69
70 import org.jaxen.JaxenException;
71 import org.jaxen.XPath;
72 import org.jaxen.dom.DOMXPath;
73 import org.jaxen.saxpath.Axis;
74 import org.jaxen.saxpath.Operator;
75 import org.jaxen.saxpath.XPathSyntaxException;
76 import org.jaxen.saxpath.conformance.ConformanceXPathHandler;
77 import org.w3c.dom.Document;
78
79 public class XPathReaderTest extends TestCase
80 {
81 private ConformanceXPathHandler expected;
82 private ConformanceXPathHandler actual;
83
84 private XPathReader reader;
85 private String text;
86
87 private String[] paths = {
88 "/foo/bar[@a='1' and @b='2']",
89 "/foo/bar[@a='1' and @b!='2']",
90 "//attribute::*[.!='crunchy']",
91 "'//*[contains(string(text()),\"yada yada\")]'",
92 };
93
94 private String[][] bogusPaths = {
95 new String[]{"chyld::foo", "Expected valid axis name instead of [chyld]"},
96 new String[]{"foo/tacos()", "Expected node-type"},
97 new String[]{"foo/tacos()", "Expected node-type"},
98 new String[]{"*:foo", "Unexpected ':'"},
99 new String[]{"/foo/bar[baz", "Expected: ]"},
100 new String[]{"/cracker/cheese[(mold > 1) and (sense/taste", "Expected: )"},
101 new String[]{"//", "Location path cannot end with //"}
102 };
103
104 public XPathReaderTest( String name )
105 {
106 super( name );
107 }
108
109 public void setUp()
110 {
111 setReader( new XPathReader() );
112 setText( null );
113
114 this.actual = new ConformanceXPathHandler();
115 this.expected = new ConformanceXPathHandler();
116
117 getReader().setXPathHandler( actual() );
118 }
119
120 public void tearDown()
121 {
122 setReader( null );
123 setText( null );
124 }
125
126
127
128
129
130 public void testPaths()
131 {
132 XPathReader reader = new XPathReader();
133
134 System.out.println( "Valid Expressions" );
135
136 for( int i = 0; i < paths.length; ++i )
137 {
138 System.out.println( "----------------------------------------" );
139 System.out.println( paths[i] );
140 System.out.println( "----------------------------------------" );
141 try
142 {
143 reader.parse( paths[i] );
144 }
145 catch( org.jaxen.saxpath.SAXPathException e )
146 {
147 e.printStackTrace();
148 fail( e.getMessage() );
149 }
150 catch( Exception e )
151 {
152 fail( e.getMessage() );
153 }
154 }
155 }
156
157 public void testBogusPaths()
158 {
159 XPathReader reader = new XPathReader();
160
161 System.out.println( "Bogus Expressions" );
162
163 for( int i = 0; i < bogusPaths.length; ++i )
164 {
165 final String[] bogusPath = bogusPaths[i];
166 System.out.println( "----------------------------------------" );
167 System.out.println( bogusPath[0] );
168 System.out.println( "----------------------------------------" );
169
170 try
171 {
172 reader.parse( bogusPath[0] );
173
174 fail( "Should have thrown XPathSyntaxException for " + bogusPath[0]);
175 }
176 catch( XPathSyntaxException e )
177 {
178 assertEquals( bogusPath[1], e.getMessage() );
179 }
180 catch( org.jaxen.saxpath.SAXPathException e )
181 {
182 fail( e.getMessage() );
183 }
184 catch( Exception e )
185 {
186 fail( e.getMessage() );
187 }
188 }
189 }
190
191 public void testChildrenOfNumber()
192 {
193 XPathReader reader = new XPathReader();
194 try
195 {
196 reader.parse( "1/child::test" );
197 fail( "Should have thrown XPathSyntaxException for 1/child::test");
198 }
199 catch( XPathSyntaxException e )
200 {
201 assertEquals( "Node-set expected", e.getMessage() );
202 }
203 catch( org.jaxen.saxpath.SAXPathException e )
204 {
205 fail( e.getMessage() );
206 }
207 catch( Exception e )
208 {
209 fail( e.getMessage() );
210 }
211 }
212
213 public void testChildIsNumber()
214 {
215 XPathReader reader = new XPathReader();
216 try
217 {
218 reader.parse( "jane/3" );
219 fail( "Should have thrown XPathSyntaxException for jane/3");
220 }
221 catch( XPathSyntaxException e )
222 {
223 assertEquals( "Expected one of '.', '..', '@', '*', <QName>", e.getMessage() );
224 }
225 catch( org.jaxen.saxpath.SAXPathException e )
226 {
227 fail( e.getMessage() );
228 }
229 catch( Exception e )
230 {
231 fail( e.getMessage() );
232 }
233 }
234
235 public void testNumberOrNumber()
236 {
237
238 try
239 {
240 XPath xpath = new DOMXPath( "4 | 5" );
241
242 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
243 factory.setNamespaceAware(true);
244 DocumentBuilder builder = factory.newDocumentBuilder();
245
246 Document doc = builder.parse( "xml/basic.xml" );
247
248 xpath.selectNodes( doc );
249 fail( "Should have thrown XPathSyntaxException for 4 | 5");
250 }
251 catch( JaxenException e )
252 {
253 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
254 }
255 catch( Exception e )
256 {
257 fail( e.getMessage() );
258 }
259 }
260
261 public void testStringOrNumber()
262 {
263
264 try
265 {
266 XPath xpath = new DOMXPath( "\"test\" | 5" );
267
268 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
269 factory.setNamespaceAware(true);
270 DocumentBuilder builder = factory.newDocumentBuilder();
271
272 Document doc = builder.parse( "xml/basic.xml" );
273
274 xpath.selectNodes( doc );
275 fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
276 }
277 catch( JaxenException e )
278 {
279 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
280 }
281 catch( Exception e )
282 {
283 fail( e.getMessage() );
284 }
285 }
286
287 public void testStringOrString()
288 {
289
290 try
291 {
292 XPath xpath = new DOMXPath( "\"test\" | \"festival\"" );
293
294 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
295 factory.setNamespaceAware(true);
296 DocumentBuilder builder = factory.newDocumentBuilder();
297
298 Document doc = builder.parse( "xml/basic.xml" );
299
300 xpath.selectNodes( doc );
301 fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
302 }
303 catch( JaxenException e )
304 {
305 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
306 }
307 catch( Exception e )
308 {
309 fail( e.getMessage() );
310 }
311 }
312
313 public void testUnionofNodesAndNonNodes()
314 {
315
316 try
317 {
318 XPath xpath = new DOMXPath( "count(//*) | //* " );
319
320 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
321 factory.setNamespaceAware(true);
322 DocumentBuilder builder = factory.newDocumentBuilder();
323
324 Document doc = builder.parse( "xml/basic.xml" );
325
326 xpath.selectNodes( doc );
327 fail( "Should have thrown XPathSyntaxException for \"count(//*) | //* ");
328 }
329 catch( JaxenException e )
330 {
331 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
332 }
333 catch( Exception e )
334 {
335 fail( e.getMessage() );
336 }
337 }
338
339 public void testValidAxis()
340 {
341 XPathReader reader = new XPathReader();
342
343 try
344 {
345 reader.parse( "child::foo" );
346 }
347 catch( org.jaxen.saxpath.SAXPathException e )
348 {
349 fail( e.getMessage() );
350 }
351 }
352
353 public void testInvalidAxis()
354 {
355 XPathReader reader = new XPathReader();
356
357 try
358 {
359 reader.parse( "chyld::foo" );
360 fail( "Should have thrown XPathSyntaxException" );
361 }
362 catch( XPathSyntaxException e )
363 {
364
365 }
366 catch( org.jaxen.saxpath.SAXPathException e )
367 {
368 fail( e.getMessage() );
369 }
370
371 }
372
373 public void testSimpleNameStep()
374 {
375 try
376 {
377 setText( "foo" );
378
379 getReader().setUpParse( getText() );
380
381 getReader().step( );
382
383 expected().startNameStep( Axis.CHILD,
384 "",
385 "foo" );
386 expected().endNameStep();
387
388 compare();
389 }
390 catch( org.jaxen.saxpath.SAXPathException e )
391 {
392 fail( e.getMessage() );
393 }
394
395 }
396
397 public void testNameStepWithAxisAndPrefix()
398 {
399 try
400 {
401 setText( "parent::foo:bar" );
402
403 getReader().setUpParse( getText() );
404
405 getReader().step( );
406
407 expected().startNameStep( Axis.PARENT,
408 "foo",
409 "bar" );
410 expected().endNameStep();
411
412 compare();
413 }
414 catch( org.jaxen.saxpath.SAXPathException e )
415 {
416 fail( e.getMessage() );
417 }
418 }
419
420 public void testNodeStepWithAxis()
421 {
422 try
423 {
424 setText( "parent::node()" );
425
426 getReader().setUpParse( getText() );
427
428 getReader().step();
429
430 expected().startAllNodeStep( Axis.PARENT );
431
432 expected().endAllNodeStep();
433
434 compare();
435 }
436 catch( org.jaxen.saxpath.SAXPathException e )
437 {
438 fail( e.getMessage() );
439 }
440 }
441
442 public void testProcessingInstructionStepWithName()
443 {
444 try
445 {
446 setText( "parent::processing-instruction('cheese')" );
447
448 getReader().setUpParse( getText() );
449
450 getReader().step( );
451
452 expected().startProcessingInstructionNodeStep( Axis.PARENT,
453 "cheese" );
454
455 expected().endProcessingInstructionNodeStep();
456
457 compare();
458 }
459 catch( org.jaxen.saxpath.SAXPathException e )
460 {
461 fail( e.getMessage() );
462 }
463 }
464
465 public void testProcessingInstructionStepNoName()
466 {
467 try
468 {
469 setText( "parent::processing-instruction()" );
470
471 getReader().setUpParse( getText() );
472
473 getReader().step( );
474
475 expected().startProcessingInstructionNodeStep( Axis.PARENT,
476 "" );
477
478 expected().endProcessingInstructionNodeStep();
479
480 compare();
481 }
482 catch( org.jaxen.saxpath.SAXPathException e )
483 {
484 fail( e.getMessage() );
485 }
486 }
487
488 public void testAllNodeStep()
489 {
490 try
491 {
492 setText( "parent::node()" );
493
494 getReader().setUpParse( getText() );
495
496 getReader().step( );
497
498 expected().startAllNodeStep( Axis.PARENT );
499
500 expected().endAllNodeStep();
501
502 compare();
503 }
504 catch( org.jaxen.saxpath.SAXPathException e )
505 {
506 fail( e.getMessage() );
507 }
508 }
509
510 public void testTextNodeStep()
511 {
512 try
513 {
514 setText( "parent::text()" );
515
516 getReader().setUpParse( getText() );
517
518 getReader().step( );
519
520 expected().startTextNodeStep( Axis.PARENT );
521
522 expected().endTextNodeStep();
523
524 compare();
525 }
526 catch( org.jaxen.saxpath.SAXPathException e )
527 {
528 fail( e.getMessage() );
529 }
530 }
531
532 public void testCommentNodeStep()
533 {
534 try
535 {
536 setText( "parent::comment()" );
537
538 getReader().setUpParse( getText() );
539
540 getReader().step( );
541
542 expected().startCommentNodeStep( Axis.PARENT );
543
544 expected().endCommentNodeStep();
545
546 compare();
547 }
548 catch( org.jaxen.saxpath.SAXPathException e )
549 {
550 fail( e.getMessage() );
551 }
552 }
553
554 public void testRelativeLocationPath()
555 {
556 try
557 {
558 setText( "foo/bar/baz" );
559
560 getReader().setUpParse( getText() );
561
562 getReader().locationPath( false );
563
564 expected().startRelativeLocationPath();
565
566 expected().startNameStep( Axis.CHILD,
567 "",
568 "foo" );
569 expected().endNameStep();
570
571 expected().startNameStep( Axis.CHILD,
572 "",
573 "bar" );
574 expected().endNameStep();
575
576 expected().startNameStep( Axis.CHILD,
577 "",
578 "baz" );
579 expected().endNameStep();
580
581 expected().endRelativeLocationPath();
582
583 compare();
584 }
585 catch( org.jaxen.saxpath.SAXPathException e )
586 {
587 fail( e.getMessage() );
588 }
589 }
590
591 public void testAbsoluteLocationPath()
592 {
593 try
594 {
595 setText( "/foo/bar/baz" );
596
597 getReader().setUpParse( getText() );
598
599 getReader().locationPath( true );
600
601 expected().startAbsoluteLocationPath();
602
603 expected().startNameStep( Axis.CHILD,
604 "",
605 "foo" );
606 expected().endNameStep();
607
608 expected().startNameStep( Axis.CHILD,
609 "",
610 "bar" );
611 expected().endNameStep();
612
613 expected().startNameStep( Axis.CHILD,
614 "",
615 "baz" );
616 expected().endNameStep();
617
618 expected().endAbsoluteLocationPath();
619
620 compare();
621 }
622 catch( org.jaxen.saxpath.SAXPathException e )
623 {
624 fail( e.getMessage() );
625 }
626 }
627
628 public void testNumberPredicate()
629 {
630 try
631 {
632 setText( "[1]" );
633
634 getReader().setUpParse( getText() );
635
636 getReader().predicate();
637
638 expected().startPredicate();
639
640 expected().startOrExpr();
641 expected().startAndExpr();
642 expected().startEqualityExpr();
643 expected().startEqualityExpr();
644 expected().startRelationalExpr();
645 expected().startRelationalExpr();
646 expected().startAdditiveExpr();
647 expected().startAdditiveExpr();
648 expected().startMultiplicativeExpr();
649 expected().startMultiplicativeExpr();
650 expected().startUnaryExpr();
651 expected().startUnionExpr();
652 expected().startPathExpr();
653 expected().startFilterExpr();
654
655 expected().number( 1 );
656
657 expected().endFilterExpr();
658 expected().endPathExpr();
659 expected().endUnionExpr( false );
660 expected().endUnaryExpr( Operator.NO_OP );
661 expected().endMultiplicativeExpr( Operator.NO_OP );
662 expected().endMultiplicativeExpr( Operator.NO_OP );
663 expected().endAdditiveExpr( Operator.NO_OP );
664 expected().endAdditiveExpr( Operator.NO_OP );
665 expected().endRelationalExpr( Operator.NO_OP );
666 expected().endRelationalExpr( Operator.NO_OP );
667 expected().endEqualityExpr( Operator.NO_OP );
668 expected().endEqualityExpr( Operator.NO_OP );
669 expected().endAndExpr( false );
670 expected().endOrExpr( false );
671
672 expected().endPredicate();
673
674 compare();
675 }
676 catch( org.jaxen.saxpath.SAXPathException e )
677 {
678 fail( e.getMessage() );
679 }
680 }
681
682
683
684
685 private void setText( String text )
686 {
687 this.text = text;
688 }
689
690 private String getText()
691 {
692 return this.text;
693 }
694
695 private void setReader( XPathReader reader )
696 {
697 this.reader = reader;
698 }
699
700 private XPathReader getReader()
701 {
702 return this.reader;
703 }
704
705 private void compare()
706 {
707 assertEquals( expected(),
708 actual() );
709 }
710
711 private ConformanceXPathHandler expected()
712 {
713 return this.expected;
714 }
715
716 private ConformanceXPathHandler actual()
717 {
718 return this.actual;
719 }
720 }