From 57bf603b7332db86c39680d16b78f94a904daf46 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Mon, 1 Aug 2022 16:37:22 +0000 Subject: [PATCH] 8289948: Improve test coverage for XPath functions: Node Set Functions Reviewed-by: joehw --- .../jaxp/unittest/xpath/XPathAnyTypeTest.java | 20 +- .../unittest/xpath/XPathExpAnyTypeTest.java | 14 +- .../unittest/xpath/XPathNodeSetFnTest.java | 222 ++++++++++++++++++ .../jaxp/unittest/xpath/XPathTestBase.java | 133 ++++++++--- 4 files changed, 344 insertions(+), 45 deletions(-) create mode 100644 test/jaxp/javax/xml/jaxp/unittest/xpath/XPathNodeSetFnTest.java diff --git a/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAnyTypeTest.java b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAnyTypeTest.java index 47b350f3532..27badf40864 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAnyTypeTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAnyTypeTest.java @@ -90,7 +90,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test04(XPath xpath, Document doc) throws XPathExpressionException { - boolean result1 = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc, Boolean.class); + boolean result1 = xpath.evaluateExpression("boolean" + + "(/Customers/Customer[@id=\"x3\"])", doc, Boolean.class); assertTrue(result1); } @@ -121,7 +122,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test07(XPath xpath, Document doc) throws XPathExpressionException { - String result1 = xpath.evaluateExpression("string(/Customers/Customer[@id=3]/Phone/text())", doc, String.class); + String result1 = xpath.evaluateExpression("string(/Customers/Customer" + + "[@id=\"x3\"]/Phone/text())", doc, String.class); assertTrue(result1.equals("3333333333")); } @@ -142,7 +144,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test09(XPath xpath, Document doc) throws XPathExpressionException { - Node n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, Node.class); + Node n = xpath.evaluateExpression("/Customers/Customer[@id=\"x3\"]", + doc, Node.class); assertEquals(n.getLocalName(), "Customer"); } @@ -151,7 +154,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class) public void test10(XPath xpath, Document doc) throws XPathExpressionException { - File n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, File.class); + File n = xpath.evaluateExpression("/Customers/Customer[@id=\"x3\"]", + doc, File.class); } /* @@ -159,7 +163,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test11(XPath xpath, Document doc) throws XPathExpressionException { - XPathEvaluationResult result = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc); + XPathEvaluationResult result = xpath.evaluateExpression( + "boolean(/Customers/Customer[@id=\"x3\"])", doc); verifyResult(result, true); } @@ -178,7 +183,7 @@ public class XPathAnyTypeTest extends XPathTestBase { @Test(dataProvider = "document") public void test13(XPath xpath, Document doc) throws XPathExpressionException { XPathEvaluationResult result = xpath.evaluateExpression( - "string(/Customers/Customer[@id=3]/Phone/text())", doc, XPathEvaluationResult.class); + "string(/Customers/Customer[@id=\"x3\"]/Phone/text())", doc, XPathEvaluationResult.class); verifyResult(result, "3333333333"); } @@ -196,7 +201,8 @@ public class XPathAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test15(XPath xpath, Document doc) throws XPathExpressionException { - XPathEvaluationResult result = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc); + XPathEvaluationResult result = xpath.evaluateExpression( + "/Customers/Customer[@id=\"x3\"]", doc); verifyResult(result, "Customer"); } } diff --git a/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpAnyTypeTest.java b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpAnyTypeTest.java index 4502083efa6..964d83d34f0 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpAnyTypeTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathExpAnyTypeTest.java @@ -76,7 +76,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test04(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])"); + XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=\"x3\"])"); boolean result1 = exp.evaluateExpression(doc, Boolean.class); assertTrue(result1); } @@ -99,7 +99,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test06(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())"); + XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=\"x3\"]/Phone/text())"); String result1 = exp.evaluateExpression(doc, String.class); assertTrue(result1.equals("3333333333")); } @@ -122,7 +122,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test08(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]"); + XPathExpression exp = xpath.compile("/Customers/Customer[@id=\"x3\"]"); Node n = exp.evaluateExpression(doc, Node.class); assertEquals(n.getLocalName(), "Customer"); } @@ -132,7 +132,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class) public void test09(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]"); + XPathExpression exp = xpath.compile("/Customers/Customer[@id=\"x3\"]"); File n = exp.evaluateExpression(doc, File.class); } @@ -141,7 +141,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test10(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])"); + XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=\"x3\"])"); XPathEvaluationResult result = exp.evaluateExpression(doc); verifyResult(result, true); } @@ -161,7 +161,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test12(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())"); + XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=\"x3\"]/Phone/text())"); XPathEvaluationResult result = exp.evaluateExpression(doc, XPathEvaluationResult.class); verifyResult(result, "3333333333"); } @@ -181,7 +181,7 @@ public class XPathExpAnyTypeTest extends XPathTestBase { */ @Test(dataProvider = "document") public void test14(XPath xpath, Document doc) throws XPathExpressionException { - XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]"); + XPathExpression exp = xpath.compile("/Customers/Customer[@id=\"x3\"]"); XPathEvaluationResult result = exp.evaluateExpression(doc); verifyResult(result, "Customer"); } diff --git a/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathNodeSetFnTest.java b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathNodeSetFnTest.java new file mode 100644 index 00000000000..b39378a90f6 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathNodeSetFnTest.java @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package xpath; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import javax.xml.xpath.*; + +/* + * @test + * @bug 8289948 + * @library /javax/xml/jaxp/unittest + * @run testng xpath.XPathNodeSetFnTest + * @summary Tests the XPath Node Set Functions + */ +public class XPathNodeSetFnTest extends XPathTestBase { + + private static final Document doc = getDtdDocument(); + + /* + * DataProvider for testing the id function. + * Data columns: + * see parameters of the test "testIdFn" + */ + @DataProvider(name = "idExpTestCases") + public Object[][] getIdExp() { + return new Object[][]{ + {"id('x3')", "Customer_x3"}, + {"id('x1 x2 x3')[3]", "Customer_x3"}, + {"id('x1 | x2 | x3')[3]", "Customer_x3"}, + {"id('x')", "Email_x"}, + {"id(//Customer[3]/@id)", "Customer_x3"}, + {"id(//*[.='123@xyz.com']/@id)", "Email_x"}, + }; + } + + /* + * DataProvider for testing the count function. + * Data columns: + * see parameters of the test "testCountFn" + */ + @DataProvider(name = "countExpTestCases") + public Object[][] getCountExp() { + return new Object[][]{ + {"count(//Customer)", CUSTOMERS}, + {"count(//@id)", ID_ATTRIBUTES}, + {"count(//Customer/@id)", CUSTOMERS}, + {"count(//@*)", ID_ATTRIBUTES + FOO_ID_ATTRIBUTES}, + {"count(//*)", + ROOT + CUSTOMERS + FOO_CUSTOMERS + + (CUSTOMERS + FOO_CUSTOMERS) * + CUSTOMER_ELEMENTS}, + {"count(//*[@id])", ID_ATTRIBUTES}, + {"count(./*)", ROOT}, + {"count(//Customer[1]/following::*)", + CUSTOMERS - 1 + FOO_CUSTOMERS + + (CUSTOMERS - 1 + FOO_CUSTOMERS) * + CUSTOMER_ELEMENTS}, + {"count(//Customer[1]/following-sibling::*)", + CUSTOMERS - 1 + FOO_CUSTOMERS}, + {"count(//Customer[3]/preceding::*)", + CUSTOMERS - 1 + (CUSTOMERS - 1) * CUSTOMER_ELEMENTS}, + {"count(//Customer[3]/preceding-sibling::*)", CUSTOMERS - 1}, + {"count(//Customer[1]/ancestor::*)", ROOT}, + {"count(//Customer[1]/ancestor-or-self::*)", ROOT + 1}, + {"count(//Customer[1]/descendant::*)", CUSTOMER_ELEMENTS}, + {"count(//Customer[1]/descendant-or-self::*)", + CUSTOMER_ELEMENTS + 1}, + {"count(//Customer/node())", + ID_ATTRIBUTES + CUSTOMERS * CUSTOMER_ELEMENTS}, + }; + } + + /* + * DataProvider for testing the position function. + * Data columns: + * see parameters of the test "testPositionFn" + */ + @DataProvider(name = "positionExpTestCases") + public Object[][] getPositionExp() { + return new Object[][]{ + {"//Customer[position()=1]", "Customer_x1"}, + {"//Customer[position()=last()]", "Customer_x3"}, + {"//Customer[position()>1 and position()"; - static final String rawXML - = "" - + "" - + " " + static final String DTD = """ + + + + + + + + + + + + ]> + + """; + + static final String RAW_XML + = "" + + " " + " name1" + " 1111111111" - + " 123@xyz.com" + + " 123@xyz.com" + "
" + " 1111 111st ave" + " The City" + " The State" + "
" + "
" - + " " - + " name1" + + " " + + " name2" + " 2222222222" - + " 123@xyz.com" + + " 123@xyz.com" + "
" + " 2222 222nd ave" + " The City" + " The State" + "
" + "
" - + " " - + " name1" + + " " + + " name3" + " 3333333333" - + " 123@xyz.com" + + " 123@xyz.com" + "
" + " 3333 333rd ave" + " The City" + " The State" + "
" + "
" + + " " + + " name1" + + " 1111111111" + + " 123@xyz.com" + + " " + + " 1111 111st ave" + + " The City" + + " The State" + + " " + + " " + "
"; + // Number of root element. + final int ROOT = 1; + // Number of Customer elements. + final int CUSTOMERS = 3; + // Number of id attributes. + final int ID_ATTRIBUTES = 6; + // Number of child elements of Customer. + final int CUSTOMER_ELEMENTS = 7; + // Number of Customer in the foo namespace. + final int FOO_CUSTOMERS = 1; + // Number of id attributes in the foo namespace. + final int FOO_ID_ATTRIBUTES = 2; + + /** + * Returns a {@link org.w3c.dom.Document} for XML with DTD. + * @return a DOM Document + * @throws RuntimeException if any error occurred during document + * initialization. + */ + public static Document getDtdDocument() throws RuntimeException { + return documentOf(DECLARATION + DTD + RAW_XML); + } + + /** + * Returns a {@link org.w3c.dom.Document} for raw XML. + * @return a DOM Document + * @throws RuntimeException if any error occurred during document + * initialization. + */ + public static Document getDocument() throws RuntimeException { + return documentOf(DECLARATION + RAW_XML); + } + + /** + * Returns a {@link org.w3c.dom.Document} for input XML string. + * @param xml the input xml string. + * @return a DOM Document. + * @throws RuntimeException if any error occurred during document + * initialization. + */ + public static Document documentOf(String xml) throws RuntimeException { + try { + var dBF = DocumentBuilderFactory.newInstance(); + dBF.setValidating(false); + dBF.setNamespaceAware(true); + return dBF.newDocumentBuilder().parse( + new ByteArrayInputStream(xml.getBytes("UTF-8"))); + } catch (Exception e) { + System.out.println("Exception while initializing XML document"); + throw new RuntimeException(e.getMessage()); + } + } + void verifyResult(XPathEvaluationResult result, Object expected) { switch (result.type()) { case BOOLEAN: @@ -126,13 +202,13 @@ class XPathTestBase { public Object[][] getInvalidNumericTypes() { XPath xpath = XPathFactory.newInstance().newXPath(); return new Object[][]{{xpath, AtomicInteger.class}, - {xpath, AtomicInteger.class}, - {xpath, AtomicLong.class}, - {xpath, BigDecimal.class}, - {xpath, BigInteger.class}, - {xpath, Byte.class}, - {xpath, Float.class}, - {xpath, Short.class} + {xpath, AtomicInteger.class}, + {xpath, AtomicLong.class}, + {xpath, BigDecimal.class}, + {xpath, BigInteger.class}, + {xpath, Byte.class}, + {xpath, Float.class}, + {xpath, Short.class} }; } @@ -140,13 +216,8 @@ class XPathTestBase { * DataProvider: XPath and Document objects */ @DataProvider(name = "document") - public Object[][] getDocument() throws Exception { - DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance(); - dBF.setValidating(false); - dBF.setNamespaceAware(true); - Document doc = dBF.newDocumentBuilder().parse( - new ByteArrayInputStream(rawXML.getBytes("UTF-8"))); - + public Object[][] getDocuments() throws RuntimeException { + Document doc = getDocument(); return new Object[][]{{XPathFactory.newInstance().newXPath(), doc}}; } }