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;
018
019 import static org.junit.Assert.assertEquals;
020 import static org.junit.Assert.assertFalse;
021 import static org.junit.Assert.assertNull;
022 import static org.junit.Assert.assertTrue;
023 import static org.junit.Assert.fail;
024
025 import java.util.NoSuchElementException;
026
027 import org.junit.Before;
028 import org.junit.Test;
029
030 /**
031 * Test class for DefaultConfigurationKey.
032 *
033 * @author Oliver Heger
034 * @version $Id: TestDefaultConfigurationKey.java 1225914 2011-12-30 20:26:36Z oheger $
035 */
036 public class TestDefaultConfigurationKey
037 {
038 /** Constant for a test key. */
039 private static final String TESTPROPS = "tables.table(0).fields.field(1)";
040
041 /** Constant for a test attribute key. */
042 private static final String TESTATTR = "[@dataType]";
043
044 /** Constant for a complex attribute key. */
045 private static final String TESTKEY = TESTPROPS + TESTATTR;
046
047 /** Stores the expression engine of the key to test. */
048 DefaultExpressionEngine expressionEngine;
049
050 /** Stores the object to be tested. */
051 DefaultConfigurationKey key;
052
053 @Before
054 public void setUp() throws Exception
055 {
056 expressionEngine = new DefaultExpressionEngine();
057 key = new DefaultConfigurationKey(expressionEngine);
058 }
059
060 /**
061 * Tests setting the expression engine to null. This should not be allowed.
062 */
063 @Test(expected = IllegalArgumentException.class)
064 public void testSetNullExpressionEngine()
065 {
066 key.setExpressionEngine(null);
067 }
068
069 /**
070 * Tests the isAttributeKey() method with several keys.
071 */
072 @Test
073 public void testIsAttributeKey()
074 {
075 assertTrue("Attribute key not detected", key.isAttributeKey(TESTATTR));
076 assertFalse("Property key considered as attribute", key
077 .isAttributeKey(TESTPROPS));
078 assertFalse("Null key considered as attribute", key
079 .isAttributeKey(null));
080 }
081
082 /**
083 * Tests if attribute keys are correctly detected if no end markers are set.
084 * (In this test case we use the same delimiter for attributes as for simple
085 * properties.)
086 */
087 @Test
088 public void testIsAttributeKeyWithoutEndMarkers()
089 {
090 expressionEngine.setAttributeEnd(null);
091 expressionEngine
092 .setAttributeStart(DefaultExpressionEngine.DEFAULT_PROPERTY_DELIMITER);
093 assertTrue(
094 "Attribute key not detected",
095 key
096 .isAttributeKey(DefaultExpressionEngine.DEFAULT_PROPERTY_DELIMITER
097 + "test"));
098 assertFalse("Property key considered as attribute key", key
099 .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 }