1 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 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 } 448 | Popular Tags |