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.plist; 019 020 import static org.junit.Assert.assertEquals; 021 import static org.junit.Assert.assertFalse; 022 import static org.junit.Assert.assertNotNull; 023 import static org.junit.Assert.assertTrue; 024 import static org.junit.Assert.fail; 025 026 import java.io.File; 027 import java.io.StringReader; 028 import java.util.Calendar; 029 import java.util.Date; 030 import java.util.Iterator; 031 import java.util.List; 032 import java.util.TimeZone; 033 034 import junitx.framework.ArrayAssert; 035 import junitx.framework.ListAssert; 036 import junitx.framework.ObjectAssert; 037 038 import org.apache.commons.configuration.Configuration; 039 import org.apache.commons.configuration.ConfigurationAssert; 040 import org.apache.commons.configuration.ConfigurationComparator; 041 import org.apache.commons.configuration.ConfigurationException; 042 import org.apache.commons.configuration.StrictConfigurationComparator; 043 import org.junit.Before; 044 import org.junit.Test; 045 046 /** 047 * @author Emmanuel Bourg 048 * @version $Id: TestPropertyListConfiguration.java 1225902 2011-12-30 19:46:24Z oheger $ 049 */ 050 public class TestPropertyListConfiguration 051 { 052 private PropertyListConfiguration config; 053 054 private String testProperties = ConfigurationAssert.getTestFile("test.plist").getAbsolutePath(); 055 056 @Before 057 public void setUp() throws Exception 058 { 059 config = new PropertyListConfiguration(); 060 config.setFileName(testProperties); 061 config.load(); 062 } 063 064 @Test 065 public void testLoad() 066 { 067 assertFalse("the configuration is empty", config.isEmpty()); 068 } 069 070 @Test 071 public void testLoadWithError() 072 { 073 config = new PropertyListConfiguration(); 074 try { 075 config.load(new StringReader("")); 076 fail("No exception thrown on loading an empty file"); 077 } catch (ConfigurationException e) { 078 // expected 079 assertNotNull(e.getMessage()); 080 } 081 } 082 083 @Test 084 public void testString() 085 { 086 assertEquals("simple-string", "string1", config.getProperty("simple-string")); 087 } 088 089 @Test 090 public void testQuotedString() 091 { 092 assertEquals("quoted-string", "string2", config.getProperty("quoted-string")); 093 assertEquals("quoted-string2", "this is a string", config.getProperty("quoted-string2")); 094 assertEquals("complex-string", "this is a \"complex\" string {(=,;)}", config.getProperty("complex-string")); 095 } 096 097 @Test 098 public void testEmptyArray() 099 { 100 String key = "empty-array"; 101 assertNotNull("array null", config.getProperty(key)); 102 103 List<?> list = (List<?>) config.getProperty(key); 104 assertTrue("array is not empty", list.isEmpty()); 105 } 106 107 @Test 108 public void testArray() 109 { 110 String key = "array"; 111 assertNotNull("array null", config.getProperty(key)); 112 113 List<?> list = (List<?>) config.getProperty(key); 114 assertFalse("array is empty", list.isEmpty()); 115 116 assertEquals("1st value", "value1", list.get(0)); 117 assertEquals("2nd value", "value2", list.get(1)); 118 assertEquals("3rd value", "value3", list.get(2)); 119 } 120 121 @Test 122 public void testNestedArrays() 123 { 124 String key = "nested-arrays"; 125 126 Object array = config.getProperty(key); 127 128 // root array 129 assertNotNull("array not found", array); 130 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array); 131 List<?> list = config.getList(key); 132 133 assertFalse("empty array", list.isEmpty()); 134 assertEquals("size", 2, list.size()); 135 136 // 1st array 137 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(0)); 138 List<?> list1 = (List<?>) list.get(0); 139 assertFalse("nested array 1 is empty", list1.isEmpty()); 140 assertEquals("size", 2, list1.size()); 141 assertEquals("1st element", "a", list1.get(0)); 142 assertEquals("2nd element", "b", list1.get(1)); 143 144 // 2nd array 145 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, list.get(1)); 146 List<?> list2 = (List<?>) list.get(1); 147 assertFalse("nested array 2 is empty", list2.isEmpty()); 148 assertEquals("size", 2, list2.size()); 149 assertEquals("1st element", "c", list2.get(0)); 150 assertEquals("2nd element", "d", list2.get(1)); 151 } 152 153 @Test 154 public void testDictionary() 155 { 156 assertEquals("1st element in dictionary", "bar1", config.getProperty("dictionary.foo1")); 157 assertEquals("2nd element in dictionary", "bar2", config.getProperty("dictionary.foo2")); 158 } 159 160 @Test 161 public void testDictionaryArray() 162 { 163 String key = "dictionary-array"; 164 165 Object array = config.getProperty(key); 166 167 // root array 168 assertNotNull("array not found", array); 169 ObjectAssert.assertInstanceOf("the array element is not parsed as a List", List.class, array); 170 List<?> list = config.getList(key); 171 172 assertFalse("empty array", list.isEmpty()); 173 assertEquals("size", 2, list.size()); 174 175 // 1st dictionary 176 ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(0)); 177 Configuration conf1 = (Configuration) list.get(0); 178 assertFalse("configuration 1 is empty", conf1.isEmpty()); 179 assertEquals("configuration element", "bar", conf1.getProperty("foo")); 180 181 // 2nd dictionary 182 ObjectAssert.assertInstanceOf("the dict element is not parsed as a Configuration", Configuration.class, list.get(1)); 183 Configuration conf2 = (Configuration) list.get(1); 184 assertFalse("configuration 2 is empty", conf2.isEmpty()); 185 assertEquals("configuration element", "value", conf2.getProperty("key")); 186 } 187 188 @Test 189 public void testNestedDictionaries() 190 { 191 assertEquals("nested property", "value", config.getString("nested-dictionaries.foo.bar.key")); 192 } 193 194 @Test 195 public void testData() 196 { 197 ObjectAssert.assertInstanceOf("data", (new byte[0]).getClass(), config.getProperty("data")); 198 ArrayAssert.assertEquals("data", "foo bar".getBytes(), (byte[]) config.getProperty("data")); 199 } 200 201 @Test 202 public void testDate() throws Exception 203 { 204 Calendar cal = Calendar.getInstance(); 205 cal.clear(); 206 cal.set(2002, 2, 22, 11, 30, 0); 207 cal.setTimeZone(TimeZone.getTimeZone("GMT+0100")); 208 Date date = cal.getTime(); 209 210 assertEquals("date", date, config.getProperty("date")); 211 } 212 213 @Test 214 public void testSave() throws Exception 215 { 216 File savedFile = new File("target/testsave.plist"); 217 218 // remove the file previously saved if necessary 219 if (savedFile.exists()) 220 { 221 assertTrue(savedFile.delete()); 222 } 223 224 // save the configuration 225 String filename = savedFile.getAbsolutePath(); 226 config.save(filename); 227 228 assertTrue("The saved file doesn't exist", savedFile.exists()); 229 230 // read the configuration and compare the properties 231 Configuration checkConfig = new PropertyListConfiguration(new File(filename)); 232 233 Iterator<String> it = config.getKeys(); 234 while (it.hasNext()) 235 { 236 String key = it.next(); 237 assertTrue("The saved configuration doesn't contain the key '" + key + "'", checkConfig.containsKey(key)); 238 239 Object value = checkConfig.getProperty(key); 240 if (value instanceof byte[]) 241 { 242 byte[] array = (byte[]) value; 243 ArrayAssert.assertEquals("Value of the '" + key + "' property", (byte[]) config.getProperty(key), array); 244 } 245 else if (value instanceof List) 246 { 247 List<?> list1 = (List<?>) config.getProperty(key); 248 List<?> list2 = (List<?>) value; 249 250 assertEquals("The size of the list for the key '" + key + "' doesn't match", list1.size(), list2.size()); 251 252 for (int i = 0; i < list2.size(); i++) 253 { 254 Object value1 = list1.get(i); 255 Object value2 = list2.get(i); 256 257 if (value1 instanceof Configuration) 258 { 259 ConfigurationComparator comparator = new StrictConfigurationComparator(); 260 assertTrue("The dictionnary at index " + i + " for the key '" + key + "' doesn't match", comparator.compare((Configuration) value1, (Configuration) value2)); 261 } 262 else 263 { 264 assertEquals("Element at index " + i + " for the key '" + key + "'", value1, value2); 265 } 266 } 267 268 ListAssert.assertEquals("Value of the '" + key + "' property", (List<?>) config.getProperty(key), list1); 269 } 270 else 271 { 272 assertEquals("Value of the '" + key + "' property", config.getProperty(key), checkConfig.getProperty(key)); 273 } 274 275 } 276 } 277 278 @Test 279 public void testSaveEmptyDictionary() throws Exception 280 { 281 File savedFile = new File("target/testsave.plist"); 282 283 // remove the file previously saved if necessary 284 if (savedFile.exists()) 285 { 286 assertTrue(savedFile.delete()); 287 } 288 289 // save the configuration 290 String filename = savedFile.getAbsolutePath(); 291 config.save(filename); 292 293 assertTrue("The saved file doesn't exist", savedFile.exists()); 294 295 // read the configuration and compare the properties 296 PropertyListConfiguration checkConfig = new PropertyListConfiguration(new File(filename)); 297 298 assertFalse(config.getRootNode().getChildren("empty-dictionary").isEmpty()); 299 assertFalse(checkConfig.getRootNode().getChildren("empty-dictionary").isEmpty()); 300 } 301 302 @Test 303 public void testQuoteString() 304 { 305 assertEquals("null string", null, config.quoteString(null)); 306 assertEquals("simple string", "abcd", config.quoteString("abcd")); 307 assertEquals("string with a space", "\"ab cd\"", config.quoteString("ab cd")); 308 assertEquals("string with a quote", "\"foo\\\"bar\"", config.quoteString("foo\"bar")); 309 assertEquals("string with a special char", "\"foo;bar\"", config.quoteString("foo;bar")); 310 } 311 312 /** 313 * Ensure that setProperty doesn't alter an array of byte 314 * since it's a first class type in plist file 315 */ 316 @Test 317 public void testSetDataProperty() throws Exception 318 { 319 byte[] expected = new byte[]{1, 2, 3, 4}; 320 PropertyListConfiguration config = new PropertyListConfiguration(); 321 config.setProperty("foo", expected); 322 config.save("target/testdata.plist"); 323 324 PropertyListConfiguration config2 = new PropertyListConfiguration("target/testdata.plist"); 325 Object array = config2.getProperty("foo"); 326 327 assertNotNull("data not found", array); 328 assertEquals("property type", byte[].class, array.getClass()); 329 ArrayAssert.assertEquals(expected, (byte[]) array); 330 } 331 332 /** 333 * Ensure that addProperty doesn't alter an array of byte 334 */ 335 @Test 336 public void testAddDataProperty() throws Exception 337 { 338 byte[] expected = new byte[]{1, 2, 3, 4}; 339 PropertyListConfiguration config = new PropertyListConfiguration(); 340 config.addProperty("foo", expected); 341 config.save("target/testdata.plist"); 342 343 PropertyListConfiguration config2 = new PropertyListConfiguration("target/testdata.plist"); 344 Object array = config2.getProperty("foo"); 345 346 assertNotNull("data not found", array); 347 assertEquals("property type", byte[].class, array.getClass()); 348 ArrayAssert.assertEquals(expected, (byte[]) array); 349 } 350 351 @Test 352 public void testInitCopy() 353 { 354 PropertyListConfiguration copy = new PropertyListConfiguration(config); 355 assertFalse("Nothing was copied", copy.isEmpty()); 356 } 357 358 /** 359 * Tests parsing a date with an invalid numeric value. 360 */ 361 @Test(expected = ParseException.class) 362 public void testParseDateNoNumber() throws ParseException 363 { 364 PropertyListConfiguration 365 .parseDate("<*D2002-03-22 1c:30:00 +0100>"); 366 } 367 368 /** 369 * Tests parsing a date that is not long enough. 370 */ 371 @Test(expected = ParseException.class) 372 public void testParseDateTooShort() throws ParseException 373 { 374 PropertyListConfiguration.parseDate("<*D2002-03-22 11:3>"); 375 } 376 377 /** 378 * Tests parsing a date that contains an invalid separator character. 379 */ 380 @Test(expected = ParseException.class) 381 public void testParseDateInvalidChar() throws ParseException 382 { 383 PropertyListConfiguration 384 .parseDate("<*D2002+03-22 11:30:00 +0100>"); 385 } 386 387 /** 388 * Tries parsing a null date. This should cause an exception.n 389 */ 390 @Test(expected = ParseException.class) 391 public void testParseDateNull() throws ParseException 392 { 393 PropertyListConfiguration.parseDate(null); 394 } 395 396 /** 397 * Tests formatting a date. 398 */ 399 @Test 400 public void testFormatDate() 401 { 402 Calendar cal = Calendar.getInstance(); 403 cal.clear(); 404 cal.set(2007, 9, 29, 23, 4, 30); 405 cal.setTimeZone(TimeZone.getTimeZone("GMT-0230")); 406 assertEquals("Wrong date literal (1)", "<*D2007-10-29 23:04:30 -0230>", 407 PropertyListConfiguration.formatDate(cal)); 408 cal.clear(); 409 cal.set(2007, 9, 30, 22, 2, 15); 410 cal.setTimeZone(TimeZone.getTimeZone("GMT+1111")); 411 assertEquals("Wrong date literal (2)", "<*D2007-10-30 22:02:15 +1111>", 412 PropertyListConfiguration.formatDate(cal)); 413 } 414 }