View Javadoc

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.assertNull;
22  import static org.junit.Assert.assertTrue;
23  import static org.junit.Assert.fail;
24  
25  import java.util.NoSuchElementException;
26  
27  import org.junit.Before;
28  import org.junit.Test;
29  
30  /**
31   * Test class for DefaultConfigurationKey.
32   *
33   * @author Oliver Heger
34   * @version $Id: TestDefaultConfigurationKey.java 1225914 2011-12-30 20:26:36Z oheger $
35   */
36  public class TestDefaultConfigurationKey
37  {
38      /** Constant for a test key. */
39      private static final String TESTPROPS = "tables.table(0).fields.field(1)";
40  
41      /** Constant for a test attribute key. */
42      private static final String TESTATTR = "[@dataType]";
43  
44      /** Constant for a complex attribute key. */
45      private static final String TESTKEY = TESTPROPS + TESTATTR;
46  
47      /** Stores the expression engine of the key to test. */
48      DefaultExpressionEngine expressionEngine;
49  
50      /** Stores the object to be tested. */
51      DefaultConfigurationKey key;
52  
53      @Before
54      public void setUp() throws Exception
55      {
56          expressionEngine = new DefaultExpressionEngine();
57          key = new DefaultConfigurationKey(expressionEngine);
58      }
59  
60      /**
61       * Tests setting the expression engine to null. This should not be allowed.
62       */
63      @Test(expected = IllegalArgumentException.class)
64      public void testSetNullExpressionEngine()
65      {
66          key.setExpressionEngine(null);
67      }
68  
69      /**
70       * Tests the isAttributeKey() method with several keys.
71       */
72      @Test
73      public void testIsAttributeKey()
74      {
75          assertTrue("Attribute key not detected", key.isAttributeKey(TESTATTR));
76          assertFalse("Property key considered as attribute", key
77                  .isAttributeKey(TESTPROPS));
78          assertFalse("Null key considered as attribute", key
79                  .isAttributeKey(null));
80      }
81  
82      /**
83       * Tests if attribute keys are correctly detected if no end markers are set.
84       * (In this test case we use the same delimiter for attributes as for simple
85       * properties.)
86       */
87      @Test
88      public void testIsAttributeKeyWithoutEndMarkers()
89      {
90          expressionEngine.setAttributeEnd(null);
91          expressionEngine
92                  .setAttributeStart(DefaultExpressionEngine.DEFAULT_PROPERTY_DELIMITER);
93          assertTrue(
94                  "Attribute key not detected",
95                  key
96                          .isAttributeKey(DefaultExpressionEngine.DEFAULT_PROPERTY_DELIMITER
97                                  + "test"));
98          assertFalse("Property key considered as attribute key", key
99                  .isAttributeKey(TESTATTR));
100     }
101 
102     /**
103      * Tests removing leading delimiters.
104      */
105     @Test
106     public void testTrimLeft()
107     {
108         assertEquals("Key was not left trimmed", "test.", key
109                 .trimLeft(".test."));
110         assertEquals("Too much left trimming", "..test.", key
111                 .trimLeft("..test."));
112     }
113 
114     /**
115      * Tests removing trailing delimiters.
116      */
117     @Test
118     public void testTrimRight()
119     {
120         assertEquals("Key was not right trimmed", ".test", key
121                 .trimRight(".test."));
122         assertEquals("Too much right trimming", ".test..", key
123                 .trimRight(".test.."));
124     }
125 
126     /**
127      * Tests removing delimiters.
128      */
129     @Test
130     public void testTrim()
131     {
132         assertEquals("Key was not trimmed", "test", key.trim(".test."));
133         assertEquals("Null key could not be processed", "", key.trim(null));
134         assertEquals("Delimiter could not be processed", "", key
135                 .trim(DefaultExpressionEngine.DEFAULT_PROPERTY_DELIMITER));
136     }
137 
138     /**
139      * Tests appending keys.
140      */
141     @Test
142     public void testAppend()
143     {
144         key.append("tables").append("table(0).");
145         key.append("fields.").append("field(1)");
146         key.append(null).append(TESTATTR);
147         assertEquals("Wrong key", TESTKEY, key.toString());
148     }
149 
150     /**
151      * Tests appending keys that contain delimiters.
152      */
153     @Test
154     public void testAppendDelimiters()
155     {
156         key.append("key..").append("test").append(".");
157         key.append(".more").append("..tests");
158         assertEquals("Wrong key", "key...test.more...tests", key.toString());
159     }
160 
161     /**
162      * Tests appending keys that contain delimiters when no escpaped delimiter
163      * is defined.
164      */
165     @Test
166     public void testAppendDelimitersWithoutEscaping()
167     {
168         expressionEngine.setEscapedDelimiter(null);
169         key.append("key.......").append("test").append(".");
170         key.append(".more").append("..tests");
171         assertEquals("Wrong constructed key", "key.test.more.tests", key
172                 .toString());
173     }
174 
175     /**
176      * Tests calling append with the escape flag.
177      */
178     @Test
179     public void testAppendWithEscapeFlag()
180     {
181         key.append(".key.test.", true);
182         key.append(".more").append(".tests", true);
183         assertEquals("Wrong constructed key", "..key..test...more...tests", key
184                 .toString());
185     }
186 
187     /**
188      * Tests constructing keys for attributes.
189      */
190     @Test
191     public void testConstructAttributeKey()
192     {
193         assertEquals("Wrong attribute key", TESTATTR, key
194                 .constructAttributeKey("dataType"));
195         assertEquals("Attribute key was incorrectly converted", TESTATTR, key
196                 .constructAttributeKey(TESTATTR));
197         assertEquals("Null key could not be processed", "", key
198                 .constructAttributeKey(null));
199     }
200 
201     /**
202      * Tests constructing attribute keys when no end markers are defined. In
203      * this test case we use the property delimiter as attribute prefix.
204      */
205     @Test
206     public void testConstructAttributeKeyWithoutEndMarkers()
207     {
208         expressionEngine.setAttributeEnd(null);
209         expressionEngine.setAttributeStart(expressionEngine
210                 .getPropertyDelimiter());
211         assertEquals("Wrong attribute key", ".test", key
212                 .constructAttributeKey("test"));
213         assertEquals("Attribute key was incorrectly converted", ".test", key
214                 .constructAttributeKey(".test"));
215     }
216 
217     /**
218      * Tests appending attribute keys.
219      */
220     @Test
221     public void testAppendAttribute()
222     {
223         key.appendAttribute("dataType");
224         assertEquals("Attribute key not correctly appended", TESTATTR, key
225                 .toString());
226     }
227 
228     /**
229      * Tests appending an attribute key that is already decorated-
230      */
231     @Test
232     public void testAppendDecoratedAttributeKey()
233     {
234         key.appendAttribute(TESTATTR);
235         assertEquals("Decorated attribute key not correctly appended",
236                 TESTATTR, key.toString());
237     }
238 
239     /**
240      * Tests appending a null attribute key.
241      */
242     @Test
243     public void testAppendNullAttributeKey()
244     {
245         key.appendAttribute(null);
246         assertEquals("Null attribute key not correctly appended", "", key
247                 .toString());
248     }
249 
250     /**
251      * Tests appending an index to a key.
252      */
253     @Test
254     public void testAppendIndex()
255     {
256         key.append("test").appendIndex(42);
257         assertEquals("Index was not correctly appended", "test(42)", key
258                 .toString());
259     }
260 
261     /**
262      * Tests constructing a complex key by chaining multiple append operations.
263      */
264     @Test
265     public void testAppendComplexKey()
266     {
267         key.append("tables").append("table.").appendIndex(0);
268         key.append("fields.").append("field").appendIndex(1);
269         key.appendAttribute("dataType");
270         assertEquals("Wrong complex key", TESTKEY, key.toString());
271     }
272 
273     /**
274      * Tests getting and setting the key's length.
275      */
276     @Test
277     public void testLength()
278     {
279         key.append(TESTPROPS);
280         assertEquals("Wrong length", TESTPROPS.length(), key.length());
281         key.appendAttribute("dataType");
282         assertEquals("Wrong length", TESTKEY.length(), key.length());
283         key.setLength(TESTPROPS.length());
284         assertEquals("Wrong length after shortening", TESTPROPS.length(), key
285                 .length());
286         assertEquals("Wrong resulting key", TESTPROPS, key.toString());
287     }
288 
289     /**
290      * Tests comparing configuration keys.
291      */
292     @Test
293     public void testEquals()
294     {
295         DefaultConfigurationKey k1 = new DefaultConfigurationKey(
296                 expressionEngine, TESTKEY);
297         DefaultConfigurationKey k2 = new DefaultConfigurationKey(
298                 expressionEngine, TESTKEY);
299         assertTrue("Keys are not equal", k1.equals(k2));
300         assertTrue("Not reflexiv", k2.equals(k1));
301         assertEquals("Hash codes not equal", k1.hashCode(), k2.hashCode());
302         k2.append("anotherPart");
303         assertFalse("Keys considered equal", k1.equals(k2));
304         assertFalse("Keys considered equal", k2.equals(k1));
305         assertFalse("Key equals null key", k1.equals(null));
306         assertTrue("Faild comparison with string", k1.equals(TESTKEY));
307     }
308 
309     /**
310      * Tests determining an attribute key's name.
311      */
312     @Test
313     public void testAttributeName()
314     {
315         assertEquals("Plain key not detected", "test", key
316                 .attributeName("test"));
317         assertEquals("Attribute markers not stripped", "dataType", key
318                 .attributeName(TESTATTR));
319         assertNull("Null key not processed", key.attributeName(null));
320     }
321 
322     /**
323      * Tests to iterate over a simple key.
324      */
325     @Test
326     public void testIterate()
327     {
328         key.append(TESTKEY);
329         DefaultConfigurationKey.KeyIterator it = key.iterator();
330         assertTrue("No key parts", it.hasNext());
331         assertEquals("Wrong key part", "tables", it.nextKey());
332         assertEquals("Wrong key part", "table", it.nextKey());
333         assertTrue("No index found", it.hasIndex());
334         assertEquals("Wrong index", 0, it.getIndex());
335         assertEquals("Wrong key part", "fields", it.nextKey());
336         assertFalse("Found an index", it.hasIndex());
337         assertEquals("Wrong key part", "field", it.nextKey(true));
338         assertEquals("Wrong index", 1, it.getIndex());
339         assertFalse("Found an attribute", it.isAttribute());
340         assertEquals("Wrong current key", "field", it.currentKey(true));
341         assertEquals("Wrong key part", "dataType", it.nextKey());
342         assertEquals("Wrong decorated key part", "[@dataType]", it
343                 .currentKey(true));
344         assertTrue("Attribute not found", it.isAttribute());
345         assertFalse("Too many key parts", it.hasNext());
346         try
347         {
348             it.next();
349             fail("Could iterate over the iteration's end!");
350         }
351         catch (NoSuchElementException nex)
352         {
353             // ok
354         }
355     }
356 
357     /**
358      * Tests an iteration where the remove() method is called. This is not
359      * supported.
360      */
361     @Test(expected = UnsupportedOperationException.class)
362     public void testIterateWithRemove()
363     {
364         assertFalse(key.iterator().hasNext());
365         key.append("simple");
366         DefaultConfigurationKey.KeyIterator it = key.iterator();
367         assertTrue(it.hasNext());
368         assertEquals("simple", it.next());
369         it.remove();
370     }
371 
372     /**
373      * Tests iterating over some funny keys.
374      */
375     @Test
376     public void testIterateStrangeKeys()
377     {
378         key = new DefaultConfigurationKey(expressionEngine, "key.");
379         DefaultConfigurationKey.KeyIterator it = key.iterator();
380         assertTrue("Too few key parts", it.hasNext());
381         assertEquals("Wrong key part", "key", it.next());
382         assertFalse("Too many key parts", it.hasNext());
383 
384         key = new DefaultConfigurationKey(expressionEngine, ".");
385         it = key.iterator();
386         assertFalse("Simple delimiter key has more parts", it.hasNext());
387 
388         key = new DefaultConfigurationKey(expressionEngine,
389                 "key().index()undefined(0).test");
390         it = key.iterator();
391         assertEquals("Wrong first part", "key()", it.next());
392         assertFalse("Index detected in first part", it.hasIndex());
393         assertEquals("Wrong second part", "index()undefined", it.nextKey(false));
394         assertTrue("No index detected in second part", it.hasIndex());
395         assertEquals("Wrong index value", 0, it.getIndex());
396     }
397 
398     /**
399      * Tests iterating over keys with escaped delimiters.
400      */
401     @Test
402     public void testIterateEscapedDelimiters()
403     {
404         key.append("my..elem");
405         key.append("trailing..dot..");
406         key.append(".strange");
407         assertEquals("my..elem.trailing..dot...strange", key.toString());
408         DefaultConfigurationKey.KeyIterator kit = key.iterator();
409         assertEquals("Wrong first part", "my.elem", kit.nextKey());
410         assertEquals("Wrong second part", "trailing.dot.", kit.nextKey());
411         assertEquals("Wrong third part", "strange", kit.nextKey());
412         assertFalse("Too many parts", kit.hasNext());
413     }
414 
415     /**
416      * Tests iterating over keys when a different escaped delimiter is used.
417      */
418     @Test
419     public void testIterateAlternativeEscapeDelimiter()
420     {
421         expressionEngine.setEscapedDelimiter("\\.");
422         key.append("\\.my\\.elem");
423         key.append("trailing\\.dot\\.");
424         key.append(".strange");
425         assertEquals("\\.my\\.elem.trailing\\.dot\\..strange", key.toString());
426         DefaultConfigurationKey.KeyIterator kit = key.iterator();
427         assertEquals("Wrong first part", ".my.elem", kit.nextKey());
428         assertEquals("Wrong second part", "trailing.dot.", kit.nextKey());
429         assertEquals("Wrong third part", "strange", kit.nextKey());
430         assertFalse("Too many parts", kit.hasNext());
431     }
432 
433     /**
434      * Tests iterating when no escape delimiter is defined.
435      */
436     @Test
437     public void testIterateWithoutEscapeDelimiter()
438     {
439         expressionEngine.setEscapedDelimiter(null);
440         key.append("..my..elem.trailing..dot...strange");
441         assertEquals("Wrong key", "my..elem.trailing..dot...strange", key
442                 .toString());
443         DefaultConfigurationKey.KeyIterator kit = key.iterator();
444         final String[] parts =
445         { "my", "elem", "trailing", "dot", "strange"};
446         for (int i = 0; i < parts.length; i++)
447         {
448             assertEquals("Wrong key part " + i, parts[i], kit.next());
449         }
450         assertFalse("Too many parts", kit.hasNext());
451     }
452 
453     /**
454      * Tests whether a key with brackets in it can be iterated over.
455      */
456     @Test
457     public void testIterateWithBrackets()
458     {
459         key.append("directory.platform(x86).path");
460         DefaultConfigurationKey.KeyIterator kit = key.iterator();
461         String part = kit.nextKey();
462         assertEquals("Wrong part 1", "directory", part);
463         assertFalse("Has index 1", kit.hasIndex());
464         part = kit.nextKey();
465         assertEquals("Wrong part 2", "platform(x86)", part);
466         assertFalse("Has index 2", kit.hasIndex());
467         part = kit.nextKey();
468         assertEquals("Wrong part 3", "path", part);
469         assertFalse("Has index 3", kit.hasIndex());
470         assertFalse("Too many elements", kit.hasNext());
471     }
472 
473     /**
474      * Tests iterating over an attribute key that has an index.
475      */
476     @Test
477     public void testAttributeKeyWithIndex()
478     {
479         key.append(TESTATTR);
480         key.appendIndex(0);
481         assertEquals("Wrong attribute key with index", TESTATTR + "(0)", key
482                 .toString());
483 
484         DefaultConfigurationKey.KeyIterator it = key.iterator();
485         assertTrue("No first element", it.hasNext());
486         it.next();
487         assertTrue("Index not found", it.hasIndex());
488         assertEquals("Incorrect index", 0, it.getIndex());
489         assertTrue("Attribute not found", it.isAttribute());
490         assertEquals("Wrong plain key", "dataType", it.currentKey(false));
491         assertEquals("Wrong decorated key", TESTATTR, it.currentKey(true));
492     }
493 
494     /**
495      * Tests iteration when the attribute markers equals the property delimiter.
496      */
497     @Test
498     public void testIterateAttributeEqualsPropertyDelimiter()
499     {
500         expressionEngine.setAttributeEnd(null);
501         expressionEngine.setAttributeStart(expressionEngine
502                 .getPropertyDelimiter());
503         key.append("this.isa.key");
504         DefaultConfigurationKey.KeyIterator kit = key.iterator();
505         assertEquals("Wrong first key part", "this", kit.next());
506         assertFalse("First part is an attribute", kit.isAttribute());
507         assertTrue("First part is not a property key", kit.isPropertyKey());
508         assertEquals("Wrong second key part", "isa", kit.next());
509         assertFalse("Second part is an attribute", kit.isAttribute());
510         assertTrue("Second part is not a property key", kit.isPropertyKey());
511         assertEquals("Wrong third key part", "key", kit.next());
512         assertTrue("Third part is not an attribute", kit.isAttribute());
513         assertTrue("Third part is not a property key", kit.isPropertyKey());
514         assertEquals("Wrong decorated key part", "key", kit.currentKey(true));
515     }
516 }