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 java.io.IOException;
66
67 import javax.xml.parsers.DocumentBuilder;
68 import javax.xml.parsers.DocumentBuilderFactory;
69 import javax.xml.parsers.ParserConfigurationException;
70
71 import junit.framework.TestCase;
72
73 import org.jaxen.JaxenException;
74 import org.jaxen.XPath;
75 import org.jaxen.dom.DOMXPath;
76 import org.jaxen.saxpath.Axis;
77 import org.jaxen.saxpath.SAXPathException;
78 import org.jaxen.saxpath.XPathSyntaxException;
79 import org.w3c.dom.Document;
80 import org.xml.sax.SAXException;
81
82 public class XPathReaderTest extends TestCase
83 {
84 private ConformanceXPathHandler expected;
85 private ConformanceXPathHandler actual;
86 private Document doc;
87
88 private XPathReader reader;
89 private String text;
90
91 private String[] paths = {
92 "/foo/bar[@a='1' and @b='2']",
93 "/foo/bar[@a='1' and @b!='2']",
94 "$varname[@a='1']",
95 "//attribute::*[.!='crunchy']",
96 "'//*[contains(string(text()),\"yada yada\")]'",
97 };
98
99 private String[][] bogusPaths = {
100 new String[]{"chyld::foo", "Expected valid axis name instead of [chyld]"},
101 new String[]{"foo/tacos()", "Expected node-type"},
102 new String[]{"foo/tacos()", "Expected node-type"},
103 new String[]{"*:foo", "Unexpected ':'"},
104 new String[]{"/foo/bar[baz", "Expected: ]"},
105 new String[]{"/cracker/cheese[(mold > 1) and (sense/taste", "Expected: )"},
106 new String[]{"//", "Location path cannot end with //"},
107 new String[]{"foo/$variable/foo", "Expected one of '.', '..', '@', '*', <QName>"}
108 };
109
110 public XPathReaderTest( String name )
111 {
112 super( name );
113 }
114
115 public void setUp() throws ParserConfigurationException, SAXException, IOException
116 {
117 this.reader = new XPathReader();
118 this.text = null;
119
120 this.actual = new ConformanceXPathHandler();
121 this.expected = new ConformanceXPathHandler();
122
123 this.reader.setXPathHandler( this.actual );
124
125 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
126 factory.setNamespaceAware(true);
127 DocumentBuilder builder = factory.newDocumentBuilder();
128 doc = builder.parse( "xml/basic.xml" );
129
130 }
131
132 public void tearDown()
133 {
134 this.reader = null;
135 this.text = null;
136 }
137
138
139
140
141
142 public void testPaths() throws SAXPathException
143 {
144
145 for( int i = 0; i < paths.length; ++i )
146 {
147 reader.parse( paths[i] );
148 }
149 }
150
151 public void testBogusPaths() throws SAXPathException
152 {
153
154 for( int i = 0; i < bogusPaths.length; ++i )
155 {
156 final String[] bogusPath = bogusPaths[i];
157
158 try
159 {
160 reader.parse( bogusPath[0] );
161 fail( "Should have thrown XPathSyntaxException for " + bogusPath[0]);
162 }
163 catch( XPathSyntaxException e )
164 {
165 assertEquals( bogusPath[1], e.getMessage() );
166 }
167 }
168 }
169
170 public void testChildrenOfNumber() throws SAXPathException
171 {
172 try
173 {
174 reader.parse( "1/child::test" );
175 fail( "Should have thrown XPathSyntaxException for 1/child::test");
176 }
177 catch( XPathSyntaxException e )
178 {
179 assertEquals( "Node-set expected", e.getMessage() );
180 }
181 }
182
183 public void testChildIsNumber() throws SAXPathException
184 {
185 try
186 {
187 reader.parse( "jane/3" );
188 fail( "Should have thrown XPathSyntaxException for jane/3");
189 }
190 catch( XPathSyntaxException e )
191 {
192 assertEquals( "Expected one of '.', '..', '@', '*', <QName>", e.getMessage() );
193 }
194
195 }
196
197 public void testNumberOrNumber()
198 {
199
200 try
201 {
202 XPath xpath = new DOMXPath( "4 | 5" );
203 xpath.selectNodes( doc );
204 fail( "Should have thrown XPathSyntaxException for 4 | 5");
205 }
206 catch( JaxenException e )
207 {
208 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
209 }
210 }
211
212 public void testStringOrNumber()
213 {
214
215 try
216 {
217 XPath xpath = new DOMXPath( "\"test\" | 5" );
218 xpath.selectNodes( doc );
219 fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
220 }
221 catch( JaxenException e )
222 {
223 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
224 }
225 }
226
227 public void testStringOrString()
228 {
229
230 try
231 {
232 XPath xpath = new DOMXPath( "\"test\" | \"festival\"" );
233 xpath.selectNodes( doc );
234 fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
235 }
236 catch( JaxenException e )
237 {
238 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
239 }
240
241 }
242
243 public void testUnionofNodesAndNonNodes()
244 {
245
246 try
247 {
248 XPath xpath = new DOMXPath( "count(//*) | //* " );
249 xpath.selectNodes( doc );
250 fail( "Should have thrown XPathSyntaxException for \"count(//*) | //* ");
251 }
252 catch( JaxenException e )
253 {
254 assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
255 }
256 }
257
258 public void testValidAxis() throws SAXPathException
259 {
260 reader.parse( "child::foo" );
261 }
262
263 public void testInvalidAxis() throws SAXPathException
264 {
265
266 try
267 {
268 reader.parse( "chyld::foo" );
269 fail( "Should have thrown XPathSyntaxException" );
270 }
271 catch( XPathSyntaxException ex )
272 {
273 assertNotNull(ex.getMessage());
274 }
275
276 }
277
278 public void testSimpleNameStep() throws SAXPathException
279 {
280 this.text = "foo";
281 this.reader.setUpParse( this.text );
282 this.reader.step( );
283 this.expected.startNameStep( Axis.CHILD,
284 "",
285 "foo" );
286 this.expected.endNameStep();
287 assertEquals( this.expected,
288 this.actual );
289
290 }
291
292 public void testNameStepWithAxisAndPrefix() throws SAXPathException
293 {
294 this.text = "parent::foo:bar";
295 this.reader.setUpParse( this.text );
296 this.reader.step( );
297 this.expected.startNameStep( Axis.PARENT,
298 "foo",
299 "bar" );
300 this.expected.endNameStep();
301 assertEquals( this.expected,
302 this.actual );
303
304 }
305
306 public void testNodeStepWithAxis() throws SAXPathException
307 {
308
309 this.text = "parent::node()";
310 this.reader.setUpParse( this.text );
311 this.reader.step();
312 this.expected.startAllNodeStep( Axis.PARENT );
313 this.expected.endAllNodeStep();
314 assertEquals( this.expected,
315 this.actual );
316
317 }
318
319 public void testProcessingInstructionStepWithName() throws SAXPathException
320 {
321 this.text = "parent::processing-instruction('cheese')";
322 this.reader.setUpParse( this.text );
323 this.reader.step( );
324 this.expected.startProcessingInstructionNodeStep( Axis.PARENT,
325 "cheese" );
326 this.expected.endProcessingInstructionNodeStep();
327 assertEquals( this.expected,
328 this.actual );
329 }
330
331 public void testProcessingInstructionStepNoName() throws SAXPathException
332 {
333 this.text = "parent::processing-instruction()";
334 this.reader.setUpParse( this.text );
335 this.reader.step( );
336 this.expected.startProcessingInstructionNodeStep( Axis.PARENT,
337 "" );
338 this.expected.endProcessingInstructionNodeStep();
339 assertEquals( this.expected,
340 this.actual );
341
342 }
343
344 public void testAllNodeStep() throws SAXPathException
345 {
346
347 this.text = "parent::node()";
348 this.reader.setUpParse( this.text );
349 this.reader.step( );
350 this.expected.startAllNodeStep( Axis.PARENT );
351 this.expected.endAllNodeStep();
352 assertEquals( this.expected,
353 this.actual );
354
355 }
356
357 public void testTextNodeStep() throws SAXPathException
358 {
359
360 this.text = "parent::text()";
361 this.reader.setUpParse( this.text );
362 this.reader.step( );
363 this.expected.startTextNodeStep( Axis.PARENT );
364 this.expected.endTextNodeStep();
365 assertEquals( this.expected,
366 this.actual );
367
368 }
369
370 public void testCommentNodeStep() throws SAXPathException
371 {
372
373 this.text = "parent::comment()";
374 this.reader.setUpParse( this.text );
375 this.reader.step( );
376 this.expected.startCommentNodeStep( Axis.PARENT );
377 this.expected.endCommentNodeStep();
378 assertEquals( this.expected,
379 this.actual );
380
381 }
382
383 public void testLocationPathStartsWithVariable() throws SAXPathException
384 {
385
386 reader.parse( "$variable/foo" );
387
388 }
389
390 public void testLocationPathStartsWithParentheses() throws SAXPathException
391 {
392
393 reader.parse( "(//x)/foo" );
394
395 }
396
397 public void testRelativeLocationPath() throws SAXPathException
398 {
399
400 this.text = "foo/bar/baz";
401 this.reader.setUpParse( this.text );
402 this.reader.locationPath( false );
403 this.expected.startRelativeLocationPath();
404 this.expected.startNameStep( Axis.CHILD,
405 "",
406 "foo" );
407 this.expected.endNameStep();
408 this.expected.startNameStep( Axis.CHILD,
409 "",
410 "bar" );
411 this.expected.endNameStep();
412 this.expected.startNameStep( Axis.CHILD,
413 "",
414 "baz" );
415 this.expected.endNameStep();
416 this.expected.endRelativeLocationPath();
417 assertEquals( this.expected,
418 this.actual );
419
420 }
421
422 public void testAbsoluteLocationPath() throws SAXPathException
423 {
424
425 this.text = "/foo/bar/baz";
426 this.reader.setUpParse( this.text );
427 this.reader.locationPath( true );
428 this.expected.startAbsoluteLocationPath();
429 this.expected.startNameStep( Axis.CHILD,
430 "",
431 "foo" );
432 this.expected.endNameStep();
433 this.expected.startNameStep( Axis.CHILD,
434 "",
435 "bar" );
436 this.expected.endNameStep();
437 this.expected.startNameStep( Axis.CHILD,
438 "",
439 "baz" );
440 this.expected.endNameStep();
441 this.expected.endAbsoluteLocationPath();
442 assertEquals( this.expected,
443 this.actual );
444
445 }
446
447 }