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.assertNull;
021    import static org.junit.Assert.assertTrue;
022    
023    import java.util.Iterator;
024    import java.util.List;
025    import java.util.Locale;
026    
027    import org.apache.commons.configuration.tree.ConfigurationNode;
028    import org.apache.commons.configuration.tree.DefaultConfigurationNode;
029    import org.apache.commons.jxpath.ri.Compiler;
030    import org.apache.commons.jxpath.ri.QName;
031    import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
032    import org.apache.commons.jxpath.ri.compiler.NodeTest;
033    import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
034    import org.apache.commons.jxpath.ri.compiler.ProcessingInstructionTest;
035    import org.apache.commons.jxpath.ri.model.NodeIterator;
036    import org.apache.commons.jxpath.ri.model.NodePointer;
037    import org.junit.Before;
038    import org.junit.Test;
039    
040    /**
041     * Test class for ConfigurationNodeIteratorChildren.
042     *
043     * @author <a
044     * href="http://commons.apache.org/configuration/team-list.html">Commons
045     * Configuration team</a>
046     * @version $Id: TestConfigurationNodeIteratorChildren.java 1226104 2011-12-31 15:37:16Z oheger $
047     */
048    public class TestConfigurationNodeIteratorChildren extends AbstractXPathTest
049    {
050        /** Stores the node pointer to the root node. */
051        NodePointer rootPointer;
052    
053        @Override
054        @Before
055        public void setUp() throws Exception
056        {
057            super.setUp();
058            rootPointer = new ConfigurationNodePointer(root, Locale.getDefault());
059        }
060    
061        /**
062         * Tests to iterate over all children of the root node.
063         */
064        @Test
065        public void testIterateAllChildren()
066        {
067            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
068                    rootPointer, null, false, null);
069            assertEquals("Wrong number of elements", CHILD_COUNT, iteratorSize(it));
070            checkValues(it, new int[]
071            { 1, 2, 3, 4, 5 });
072        }
073    
074        /**
075         * Tests a reverse iteration.
076         */
077        @Test
078        public void testIterateReverse()
079        {
080            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
081                    rootPointer, null, true, null);
082            assertEquals("Wrong number of elements", CHILD_COUNT, iteratorSize(it));
083            checkValues(it, new int[]
084            { 5, 4, 3, 2, 1 });
085        }
086    
087        /**
088         * Tests using a node test with a wildcard name.
089         */
090        @Test
091        public void testIterateWithWildcardTest()
092        {
093            NodeNameTest test = new NodeNameTest(new QName(null, "*"));
094            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
095                    rootPointer, test, false, null);
096            assertEquals("Wrong number of elements", CHILD_COUNT, iteratorSize(it));
097        }
098    
099        /**
100         * Tests using a node test that defines a namespace prefix. Because
101         * namespaces are not supported, no elements should be in the iteration.
102         */
103        @Test
104        public void testIterateWithPrefixTest()
105        {
106            NodeNameTest test = new NodeNameTest(new QName("prefix", "*"));
107            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
108                    rootPointer, test, false, null);
109            assertNull("Undefined node pointer not returned", it.getNodePointer());
110            assertEquals("Prefix was not evaluated", 0, iteratorSize(it));
111        }
112    
113        /**
114         * Tests using a node test that selects a certain sub node name.
115         */
116        @Test
117        public void testIterateWithNameTest()
118        {
119            NodeNameTest test = new NodeNameTest(new QName(null, CHILD_NAME2));
120            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
121                    rootPointer, test, false, null);
122            assertTrue("No children found", iteratorSize(it) > 0);
123            for (ConfigurationNode nd : iterationElements(it))
124            {
125                assertEquals("Wrong child element", CHILD_NAME2, nd.getName());
126            }
127        }
128    
129        /**
130         * Tests using a not supported test class. This should yield an empty
131         * iteration.
132         */
133        @Test
134        public void testIterateWithUnknownTest()
135        {
136            NodeTest test = new ProcessingInstructionTest("test");
137            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
138                    rootPointer, test, false, null);
139            assertEquals("Unknown test was not evaluated", 0, iteratorSize(it));
140        }
141    
142        /**
143         * Tests using a type test for nodes. This should return all nodes.
144         */
145        @Test
146        public void testIterateWithNodeType()
147        {
148            NodeTypeTest test = new NodeTypeTest(Compiler.NODE_TYPE_NODE);
149            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
150                    rootPointer, test, false, null);
151            assertEquals("Node type not evaluated", CHILD_COUNT, iteratorSize(it));
152        }
153    
154        /**
155         * Tests using a type test for a non supported type. This should return an
156         * empty iteration.
157         */
158        @Test
159        public void testIterateWithUnknownType()
160        {
161            NodeTypeTest test = new NodeTypeTest(Compiler.NODE_TYPE_COMMENT);
162            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
163                    rootPointer, test, false, null);
164            assertEquals("Unknown node type not evaluated", 0, iteratorSize(it));
165        }
166    
167        /**
168         * Tests defining a start node for the iteration.
169         */
170        @Test
171        public void testIterateStartsWith()
172        {
173            NodePointer childPointer = new ConfigurationNodePointer(rootPointer,
174                    root.getChild(2));
175            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
176                    rootPointer, null, false, childPointer);
177            assertEquals("Wrong start position", 0, it.getPosition());
178            List<ConfigurationNode> nodes = iterationElements(it);
179            assertEquals("Wrong size of iteration", CHILD_COUNT - 3, nodes.size());
180            int index = 4;
181            for (Iterator<ConfigurationNode> it2 = nodes.iterator(); it2.hasNext(); index++)
182            {
183                ConfigurationNode node = it2.next();
184                assertEquals("Wrong node value", String.valueOf(index), node
185                        .getValue());
186            }
187        }
188    
189        /**
190         * Tests defining a start node for a reverse iteration.
191         */
192        @Test
193        public void testIterateStartsWithReverse()
194        {
195            NodePointer childPointer = new ConfigurationNodePointer(rootPointer,
196                    root.getChild(3));
197            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
198                    rootPointer, null, true, childPointer);
199            int value = 3;
200            for (int index = 1; it.setPosition(index); index++, value--)
201            {
202                ConfigurationNode node = (ConfigurationNode) it.getNodePointer()
203                        .getNode();
204                assertEquals("Incorrect value at index " + index, String
205                        .valueOf(value), node.getValue());
206            }
207            assertEquals("Iteration ended not at end node", 0, value);
208        }
209    
210        /**
211         * Tests iteration with an invalid start node. This should cause the
212         * iteration to start at the first position.
213         */
214        @Test
215        public void testIterateStartsWithInvalid()
216        {
217            NodePointer childPointer = new ConfigurationNodePointer(rootPointer,
218                    new DefaultConfigurationNode("newNode"));
219            ConfigurationNodeIteratorChildren it = new ConfigurationNodeIteratorChildren(
220                    rootPointer, null, false, childPointer);
221            assertEquals("Wrong size of iteration", CHILD_COUNT, iteratorSize(it));
222            it.setPosition(1);
223            ConfigurationNode node = (ConfigurationNode) it.getNodePointer()
224                    .getNode();
225            assertEquals("Wrong start node", "1", node.getValue());
226        }
227    
228        /**
229         * Helper method for checking the values of the nodes returned by an
230         * iterator. Because the values indicate the order of the child nodes with
231         * this test it can be checked whether the nodes were returned in the
232         * correct order.
233         *
234         * @param iterator the iterator
235         * @param expectedIndices an array with the expected indices
236         */
237        private void checkValues(NodeIterator iterator, int[] expectedIndices)
238        {
239            List<ConfigurationNode> nodes = iterationElements(iterator);
240            for (int i = 0; i < expectedIndices.length; i++)
241            {
242                ConfigurationNode child = nodes.get(i);
243                assertTrue("Wrong index value for child " + i, child.getValue()
244                        .toString().endsWith(String.valueOf(expectedIndices[i])));
245            }
246        }
247    }