001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.configuration.tree.xpath;
018    
019    import static org.junit.Assert.assertEquals;
020    import static org.junit.Assert.assertTrue;
021    
022    import java.util.Iterator;
023    import java.util.List;
024    
025    import org.apache.commons.configuration.tree.ConfigurationNode;
026    import org.apache.commons.configuration.tree.DefaultConfigurationNode;
027    import org.apache.commons.jxpath.JXPathContext;
028    import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
029    import org.junit.Before;
030    import org.junit.Test;
031    
032    /**
033     * Test class for ConfigurationNodePointerFactory. This class does not directly
034     * call the factory's methods, but rather checks if it can be installed in a
035     * {@code JXPathContext} and if XPath expressions can be evaluated.
036     *
037     * @author <a
038     * href="http://commons.apache.org/configuration/team-list.html">Commons
039     * Configuration team</a>
040     * @version $Id: TestConfigurationNodePointerFactory.java 1226104 2011-12-31 15:37:16Z oheger $
041     */
042    public class TestConfigurationNodePointerFactory extends AbstractXPathTest
043    {
044        /** Stores the JXPathContext used for testing. */
045        JXPathContext context;
046    
047        @Override
048        @Before
049        public void setUp() throws Exception
050        {
051            super.setUp();
052            JXPathContextReferenceImpl
053                    .addNodePointerFactory(new ConfigurationNodePointerFactory());
054            context = JXPathContext.newContext(root);
055            context.setLenient(true);
056        }
057    
058        /**
059         * Tests simple XPath expressions.
060         */
061        @Test
062        public void testSimpleXPath()
063        {
064            List<?> nodes = context.selectNodes(CHILD_NAME1);
065            assertEquals("Incorrect number of results", 2, nodes.size());
066            for (Iterator<?> it = nodes.iterator(); it.hasNext();)
067            {
068                ConfigurationNode node = (ConfigurationNode) it.next();
069                assertEquals("Incorrect node name", CHILD_NAME1, node.getName());
070                assertEquals("Incorrect parent node", root, node.getParentNode());
071            }
072    
073            nodes = context.selectNodes("/" + CHILD_NAME1);
074            assertEquals("Incorrect number of results", 2, nodes.size());
075    
076            nodes = context.selectNodes(CHILD_NAME2 + "/" + CHILD_NAME1 + "/"
077                    + CHILD_NAME2);
078            assertEquals("Incorrect number of results", 18, nodes.size());
079        }
080    
081        /**
082         * Tests using indices to specify elements.
083         */
084        @Test
085        public void testIndices()
086        {
087            assertEquals("Incorrect value", "1.2.3", context.getValue("/"
088                    + CHILD_NAME2 + "[1]/" + CHILD_NAME1 + "[1]/" + CHILD_NAME2
089                    + "[2]"));
090            assertEquals("Incorrect value of last node", String
091                    .valueOf(CHILD_COUNT), context.getValue(CHILD_NAME2
092                    + "[last()]"));
093    
094            List<?> nodes = context.selectNodes("/" + CHILD_NAME1 + "[1]/*");
095            assertEquals("Wrong number of children", CHILD_COUNT, nodes.size());
096            int index = 1;
097            for (Iterator<?> it = nodes.iterator(); it.hasNext(); index++)
098            {
099                ConfigurationNode node = (ConfigurationNode) it.next();
100                assertEquals("Wrong node value for child " + index, "2." + index,
101                        node.getValue());
102            }
103        }
104    
105        /**
106         * Tests accessing attributes.
107         */
108        @Test
109        public void testAttributes()
110        {
111            root.addAttribute(new DefaultConfigurationNode("testAttr", "true"));
112            assertEquals("Did not find attribute of root node", "true", context
113                    .getValue("@testAttr"));
114            assertEquals("Incorrect attribute value", "1", context.getValue("/"
115                    + CHILD_NAME2 + "[1]/@" + ATTR_NAME));
116    
117            assertTrue("Found elements with name attribute", context.selectNodes(
118                    "//" + CHILD_NAME2 + "[@name]").isEmpty());
119            ConfigurationNode node = root.getChild(2).getChild(
120                    1).getChildren(CHILD_NAME2).get(1);
121            node.addAttribute(new DefaultConfigurationNode("name", "testValue"));
122            List<?> nodes = context.selectNodes("//" + CHILD_NAME2 + "[@name]");
123            assertEquals("Name attribute not found", 1, nodes.size());
124            assertEquals("Wrong node returned", node, nodes.get(0));
125        }
126    
127        /**
128         * Tests accessing a node's text.
129         */
130        @Test
131        public void testText()
132        {
133            List<?> nodes = context.selectNodes("//" + CHILD_NAME2
134                    + "[text()='1.1.1']");
135            assertEquals("Incorrect number of result nodes", 1, nodes.size());
136        }
137    
138        /**
139         * Tests accessing the parent axis.
140         */
141        @Test
142        public void testParentAxis()
143        {
144            List<?> nodes = context.selectNodes("/" + CHILD_NAME2 + "/parent::*");
145            assertEquals("Wrong number of parent nodes", 1, nodes.size());
146        }
147    
148        /**
149         * Tests accessing the following sibling axis.
150         */
151        @Test
152        public void testFollowingSiblingAxis()
153        {
154            List<?> nodes = context.selectNodes("/" + CHILD_NAME1
155                    + "[2]/following-sibling::*");
156            assertEquals("Wrong number of following siblings", 1, nodes.size());
157            ConfigurationNode node = (ConfigurationNode) nodes.get(0);
158            assertEquals("Wrong node type", CHILD_NAME2, node.getName());
159            assertEquals("Wrong index", String.valueOf(CHILD_COUNT), node
160                    .getValue());
161        }
162    
163        /**
164         * Tests accessing the preceding sibling axis.
165         */
166        @Test
167        public void testPrecedingSiblingAxis()
168        {
169            List<?> nodes = context.selectNodes("/" + CHILD_NAME1
170                    + "[2]/preceding-sibling::*");
171            assertEquals("Wrong number of preceding siblings", 3, nodes.size());
172            for (int index = 0, value = 3; index < nodes.size(); index++, value--)
173            {
174                assertEquals("Wrong node index", String.valueOf(value),
175                        ((ConfigurationNode) nodes.get(index)).getValue());
176            }
177        }
178    }