    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.lang.reflect.Method;
    21  import java.math.BigDecimal;
    22  import java.util.Iterator;
    23  import java.util.List;
    24
    25  import org.apache.commons.lang.SystemUtils;
    26
    27  import junit.framework.TestCase;
    28
    29  /***
    30   * Test class for PropertyConverter.
    31   *
    32   * @author Emmanuel Bourg
    33   * @version $Revision: 662269 $, $Date: 2008-06-01 21:30:02 +0200 (So, 01 Jun 2008) $
    34   */
    35  public class TestPropertyConverter extends TestCase
    36  {
    37      public void testSplit()
    38      {
    39          String s = "abc, xyz , 123";
    40          List list = PropertyConverter.split(s, ',');
    41
    42          assertEquals("size", 3, list.size());
    43          assertEquals("1st token for '" + s + "'", "abc", list.get(0));
    44          assertEquals("2nd token for '" + s + "'", "xyz", list.get(1));
    45          assertEquals("3rd token for '" + s + "'", "123", list.get(2));
    46      }
    47
    48      public void testSplitNoTrim()
    49      {
    50          String s = "abc, xyz , 123";
    51          List list = PropertyConverter.split(s, ',', false);
    52
    53          assertEquals("size", 3, list.size());
    54          assertEquals("1st token for '" + s + "'", "abc", list.get(0));
    55          assertEquals("2nd token for '" + s + "'", " xyz ", list.get(1));
    56          assertEquals("3rd token for '" + s + "'", " 123", list.get(2));
    57      }
    58
    59      public void testSplitWithEscapedSeparator()
    60      {
    61          String s = "abc//,xyz, 123";
    62          List list = PropertyConverter.split(s, ',');
    63
    64          assertEquals("size", 2, list.size());
    65          assertEquals("1st token for '" + s + "'", "abc,xyz", list.get(0));
    66          assertEquals("2nd token for '" + s + "'", "123", list.get(1));
    67      }
    68
    69      public void testSplitEmptyValues()
    70      {
    71          String s = ",,";
    72          List list = PropertyConverter.split(s, ',');
    73
    74          assertEquals("size", 3, list.size());
    75          assertEquals("1st token for '" + s + "'", "", list.get(0));
    76          assertEquals("2nd token for '" + s + "'", "", list.get(1));
    77          assertEquals("3rd token for '" + s + "'", "", list.get(2));
    78      }
    79
    80      public void testSplitWithEndingSlash()
    81      {
    82          String s = "abc, xyz//";
    83          List list = PropertyConverter.split(s, ',');
    84
    85          assertEquals("size", 2, list.size());
    86          assertEquals("1st token for '" + s + "'", "abc", list.get(0));
    87          assertEquals("2nd token for '" + s + "'", "xyz//", list.get(1));
    88      }
    89
    90      public void testSplitNull()
    91      {
    92          List list = PropertyConverter.split(null, ',');
    93          assertNotNull(list);
    94          assertTrue(list.isEmpty());
    95      }
    96
    97      /***
    98       * Tests whether an escape character can be itself escaped.
    99       */
    100     public void testSplitEscapeEscapeChar()
    101     {
    102         List list = PropertyConverter.split("C://Temp////,xyz", ',');
    103         assertEquals("Wrong list size", 2, list.size());
    104         assertEquals("Wrong element 1", "C://Temp//", list.get(0));
    105         assertEquals("Wrong element 2", "xyz", list.get(1));
    106     }
    107
    108     /***
    109      * Tests whether delimiters are correctly escaped.
    110      */
    111     public void testEscapeDelimiters()
    112     {
    113         assertEquals("Wrong escaped delimiters",
    114                 "C:////Temp//////,D:////Data////", PropertyConverter
    115                         .escapeDelimiters("C://Temp//,D://Data//", ','));
    116     }
    117
    118     public void testToIterator()
    119     {
    120         int[] array = new int[]{1, 2, 3};
    121
    122         Iterator it = PropertyConverter.toIterator(array, ',');
    123
    124         assertEquals("1st element", new Integer(1), it.next());
    125         assertEquals("2nd element", new Integer(2), it.next());
    126         assertEquals("3rd element", new Integer(3), it.next());
    127     }
    128
    129     /***
    130      * Tests the interpolation features.
    131      */
    132     public void testInterpolateString()
    133     {
    134         PropertiesConfiguration config = new PropertiesConfiguration();
    135         config.addProperty("animal", "quick brown fox");
    136         config.addProperty("target", "lazy dog");
    137         assertEquals("Wrong interpolation",
    138                 "The quick brown fox jumps over the lazy dog.",
    139                 PropertyConverter.interpolate("The ${animal} jumps over the ${target}.", config));
    140     }
    141
    142     /***
    143      * Tests interpolation of an object. Here nothing should be substituted.
    144      */
    145     public void testInterpolateObject()
    146     {
    147         assertEquals("Object was not correctly interpolated", new Integer(42),
    148                 PropertyConverter.interpolate(new Integer(42), new PropertiesConfiguration()));
    149     }
    150
    151     /***
    152      * Tests complex interpolation where the variables' values contain in turn
    153      * other variables.
    154      */
    155     public void testInterpolateRecursive()
    156     {
    157         PropertiesConfiguration config = new PropertiesConfiguration();
    158         config.addProperty("animal", "${animal_attr} fox");
    159         config.addProperty("target", "${target_attr} dog");
    160         config.addProperty("animal_attr", "quick brown");
    161         config.addProperty("target_attr", "lazy");
    162         assertEquals("Wrong complex interpolation",
    163                 "The quick brown fox jumps over the lazy dog.",
    164                 PropertyConverter.interpolate("The ${animal} jumps over the ${target}.", config));
    165     }
    166
    167     /***
    168      * Tests an interpolation that leads to a cycle. This should throw an
    169      * exception.
    170      */
    171     public void testCyclicInterpolation()
    172     {
    173         PropertiesConfiguration config = new PropertiesConfiguration();
    174         config.addProperty("animal", "${animal_attr} ${species}");
    175         config.addProperty("animal_attr", "quick brown");
    176         config.addProperty("species", "${animal}");
    177         try
    178         {
    179             PropertyConverter.interpolate("This is a ${animal}", config);
    180             fail("Cyclic interpolation was not detected!");
    181         }
    182         catch (IllegalStateException iex)
    183         {
    184             // ok
    185         }
    186     }
    187
    188     /***
    189      * Tests interpolation if a variable is unknown. Then the variable won't be
    190      * substituted.
    191      */
    192     public void testInterpolationUnknownVariable()
    193     {
    194         PropertiesConfiguration config = new PropertiesConfiguration();
    195         config.addProperty("animal", "quick brown fox");
    196         assertEquals("Wrong interpolation",
    197                 "The quick brown fox jumps over ${target}.",
    198                 PropertyConverter.interpolate("The ${animal} jumps over ${target}.", config));
    199     }
    200
    201     /***
    202      * Tests conversion to numbers when the passed in objects are already
    203      * numbers.
    204      */
    205     public void testToNumberDirect()
    206     {
    207         Integer i = new Integer(42);
    208         assertSame("Wrong integer", i, PropertyConverter.toNumber(i, Integer.class));
    209         BigDecimal d = new BigDecimal("3.1415");
    210         assertSame("Wrong BigDecimal", d, PropertyConverter.toNumber(d, Integer.class));
    211     }
    212
    213     /***
    214      * Tests conversion to numbers when the passed in objects have a compatible
    215      * string representation.
    216      */
    217     public void testToNumberFromString()
    218     {
    219         assertEquals("Incorrect Integer value", new Integer(42), PropertyConverter.toNumber("42", Integer.class));
    220         assertEquals("Incorrect Short value", new Short((short) 10), PropertyConverter.toNumber(new StringBuffer("10"), Short.class));
    221     }
    222
    223     /***
    224      * Tests conversion to numbers when the passed in objects are strings with
    225      * prefixes for special radices.
    226      */
    227     public void testToNumberFromHexString()
    228     {
    229         Number n = PropertyConverter.toNumber("0x10", Integer.class);
    230         assertEquals("Incorrect Integer value", 16, n.intValue());
    231     }
    232
    233     /***
    234      * Tests conversion to numbers when an invalid Hex value is passed in. This
    235      * should cause an exception.
    236      */
    237     public void testToNumberFromInvalidHexString()
    238     {
    239         try
    240         {
    241             PropertyConverter.toNumber("0xNotAHexValue", Integer.class);
    242             fail("Could convert invalid hex value!");
    243         }
    244         catch (ConversionException cex)
    245         {
    246             // ok
    247         }
    248     }
    249
    250     /***
    251      * Tests conversion to numbers when the passed in objects have no numeric
    252      * String representation. This should cause an exception.
    253      */
    254     public void testToNumberFromInvalidString()
    255     {
    256         try
    257         {
    258             PropertyConverter.toNumber("Not a number", Byte.class);
    259             fail("Could convert invalid String!");
    260         }
    261         catch (ConversionException cex)
    262         {
    263             // ok
    264         }
    265     }
    266
    267     /***
    268      * Tests conversion to numbers when the passed in target class is invalid.
    269      * This should cause an exception.
    270      */
    271     public void testToNumberWithInvalidClass()
    272     {
    273         try
    274         {
    275             PropertyConverter.toNumber("42", Object.class);
    276             fail("Could convert to invalid target class!");
    277         }
    278         catch (ConversionException cex)
    279         {
    280             //ok
    281         }
    282     }
    283
    284     // enumeration type used for the tests, Java 5 only
    285     private Class enumClass;
    286     private Object enumObject;
    287     {
    288         if (SystemUtils.isJavaVersionAtLeast(1.5f))
    289         {
    290             try
    291             {
    292                 enumClass = Class.forName("java.lang.annotation.ElementType");
    293
    294                 Method valueOfMethod = enumClass.getMethod("valueOf", new Class[] { String.class });
    295                 enumObject = valueOfMethod.invoke(null, new Object[] { "METHOD" });
    296             }
    297             catch (Exception e)
    298             {
    299             }
    300         }
    301     }
    302
    303     public void testToEnumFromEnum()
    304     {
    305         if (!SystemUtils.isJavaVersionAtLeast(1.5f))
    306         {
    307             return;
    308         }
    309
    310         assertEquals(enumObject, PropertyConverter.toEnum(enumObject, enumClass));
    311     }
    312
    313     public void testToEnumFromString()
    314     {
    315         if (!SystemUtils.isJavaVersionAtLeast(1.5f))
    316         {
    317             return;
    318         }
    319
    320         assertEquals(enumObject, PropertyConverter.toEnum("METHOD", enumClass));
    321     }
    322
    323     public void testToEnumFromInvalidString()
    324     {
    325         if (!SystemUtils.isJavaVersionAtLeast(1.5f))
    326         {
    327             return;
    328         }
    329
    330         try
    331         {
    332             assertEquals(enumObject, PropertyConverter.toEnum("FOO", enumClass));
    333             fail("Could convert invalid String!");
    334         }
    335         catch (ConversionException e)
    336         {
    337             // expected
    338         }
    339     }
    340
    341     public void testToEnumFromNumber()
    342     {
    343         if (!SystemUtils.isJavaVersionAtLeast(1.5f))
    344         {
    345             return;
    346         }
    347
    348         assertEquals(enumObject, PropertyConverter.toEnum(new Integer(2), enumClass));
    349     }
    350
    351     public void testToEnumFromInvalidNumber()
    352     {
    353         if (!SystemUtils.isJavaVersionAtLeast(1.5f))
    354         {
    355             return;
    356         }
    357
    358         try
    359         {
    360             assertEquals(enumObject, PropertyConverter.toEnum(new Integer(-1), enumClass));
    361             fail("Could convert invalid number!");
    362         }
    363         catch (ConversionException e)
    364         {
    365             // expected
    366         }
    367     }
    368 }