Clover coverage report - Clover results for XOM 1.2d1
Coverage timestamp: Wed Feb 8 2006 08:31:33 EST
file stats: LOC: 2,409   Methods: 128
NCLOC: 1,671   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XPathTest.java 91.2% 97.9% 100% 97.8%
coverage coverage
 1    /* Copyright 2005 Elliotte Rusty Harold
 2   
 3    This library is free software; you can redistribute it and/or modify
 4    it under the terms of version 2.1 of the GNU Lesser General Public
 5    License as published by the Free Software Foundation.
 6   
 7    This library is distributed in the hope that it will be useful,
 8    but WITHOUT ANY WARRANTY; without even the implied warranty of
 9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 10    GNU Lesser General Public License for more details.
 11   
 12    You should have received a copy of the GNU Lesser General Public
 13    License along with this library; if not, write to the
 14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 15    Boston, MA 02111-1307 USA
 16   
 17    You can contact Elliotte Rusty Harold by sending e-mail to
 18    elharo@metalab.unc.edu. Please include the word "XOM" in the
 19    subject line. The XOM home page is located at http://www.xom.nu/
 20    */
 21   
 22    package nu.xom.tests;
 23   
 24    import java.io.ByteArrayOutputStream;
 25    import java.io.File;
 26    import java.io.IOException;
 27    import java.io.PrintStream;
 28    import java.net.MalformedURLException;
 29   
 30    import nu.xom.Attribute;
 31    import nu.xom.Builder;
 32    import nu.xom.Comment;
 33    import nu.xom.DocType;
 34    import nu.xom.Document;
 35    import nu.xom.Element;
 36    import nu.xom.Elements;
 37    import nu.xom.Namespace;
 38    import nu.xom.NamespaceConflictException;
 39    import nu.xom.Node;
 40    import nu.xom.Nodes;
 41    import nu.xom.ParsingException;
 42    import nu.xom.ProcessingInstruction;
 43    import nu.xom.Text;
 44    import nu.xom.XPathContext;
 45    import nu.xom.XPathException;
 46    import nu.xom.XPathTypeException;
 47   
 48    /**
 49    * <p>
 50    * Unit tests for XPath functionality
 51    * </p>
 52    *
 53    * @author Elliotte Rusty Harold
 54    * @version 1.1b4
 55    *
 56    */
 57    public class XPathTest extends XOMTestCase {
 58   
 59  122 public XPathTest(String name) {
 60  122 super(name);
 61    }
 62   
 63   
 64    // This class tests error conditions, which Xerces
 65    // annoyingly logs to System.err. This hides System.err
 66    // before each test and restores it after each test.
 67    private PrintStream systemErr = System.err;
 68   
 69  122 protected void setUp() {
 70  122 System.setErr(new PrintStream(new ByteArrayOutputStream()));
 71    }
 72   
 73   
 74  122 protected void tearDown() {
 75  122 System.setErr(systemErr);
 76    }
 77   
 78  1 public void testAllNodesQuery() {
 79   
 80  1 Document doc = new Document(new Element("doc"));
 81  1 Nodes subset = doc.query("//. | /");
 82  1 assertEquals(2, subset.size());
 83   
 84    }
 85   
 86   
 87    /* <a>
 88    <x>1</x>
 89    <b>
 90    <x>2</x>
 91    <x>3</x>
 92    </b>
 93    <x>4</x>
 94    </a> */
 95  1 public void testDescendantAxisOrder() {
 96   
 97  1 Element a = new Element("a");
 98  1 Document doc = new Document(a);
 99  1 Element x1 = new Element("x");
 100  1 x1.appendChild("a1");
 101  1 Element x2 = new Element("x");
 102  1 x2.appendChild("b2");
 103  1 Element x3 = new Element("x");
 104  1 x3.appendChild("c3");
 105  1 Element x4 = new Element("x");
 106  1 x4.appendChild("d4");
 107  1 a.appendChild(x1);
 108  1 Element b = new Element("b");
 109  1 b.appendChild(x2);
 110  1 b.appendChild(x3);
 111  1 a.appendChild(b);
 112  1 a.appendChild(x4);
 113  1 Nodes result = doc.query("//x");
 114  1 assertEquals(4, result.size());
 115  1 assertTrue(result.get(0) instanceof Element);
 116  1 assertTrue(result.get(1) instanceof Element);
 117  1 assertTrue(result.get(2) instanceof Element);
 118  1 assertTrue(result.get(3) instanceof Element);
 119  1 assertEquals(x1, result.get(0));
 120  1 assertEquals(x2, result.get(1));
 121  1 assertEquals(x3, result.get(2));
 122  1 assertEquals(x4, result.get(3));
 123   
 124    }
 125   
 126   
 127  1 public void testSimpleQuery() {
 128   
 129  1 Element parent = new Element("Test");
 130  1 Element child = new Element("child");
 131  1 parent.appendChild(child);
 132   
 133  1 Nodes result = parent.query("*");
 134  1 assertEquals(1, result.size());
 135  1 assertEquals(child, result.get(0));
 136   
 137    }
 138   
 139   
 140  1 public void testChildWildCard() {
 141   
 142  1 Element a = new Element("a");
 143  1 Element b = new Element("b");
 144  1 Element c = new Element("c");
 145  1 Element d = new Element("d");
 146   
 147  1 a.appendChild(b);
 148  1 b.appendChild(c);
 149  1 c.appendChild(d);
 150   
 151  1 Nodes result = a.query("/a/b/*/d");
 152  1 assertEquals(1, result.size());
 153  1 assertEquals(d, result.get(0));
 154   
 155    }
 156   
 157   
 158  1 public void testSimpleChild() {
 159   
 160  1 Element a = new Element("a");
 161  1 Nodes result = a.query("/a");
 162  1 assertEquals(1, result.size());
 163   
 164    }
 165   
 166   
 167  1 public void testSimpleWildCard() {
 168   
 169  1 Element a = new Element("a");
 170  1 Nodes result = a.query("/*");
 171  1 assertEquals(1, result.size());
 172   
 173    }
 174   
 175   
 176  1 public void testLongs() {
 177   
 178  1 Document doc = new Document(new Element("root"));
 179   
 180  1 Nodes result = doc.query("/*[5000000000=5000000000]");
 181  1 assertEquals(1, result.size());
 182   
 183  1 result = doc.query("/*[5000000000 < 5000000001]");
 184  1 assertEquals(1, result.size());
 185  1 result = doc.query("/*[5000000000 > 5000000001]");
 186  1 assertEquals(0, result.size());
 187  1 result = doc.query("/*[5000000001 >= 5000000001]");
 188  1 assertEquals(1, result.size());
 189  1 result = doc.query("/*[5000000001 > 5000000001]");
 190  1 assertEquals(0, result.size());
 191   
 192    }
 193   
 194   
 195  1 public void testNamespaceNodeParent() {
 196   
 197  1 Element root = new Element("root");
 198  1 Document doc = new Document(root);
 199  1 Element child = new Element("pre:child", "http://www.ietf.org");
 200  1 root.appendChild(child);
 201   
 202  1 Nodes result = doc.query("/root/*/namespace::*/parent::*");
 203  1 assertEquals(1, result.size());
 204  1 assertEquals(child, result.get(0));
 205   
 206    }
 207   
 208   
 209  1 public void testNamespaceNodeChild() {
 210   
 211  1 Element root = new Element("root");
 212  1 Document doc = new Document(root);
 213  1 Element child = new Element("pre:child", "http://www.ietf.org");
 214  1 root.appendChild(child);
 215   
 216  1 Nodes result = doc.query("/root/*/namespace::*/child::*");
 217  1 assertEquals(0, result.size());
 218   
 219    }
 220   
 221   
 222    // JAXEN-46: http://jira.codehaus.org/browse/JAXEN-46
 223  1 public void testHashInAttributeValue() {
 224   
 225  1 Element root = new Element("test");
 226  1 Document doc = new Document(root);
 227  1 Attribute test = new Attribute("test", "SUBSCRIBER");
 228  1 Attribute test1 = new Attribute("test1", "SUBSCRIBER#");
 229  1 root.addAttribute(test);
 230  1 root.addAttribute(test1);
 231   
 232  1 Nodes result = doc.query("test[@test='SUBSCRIBER']");
 233  1 assertEquals(1, result.size());
 234  1 assertEquals(root, result.get(0));
 235   
 236  1 result = doc.query("test[@test1='SUBSCRIBER#']");
 237  1 assertEquals(1, result.size());
 238  1 assertEquals(root, result.get(0));
 239   
 240    }
 241   
 242   
 243  1 public void testUseRootNodeWhenQueryingDocumentLessElements() {
 244   
 245  1 Element test = new Element("Test");
 246   
 247  1 Nodes result = test.query("/*");
 248  1 assertEquals(1, result.size());
 249  1 assertEquals(test, result.get(0));
 250   
 251  1 try {
 252  1 test.query("/");
 253  0 fail("Did not throw exception when querying rootless document for root");
 254    }
 255    catch (XPathException success) {
 256  1 assertNotNull(success.getMessage());
 257    }
 258   
 259    }
 260   
 261   
 262  1 public void testUseRootNodeWhenQueryingDocumentLessElements2() {
 263   
 264  1 Element test = new Element("Test");
 265  1 Nodes result = test.query("/None");
 266  1 assertEquals(0, result.size());
 267   
 268    }
 269   
 270   
 271  1 public void testUseRootNodeWhenQueryingDocumentLessElements3() {
 272   
 273  1 Element test = new Element("Test");
 274   
 275  1 Nodes result = test.query("//*");
 276  1 assertEquals(1, result.size());
 277   
 278    }
 279   
 280   
 281  1 public void testUseRootNodeWhenQueryingDocumentLessElements4() {
 282   
 283  1 Element test = new Element("Test");
 284   
 285  1 Nodes result = test.query("//* | /");
 286  1 assertEquals(1, result.size());
 287   
 288    }
 289   
 290   
 291  1 public void testUnionOfNodesWithInts() {
 292   
 293  1 Element parent = new Element("Test");
 294  1 Element child = new Element("child");
 295  1 parent.appendChild(child);
 296   
 297  1 try {
 298  1 parent.query("* | count(/*)");
 299  0 fail("Allowed query returning non-node-set");
 300    }
 301    catch (XPathException success) {
 302  1 assertNotNull(success.getMessage());
 303    }
 304   
 305    }
 306   
 307   
 308  1 public void testFranceschet1() throws ParsingException, IOException {
 309   
 310  1 Builder builder = new Builder();
 311  1 Document doc = builder.build(
 312    "http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml"
 313    );
 314  1 Element root = doc.getRootElement();
 315  1 Elements inputs = root.getChildElements("document");
 316  1 Element input = inputs.get(0).getFirstChildElement("site");
 317  1 input.detach();
 318   
 319  1 Nodes doc1Queries = root.query("child::query[starts-with(@id, 'Q')]");
 320   
 321  1 for (int i = 0; i < doc1Queries.size(); i++) {
 322  47 Element query = (Element) doc1Queries.get(i);
 323  47 String xpath = query.getFirstChildElement("syntax").getValue();
 324  47 String id = query.getAttributeValue("id");
 325    // this query needs special comparison code due to
 326    // adjacent text nodes
 327  1 if ("Q21".equals(id)) continue;
 328    // test suite bug relating to id() function
 329  5 else if (xpath.indexOf("id(") >= 0) continue;
 330  41 Nodes result = input.query(xpath);
 331  41 Element answer = query.getFirstChildElement("answer");
 332  41 Nodes expected = new Nodes();
 333  41 for (int j = 0; j < answer.getChildCount(); j++) {
 334  233 Node node = answer.getChild(j);
 335  233 if (node instanceof Text) {
 336  1 if (!("".equals(node.getValue().trim()))) {
 337  0 expected.append(node);
 338    }
 339    }
 340    else {
 341  232 expected.append(node);
 342    }
 343    }
 344  41 assertEquals("Failed query " + id, expected.size(), result.size());
 345  41 for (int j = 0; j < result.size(); j++) {
 346  232 Node expectedNode = expected.get(j);
 347  232 Node actualNode = result.get(j);
 348  232 assertEquals(id + " " + expectedNode.toXML() + " " + actualNode.toXML(), expectedNode, actualNode);
 349    }
 350    }
 351   
 352    }
 353   
 354   
 355  1 public void testFranceschet2() throws ParsingException, IOException {
 356   
 357  1 Builder builder = new Builder();
 358  1 Document doc = builder.build(
 359    "http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml"
 360    );
 361  1 Element root = doc.getRootElement();
 362  1 Elements inputs = root.getChildElements("document");
 363  1 Element input = inputs.get(1);
 364  1 Document html = new Document(new Element("fake"));
 365  1 int p = 0;
 366  1 while (true) {
 367  7 Node node = input.getChild(0);
 368  1 if (node instanceof Element) break;
 369    else {
 370  6 node.detach();
 371  3 if (node instanceof Text) continue;
 372  3 html.insertChild(node, p++);
 373    }
 374    }
 375  1 Node newroot = input.getChild(0);
 376  1 newroot.detach();
 377  1 html.setRootElement((Element) newroot);
 378  1 while (input.getChildCount() > 0) {
 379  2 Node node = input.getChild(0);
 380  2 node.detach();
 381  1 if (node instanceof Text) continue;
 382  1 html.appendChild(node);
 383    }
 384   
 385  1 Nodes doc2Queries = root.query("child::query[starts-with(@id, 'A')]");
 386   
 387  1 XPathContext context = new XPathContext();
 388  1 context.addNamespace("svg", "http://www.w3.org/2000/svg");
 389  1 context.addNamespace("xlink", "http://www.w3.org/1999/xlink");
 390   
 391  1 for (int i = 0; i < doc2Queries.size(); i++) {
 392  12 Element query = (Element) doc2Queries.get(i);
 393  12 String xpath = query.getFirstChildElement("syntax").getValue();
 394  12 String id = query.getAttributeValue("id");
 395   
 396  12 Nodes result = html.query(xpath, context);
 397  12 Element answer = query.getFirstChildElement("answer");
 398  12 Nodes expected = new Nodes();
 399  12 for (int j = 0; j < answer.getChildCount(); j++) {
 400  43 Node node = answer.getChild(j);
 401  43 if (node instanceof Text) {
 402  0 if (!("".equals(node.getValue().trim()))) {
 403  0 expected.append(node);
 404    }
 405    }
 406    else {
 407  43 expected.append(node);
 408    }
 409    }
 410  12 assertEquals("Failed query " + id, expected.size(), result.size());
 411  12 for (int j = 0; j < result.size(); j++) {
 412  43 Node expectedNode = expected.get(j);
 413  43 Node actualNode = result.get(j);
 414  43 assertEquals(id + " " + expectedNode.toXML() + " "
 415    + actualNode.toXML(), expectedNode, actualNode);
 416    }
 417    }
 418   
 419    }
 420   
 421   
 422  1 public void testQueryThatReturnsNumber() {
 423   
 424  1 Element parent = new Element("Test");
 425  1 Element child = new Element("child");
 426  1 parent.appendChild(child);
 427   
 428  1 try {
 429  1 parent.query("count(*)");
 430  0 fail("Allowed query to return number");
 431    }
 432    catch (XPathTypeException success) {
 433  1 assertNotNull(success.getMessage());
 434  1 assertEquals(new Double(1), success.getReturnValue());
 435  1 assertEquals("count(*)", success.getXPath());
 436    }
 437   
 438    }
 439   
 440   
 441  1 public void testStartsWith() {
 442   
 443  1 Element parent = new Element("Test");
 444  1 Element child = new Element("child");
 445  1 child.addAttribute(new Attribute("foo", "bar"));
 446  1 parent.appendChild(child);
 447  1 Element child2 = new Element("child");
 448  1 child2.addAttribute(new Attribute("foo", "big"));
 449  1 parent.appendChild(child2);
 450   
 451  1 Nodes result = parent.query(".//*[starts-with(@foo, 'ba')]");
 452  1 assertEquals(1, result.size());
 453  1 assertEquals(child, result.get(0));
 454   
 455    }
 456   
 457   
 458    // a jaxen extension function
 459  1 public void testEndsWith() {
 460   
 461  1 Element parent = new Element("Test");
 462  1 Element child = new Element("child");
 463  1 child.addAttribute(new Attribute("foo", "bar"));
 464  1 parent.appendChild(child);
 465   
 466  1 try {
 467  1 parent.query(".//*[ends-with(@foo, 'ar')]");
 468  0 fail("Allowed Jaxen extension function");
 469    }
 470    catch (XPathException success) {
 471  1 assertTrue(success.getMessage().indexOf("ends-with") >= 0);
 472    }
 473   
 474    }
 475   
 476   
 477  1 public void testEmptyTextNodesDontCount() {
 478   
 479  1 Element parent = new Element("Test");
 480  1 Element child1 = new Element("child1");
 481  1 parent.appendChild(child1);
 482  1 parent.appendChild(new Text(""));
 483  1 parent.appendChild(new Text(""));
 484  1 Element child2 = new Element("child2");
 485  1 parent.appendChild(child2);
 486   
 487  1 Nodes result = parent.query("*");
 488  1 assertEquals(2, result.size());
 489  1 assertEquals(child1, result.get(0));
 490   
 491  1 result = parent.query("*[2]");
 492  1 assertEquals(1, result.size());
 493  1 assertEquals(child2, result.get(0));
 494   
 495    }
 496   
 497   
 498  1 public void testEmptyTextNodesDontCount2() {
 499   
 500  1 Element parent = new Element("Test");
 501  1 parent.appendChild(new Text(""));
 502  1 Element child1 = new Element("child1");
 503  1 parent.appendChild(child1);
 504  1 Element child2 = new Element("child2");
 505  1 parent.appendChild(child2);
 506   
 507  1 Nodes result = parent.query("node()");
 508  1 assertEquals(2, result.size());
 509  1 assertEquals(child1, result.get(0));
 510  1 assertEquals(child2, result.get(1));
 511   
 512  1 result = parent.query("node()[1]");
 513  1 assertEquals(1, result.size());
 514  1 assertEquals(child1, result.get(0));
 515   
 516    }
 517   
 518   
 519  1 public void testEmptyTextNodesAtEndOfParent() {
 520   
 521  1 Element parent = new Element("Test");
 522  1 Element child1 = new Element("child1");
 523  1 parent.appendChild(child1);
 524  1 Element child2 = new Element("child2");
 525  1 parent.appendChild(child2);
 526  1 parent.appendChild(new Text(""));
 527  1 parent.appendChild(new Text(""));
 528  1 parent.appendChild(new Text(""));
 529   
 530  1 Nodes result = parent.query("node()");
 531  1 assertEquals(2, result.size());
 532  1 assertEquals(child1, result.get(0));
 533  1 assertEquals(child2, result.get(1));
 534   
 535  1 result = parent.query("node()[1]");
 536  1 assertEquals(1, result.size());
 537  1 assertEquals(child1, result.get(0));
 538   
 539    }
 540   
 541   
 542  1 public void testEmptyTextNodeNextToNonEmptyTextNode() {
 543   
 544  1 Element parent = new Element("Test");
 545  1 Text empty = new Text("");
 546  1 parent.appendChild(empty);
 547  1 Text nonempty = new Text("value");
 548  1 parent.appendChild(nonempty);
 549  1 Element child1 = new Element("child1");
 550  1 parent.appendChild(child1);
 551  1 Element child2 = new Element("child2");
 552  1 parent.appendChild(child2);
 553   
 554  1 Nodes result = parent.query("node()");
 555  1 assertEquals(4, result.size());
 556  1 assertEquals(empty, result.get(0));
 557  1 assertEquals(nonempty, result.get(1));
 558   
 559  1 result = parent.query("node()[1]");
 560  1 assertEquals(2, result.size());
 561  1 assertEquals(empty, result.get(0));
 562   
 563    }
 564   
 565   
 566  1 public void testBasicPredicate() {
 567   
 568  1 Element parent = new Element("Test");
 569  1 Element child1 = new Element("child");
 570  1 child1.appendChild("1");
 571  1 parent.appendChild(child1);
 572  1 Element child2 = new Element("child");
 573  1 child2.appendChild("2");
 574  1 parent.appendChild(child2);
 575  1 Element child3 = new Element("child");
 576  1 child3.appendChild("3");
 577  1 parent.appendChild(child3);
 578   
 579  1 Nodes result = parent.query("*[.='2']");
 580  1 assertEquals(1, result.size());
 581  1 assertEquals(child2, result.get(0));
 582   
 583    }
 584   
 585   
 586  1 public void testXMLLang() {
 587   
 588  1 Element parent = new Element("Test");
 589  1 Element child1 = new Element("child");
 590  1 child1.addAttribute(new Attribute("xml:lang",
 591    "http://www.w3.org/XML/1998/namespace", "en"));
 592  1 parent.appendChild(child1);
 593  1 Element child2 = new Element("child");
 594  1 child2.appendChild("2");
 595  1 child2.addAttribute(new Attribute("xml:lang",
 596    "http://www.w3.org/XML/1998/namespace", "fr"));
 597  1 parent.appendChild(child2);
 598  1 Element child3 = new Element("child");
 599  1 child3.appendChild("3");
 600  1 parent.appendChild(child3);
 601  1 Element child4 = new Element("child");
 602  1 child4.appendChild("4");
 603  1 child4.addAttribute(new Attribute("xml:lang",
 604    "http://www.w3.org/XML/1998/namespace", "en-US"));
 605  1 parent.appendChild(child4);
 606   
 607  1 Nodes result = parent.query("child::*[lang('en')]");
 608  1 assertEquals(2, result.size());
 609  1 assertEquals(child1, result.get(0));
 610  1 assertEquals(child4, result.get(1));
 611   
 612    }
 613   
 614   
 615  1 public void testXMLPrefixIsAlwaysBound() {
 616   
 617  1 Element parent = new Element("Test");
 618  1 Element child1 = new Element("child");
 619  1 child1.addAttribute(new Attribute("xml:lang",
 620    "http://www.w3.org/XML/1998/namespace", "en"));
 621  1 parent.appendChild(child1);
 622  1 Element child2 = new Element("child");
 623  1 child2.appendChild("2");
 624  1 child2.addAttribute(new Attribute("xml:lang",
 625    "http://www.w3.org/XML/1998/namespace", "fr"));
 626  1 parent.appendChild(child2);
 627  1 Element child3 = new Element("child");
 628  1 child3.appendChild("3");
 629  1 parent.appendChild(child3);
 630  1 Element child4 = new Element("child");
 631  1 child4.appendChild("4");
 632  1 child4.addAttribute(new Attribute("xml:lang",
 633    "http://www.w3.org/XML/1998/namespace", "en-US"));
 634  1 parent.appendChild(child4);
 635   
 636  1 Nodes result = parent.query("child::*/@xml:lang");
 637  1 assertEquals(3, result.size());
 638   
 639    }
 640   
 641   
 642  1 public void testCantRebindXMLPrefix() {
 643   
 644  1 XPathContext context = new XPathContext();
 645  1 try {
 646  1 context.addNamespace("xml", "http://www.example.org");
 647  0 fail("Rebound xml prefix");
 648    }
 649    catch (NamespaceConflictException success) {
 650  1 assertNotNull(success.getMessage());
 651    }
 652   
 653    }
 654   
 655   
 656  1 public void testParentAxis() {
 657   
 658  1 Element parent = new Element("Test");
 659  1 Element child = new Element("child");
 660  1 parent.appendChild(child);
 661   
 662  1 Nodes result = child.query("parent::*");
 663  1 assertEquals(1, result.size());
 664  1 assertEquals(parent, result.get(0));
 665   
 666    }
 667   
 668   
 669  1 public void testAncestorAxis() {
 670   
 671  1 Element grandparent = new Element("Test");
 672  1 new Document(grandparent);
 673  1 Element parent = new Element("Test");
 674  1 Element child = new Element("child");
 675  1 parent.appendChild(child);
 676  1 grandparent.appendChild(parent);
 677   
 678  1 Nodes result = child.query("ancestor::*");
 679  1 assertEquals(2, result.size());
 680  1 assertEquals(grandparent, result.get(0));
 681  1 assertEquals(parent, result.get(1));
 682   
 683    }
 684   
 685   
 686  1 public void testParentAxisWithDocument() {
 687   
 688  1 Element root = new Element("Test");
 689  1 new Document(root);
 690   
 691  1 Nodes result = root.query("parent::*");
 692  1 assertEquals(0, result.size());
 693   
 694    }
 695   
 696   
 697  1 public void testParentAxisWithNodeMatchingDocument() {
 698   
 699  1 Element root = new Element("Test");
 700  1 Document doc = new Document(root);
 701   
 702  1 Nodes result = root.query("parent::node()");
 703  1 assertEquals(1, result.size());
 704  1 assertEquals(doc, result.get(0));
 705   
 706    }
 707   
 708   
 709  1 public void testSubstringFunction() {
 710   
 711  1 Element root = new Element("Test");
 712  1 new Document(root);
 713   
 714  1 Nodes result = root.query("/*[substring('12345', 0, 3)='12']");
 715  1 assertEquals(1, result.size());
 716  1 assertEquals(root, result.get(0));
 717   
 718    }
 719   
 720   
 721  1 public void testPrecedingAxisWithElementName() {
 722   
 723  1 Element root = new Element("Test");
 724  1 Document doc = new Document(root);
 725   
 726  1 Nodes result = doc.query("/descendant::*/preceding::x");
 727  1 assertEquals(0, result.size());
 728   
 729    }
 730   
 731   
 732   
 733   
 734  1 public void testDocTypeIsNotAnXPathNode() {
 735   
 736  1 Element root = new Element("root");
 737  1 Document doc = new Document(root);
 738  1 DocType doctype = new DocType("root");
 739  1 doc.setDocType(doctype);
 740   
 741  1 Nodes result = doc.query("child::node()[1]");
 742  1 assertEquals(1, result.size());
 743  1 assertEquals(root, result.get(0));
 744   
 745    }
 746   
 747   
 748  1 public void testGetNodeBeforeDocType() {
 749   
 750  1 Element root = new Element("root");
 751  1 Document doc = new Document(root);
 752  1 DocType doctype = new DocType("root");
 753  1 doc.setDocType(doctype);
 754  1 Comment c = new Comment("test");
 755  1 doc.insertChild(c, 0);
 756   
 757  1 Nodes result = doc.query("child::node()[1]");
 758  1 assertEquals(1, result.size());
 759  1 assertEquals(c, result.get(0));
 760   
 761    }
 762   
 763   
 764  1 public void testCantUseDocTypeAsXPathContextNode() {
 765   
 766  1 Element root = new Element("root");
 767  1 Document doc = new Document(root);
 768  1 DocType doctype = new DocType("root");
 769  1 doc.setDocType(doctype);
 770   
 771  1 try {
 772  1 doctype.query("/");
 773  0 fail("Allowed DocType as context node");
 774    }
 775    catch (XPathException success) {
 776  1 assertNotNull(success.getMessage());
 777    }
 778   
 779    }
 780   
 781   
 782  1 public void testDescendantAxis() {
 783   
 784  1 Element grandparent = new Element("Test");
 785  1 Document doc = new Document(grandparent);
 786  1 Element parent = new Element("Test");
 787  1 Element child = new Element("child");
 788  1 parent.appendChild(child);
 789  1 grandparent.appendChild(parent);
 790   
 791  1 Nodes result = doc.query("descendant::*");
 792  1 assertEquals(3, result.size());
 793  1 assertEquals(grandparent, result.get(0));
 794  1 assertEquals(parent, result.get(1));
 795  1 assertEquals(child, result.get(2));
 796   
 797    }
 798   
 799   
 800  1 public void testGetElementQName() {
 801   
 802  1 Element grandparent = new Element("Test");
 803  1 Document doc = new Document(grandparent);
 804  1 Element parent = new Element("Test");
 805  1 Element child1 = new Element("pre:child", "http://www.example.org/");
 806  1 Element child2 = new Element("pre:child", "http://www.example.com/");
 807  1 parent.appendChild(child1);
 808  1 parent.appendChild(child2);
 809  1 grandparent.appendChild(parent);
 810   
 811  1 Nodes result = doc.query("descendant::*[name(.)='pre:child']");
 812  1 assertEquals(2, result.size());
 813  1 assertEquals(child1, result.get(0));
 814  1 assertEquals(child2, result.get(1));
 815   
 816    }
 817   
 818   
 819    // This does not actually hit the method I was aiming at.
 820    // Apparently, Jaxen never actually invokes
 821    // getElementStringValue()
 822  1 public void testGetElementStringValue() {
 823   
 824  1 Element grandparent = new Element("Test");
 825  1 Document doc = new Document(grandparent);
 826  1 Element parent = new Element("Test");
 827  1 Element child1 = new Element("child");
 828  1 child1.appendChild("foo");
 829  1 Element child2 = new Element("child");
 830  1 child2.appendChild("bar");
 831  1 parent.appendChild(child1);
 832  1 parent.appendChild(child2);
 833  1 grandparent.appendChild(parent);
 834   
 835  1 Nodes result = doc.query("descendant::*[.='foo']");
 836  1 assertEquals(1, result.size());
 837  1 assertEquals(child1, result.get(0));
 838   
 839    }
 840   
 841   
 842  1 public void testGetNonExistentNode() {
 843   
 844  1 Element grandparent = new Element("Test");
 845  1 Document doc = new Document(grandparent);
 846  1 Element parent = new Element("Test");
 847  1 Element child1 = new Element("child");
 848  1 child1.appendChild("foo");
 849  1 Element child2 = new Element("child");
 850  1 child2.appendChild("bar");
 851  1 parent.appendChild(child1);
 852  1 parent.appendChild(child2);
 853  1 grandparent.appendChild(parent);
 854   
 855  1 Nodes result = doc.query("/Test/Test/*[12]");
 856  1 assertEquals(0, result.size());
 857   
 858    }
 859   
 860   
 861  1 public void testGetAttributeQName() {
 862   
 863  1 Element grandparent = new Element("Test");
 864  1 Document doc = new Document(grandparent);
 865  1 Element parent = new Element("Test");
 866  1 Attribute a1 = new Attribute("pre:attribute", "http://www.example.org/", "test");
 867  1 Attribute a2 = new Attribute("pre:attribute", "http://www.example.com/", "test");
 868  1 parent.addAttribute(a2);
 869  1 grandparent.addAttribute(a1);
 870  1 grandparent.appendChild(parent);
 871   
 872  1 Nodes result = doc.query("descendant::*/attribute::*[name(.)='pre:attribute']");
 873  1 assertEquals(2, result.size());
 874  1 assertTrue(result.contains(a1));
 875  1 assertTrue(result.contains(a2));
 876   
 877    }
 878   
 879   
 880  1 public void testGetNamespaceStringValue() {
 881   
 882  1 Element test = new Element("Test", "http://www.example.com/");
 883   
 884  1 Nodes result = test.query("self::*[contains(namespace::*, 'http://')]");
 885  1 assertEquals(1, result.size());
 886  1 assertEquals(test, result.get(0));
 887   
 888    }
 889   
 890   
 891    private File inputDir = new File("data");
 892   
 893   
 894  1 public void testGetDocument() throws MalformedURLException {
 895   
 896  1 Element element = new Element("test");
 897  1 File f = new File(inputDir, "prettyxml.xml");
 898  1 String url = f.toURL().toExternalForm();
 899  1 try {
 900  1 element.query("document('" + url + "')/*");
 901  0 fail("allowed document() function");
 902    }
 903    catch(XPathException success) {
 904  1 assertTrue(success.getMessage().indexOf("document") >= 0);
 905    }
 906   
 907    }
 908   
 909   
 910  1 public void testGetMultipleNodesViaDocumentFunction()
 911    throws MalformedURLException {
 912   
 913  1 Element element = new Element("test");
 914  1 File f = new File(inputDir, "prettyxml.xml");
 915  1 String url = f.toURL().toExternalForm();
 916  1 try {
 917  1 element.query("document('" + url + "')//*");
 918  0 fail("allowed document() function");
 919    }
 920    catch(XPathException success) {
 921  1 assertTrue(success.getMessage().indexOf("document") >= 0);
 922    }
 923   
 924    }
 925   
 926   
 927  1 public void testDoubleDocument() throws MalformedURLException {
 928   
 929  1 Element element = new Element("test");
 930  1 File f1 = new File(inputDir, "prettyxml.xml");
 931  1 String url1 = f1.toURL().toExternalForm();
 932  1 File f2 = new File(inputDir, "test.xml");
 933  1 String url2 = f2.toURL().toExternalForm();
 934  1 try {
 935  1 element.query("document('" + url1 + "')/* | "
 936    + "document('" + url2 + "')/*");
 937  0 fail("allowed document() function");
 938    }
 939    catch(XPathException success) {
 940  1 assertTrue(success.getMessage().indexOf("document") >= 0);
 941    }
 942   
 943    }
 944   
 945   
 946  1 public void testGetNonExistentDocument() {
 947   
 948  1 Element element = new Element("test");
 949  1 try {
 950  1 element.query("document('http://www.ibiblio.org/aksdjhk/')/*");
 951  0 fail("That file doesn't exist!");
 952    }
 953    catch (XPathException success) {
 954  1 assertNotNull(success.getMessage());
 955    }
 956   
 957    }
 958   
 959   
 960  1 public void testMalformedDocument() {
 961   
 962  1 Element element = new Element("test");
 963  1 try {
 964  1 element.query("document('http://www.cafeaulait.org/formatter/Formatter.java')/*");
 965  0 fail("Queried malformed document!");
 966    }
 967    catch (XPathException success) {
 968  1 assertNotNull(success.getMessage());
 969    }
 970   
 971    }
 972   
 973   
 974  1 public void testGetDocumentNode() {
 975   
 976  1 Element element = new Element("test");
 977  1 Document doc = new Document(element);
 978  1 Nodes result = element.query("/");
 979  1 assertEquals(1, result.size());
 980  1 assertEquals(doc, result.get(0));
 981   
 982    }
 983   
 984   
 985  1 public void testCommentNodeTest() {
 986   
 987  1 Element grandparent = new Element("Test");
 988  1 Document doc = new Document(grandparent);
 989  1 Element parent = new Element("Test");
 990  1 Element child = new Element("child");
 991  1 parent.appendChild(child);
 992  1 grandparent.appendChild(parent);
 993   
 994  1 Comment c1 = new Comment("c1");
 995  1 Comment c2 = new Comment("c2");
 996  1 Comment c3 = new Comment("c3");
 997  1 Comment c4 = new Comment("c4");
 998   
 999  1 doc.insertChild(c1, 0);
 1000  1 grandparent.insertChild(c2, 0);
 1001  1 parent.insertChild(c3, 0);
 1002  1 child.insertChild(c4, 0);
 1003   
 1004  1 Nodes result = doc.query("descendant::comment()");
 1005  1 assertEquals(4, result.size());
 1006  1 assertEquals(c1, result.get(0));
 1007  1 assertEquals(c2, result.get(1));
 1008  1 assertEquals(c3, result.get(2));
 1009  1 assertEquals(c4, result.get(3));
 1010   
 1011    }
 1012   
 1013   
 1014  1 public void testCommentStringValue() {
 1015   
 1016  1 Element grandparent = new Element("Test");
 1017  1 Document doc = new Document(grandparent);
 1018  1 Element parent = new Element("Test");
 1019  1 Element child = new Element("child");
 1020  1 parent.appendChild(child);
 1021  1 grandparent.appendChild(parent);
 1022   
 1023  1 Comment c1 = new Comment("c1");
 1024  1 Comment c2 = new Comment("c2");
 1025  1 Comment c3 = new Comment("c3");
 1026  1 Comment c4 = new Comment("c4");
 1027   
 1028  1 doc.insertChild(c1, 0);
 1029  1 grandparent.insertChild(c2, 0);
 1030  1 parent.insertChild(c3, 0);
 1031  1 child.insertChild(c4, 0);
 1032   
 1033  1 Nodes result = doc.query("descendant::comment()[.='c3']");
 1034  1 assertEquals(1, result.size());
 1035  1 assertEquals(c3, result.get(0));
 1036   
 1037    }
 1038   
 1039   
 1040  1 public void testGetProcessingInstructionData() {
 1041   
 1042  1 Element grandparent = new Element("Test");
 1043  1 Document doc = new Document(grandparent);
 1044  1 Element parent = new Element("Test");
 1045  1 Element child = new Element("child");
 1046  1 parent.appendChild(child);
 1047  1 grandparent.appendChild(parent);
 1048   
 1049  1 ProcessingInstruction p1 = new ProcessingInstruction("c1", "1");
 1050  1 ProcessingInstruction p2 = new ProcessingInstruction("c1", "2");
 1051  1 ProcessingInstruction p3 = new ProcessingInstruction("c1", "3");
 1052  1 ProcessingInstruction p4 = new ProcessingInstruction("c1", "4");
 1053   
 1054  1 doc.insertChild(p1, 0);
 1055  1 grandparent.insertChild(p2, 0);
 1056  1 parent.insertChild(p3, 0);
 1057  1 child.insertChild(p4, 0);
 1058   
 1059  1 Nodes result = doc.query("descendant::processing-instruction()[.='3']");
 1060  1 assertEquals(1, result.size());
 1061  1 assertEquals(p3, result.get(0));
 1062   
 1063    }
 1064   
 1065   
 1066  1 public void testProcessingInstructionNodeTest() {
 1067   
 1068  1 Element grandparent = new Element("Test");
 1069  1 Document doc = new Document(grandparent);
 1070  1 Element parent = new Element("Test");
 1071  1 Element child = new Element("child");
 1072  1 parent.appendChild(child);
 1073  1 grandparent.appendChild(parent);
 1074   
 1075  1 Comment c1 = new Comment("c1");
 1076  1 Comment c2 = new Comment("c2");
 1077  1 Comment c3 = new Comment("c3");
 1078  1 Comment c4 = new Comment("c4");
 1079   
 1080  1 doc.insertChild(c1, 0);
 1081  1 grandparent.insertChild(c2, 0);
 1082  1 parent.insertChild(c3, 0);
 1083  1 child.insertChild(c4, 0);
 1084  1 ProcessingInstruction pi = new ProcessingInstruction("appendix", "text");
 1085  1 doc.appendChild(pi);
 1086  1 ProcessingInstruction pi2 = new ProcessingInstruction("test", "text");
 1087  1 parent.appendChild(pi2);
 1088   
 1089  1 Nodes result = doc.query("descendant::processing-instruction('test')");
 1090  1 assertEquals(1, result.size());
 1091  1 assertEquals(pi2, result.get(0));
 1092   
 1093    }
 1094   
 1095   
 1096  1 public void testDescendantOrSelfAxis() {
 1097   
 1098  1 Element grandparent = new Element("Test");
 1099  1 Element parent = new Element("Test");
 1100  1 Element child = new Element("child");
 1101  1 parent.appendChild(child);
 1102  1 grandparent.appendChild(parent);
 1103   
 1104  1 Nodes result = grandparent.query("descendant-or-self::*");
 1105  1 assertEquals(3, result.size());
 1106  1 assertEquals(grandparent, result.get(0));
 1107  1 assertEquals(parent, result.get(1));
 1108  1 assertEquals(child, result.get(2));
 1109   
 1110    }
 1111   
 1112   
 1113  1 public void testAncestorOrSelfAxis() {
 1114   
 1115  1 Element grandparent = new Element("Test");
 1116  1 new Document(grandparent);
 1117  1 Element parent = new Element("Test");
 1118  1 Element child = new Element("child");
 1119  1 parent.appendChild(child);
 1120  1 grandparent.appendChild(parent);
 1121   
 1122  1 Nodes result = child.query("ancestor-or-self::*");
 1123  1 assertEquals(3, result.size());
 1124  1 assertEquals(child, result.get(2));
 1125  1 assertEquals(parent, result.get(1));
 1126  1 assertEquals(grandparent, result.get(0));
 1127   
 1128    }
 1129   
 1130   
 1131  1 public void testSelfAxis() {
 1132   
 1133  1 Element parent = new Element("Test");
 1134  1 Element child = new Element("child");
 1135  1 parent.appendChild(child);
 1136   
 1137  1 Nodes result = child.query("self::*");
 1138  1 assertEquals(1, result.size());
 1139  1 assertEquals(child, result.get(0));
 1140  1 result = parent.query("self::*");
 1141  1 assertEquals(1, result.size());
 1142  1 assertEquals(parent, result.get(0));
 1143   
 1144    }
 1145   
 1146   
 1147  1 public void testSelfAxisWithUnparentedText() {
 1148   
 1149  1 Text text = new Text("test");
 1150  1 Nodes result = text.query("self::text()");
 1151  1 assertEquals(1, result.size());
 1152  1 assertEquals(text, result.get(0));
 1153   
 1154    }
 1155   
 1156  1 public void testSelfAxisWithAttribute() {
 1157   
 1158  1 Element e = new Element("child");
 1159  1 e.addAttribute(new Attribute("test", "value"));
 1160  1 Nodes result = e.query("@*[self::test]");
 1161  1 assertEquals(0, result.size());
 1162   
 1163    }
 1164   
 1165   
 1166  1 public void testSelfAxisWithTextChild() {
 1167   
 1168  1 Element parent = new Element("parent");
 1169  1 Node child = new Text("child");
 1170  1 parent.appendChild(child);
 1171  1 Nodes result = child.query("self::text()");
 1172  1 assertEquals(1, result.size());
 1173  1 assertEquals(child, result.get(0));
 1174   
 1175    }
 1176   
 1177   
 1178  1 public void testSelfAxisWithTextChildren() {
 1179   
 1180  1 Element parent = new Element("parent");
 1181  1 Node child1 = new Text("1");
 1182  1 Node child2 = new Text("2");
 1183  1 Node child3 = new Text("3");
 1184  1 Node child4 = new Text("4");
 1185  1 parent.appendChild(child1);
 1186  1 parent.appendChild(child2);
 1187  1 parent.appendChild(child3);
 1188  1 parent.appendChild(child4);
 1189  1 Nodes result = child1.query("self::text()");
 1190  1 assertEquals(4, result.size());
 1191  1 assertEquals(child1, result.get(0));
 1192  1 assertEquals(child2, result.get(1));
 1193  1 assertEquals(child3, result.get(2));
 1194  1 assertEquals(child4, result.get(3));
 1195   
 1196    }
 1197   
 1198   
 1199  1 public void testSelfAxisWithTextChildren2() {
 1200   
 1201  1 Element parent = new Element("parent");
 1202  1 Node child1 = new Text("1");
 1203  1 Node child2 = new Text("2");
 1204  1 Node child3 = new Text("3");
 1205  1 Node child4 = new Text("4");
 1206  1 parent.appendChild(child1);
 1207  1 parent.appendChild(child2);
 1208  1 parent.appendChild(child3);
 1209  1 parent.appendChild(child4);
 1210  1 Nodes result = child3.query("self::text()");
 1211  1 assertEquals(4, result.size());
 1212  1 assertEquals(child1, result.get(0));
 1213  1 assertEquals(child2, result.get(1));
 1214  1 assertEquals(child3, result.get(2));
 1215  1 assertEquals(child4, result.get(3));
 1216   
 1217    }
 1218   
 1219   
 1220  1 public void testSelfAxisWithTextChildAndNoParent() {
 1221   
 1222  1 Node child = new Text("child");
 1223  1 Nodes result = child.query("self::text()");
 1224  1 assertEquals(1, result.size());
 1225  1 assertEquals(child, result.get(0));
 1226   
 1227    }
 1228   
 1229   
 1230  1 public void testAttributeAxis() {
 1231   
 1232  1 Element parent = new Element("Test");
 1233  1 Element child = new Element("child");
 1234  1 parent.appendChild(child);
 1235  1 parent.addAttribute(new Attribute("name", "value"));
 1236  1 parent.addAttribute(new Attribute("name2", "value"));
 1237   
 1238  1 Nodes result = child.query("attribute::*");
 1239  1 assertEquals(0, result.size());
 1240  1 result = parent.query("attribute::*");
 1241  1 assertEquals(2, result.size());
 1242  1 result = parent.query("attribute::name");
 1243  1 assertEquals(1, result.size());
 1244   
 1245    }
 1246   
 1247   
 1248  1 public void testAttributeAxisOnNonElement() {
 1249   
 1250  1 Text text = new Text("Test");
 1251  1 Nodes result = text.query("attribute::*");
 1252  1 assertEquals(0, result.size());
 1253   
 1254    }
 1255   
 1256   
 1257  1 public void testEmptyParentAxis() {
 1258   
 1259  1 Element parent = new Element("Test");
 1260  1 Element child = new Element("child");
 1261  1 parent.appendChild(child);
 1262   
 1263  1 Nodes result = parent.query("parent::*");
 1264  1 assertEquals(0, result.size());
 1265   
 1266    }
 1267   
 1268   
 1269  1 public void testPrecedingSiblingAxis() {
 1270   
 1271  1 Element parent = new Element("Test");
 1272  1 Element child1 = new Element("child1");
 1273  1 Element child2 = new Element("child2");
 1274  1 Element child3 = new Element("child3");
 1275  1 parent.appendChild(child1);
 1276  1 parent.appendChild(child2);
 1277  1 parent.appendChild(child3);
 1278   
 1279  1 Nodes result = child1.query("preceding-sibling::*");
 1280  1 assertEquals(0, result.size());
 1281  1 result = child2.query("preceding-sibling::*");
 1282  1 assertEquals(1, result.size());
 1283  1 assertEquals(child1, result.get(0));
 1284  1 result = child3.query("preceding-sibling::*");
 1285  1 assertEquals(2, result.size());
 1286   
 1287    }
 1288   
 1289   
 1290  1 public void testAttributeHasNoSiblings() {
 1291   
 1292  1 Element parent = new Element("Test");
 1293  1 Element child1 = new Element("child1");
 1294  1 Element child2 = new Element("child2");
 1295  1 Element child3 = new Element("child3");
 1296  1 parent.appendChild(child1);
 1297  1 parent.appendChild(child2);
 1298  1 parent.appendChild(child3);
 1299  1 Attribute a1 = new Attribute("a1", "value");
 1300  1 Attribute a2 = new Attribute("a2", "value");
 1301  1 Attribute a3 = new Attribute("a3", "value");
 1302  1 child2.addAttribute(a1);
 1303  1 child2.addAttribute(a2);
 1304  1 child2.addAttribute(a3);
 1305   
 1306  1 Nodes result = a2.query("preceding-sibling::node()");
 1307  1 assertEquals(0, result.size());
 1308  1 result = a2.query("following-sibling::node()");
 1309  1 assertEquals(0, result.size());
 1310   
 1311    }
 1312   
 1313   
 1314  1 public void testIDFunction() {
 1315   
 1316  1 Element parent = new Element("Test");
 1317  1 Element child1 = new Element("child1");
 1318  1 Element child2 = new Element("child2");
 1319  1 Element child3 = new Element("child3");
 1320  1 Attribute id = new Attribute("a", "anchor");
 1321  1 id.setType(Attribute.Type.ID);
 1322  1 child2.addAttribute(id);
 1323   
 1324  1 parent.appendChild(child1);
 1325  1 parent.appendChild(child2);
 1326  1 parent.appendChild(child3);
 1327   
 1328  1 Nodes result = parent.query("id('anchor')");
 1329  1 assertEquals(1, result.size());
 1330  1 assertEquals(child2, result.get(0));
 1331   
 1332    }
 1333   
 1334   
 1335  1 public void testIDQueryOnDocumentNode() {
 1336   
 1337  1 Element parent = new Element("Test");
 1338  1 Element child1 = new Element("child1");
 1339  1 Element child2 = new Element("child2");
 1340  1 Element child3 = new Element("child3");
 1341  1 Attribute id = new Attribute("a", "anchor");
 1342  1 id.setType(Attribute.Type.ID);
 1343  1 child2.addAttribute(id);
 1344   
 1345  1 parent.appendChild(child1);
 1346  1 parent.appendChild(child2);
 1347  1 parent.appendChild(child3);
 1348  1 Document doc = new Document(parent);
 1349   
 1350  1 Nodes result = doc.query("id('anchor')");
 1351  1 assertEquals(1, result.size());
 1352  1 assertEquals(child2, result.get(0));
 1353   
 1354    }
 1355   
 1356   
 1357  1 public void testIDFunctionWithoutType() {
 1358   
 1359  1 Element parent = new Element("Test");
 1360  1 Element child1 = new Element("child1");
 1361  1 Element child2 = new Element("child2");
 1362  1 Element child3 = new Element("child3");
 1363  1 Attribute id = new Attribute("id", "anchor");
 1364  1 child2.addAttribute(id);
 1365   
 1366  1 parent.appendChild(child1);
 1367  1 parent.appendChild(child2);
 1368  1 parent.appendChild(child3);
 1369   
 1370  1 Nodes result = parent.query("id('anchor')");
 1371  1 assertEquals(0, result.size());
 1372   
 1373    }
 1374   
 1375   
 1376  1 public void testIDFunctionFromTextNode() {
 1377   
 1378  1 Element parent = new Element("Test");
 1379  1 Element child1 = new Element("child1");
 1380  1 Element child2 = new Element("child2");
 1381  1 Element child3 = new Element("child3");
 1382  1 Text text = new Text("test");
 1383  1 child3.appendChild(text);
 1384  1 Attribute id = new Attribute("a", "anchor");
 1385  1 id.setType(Attribute.Type.ID);
 1386  1 child2.addAttribute(id);
 1387   
 1388  1 parent.appendChild(child1);
 1389  1 parent.appendChild(child2);
 1390  1 parent.appendChild(child3);
 1391   
 1392  1 Nodes result = text.query("id('anchor')");
 1393  1 assertEquals(1, result.size());
 1394  1 assertEquals(child2, result.get(0));
 1395   
 1396    }
 1397   
 1398   
 1399  1 public void testIDFunctionFromUnparentedTextNode() {
 1400   
 1401  1 Text text = new Text("test");
 1402  1 Nodes result = text.query("id('anchor')");
 1403  1 assertEquals(0, result.size());
 1404   
 1405    }
 1406   
 1407   
 1408  1 public void testIDFunctionFromDisconnectedTextNode() {
 1409   
 1410  1 Text text = new Text("test");
 1411  1 Nodes result = text.query("id('anchor')");
 1412  1 assertEquals(0, result.size());
 1413   
 1414    }
 1415   
 1416   
 1417  1 public void testFollowingSiblingAxis() {
 1418   
 1419  1 Element parent = new Element("Test");
 1420  1 Element child1 = new Element("child1");
 1421  1 Element child2 = new Element("child2");
 1422  1 Element child3 = new Element("child3");
 1423  1 parent.appendChild(child1);
 1424  1 parent.appendChild(child2);
 1425  1 parent.appendChild(child3);
 1426   
 1427  1 Nodes result = child3.query("following-sibling::*");
 1428  1 assertEquals(0, result.size());
 1429  1 result = child2.query("following-sibling::*");
 1430  1 assertEquals(1, result.size());
 1431  1 assertEquals(child3, result.get(0));
 1432  1 result = child1.query("following-sibling::*");
 1433  1 assertEquals(2, result.size());
 1434   
 1435    }
 1436   
 1437   
 1438  1 public void testNamespaceQuery() {
 1439   
 1440  1 Element parent = new Element("Test", "http://www.example.org");
 1441  1 Element child = new Element("child", "http://www.example.org");
 1442  1 parent.appendChild(child);
 1443   
 1444  1 XPathContext context = new XPathContext("pre", "http://www.example.org");
 1445  1 Nodes result = parent.query("child::pre:child", context);
 1446  1 assertEquals(1, result.size());
 1447  1 assertEquals(child, result.get(0));
 1448   
 1449    }
 1450   
 1451   
 1452  1 public void testNamespaceAxis() {
 1453   
 1454  1 Element parent = new Element("Test", "http://www.example.org");
 1455   
 1456  1 Nodes result = parent.query("namespace::*");
 1457  1 assertEquals(2, result.size());
 1458  1 Namespace n1 = (Namespace) result.get(0);
 1459  1 Namespace n2 = (Namespace) result.get(1);
 1460  1 assertTrue(n1.getPrefix().equals("") || n2.getPrefix().equals(""));
 1461  1 assertTrue(n1.getPrefix().equals("xml") || n2.getPrefix().equals("xml"));
 1462  1 assertTrue(n1.getValue().equals("http://www.example.org")
 1463    || n2.getValue().equals("http://www.example.org"));
 1464  1 assertTrue(n1.getValue().equals(Namespace.XML_NAMESPACE)
 1465    || n2.getValue().equals(Namespace.XML_NAMESPACE));
 1466   
 1467    }
 1468   
 1469   
 1470  1 public void testNamespaceAxisFromNonElement() {
 1471   
 1472  1 Text text = new Text("test");
 1473   
 1474  1 Nodes result = text.query("namespace::*");
 1475  1 assertEquals(0, result.size());
 1476   
 1477    }
 1478   
 1479   
 1480  1 public void testPredicateWithNamespaceAxis() {
 1481   
 1482  1 Element parent = new Element("Test");
 1483  1 Element child = new Element("child", "http://www.example.com");
 1484  1 Element grandchild = new Element("child", "http://www.example.com");
 1485  1 grandchild.addNamespaceDeclaration("pre", "http://www.w3.org/");
 1486  1 parent.appendChild(child);
 1487  1 child.appendChild(grandchild);
 1488   
 1489    // Every node has at least a mapping for xml prefix.
 1490  1 Nodes result = parent.query("self::*[count(namespace::*)=0]");
 1491  1 assertEquals(0, result.size());
 1492   
 1493  1 result = parent.query("self::*[count(namespace::*)=1]");
 1494  1 assertEquals(1, result.size());
 1495  1 assertEquals(parent, result.get(0));
 1496   
 1497  1 result = child.query("self::*[count(namespace::*)=2]");
 1498  1 assertEquals(1, result.size());
 1499  1 assertEquals(child, result.get(0));
 1500   
 1501  1 result = grandchild.query("self::*[count(namespace::*)=3]");
 1502  1 assertEquals(1, result.size());
 1503  1 assertEquals(grandchild, result.get(0));
 1504   
 1505    }
 1506   
 1507   
 1508  1 public void testPredicateWithNamespaceAxis2() {
 1509   
 1510  1 Element parent = new Element("Test");
 1511  1 Element child = new Element("child", "http://www.example.com");
 1512  1 Element grandchild = new Element("child", "http://www.example.com");
 1513  1 grandchild.addNamespaceDeclaration("pre", "http://www.w3.org/");
 1514  1 parent.appendChild(child);
 1515  1 child.appendChild(grandchild);
 1516   
 1517    // Every node has at least a mapping for xml prefix.
 1518  1 Nodes result = parent.query("*[count(namespace::*)=0]");
 1519  1 assertEquals(0, result.size());
 1520   
 1521  1 result = parent.query(".//self::*[count(namespace::*)=1]");
 1522  1 assertEquals(1, result.size());
 1523  1 assertEquals(parent, result.get(0));
 1524   
 1525  1 result = parent.query(".//*[count(namespace::*)=2]");
 1526  1 assertEquals(1, result.size());
 1527  1 assertEquals(child, result.get(0));
 1528   
 1529  1 result = parent.query(".//*[count(namespace::*)=3]");
 1530  1 assertEquals(1, result.size());
 1531  1 assertEquals(grandchild, result.get(0));
 1532   
 1533    }
 1534   
 1535   
 1536  1 public void testNamespaceQueryWithNullPrefix() {
 1537   
 1538  1 try {
 1539  1 XPathContext context = new XPathContext("pre", "http://www.example.org");
 1540  1 context.addNamespace(null, "http://www.w3.org");
 1541  0 fail("Allowed null prefix");
 1542    }
 1543    catch (NullPointerException success) {
 1544  1 assertNotNull(success.getMessage());
 1545    }
 1546   
 1547    }
 1548   
 1549   
 1550  1 public void testNamespaceQueryWithNullPrefix2() {
 1551   
 1552  1 try {
 1553  1 new XPathContext(null, "http://www.example.org");
 1554  0 fail("Allowed null prefix");
 1555    }
 1556    catch (NullPointerException success) {
 1557  1 assertNotNull(success.getMessage());
 1558    }
 1559   
 1560    }
 1561   
 1562   
 1563  1 public void testNamespaceQueryWithEmptyPrefix() {
 1564   
 1565  1 try {
 1566  1 XPathContext context = new XPathContext("pre", "http://www.example.org");
 1567  1 context.addNamespace("", "http://www.w3.org");
 1568    }
 1569    catch (NamespaceConflictException success) {
 1570  1 assertTrue(success.getMessage().length() > 1);
 1571    }
 1572   
 1573    }
 1574   
 1575   
 1576  1 public void testNamespaceQueryWithEmptyPrefix2() {
 1577   
 1578  1 try {
 1579  1 new XPathContext("", "http://www.example.org");
 1580    }
 1581    catch (NamespaceConflictException success) {
 1582  1 assertTrue(success.getMessage().length() > 1);
 1583    }
 1584   
 1585    }
 1586   
 1587   
 1588  1 public void testNamespaceQueryWithNullURI() {
 1589   
 1590  1 Element parent = new Element("Test", "http://www.example.org");
 1591  1 Element child = new Element("child", "http://www.example.org");
 1592  1 parent.appendChild(child);
 1593   
 1594  1 XPathContext context = new XPathContext("pre", null);
 1595  1 try {
 1596  1 parent.query("child::pre:child", context);
 1597  0 fail("Allowed null URI");
 1598    }
 1599    catch (XPathException success) {
 1600  1 assertNotNull(success.getCause());
 1601  1 assertNotNull(success.getMessage());
 1602    }
 1603   
 1604    }
 1605   
 1606   
 1607  1 public void testNamespaceQueryWithEmptyURI() {
 1608   
 1609  1 Element parent = new Element("Test", "http://www.example.org");
 1610  1 Element child = new Element("child", "http://www.example.org");
 1611  1 parent.appendChild(child);
 1612   
 1613  1 XPathContext context = new XPathContext("pre", "");
 1614  1 try {
 1615  1 parent.query("child::pre:child", context);
 1616  0 fail("Allowed empty string as namespace URI");
 1617    }
 1618    catch (XPathException success) {
 1619  1 assertNotNull(success.getCause());
 1620  1 assertNotNull(success.getMessage());
 1621    }
 1622   
 1623    }
 1624   
 1625   
 1626  1 public void testNamespaceQueryWithReboundPrefix() {
 1627   
 1628  1 Element parent = new Element("Test", "http://www.example.org");
 1629  1 Element child = new Element("child", "http://www.example.org");
 1630  1 parent.appendChild(child);
 1631   
 1632  1 XPathContext context = new XPathContext("pre", "http://www.example.com");
 1633  1 Nodes result = parent.query("child::pre:child", context);
 1634  1 assertEquals(0, result.size());
 1635   
 1636  1 context.addNamespace("pre", "http://www.example.org");
 1637  1 result = parent.query("child::pre:child", context);
 1638  1 assertEquals(1, result.size());
 1639  1 assertEquals(child, result.get(0));
 1640   
 1641    }
 1642   
 1643   
 1644  1 public void testNamespaceQueryWithUnboundPrefix() {
 1645   
 1646  1 Element parent = new Element("Test", "http://www.example.org");
 1647  1 Element child = new Element("child", "http://www.example.org");
 1648  1 parent.appendChild(child);
 1649   
 1650  1 XPathContext context = new XPathContext("not", "http://www.example.com");
 1651  1 try {
 1652  1 parent.query("child::pre:child", context);
 1653  0 fail("Queried with unbound prefix");
 1654    }
 1655    catch (XPathException success) {
 1656  1 assertNotNull(success.getMessage());
 1657  1 assertNotNull(success.getCause());
 1658    }
 1659   
 1660  1 try {
 1661  1 parent.query("child::pre:child");
 1662  0 fail("Queried with unbound prefix");
 1663    }
 1664    catch (XPathException success) {
 1665  1 assertNotNull(success.getMessage());
 1666  1 assertNotNull(success.getCause());
 1667    }
 1668   
 1669    }
 1670   
 1671   
 1672  1 public void testElementBasedNamespaceContext() {
 1673   
 1674  1 Element parent = new Element("Test", "http://www.example.org");
 1675  1 Element child = new Element("child", "http://www.example.org");
 1676  1 parent.appendChild(child);
 1677   
 1678  1 Element test = new Element("pre:test", "http://www.example.org");
 1679  1 XPathContext context = XPathContext.makeNamespaceContext(test);
 1680  1 Nodes result = parent.query("child::pre:child", context);
 1681  1 assertEquals(1, result.size());
 1682  1 assertEquals(child, result.get(0));
 1683   
 1684    }
 1685   
 1686   
 1687  1 public void testAttributeBasedNamespaceContext() {
 1688   
 1689  1 Element parent = new Element("Test", "http://www.example.org");
 1690  1 Element child = new Element("child", "http://www.example.org");
 1691  1 parent.appendChild(child);
 1692   
 1693  1 Element test = new Element("test");
 1694  1 test.addAttribute(new Attribute("pre:test", "http://www.example.org", "value"));
 1695  1 XPathContext context = XPathContext.makeNamespaceContext(test);
 1696  1 Nodes result = parent.query("child::pre:child", context);
 1697  1 assertEquals(1, result.size());
 1698  1 assertEquals(child, result.get(0));
 1699   
 1700    }
 1701   
 1702   
 1703  1 public void testAdditionalNamespaceBasedNamespaceContext() {
 1704   
 1705  1 Element parent = new Element("Test", "http://www.example.org");
 1706  1 Element child = new Element("child", "http://www.example.org");
 1707  1 parent.appendChild(child);
 1708   
 1709  1 Element test = new Element("test");
 1710  1 test.addNamespaceDeclaration("pre", "http://www.example.org");
 1711  1 XPathContext context = XPathContext.makeNamespaceContext(test);
 1712  1 Nodes result = parent.query("child::pre:child", context);
 1713  1 assertEquals(1, result.size());
 1714  1 assertEquals(child, result.get(0));
 1715   
 1716    }
 1717   
 1718   
 1719  1 public void testAncestorElementBasedNamespaceContext() {
 1720   
 1721  1 Element parent = new Element("Test", "http://www.example.org");
 1722  1 Element child = new Element("child", "http://www.example.org");
 1723  1 parent.appendChild(child);
 1724   
 1725  1 Element test = new Element("pre:test", "http://www.example.org");
 1726  1 Element testChild = new Element("testchild");
 1727  1 test.appendChild(testChild);
 1728  1 XPathContext context = XPathContext.makeNamespaceContext(testChild);
 1729  1 Nodes result = parent.query("child::pre:child", context);
 1730  1 assertEquals(1, result.size());
 1731  1 assertEquals(child, result.get(0));
 1732   
 1733    }
 1734   
 1735   
 1736  1 public void testAncestorAttributeBasedNamespaceContext() {
 1737   
 1738  1 Element parent = new Element("Test", "http://www.example.org");
 1739  1 Element child = new Element("child", "http://www.example.org");
 1740  1 parent.appendChild(child);
 1741   
 1742  1 Element test = new Element("test");
 1743  1 test.addAttribute(new Attribute("pre:test", "http://www.example.org", "value"));
 1744  1 Element testChild = new Element("testchild");
 1745  1 test.appendChild(testChild);
 1746  1 XPathContext context = XPathContext.makeNamespaceContext(testChild);
 1747  1 Nodes result = parent.query("child::pre:child", context);
 1748  1 assertEquals(1, result.size());
 1749  1 assertEquals(child, result.get(0));
 1750   
 1751    }
 1752   
 1753   
 1754  1 public void testAncestorAdditionalNamespaceBasedNamespaceContext() {
 1755   
 1756  1 Element parent = new Element("Test", "http://www.example.org");
 1757  1 Element child = new Element("child", "http://www.example.org");
 1758  1 parent.appendChild(child);
 1759   
 1760  1 Element test = new Element("test");
 1761  1 test.addNamespaceDeclaration("pre", "http://www.example.org");
 1762  1 Element testChild = new Element("testchild");
 1763  1 test.appendChild(testChild);
 1764  1 XPathContext context = XPathContext.makeNamespaceContext(testChild);
 1765  1 Nodes result = parent.query("child::pre:child", context);
 1766  1 assertEquals(1, result.size());
 1767  1 assertEquals(child, result.get(0));
 1768   
 1769    }
 1770   
 1771   
 1772  1 public void testPrefixedNamespaceQuery() {
 1773   
 1774  1 Element parent = new Element("a:Test", "http://www.example.org");
 1775  1 Element child = new Element("b:child", "http://www.example.org");
 1776  1 Attribute att = new Attribute("c:dog", "http://www.cafeconleche.org/", "test");
 1777  1 parent.appendChild(child);
 1778  1 child.addAttribute(att);
 1779   
 1780  1 XPathContext context = new XPathContext("pre", "http://www.example.org");
 1781  1 context.addNamespace("c", "http://www.cafeconleche.org/");
 1782  1 Nodes result = parent.query("child::pre:child", context);
 1783  1 assertEquals(1, result.size());
 1784  1 assertEquals(child, result.get(0));
 1785   
 1786  1 result = child.query("@c:*", context);
 1787  1 assertEquals(1, result.size());
 1788  1 assertEquals(att, result.get(0));
 1789   
 1790    }
 1791   
 1792   
 1793  1 public void testBradley() {
 1794   
 1795  1 Element element = new Element("root");
 1796  1 Text t1 = new Text("makes ");
 1797  1 Text t2 = new Text("a");
 1798  1 Text t3 = new Text(" good");
 1799  1 Text t4 = new Text(" point.");
 1800  1 Element child = new Element("someElement");
 1801  1 Text t5 = new Text(" Yes");
 1802  1 Text t6 = new Text(" he");
 1803  1 Text t7 = new Text(" does!");
 1804  1 element.appendChild(t1);
 1805  1 element.appendChild(t2);
 1806  1 element.appendChild(t3);
 1807  1 element.appendChild(t4);
 1808  1 element.appendChild(child);
 1809  1 element.appendChild(t5);
 1810  1 element.appendChild(t6);
 1811  1 element.appendChild(t7);
 1812   
 1813  1 Nodes result = element.query("./text()[contains(., 'o')]");
 1814  1 assertEquals(7, result.size());
 1815  1 assertEquals(t1, result.get(0));
 1816  1 assertEquals(t2, result.get(1));
 1817  1 assertEquals(t3, result.get(2));
 1818  1 assertEquals(t4, result.get(3));
 1819  1 assertEquals(t5, result.get(4));
 1820  1 assertEquals(t6, result.get(5));
 1821  1 assertEquals(t7, result.get(6));
 1822   
 1823   
 1824    }
 1825   
 1826   
 1827  1 public void testNamespaceQueryWithAdjacentTextNodes() {
 1828   
 1829  1 Element parent = new Element("Test", "http://www.example.org");
 1830  1 Element child = new Element("child", "http://www.example.org");
 1831  1 parent.appendChild(child);
 1832  1 child.appendChild("1");
 1833  1 child.appendChild("2");
 1834   
 1835  1 XPathContext context = new XPathContext("pre", "http://www.example.org");
 1836  1 Nodes result = parent.query("descendant::text()", context);
 1837  1 assertEquals(2, result.size());
 1838  1 assertEquals("1", result.get(0).getValue());
 1839  1 assertEquals("2", result.get(1).getValue());
 1840   
 1841    }
 1842   
 1843   
 1844  1 public void testNamespaceQueryWithoutPrefixMapping() {
 1845   
 1846  1 Element parent = new Element("Test", "http://www.example.org");
 1847  1 Element child = new Element("child", "http://www.example.org");
 1848  1 parent.appendChild(child);
 1849   
 1850  1 Nodes result = parent.query("child");
 1851  1 assertEquals(0, result.size());
 1852   
 1853    }
 1854   
 1855   
 1856  1 public void testAdjacentTextObjects() {
 1857   
 1858  1 Element parent = new Element("Test");
 1859  1 parent.appendChild("test");
 1860  1 parent.appendChild("again");
 1861   
 1862  1 Nodes result = parent.query("text()");
 1863  1 assertEquals(2, result.size());
 1864  1 assertEquals("test", result.get(0).getValue());
 1865  1 assertEquals("again", result.get(1).getValue());
 1866   
 1867    }
 1868   
 1869   
 1870  1 public void testQueryCrossesAdjacentTextObjects() {
 1871   
 1872  1 Element parent = new Element("Test");
 1873  1 parent.appendChild("test");
 1874  1 parent.appendChild("again");
 1875   
 1876  1 Nodes result = parent.query("node()[contains(., 'tag')]");
 1877  1 assertEquals(2, result.size());
 1878  1 assertEquals("test", result.get(0).getValue());
 1879  1 assertEquals("again", result.get(1).getValue());
 1880   
 1881    }
 1882   
 1883   
 1884    // According to section 5.7 of the XPath 1.0 spec,
 1885    // "As much character data as possible is grouped into each text
 1886    // node: a text node never has an immediately following or
 1887    // preceding sibling that is a text node."
 1888  1 public void testAdjacentTextNodes2() {
 1889   
 1890  1 Element parent = new Element("Test");
 1891  1 parent.appendChild("test");
 1892  1 parent.appendChild("again");
 1893   
 1894  1 Nodes result = parent.query("child::text()[1]");
 1895  1 assertEquals(2, result.size());
 1896  1 assertEquals("test", result.get(0).getValue());
 1897  1 assertEquals("again", result.get(1).getValue());
 1898   
 1899    }
 1900   
 1901   
 1902    // According to section 5.7 of the XPath 1.0 spec,
 1903    // "A text node always has at least one character of data."
 1904  1 public void testEmptyTextNodes() {
 1905   
 1906  1 Element parent = new Element("Test");
 1907  1 parent.appendChild("");
 1908   
 1909  1 Nodes result = parent.query("child::text()");
 1910  1 assertEquals(0, result.size());
 1911   
 1912    }
 1913   
 1914   
 1915  1 public void testEmptyTextFollowsNonEmptyText() {
 1916   
 1917  1 Element parent = new Element("parent");
 1918  1 Text empty = new Text("");
 1919  1 Text nonempty = new Text("value");
 1920  1 parent.appendChild(nonempty);
 1921  1 parent.appendChild(empty);
 1922  1 Nodes result = parent.query("node()");
 1923  1 assertEquals(2, result.size());
 1924   
 1925    }
 1926   
 1927   
 1928  1 public void testCountAdjacentEmptyAndNonEmptyTextNodes() {
 1929   
 1930  1 Element parent = new Element("parent");
 1931  1 Text empty = new Text("");
 1932  1 Text nonempty = new Text("value");
 1933  1 parent.appendChild(nonempty);
 1934  1 parent.appendChild(empty);
 1935   
 1936  1 Nodes result2 = parent.query("/*[count(node())=1]");
 1937  1 assertEquals(1, result2.size());
 1938  1 assertEquals(parent, result2.get(0));
 1939   
 1940  1 Nodes nodes1 = parent.query("node()[1]");
 1941  1 assertEquals(2, nodes1.size());
 1942  1 Nodes nodes2 = parent.query("node()[2]");
 1943  1 assertEquals(0, nodes2.size());
 1944   
 1945    }
 1946   
 1947   
 1948  1 public void testAdjacentEmptyAndNonEmptyTextNodes() {
 1949   
 1950  1 Element parent = new Element("parent");
 1951  1 Text empty = new Text("");
 1952  1 Text nonempty = new Text("value");
 1953  1 Text nonempty2 = new Text("value2");
 1954  1 parent.appendChild(empty);
 1955  1 parent.appendChild(nonempty);
 1956  1 parent.appendChild(nonempty2);
 1957   
 1958  1 Nodes result = parent.query("node()");
 1959  1 assertEquals(3, result.size());
 1960   
 1961  1 Nodes result2 = parent.query("/*[count(node())=1]");
 1962  1 assertEquals(1, result2.size());
 1963  1 assertEquals(parent, result2.get(0));
 1964   
 1965  1 Nodes nodes1 = parent.query("node()[1]");
 1966  1 assertEquals(3, nodes1.size());
 1967   
 1968  1 Nodes nodes2 = parent.query("node()[2]");
 1969  1 assertEquals(0, nodes2.size());
 1970   
 1971    }
 1972   
 1973   
 1974  1 public void testBadXPathExpression() {
 1975   
 1976  1 Element parent = new Element("Test");
 1977   
 1978  1 try {
 1979  1 parent.query("This is not an XPath expression");
 1980  0 fail("Allowed malformed query");
 1981    }
 1982    catch (XPathException success) {
 1983  1 assertNotNull(success.getMessage());
 1984    }
 1985   
 1986    }
 1987   
 1988   
 1989  1 public void testNaNEvaluatesToFalse() {
 1990   
 1991  1 Element root = new Element("root");
 1992  1 Document doc = new Document(root);
 1993   
 1994  1 Nodes result = doc.query("/*[boolean(0 div 0)]");
 1995  1 assertEquals(0, result.size());
 1996   
 1997    }
 1998   
 1999   
 2000    /* <body>
 2001    <p>
 2002    <span></span>
 2003    </p>
 2004    <div></div>
 2005    </body> */
 2006  1 public void testPrecedingAxis() {
 2007   
 2008  1 Element body = new Element("body");
 2009  1 Element p = new Element("p");
 2010  1 body.appendChild(p);
 2011  1 Element span = new Element("span");
 2012  1 p.appendChild(span);
 2013  1 Element div = new Element("div");
 2014  1 body.appendChild(div);
 2015   
 2016  1 Nodes result = div.query("preceding::*[1]");
 2017  1 assertEquals(1, result.size());
 2018  1 assertEquals(span, result.get(0));
 2019   
 2020    }
 2021   
 2022   
 2023  1 public void testRootNodeValueIsNonEmpty() {
 2024   
 2025  1 Element root = new Element("html");
 2026  1 Document doc = new Document(root);
 2027  1 root.appendChild("test");
 2028   
 2029  1 Nodes result = doc.query("/*[string(/) != '']");
 2030  1 assertEquals(1, result.size());
 2031  1 assertEquals(root, result.get(0));
 2032   
 2033    }
 2034   
 2035   
 2036  1 public void testContextPositionForParaentlessNodeIs1() {
 2037   
 2038  1 Element root = new Element("html");
 2039   
 2040  1 Nodes result = root.query("self::*[1]");
 2041  1 assertEquals(1, result.size());
 2042  1 assertEquals(root, result.get(0));
 2043   
 2044    }
 2045   
 2046   
 2047  1 public void testContextSizeForParaentlessNodeIs1() {
 2048   
 2049  1 Element root = new Element("html");
 2050   
 2051  1 Nodes result = root.query("self::*[last()=1]");
 2052  1 assertEquals(1, result.size());
 2053  1 assertEquals(root, result.get(0));
 2054   
 2055    }
 2056   
 2057   
 2058  1 public void testLastFunction() {
 2059   
 2060  1 Element root = new Element("html");
 2061  1 Element child1 = new Element("child1");
 2062  1 Element child2 = new Element("child2");
 2063  1 root.appendChild(child1);
 2064  1 root.appendChild(child2);
 2065  1 new Document(root);
 2066   
 2067  1 Nodes result = child2.query("self::*[position()=last()]");
 2068  1 assertEquals(1, result.size());
 2069  1 assertEquals(child2, result.get(0));
 2070   
 2071    }
 2072   
 2073   
 2074  1 public void testJaxen51() throws ParsingException, IOException {
 2075   
 2076  1 String data = "<root>\n <servlet-mapping>\n"
 2077    + " <servlet-name>DeviceInfoServlet</servlet-name>\n"
 2078    + " <url-pattern>/tools/*</url-pattern>\n"
 2079    + "</servlet-mapping>\n</root>";
 2080   
 2081  1 Builder builder = new Builder();
 2082  1 Document doc = builder.build(data, null);
 2083   
 2084  1 Nodes result = doc.query("//*[./../servlet-name = 'DeviceInfoServlet']");
 2085  1 assertEquals(2, result.size());
 2086   
 2087    }
 2088   
 2089   
 2090  1 public void testXPathNamespaceParentage()
 2091    throws ParsingException, IOException {
 2092   
 2093  1 String input = "<!DOCTYPE doc [\n"
 2094    + "<!ATTLIST e2 xml:space (default|preserve) 'preserve'>\n"
 2095    + "<!ATTLIST e3 id ID #IMPLIED>\n"
 2096    + "]>\n"
 2097    + "<doc xmlns=\"http://www.ietf.org\" xmlns:w3c=\"http://www.w3.org\">\n"
 2098    + " <e1>\n"
 2099    + " <e2 xmlns=\"\">\n"
 2100    + " <e3 id=\"E3\"/>\n"
 2101    + " </e2>\n"
 2102    + " </e1>\n"
 2103    + "</doc>";
 2104   
 2105  1 Document doc = (new Builder()).build(input, null);
 2106  1 String xpath = "(/*/* | /*/*/namespace::*)\n";
 2107  1 Nodes result = doc.query(xpath);
 2108  1 assertEquals(4, result.size());
 2109  1 Element parent = (Element) result.get(0);
 2110  1 for (int i = 1; i < 4; i++) {
 2111  3 Namespace namespace = (Namespace) result.get(i);
 2112  3 assertEquals(parent, namespace.getParent());
 2113    }
 2114   
 2115    }
 2116   
 2117   
 2118  1 public void testAttributesFollowElementsInDocumentOrder()
 2119    throws ParsingException, IOException {
 2120   
 2121  1 String input = "<document>\n"
 2122    + " <e1 a='b' c='d' e='f'>\n"
 2123    + " <e2>\n"
 2124    + " <e3 id=\"E3\"/>\n"
 2125    + " </e2>\n"
 2126    + " </e1>\n"
 2127    + "</document>";
 2128   
 2129  1 Document doc = (new Builder()).build(input, null);
 2130  1 String xpath = "(/*/* | /*/*/attribute::*)\n";
 2131  1 Nodes result = doc.query(xpath);
 2132  1 assertEquals(4, result.size());
 2133  1 Element parent = (Element) result.get(0);
 2134  1 for (int i = 1; i < 4; i++) {
 2135  3 Attribute attribute = (Attribute) result.get(i);
 2136  3 assertEquals(parent, attribute.getParent());
 2137    }
 2138   
 2139    }
 2140   
 2141   
 2142  1 public void testDoubleSlashIsIncorrect() {
 2143   
 2144  1 Element root = new Element("root", "http://www.example.org");
 2145  1 Document doc = new Document(root);
 2146  1 root.appendChild(new Element("child"));
 2147  1 root.appendChild("test");
 2148  1 root.addAttribute(new Attribute("test", "test"));
 2149   
 2150  1 try {
 2151  1 doc.query("//");
 2152  0 fail("Queried //");
 2153    }
 2154    catch (XPathException success) {
 2155  1 assertNotNull(success.getMessage());
 2156    }
 2157   
 2158    }
 2159   
 2160   
 2161  1 public void testDoubleSlashIsIncorrect2() {
 2162   
 2163  1 Element root = new Element("root", "http://www.example.org");
 2164  1 Document doc = new Document(root);
 2165  1 root.appendChild(new Element("child"));
 2166  1 root.appendChild("test");
 2167  1 root.addAttribute(new Attribute("test", "test"));
 2168   
 2169  1 try {
 2170  1 doc.query("// ");
 2171  0 fail("Queried // ");
 2172    }
 2173    catch (XPathException success) {
 2174  1 assertNotNull(success.getMessage());
 2175    }
 2176   
 2177    }
 2178   
 2179   
 2180  1 public void testWhiteSpaceIsAllowedBetweenTokens() {
 2181   
 2182  1 Element root = new Element("root", "http://www.example.org");
 2183  1 Document doc = new Document(root);
 2184  1 root.appendChild(new Element("child"));
 2185  1 root.appendChild("test");
 2186  1 root.addAttribute(new Attribute("test", "test"));
 2187   
 2188  1 Nodes nodes = doc.query("// a");
 2189  1 assertEquals(0, nodes.size());
 2190   
 2191    }
 2192   
 2193   
 2194    /* public void testMassimo() throws ParsingException, IOException {
 2195   
 2196    Builder builder = new Builder();
 2197    Document doc = builder.build("http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml");
 2198    Element root = doc.getRootElement();
 2199    Element input_1 = root.getFirstChildElement("document_1");
 2200    Element input_2 = root.getFirstChildElement("document_2");
 2201   
 2202    Nodes queries = root.query("child::query[starts-with('@id', 'Q')]");
 2203    for (int i = 0; i < queries.size(); i++) {
 2204    Element query = (Element) queries.get(i);
 2205    String xpath = query.getFirstChildElement("syntax").getValue();
 2206    Nodes actual = input_1.query(xpath);
 2207    Elements expected = query.getChildElements();
 2208    }
 2209   
 2210    } */
 2211   
 2212   
 2213  1 public void testJaxenIntegrationTest() throws ParsingException, IOException {
 2214   
 2215  1 Builder builder = new Builder();
 2216  1 Document testDoc = builder.build(
 2217    "http://cvs.jaxen.codehaus.org/viewrep/~raw,r=HEAD/jaxen/jaxen/xml/test/tests.xml");
 2218  1 Elements documents = testDoc.getRootElement().getChildElements("document");
 2219  1 for (int i = 0; i < documents.size(); i++) {
 2220  34 Element documentElement = documents.get(i);
 2221  34 String url = documentElement.getAttributeValue("url");
 2222  34 Document source = builder.build(
 2223    "http://cvs.jaxen.codehaus.org/viewrep/~raw,r=HEAD/jaxen/jaxen/"
 2224    + url);
 2225  34 Elements contextElements = documentElement.getChildElements("context");
 2226  34 for (int j = 0; j < contextElements.size(); j++) {
 2227  61 Element contextElement = contextElements.get(j);
 2228   
 2229    // skip tests that use variables
 2230    // because XOM doesn't support variables in
 2231    // XPath expressions
 2232  1 if (queryUsesVars(contextElement)) continue;
 2233   
 2234  60 String xpath = contextElement.getAttributeValue("select");
 2235  60 XPathContext namespaces = getXPathContext(contextElement);
 2236  60 Node context = source.query(xpath).get(0);
 2237   
 2238    // process counts
 2239  60 Elements tests = contextElement.getChildElements("test");
 2240  60 for (int k = 0; k < tests.size(); k++) {
 2241  137 Element test = tests.get(k);
 2242   
 2243  137 String select = test.getAttributeValue("select");
 2244  137 Attribute countAttribute = test.getAttribute("count");
 2245  137 int count = -1;
 2246  137 if (countAttribute != null) {
 2247  131 count = Integer.parseInt(countAttribute.getValue());
 2248    }
 2249   
 2250  137 boolean exceptional = false;
 2251  137 String exception = test.getAttributeValue("exception");
 2252  137 if ("true".equals(exception)) {
 2253  8 exceptional = true;
 2254    }
 2255   
 2256  137 if (exceptional) {
 2257  8 try {
 2258  8 context.query(select, namespaces);
 2259  0 fail("Evaluated " + select);
 2260    }
 2261    catch (XPathException success) {
 2262  8 assertNotNull(success.getMessage());
 2263    }
 2264    }
 2265    else {
 2266  129 try {
 2267  129 Nodes results = context.query(select, namespaces);
 2268  122 if (count != -1) {
 2269  116 assertEquals(select, count, results.size());
 2270    }
 2271  122 Elements valueOfs = test.getChildElements("valueOf");
 2272  122 for (int v = 0; v < valueOfs.size(); v++) {
 2273  13 Element vo = valueOfs.get(v);
 2274  13 checkValueOf(results.get(0), vo, namespaces);
 2275    }
 2276    }
 2277    catch (XPathException ex) {
 2278  7 if (ex.getMessage().equalsIgnoreCase("XPath error: No such function document")
 2279    || ex.getMessage().equalsIgnoreCase("XPath error: No such function evaluate")) {
 2280  7 continue;
 2281    }
 2282  0 throw ex;
 2283    }
 2284   
 2285    }
 2286    }
 2287   
 2288    // process valueOfs
 2289  60 Elements valueOfs = contextElement.getChildElements("valueOf");
 2290  60 for (int k = 0; k < valueOfs.size(); k++) {
 2291  137 checkValueOf(context, valueOfs.get(k), namespaces);
 2292    }
 2293   
 2294    }
 2295    }
 2296    }
 2297   
 2298   
 2299  150 private void checkValueOf(Node context, Element valueOf, XPathContext namespaces) {
 2300   
 2301  150 String select = valueOf.getAttributeValue("select");
 2302  150 try {
 2303  150 Nodes nodes = context.query(select, namespaces);
 2304  29 String result = nodes.get(0).getValue();
 2305  29 assertEquals(valueOf.getValue(), result);
 2306    }
 2307    catch (XPathTypeException ex) {
 2308  111 assertNotNull(ex.getMessage());
 2309    }
 2310    catch (XPathException ex) {
 2311  10 if (ex.getMessage().equalsIgnoreCase("XPath error: No such function document")
 2312    || ex.getMessage().equalsIgnoreCase("XPath error: No such function upper-case")
 2313    || ex.getMessage().equalsIgnoreCase("XPath error: No such function lower-case")
 2314    || ex.getMessage().equalsIgnoreCase("XPath error: No such function ends-with")
 2315    ) {
 2316  10 return;
 2317    }
 2318  0 throw ex;
 2319    }
 2320   
 2321    }
 2322   
 2323   
 2324  60 private XPathContext getXPathContext(Element contextElement) {
 2325   
 2326  60 XPathContext context = new XPathContext();
 2327  60 for (int i = 0; i < contextElement.getNamespaceDeclarationCount(); i++) {
 2328  69 String prefix = contextElement.getNamespacePrefix(i);
 2329  69 if (! "".equals(prefix)) {
 2330  9 context.addNamespace(prefix, contextElement.getNamespaceURI(prefix));
 2331    }
 2332    }
 2333  60 return context;
 2334    }
 2335   
 2336   
 2337  61 private boolean queryUsesVars(Element testElement) {
 2338   
 2339  61 for (int i = 0; i < testElement.getAttributeCount(); i++) {
 2340  62 Attribute a = testElement.getAttribute(i);
 2341  62 if ("http://jaxen.org/test-harness/var".equals(a.getNamespaceURI())) {
 2342  1 return true;
 2343    }
 2344    }
 2345  60 return false;
 2346    }
 2347   
 2348   
 2349  1 public void testTextChildInPredicate() {
 2350   
 2351  1 Element item = new Element("item");
 2352  1 Document doc = new Document(item);
 2353  1 Element name = new Element("name");
 2354  1 name.appendChild("a");
 2355  1 item.appendChild(name);
 2356  1 Element value = new Element("value");
 2357  1 value.appendChild("b");
 2358  1 item.appendChild(value);
 2359  1 Nodes result = doc.query("/item[name/text()='a']/value");
 2360  1 assertEquals(1, result.size());
 2361  1 assertEquals("b", result.get(0).getValue());
 2362   
 2363    }
 2364   
 2365   
 2366  1 public void testSimpleTextChildInPredicate() {
 2367   
 2368  1 Element item = new Element("item");
 2369  1 Document doc = new Document(item);
 2370  1 item.appendChild("a");
 2371  1 Nodes result = doc.query("/item[text()='a']");
 2372  1 assertEquals(1, result.size());
 2373   
 2374    }
 2375   
 2376   
 2377  1 public void testPrecedingAxisInDocumentOrder() {
 2378   
 2379  1 Element root = new Element("root");
 2380  1 new Document(root);
 2381   
 2382  1 Element a = new Element("a");
 2383  1 root.appendChild(a);
 2384  1 Element b = new Element("b");
 2385  1 root.appendChild(b);
 2386  1 Element c = new Element("c");
 2387  1 a.appendChild(c);
 2388   
 2389  1 Nodes result = b.query("preceding::*");
 2390  1 assertEquals(2, result.size());
 2391  1 assertEquals(a, result.get(0));
 2392  1 assertEquals(c, result.get(1));
 2393   
 2394    }
 2395   
 2396   
 2397  1 public void testAttributeWithUnderscore() {
 2398   
 2399  1 Element a = new Element("a");
 2400  1 Attribute foo = new Attribute("_foo", "bar");
 2401  1 a.addAttribute(foo);
 2402  1 Nodes results = a.query("//@_foo");
 2403  1 assertEquals(1, results.size());
 2404  1 assertEquals(foo, results.get(0));
 2405   
 2406    }
 2407   
 2408   
 2409    }