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