    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
    18  package org.apache.commons.configuration;
    19
    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;
    28  import java.util.Set;
    29  import java.util.StringTokenizer;
    30
    31  import junit.framework.TestCase;
    32  import junitx.framework.ListAssert;
    33  import junitx.framework.ObjectAssert;
    34
    35  import org.apache.commons.collections.set.ListOrderedSet;
    36  import org.apache.commons.configuration.event.ConfigurationEvent;
    37  import org.apache.commons.configuration.event.ConfigurationListener;
    38
    39  /***
    40   * Tests some basic functions of the BaseConfiguration class. Missing keys will
    41   * throw Exceptions
    42   *
    43   * @version $Id: TestBaseConfiguration.java 588335 2007-10-25 20:22:35Z oheger $
    44   */
    45  public class TestBaseConfiguration extends TestCase
    46  {
    47      /*** Constant for the number key.*/
    48      static final String KEY_NUMBER = "number";
    49
    50      protected BaseConfiguration config = null;
    51
    52      protected static Class missingElementException = NoSuchElementException.class;
    53      protected static Class incompatibleElementException = ConversionException.class;
    54
    55      protected void setUp() throws Exception
    56      {
    57          config = new BaseConfiguration();
    58          config.setThrowExceptionOnMissing(true);
    59      }
    60
    61      public void testThrowExceptionOnMissing()
    62      {
    63          assertTrue("Throw Exception Property is not set!", config.isThrowExceptionOnMissing());
    64      }
    65
    66      public void testGetProperty()
    67      {
    68          /* should be empty and return null */
    69          assertEquals("This returns null", config.getProperty("foo"), null);
    70
    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");
    75      }
    76
    77      public void testGetByte()
    78      {
    79          config.setProperty("number", "1");
    80          byte oneB = 1;
    81          byte twoB = 2;
    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")));
    86
    87          // missing key without default value
    88          Throwable t = null;
    89          try
    90          {
    91              config.getByte("numberNotInConfig");
    92          }
    93          catch (Throwable T)
    94          {
    95              t = T;
    96          }
    97          assertNotNull("No exception thrown for missing keys", t);
    98          ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    99
    100         // existing key with an incompatible value
    101         config.setProperty("test.empty", "");
    102         t = null;
    103         try
    104         {
    105             config.getByte("test.empty");
    106         }
    107         catch (Throwable T)
    108         {
    109             t = T;
    110         }
    111         assertNotNull("No exception thrown for incompatible values", t);
    112         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    113     }
    114
    115     public void testGetShort()
    116     {
    117         config.setProperty("numberS", "1");
    118         short oneS = 1;
    119         short twoS = 2;
    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")));
    124
    125         // missing key without default value
    126         Throwable t = null;
    127         try
    128         {
    129             config.getShort("numberNotInConfig");
    130         }
    131         catch (Throwable T)
    132         {
    133             t = T;
    134         }
    135         assertNotNull("No exception thrown for missing keys", t);
    136         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    137
    138         // existing key with an incompatible value
    139         config.setProperty("test.empty", "");
    140         t = null;
    141         try
    142         {
    143             config.getShort("test.empty");
    144         }
    145         catch (Throwable T)
    146         {
    147             t = T;
    148         }
    149         assertNotNull("No exception thrown for incompatible values", t);
    150         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    151     }
    152
    153     public void testGetLong()
    154     {
    155         config.setProperty("numberL", "1");
    156         long oneL = 1;
    157         long twoL = 2;
    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")));
    162
    163         // missing key without default value
    164         Throwable t = null;
    165         try
    166         {
    167             config.getLong("numberNotInConfig");
    168         }
    169         catch (Throwable T)
    170         {
    171             t = T;
    172         }
    173         assertNotNull("No exception thrown for missing keys", t);
    174         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    175
    176         // existing key with an incompatible value
    177         config.setProperty("test.empty", "");
    178         t = null;
    179         try
    180         {
    181             config.getLong("test.empty");
    182         }
    183         catch (Throwable T)
    184         {
    185             t = T;
    186         }
    187         assertNotNull("No exception thrown for incompatible values", t);
    188         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    189     }
    190
    191     public void testGetFloat()
    192     {
    193         config.setProperty("numberF", "1.0");
    194         float oneF = 1;
    195         float twoF = 2;
    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")));
    200
    201         // missing key without default value
    202         Throwable t = null;
    203         try
    204         {
    205             config.getFloat("numberNotInConfig");
    206         }
    207         catch (Throwable T)
    208         {
    209             t = T;
    210         }
    211         assertNotNull("No exception thrown for missing keys", t);
    212         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    213
    214         // existing key with an incompatible value
    215         config.setProperty("test.empty", "");
    216         t = null;
    217         try
    218         {
    219             config.getFloat("test.empty");
    220         }
    221         catch (Throwable T)
    222         {
    223             t = T;
    224         }
    225         assertNotNull("No exception thrown for incompatible values", t);
    226         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    227     }
    228
    229     public void testGetDouble()
    230     {
    231         config.setProperty("numberD", "1.0");
    232         double oneD = 1;
    233         double twoD = 2;
    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")));
    238
    239         // missing key without default value
    240         Throwable t = null;
    241         try
    242         {
    243             config.getDouble("numberNotInConfig");
    244         }
    245         catch (Throwable T)
    246         {
    247             t = T;
    248         }
    249         assertNotNull("No exception thrown for missing keys", t);
    250         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    251
    252         // existing key with an incompatible value
    253         config.setProperty("test.empty", "");
    254         t = null;
    255         try
    256         {
    257             config.getDouble("test.empty");
    258         }
    259         catch (Throwable T)
    260         {
    261             t = T;
    262         }
    263         assertNotNull("No exception thrown for incompatible values", t);
    264         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    265     }
    266
    267     public void testGetBigDecimal()
    268     {
    269         config.setProperty("numberBigD", "123.456");
    270         BigDecimal number = new BigDecimal("123.456");
    271         BigDecimal defaultValue = new BigDecimal("654.321");
    272
    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));
    276
    277         // missing key without default value
    278         Throwable t = null;
    279         try
    280         {
    281             config.getBigDecimal("numberNotInConfig");
    282         }
    283         catch (Throwable T)
    284         {
    285             t = T;
    286         }
    287         assertNotNull("No exception thrown for missing keys", t);
    288         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    289
    290         // existing key with an incompatible value
    291         config.setProperty("test.empty", "");
    292         t = null;
    293         try
    294         {
    295             config.getBigDecimal("test.empty");
    296         }
    297         catch (Throwable T)
    298         {
    299             t = T;
    300         }
    301         assertNotNull("No exception thrown for incompatible values", t);
    302         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    303     }
    304
    305     public void testGetBigInteger()
    306     {
    307         config.setProperty("numberBigI", "1234567890");
    308         BigInteger number = new BigInteger("1234567890");
    309         BigInteger defaultValue = new BigInteger("654321");
    310
    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));
    314
    315         // missing key without default value
    316         Throwable t = null;
    317         try
    318         {
    319             config.getBigInteger("numberNotInConfig");
    320         }
    321         catch (Throwable T)
    322         {
    323             t = T;
    324         }
    325         assertNotNull("No exception thrown for missing keys", t);
    326         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    327
    328         // existing key with an incompatible value
    329         config.setProperty("test.empty", "");
    330         t = null;
    331         try
    332         {
    333             config.getBigInteger("test.empty");
    334         }
    335         catch (Throwable T)
    336         {
    337             t = T;
    338         }
    339         assertNotNull("No exception thrown for incompatible values", t);
    340         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    341     }
    342
    343     public void testGetString()
    344     {
    345         config.setProperty("testString", "The quick brown fox");
    346         String string = "The quick brown fox";
    347         String defaultValue = "jumps over the lazy dog";
    348
    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));
    352
    353         // missing key without default value
    354         Throwable t = null;
    355         try
    356         {
    357             config.getString("stringNotInConfig");
    358         }
    359         catch (Throwable T)
    360         {
    361             t = T;
    362         }
    363         assertNotNull("No exception thrown for missing keys", t);
    364         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    365     }
    366
    367     public void testGetBoolean()
    368     {
    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)));
    375
    376         // missing key without default value
    377         Throwable t = null;
    378         try
    379         {
    380             config.getBoolean("numberNotInConfig");
    381         }
    382         catch (Throwable T)
    383         {
    384             t = T;
    385         }
    386         assertNotNull("No exception thrown for missing keys", t);
    387         ObjectAssert.assertInstanceOf("Exception thrown for missing keys", missingElementException, t);
    388
    389         // existing key with an incompatible value
    390         config.setProperty("test.empty", "");
    391         t = null;
    392         try
    393         {
    394             config.getBoolean("test.empty");
    395         }
    396         catch (Throwable T)
    397         {
    398             t = T;
    399         }
    400         assertNotNull("No exception thrown for incompatible values", t);
    401         ObjectAssert.assertInstanceOf("Exception thrown for incompatible values", incompatibleElementException, t);
    402     }
    403
    404     public void testGetList()
    405     {
    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"));
    413
    414         /*
    415          *  now test dan's new fix where we get the first scalar
    416          *  when we access a list valued property
    417          */
    418         try
    419         {
    420             config.getString("number");
    421         }
    422         catch (NoSuchElementException nsse)
    423         {
    424             fail("Should return a string");
    425         }
    426     }
    427
    428     public void testGetInterpolatedList()
    429     {
    430         config.addProperty("number", "1");
    431         config.addProperty("array", "${number}");
    432         config.addProperty("array", "${number}");
    433
    434         List list = new ArrayList();
    435         list.add("1");
    436         list.add("1");
    437
    438         ListAssert.assertEquals("'array' property", list, config.getList("array"));
    439     }
    440
    441     public void testGetInterpolatedPrimitives()
    442     {
    443         config.addProperty("number", "1");
    444         config.addProperty("value", "${number}");
    445
    446         config.addProperty("boolean", "true");
    447         config.addProperty("booleanValue", "${boolean}");
    448
    449         // primitive types
    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);
    457
    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));
    466
    467         assertEquals("BigInteger interpolation", new BigInteger("1"), config.getBigInteger("value", null));
    468         assertEquals("BigDecimal interpolation", new BigDecimal("1"), config.getBigDecimal("value", null));
    469     }
    470
    471     public void testCommaSeparatedString()
    472     {
    473         String prop = "hey, that's a test";
    474         config.setProperty("prop.string", prop);
    475         try
    476         {
    477             config.getList("prop.string");
    478         }
    479         catch (NoSuchElementException nsse)
    480         {
    481             fail("Should return a list");
    482         }
    483
    484         String prop2 = "hey//, that's a test";
    485         config.clearProperty("prop.string");
    486         config.setProperty("prop.string", prop2);
    487         try
    488         {
    489             config.getString("prop.string");
    490         }
    491         catch (NoSuchElementException nsse)
    492         {
    493             fail("Should return a list");
    494         }
    495
    496     }
    497
    498     public void testAddProperty() throws Exception
    499     {
    500         Collection props = new ArrayList();
    501         props.add("one");
    502         props.add("two,three,four");
    503         props.add(new String[] { "5.1", "5.2", "5.3,5.4", "5.5" });
    504         props.add("six");
    505         config.addProperty("complex.property", props);
    506
    507         Object val = config.getProperty("complex.property");
    508         assertTrue(val instanceof Collection);
    509         Collection col = (Collection) val;
    510         assertEquals(10, col.size());
    511
    512         props = new ArrayList();
    513         props.add("quick");
    514         props.add("brown");
    515         props.add("fox,jumps");
    516         Object[] data = new Object[] {
    517                 "The", props, "over,the", "lazy", "dog."
    518         };
    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())
    526         {
    527             assertTrue(it.hasNext());
    528             assertEquals(tok.nextToken(), it.next());
    529         }
    530         assertFalse(it.hasNext());
    531
    532         config.setProperty("complex.property", null);
    533         assertFalse(config.containsKey("complex.property"));
    534     }
    535
    536     public void testPropertyAccess()
    537     {
    538         config.clearProperty("prop.properties");
    539         config.setProperty("prop.properties", "");
    540         assertEquals(
    541                 "This returns an empty Properties object",
    542                 config.getProperties("prop.properties"),
    543                 new Properties());
    544         config.clearProperty("prop.properties");
    545         config.setProperty("prop.properties", "foo=bar, baz=moo, seal=clubber");
    546
    547         Properties p = new Properties();
    548         p.setProperty("foo", "bar");
    549         p.setProperty("baz", "moo");
    550         p.setProperty("seal", "clubber");
    551         assertEquals(
    552                 "This returns a filled in Properties object",
    553                 config.getProperties("prop.properties"),
    554                 p);
    555     }
    556
    557     public void testSubset()
    558     {
    559         /*
    560          * test subset : assure we don't reprocess the data elements
    561          * when generating the subset
    562          */
    563
    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");
    568
    569         Configuration subEprop = config.subset("prop");
    570
    571         assertEquals(
    572                 "Returns the full string",
    573                 prop,
    574                 subEprop.getString("string"));
    575         try
    576         {
    577             subEprop.getString("string");
    578         }
    579         catch (NoSuchElementException nsse)
    580         {
    581             fail("Should return a string");
    582         }
    583         try
    584         {
    585             subEprop.getList("string");
    586         }
    587         catch (NoSuchElementException nsse)
    588         {
    589             fail("Should return a list");
    590         }
    591
    592         Iterator it = subEprop.getKeys();
    593         it.next();
    594         assertFalse(it.hasNext());
    595
    596         subEprop = config.subset("prop.");
    597         it = subEprop.getKeys();
    598         assertFalse(it.hasNext());
    599     }
    600
    601     public void testInterpolation()
    602     {
    603         InterpolationTestHelper.testInterpolation(config);
    604     }
    605
    606     public void testMultipleInterpolation()
    607     {
    608         InterpolationTestHelper.testMultipleInterpolation(config);
    609     }
    610
    611     public void testInterpolationLoop()
    612     {
    613         InterpolationTestHelper.testInterpolationLoop(config);
    614     }
    615
    616     /***
    617      * Tests interpolation when a subset configuration is involved.
    618      */
    619     public void testInterpolationSubset()
    620     {
    621         InterpolationTestHelper.testInterpolationSubset(config);
    622     }
    623
    624     /***
    625      * Tests interpolation when the referred property is not found.
    626      */
    627     public void testInterpolationUnknownProperty()
    628     {
    629         InterpolationTestHelper.testInterpolationUnknownProperty(config);
    630     }
    631
    632     /***
    633      * Tests interpolation of system properties.
    634      */
    635     public void testInterpolationSystemProperties()
    636     {
    637         InterpolationTestHelper.testInterpolationSystemProperties(config);
    638     }
    639
    640     /***
    641      * Tests interpolation of constant values.
    642      */
    643     public void testInterpolationConstants()
    644     {
    645         InterpolationTestHelper.testInterpolationConstants(config);
    646     }
    647
    648     /***
    649      * Tests whether a variable can be escaped, so that it won't be
    650      * interpolated.
    651      */
    652     public void testInterpolationEscaped()
    653     {
    654         InterpolationTestHelper.testInterpolationEscaped(config);
    655     }
    656
    657     /***
    658      * Tests accessing and manipulating the interpolator object.
    659      */
    660     public void testGetInterpolator()
    661     {
    662         InterpolationTestHelper.testGetInterpolator(config);
    663     }
    664
    665     /***
    666      * Tests obtaining a configuration with all variables replaced by their
    667      * actual values.
    668      */
    669     public void testInterpolatedConfiguration()
    670     {
    671         InterpolationTestHelper.testInterpolatedConfiguration(config);
    672     }
    673
    674     public void testGetHexadecimalValue()
    675     {
    676         config.setProperty("number", "0xFF");
    677         assertEquals("byte value", (byte) 0xFF, config.getByte("number"));
    678
    679         config.setProperty("number", "0xFFFF");
    680         assertEquals("short value", (short) 0xFFFF, config.getShort("number"));
    681
    682         config.setProperty("number", "0xFFFFFFFF");
    683         assertEquals("int value", 0xFFFFFFFF, config.getInt("number"));
    684
    685         config.setProperty("number", "0xFFFFFFFFFFFFFFFF");
    686         assertEquals("long value", 0xFFFFFFFFFFFFFFFFL, config.getLong("number"));
    687
    688         assertEquals("long value", 0xFFFFFFFFFFFFFFFFL, config.getBigInteger("number").longValue());
    689     }
    690
    691     public void testResolveContainerStore()
    692     {
    693         AbstractConfiguration config = new BaseConfiguration();
    694
    695         // array of objects
    696         config.addPropertyDirect("array", new String[] { "foo", "bar" });
    697
    698         assertEquals("first element of the 'array' property", "foo", config.resolveContainerStore("array"));
    699
    700         // list of objects
    701         List list = new ArrayList();
    702         list.add("foo");
    703         list.add("bar");
    704         config.addPropertyDirect("list", list);
    705
    706         assertEquals("first element of the 'list' property", "foo", config.resolveContainerStore("list"));
    707
    708         // set of objects
    709         Set set = new ListOrderedSet();
    710         set.add("foo");
    711         set.add("bar");
    712         config.addPropertyDirect("set", set);
    713
    714         assertEquals("first element of the 'set' property", "foo", config.resolveContainerStore("set"));
    715
    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"));
    719
    720         config.addPropertyDirect("array.byte", new byte[] { 1, 2 });
    721         assertEquals("first element of the 'array.byte' property", 1, config.getByte("array.byte"));
    722
    723         config.addPropertyDirect("array.short", new short[] { 1, 2 });
    724         assertEquals("first element of the 'array.short' property", 1, config.getShort("array.short"));
    725
    726         config.addPropertyDirect("array.int", new int[] { 1, 2 });
    727         assertEquals("first element of the 'array.int' property", 1, config.getInt("array.int"));
    728
    729         config.addPropertyDirect("array.long", new long[] { 1, 2 });
    730         assertEquals("first element of the 'array.long' property", 1, config.getLong("array.long"));
    731
    732         config.addPropertyDirect("array.float", new float[] { 1, 2 });
    733         assertEquals("first element of the 'array.float' property", 1, config.getFloat("array.float"), 0);
    734
    735         config.addPropertyDirect("array.double", new double[] { 1, 2 });
    736         assertEquals("first element of the 'array.double' property", 1, config.getDouble("array.double"), 0);
    737     }
    738
    739     /***
    740      * Tests if conversion between number types is possible.
    741      */
    742     public void testNumberConversions()
    743     {
    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);
    753
    754         assertEquals("Wrong Long returned", new Long(42L), config.getLong(
    755                 KEY_NUMBER, null));
    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));
    760     }
    761
    762     /***
    763      * Tests cloning a BaseConfiguration.
    764      */
    765     public void testClone()
    766     {
    767         for (int i = 0; i < 10; i++)
    768         {
    769             config.addProperty("key" + i, new Integer(i));
    770         }
    771         BaseConfiguration config2 = (BaseConfiguration) config.clone();
    772
    773         for (Iterator it = config.getKeys(); it.hasNext();)
    774         {
    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));
    779         }
    780     }
    781
    782     /***
    783      * Tests whether a cloned configuration is decoupled from its original.
    784      */
    785     public void testCloneModify()
    786     {
    787         ConfigurationListener l = new ConfigurationListener()
    788         {
    789             public void configurationChanged(ConfigurationEvent event)
    790             {
    791                 // just a dummy
    792             }
    793         };
    794         config.addConfigurationListener(l);
    795         config.addProperty("original", Boolean.TRUE);
    796         BaseConfiguration config2 = (BaseConfiguration) config.clone();
    797
    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"));
    803
    804         assertEquals("Event listener was copied", 0, config2
    805                 .getConfigurationListeners().size());
    806     }
    807 }