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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
package org.apache.commons.configuration;
20
import java.math.BigDecimal;
21
import java.math.BigInteger;
22
import java.util.ArrayList;
23
import java.util.Collection;
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.NoSuchElementException;
27
import java.util.Properties;
29
import java.util.StringTokenizer;
31
import junit.framework.TestCase;
32
import junitx.framework.ListAssert;
33
import junitx.framework.ObjectAssert;
35
import org.apache.commons.collections.set.ListOrderedSet;
36
import org.apache.commons.configuration.event.ConfigurationEvent;
37
import org.apache.commons.configuration.event.ConfigurationListener;
40
* Tests some basic functions of the BaseConfiguration class. Missing keys will
43
* @version $Id: TestBaseConfiguration.java 806862 2009-08-22 15:13:31Z oheger $
45
public class TestBaseConfiguration extends TestCase
47
/** Constant for the number key.*/
48
static final String KEY_NUMBER = "number";
50
protected BaseConfiguration config = null;
52
protected static Class missingElementException = NoSuchElementException.class;
53
protected static Class incompatibleElementException = ConversionException.class;
55
protected void setUp() throws Exception
57
config = new BaseConfiguration();
58
config.setThrowExceptionOnMissing(true);
61
public void testThrowExceptionOnMissing()
63
assertTrue("Throw Exception Property is not set!", config.isThrowExceptionOnMissing());
66
public void testGetProperty()
68
/* should be empty and return null */
69
assertEquals("This returns null", config.getProperty("foo"), null);
71
/* add a real value, and get it two different ways */
72
config.setProperty("number", "1");
73
assertEquals("This returns '1'", config.getProperty("number"), "1");
74
assertEquals("This returns '1'", config.getString("number"), "1");
77
public void testGetByte()
79
config.setProperty("number", "1");
82
assertEquals("This returns 1(byte)", oneB, config.getByte("number"));
83
assertEquals("This returns 1(byte)", oneB, config.getByte("number", twoB));
84
assertEquals("This returns 2(default byte)", twoB, config.getByte("numberNotInConfig", twoB));
85
assertEquals("This returns 1(Byte)", new Byte(oneB), config.getByte("number", new Byte("2")));
87
// missing key without default value
91
config.getByte("numberNotInConfig");
97
assertNotNull("No exception thrown for missing keys", t);
98
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
100
// existing key with an incompatible value
101
config.setProperty("test.empty", "");
105
config.getByte("test.empty");
111
assertNotNull("No exception thrown for incompatible values", t);
112
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
115
public void testGetShort()
117
config.setProperty("numberS", "1");
120
assertEquals("This returns 1(short)", oneS, config.getShort("numberS"));
121
assertEquals("This returns 1(short)", oneS, config.getShort("numberS", twoS));
122
assertEquals("This returns 2(default short)", twoS, config.getShort("numberNotInConfig", twoS));
123
assertEquals("This returns 1(Short)", new Short(oneS), config.getShort("numberS", new Short("2")));
125
// missing key without default value
129
config.getShort("numberNotInConfig");
135
assertNotNull("No exception thrown for missing keys", t);
136
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
138
// existing key with an incompatible value
139
config.setProperty("test.empty", "");
143
config.getShort("test.empty");
149
assertNotNull("No exception thrown for incompatible values", t);
150
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
153
public void testGetLong()
155
config.setProperty("numberL", "1");
158
assertEquals("This returns 1(long)", oneL, config.getLong("numberL"));
159
assertEquals("This returns 1(long)", oneL, config.getLong("numberL", twoL));
160
assertEquals("This returns 2(default long)", twoL, config.getLong("numberNotInConfig", twoL));
161
assertEquals("This returns 1(Long)", new Long(oneL), config.getLong("numberL", new Long("2")));
163
// missing key without default value
167
config.getLong("numberNotInConfig");
173
assertNotNull("No exception thrown for missing keys", t);
174
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
176
// existing key with an incompatible value
177
config.setProperty("test.empty", "");
181
config.getLong("test.empty");
187
assertNotNull("No exception thrown for incompatible values", t);
188
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
191
public void testGetFloat()
193
config.setProperty("numberF", "1.0");
196
assertEquals("This returns 1(float)", oneF, config.getFloat("numberF"), 0);
197
assertEquals("This returns 1(float)", oneF, config.getFloat("numberF", twoF), 0);
198
assertEquals("This returns 2(default float)", twoF, config.getFloat("numberNotInConfig", twoF), 0);
199
assertEquals("This returns 1(Float)", new Float(oneF), config.getFloat("numberF", new Float("2")));
201
// missing key without default value
205
config.getFloat("numberNotInConfig");
211
assertNotNull("No exception thrown for missing keys", t);
212
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
214
// existing key with an incompatible value
215
config.setProperty("test.empty", "");
219
config.getFloat("test.empty");
225
assertNotNull("No exception thrown for incompatible values", t);
226
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
229
public void testGetDouble()
231
config.setProperty("numberD", "1.0");
234
assertEquals("This returns 1(double)", oneD, config.getDouble("numberD"), 0);
235
assertEquals("This returns 1(double)", oneD, config.getDouble("numberD", twoD), 0);
236
assertEquals("This returns 2(default double)", twoD, config.getDouble("numberNotInConfig", twoD), 0);
237
assertEquals("This returns 1(Double)", new Double(oneD), config.getDouble("numberD", new Double("2")));
239
// missing key without default value
243
config.getDouble("numberNotInConfig");
249
assertNotNull("No exception thrown for missing keys", t);
250
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
252
// existing key with an incompatible value
253
config.setProperty("test.empty", "");
257
config.getDouble("test.empty");
263
assertNotNull("No exception thrown for incompatible values", t);
264
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
267
public void testGetBigDecimal()
269
config.setProperty("numberBigD", "123.456");
270
BigDecimal number = new BigDecimal("123.456");
271
BigDecimal defaultValue = new BigDecimal("654.321");
273
assertEquals("Existing key", number, config.getBigDecimal("numberBigD"));
274
assertEquals("Existing key with default value", number, config.getBigDecimal("numberBigD", defaultValue));
275
assertEquals("Missing key with default value", defaultValue, config.getBigDecimal("numberNotInConfig", defaultValue));
277
// missing key without default value
281
config.getBigDecimal("numberNotInConfig");
287
assertNotNull("No exception thrown for missing keys", t);
288
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
290
// existing key with an incompatible value
291
config.setProperty("test.empty", "");
295
config.getBigDecimal("test.empty");
301
assertNotNull("No exception thrown for incompatible values", t);
302
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
305
public void testGetBigInteger()
307
config.setProperty("numberBigI", "1234567890");
308
BigInteger number = new BigInteger("1234567890");
309
BigInteger defaultValue = new BigInteger("654321");
311
assertEquals("Existing key", number, config.getBigInteger("numberBigI"));
312
assertEquals("Existing key with default value", number, config.getBigInteger("numberBigI", defaultValue));
313
assertEquals("Missing key with default value", defaultValue, config.getBigInteger("numberNotInConfig", defaultValue));
315
// missing key without default value
319
config.getBigInteger("numberNotInConfig");
325
assertNotNull("No exception thrown for missing keys", t);
326
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
328
// existing key with an incompatible value
329
config.setProperty("test.empty", "");
333
config.getBigInteger("test.empty");
339
assertNotNull("No exception thrown for incompatible values", t);
340
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
343
public void testGetString()
345
config.setProperty("testString", "The quick brown fox");
346
String string = "The quick brown fox";
347
String defaultValue = "jumps over the lazy dog";
349
assertEquals("Existing key", string, config.getString("testString"));
350
assertEquals("Existing key with default value", string, config.getString("testString", defaultValue));
351
assertEquals("Missing key with default value", defaultValue, config.getString("stringNotInConfig", defaultValue));
353
// missing key without default value
357
config.getString("stringNotInConfig");
363
assertNotNull("No exception thrown for missing keys", t);
364
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
367
public void testGetBoolean()
369
config.setProperty("boolA", Boolean.TRUE);
370
boolean boolT = true, boolF = false;
371
assertEquals("This returns true", boolT, config.getBoolean("boolA"));
372
assertEquals("This returns true, not the default", boolT, config.getBoolean("boolA", boolF));
373
assertEquals("This returns false(default)", boolF, config.getBoolean("boolNotInConfig", boolF));
374
assertEquals("This returns true(Boolean)", new Boolean(boolT), config.getBoolean("boolA", new Boolean(boolF)));
376
// missing key without default value
380
config.getBoolean("numberNotInConfig");
386
assertNotNull("No exception thrown for missing keys", t);
387
ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
389
// existing key with an incompatible value
390
config.setProperty("test.empty", "");
394
config.getBoolean("test.empty");
400
assertNotNull("No exception thrown for incompatible values", t);
401
ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
404
public void testGetList()
406
config.addProperty("number", "1");
407
config.addProperty("number", "2");
408
List list = config.getList("number");
409
assertNotNull("The list is null", list);
410
assertEquals("List size", 2, list.size());
411
assertTrue("The number 1 is missing from the list", list.contains("1"));
412
assertTrue("The number 2 is missing from the list", list.contains("2"));
415
* now test dan's new fix where we get the first scalar
416
* when we access a list valued property
420
config.getString("number");
422
catch (NoSuchElementException nsse)
424
fail("Should return a string");
428
public void testGetInterpolatedList()
430
config.addProperty("number", "1");
431
config.addProperty("array", "${number}");
432
config.addProperty("array", "${number}");
434
List list = new ArrayList();
438
ListAssert.assertEquals("'array' property", list, config.getList("array"));
441
public void testGetInterpolatedPrimitives()
443
config.addProperty("number", "1");
444
config.addProperty("value", "${number}");
446
config.addProperty("boolean", "true");
447
config.addProperty("booleanValue", "${boolean}");
450
assertEquals("boolean interpolation", true, config.getBoolean("booleanValue"));
451
assertEquals("byte interpolation", 1, config.getByte("value"));
452
assertEquals("short interpolation", 1, config.getShort("value"));
453
assertEquals("int interpolation", 1, config.getInt("value"));
454
assertEquals("long interpolation", 1, config.getLong("value"));
455
assertEquals("float interpolation", 1, config.getFloat("value"), 0);
456
assertEquals("double interpolation", 1, config.getDouble("value"), 0);
458
// primitive wrappers
459
assertEquals("Boolean interpolation", Boolean.TRUE, config.getBoolean("booleanValue", null));
460
assertEquals("Byte interpolation", new Byte("1"), config.getByte("value", null));
461
assertEquals("Short interpolation", new Short("1"), config.getShort("value", null));
462
assertEquals("Integer interpolation", new Integer("1"), config.getInteger("value", null));
463
assertEquals("Long interpolation", new Long("1"), config.getLong("value", null));
464
assertEquals("Float interpolation", new Float("1"), config.getFloat("value", null));
465
assertEquals("Double interpolation", new Double("1"), config.getDouble("value", null));
467
assertEquals("BigInteger interpolation", new BigInteger("1"), config.getBigInteger("value", null));
468
assertEquals("BigDecimal interpolation", new BigDecimal("1"), config.getBigDecimal("value", null));
471
public void testCommaSeparatedString()
473
String prop = "hey, that's a test";
474
config.setProperty("prop.string", prop);
477
config.getList("prop.string");
479
catch (NoSuchElementException nsse)
481
fail("Should return a list");
484
String prop2 = "hey\\, that's a test";
485
config.clearProperty("prop.string");
486
config.setProperty("prop.string", prop2);
489
config.getString("prop.string");
491
catch (NoSuchElementException nsse)
493
fail("Should return a list");
498
public void testAddProperty() throws Exception
500
Collection props = new ArrayList();
502
props.add("two,three,four");
503
props.add(new String[] { "5.1", "5.2", "5.3,5.4", "5.5" });
505
config.addProperty("complex.property", props);
507
Object val = config.getProperty("complex.property");
508
assertTrue(val instanceof Collection);
509
Collection col = (Collection) val;
510
assertEquals(10, col.size());
512
props = new ArrayList();
515
props.add("fox,jumps");
516
Object[] data = new Object[] {
517
"The", props, "over,the", "lazy", "dog."
519
config.setProperty("complex.property", data);
520
val = config.getProperty("complex.property");
521
assertTrue(val instanceof Collection);
522
col = (Collection) val;
523
Iterator it = col.iterator();
524
StringTokenizer tok = new StringTokenizer("The quick brown fox jumps over the lazy dog.", " ");
525
while(tok.hasMoreTokens())
527
assertTrue(it.hasNext());
528
assertEquals(tok.nextToken(), it.next());
530
assertFalse(it.hasNext());
532
config.setProperty("complex.property", null);
533
assertFalse(config.containsKey("complex.property"));
536
public void testPropertyAccess()
538
config.clearProperty("prop.properties");
539
config.setProperty("prop.properties", "");
541
"This returns an empty Properties object",
542
config.getProperties("prop.properties"),
544
config.clearProperty("prop.properties");
545
config.setProperty("prop.properties", "foo=bar, baz=moo, seal=clubber");
547
Properties p = new Properties();
548
p.setProperty("foo", "bar");
549
p.setProperty("baz", "moo");
550
p.setProperty("seal", "clubber");
552
"This returns a filled in Properties object",
553
config.getProperties("prop.properties"),
557
public void testSubset()
560
* test subset : assure we don't reprocess the data elements
561
* when generating the subset
564
String prop = "hey, that's a test";
565
String prop2 = "hey\\, that's a test";
566
config.setProperty("prop.string", prop2);
567
config.setProperty("property.string", "hello");
569
Configuration subEprop = config.subset("prop");
572
"Returns the full string",
574
subEprop.getString("string"));
577
subEprop.getString("string");
579
catch (NoSuchElementException nsse)
581
fail("Should return a string");
585
subEprop.getList("string");
587
catch (NoSuchElementException nsse)
589
fail("Should return a list");
592
Iterator it = subEprop.getKeys();
594
assertFalse(it.hasNext());
596
subEprop = config.subset("prop.");
597
it = subEprop.getKeys();
598
assertFalse(it.hasNext());
601
public void testInterpolation()
603
InterpolationTestHelper.testInterpolation(config);
606
public void testMultipleInterpolation()
608
InterpolationTestHelper.testMultipleInterpolation(config);
611
public void testInterpolationLoop()
613
InterpolationTestHelper.testInterpolationLoop(config);
617
* Tests interpolation when a subset configuration is involved.
619
public void testInterpolationSubset()
621
InterpolationTestHelper.testInterpolationSubset(config);
625
* Tests interpolation when the referred property is not found.
627
public void testInterpolationUnknownProperty()
629
InterpolationTestHelper.testInterpolationUnknownProperty(config);
633
* Tests interpolation of system properties.
635
public void testInterpolationSystemProperties()
637
InterpolationTestHelper.testInterpolationSystemProperties(config);
641
* Tests interpolation of constant values.
643
public void testInterpolationConstants()
645
InterpolationTestHelper.testInterpolationConstants(config);
649
* Tests whether a variable can be escaped, so that it won't be
652
public void testInterpolationEscaped()
654
InterpolationTestHelper.testInterpolationEscaped(config);
658
* Tests accessing and manipulating the interpolator object.
660
public void testGetInterpolator()
662
InterpolationTestHelper.testGetInterpolator(config);
666
* Tests obtaining a configuration with all variables replaced by their
669
public void testInterpolatedConfiguration()
671
InterpolationTestHelper.testInterpolatedConfiguration(config);
674
public void testGetHexadecimalValue()
676
config.setProperty("number", "0xFF");
677
assertEquals("byte value", (byte) 0xFF, config.getByte("number"));
679
config.setProperty("number", "0xFFFF");
680
assertEquals("short value", (short) 0xFFFF, config.getShort("number"));
682
config.setProperty("number", "0xFFFFFFFF");
683
assertEquals("int value", 0xFFFFFFFF, config.getInt("number"));
685
config.setProperty("number", "0xFFFFFFFFFFFFFFFF");
686
assertEquals("long value", 0xFFFFFFFFFFFFFFFFL, config.getLong("number"));
688
assertEquals("long value", 0xFFFFFFFFFFFFFFFFL, config.getBigInteger("number").longValue());
691
public void testResolveContainerStore()
693
AbstractConfiguration config = new BaseConfiguration();
696
config.addPropertyDirect("array", new String[] { "foo", "bar" });
698
assertEquals("first element of the 'array' property", "foo", config.resolveContainerStore("array"));
701
List list = new ArrayList();
704
config.addPropertyDirect("list", list);
706
assertEquals("first element of the 'list' property", "foo", config.resolveContainerStore("list"));
709
Set set = new ListOrderedSet();
712
config.addPropertyDirect("set", set);
714
assertEquals("first element of the 'set' property", "foo", config.resolveContainerStore("set"));
716
// arrays of primitives
717
config.addPropertyDirect("array.boolean", new boolean[] { true, false });
718
assertEquals("first element of the 'array.boolean' property", true, config.getBoolean("array.boolean"));
720
config.addPropertyDirect("array.byte", new byte[] { 1, 2 });
721
assertEquals("first element of the 'array.byte' property", 1, config.getByte("array.byte"));
723
config.addPropertyDirect("array.short", new short[] { 1, 2 });
724
assertEquals("first element of the 'array.short' property", 1, config.getShort("array.short"));
726
config.addPropertyDirect("array.int", new int[] { 1, 2 });
727
assertEquals("first element of the 'array.int' property", 1, config.getInt("array.int"));
729
config.addPropertyDirect("array.long", new long[] { 1, 2 });
730
assertEquals("first element of the 'array.long' property", 1, config.getLong("array.long"));
732
config.addPropertyDirect("array.float", new float[] { 1, 2 });
733
assertEquals("first element of the 'array.float' property", 1, config.getFloat("array.float"), 0);
735
config.addPropertyDirect("array.double", new double[] { 1, 2 });
736
assertEquals("first element of the 'array.double' property", 1, config.getDouble("array.double"), 0);
740
* Tests if conversion between number types is possible.
742
public void testNumberConversions()
744
config.setProperty(KEY_NUMBER, new Integer(42));
745
assertEquals("Wrong int returned", 42, config.getInt(KEY_NUMBER));
746
assertEquals("Wrong long returned", 42L, config.getLong(KEY_NUMBER));
747
assertEquals("Wrong byte returned", (byte) 42, config
748
.getByte(KEY_NUMBER));
749
assertEquals("Wrong float returned", 42.0f,
750
config.getFloat(KEY_NUMBER), 0.01f);
751
assertEquals("Wrong double returned", 42.0, config
752
.getDouble(KEY_NUMBER), 0.001);
754
assertEquals("Wrong Long returned", new Long(42L), config.getLong(
756
assertEquals("Wrong BigInt returned", new BigInteger("42"), config
757
.getBigInteger(KEY_NUMBER));
758
assertEquals("Wrong DigDecimal returned", new BigDecimal("42"), config
759
.getBigDecimal(KEY_NUMBER));
763
* Tests cloning a BaseConfiguration.
765
public void testClone()
767
for (int i = 0; i < 10; i++)
769
config.addProperty("key" + i, new Integer(i));
771
BaseConfiguration config2 = (BaseConfiguration) config.clone();
773
for (Iterator it = config.getKeys(); it.hasNext();)
775
String key = (String) it.next();
776
assertTrue("Key not found: " + key, config2.containsKey(key));
777
assertEquals("Wrong value for key " + key, config.getProperty(key),
778
config2.getProperty(key));
783
* Tests whether a cloned configuration is decoupled from its original.
785
public void testCloneModify()
787
ConfigurationListener l = new ConfigurationListener()
789
public void configurationChanged(ConfigurationEvent event)
794
config.addConfigurationListener(l);
795
config.addProperty("original", Boolean.TRUE);
796
BaseConfiguration config2 = (BaseConfiguration) config.clone();
798
config2.addProperty("clone", Boolean.TRUE);
799
assertFalse("New key appears in original", config.containsKey("clone"));
800
config2.setProperty("original", Boolean.FALSE);
801
assertTrue("Wrong value of original property", config
802
.getBoolean("original"));
804
assertEquals("Event listener was copied", 0, config2
805
.getConfigurationListeners().size());
809
* Tests the clone() method if a list property is involved.
811
public void testCloneListProperty()
813
final String key = "list";
814
config.addProperty(key, "value1");
815
config.addProperty(key, "value2");
816
BaseConfiguration config2 = (BaseConfiguration) config.clone();
817
config2.addProperty(key, "value3");
818
assertEquals("Wrong number of original properties", 2, config.getList(