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

« back to all changes in this revision

Viewing changes to src/test/java/org/apache/commons/configuration/tree/TestDefaultExpressionEngine.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;
 
18
 
 
19
import static org.junit.Assert.assertEquals;
 
20
import static org.junit.Assert.assertFalse;
 
21
import static org.junit.Assert.assertSame;
 
22
import static org.junit.Assert.assertTrue;
 
23
 
 
24
import java.util.Iterator;
 
25
import java.util.List;
 
26
 
 
27
import org.junit.Before;
 
28
import org.junit.Test;
 
29
 
 
30
/**
 
31
 * Test class for DefaultExpressionEngine.
 
32
 *
 
33
 * @author <a
 
34
 * href="http://commons.apache.org/configuration/team-list.html">Commons
 
35
 * Configuration team</a>
 
36
 * @version $Id: TestDefaultExpressionEngine.java 1225918 2011-12-30 20:54:47Z oheger $
 
37
 */
 
38
public class TestDefaultExpressionEngine
 
39
{
 
40
    /** Stores the names of the test nodes representing tables. */
 
41
    private static String[] tables =
 
42
    { "users", "documents"};
 
43
 
 
44
    /** Stores the types of the test table nodes. */
 
45
    private static String[] tabTypes =
 
46
    { "system", "application"};
 
47
 
 
48
    /** Test data fields for the node hierarchy. */
 
49
    private static String[][] fields =
 
50
    {
 
51
    { "uid", "uname", "firstName", "lastName", "email"},
 
52
    { "docid", "name", "creationDate", "authorID", "version"}};
 
53
 
 
54
    /** The object to be tested. */
 
55
    DefaultExpressionEngine engine;
 
56
 
 
57
    /** The root of a hierarchy with configuration nodes. */
 
58
    ConfigurationNode root;
 
59
 
 
60
    @Before
 
61
    public void setUp() throws Exception
 
62
    {
 
63
        root = setUpNodes();
 
64
        engine = new DefaultExpressionEngine();
 
65
    }
 
66
 
 
67
    /**
 
68
     * Tests some simple queries.
 
69
     */
 
70
    @Test
 
71
    public void testQueryKeys()
 
72
    {
 
73
        checkKey("tables.table.name", "name", 2);
 
74
        checkKey("tables.table.fields.field.name", "name", 10);
 
75
        checkKey("tables.table[@type]", "type", 2);
 
76
        checkKey("tables.table(0).fields.field.name", "name", 5);
 
77
        checkKey("tables.table(1).fields.field.name", "name", 5);
 
78
        checkKey("tables.table.fields.field(1).name", "name", 2);
 
79
    }
 
80
 
 
81
    /**
 
82
     * Performs some queries and evaluates the values of the result nodes.
 
83
     */
 
84
    @Test
 
85
    public void testQueryNodes()
 
86
    {
 
87
        for (int i = 0; i < tables.length; i++)
 
88
        {
 
89
            checkKeyValue("tables.table(" + i + ").name", "name", tables[i]);
 
90
            checkKeyValue("tables.table(" + i + ")[@type]", "type", tabTypes[i]);
 
91
 
 
92
            for (int j = 0; j < fields[i].length; j++)
 
93
            {
 
94
                checkKeyValue("tables.table(" + i + ").fields.field(" + j
 
95
                        + ").name", "name", fields[i][j]);
 
96
            }
 
97
        }
 
98
    }
 
99
 
 
100
    /**
 
101
     * Tests querying keys that do not exist.
 
102
     */
 
103
    @Test
 
104
    public void testQueryNonExistingKeys()
 
105
    {
 
106
        checkKey("tables.tablespace.name", null, 0);
 
107
        checkKey("tables.table(2).name", null, 0);
 
108
        checkKey("a complete unknown key", null, 0);
 
109
        checkKey("tables.table(0).fields.field(-1).name", null, 0);
 
110
        checkKey("tables.table(0).fields.field(28).name", null, 0);
 
111
        checkKey("tables.table(0).fields.field().name", null, 0);
 
112
        checkKey("connection.settings.usr.name", null, 0);
 
113
    }
 
114
 
 
115
    /**
 
116
     * Tests querying nodes whose names contain a delimiter.
 
117
     */
 
118
    @Test
 
119
    public void testQueryEscapedKeys()
 
120
    {
 
121
        checkKeyValue("connection..settings.usr..name", "usr.name", "scott");
 
122
        checkKeyValue("connection..settings.usr..pwd", "usr.pwd", "tiger");
 
123
    }
 
124
 
 
125
    /**
 
126
     * Tests some queries when the same delimiter is used for properties and
 
127
     * attributes.
 
128
     */
 
129
    @Test
 
130
    public void testQueryAttributeEmulation()
 
131
    {
 
132
        engine.setAttributeEnd(null);
 
133
        engine.setAttributeStart(engine.getPropertyDelimiter());
 
134
        checkKeyValue("tables.table(0).name", "name", tables[0]);
 
135
        checkKeyValue("tables.table(0).type", "type", tabTypes[0]);
 
136
        checkKey("tables.table.type", "type", 2);
 
137
    }
 
138
 
 
139
    /**
 
140
     * Tests accessing the root node.
 
141
     */
 
142
    @Test
 
143
    public void testQueryRootNode()
 
144
    {
 
145
        List<ConfigurationNode> nodes = checkKey(null, null, 1);
 
146
        assertSame("Root node not found", root, nodes.get(0));
 
147
        nodes = checkKey("", null, 1);
 
148
        assertSame("Root node not found", root, nodes.get(0));
 
149
        checkKeyValue("[@test]", "test", "true");
 
150
    }
 
151
 
 
152
    /**
 
153
     * Tests a different query syntax. Sets other strings for the typical tokens
 
154
     * used by the expression engine.
 
155
     */
 
156
    @Test
 
157
    public void testQueryAlternativeSyntax()
 
158
    {
 
159
        setUpAlternativeSyntax();
 
160
        checkKeyValue("tables/table[1]/name", "name", tables[1]);
 
161
        checkKeyValue("tables/table[0]@type", "type", tabTypes[0]);
 
162
        checkKeyValue("@test", "test", "true");
 
163
        checkKeyValue("connection.settings/usr.name", "usr.name", "scott");
 
164
    }
 
165
 
 
166
    /**
 
167
     * Tests obtaining keys for nodes.
 
168
     */
 
169
    @Test
 
170
    public void testNodeKey()
 
171
    {
 
172
        ConfigurationNode node = root.getChild(0);
 
173
        assertEquals("Invalid name for descendant of root", "tables", engine
 
174
                .nodeKey(node, ""));
 
175
        assertEquals("Parent key not respected", "test.tables", engine.nodeKey(
 
176
                node, "test"));
 
177
        assertEquals("Full parent key not taken into account",
 
178
                "a.full.parent.key.tables", engine.nodeKey(node,
 
179
                        "a.full.parent.key"));
 
180
    }
 
181
 
 
182
    /**
 
183
     * Tests obtaining keys when the root node is involved.
 
184
     */
 
185
    @Test
 
186
    public void testNodeKeyWithRoot()
 
187
    {
 
188
        assertEquals("Wrong name for root noot", "", engine.nodeKey(root, null));
 
189
        assertEquals("Null name not detected", "test", engine.nodeKey(root,
 
190
                "test"));
 
191
    }
 
192
 
 
193
    /**
 
194
     * Tests obtaining keys for attribute nodes.
 
195
     */
 
196
    @Test
 
197
    public void testNodeKeyWithAttribute()
 
198
    {
 
199
        ConfigurationNode node = root.getChild(0).getChild(0).getAttribute(0);
 
200
        assertEquals("Wrong attribute node", "type", node.getName());
 
201
        assertEquals("Wrong attribute key", "tables.table[@type]", engine
 
202
                .nodeKey(node, "tables.table"));
 
203
        assertEquals("Wrong key for root attribute", "[@test]", engine.nodeKey(
 
204
                root.getAttribute(0), ""));
 
205
    }
 
206
 
 
207
    /**
 
208
     * Tests obtaining keys for nodes that contain the delimiter character.
 
209
     */
 
210
    @Test
 
211
    public void testNodeKeyWithEscapedDelimiters()
 
212
    {
 
213
        ConfigurationNode node = root.getChild(1);
 
214
        assertEquals("Wrong escaped key", "connection..settings", engine
 
215
                .nodeKey(node, ""));
 
216
        assertEquals("Wrong complex escaped key",
 
217
                "connection..settings.usr..name", engine.nodeKey(node
 
218
                        .getChild(0), engine.nodeKey(node, "")));
 
219
    }
 
220
 
 
221
    /**
 
222
     * Tests obtaining node keys when a different syntax is set.
 
223
     */
 
224
    @Test
 
225
    public void testNodeKeyWithAlternativeSyntax()
 
226
    {
 
227
        setUpAlternativeSyntax();
 
228
        assertEquals("Wrong child key", "tables/table", engine.nodeKey(root
 
229
                .getChild(0).getChild(0), "tables"));
 
230
        assertEquals("Wrong attribute key", "@test", engine.nodeKey(root
 
231
                .getAttribute(0), ""));
 
232
 
 
233
        engine.setAttributeStart(engine.getPropertyDelimiter());
 
234
        assertEquals("Wrong attribute key", "/test", engine.nodeKey(root
 
235
                .getAttribute(0), ""));
 
236
    }
 
237
 
 
238
    /**
 
239
     * Tests adding direct child nodes to the existing hierarchy.
 
240
     */
 
241
    @Test
 
242
    public void testPrepareAddDirectly()
 
243
    {
 
244
        NodeAddData data = engine.prepareAdd(root, "newNode");
 
245
        assertSame("Wrong parent node", root, data.getParent());
 
246
        assertTrue("Path nodes available", data.getPathNodes().isEmpty());
 
247
        assertEquals("Wrong name of new node", "newNode", data.getNewNodeName());
 
248
        assertFalse("New node is an attribute", data.isAttribute());
 
249
 
 
250
        data = engine.prepareAdd(root, "tables.table.fields.field.name");
 
251
        assertEquals("Wrong name of new node", "name", data.getNewNodeName());
 
252
        assertTrue("Path nodes available", data.getPathNodes().isEmpty());
 
253
        assertEquals("Wrong parent node", "field", data.getParent().getName());
 
254
        ConfigurationNode nd = data.getParent().getChild(0);
 
255
        assertEquals("Field has no name node", "name", nd.getName());
 
256
        assertEquals("Incorrect name", "version", nd.getValue());
 
257
    }
 
258
 
 
259
    /**
 
260
     * Tests adding when indices are involved.
 
261
     */
 
262
    @Test
 
263
    public void testPrepareAddWithIndex()
 
264
    {
 
265
        NodeAddData data = engine
 
266
                .prepareAdd(root, "tables.table(0).tableSpace");
 
267
        assertEquals("Wrong name of new node", "tableSpace", data
 
268
                .getNewNodeName());
 
269
        assertTrue("Path nodes available", data.getPathNodes().isEmpty());
 
270
        assertEquals("Wrong type of parent node", "table", data.getParent()
 
271
                .getName());
 
272
        ConfigurationNode node = data.getParent().getChild(0);
 
273
        assertEquals("Wrong table", tables[0], node.getValue());
 
274
 
 
275
        data = engine.prepareAdd(root, "tables.table(1).fields.field(2).alias");
 
276
        assertEquals("Wrong name of new node", "alias", data.getNewNodeName());
 
277
        assertEquals("Wrong type of parent node", "field", data.getParent()
 
278
                .getName());
 
279
        assertEquals("Wrong field node", "creationDate", data.getParent()
 
280
                .getChild(0).getValue());
 
281
    }
 
282
 
 
283
    /**
 
284
     * Tests adding new attributes.
 
285
     */
 
286
    @Test
 
287
    public void testPrepareAddAttribute()
 
288
    {
 
289
        NodeAddData data = engine.prepareAdd(root,
 
290
                "tables.table(0)[@tableSpace]");
 
291
        assertEquals("Wrong table node", tables[0], data.getParent()
 
292
                .getChild(0).getValue());
 
293
        assertEquals("Wrong name of new node", "tableSpace", data
 
294
                .getNewNodeName());
 
295
        assertTrue("Attribute not detected", data.isAttribute());
 
296
        assertTrue("Path nodes available", data.getPathNodes().isEmpty());
 
297
 
 
298
        data = engine.prepareAdd(root, "[@newAttr]");
 
299
        assertSame("Root node is not parent", root, data.getParent());
 
300
        assertEquals("Wrong name of new node", "newAttr", data.getNewNodeName());
 
301
        assertTrue("Attribute not detected", data.isAttribute());
 
302
    }
 
303
 
 
304
    /**
 
305
     * Tests add operations where complete paths are added.
 
306
     */
 
307
    @Test
 
308
    public void testPrepareAddWithPath()
 
309
    {
 
310
        NodeAddData data = engine.prepareAdd(root,
 
311
                "tables.table(1).fields.field(-1).name");
 
312
        assertEquals("Wrong name of new node", "name", data.getNewNodeName());
 
313
        checkNodePath(data, new String[]
 
314
        { "field"});
 
315
        assertEquals("Wrong type of parent node", "fields", data.getParent()
 
316
                .getName());
 
317
 
 
318
        data = engine.prepareAdd(root, "tables.table(-1).name");
 
319
        assertEquals("Wrong name of new node", "name", data.getNewNodeName());
 
320
        checkNodePath(data, new String[]
 
321
        { "table"});
 
322
        assertEquals("Wrong type of parent node", "tables", data.getParent()
 
323
                .getName());
 
324
 
 
325
        data = engine.prepareAdd(root, "a.complete.new.path");
 
326
        assertEquals("Wrong name of new node", "path", data.getNewNodeName());
 
327
        checkNodePath(data, new String[]
 
328
        { "a", "complete", "new"});
 
329
        assertSame("Root is not parent", root, data.getParent());
 
330
    }
 
331
 
 
332
    /**
 
333
     * Tests add operations when property and attribute delimiters are equal.
 
334
     * Then it is not possible to add new attribute nodes.
 
335
     */
 
336
    @Test
 
337
    public void testPrepareAddWithSameAttributeDelimiter()
 
338
    {
 
339
        engine.setAttributeEnd(null);
 
340
        engine.setAttributeStart(engine.getPropertyDelimiter());
 
341
 
 
342
        NodeAddData data = engine.prepareAdd(root, "tables.table(0).test");
 
343
        assertEquals("Wrong name of new node", "test", data.getNewNodeName());
 
344
        assertFalse("New node is an attribute", data.isAttribute());
 
345
        assertEquals("Wrong type of parent node", "table", data.getParent()
 
346
                .getName());
 
347
 
 
348
        data = engine.prepareAdd(root, "a.complete.new.path");
 
349
        assertFalse("New node is an attribute", data.isAttribute());
 
350
        checkNodePath(data, new String[]
 
351
        { "a", "complete", "new"});
 
352
    }
 
353
 
 
354
    /**
 
355
     * Tests add operations when an alternative syntax is set.
 
356
     */
 
357
    @Test
 
358
    public void testPrepareAddWithAlternativeSyntax()
 
359
    {
 
360
        setUpAlternativeSyntax();
 
361
        NodeAddData data = engine.prepareAdd(root, "tables/table[0]/test");
 
362
        assertEquals("Wrong name of new node", "test", data.getNewNodeName());
 
363
        assertFalse("New node is attribute", data.isAttribute());
 
364
        assertEquals("Wrong parent node", tables[0], data.getParent().getChild(
 
365
                0).getValue());
 
366
 
 
367
        data = engine.prepareAdd(root, "a/complete/new/path@attr");
 
368
        assertEquals("Wrong name of new attribute", "attr", data
 
369
                .getNewNodeName());
 
370
        checkNodePath(data, new String[]
 
371
        { "a", "complete", "new", "path"});
 
372
        assertSame("Root is not parent", root, data.getParent());
 
373
    }
 
374
 
 
375
    /**
 
376
     * Tests using invalid keys, e.g. if something should be added to
 
377
     * attributes.
 
378
     */
 
379
    @Test(expected = IllegalArgumentException.class)
 
380
    public void testPrepareAddInvalidKey()
 
381
    {
 
382
        engine.prepareAdd(root, "tables.table(0)[@type].new");
 
383
    }
 
384
 
 
385
    @Test(expected = IllegalArgumentException.class)
 
386
    public void testPrepareAddInvalidKeyAttribute()
 
387
    {
 
388
        engine
 
389
        .prepareAdd(root,
 
390
                "a.complete.new.path.with.an[@attribute].at.a.non.allowed[@position]");
 
391
    }
 
392
 
 
393
    @Test(expected = IllegalArgumentException.class)
 
394
    public void testPrepareAddNullKey()
 
395
    {
 
396
        engine.prepareAdd(root, null);
 
397
    }
 
398
 
 
399
    @Test(expected = IllegalArgumentException.class)
 
400
    public void testPrepareAddEmptyKey()
 
401
    {
 
402
        engine.prepareAdd(root, "");
 
403
    }
 
404
 
 
405
    /**
 
406
     * Creates a node hierarchy for testing that consists of tables, their
 
407
     * fields, and some additional data:
 
408
     *
 
409
     * <pre>
 
410
     *  tables
 
411
     *       table
 
412
     *          name
 
413
     *          fields
 
414
     *              field
 
415
     *                  name
 
416
     *              field
 
417
     *                  name
 
418
     * </pre>
 
419
     *
 
420
     * @return the root of the test node hierarchy
 
421
     */
 
422
    protected ConfigurationNode setUpNodes()
 
423
    {
 
424
        DefaultConfigurationNode rootNode = new DefaultConfigurationNode();
 
425
 
 
426
        DefaultConfigurationNode nodeTables = new DefaultConfigurationNode(
 
427
                "tables");
 
428
        rootNode.addChild(nodeTables);
 
429
        for (int i = 0; i < tables.length; i++)
 
430
        {
 
431
            DefaultConfigurationNode nodeTable = new DefaultConfigurationNode(
 
432
                    "table");
 
433
            nodeTables.addChild(nodeTable);
 
434
            nodeTable.addChild(new DefaultConfigurationNode("name", tables[i]));
 
435
            nodeTable.addAttribute(new DefaultConfigurationNode("type",
 
436
                    tabTypes[i]));
 
437
            DefaultConfigurationNode nodeFields = new DefaultConfigurationNode(
 
438
                    "fields");
 
439
            nodeTable.addChild(nodeFields);
 
440
 
 
441
            for (int j = 0; j < fields[i].length; j++)
 
442
            {
 
443
                nodeFields.addChild(createFieldNode(fields[i][j]));
 
444
            }
 
445
        }
 
446
 
 
447
        DefaultConfigurationNode nodeConn = new DefaultConfigurationNode(
 
448
                "connection.settings");
 
449
        rootNode.addChild(nodeConn);
 
450
        nodeConn.addChild(new DefaultConfigurationNode("usr.name", "scott"));
 
451
        nodeConn.addChild(new DefaultConfigurationNode("usr.pwd", "tiger"));
 
452
        rootNode.addAttribute(new DefaultConfigurationNode("test", "true"));
 
453
 
 
454
        return rootNode;
 
455
    }
 
456
 
 
457
    /**
 
458
     * Configures the expression engine to use a different syntax.
 
459
     */
 
460
    private void setUpAlternativeSyntax()
 
461
    {
 
462
        engine.setAttributeEnd(null);
 
463
        engine.setAttributeStart("@");
 
464
        engine.setPropertyDelimiter("/");
 
465
        engine.setEscapedDelimiter(null);
 
466
        engine.setIndexStart("[");
 
467
        engine.setIndexEnd("]");
 
468
    }
 
469
 
 
470
    /**
 
471
     * Helper method for checking the evaluation of a key. Queries the
 
472
     * expression engine and tests if the expected results are returned.
 
473
     *
 
474
     * @param key the key
 
475
     * @param name the name of the nodes to be returned
 
476
     * @param count the number of expected result nodes
 
477
     * @return the list with the results of the query
 
478
     */
 
479
    private List<ConfigurationNode> checkKey(String key, String name, int count)
 
480
    {
 
481
        List<ConfigurationNode> nodes = engine.query(root, key);
 
482
        assertEquals("Wrong number of result nodes for key " + key, count,
 
483
                nodes.size());
 
484
        for (Iterator<ConfigurationNode> it = nodes.iterator(); it.hasNext();)
 
485
        {
 
486
            assertEquals("Wrong result node for key " + key, name,
 
487
                    it.next().getName());
 
488
        }
 
489
        return nodes;
 
490
    }
 
491
 
 
492
    /**
 
493
     * Helper method for checking the value of a node specified by the given
 
494
     * key. This method evaluates the key and checks whether the resulting node
 
495
     * has the expected value.
 
496
     *
 
497
     * @param key the key
 
498
     * @param name the expected name of the result node
 
499
     * @param value the expected value of the result node
 
500
     */
 
501
    private void checkKeyValue(String key, String name, String value)
 
502
    {
 
503
        List<ConfigurationNode> nodes = checkKey(key, name, 1);
 
504
        assertEquals("Wrong value for key " + key, value,
 
505
                nodes.get(0).getValue());
 
506
    }
 
507
 
 
508
    /**
 
509
     * Helper method for checking the path of an add operation.
 
510
     *
 
511
     * @param data the add data object
 
512
     * @param expected the expected path nodes
 
513
     */
 
514
    private void checkNodePath(NodeAddData data, String[] expected)
 
515
    {
 
516
        assertEquals("Wrong number of path nodes", expected.length, data
 
517
                .getPathNodes().size());
 
518
        Iterator<String> it = data.getPathNodes().iterator();
 
519
        for (int i = 0; i < expected.length; i++)
 
520
        {
 
521
            assertEquals("Wrong path node " + i, expected[i], it.next());
 
522
        }
 
523
    }
 
524
 
 
525
    /**
 
526
     * Helper method for creating a field node with its children for the test
 
527
     * node hierarchy.
 
528
     *
 
529
     * @param name the name of the field
 
530
     * @return the field node
 
531
     */
 
532
    private static ConfigurationNode createFieldNode(String name)
 
533
    {
 
534
        DefaultConfigurationNode nodeField = new DefaultConfigurationNode(
 
535
                "field");
 
536
        nodeField.addChild(new DefaultConfigurationNode("name", name));
 
537
        return nodeField;
 
538
    }
 
539
}