001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.configuration; 019 020 import static org.junit.Assert.assertEquals; 021 import static org.junit.Assert.assertNotNull; 022 import static org.junit.Assert.assertSame; 023 import static org.junit.Assert.assertTrue; 024 025 import java.lang.annotation.ElementType; 026 import java.math.BigDecimal; 027 import java.util.Iterator; 028 import java.util.List; 029 030 import org.junit.Test; 031 032 /** 033 * Test class for PropertyConverter. 034 * 035 * @author Emmanuel Bourg 036 * @version $Id: TestPropertyConverter.java 1301990 2012-03-17 20:10:46Z oheger $ 037 */ 038 public class TestPropertyConverter 039 { 040 /** Constant for an enumeration class used by some tests. */ 041 private static final Class<ElementType> ENUM_CLASS = ElementType.class; 042 043 @Test 044 public void testSplit() 045 { 046 String s = "abc, xyz , 123"; 047 List<String> list = PropertyConverter.split(s, ','); 048 049 assertEquals("size", 3, list.size()); 050 assertEquals("1st token for '" + s + "'", "abc", list.get(0)); 051 assertEquals("2nd token for '" + s + "'", "xyz", list.get(1)); 052 assertEquals("3rd token for '" + s + "'", "123", list.get(2)); 053 } 054 055 @Test 056 public void testSplitNoTrim() 057 { 058 String s = "abc, xyz , 123"; 059 List<String> list = PropertyConverter.split(s, ',', false); 060 061 assertEquals("size", 3, list.size()); 062 assertEquals("1st token for '" + s + "'", "abc", list.get(0)); 063 assertEquals("2nd token for '" + s + "'", " xyz ", list.get(1)); 064 assertEquals("3rd token for '" + s + "'", " 123", list.get(2)); 065 } 066 067 @Test 068 public void testSplitWithEscapedSeparator() 069 { 070 String s = "abc\\,xyz, 123"; 071 List<String> list = PropertyConverter.split(s, ','); 072 073 assertEquals("size", 2, list.size()); 074 assertEquals("1st token for '" + s + "'", "abc,xyz", list.get(0)); 075 assertEquals("2nd token for '" + s + "'", "123", list.get(1)); 076 } 077 078 @Test 079 public void testSplitEmptyValues() 080 { 081 String s = ",,"; 082 List<String> list = PropertyConverter.split(s, ','); 083 084 assertEquals("size", 3, list.size()); 085 assertEquals("1st token for '" + s + "'", "", list.get(0)); 086 assertEquals("2nd token for '" + s + "'", "", list.get(1)); 087 assertEquals("3rd token for '" + s + "'", "", list.get(2)); 088 } 089 090 @Test 091 public void testSplitWithEndingSlash() 092 { 093 String s = "abc, xyz\\"; 094 List<String> list = PropertyConverter.split(s, ','); 095 096 assertEquals("size", 2, list.size()); 097 assertEquals("1st token for '" + s + "'", "abc", list.get(0)); 098 assertEquals("2nd token for '" + s + "'", "xyz\\", list.get(1)); 099 } 100 101 @Test 102 public void testSplitNull() 103 { 104 List<String> list = PropertyConverter.split(null, ','); 105 assertNotNull(list); 106 assertTrue(list.isEmpty()); 107 } 108 109 /** 110 * Tests whether an escape character can be itself escaped. 111 */ 112 @Test 113 public void testSplitEscapeEscapeChar() 114 { 115 List<String> list = PropertyConverter.split("C:\\Temp\\\\,xyz", ','); 116 assertEquals("Wrong list size", 2, list.size()); 117 assertEquals("Wrong element 1", "C:\\Temp\\", list.get(0)); 118 assertEquals("Wrong element 2", "xyz", list.get(1)); 119 } 120 121 /** 122 * Tests whether delimiters are correctly escaped. 123 */ 124 @Test 125 public void testEscapeDelimiters() 126 { 127 assertEquals("Wrong escaped delimiters", 128 "C:\\\\Temp\\\\\\,D:\\\\Data\\\\", PropertyConverter 129 .escapeDelimiters("C:\\Temp\\,D:\\Data\\", ',')); 130 } 131 132 /** 133 * Tests whether only the list delimiter can be escaped. 134 */ 135 @Test 136 public void testEscapeListDelimiter() 137 { 138 assertEquals("Wrong escaped list delimiter", "C:\\Temp\\\\,D:\\Data\\", 139 PropertyConverter.escapeListDelimiter("C:\\Temp\\,D:\\Data\\", 140 ',')); 141 } 142 143 @Test 144 public void testToIterator() 145 { 146 int[] array = new int[]{1, 2, 3}; 147 148 Iterator<?> it = PropertyConverter.toIterator(array, ','); 149 150 assertEquals("1st element", new Integer(1), it.next()); 151 assertEquals("2nd element", new Integer(2), it.next()); 152 assertEquals("3rd element", new Integer(3), it.next()); 153 } 154 155 /** 156 * Tests the interpolation features. 157 */ 158 @Test 159 public void testInterpolateString() 160 { 161 PropertiesConfiguration config = new PropertiesConfiguration(); 162 config.addProperty("animal", "quick brown fox"); 163 config.addProperty("target", "lazy dog"); 164 assertEquals("Wrong interpolation", 165 "The quick brown fox jumps over the lazy dog.", 166 PropertyConverter.interpolate("The ${animal} jumps over the ${target}.", config)); 167 } 168 169 /** 170 * Tests interpolation of an object. Here nothing should be substituted. 171 */ 172 @Test 173 public void testInterpolateObject() 174 { 175 assertEquals("Object was not correctly interpolated", new Integer(42), 176 PropertyConverter.interpolate(new Integer(42), new PropertiesConfiguration())); 177 } 178 179 /** 180 * Tests complex interpolation where the variables' values contain in turn 181 * other variables. 182 */ 183 @Test 184 public void testInterpolateRecursive() 185 { 186 PropertiesConfiguration config = new PropertiesConfiguration(); 187 config.addProperty("animal", "${animal_attr} fox"); 188 config.addProperty("target", "${target_attr} dog"); 189 config.addProperty("animal_attr", "quick brown"); 190 config.addProperty("target_attr", "lazy"); 191 assertEquals("Wrong complex interpolation", 192 "The quick brown fox jumps over the lazy dog.", 193 PropertyConverter.interpolate("The ${animal} jumps over the ${target}.", config)); 194 } 195 196 /** 197 * Tests an interpolation that leads to a cycle. This should throw an 198 * exception. 199 */ 200 @Test(expected = IllegalStateException.class) 201 public void testCyclicInterpolation() 202 { 203 PropertiesConfiguration config = new PropertiesConfiguration(); 204 config.addProperty("animal", "${animal_attr} ${species}"); 205 config.addProperty("animal_attr", "quick brown"); 206 config.addProperty("species", "${animal}"); 207 PropertyConverter.interpolate("This is a ${animal}", config); 208 } 209 210 /** 211 * Tests interpolation if a variable is unknown. Then the variable won't be 212 * substituted. 213 */ 214 @Test 215 public void testInterpolationUnknownVariable() 216 { 217 PropertiesConfiguration config = new PropertiesConfiguration(); 218 config.addProperty("animal", "quick brown fox"); 219 assertEquals("Wrong interpolation", 220 "The quick brown fox jumps over ${target}.", 221 PropertyConverter.interpolate("The ${animal} jumps over ${target}.", config)); 222 } 223 224 /** 225 * Tests conversion to numbers when the passed in objects are already 226 * numbers. 227 */ 228 @Test 229 public void testToNumberDirect() 230 { 231 Integer i = new Integer(42); 232 assertSame("Wrong integer", i, PropertyConverter.toNumber(i, Integer.class)); 233 BigDecimal d = new BigDecimal("3.1415"); 234 assertSame("Wrong BigDecimal", d, PropertyConverter.toNumber(d, Integer.class)); 235 } 236 237 /** 238 * Tests conversion to numbers when the passed in objects have a compatible 239 * string representation. 240 */ 241 @Test 242 public void testToNumberFromString() 243 { 244 assertEquals("Incorrect Integer value", new Integer(42), PropertyConverter.toNumber("42", Integer.class)); 245 assertEquals("Incorrect Short value", new Short((short) 10), PropertyConverter.toNumber(new StringBuffer("10"), Short.class)); 246 } 247 248 /** 249 * Tests conversion to numbers when the passed in objects are strings with 250 * prefixes for special radices. 251 */ 252 @Test 253 public void testToNumberFromHexString() 254 { 255 Number n = PropertyConverter.toNumber("0x10", Integer.class); 256 assertEquals("Incorrect Integer value", 16, n.intValue()); 257 } 258 259 /** 260 * Tests conversion to numbers when an invalid Hex value is passed in. 261 * This should cause an exception. 262 */ 263 @Test(expected = ConversionException.class) 264 public void testToNumberFromInvalidHexString() 265 { 266 PropertyConverter.toNumber("0xNotAHexValue", Integer.class); 267 } 268 269 /** 270 * Tests conversion to numbers when the passed in objects are strings with 271 * prefixes for special radices. 272 */ 273 @Test 274 public void testToNumberFromBinaryString() 275 { 276 Number n = PropertyConverter.toNumber("0b1111", Integer.class); 277 assertEquals("Incorrect Integer value", 15, n.intValue()); 278 } 279 280 /** 281 * Tests conversion to numbers when an invalid binary value is passed in. 282 * This should cause an exception. 283 */ 284 @Test(expected = ConversionException.class) 285 public void testToNumberFromInvalidBinaryString() 286 { 287 PropertyConverter.toNumber("0bNotABinValue", Integer.class); 288 } 289 290 /** 291 * Tests conversion to numbers when the passed in objects have no numeric 292 * String representation. This should cause an exception. 293 */ 294 @Test(expected = ConversionException.class) 295 public void testToNumberFromInvalidString() 296 { 297 PropertyConverter.toNumber("Not a number", Byte.class); 298 } 299 300 /** 301 * Tests conversion to numbers when the passed in target class is invalid. 302 * This should cause an exception. 303 */ 304 @Test(expected = ConversionException.class) 305 public void testToNumberWithInvalidClass() 306 { 307 PropertyConverter.toNumber("42", Object.class); 308 } 309 310 @Test 311 public void testToEnumFromEnum() 312 { 313 assertEquals(ElementType.METHOD, PropertyConverter.toEnum(ElementType.METHOD, ENUM_CLASS)); 314 } 315 316 @Test 317 public void testToEnumFromString() 318 { 319 assertEquals(ElementType.METHOD, PropertyConverter.toEnum("METHOD", ENUM_CLASS)); 320 } 321 322 @Test(expected = ConversionException.class) 323 public void testToEnumFromInvalidString() 324 { 325 PropertyConverter.toEnum("FOO", ENUM_CLASS); 326 } 327 328 @Test 329 public void testToEnumFromNumber() 330 { 331 assertEquals(ElementType.METHOD, PropertyConverter.toEnum( 332 Integer.valueOf(ElementType.METHOD.ordinal()), 333 ENUM_CLASS)); 334 } 335 336 @Test(expected = ConversionException.class) 337 public void testToEnumFromInvalidNumber() 338 { 339 PropertyConverter.toEnum(Integer.valueOf(-1), ENUM_CLASS); 340 } 341 342 /** 343 * Tests a trivial conversion: the value has already the desired type. 344 */ 345 @Test 346 public void testToNoConversionNeeded() 347 { 348 String value = "testValue"; 349 assertEquals("Wrong conversion result", value, 350 PropertyConverter.to(String.class, value, null)); 351 } 352 }