dmitri 2002/10/12 20:01:03 Modified: jxpath/src/test/org/apache/commons/jxpath/ri/model/jdom JDOMModelTest.java jxpath/src/test/org/apache/commons/jxpath/ri/model/dom DOMModelTest.java Added: jxpath/src/test/org/apache/commons/jxpath/ri/model XMLModelTestCase.java jxpath/src/test/org/apache/commons/jxpath JXPathTest.java Removed: jxpath/src/test/org/apache/commons/jxpath/ri/model XMLModelTest.java jxpath/src/test/org/apache/commons/jxpath JXPathTestCase.java Log: Added tests for the new functionalities and bug fixes Renamed classes for uniformity Revision Changes Path 1.1 jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/XMLModelTestCase.java Index: XMLModelTestCase.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/XMLModelTestCase.java,v 1.1 2002/10/13 03:01:03 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/10/13 03:01:03 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath.ri.model; import java.lang.reflect.InvocationTargetException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.w3c.dom.*; import java.util.*; import java.lang.reflect.*; import org.apache.commons.jxpath.*; import org.apache.commons.jxpath.util.*; import org.apache.commons.jxpath.ri.*; import org.apache.commons.jxpath.ri.parser.*; import org.apache.commons.jxpath.ri.model.*; import org.apache.commons.jxpath.ri.model.beans.*; import org.apache.commons.jxpath.ri.axes.*; import org.apache.commons.jxpath.ri.compiler.*; import org.apache.commons.jxpath.ri.compiler.Expression; import org.apache.commons.jxpath.xml.*; import java.beans.*; /** * Abstract superclass for pure XPath 1.0. Subclasses * apply the same XPaths to contexts using different models: * DOM, JDOM etc. * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/10/13 03:01:03 $ */ public abstract class XMLModelTestCase extends TestCase { private boolean enabled = true; /** * Construct a new instance of this test case. * * @param name Name of the test case */ public XMLModelTestCase(String name) { super(name); } protected abstract String getModel(); protected DocumentContainer createDocumentContainer(){ return new DocumentContainer( getClass().getClassLoader(). getResource("org/apache/commons/jxpath/Vendor.xml"), getModel()); } protected JXPathContext createContext(){ JXPathContext context = JXPathContext.newContext(createDocumentContainer()); context.setFactory(new TestFactory()); return context; } // ------------------------------------------------ Individual Test Methods public void testDocumentOrder(){ if (!enabled){ return; } JXPathContext context = createContext(); testDocumentOrder(context, "vendor/location", "vendor/location/address/street", -1); testDocumentOrder(context, "vendor/location[@id = '100']", "vendor/location[@id = '101']", -1); testDocumentOrder(context, "vendor//price:amount", "vendor/location", 1); } private void testDocumentOrder(JXPathContext context, String path1, String path2, int expected){ NodePointer np1 = (NodePointer)context.getPointer(path1); NodePointer np2 = (NodePointer)context.getPointer(path2); try { int res = np1.compareTo(np2); if (res < 0){ res = -1; } else if (res > 0){ res = 1; } assertEquals("Comparing paths '" + path1 + "' and '" + path2 + "'", expected, res); } catch (Exception ex){ System.err.println("Comparing paths '" + path1 + "' and '" + path2 + "'"); ex.printStackTrace(); } } /** * Test JXPathContext.createPath() with various arguments */ public void testCreatePath(){ if (!enabled){ return; } JXPathContext context = createContext(); // Create a DOM element testCreatePath(context, "/vendor[1]/location[3]", ""); // Create a DOM element with contents testCreatePath(context, "/vendor[1]/location[3]/address/street", "", "/vendor[1]/location[3]/address[1]/street[1]"); // Create a DOM attribute testCreatePath(context, "/vendor[1]/location[2]/@manager", ""); testCreatePath(context, "/vendor[1]/location[1]/@name", "local"); } private void testCreatePath(JXPathContext context, String path, Object value){ testCreatePath(context, path, value, path); } private void testCreatePath(JXPathContext context, String path, Object value, String expectedPath){ Pointer ptr = null; try { ptr = context.createPath(path); } catch(JXPathException ex){ ex.getException().printStackTrace(); } assertEquals("Pointer <" + path + ">", expectedPath, ptr.asPath()); assertEquals("Created <" + path + ">", value, ptr.getValue()); } /** * Test JXPath.createPathAndSetValue() with various arguments */ public void testCreatePathAndSetValue(){ if (!enabled){ return; } JXPathContext context = createContext(); // Create a XML element testCreatePathAndSetValue(context, "vendor/location[3]", ""); // Create a DOM element with contents testCreatePathAndSetValue(context, "vendor/location[3]/address/street", "Lemon Circle"); // Create an attribute testCreatePathAndSetValue(context, "vendor/location[2]/@manager", "John Doe"); testCreatePathAndSetValue(context, "vendor/location[1]/@manager", "John Doe"); testCreatePathAndSetValue(context, "vendor/product/name/attribute::price:language", "English"); } private void testCreatePathAndSetValue(JXPathContext context, String path, Object value){ Pointer ptr = context.createPathAndSetValue(path, value); assertTrue("Pointer <" + path + ">", ptr != null); assertEquals("Created <" + path + ">", value, context.getValue(path)); assertEquals("Pointer value <" + path + ">", value, ptr.getValue()); } /** * Test JXPathContext.removePath() with various arguments */ public void testRemovePath(){ if (!enabled){ return; } JXPathContext context = createContext(); // Remove XML nodes context.removePath("vendor/location[@id = '101']//street/text()"); assertEquals("Remove DOM text", "", context.getValue("vendor/location[@id = '101']//street")); context.removePath("vendor/location[@id = '101']//street"); assertEquals("Remove DOM element", new Double(0), context.getValue("count(vendor/location[@id = '101']//street)")); context.removePath("vendor/location[@id = '100']/@name"); assertEquals("Remove DOM attribute", new Double(0), context.getValue("count(vendor/location[@id = '100']/@name)")); } public void testID(){ if (!enabled){ return; } JXPathContext context = createContext(); context.setIdentityManager(new IdentityManager(){ public Pointer getPointerByID(JXPathContext context, String id){ NodePointer ptr = (NodePointer)context.getPointer("/"); ptr = ptr.getValuePointer(); // Unwrap the container return ptr.getPointerByID(context, id); } }); context.setKeyManager(new KeyManager(){ public Pointer getPointerByKey(JXPathContext context, String key, String value){ return NodePointer.newNodePointer(null, "42", null); } }); assertEquals("Test ID", "Tangerine Drive", context.getValue("id(101)//street")); assertEquals("Test ID Path", "id('101')/address[1]/street[1]", context.getPointer("id(101)//street").asPath()); context.setLenient(true); assertEquals("Test ID Path Null", "id(105)/address/street", context.getPointer("id(105)/address/street").asPath()); } public void testModel() throws Exception { if (!enabled){ return; } DocumentContainer docCtr = createDocumentContainer(); JXPathContext context = createContext(); context.getVariables().declareVariable("document", docCtr.getValue()); context.getVariables().declareVariable("container", docCtr); testXPaths(context, dom_tests, false); } private void testXPaths(JXPathContext ctx, XP xpath_tests[], boolean ignorePath) throws Exception{ Exception exception = null; for (int i=0; i < xpath_tests.length; i++) { try { Object actual; // System.err.println("XPATH: " + xpath_tests[i].xpath); if (xpath_tests[i].path){ if (ignorePath){ actual = xpath_tests[i].expected; } else { if (xpath_tests[i].eval){ Iterator it = ctx.iteratePointers(xpath_tests[i].xpath); List paths = new ArrayList(); while (it.hasNext()){ paths.add(((Pointer)it.next()).asPath()); } actual = paths; } else { ctx.setLenient(xpath_tests[i].lenient); actual = ctx.getPointer(xpath_tests[i].xpath).asPath(); } } } else { if (xpath_tests[i].eval){ ArrayList list = new ArrayList(); Iterator it = ctx.iterate(xpath_tests[i].xpath); while (it.hasNext()){ list.add(it.next()); } actual = list; } else { ctx.setLenient(xpath_tests[i].lenient); actual = ctx.getValue(xpath_tests[i].xpath); ctx.setLenient(false); } } assertEquals("Evaluating <" + xpath_tests[i].xpath + ">", xpath_tests[i].expected, actual); } catch (Exception ex){ System.err.println("Exception during <" + xpath_tests[i].xpath + ">"); ex.printStackTrace(); exception = ex; } if (exception != null){ throw exception; } } // Make sure that location paths are properly constructed for (int i=0; i < xpath_tests.length; i++) { try { if (!xpath_tests[i].path && !xpath_tests[i].eval){ Pointer ptr = ctx.getPointer(xpath_tests[i].xpath); Pointer test = ctx.getPointer(ptr.asPath()); assertEquals("Testing pointer for <" + xpath_tests[i].xpath + ">", ptr.asPath(), test.asPath()); } } catch (Exception ex){ System.err.println("Exception during pointer test <" + xpath_tests[i].xpath + ">"); ex.printStackTrace(); } } } private static class XP { public String xpath; public Object expected; public boolean eval; public boolean path; public boolean lenient; public XP(String xpath, Object expected, boolean eval, boolean path, boolean lenient){ this.xpath = xpath; this.expected = expected; this.eval = eval; this.path = path; this.lenient = lenient; } } private static XP test(String xpath, Object expected){ return new XP(xpath, expected, false, false, false); } private static XP testLenient(String xpath, Object expected){ return new XP(xpath, expected, false, false, true); } private static XP testEval(String xpath, Object expected){ return new XP(xpath, expected, true, false, false); } private static XP testPath(String xpath, Object expected){ return new XP(xpath, expected, false, true, true); } private static XP testEvalPath(String xpath, Object expected){ return new XP(xpath, expected, true, true, false); } private static List list(Object o1){ List list = new ArrayList(); list.add(o1); return list; } private static List list(Object o1, Object o2){ List list = new ArrayList(); list.add(o1); list.add(o2); return list; } static final XP[] dom_tests = new XP[]{ test("vendor/location/address/street", "Orchard Road"), test("vendor/location[2]/address/street", "Tangerine Drive"), test("vendor/location/address/city", "Fruit Market"), test("//street", "Orchard Road"), test("local-name(//street/..)", "address"), test("number(vendor/location/employeeCount)", new Double(10)), test("vendor/location/employeeCount + 1", new Double(11)), test("vendor/location/employeeCount and true()", Boolean.TRUE), test("vendor/location[.//employeeCount = 10]/following-sibling::location//street", "Tangerine Drive"), testPath("vendor/location[.//employeeCount = 10]/following-sibling::location//street", "/vendor[1]/location[2]/address[1]/street[1]"), testPath("//location[2]/preceding-sibling::location//street", "/vendor[1]/location[1]/address[1]/street[1]"), test("vendor/location/@id", "100"), testPath("vendor/location/@id", "/vendor[1]/location[1]/@id"), testEval("vendor/location/@id", list("100", "101")), test("vendor/product/price:amount", "45.95"), test("namespace-uri(vendor/product/price:amount)", "priceNS"), test("local-name(vendor/product/price:amount)", "amount"), test("name(vendor/product/price:amount)", "priceNS:amount"), test("vendor/product/prix", "934.99"), test("vendor/product/prix/namespace::price", "priceNS"), testPath("vendor/product/prix/namespace::price", "/vendor[1]/product[1]/prix[1]/namespace::price"), test("count(vendor/product/namespace::*)", new Double(3)), test("name(vendor/product/prix/namespace::price)", "priceNS:price"), test("local-name(vendor/product/prix/namespace::price)", "price"), test("vendor/product/price:amount/@price:discount", "10%"), test("vendor/product/value:amount/@value:discount", "10%"), test("namespace-uri(vendor/product/price:amount/@price:discount)", "priceNS"), test("local-name(vendor/product/price:amount/@price:discount)", "discount"), test("name(vendor/product/price:amount/@price:discount)", "priceNS:discount"), test("vendor/product/price:amount/@discount", "20%"), test("namespace-uri(vendor/product/price:amount/@discount)", ""), test("local-name(vendor/product/price:amount/@discount)", "discount"), test("name(vendor/product/price:amount/@discount)", "discount"), test("vendor/product/price:sale/saleEnds/ancestor::price:sale/saleEnds", "never"), test("vendor/product/price:sale/ancestor-or-self::price:sale/saleEnds", "never"), test("vendor/product/price:sale/saleEnds/ancestor::price:*" + "/saleEnds", "never"), test("count(vendor/product/price:*)", new Double(2)), test("count(vendor/product/value:*)", new Double(2)), test("count(vendor/product/*)", new Double(2)), testEval("vendor/product/price:amount/@price:*", list("10%")), testEval("vendor/product/price:amount/@*", list("20%")), test("count(//price:*)", new Double(2)), test("vendor/product/price:sale/saleEnds/parent::price:*" + "/saleEnds", "never"), test("//location/following::price:sale/saleEnds", "never"), test("//price:sale/self::price:sale/saleEnds", "never"), testLenient("//price:sale/self::x/saleEnds", null), test("//product/comment()", "We are not buying this product, ever"), test("//product/text()[. != '']", "We love this product."), testPath("//product/text()", "/vendor[1]/product[1]/text()[1]"), test("//product/processing-instruction()", "do not show anybody"), test("//product/processing-instruction('report')", "average only"), testPath("//product/processing-instruction('report')", "/vendor[1]/product[1]/processing-instruction('report')[1]"), test("name(//product/processing-instruction()[1])", "security"), test("//product/prix/@xml:lang", "fr"), test("//product/prix[lang('fr')]", "934.99"), test("//product/price:sale[lang('en')]/saleEnds", "never"), test("vendor/location/@manager", ""), testLenient("vendor/location/@missing", null), test("count(vendor/location[1]/@*)", new Double(3)), test("vendor/location[@id='101']//street", "Tangerine Drive"), test("$document/vendor/location[1]//street", "Orchard Road"), testPath("$document/vendor/location[1]//street", "$document/vendor[1]/location[1]/address[1]/street[1]"), test("$document/vendor//street", "Orchard Road"), test("$container/vendor//street", "Orchard Road"), test("$container//street", "Orchard Road"), testPath("$container//street", "$container/vendor[1]/location[1]/address[1]/street[1]"), testEval("vendor/contact/following::location//street", list("Orchard Road", "Tangerine Drive")), }; } 1.1 jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/JXPathTest.java Index: JXPathTest.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/JXPathTest.java,v 1.1 2002/10/13 03:01:03 dmitri Exp $ * $Revision: 1.1 $ * $Date: 2002/10/13 03:01:03 $ * * ==================================================================== * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2001, Plotnix, Inc, * <http://www.plotnix.com/>. * For more information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.commons.jxpath; import java.lang.reflect.InvocationTargetException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.w3c.dom.*; import java.util.*; import java.lang.reflect.*; import org.apache.commons.jxpath.util.*; import org.apache.commons.jxpath.ri.*; import org.apache.commons.jxpath.ri.parser.*; import org.apache.commons.jxpath.ri.model.*; import org.apache.commons.jxpath.ri.model.beans.*; import org.apache.commons.jxpath.ri.axes.*; import org.apache.commons.jxpath.ri.compiler.*; import org.apache.commons.jxpath.ri.compiler.Expression; import org.apache.commons.jxpath.xml.*; import java.beans.*; /** * <p> * Test Case for the JXPath class. The majority of these tests use * instances of the TestBean class, so be sure to update the tests if you * change the characteristics of that class. * </p> * * <p> * Note that the tests are dependant upon the static aspects * (such as array sizes...) of the TestBean.java class, so ensure * that all changes to TestBean are reflected here. * </p> * * @author Dmitri Plotnikov * @version $Revision: 1.1 $ $Date: 2002/10/13 03:01:03 $ */ public class JXPathTest extends TestCase { private static boolean combineTests = false; private static boolean enabled = true; /** * Exercises this test case only */ public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } // ---------------------------------------------------- Instance Variables /** * The test bean for each test. */ protected TestBean bean = null; // ---------------------------------------------------------- Constructors /** * Construct a new instance of this test case. * * @param name Name of the test case */ public JXPathTest(String name) { super(name); } // -------------------------------------------------- Overall Test Methods /** * Set up instance variables required by this test case. */ public void setUp() { bean = new TestBean(); } /** * Return the tests included in this test suite. */ public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(JXPathTest.class); if (combineTests && enabled){ suite.addTestSuite(org.apache.commons.jxpath.ri.axes.SimplePathInterpreterTest.class); suite.addTestSuite(org.apache.commons.jxpath.ri.model.dom.DOMModelTest.class); suite.addTestSuite(org.apache.commons.jxpath.ri.model.jdom.JDOMModelTest.class); } return suite; } /** * Tear down instance variables required by this test case. */ public void tearDown() { bean = null; } // ------------------------------------------------ Individual Test Methods /** * Test property iterators, the core of the graph traversal engine */ public void testIndividualIterators(){ if (!enabled){ return; } // testIndividual(0, 0, true, false, 3); testIndividual(+1, 0, true, false, 0); testIndividual(-1, 0, true, false, 4); testIndividual(0, -1, true, true, 4); testIndividual(+1, -1, true, true, 4); testIndividual(-1, -1, true, true, 0); testIndividual(0, 1, true, false, 2); testIndividual(0, 1, true, true, 1); testIndividual(0, 0, false, false, 4); testIndividual(0, 0, false, true, 4); } private void testIndividual(int relativePropertyIndex, int offset, boolean useStartLocation, boolean reverse, int expected){ PropertyOwnerPointer root = (PropertyOwnerPointer)NodePointer.newNodePointer(new QName(null, "root"), bean, Locale.getDefault()); NodeIterator it; if (useStartLocation){ PropertyPointer holder = root.getPropertyPointer(); holder.setPropertyIndex(relativeProperty(holder, relativePropertyIndex)); holder.setIndex(offset); it = root.childIterator(new NodeNameTest(new QName(null, "integers")), reverse, holder); } else { it = root.childIterator(new NodeNameTest(new QName(null, "integers")), reverse, null); } int size = 0; while(it.setPosition(it.getPosition() + 1)){ size++; } assertEquals("ITERATIONS: Individual, relativePropertyIndex=" + relativePropertyIndex + ", offset=" + offset + ", useStartLocation=" + useStartLocation + ", reverse=" + reverse, expected, size); } public void testMultipleIterators(){ if (!enabled){ return; } testMultiple(0, 0, true, false, 20); testMultiple(3, 0, true, false, 16); testMultiple(3, -1, true, true, 8); testMultiple(3, 0, true, true, 4); testMultiple(0, 0, false, false, 21); testMultiple(0, 0, false, true, 21); testMultiple(3, 1, true, false, 15); testMultiple(3, 3, true, false, 13); } private void testMultiple(int propertyIndex, int offset, boolean useStartLocation, boolean reverse, int expected){ PropertyOwnerPointer root = (PropertyOwnerPointer)NodePointer.newNodePointer(new QName(null, "root"), bean, Locale.getDefault()); NodeIterator it; if (useStartLocation){ PropertyPointer holder = root.getPropertyPointer(); holder.setPropertyIndex(propertyIndex); holder.setIndex(offset); it = root.childIterator(null, reverse, holder); } else { it = root.childIterator(null, reverse, null); } int size = 0; while(it.setPosition(it.getPosition() + 1)){ // System.err.println("LOC: " + it.getCurrentNodePointer()); size++; } assertEquals("ITERATIONS: Multiple, propertyIndex=" + propertyIndex + ", offset=" + offset + ", useStartLocation=" + useStartLocation + ", reverse=" + reverse, expected, size); } private int relativeProperty(PropertyPointer holder, int offset){ String[] names = holder.getPropertyNames(); for (int i = 0; i < names.length; i++){ if (names[i].equals("integers")){ return i + offset; } } return -1; } /** * Test JXPath.getValue() with various arguments */ public void testGetValue(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(bean); testGetValue(context, "2+2", new Double(4.0)); testGetValue(context, "boolean", Boolean.FALSE); testGetValue(context, "substring(boolean, 1,2)", "fa"); // 'fa'lse testGetValue(context, "int*2", new Double(2.0)); testGetValue(context, "integers[1]", new Integer(1)); testGetValue(context, "nestedBean", bean.getNestedBean()); testGetValue(context, "nestedBean/boolean", Boolean.FALSE); testGetValue(context, "object/name", "Name 5"); testGetValue(context, "objects[1]", new Integer(1)); testGetValue(context, "map/Key1", "Value 1"); testGetValue(context, "beans[name = 'Name 1']", bean.getBeans()[0]); testGetValue(context, ".[1]/int", new Integer(1)); // testGetValue(context, "id('foo')", new Integer(1)); // testGetValue(context, "key('foo', 'bar')", new Integer(1)); testGetValue(context, "integers[1]", new Double(1), Double.class); testGetValue(context, "2 + 3", "5.0", String.class); testGetValue(context, "2 + 3", Boolean.TRUE, boolean.class); testGetValue(context, "'true'", Boolean.TRUE, Boolean.class); Map tm = new Hashtable(); tm.put("bar", "zz"); bean.getMap().put("foo", new Map[]{tm, tm}); bean.getMap().put("biz", tm); testGetValue(context, "map/foo[2]/bar/../bar", "zz"); testGetValue(context, "map[@name='biz'][@name='bar']", "zz"); boolean exception = false; try { testGetValue(context, "'foo'", null, Date.class); } catch(Exception ex){ exception = true; } assertTrue("Type conversion exception", exception); } public void testGetPointer(){ // if (!enabled){ // return; // } JXPathContext context = JXPathContext.newContext(createTestBeanWithDOM()); NodePointer pointer = (NodePointer)context.getPointer("@int"); assertEquals("GetPointer <" + "@int" + ">", "/@int", pointer.toString()); pointer = (NodePointer)context.getPointer("vendor/location/@id"); assertEquals("GetPointer <" + "vendor/location/@id" + ">", "/vendor/location[1]/@id", pointer.toString()); } /** * Test JXPath.iterate() with various arguments */ public void testIterateArray(){ if (!enabled){ return; } Map map = new HashMap(); map.put("foo", new String[]{"a", "b", "c"}); JXPathContext context = JXPathContext.newContext(map); Iterator it = context.iterate("foo"); List actual = new ArrayList(); while (it.hasNext()){ actual.add(it.next()); } assertEquals("Iterating <" + "foo" + ">", list("a", "b", "c"), actual); } public void testIteratePointersArray(){ if (!enabled){ return; } Map map = new HashMap(); map.put("foo", new String[]{"a", "b", "c"}); JXPathContext context = JXPathContext.newContext(map); Iterator it = context.iteratePointers("foo"); List actual = new ArrayList(); while (it.hasNext()){ Pointer ptr = (Pointer)it.next(); actual.add(context.getValue(ptr.asPath())); } assertEquals("Iterating pointers <" + "foo" + ">", list("a", "b", "c"), actual); } public void testIteratePointersArrayElementWithVariable(){ if (!enabled){ return; } Map map = new HashMap(); map.put("foo", new String[]{"a", "b", "c"}); JXPathContext context = JXPathContext.newContext(map); context.getVariables().declareVariable("x", new Integer(2)); Iterator it = context.iteratePointers("foo[$x]"); List actual = new ArrayList(); while (it.hasNext()){ Pointer ptr = (Pointer)it.next(); actual.add(context.getValue(ptr.asPath())); } assertEquals("Iterating pointers <" + "foo" + ">", list("b"), actual); } public void testIteratePropertyArrayWithHasNext(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(bean); Iterator it = context.iteratePointers("/integers"); List actual = new ArrayList(); while(it.hasNext()){ actual.add(((Pointer)it.next()).asPath()); } assertEquals("Iterating 'hasNext'/'next'<" + "/integers" + ">", list("/integers[1]", "/integers[2]", "/integers[3]", "/integers[4]"), actual); } public void testIteratePropertyArrayWithoutHasNext(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(bean); Iterator it = context.iteratePointers("/integers"); List actual = new ArrayList(); for (int i = 0; i < 4; i++){ actual.add(it.next().toString()); } assertEquals("Iterating 'next'<" + "/integers" + ">", list("/integers[1]", "/integers[2]", "/integers[3]", "/integers[4]"), actual); } public void testIterateVector(){ if (!enabled){ return; } Map map = new HashMap(); Vector vec = new Vector(); vec.add(new HashMap()); vec.add(new HashMap()); map.put("vec", vec); JXPathContext context = JXPathContext.newContext(map); Iterator it = context.iteratePointers("/vec"); List actual = new ArrayList(); while(it.hasNext()){ actual.add(((Pointer)it.next()).asPath()); } assertEquals("Iterating 'hasNext'/'next'<" + "/vec" + ">", list("/.[@name='vec'][1]", "/.[@name='vec'][2]"), actual); } public void testIterateAndSet(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(new TestBean()); Iterator it = context.iteratePointers("beans/int"); int i = 5; while (it.hasNext()){ NodePointer pointer = (NodePointer)it.next(); pointer.setValue(new Integer(i++)); } it = context.iteratePointers("beans/int"); List actual = new ArrayList(); while (it.hasNext()){ actual.add(((Pointer)it.next()).getValue()); } assertEquals("Iterating <" + "beans/int" + ">", list(new Integer(5), new Integer(6)), actual); } /** * Test JXPath.getValue() with variables */ public void testVariables(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(bean.getBeans()); context.getVariables().declareVariable("x", new Double(7.0)); context.getVariables().declareVariable("y", null); context.getVariables().declareVariable("z", bean); context.getVariables().declareVariable("t", new String[]{"a", "b"}); context.getVariables().declareVariable("m", bean.getMap()); testGetValue(context, "$x + 3", new Double(10.0)); testGetValue(context, "$y", null); testGetValue(context, "$y + 1", new Double(1.0)); boolean exception = false; try { testGetValue(context, "$none", null); } catch (Exception ex){ exception = true; } assertTrue("Evaluating '$none', expected exception - did not get it", exception); testGetValue(context, "$z/int", new Integer(1)); testGetValue(context, "$z/integers[$x - 5]", new Integer(2)); testGetValue(context, ".", bean.getBeans()); // testGetValue(context, ".[2]/name", "Name 2"); // TBD: is this even legal? testGetValue(context, "$t[2]", "b"); testGetValue(context, "$m/Key1", "Value 1"); } private void testGetValue(JXPathContext context, String xpath, Object expected) { Object actual = context.getValue(xpath); assertEquals("Evaluating <" + xpath + ">", expected, actual); CompiledExpression expr = context.compile(xpath); actual = expr.getValue(context); assertEquals("Evaluating CE <" + xpath + ">", expected, actual); } private void testGetValue(JXPathContext context, String xpath, Object expected, Class requiredType) { Object actual = context.getValue(xpath, requiredType); assertEquals("Evaluating <" + xpath + ">", expected, actual); CompiledExpression expr = context.compile(xpath); actual = expr.getValue(context, requiredType); assertEquals("Evaluating CE <" + xpath + ">", expected, actual); } /** * Test JXPath.eval() with various arguments */ public void testEval(){ if (enabled){ JXPathContext context = JXPathContext.newContext(bean); testEval(context, "integers[position()<3]", Arrays.asList(new Integer[]{new Integer(1), new Integer(2)})); } } private void testEval(JXPathContext context, String xpath, Object expected) { Iterator it = context.iterate(xpath); ArrayList actual = new ArrayList(); while (it.hasNext()){ actual.add(it.next()); } assertEquals("Evaluating <" + xpath + ">", expected, actual); CompiledExpression expr = context.compile(xpath); it = expr.iterate(context); actual = new ArrayList(); while (it.hasNext()){ actual.add(it.next()); } assertEquals("Evaluating CE <" + xpath + ">", expected, actual); } public void testContextDependency(){ if (enabled){ testContextDependency("1", false); testContextDependency("$x", false); testContextDependency("/foo", false); testContextDependency("foo", true); testContextDependency("/foo[3]", false); testContextDependency("/foo[$x]", false); testContextDependency("/foo[bar]", true); testContextDependency("3 + 5", false); testContextDependency("test:func(3, 5)", true); testContextDependency("test:func(3, foo)", true); } } public void testContextDependency(String xpath, boolean expected){ Expression expr = (Expression)Parser.parseExpression(xpath, new TreeCompiler()); assertEquals("Evaluating <" + xpath + ">", expected, expr.isContextDependent()); } public void testDocumentOrder(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(bean); testDocumentOrder(context, "boolean", "int", -1); testDocumentOrder(context, "integers[1]", "integers[2]", -1); testDocumentOrder(context, "integers[1]", "integers[1]", 0); testDocumentOrder(context, "nestedBean/int", "nestedBean", 1); testDocumentOrder(context, "nestedBean/int", "nestedBean/strings", -1); testDocumentOrder(context, "nestedBean/int", "object/int", -1); context = JXPathContext.newContext(createTestBeanWithDOM()); testDocumentOrder(context, "vendor/location", "vendor/location/address/street", -1); testDocumentOrder(context, "vendor/location[@id = '100']", "vendor/location[@id = '101']", -1); testDocumentOrder(context, "vendor//price:amount", "vendor/location", 1); // testDocumentOrder(context, "nonexistent//foo", "vendor/location", 1); // Will throw an exception } private void testDocumentOrder(JXPathContext context, String path1, String path2, int expected){ NodePointer np1 = (NodePointer)context.getPointer(path1); NodePointer np2 = (NodePointer)context.getPointer(path2); try { int res = np1.compareTo(np2); if (res < 0){ res = -1; } else if (res > 0){ res = 1; } assertEquals("Comparing paths '" + path1 + "' and '" + path2 + "'", expected, res); } catch (Exception ex){ System.err.println("Comparing paths '" + path1 + "' and '" + path2 + "'"); ex.printStackTrace(); } } /** * Test JXPath.setValue() with various arguments */ public void testSetValue(){ if (!enabled){ return; } TestBean tBean = new TestBean(); JXPathContext context = JXPathContext.newContext(tBean); context.getVariables().declareVariable("x", null); context.setValue("$x", new Integer(1)); assertEquals("Modified <" + "$x" + ">", new Integer(1), context.getValue("$x")); boolean exception = false; try { context.setValue("$y", new Integer(1)); } catch (Exception ex){ exception = true; } assertTrue("Setting '$y = 1', expected exception - did not get it", exception); context.setValue("int", new Integer(3)); assertEquals("Modified <" + "int" + ">", new Integer(3), context.getValue("int")); context.setValue("int", new int[]{4}); assertEquals("Modified <" + "int" + ">", new Integer(4), context.getValue("int")); context.setValue("integers[2]", new Integer(5)); assertEquals("Modified <" + "integers[2]" + ">", new Integer(5), context.getValue("integers[2]")); context.setValue("integers[2]", new int[]{6}); assertEquals("Modified <" + "integers[2]" + ">", new Integer(6), context.getValue("integers[2]")); NestedTestBean nBean = new NestedTestBean("Name 9"); tBean.getBeans()[1] = null; context.setValue("beans[2]", nBean); assertEquals("Modified <" + "beans[2]" + ">", nBean, context.getValue("beans[2]")); context.setValue("map/Key1", new Integer(6)); assertEquals("Modified <" + "map/Key1" + ">", new Integer(6), context.getValue("map/Key1")); context.setValue("map/Key1", new Integer[]{new Integer(7), new Integer(8)}); context.setValue("map/Key1[1]", new Integer(9)); assertEquals("Modified <" + "map/Key1[1]" + ">", new Integer(9), context.getValue("map/Key1[1]")); context.setValue("map/Key4", new Integer(7)); assertEquals("Modified <" + "map/Key4" + ">", new Integer(7), context.getValue("map/Key4")); context.setValue("integers[. = 6]", new Integer(8)); assertEquals("Modified <" + "integers[. = 6]" + ">", new Integer(8), context.getValue("integers[2]")); context.setValue("beans[name = 'Name 9']/int", new Integer(9)); assertEquals("Modified <" + "beans[name = 'Name 9']/int" + ">", new Integer(9), context.getValue("beans[name = 'Name 9']/int")); context.setValue("@int", new Integer(10)); assertEquals("Modified <" + "@int" + ">", new Integer(10), context.getValue("@int")); } /** * Test JXPathContext.createPath() with various arguments */ public void testCreatePath(){ if (!enabled){ return; } TestBeanWithNode tBean = createTestBeanWithDOM(); tBean.setNestedBean(null); tBean.setBeans(null); tBean.setMap(null); JXPathContext context = JXPathContext.newContext(tBean); context.setFactory(new TestFactory()); // Calls factory.declareVariable("string") testCreatePath(context, "$string", null); // Declare and set to null assertTrue("Variable created", context.getVariables().isDeclaredVariable("string")); // Calls factory.declareVariable("stringArray"). The factory needs to create a collection testCreatePath(context, "$stringArray[2]", ""); assertEquals("Created <" + "$stringArray[1]" + ">", "Value1", context.getValue("$stringArray[1]")); context.getVariables().declareVariable("array", new String[]{"Value1"}); // Does not involve factory at all - just expands the collection testCreatePath(context, "$array[2]", ""); // Make sure it is still the same array assertEquals("Created <" + "$array[1]" + ">", "Value1", context.getValue("$array[1]")); // Calls factory.declareVariable("test"). The factory should create a TestBean testCreatePath(context, "$test/boolean", Boolean.FALSE); // Calls factory.declareVariable("testArray"). // The factory should create a collection of TestBeans. // Then calls factory.createObject(..., collection, "testArray", 1). // That one should produce an instance of TestBean and put it in the collection // at index 1. testCreatePath(context, "$testArray[2]/boolean", Boolean.FALSE); // Calls factory.createObject(..., TestBean, "nestedBean") testCreatePath(context, "/nestedBean/int", new Integer(1)); // Calls factory.expandCollection(..., testBean, "beans", 2), then // factory.createObject(..., testBean, "beans", 2) testCreatePath(context, "/beans[2]/int", new Integer(1)); // Another, but the collection already exists testCreatePath(context, "/beans[3]/int", new Integer(1)); // Calls factory.expandCollection(..., testBean, "beans", 2), then // sets the value testCreatePath(context, "/nestedBean/strings[2]", "String 2"); // Calls factory.createObject(..., testBean, "map"), then // sets the value testCreatePath(context, "/map[@name='TestKey1']", ""); // Calls factory.createObject(..., testBean, "map"), then // then factory.createObject(..., map, "TestKey2"), then // sets the value testCreatePath(context, "/map[@name='TestKey2']/int", new Integer(1)); testCreatePath(context, "/map/TestKey3[2]", null, "/map[@name='TestKey3'][2]"); // Should be the same as the one before testCreatePath(context, "/map[@name='TestKey3'][3]", null); // Create an element of a dynamic map element, which is a collection testCreatePath(context, "/map/TestKey4[1]/int", new Integer(1), "/map[@name='TestKey4'][1]/int"); tBean.getMap().remove("TestKey4"); // Should be the same as the one before testCreatePath(context, "/map[@name='TestKey4'][1]/int", new Integer(1)); // Create a DOM element testCreatePath(context, "/vendor/location[3]", ""); // Create a DOM element with contents testCreatePath(context, "/vendor/location[3]/address/street", "", "/vendor/location[3]/address[1]/street[1]"); // Comprehensive tests: map & bean tBean.setMap(null); testCreatePath(context, "/map[@name='TestKey5']/nestedBean/int", new Integer(1)); tBean.setMap(null); testCreatePath(context, "/map[@name='TestKey5']/beans[2]/int", new Integer(1)); } private void testCreatePath(JXPathContext context, String path, Object value){ testCreatePath(context, path, value, path); } private void testCreatePath(JXPathContext context, String path, Object value, String expectedPath){ Pointer ptr = null; try { ptr = context.createPath(path); } catch(JXPathException ex){ ex.getException().printStackTrace(); } assertEquals("Pointer <" + path + ">", expectedPath, ptr.asPath()); assertEquals("Created <" + path + ">", value, ptr.getValue()); } /** * Test JXPath.createPathAndSetValue() with various arguments */ public void testCreatePathAndSetValue(){ if (!enabled){ return; } TestBean tBean = createTestBeanWithDOM(); tBean.setNestedBean(null); tBean.setBeans(null); tBean.setMap(null); JXPathContext context = JXPathContext.newContext(tBean); context.setFactory(new TestFactory()); // Calls factory.declareVariable("string") testCreatePathAndSetValue(context, "$string", "Value"); // Calls factory.declareVariable("stringArray"). The factory needs to create a collection testCreatePathAndSetValue(context, "$stringArray[2]", "Value2"); assertEquals("Created <" + "$stringArray[1]" + ">", "Value1", context.getValue("$stringArray[1]")); context.getVariables().declareVariable("array", new String[]{"Value1"}); // Does not involve factory at all - just expands the collection testCreatePathAndSetValue(context, "$array[2]", "Value2"); // Make sure it is still the same array assertEquals("Created <" + "$array[1]" + ">", "Value1", context.getValue("$array[1]")); // Calls factory.declareVariable("test"). The factory should create a TestBean testCreatePathAndSetValue(context, "$test/boolean", Boolean.TRUE); // Calls factory.declareVariable("testArray"). // The factory should create a collection of TestBeans. // Then calls factory.createObject(..., collection, "testArray", 1). // That one should produce an instance of TestBean and put it in the collection // at index 1. testCreatePathAndSetValue(context, "$testArray[2]/boolean", Boolean.TRUE); // Calls factory.createObject(..., TestBean, "nestedBean") testCreatePathAndSetValue(context, "nestedBean/int", new Integer(1)); // Calls factory.expandCollection(..., testBean, "beans", 2), then // factory.createObject(..., testBean, "beans", 2) testCreatePathAndSetValue(context, "beans[2]/int", new Integer(2)); // Another, but the collection already exists testCreatePathAndSetValue(context, "beans[3]/int", new Integer(3)); // Calls factory.expandCollection(..., testBean, "beans", 2), then // sets the value testCreatePathAndSetValue(context, "nestedBean/strings[2]", "Test"); // Calls factory.createObject(..., testBean, "map"), then // sets the value testCreatePathAndSetValue(context, "map[@name = 'TestKey1']", "Test"); // Calls factory.createObject(..., testBean, "map"), then // then factory.createObject(..., map, "TestKey2"), then // sets the value testCreatePathAndSetValue(context, "map[@name = 'TestKey2']/int", new Integer(4)); // Calls factory.expandCollection(..., map, "TestKey3", 2) testCreatePathAndSetValue(context, "map/TestKey3[2]", "Test"); // Should be the same as the one before testCreatePathAndSetValue(context, "map[@name='TestKey3'][3]", "Test"); // Create an element of a dynamic map element, which is a collection testCreatePathAndSetValue(context, "map/TestKey4[1]/int", new Integer(5)); tBean.getMap().remove("TestKey4"); // Should be the same as the one before testCreatePathAndSetValue(context, "map[@name = 'TestKey4'][1]/int", new Integer(5)); // Create a DOM element testCreatePathAndSetValue(context, "vendor/location[3]", ""); // Create a DOM element with contents testCreatePathAndSetValue(context, "vendor/location[3]/address/street", "Lemon Circle"); // Comprehensive tests: map & bean tBean.setMap(null); testCreatePathAndSetValue(context, "map[@name = 'TestKey5']/nestedBean/int", new Integer(6)); tBean.setMap(null); testCreatePathAndSetValue(context, "map[@name = 'TestKey5']/beans[2]/int", new Integer(7)); context = JXPathContext.newContext(new HashMap()); context.setFactory(new TestFactory()); testCreatePathAndSetValue(context, "/testKey1/testKey2/testKey3", new Integer(8)); context.setValue("/testKey1", new HashMap()); } private void testCreatePathAndSetValue(JXPathContext context, String path, Object value){ Pointer ptr = context.createPathAndSetValue(path, value); assertTrue("Pointer <" + path + ">", ptr != null); assertEquals("Created <" + path + ">", value, context.getValue(path)); assertEquals("Pointer value <" + path + ">", value, ptr.getValue()); } /** * Test JXPathContext.removePath() with various arguments */ public void testRemovePath(){ if (!enabled){ return; } TestBeanWithNode tBean = createTestBeanWithDOM(); JXPathContext context = JXPathContext.newContext(tBean); // Undeclare variable context.getVariables().declareVariable("temp", "temp"); context.removePath("$temp"); assertTrue("Undeclare variable", !context.getVariables().isDeclaredVariable("temp")); // Remove array element context.getVariables(). declareVariable("temp", new String[]{"temp1", "temp2"}); context.removePath("$temp[1]"); assertEquals("Remove array element", "temp2", context.getValue("$temp[1]")); // Remove list element context.getVariables(). declareVariable("temp", list("temp1", "temp2")); context.removePath("$temp[1]"); assertEquals("Remove collection element", "temp2", context.getValue("$temp[1]")); // Remove property value context.removePath("nestedBean/int"); assertEquals("Remove property value", new Integer(0), context.getValue("nestedBean/int")); // Remove property value context.removePath("nestedBean/strings[1]"); assertEquals("Remove property value", "String 2", context.getValue("nestedBean/strings[1]")); context.removePath("nestedBean"); context.setLenient(true); assertEquals("Remove property value", null, context.getValue("nestedBean")); tBean.getMap().put("TestKey1", "test"); // Remove dynamic property context.removePath("map[@name = 'TestKey1']"); assertEquals("Remove dynamic property value", null, context.getValue("map[@name = 'TestKey1']")); tBean.getMap().put("TestKey2", new String[]{"temp1", "temp2"}); context.removePath("map[@name = 'TestKey2'][1]"); assertEquals("Remove dynamic property collection element", "temp2", context.getValue("map[@name = 'TestKey2'][1]")); // Remove DOM nodes context.removePath("vendor/location[@id = '101']//street/text()"); assertEquals("Remove DOM text", "", context.getValue("vendor/location[@id = '101']//street")); context.removePath("vendor/location[@id = '101']//street"); assertEquals("Remove DOM element", new Double(0), context.getValue("count(vendor/location[@id = '101']//street)")); context.removePath("vendor/location[@id = '100']/@name"); assertEquals("Remove DOM attribute", new Double(0), context.getValue("count(vendor/location[@id = '100']/@name)")); } public void testIDAndKey(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(createTestBeanWithDOM()); context.setIdentityManager(new IdentityManager(){ public Pointer getPointerByID(JXPathContext context, String id){ NodePointer ptr = (NodePointer)context.getPointer("/vendor"); return ptr.getPointerByID(context, id); } }); context.setKeyManager(new KeyManager(){ public Pointer getPointerByKey(JXPathContext context, String key, String value){ return NodePointer.newNodePointer(null, "42", null); } }); assertEquals("Test ID", "Tangerine Drive", context.getValue("id(101)//street")); assertEquals("Test ID Path", "id('101')/address[1]/street[1]", context.getPointer("id(101)//street").asPath()); assertEquals("Test key", "42", context.getValue("key('a', 'b')")); context.setLenient(true); assertEquals("Test ID Path Null", "id(105)/address/street", context.getPointer("id(105)/address/street").asPath()); } public void testNull(){ if (!enabled){ return; } JXPathContext context = JXPathContext.newContext(new TestNull()); testGetValue(context, "nothing", null); testGetValue(context, "child/nothing", null); testGetValue(context, "array[2]", null); context.setLenient(true); testGetValue(context, "nothing/something", null); testGetValue(context, "array[2]/something", null); } /** * Test JXPath.getValue() with nested contexts */ public void testNestedContext(){ if (enabled){ JXPathContext pcontext = JXPathContext.newContext(null); pcontext.getVariables().declareVariable("x", bean); JXPathContext context = JXPathContext.newContext(pcontext, bean); testGetValue(context, "integers[$x/int]", new Integer(1)); } } private static class Context implements ExpressionContext { private Object object; public Context(Object object){ this.object = object; } public Pointer getContextNodePointer(){ return NodePointer.newNodePointer(null, object, Locale.getDefault()); } public List getContextNodeList(){ return null; } public JXPathContext getJXPathContext(){ return null; } public int getPosition(){ return 0; } } public void testFunctions(){ if (enabled){ Object[] args; Function func; TestFunctions test = new TestFunctions(); Functions funcs = new ClassFunctions(TestFunctions.class, "test"); args = new Object[]{new Integer(1), "x"}; func = funcs.getFunction("test", "new", args); assertEquals("test:new(1, x)", func.invoke(new Context(null), args).toString(), "foo=1; bar=x"); args = new Object[]{"baz"}; func = funcs.getFunction("test", "new", args); assertEquals("test:new('baz')", func.invoke(new Context(new Integer(1)), args).toString(), "foo=1; bar=baz"); args = new Object[]{new Integer(1), "x"}; func = funcs.getFunction("test", "build", args); assertEquals("test:build(1, x)", func.invoke(new Context(null), args).toString(), "foo=1; bar=x"); args = new Object[]{"7", new Integer(1)}; func = funcs.getFunction("test", "build", args); assertEquals("test:build('7', 1)", func.invoke(new Context(null), args).toString(), "foo=7; bar=1"); args = new Object[]{test}; func = funcs.getFunction("test", "getFoo", args); assertEquals("test:getFoo($test, 1, x)", func.invoke(new Context(null), args).toString(), "0"); args = new Object[0]; func = funcs.getFunction("test", "path", args); assertEquals("test:path()", func.invoke(new Context(new Integer(1)), args), "1"); args = new Object[]{test}; func = funcs.getFunction("test", "instancePath", args); assertEquals("test:instancePath()", func.invoke(new Context(new Integer(1)), args), "1"); args = new Object[]{test, "*"}; func = funcs.getFunction("test", "pathWithSuffix", args); assertEquals("test:pathWithSuffix('*')", func.invoke(new Context(new Integer(1)), args), "1*"); } } public void testParserReferenceImpl() throws Exception { if (!enabled){ return; } System.setProperty(JXPathContextFactory.FACTORY_NAME_PROPERTY, "org.apache.commons.jxpath.ri.JXPathContextFactoryReferenceImpl"); testParser(JXPathContextFactory.newInstance().newContext(null, bean), false); } public void testParser(JXPathContext ctx, boolean ignorePath) throws Exception { bean.getBeans()[1].setInt(3); ctx.setLocale(Locale.US); ctx.getVariables().declareVariable("a", new Double(1)); ctx.getVariables().declareVariable("b", new Double(1)); ctx.getVariables().declareVariable("nan", new Double(Double.NaN)); ctx.getVariables().declareVariable("test", new TestFunctions(4, "test")); ctx.getVariables().declareVariable("testnull", new TestNull()); FunctionLibrary lib = new FunctionLibrary(); lib.addFunctions(new ClassFunctions(TestFunctions.class, "test")); lib.addFunctions(new ClassFunctions(TestFunctions2.class, "test")); lib.addFunctions(new PackageFunctions("", "call")); lib.addFunctions(new PackageFunctions("org.apache.commons.jxpath.", "jxpathtest")); ctx.setFunctions(lib); testXPaths(ctx, xpath_tests, ignorePath); } private void testXPaths(JXPathContext ctx, XP xpath_tests[], boolean ignorePath) throws Exception{ Exception exception = null; for (int i=0; i < xpath_tests.length; i++) { try { Object actual; // System.err.println("XPATH: " + xpath_tests[i].xpath); if (xpath_tests[i].path){ if (ignorePath){ actual = xpath_tests[i].expected; } else { if (xpath_tests[i].eval){ Iterator it = ctx.iteratePointers(xpath_tests[i].xpath); List paths = new ArrayList(); while (it.hasNext()){ paths.add(((Pointer)it.next()).asPath()); } actual = paths; } else { ctx.setLenient(xpath_tests[i].lenient); actual = ctx.getPointer(xpath_tests[i].xpath).asPath(); } } } else { if (xpath_tests[i].eval){ ArrayList list = new ArrayList(); Iterator it = ctx.iterate(xpath_tests[i].xpath); while (it.hasNext()){ list.add(it.next()); } actual = list; } else { ctx.setLenient(xpath_tests[i].lenient); actual = ctx.getValue(xpath_tests[i].xpath); ctx.setLenient(false); } } assertEquals("Evaluating <" + xpath_tests[i].xpath + ">", xpath_tests[i].expected, actual); } catch (Exception ex){ System.err.println("Exception during <" + xpath_tests[i].xpath + ">"); ex.printStackTrace(); exception = ex; } if (exception != null){ throw exception; } } // Make sure that location paths are properly constructed for (int i=0; i < xpath_tests.length; i++) { try { if (!xpath_tests[i].path && !xpath_tests[i].eval){ Pointer ptr = ctx.getPointer(xpath_tests[i].xpath); Pointer test = ctx.getPointer(ptr.asPath()); assertEquals("Testing pointer for <" + xpath_tests[i].xpath + ">", ptr.asPath(), test.asPath()); } } catch (Exception ex){ System.err.println("Exception during pointer test <" + xpath_tests[i].xpath + ">"); ex.printStackTrace(); } } } private static class XP { public String xpath; public Object expected; public boolean eval; public boolean path; public boolean lenient; public XP(String xpath, Object expected, boolean eval, boolean path, boolean lenient){ this.xpath = xpath; this.expected = expected; this.eval = eval; this.path = path; this.lenient = lenient; } } private static XP test(String xpath, Object expected){ return new XP(xpath, expected, false, false, false); } private static XP testLenient(String xpath, Object expected){ return new XP(xpath, expected, false, false, true); } private static XP testEval(String xpath, Object expected){ return new XP(xpath, expected, true, false, false); } private static XP testPath(String xpath, Object expected){ return new XP(xpath, expected, false, true, true); } private static XP testEvalPath(String xpath, Object expected){ return new XP(xpath, expected, true, true, false); } static final XP[] xpath_tests = new XP[]{ // Numbers test("1", new Double(1.0)), testEval("1", list(new Double(1.0))), test("-1", new Double(-1.0)), test("2 + 2", new Double(4.0)), test("3 - 2", new Double(1.0)), test("1 + 2 + 3 - 4 + 5", new Double(7.0)), test("3 * 2", new Double(3.0*2.0)), test("3 div 2", new Double(3.0/2.0)), test("5 mod 2", new Double(1.0)), test("5.9 mod 2.1", new Double(1.0)), // Error in Xalan? test("5 mod -2", new Double(1.0)), test("-5 mod 2", new Double(-1.0)), test("-5 mod -2", new Double(-1.0)), test("1 < 2", Boolean.TRUE), test("1 > 2", Boolean.FALSE), test("1 <= 1", Boolean.TRUE), test("1 >= 2", Boolean.FALSE), test("3 > 2 > 1", Boolean.FALSE), test("3 > 2 and 2 > 1", Boolean.TRUE), test("3 > 2 and 2 < 1", Boolean.FALSE), test("3 < 2 or 2 > 1", Boolean.TRUE), test("3 < 2 or 2 < 1", Boolean.FALSE), test("1 = 1", Boolean.TRUE), test("1 = '1'", Boolean.TRUE), test("1 > 2 = 2 > 3", Boolean.TRUE), test("1 > 2 = 0", Boolean.TRUE), test("1 = 2", Boolean.FALSE), // Variables test("$a", new Double(1)), testPath("$a", "$a"), test("$a = $b", Boolean.TRUE), test("$a = $test", Boolean.FALSE), // Traversal // ancestor:: test("int/ancestor::root = /", Boolean.TRUE), test("count(beans/name/ancestor-or-self::node())", new Double(5)), test("beans/name/ancestor-or-self::node()[3] = /", Boolean.TRUE), // child:: test("count(set)", new Double(3)), test("boolean", Boolean.FALSE), // test("boolean/class/name", "java.lang.Boolean"), testEval("foo:boolean", list()), test("count(*)", new Double(21.0)), test("count(@*)", new Double(21.0)), testPath("boolean", "/boolean"), testEvalPath("boolean", list("/boolean")), test("nestedBean/name", "Name 0"), testPath("nestedBean/name", "/nestedBean/name"), testEvalPath("nestedBean/name", list("/nestedBean/name")), testEval("integers", list(new Integer(1), new Integer(2), new Integer(3), new Integer(4))), testPath("integers", "/integers"), testEvalPath("integers", list("/integers[1]", "/integers[2]", "/integers[3]", "/integers[4]")), test("integers[2]", new Integer(2)), testPath("integers[2]", "/integers[2]"), testEvalPath("integers[2]", list("/integers[2]")), test("beans[1]/name", "Name 1"), testPath("beans[1]/name", "/beans[1]/name"), testEval("beans[1]/strings", list("String 1", "String 2", "String 3")), testEval("beans/strings[2]", list("String 2", "String 2")), test("beans/strings[2]", "String 2"), test("beans[int > 2]/name", "Name 2"), test("beans/strings[name(.)='strings'][2]", "String 2"), test("(beans/strings[2])[1]", "String 2"), test("count(*)", new Double(21)), test("count(child::node())", new Double(21)), // descendant:: test("count(descendant::node())", new Double(65)), test("count(descendant::root)", new Double(0)), test("count(descendant::name)", new Double(7)), // descendant-or-self:: testEval("//name", list("Name 1", "Name 2", "Name 3", "Name 6", "Name 0", "Name 5", "Name 4")), test("//Key1", "Value 1"), testEval("//self::node()[name = 'Name 0']/name", list("Name 0")), testEval("//self::node()[name(.) = concat('n', 'a', 'm', 'e')]", list("Name 1", "Name 2", "Name 3", "Name 6", "Name 0", "Name 5", "Name 4")), test("count(//self::beans)", new Double(2)), test("count(nestedBean//.)", new Double(7)), testEval("descendant-or-self::name", list("Name 1", "Name 2", "Name 3", "Name 6", "Name 0", "Name 5", "Name 4")), test("count(descendant-or-self::root)", new Double(1)), test("count(descendant-or-self::node())", new Double(66)), // following:: test("count(nestedBean/strings[2]/following::node())", new Double(21)), test("count(nestedBean/strings[2]/following::strings)", new Double(7)), // following-sibling:: test("count(/nestedBean/following-sibling::node())", new Double(8)), test("count(/nestedBean/following-sibling::object)", new Double(1)), test("count(/nestedBean/boolean/../following-sibling::node())", new Double(8)), test("count(/nestedBean/boolean/../following-sibling::object)", new Double(1)), test("count(/descendant::boolean/following-sibling::node())", new Double(53)), test("count(/descendant::boolean/following-sibling::name)", new Double(7)), // parent:: test("count(/beans/..)", new Double(1)), test("count(//..)", new Double(9)), test("count(//../..)", new Double(2)), testEval("//parent::beans/name", list("Name 1", "Name 2")), // preceding:: test("count(beans[2]/int/preceding::node())", new Double(8)), test("count(beans[2]/int/preceding::boolean)", new Double(2)), // preceding-sibling:: test("count(/boolean/preceding-sibling::node())", new Double(2)), test("count(/nestedBean/int/../preceding-sibling::node())", new Double(12)), test("count(/descendant::int/preceding-sibling::node())", new Double(10)), // self:: test("self::node() = /", Boolean.TRUE), test("self::root = /", Boolean.TRUE), // Union - note corrected document order testEval("integers | beans[1]/strings", list("String 1", "String 2", "String 3", new Integer(1), new Integer(2), new Integer(3), new Integer(4))), test("count((integers | beans[1]/strings)[contains(., '1')])", new Double(2)), test("count((integers | beans[1]/strings)[name(.) = 'strings'])", new Double(3)), // Note that the following is different from "integer[2]" - it is a filter expression test("(integers)[2]", new Integer(2)), // TBD // Core functions test("integers[last()]", new Integer(4)), test("integers[position() = last() - 1]", new Integer(3)), testEval("integers[position() < 3]", list(new Integer(1), new Integer(2))), test("count(beans/strings)", new Double(6)), test("integers[string() = '2']", new Integer(2)), test("name(integers)", "integers"), testEval("*[name(.) = 'integers']", list(new Integer(1), new Integer(2), new Integer(3), new Integer(4))), // Dynamic properties test("nestedBean[@name = 'int']", new Integer(1)), // Not implemented in Xalan testPath("nestedBean[@name = 'int']", "/nestedBean/int"), test("map[@name = 'Key1']", "Value 1"), // Not implemented in Xalan testPath("map[@name = 'Key1']", "/map[@name='Key1']"), test("map/Key1", "Value 1"), testPath("map/Key1", "/map[@name='Key1']"), testPath("map[@name = 'Key"'"'1']", "/map[@name='Key"'"'1']"), test("map/Key2/name", "Name 6"), testPath("map/Key2/name", "/map[@name='Key2']/name"), test("/.[@name='map']/Key2/name", "Name 6"), testPath("/.[@name='map']/Key2/name", "/map[@name='Key2']/name"), test("/map[@name='Key2'][@name='name']", "Name 6"), testPath("/map[@name='Key2'][@name='name']", "/map[@name='Key2']/name"), test("/.[@name='map'][@name='Key2'][@name='name']", "Name 6"), testPath("/.[@name='map'][@name='Key2'][@name='name']", "/map[@name='Key2']/name"), // Standard functions test("string(2)", "2"), test("string($nan)", "NaN"), test("string(-$nan)", "NaN"), test("string(-2 div 0)", "-Infinity"), test("string(2 div 0)", "Infinity"), test("concat('a', 'b', 'c')", "abc"), test("starts-with('abc', 'ab')", Boolean.TRUE), test("starts-with('xabc', 'ab')", Boolean.FALSE), test("contains('xabc', 'ab')", Boolean.TRUE), test("contains('xabc', 'ba')", Boolean.FALSE), test("substring-before('1999/04/01', '/')", "1999"), test("substring-after('1999/04/01', '/')", "04/01"), test("substring('12345', 2, 3)", "234"), test("substring('12345', 2)", "2345"), test("substring('12345', 1.5, 2.6)", "234"), test("substring('12345', 0, 3)", "12"), test("substring('12345', 0 div 0, 3)", ""), test("substring('12345', 1, 0 div 0)", ""), test("substring('12345', -42, 1 div 0)", "12345"), test("substring('12345', -1 div 0, 1 div 0)", ""), test("string-length('12345')", new Double(5)), testEval("beans[1]/strings[string-length() = 8]", list("String 1", "String 2", "String 3")), test("normalize-space(' abc def ')", "abc def"), test("normalize-space('abc def')", "abc def"), test("normalize-space(' ')", ""), test("translate('--aaa--', 'abc-', 'ABC')", "AAA"), test("boolean(1)", Boolean.TRUE), test("boolean(0)", Boolean.FALSE), test("boolean('x')", Boolean.TRUE), test("boolean('')", Boolean.FALSE), test("boolean(boolean)", Boolean.FALSE), test("boolean(integers[position() < 3])", Boolean.TRUE), test("boolean(integers[position() > 4])", Boolean.FALSE), test("true()", Boolean.TRUE), test("false()", Boolean.FALSE), test("not(false())", Boolean.TRUE), test("not(true())", Boolean.FALSE), test("number('1')", new Double(1)), test("sum(integers)", new Double(10)), test("floor(1.5)", new Double(1)), test("floor(-1.5)", new Double(-2)), test("ceiling(1.5)", new Double(2)), test("ceiling(-1.5)", new Double(-1)), test("round(1.5)", new Double(2)), test("round(-1.5)", new Double(-1)), test("null()", null), test("@xml:lang", "en-US"), test("count(@xml:*)", new Double(1)), testLenient("@foo", null), test("lang('en')", Boolean.TRUE), test("lang('fr')", Boolean.FALSE), // Extension functions test("string(test:new())", "foo=0; bar=null"), test("string(jxpathtest:TestFunctions.new())", "foo=0; bar=null"), test("string(" + TestFunctions.class.getName() + ".new())", "foo=0; bar=null"), test("string(test:new(3, 'baz'))", "foo=3; bar=baz"), test("string(test:new('3', 4))", "foo=3; bar=4.0"), test("string(test:getFoo($test))", "4"), test("string(call:getFoo($test))", "4"), test("string(getFoo($test))", "4"), test("string(test:setFooAndBar($test, 7, 'biz'))", "foo=7; bar=biz"), test("string(test:build(8, 'goober'))", "foo=8; bar=goober"), test("string(jxpathtest:TestFunctions.build(8, 'goober'))", "foo=8; bar=goober"), test("string(" + TestFunctions.class.getName() + ".build(8, 'goober'))", "foo=8; bar=goober"), test("string(test:increment(8))", "9"), test("length('foo')", new Integer(3)), test("call:substring('foo', 1, 2)", "o"), test("//.[test:isMap()]/Key1", "Value 1"), test("count(//.[test:count(strings) = 3])", new Double(7)), test("/beans[contains(test:path(), '[2]')]/name", "Name 2"), // null testPath("$null", "$null"), testPath("$null[3]", "$null[3]"), testPath("$testnull/nothing", "$testnull/nothing"), testPath("$testnull/nothing[2]", "$testnull/nothing[2]"), testPath("beans[8]/int", "/beans[8]/int"), testEval("$testnull/nothing[1]", Collections.EMPTY_LIST), }; private static List list(){ return Collections.EMPTY_LIST; } private static List list(Object o1){ List list = new ArrayList(); list.add(o1); return list; } private static List list(Object o1, Object o2){ List list = new ArrayList(); list.add(o1); list.add(o2); return list; } private static List list(Object o1, Object o2, Object o3){ List list = new ArrayList(); list.add(o1); list.add(o2); list.add(o3); return list; } private static List list(Object o1, Object o2, Object o3, Object o4){ List list = new ArrayList(); list.add(o1); list.add(o2); list.add(o3); list.add(o4); return list; } private static List list(Object o1, Object o2, Object o3, Object o4, Object o5){ List list = new ArrayList(); list.add(o1); list.add(o2); list.add(o3); list.add(o4); list.add(o5); return list; } private static List list(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6){ List list = new ArrayList(); list.add(o1); list.add(o2); list.add(o3); list.add(o4); list.add(o5); list.add(o6); return list; } private static List list(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7){ List list = new ArrayList(); list.add(o1); list.add(o2); list.add(o3); list.add(o4); list.add(o5); list.add(o6); list.add(o7); return list; } public void testDOM() throws Exception { if (!enabled){ return; } System.setProperty(JXPathContextFactory.FACTORY_NAME_PROPERTY, "org.apache.commons.jxpath.ri.JXPathContextFactoryReferenceImpl"); DocumentContainer docCtr = new DocumentContainer( getClass().getResource("Vendor.xml"), DocumentContainer.MODEL_DOM); Document doc = (Document)docCtr.getValue(); JXPathContext ctx = JXPathContextFactory.newInstance().newContext(null, doc); ctx.setLocale(Locale.US); ctx.getVariables().declareVariable("dom", doc); ctx.getVariables().declareVariable("object", docCtr); ctx.getVariables().declareVariable("null", null); TestBeanWithNode tbwdom = createTestBeanWithDOM(); ctx.getVariables().declareVariable("test", tbwdom); testXPaths(ctx, dom_tests, false); } private TestBeanWithNode createTestBeanWithDOM(){ DocumentContainer docCtr = new DocumentContainer(getClass().getResource("Vendor.xml"), DocumentContainer.MODEL_DOM); Document doc = (Document)docCtr.getValue(); TestBeanWithNode tbwdom = new TestBeanWithNode(); tbwdom.setVendor(doc.getDocumentElement()); tbwdom.setObject(docCtr); return tbwdom; } static final XP[] dom_tests = new XP[]{ test("vendor/location/address/street", "Orchard Road"), test("vendor/location[2]/address/street", "Tangerine Drive"), test("vendor/location/address/city", "Fruit Market"), test("//street", "Orchard Road"), test("local-name(//street/..)", "address"), test("number(vendor/location/employeeCount)", new Double(10)), test("vendor/location/employeeCount + 1", new Double(11)), test("vendor/location/employeeCount and true()", Boolean.TRUE), test("vendor/location[.//employeeCount = 10]/following-sibling::location//street", "Tangerine Drive"), testPath("vendor/location[.//employeeCount = 10]/following-sibling::location//street", "/vendor[1]/location[2]/address[1]/street[1]"), testPath("//location[2]/preceding-sibling::location//street", "/vendor[1]/location[1]/address[1]/street[1]"), test("vendor/location/@id", "100"), testPath("vendor/location/@id", "/vendor[1]/location[1]/@id"), testEval("vendor/location/@id", list("100", "101")), test("vendor/product/price:amount", "45.95"), test("namespace-uri(vendor/product/price:amount)", "priceNS"), test("local-name(vendor/product/price:amount)", "amount"), test("name(vendor/product/price:amount)", "priceNS:amount"), test("vendor/product/prix", "934.99"), test("vendor/product/prix/namespace::price", "priceNS"), testPath("vendor/product/prix/namespace::price", "/vendor[1]/product[1]/prix[1]/namespace::price"), test("count(vendor/product/namespace::*)", new Double(3)), test("name(vendor/product/prix/namespace::price)", "priceNS:price"), test("local-name(vendor/product/prix/namespace::price)", "price"), test("vendor/product/price:amount/@price:discount", "10%"), test("vendor/product/value:amount/@value:discount", "10%"), test("namespace-uri(vendor/product/price:amount/@price:discount)", "priceNS"), test("local-name(vendor/product/price:amount/@price:discount)", "discount"), test("name(vendor/product/price:amount/@price:discount)", "priceNS:discount"), test("vendor/product/price:amount/@discount", "20%"), test("namespace-uri(vendor/product/price:amount/@discount)", ""), test("local-name(vendor/product/price:amount/@discount)", "discount"), test("name(vendor/product/price:amount/@discount)", "discount"), test("vendor/product/price:sale/saleEnds/ancestor::price:sale/saleEnds", "never"), test("vendor/product/price:sale/ancestor-or-self::price:sale/saleEnds", "never"), test("vendor/product/price:sale/saleEnds/ancestor::price:*" + "/saleEnds", "never"), test("count(vendor/product/price:*)", new Double(2)), test("count(vendor/product/value:*)", new Double(2)), test("count(vendor/product/*)", new Double(2)), testEval("vendor/product/price:amount/@price:*", list("10%")), testEval("vendor/product/price:amount/@*", list("20%")), test("count(//price:*)", new Double(2)), test("vendor/product/price:sale/saleEnds/parent::price:*" + "/saleEnds", "never"), test("//location/following::price:sale/saleEnds", "never"), test("//price:sale/self::price:sale/saleEnds", "never"), testLenient("//price:sale/self::x/saleEnds", null), test("//product/comment()", "We are not buying this product, ever"), // This test was incorrect // test("//product/text()[. != '']", "We love this product."), testPath("//product/text()", "/vendor[1]/product[1]/text()[1]"), test("//product/processing-instruction()", "do not show anybody"), test("//product/processing-instruction('report')", "average only"), testPath("//product/processing-instruction('report')", "/vendor[1]/product[1]/processing-instruction('report')[1]"), test("name(//product/processing-instruction()[1])", "security"), test("//product/prix/@xml:lang", "fr"), test("//product/prix[lang('fr')]", "934.99"), test("//product/price:sale[lang('en')]/saleEnds", "never"), test("vendor/location/@manager", ""), testLenient("vendor/location/@missing", null), test("count(vendor/location[1]/@*)", new Double(3)), test("vendor/location[@id='101']//street", "Tangerine Drive"), test("$test/int", new Integer(1)), test("$test/vendor/location[1]//street", "Orchard Road"), testPath("$test/vendor/location[1]//street", "$test/vendor/location[1]/address[1]/street[1]"), test("$dom/vendor//street", "Orchard Road"), test("$test/object/vendor/location[1]//street", "Orchard Road"), testPath("$test/object/vendor/location[1]//street", "$test/object/vendor[1]/location[1]/address[1]/street[1]"), test("$object//street", "Orchard Road"), testPath("$object//street", "$object/vendor[1]/location[1]/address[1]/street[1]"), testEval("vendor/contact/following::location//street", list("Orchard Road", "Tangerine Drive")), // test("id('101')//street", "Tangerine Drive"), // testPath("id('101')//street", "id('101')/address[1]/street[1]"), }; public void testTypeConversions(){ for (int i=0; i < typeConversionTests.length; i++) { TypeConversionTest test = typeConversionTests[i]; try { boolean can = TypeUtils.canConvert(test.from, test.toType); assertTrue("Can convert: " + test, can); Object result = TypeUtils.convert(test.from, test.toType); if (result.getClass().isArray()){ ArrayList list = new ArrayList(); for (int j = 0; j < Array.getLength(result); j++){ list.add(Array.get(result, j)); } result = list; } assertEquals("Convert: " + test, test.expected, result); } catch (Exception ex){ System.err.println("Exception during conversion test <" + test + ">"); ex.printStackTrace(); } } } private static class TypeConversionTest { public Object from; public Class toType; public Object expected; public TypeConversionTest(Object from, Class toType, Object expected){ this.from = from; this.toType = toType; this.expected = expected; } public String toString(){ return from.getClass() + " to " + toType; } } private TypeConversionTest[] typeConversionTests = new TypeConversionTest[]{ new TypeConversionTest(new Integer(1), String.class, "1"), new TypeConversionTest(new int[]{1, 2}, List.class, Arrays.asList(new Object[]{new Integer(1), new Integer(2)})), new TypeConversionTest(new int[]{1, 2}, String[].class, list("1", "2")), new TypeConversionTest(list(new Integer(1), new Integer(2)), String[].class, list("1", "2")), // new TypeConversionTest(new Object(){ // public String toString(){ // return "42"; // } // }, Integer.class, new Integer(42)), }; } 1.2 +6 -6 jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/jdom/JDOMModelTest.java Index: JDOMModelTest.java =================================================================== RCS file: /home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/jdom/JDOMModelTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- JDOMModelTest.java 26 Aug 2002 22:33:10 -0000 1.1 +++ JDOMModelTest.java 13 Oct 2002 03:01:03 -0000 1.2 @@ -71,7 +71,7 @@ import org.w3c.dom.*; import java.util.*; import java.lang.reflect.*; -import org.apache.commons.jxpath.ri.model.XMLModelTest; +import org.apache.commons.jxpath.ri.model.XMLModelTestCase; import org.apache.commons.jxpath.*; import org.apache.commons.jxpath.util.*; import org.apache.commons.jxpath.ri.*; @@ -93,7 +93,7 @@ * @version $Revision$ $Date$ */ -public class JDOMModelTest extends XMLModelTest +public class JDOMModelTest extends XMLModelTestCase { /** * Exercises this test case only 1.2 +6 -6 jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/dom/DOMModelTest.java Index: DOMModelTest.java =================================================================== RCS file: /home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/dom/DOMModelTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- DOMModelTest.java 26 Aug 2002 22:33:10 -0000 1.1 +++ DOMModelTest.java 13 Oct 2002 03:01:03 -0000 1.2 @@ -71,7 +71,7 @@ import org.w3c.dom.*; import java.util.*; import java.lang.reflect.*; -import org.apache.commons.jxpath.ri.model.XMLModelTest; +import org.apache.commons.jxpath.ri.model.XMLModelTestCase; import org.apache.commons.jxpath.*; import org.apache.commons.jxpath.util.*; import org.apache.commons.jxpath.ri.*; @@ -93,7 +93,7 @@ * @version $Revision$ $Date$ */ -public class DOMModelTest extends XMLModelTest +public class DOMModelTest extends XMLModelTestCase { /** * Exercises this test case only
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>