~ubuntu-branches/ubuntu/saucy/commons-configuration/saucy

« back to all changes in this revision

Viewing changes to src/test/org/apache/commons/configuration/tree/xpath/TestXPathExpressionEngine.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-07-01 16:29:44 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130701162944-98waq5gogha5gpn1
Tags: 1.9-1
* New upstream release
* debian/control:
  - Updated Standards-Version to 3.9.4 (no changes)
  - Use canonical URLs for the Vcs-* fields
  - Added new build dependencies (libjavacc-maven-plugin-java, junit4)
  - Upgraded the dependency on the Servlet API (2.5 -> 3.0)
  - Removed the dependency on the Activation Framework (glassfish-activation)
  - Replaced the dependency on glassfish-mail with libgnumail-java
  - Removed the unused dependencies:
    liblog4j1.2-java-doc, libmaven-assembly-plugin-java
  - Replaced the dependency on libcommons-jexl-java by libcommons-jexl2-java
* debian/watch: Changed to point the official Apache distribution server
* Removed the obsolete file debian/ant.properties
* Installed the upstream changelog in the binary packages
* Added the report plugins to maven.ignoreRules
* Added the classpath attribute to the jar manifest

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
package org.apache.commons.configuration.tree.xpath;
18
 
 
19
 
import java.util.ArrayList;
20
 
import java.util.Iterator;
21
 
import java.util.List;
22
 
 
23
 
import junit.framework.TestCase;
24
 
 
25
 
import org.apache.commons.configuration.tree.ConfigurationNode;
26
 
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
27
 
import org.apache.commons.configuration.tree.NodeAddData;
28
 
import org.apache.commons.jxpath.JXPathContext;
29
 
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
30
 
import org.apache.commons.jxpath.ri.model.NodePointerFactory;
31
 
 
32
 
/**
33
 
 * Test class for XPathExpressionEngine.
34
 
 *
35
 
 * @author Oliver Heger
36
 
 * @version $Id: TestXPathExpressionEngine.java 1152343 2011-07-29 19:23:09Z oheger $
37
 
 */
38
 
public class TestXPathExpressionEngine extends TestCase
39
 
{
40
 
    /** Constant for the test root node. */
41
 
    static final ConfigurationNode ROOT = new DefaultConfigurationNode(
42
 
            "testRoot");
43
 
 
44
 
    /** Constant for the valid test key. */
45
 
    static final String TEST_KEY = "TESTKEY";
46
 
 
47
 
    /** The expression engine to be tested. */
48
 
    XPathExpressionEngine engine;
49
 
 
50
 
    protected void setUp() throws Exception
51
 
    {
52
 
        super.setUp();
53
 
        engine = new MockJXPathContextExpressionEngine();
54
 
    }
55
 
 
56
 
    /**
57
 
     * Tests the query() method with a normal expression.
58
 
     */
59
 
    public void testQueryExpression()
60
 
    {
61
 
        List nodes = engine.query(ROOT, TEST_KEY);
62
 
        assertEquals("Incorrect number of results", 1, nodes.size());
63
 
        assertSame("Wrong result node", ROOT, nodes.get(0));
64
 
        checkSelectCalls(1);
65
 
    }
66
 
 
67
 
    /**
68
 
     * Tests a query that has no results. This should return an empty list.
69
 
     */
70
 
    public void testQueryWithoutResult()
71
 
    {
72
 
        List nodes = engine.query(ROOT, "a non existing key");
73
 
        assertTrue("Result list is not empty", nodes.isEmpty());
74
 
        checkSelectCalls(1);
75
 
    }
76
 
 
77
 
    /**
78
 
     * Tests a query with an empty key. This should directly return the root
79
 
     * node without invoking the JXPathContext.
80
 
     */
81
 
    public void testQueryWithEmptyKey()
82
 
    {
83
 
        checkEmptyKey("");
84
 
    }
85
 
 
86
 
    /**
87
 
     * Tests a query with a null key. Same as an empty key.
88
 
     */
89
 
    public void testQueryWithNullKey()
90
 
    {
91
 
        checkEmptyKey(null);
92
 
    }
93
 
 
94
 
    /**
95
 
     * Helper method for testing undefined keys.
96
 
     *
97
 
     * @param key the key
98
 
     */
99
 
    private void checkEmptyKey(String key)
100
 
    {
101
 
        List nodes = engine.query(ROOT, key);
102
 
        assertEquals("Incorrect number of results", 1, nodes.size());
103
 
        assertSame("Wrong result node", ROOT, nodes.get(0));
104
 
        checkSelectCalls(0);
105
 
    }
106
 
 
107
 
    /**
108
 
     * Tests if the used JXPathContext is correctly initialized.
109
 
     */
110
 
    public void testCreateContext()
111
 
    {
112
 
        JXPathContext ctx = new XPathExpressionEngine().createContext(ROOT,
113
 
                TEST_KEY);
114
 
        assertNotNull("Context is null", ctx);
115
 
        assertTrue("Lenient mode is not set", ctx.isLenient());
116
 
        assertSame("Incorrect context bean set", ROOT, ctx.getContextBean());
117
 
 
118
 
        NodePointerFactory[] factories = JXPathContextReferenceImpl
119
 
                .getNodePointerFactories();
120
 
        boolean found = false;
121
 
        for (int i = 0; i < factories.length; i++)
122
 
        {
123
 
            if (factories[i] instanceof ConfigurationNodePointerFactory)
124
 
            {
125
 
                found = true;
126
 
            }
127
 
        }
128
 
        assertTrue("No configuration pointer factory found", found);
129
 
    }
130
 
 
131
 
    /**
132
 
     * Tests a normal call of nodeKey().
133
 
     */
134
 
    public void testNodeKeyNormal()
135
 
    {
136
 
        assertEquals("Wrong node key", "parent/child", engine.nodeKey(
137
 
                new DefaultConfigurationNode("child"), "parent"));
138
 
    }
139
 
 
140
 
    /**
141
 
     * Tests nodeKey() for an attribute node.
142
 
     */
143
 
    public void testNodeKeyAttribute()
144
 
    {
145
 
        ConfigurationNode node = new DefaultConfigurationNode("attr");
146
 
        node.setAttribute(true);
147
 
        assertEquals("Wrong attribute key", "node/@attr", engine.nodeKey(node,
148
 
                "node"));
149
 
    }
150
 
 
151
 
    /**
152
 
     * Tests nodeKey() for the root node.
153
 
     */
154
 
    public void testNodeKeyForRootNode()
155
 
    {
156
 
        assertEquals("Wrong key for root node", "", engine.nodeKey(ROOT, null));
157
 
        assertEquals("Null name not detected", "test", engine.nodeKey(
158
 
                new DefaultConfigurationNode(), "test"));
159
 
    }
160
 
 
161
 
    /**
162
 
     * Tests node key() for direct children of the root node.
163
 
     */
164
 
    public void testNodeKeyForRootChild()
165
 
    {
166
 
        ConfigurationNode node = new DefaultConfigurationNode("child");
167
 
        assertEquals("Wrong key for root child node", "child", engine.nodeKey(
168
 
                node, ""));
169
 
        node.setAttribute(true);
170
 
        assertEquals("Wrong key for root attribute", "@child", engine.nodeKey(
171
 
                node, ""));
172
 
    }
173
 
 
174
 
    /**
175
 
     * Tests adding a single child node.
176
 
     */
177
 
    public void testPrepareAddNode()
178
 
    {
179
 
        NodeAddData data = engine.prepareAdd(ROOT, TEST_KEY + "  newNode");
180
 
        checkAddPath(data, new String[]
181
 
        { "newNode" }, false);
182
 
        checkSelectCalls(1);
183
 
    }
184
 
 
185
 
    /**
186
 
     * Tests adding a new attribute node.
187
 
     */
188
 
    public void testPrepareAddAttribute()
189
 
    {
190
 
        NodeAddData data = engine.prepareAdd(ROOT, TEST_KEY + "\t@newAttr");
191
 
        checkAddPath(data, new String[]
192
 
        { "newAttr" }, true);
193
 
        checkSelectCalls(1);
194
 
    }
195
 
 
196
 
    /**
197
 
     * Tests adding a complete path.
198
 
     */
199
 
    public void testPrepareAddPath()
200
 
    {
201
 
        NodeAddData data = engine.prepareAdd(ROOT, TEST_KEY
202
 
                + " \t a/full/path/node");
203
 
        checkAddPath(data, new String[]
204
 
        { "a", "full", "path", "node" }, false);
205
 
        checkSelectCalls(1);
206
 
    }
207
 
 
208
 
    /**
209
 
     * Tests adding a complete path whose final node is an attribute.
210
 
     */
211
 
    public void testPrepareAddAttributePath()
212
 
    {
213
 
        NodeAddData data = engine.prepareAdd(ROOT, TEST_KEY
214
 
                + " a/full/path@attr");
215
 
        checkAddPath(data, new String[]
216
 
        { "a", "full", "path", "attr" }, true);
217
 
        checkSelectCalls(1);
218
 
    }
219
 
 
220
 
    /**
221
 
     * Tests adding a new node to the root.
222
 
     */
223
 
    public void testPrepareAddRootChild()
224
 
    {
225
 
        NodeAddData data = engine.prepareAdd(ROOT, " newNode");
226
 
        checkAddPath(data, new String[]
227
 
        { "newNode" }, false);
228
 
        checkSelectCalls(0);
229
 
    }
230
 
 
231
 
    /**
232
 
     * Tests adding a new attribute to the root.
233
 
     */
234
 
    public void testPrepareAddRootAttribute()
235
 
    {
236
 
        NodeAddData data = engine.prepareAdd(ROOT, " @attr");
237
 
        checkAddPath(data, new String[]
238
 
        { "attr" }, true);
239
 
        checkSelectCalls(0);
240
 
    }
241
 
 
242
 
    /**
243
 
     * Tests an add operation with a query that does not return a single node.
244
 
     */
245
 
    public void testPrepareAddInvalidParent()
246
 
    {
247
 
        try
248
 
        {
249
 
            engine.prepareAdd(ROOT, "invalidKey newNode");
250
 
            fail("Could add to invalid parent!");
251
 
        }
252
 
        catch (IllegalArgumentException iex)
253
 
        {
254
 
            // ok
255
 
        }
256
 
    }
257
 
 
258
 
    /**
259
 
     * Tests an add operation with an empty path for the new node.
260
 
     */
261
 
    public void testPrepareAddEmptyPath()
262
 
    {
263
 
        try
264
 
        {
265
 
            engine.prepareAdd(ROOT, TEST_KEY + " ");
266
 
            fail("Could add empty path!");
267
 
        }
268
 
        catch (IllegalArgumentException iex)
269
 
        {
270
 
            // ok
271
 
        }
272
 
    }
273
 
 
274
 
    /**
275
 
     * Tests an add operation where the key is null.
276
 
     */
277
 
    public void testPrepareAddNullKey()
278
 
    {
279
 
        try
280
 
        {
281
 
            engine.prepareAdd(ROOT, null);
282
 
            fail("Could add null path!");
283
 
        }
284
 
        catch (IllegalArgumentException iex)
285
 
        {
286
 
            // ok
287
 
        }
288
 
    }
289
 
 
290
 
    /**
291
 
     * Tests an add operation where the key is null.
292
 
     */
293
 
    public void testPrepareAddEmptyKey()
294
 
    {
295
 
        try
296
 
        {
297
 
            engine.prepareAdd(ROOT, "");
298
 
            fail("Could add empty path!");
299
 
        }
300
 
        catch (IllegalArgumentException iex)
301
 
        {
302
 
            // ok
303
 
        }
304
 
    }
305
 
 
306
 
    /**
307
 
     * Tests an add operation with an invalid path.
308
 
     */
309
 
    public void testPrepareAddInvalidPath()
310
 
    {
311
 
        try
312
 
        {
313
 
            engine.prepareAdd(ROOT, TEST_KEY + " an/invalid//path");
314
 
            fail("Could add invalid path!");
315
 
        }
316
 
        catch (IllegalArgumentException iex)
317
 
        {
318
 
            // ok
319
 
        }
320
 
    }
321
 
 
322
 
    /**
323
 
     * Tests an add operation with an invalid path: the path contains an
324
 
     * attribute in the middle part.
325
 
     */
326
 
    public void testPrepareAddInvalidAttributePath()
327
 
    {
328
 
        try
329
 
        {
330
 
            engine.prepareAdd(ROOT, TEST_KEY + " a/path/with@an/attribute");
331
 
            fail("Could add invalid attribute path!");
332
 
        }
333
 
        catch (IllegalArgumentException iex)
334
 
        {
335
 
            // ok
336
 
        }
337
 
    }
338
 
 
339
 
    /**
340
 
     * Tests an add operation with an invalid path: the path contains an
341
 
     * attribute after a slash.
342
 
     */
343
 
    public void testPrepareAddInvalidAttributePath2()
344
 
    {
345
 
        try
346
 
        {
347
 
            engine.prepareAdd(ROOT, TEST_KEY + " a/path/with/@attribute");
348
 
            fail("Could add invalid attribute path!");
349
 
        }
350
 
        catch (IllegalArgumentException iex)
351
 
        {
352
 
            // ok
353
 
        }
354
 
    }
355
 
 
356
 
    /**
357
 
     * Tests an add operation with an invalid path that starts with a slash.
358
 
     */
359
 
    public void testPrepareAddInvalidPathWithSlash()
360
 
    {
361
 
        try
362
 
        {
363
 
            engine.prepareAdd(ROOT, TEST_KEY + " /a/path/node");
364
 
            fail("Could add path starting with a slash!");
365
 
        }
366
 
        catch (IllegalArgumentException iex)
367
 
        {
368
 
            // ok
369
 
        }
370
 
    }
371
 
 
372
 
    /**
373
 
     * Tests an add operation with an invalid path that contains multiple
374
 
     * attribute components.
375
 
     */
376
 
    public void testPrepareAddInvalidPathMultipleAttributes()
377
 
    {
378
 
        try
379
 
        {
380
 
            engine.prepareAdd(ROOT, TEST_KEY + " an@attribute@path");
381
 
            fail("Could add path with multiple attributes!");
382
 
        }
383
 
        catch (IllegalArgumentException iex)
384
 
        {
385
 
            // ok
386
 
        }
387
 
    }
388
 
 
389
 
    /**
390
 
     * Helper method for testing the path nodes in the given add data object.
391
 
     *
392
 
     * @param data the data object to check
393
 
     * @param expected an array with the expected path elements
394
 
     * @param attr a flag if the new node is an attribute
395
 
     */
396
 
    private void checkAddPath(NodeAddData data, String[] expected, boolean attr)
397
 
    {
398
 
        assertSame("Wrong parent node", ROOT, data.getParent());
399
 
        List path = data.getPathNodes();
400
 
        assertEquals("Incorrect number of path nodes", expected.length - 1,
401
 
                path.size());
402
 
        Iterator it = path.iterator();
403
 
        for (int idx = 0; idx < expected.length - 1; idx++)
404
 
        {
405
 
            assertEquals("Wrong node at position " + idx, expected[idx], it
406
 
                    .next());
407
 
        }
408
 
        assertEquals("Wrong name of new node", expected[expected.length - 1],
409
 
                data.getNewNodeName());
410
 
        assertEquals("Incorrect attribute flag", attr, data.isAttribute());
411
 
    }
412
 
 
413
 
    /**
414
 
     * Checks if the JXPath context's selectNodes() method was called as often
415
 
     * as expected.
416
 
     *
417
 
     * @param expected the number of expected calls
418
 
     */
419
 
    protected void checkSelectCalls(int expected)
420
 
    {
421
 
        MockJXPathContext ctx = ((MockJXPathContextExpressionEngine) engine).getContext();
422
 
        int calls = (ctx == null) ? 0 : ctx.selectInvocations;
423
 
        assertEquals("Incorrect number of select calls", expected, calls);
424
 
    }
425
 
 
426
 
    /**
427
 
     * A mock implementation of the JXPathContext class. This implementation
428
 
     * will overwrite the <code>selectNodes()</code> method that is used by
429
 
     * <code>XPathExpressionEngine</code> to count the invocations of this
430
 
     * method.
431
 
     */
432
 
    static class MockJXPathContext extends JXPathContextReferenceImpl
433
 
    {
434
 
        int selectInvocations;
435
 
 
436
 
        public MockJXPathContext(Object bean)
437
 
        {
438
 
            super(null, bean);
439
 
        }
440
 
 
441
 
        /**
442
 
         * Dummy implementation of this method. If the passed in string is the
443
 
         * test key, the root node will be returned in the list. Otherwise the
444
 
         * return value is <b>null</b>.
445
 
         */
446
 
        public List selectNodes(String xpath)
447
 
        {
448
 
            selectInvocations++;
449
 
            if (TEST_KEY.equals(xpath))
450
 
            {
451
 
                List result = new ArrayList(1);
452
 
                result.add(ROOT);
453
 
                return result;
454
 
            }
455
 
            else
456
 
            {
457
 
                return null;
458
 
            }
459
 
        }
460
 
    }
461
 
 
462
 
    /**
463
 
     * A special implementation of XPathExpressionEngine that overrides
464
 
     * createContext() to return a mock context object.
465
 
     */
466
 
    static class MockJXPathContextExpressionEngine extends
467
 
            XPathExpressionEngine
468
 
    {
469
 
        /** Stores the context instance. */
470
 
        private MockJXPathContext context;
471
 
 
472
 
        protected JXPathContext createContext(ConfigurationNode root, String key)
473
 
        {
474
 
            context = new MockJXPathContext(root);
475
 
            return context;
476
 
        }
477
 
 
478
 
        /**
479
 
         * Returns the context created by the last newContext() call.
480
 
         *
481
 
         * @return the current context
482
 
         */
483
 
        public MockJXPathContext getContext()
484
 
        {
485
 
            return context;
486
 
        }
487
 
    }
488
 
}