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