    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.plist;
    19
    20  import java.io.File;
    21  import java.io.StringReader;
    22  import java.util.Calendar;
    23  import java.util.Iterator;
    24  import java.util.List;
    25  import java.util.Date;
    26  import java.util.TimeZone;
    27
    28  import junit.framework.TestCase;
    29  import junitx.framework.ArrayAssert;
    30  import junitx.framework.ListAssert;
    31  import junitx.framework.ObjectAssert;
    32  import org.apache.commons.configuration.Configuration;
    33  import org.apache.commons.configuration.ConfigurationComparator;
    34  import org.apache.commons.configuration.ConfigurationException;
    35  import org.apache.commons.configuration.StrictConfigurationComparator;
    36
    37  /***
    38   * @author Emmanuel Bourg
    39   * @version $Revision: 590474 $, $Date: 2007-10-30 22:35:11 +0100 (Di, 30 Okt 2007) $
    40   */
    41  public class TestPropertyListConfiguration extends TestCase
    42  {
    43      private PropertyListConfiguration config;
    44
    45      private String testProperties = new File("conf/test.plist").getAbsolutePath();
    46
    47      protected void setUp() throws Exception
    48      {
    49          config = new PropertyListConfiguration();
    50          config.setFileName(testProperties);
    51          config.load();
    52      }
    53
    54      public void testLoad()
    55      {
    56          assertFalse("the configuration is empty", config.isEmpty());
    57      }
    58
    59      public void testLoadWithError()
    60      {
    61          config = new PropertyListConfiguration();
    62          try {
    63              config.load(new StringReader(""));
    64              fail("No exception thrown on loading an empty file");
    65          } catch (ConfigurationException e) {
    66              // expected
    67              assertNotNull(e.getMessage());
    68          }
    69      }
    70
    71      public void testString()
    72      {
    73          assertEquals("simple-string", "string1", config.getProperty("simple-string"));
    74      }
    75
    76      public void testQuotedString()
    77      {
    78          assertEquals("quoted-string", "string2", config.getProperty("quoted-string"));
    79          assertEquals("quoted-string2", "this is a string", config.getProperty("quoted-string2"));
    80          assertEquals("complex-string", "this is a \"complex\" string {(=,;)}", config.getProperty("complex-string"));
    81      }
    82
    83      public void testEmptyArray()
    84      {
    85          String key = "empty-array";
    86          assertNotNull("array null", config.getProperty(key));
    87
    88          List list = (List) config.getProperty(key);
    89          assertTrue("array is not empty", list.isEmpty());
    90      }
    91
    92      public void testArray()
    93      {
    94          String key = "array";
    95          assertNotNull("array null", config.getProperty(key));
    96
    97          List list = (List) config.getProperty(key);
    98          assertFalse("array is empty", list.isEmpty());
    99
    100         assertEquals("1st value", "value1", list.get(0));
    101         assertEquals("2nd value", "value2", list.get(1));
    102         assertEquals("3rd value", "value3", list.get(2));
    103     }
    104
    105     public void testNestedArrays()
    106     {
    107         String key = "nested-arrays";
    108
    109         Object array = config.getProperty(key);
    110
    111         // root array
    112         assertNotNull("array not found", array);
    113         ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array);
    114         List list = config.getList(key);
    115
    116         assertFalse("empty array", list.isEmpty());
    117         assertEquals("size", 2, list.size());
    118
    119         // 1st array
    120         ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(0));
    121         List list1 = (List) list.get(0);
    122         assertFalse("nested array 1 is empty", list1.isEmpty());
    123         assertEquals("size", 2, list1.size());
    124         assertEquals("1st element", "a", list1.get(0));
    125         assertEquals("2nd element", "b", list1.get(1));
    126
    127         // 2nd array
    128         ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(1));
    129         List list2 = (List) list.get(1);
    130         assertFalse("nested array 2 is empty", list2.isEmpty());
    131         assertEquals("size", 2, list2.size());
    132         assertEquals("1st element", "c", list2.get(0));
    133         assertEquals("2nd element", "d", list2.get(1));
    134     }
    135
    136     public void testDictionary()
    137     {
    138         assertEquals("1st element in dictionary", "bar1", config.getProperty("dictionary.foo1"));
    139         assertEquals("2nd element in dictionary", "bar2", config.getProperty("dictionary.foo2"));
    140     }
    141
    142     public void testDictionaryArray()
    143     {
    144         String key = "dictionary-array";
    145
    146         Object array = config.getProperty(key);
    147
    148         // root array
    149         assertNotNull("array not found", array);
    150         ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array);
    151         List list = config.getList(key);
    152
    153         assertFalse("empty array", list.isEmpty());
    154         assertEquals("size", 2, list.size());
    155
    156         // 1st dictionary
    157         ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(0));
    158         Configuration conf1 = (Configuration) list.get(0);
    159         assertFalse("configuration 1 is empty", conf1.isEmpty());
    160         assertEquals("configuration element", "bar", conf1.getProperty("foo"));
    161
    162         // 2nd dictionary
    163         ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(1));
    164         Configuration conf2 = (Configuration) list.get(1);
    165         assertFalse("configuration 2 is empty", conf2.isEmpty());
    166         assertEquals("configuration element", "value", conf2.getProperty("key"));
    167     }
    168
    169     public void testNestedDictionaries()
    170     {
    171         assertEquals("nested property", "value", config.getString("nested-dictionaries.foo.bar.key"));
    172     }
    173
    174     public void testData()
    175     {
    176         ObjectAssert.assertInstanceOf("data", (new byte[0]).getClass(), config.getProperty("data"));
    177         ArrayAssert.assertEquals("data", "foo bar".getBytes(), (byte[]) config.getProperty("data"));
    178     }
    179
    180     public void testDate() throws Exception
    181     {
    182         Calendar cal = Calendar.getInstance();
    183         cal.clear();
    184         cal.set(2002, 2, 22, 11, 30, 0);
    185         cal.setTimeZone(TimeZone.getTimeZone("GMT+0100"));
    186         Date date = cal.getTime();
    187
    188         assertEquals("date", date, config.getProperty("date"));
    189     }
    190
    191     public void testSave() throws Exception
    192     {
    193         File savedFile = new File("target/testsave.plist");
    194
    195         // remove the file previously saved if necessary
    196         if (savedFile.exists())
    197         {
    198             assertTrue(savedFile.delete());
    199         }
    200
    201         // save the configuration
    202         String filename = savedFile.getAbsolutePath();
    203         config.save(filename);
    204
    205         assertTrue("The saved file doesn't exist", savedFile.exists());
    206
    207         // read the configuration and compare the properties
    208         Configuration checkConfig = new PropertyListConfiguration(new File(filename));
    209
    210         Iterator it = config.getKeys();
    211         while (it.hasNext())
    212         {
    213             String key = (String) it.next();
    214             assertTrue("The saved configuration doesn't contain the key '" + key + "'", checkConfig.containsKey(key));
    215
    216             Object value = checkConfig.getProperty(key);
    217             if (value instanceof byte[])
    218             {
    219                 byte[] array = (byte[]) value;
    220                 ArrayAssert.assertEquals("Value of the '" + key + "' property", (byte[]) config.getProperty(key), array);
    221             }
    222             else if (value instanceof List)
    223             {
    224                 List list1 = (List) config.getProperty(key);
    225                 List list2 = (List) value;
    226
    227                 assertEquals("The size of the list for the key '" + key + "' doesn't match", list1.size(), list2.size());
    228
    229                 for (int i = 0; i < list2.size(); i++)
    230                 {
    231                     Object value1 = list1.get(i);
    232                     Object value2 = list2.get(i);
    233
    234                     if (value1 instanceof Configuration)
    235                     {
    236                         ConfigurationComparator comparator = new StrictConfigurationComparator();
    237                         assertTrue("The dictionnary at index " + i + " for the key '" + key + "' doesn't match", comparator.compare((Configuration) value1, (Configuration) value2));
    238                     }
    239                     else
    240                     {
    241                         assertEquals("Element at index " + i + " for the key '" + key + "'", value1, value2);
    242                     }
    243                 }
    244
    245                 ListAssert.assertEquals("Value of the '" + key + "' property", (List) config.getProperty(key), list1);
    246             }
    247             else
    248             {
    249                 assertEquals("Value of the '" + key + "' property", config.getProperty(key), checkConfig.getProperty(key));
    250             }
    251
    252         }
    253     }
    254
    255     public void testQuoteString()
    256     {
    257         assertEquals("null string", null, config.quoteString(null));
    258         assertEquals("simple string", "abcd", config.quoteString("abcd"));
    259         assertEquals("string with a space", "\"ab cd\"", config.quoteString("ab cd"));
    260         assertEquals("string with a quote", "\"foo//\"bar\"", config.quoteString("foo\"bar"));
    261         assertEquals("string with a special char", "\"foo;bar\"", config.quoteString("foo;bar"));
    262     }
    263
    264     /***
    265      * Ensure that setProperty doesn't alter an array of byte
    266      * since it's a first class type in plist file
    267      */
    268     public void testSetDataProperty() throws Exception
    269     {
    270         byte[] expected = new byte[]{1, 2, 3, 4};
    271         PropertyListConfiguration config = new PropertyListConfiguration();
    272         config.setProperty("foo", expected);
    273         config.save("target/testdata.plist");
    274
    275         PropertyListConfiguration config2 = new PropertyListConfiguration("target/testdata.plist");
    276         Object array = config2.getProperty("foo");
    277
    278         assertNotNull("data not found", array);
    279         assertEquals("property type", byte[].class, array.getClass());
    280         ArrayAssert.assertEquals(expected, (byte[]) array);
    281     }
    282
    283     /***
    284      * Ensure that addProperty doesn't alter an array of byte
    285      */
    286     public void testAddDataProperty() throws Exception
    287     {
    288         byte[] expected = new byte[]{1, 2, 3, 4};
    289         PropertyListConfiguration config = new PropertyListConfiguration();
    290         config.addProperty("foo", expected);
    291         config.save("target/testdata.plist");
    292
    293         PropertyListConfiguration config2 = new PropertyListConfiguration("target/testdata.plist");
    294         Object array = config2.getProperty("foo");
    295
    296         assertNotNull("data not found", array);
    297         assertEquals("property type", byte[].class, array.getClass());
    298         ArrayAssert.assertEquals(expected, (byte[]) array);
    299     }
    300
    301     public void testInitCopy()
    302     {
    303     	PropertyListConfiguration copy = new PropertyListConfiguration(config);
    304     	assertFalse("Nothing was copied", copy.isEmpty());
    305     }
    306
    307     /***
    308      * Tests parsing a date with an invalid numeric value.
    309      */
    310     public void testParseDateNoNumber()
    311     {
    312         try
    313         {
    314             PropertyListConfiguration
    315                     .parseDate("<*D2002-03-22 1c:30:00 +0100>");
    316             fail("Could parse date with an invalid number!");
    317         }
    318         catch (ParseException pex)
    319         {
    320             // ok
    321         }
    322     }
    323
    324     /***
    325      * Tests parsing a date that is not long enough.
    326      */
    327     public void testParseDateTooShort()
    328     {
    329         try
    330         {
    331             PropertyListConfiguration.parseDate("<*D2002-03-22 11:3>");
    332             fail("Could parse too short date!");
    333         }
    334         catch (ParseException pex)
    335         {
    336             // ok
    337         }
    338     }
    339
    340     /***
    341      * Tests parsing a date that contains an invalid separator character.
    342      */
    343     public void testParseDateInvalidChar()
    344     {
    345         try
    346         {
    347             PropertyListConfiguration
    348                     .parseDate("<*D2002+03-22 11:30:00 +0100>");
    349             fail("Could parse date with an invalid separator!");
    350         }
    351         catch (ParseException pex)
    352         {
    353             // ok
    354         }
    355     }
    356
    357     /***
    358      * Tries parsing a null date. This should cause an exception.n
    359      */
    360     public void testParseDateNull()
    361     {
    362         try
    363         {
    364             PropertyListConfiguration.parseDate(null);
    365             fail("Could parse null date!");
    366         }
    367         catch (ParseException pex)
    368         {
    369             // ok
    370         }
    371     }
    372
    373     /***
    374      * Tests formatting a date.
    375      */
    376     public void testFormatDate()
    377     {
    378         Calendar cal = Calendar.getInstance();
    379         cal.clear();
    380         cal.set(2007, 9, 29, 23, 4, 30);
    381         cal.setTimeZone(TimeZone.getTimeZone("GMT-0230"));
    382         assertEquals("Wrong date literal (1)", "<*D2007-10-29 23:04:30 -0230>",
    383                 PropertyListConfiguration.formatDate(cal));
    384         cal.clear();
    385         cal.set(2007, 9, 30, 22, 2, 15);
    386         cal.setTimeZone(TimeZone.getTimeZone("GMT+1111"));
    387         assertEquals("Wrong date literal (2)", "<*D2007-10-30 22:02:15 +1111>",
    388                 PropertyListConfiguration.formatDate(cal));
    389     }
    390 }