1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package javax.xml.xpath.ptests;
  25 
  26 import java.io.IOException;
  27 import java.io.InputStream;
  28 import java.nio.file.Files;
  29 import java.nio.file.Path;
  30 import java.nio.file.Paths;
  31 import javax.xml.XMLConstants;
  32 import javax.xml.namespace.QName;
  33 import javax.xml.parsers.DocumentBuilderFactory;
  34 import javax.xml.parsers.ParserConfigurationException;
  35 import javax.xml.xpath.XPath;
  36 import static javax.xml.xpath.XPathConstants.BOOLEAN;
  37 import static javax.xml.xpath.XPathConstants.NODE;
  38 import static javax.xml.xpath.XPathConstants.NODESET;
  39 import static javax.xml.xpath.XPathConstants.NUMBER;
  40 import static javax.xml.xpath.XPathConstants.STRING;
  41 import javax.xml.xpath.XPathExpressionException;
  42 import javax.xml.xpath.XPathFactory;
  43 import static javax.xml.xpath.ptests.XPathTestConst.XML_DIR;
  44 import static jaxp.library.JAXPTestUtilities.failUnexpected;
  45 import static org.testng.Assert.assertEquals;
  46 import org.testng.annotations.BeforeTest;
  47 import org.testng.annotations.Test;
  48 import org.w3c.dom.Attr;
  49 import org.w3c.dom.Document;
  50 import org.w3c.dom.NodeList;
  51 import org.xml.sax.InputSource;
  52 import org.xml.sax.SAXException;
  53 
  54 /**
  55  * Class containing the test cases for XPathExpression API.
  56  */
  57 public class XPathExpressionTest {
  58     /**
  59      * Document object for testing XML file.
  60      */
  61     private Document document;
  62 
  63     /**
  64      * A XPath for evaluation environment and expressions.
  65      */
  66     private XPath xpath;
  67 
  68     /**
  69      * A QName using default name space.
  70      */
  71     private static final QName TEST_QNAME = new QName(XMLConstants.XML_NS_URI, "");
  72 
  73     /**
  74      * XML File Path.
  75      */
  76     private static final Path XML_PATH = Paths.get(XML_DIR + "widgets.xml");
  77 
  78     /**
  79      * An expression name which locate at "/widgets/widget[@name='a']/@quantity"
  80      */
  81     private static final String EXPRESSION_NAME_A = "/widgets/widget[@name='a']/@quantity";
  82 
  83     /**
  84      * An expression name which locate at "/widgets/widget[@name='b']/@quantity"
  85      */
  86     private static final String EXPRESSION_NAME_B = "/widgets/widget[@name='b']/@quantity";
  87 
  88     /**
  89      * Create Document object and XPath object for every time
  90      * @throws ParserConfigurationException If the factory class cannot be
  91      *                                      loaded, instantiated
  92      * @throws SAXException If any parse errors occur.
  93      * @throws IOException If operation on xml file failed.
  94      */
  95     @BeforeTest
  96     public void setup() throws ParserConfigurationException, SAXException, IOException {
  97         document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(XML_PATH.toFile());
  98         xpath = XPathFactory.newInstance().newXPath();
  99     }
 100 
 101     /**
 102      * Test for evaluate(java.lang.Object item,QName returnType)throws
 103      * XPathExpressionException.
 104      */
 105     @Test
 106     public void testCheckXPathExpression01() {
 107         try {
 108             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 109                     evaluate(document, STRING), "6");
 110         } catch (XPathExpressionException ex) {
 111             failUnexpected(ex);
 112         }
 113     }
 114 
 115     /**
 116      * evaluate(java.lang.Object item,QName returnType) throws NPE if input
 117      * source is null.
 118      */
 119     @Test(expectedExceptions = NullPointerException.class)
 120     public void testCheckXPathExpression02() {
 121         try {
 122             xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING);
 123         } catch (XPathExpressionException ex) {
 124             failUnexpected(ex);
 125         }
 126     }
 127 
 128     /**
 129      * evaluate(java.lang.Object item,QName returnType) throws NPE if returnType
 130      * is null.
 131      */
 132     @Test(expectedExceptions = NullPointerException.class)
 133     public void testCheckXPathExpression03() {
 134         try {
 135             xpath.compile(EXPRESSION_NAME_A).evaluate(document, null);
 136         } catch (XPathExpressionException ex) {
 137             failUnexpected(ex);
 138         }
 139     }
 140 
 141     /**
 142      * Test for method evaluate(java.lang.Object item,QName returnType).If a
 143      * request is made to evaluate the expression in the absence of a context
 144      * item, simple expressions, such as "1+1", can be evaluated.
 145      */
 146     @Test
 147     public void testCheckXPathExpression04() {
 148         try {
 149             assertEquals(xpath.compile("1+1").evaluate(document, STRING), "2");
 150         } catch (XPathExpressionException ex) {
 151             failUnexpected(ex);
 152         }
 153     }
 154 
 155     /**
 156      * evaluate(java.lang.Object item,QName returnType) throws IAE If returnType
 157      * is not one of the types defined in XPathConstants.
 158      */
 159     @Test(expectedExceptions = IllegalArgumentException.class)
 160     public void testCheckXPathExpression05() {
 161         try {
 162             xpath.compile(EXPRESSION_NAME_A).evaluate(document, TEST_QNAME);
 163         } catch (XPathExpressionException ex) {
 164             failUnexpected(ex);
 165         }
 166     }
 167 
 168     /**
 169      * evaluate(java.lang.Object item,QName returnType) return correct boolean
 170      * value if returnType is Boolean.
 171      */
 172     @Test
 173     public void testCheckXPathExpression06() {
 174         try {
 175             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 176                 evaluate(document, BOOLEAN), true);
 177         } catch (XPathExpressionException ex) {
 178             failUnexpected(ex);
 179         }
 180     }
 181 
 182     /**
 183      * evaluate(java.lang.Object item,QName returnType) return correct boolean
 184      * value if returnType is Boolean.
 185      */
 186     @Test
 187     public void testCheckXPathExpression07() {
 188         try {
 189             assertEquals(xpath.compile(EXPRESSION_NAME_B).
 190                 evaluate(document, BOOLEAN), false);
 191         } catch (XPathExpressionException ex) {
 192             failUnexpected(ex);
 193         }
 194     }
 195 
 196     /**
 197      * evaluate(java.lang.Object item,QName returnType) return correct number
 198      * value when return type is Double.
 199      */
 200     @Test
 201     public void testCheckXPathExpression08() {
 202         try {
 203             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 204                 evaluate(document, NUMBER), 6d);
 205         } catch (XPathExpressionException ex) {
 206             failUnexpected(ex);
 207         }
 208     }
 209 
 210     /**
 211      * evaluate(java.lang.Object item,QName returnType) evaluate an attribute
 212      * value which returnType is Node.
 213      */
 214     @Test
 215     public void testCheckXPathExpression09() {
 216         try {
 217             Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A).
 218                     evaluate(document, NODE);
 219             assertEquals(attr.getValue(), "6");
 220         } catch (XPathExpressionException ex) {
 221             failUnexpected(ex);
 222         }
 223     }
 224 
 225     /**
 226      * evaluate(java.lang.Object item,QName returnType) evaluate an attribute
 227      * value which returnType is NodeList.
 228      */
 229     @Test
 230     public void testCheckXPathExpression10() {
 231         try {
 232             NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A).
 233                     evaluate(document, NODESET);
 234             Attr attr = (Attr) nodeList.item(0);
 235             assertEquals(attr.getValue(), "6");
 236         } catch (XPathExpressionException ex) {
 237             failUnexpected(ex);
 238         }
 239     }
 240 
 241     /**
 242      * Test for evaluate(java.lang.Object item) when returnType is left off of
 243      * the XPath.evaluate method, all expressions are evaluated to a String
 244      * value.
 245      */
 246     @Test
 247     public void testCheckXPathExpression11() {
 248         try {
 249             assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document), "6");
 250         } catch (XPathExpressionException ex) {
 251             failUnexpected(ex);
 252         }
 253     }
 254 
 255     /**
 256      * evaluate(java.lang.Object item) throws NPE if expression is null.
 257      */
 258     @Test(expectedExceptions = NullPointerException.class)
 259     public void testCheckXPathExpression12() {
 260         try {
 261             xpath.compile(null).evaluate(document);
 262         } catch (XPathExpressionException ex) {
 263             failUnexpected(ex);
 264         }
 265     }
 266 
 267     /**
 268      * evaluate(java.lang.Object item) when a request is made to evaluate the
 269      * expression in the absence of a context item, simple expressions, such as
 270      * "1+1", can be evaluated.
 271      */
 272     @Test
 273     public void testCheckXPathExpression13() {
 274         try {
 275             assertEquals(xpath.compile("1+1").evaluate(document), "2");
 276         } catch (XPathExpressionException ex) {
 277             failUnexpected(ex);
 278         }
 279     }
 280 
 281     /**
 282      * evaluate(java.lang.Object item) throws NPE if document is null.
 283      */
 284     @Test(expectedExceptions = NullPointerException.class)
 285     public void testCheckXPathExpression14() {
 286         try {
 287             xpath.compile(EXPRESSION_NAME_A).evaluate(null);
 288         } catch (XPathExpressionException ex) {
 289             failUnexpected(ex);
 290         }
 291     }
 292 
 293     /**
 294      * valuate(InputSource source) return a string value if return type is
 295      * String.
 296      */
 297     @Test
 298     public void testCheckXPathExpression15() {
 299         try (InputStream is = Files.newInputStream(XML_PATH)) {
 300             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 301                     evaluate(new InputSource(is)), "6");
 302         } catch (XPathExpressionException | IOException ex) {
 303             failUnexpected(ex);
 304         }
 305     }
 306 
 307     /**
 308      * evaluate(InputSource source) throws NPE if input source is null.
 309      */
 310     @Test(expectedExceptions = NullPointerException.class)
 311     public void testCheckXPathExpression16() {
 312         try {
 313             xpath.compile(EXPRESSION_NAME_A).evaluate(null);
 314         } catch (XPathExpressionException ex) {
 315             failUnexpected(ex);
 316         }
 317     }
 318 
 319     /**
 320      * evaluate(InputSource source) throws NPE if expression is null
 321      */
 322     @Test(expectedExceptions = NullPointerException.class)
 323     public void testCheckXPathExpression17() {
 324         try (InputStream is = Files.newInputStream(XML_PATH)) {
 325             xpath.compile(null).evaluate(new InputSource(is));
 326         } catch (XPathExpressionException | IOException ex) {
 327             failUnexpected(ex);
 328         }
 329     }
 330 
 331     /**
 332      * evaluate(InputSource source) throws XPathExpressionException if
 333      * returnType is String junk characters.
 334      *
 335      * @throws XPathExpressionException
 336      */
 337     @Test(expectedExceptions = XPathExpressionException.class)
 338     public void testCheckXPathExpression18() throws XPathExpressionException {
 339         try (InputStream is = Files.newInputStream(XML_PATH)) {
 340             xpath.compile("-*&").evaluate(new InputSource(is));
 341         } catch (IOException ex) {
 342             failUnexpected(ex);
 343         }
 344     }
 345 
 346     /**
 347      * evaluate(InputSource source) throws XPathExpressionException if
 348      * expression is a blank string " ".
 349      *
 350      * @throws XPathExpressionException
 351      */
 352     @Test(expectedExceptions = XPathExpressionException.class)
 353     public void testCheckXPathExpression19() throws XPathExpressionException {
 354         try (InputStream is = Files.newInputStream(XML_PATH)) {
 355             xpath.compile(" ").evaluate(new InputSource(is));
 356         } catch (IOException ex) {
 357             failUnexpected(ex);
 358         }
 359     }
 360 
 361     /**
 362      * Test for evaluate(InputSource source,QName returnType) returns a string
 363      * value if returnType is String.
 364      */
 365     @Test
 366     public void testCheckXPathExpression20() {
 367         try (InputStream is = Files.newInputStream(XML_PATH)) {
 368             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 369                 evaluate(new InputSource(is), STRING), "6");
 370         } catch (XPathExpressionException | IOException ex) {
 371             failUnexpected(ex);
 372         }
 373     }
 374 
 375     /**
 376      * evaluate(InputSource source,QName returnType) throws NPE if source is
 377      * null.
 378      */
 379     @Test(expectedExceptions = NullPointerException.class)
 380     public void testCheckXPathExpression21() {
 381         try {
 382             xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING);
 383         } catch (XPathExpressionException ex) {
 384             failUnexpected(ex);
 385         }
 386     }
 387 
 388     /**
 389      * evaluate(InputSource source,QName returnType) throws NPE if expression is
 390      * null.
 391      */
 392     @Test(expectedExceptions = NullPointerException.class)
 393     public void testCheckXPathExpression22() {
 394         try (InputStream is = Files.newInputStream(XML_PATH)) {
 395             xpath.compile(null).evaluate(new InputSource(is), STRING);
 396         } catch (XPathExpressionException | IOException ex) {
 397             failUnexpected(ex);
 398         }
 399     }
 400 
 401     /**
 402      * evaluate(InputSource source,QName returnType) throws NPE if returnType is
 403      * null.
 404      */
 405     @Test(expectedExceptions = NullPointerException.class)
 406     public void testCheckXPathExpression23() {
 407         try (InputStream is = Files.newInputStream(XML_PATH)) {
 408             xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), null);
 409         } catch (XPathExpressionException | IOException ex) {
 410             failUnexpected(ex);
 411         }
 412     }
 413 
 414     /**
 415      * evaluate(InputSource source,QName returnType) throws
 416      * XPathExpressionException if expression is junk characters.
 417      *
 418      * @throws XPathExpressionException
 419      */
 420     @Test(expectedExceptions = XPathExpressionException.class)
 421     public void testCheckXPathExpression24() throws XPathExpressionException {
 422         try (InputStream is = Files.newInputStream(XML_PATH)) {
 423             xpath.compile("-*&").evaluate(new InputSource(is), STRING);
 424         } catch (IOException ex) {
 425             failUnexpected(ex);
 426         }
 427     }
 428 
 429     /**
 430      * evaluate(InputSource source,QName returnType) throws
 431      * XPathExpressionException if expression is blank " ".
 432      *
 433      * @throws XPathExpressionException
 434      */
 435     @Test(expectedExceptions = XPathExpressionException.class)
 436     public void testCheckXPathExpression25() throws XPathExpressionException {
 437         try (InputStream is = Files.newInputStream(XML_PATH)) {
 438             xpath.compile(" ").evaluate(new InputSource(is), STRING);
 439         } catch (IOException ex) {
 440             failUnexpected(ex);
 441         }
 442     }
 443 
 444     /**
 445      * evaluate(InputSource source,QName returnType) throws
 446      * IllegalArgumentException if returnType is not one of the types defined
 447      * in XPathConstants.
 448      */
 449     @Test(expectedExceptions = IllegalArgumentException.class)
 450     public void testCheckXPathExpression26() {
 451         try (InputStream is = Files.newInputStream(XML_PATH)) {
 452             xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), TEST_QNAME);
 453         } catch (XPathExpressionException | IOException ex) {
 454             failUnexpected(ex);
 455         }
 456     }
 457 
 458     /**
 459      * evaluate(InputSource source,QName returnType) return a correct boolean
 460      * value if returnType is Boolean.
 461      */
 462     @Test
 463     public void testCheckXPathExpression27() {
 464         try (InputStream is = Files.newInputStream(XML_PATH)) {
 465             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 466                 evaluate(new InputSource(is), BOOLEAN), true);
 467         } catch (XPathExpressionException | IOException ex) {
 468             failUnexpected(ex);
 469         }
 470     }
 471 
 472     /**
 473      * evaluate(InputSource source,QName returnType) return a correct boolean
 474      * value if returnType is Boolean.
 475      */
 476     @Test
 477     public void testCheckXPathExpression28() {
 478         try (InputStream is = Files.newInputStream(XML_PATH)) {
 479             assertEquals(xpath.compile(EXPRESSION_NAME_B).
 480                 evaluate(new InputSource(is), BOOLEAN), false);
 481         } catch (XPathExpressionException | IOException ex) {
 482             failUnexpected(ex);
 483         }
 484     }
 485 
 486     /**
 487      * evaluate(InputSource source,QName returnType) return a correct number
 488      * value if returnType is Number.
 489      */
 490     @Test
 491     public void testCheckXPathExpression29() {
 492         try (InputStream is = Files.newInputStream(XML_PATH)) {
 493             assertEquals(xpath.compile(EXPRESSION_NAME_A).
 494                 evaluate(new InputSource(is), NUMBER), 6d);
 495         } catch (XPathExpressionException | IOException ex) {
 496             failUnexpected(ex);
 497         }
 498     }
 499 
 500     /**
 501      * Test for evaluate(InputSource source,QName returnType) returns a node if
 502      * returnType is Node.
 503      */
 504     @Test
 505     public void testCheckXPathExpression30() {
 506         try (InputStream is = Files.newInputStream(XML_PATH)) {
 507             Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A).
 508                 evaluate(new InputSource(is), NODE);
 509             assertEquals(attr.getValue(), "6");
 510         } catch (XPathExpressionException | IOException ex) {
 511             failUnexpected(ex);
 512         }
 513     }
 514 
 515     /**
 516      * Test for evaluate(InputSource source,QName returnType) return a node list
 517      * if returnType is NodeList.
 518      */
 519     @Test
 520     public void testCheckXPathExpression31() {
 521         try (InputStream is = Files.newInputStream(XML_PATH)) {
 522             NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A).
 523                 evaluate(new InputSource(is), NODESET);
 524             assertEquals(((Attr) nodeList.item(0)).getValue(), "6");
 525         } catch (XPathExpressionException | IOException  ex) {
 526             failUnexpected(ex);
 527         }
 528     }
 529 }