1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.io.PrintWriter;
22 import java.io.StringReader;
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27
28 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
29
30 import junit.framework.TestCase;
31
32 /***
33 * Test for loading and saving properties files.
34 *
35 * @version $Id: TestPropertiesConfiguration.java 331135 2005-11-06 18:57:39Z oheger $
36 */
37 public class TestPropertiesConfiguration extends TestCase
38 {
39 private PropertiesConfiguration conf;
40
41 /*** The File that we test with */
42 private String testProperties = new File("conf/test.properties").getAbsolutePath();
43
44 private String testBasePath = new File("conf").getAbsolutePath();
45 private String testBasePath2 = new File("conf").getAbsoluteFile().getParentFile().getAbsolutePath();
46 private File testSavePropertiesFile = new File("target/testsave.properties");
47
48 protected void setUp() throws Exception
49 {
50 conf = new PropertiesConfiguration(testProperties);
51 }
52
53 public void testLoad() throws Exception
54 {
55 String loaded = conf.getString("configuration.loaded");
56 assertEquals("true", loaded);
57 }
58
59 /***
60 * Tests if properties can be appended by simply calling load() another
61 * time.
62 */
63 public void testAppend() throws Exception
64 {
65 File file2 = new File("conf/threesome.properties");
66 conf.load(file2);
67 assertEquals("aaa", conf.getString("test.threesome.one"));
68 assertEquals("true", conf.getString("configuration.loaded"));
69 }
70
71 /***
72 * Tests that empty properties are treated as the empty string
73 * (rather than as null).
74 */
75 public void testEmpty() throws Exception
76 {
77 String empty = conf.getString("test.empty");
78 assertNotNull(empty);
79 assertEquals("", empty);
80 }
81
82 /***
83 * Tests that references to other properties work
84 */
85 public void testReference() throws Exception
86 {
87 assertEquals("baseextra", conf.getString("base.reference"));
88 }
89
90 /***
91 * test if includes properties get loaded too
92 */
93 public void testLoadInclude() throws Exception
94 {
95 String loaded = conf.getString("include.loaded");
96 assertEquals("true", loaded);
97 }
98
99 public void testSetInclude() throws Exception
100 {
101
102 PropertiesConfiguration.setInclude("import");
103
104
105 PropertiesConfiguration conf = new PropertiesConfiguration();
106 conf.load("conf/test.properties");
107
108
109 PropertiesConfiguration.setInclude("include");
110
111 assertNull(conf.getString("include.loaded"));
112 }
113
114 /***
115 * Tests <code>List</code> parsing.
116 */
117 public void testList() throws Exception
118 {
119 List packages = conf.getList("packages");
120
121 assertEquals(3, packages.size());
122 }
123
124 public void testSave() throws Exception
125 {
126
127 if (testSavePropertiesFile.exists())
128 {
129 assertTrue(testSavePropertiesFile.delete());
130 }
131
132
133 conf.addProperty("string", "value1");
134 List list = new ArrayList();
135 for (int i = 1; i < 5; i++)
136 {
137 list.add("value" + i);
138 }
139 conf.addProperty("array", list);
140
141
142 String filename = testSavePropertiesFile.getAbsolutePath();
143 conf.save(filename);
144
145 assertTrue("The saved file doesn't exist", testSavePropertiesFile.exists());
146
147
148 PropertiesConfiguration checkConfig = new PropertiesConfiguration(filename);
149 for (Iterator i = conf.getKeys(); i.hasNext();)
150 {
151 String key = (String) i.next();
152 assertTrue("The saved configuration doesn't contain the key '" + key + "'", checkConfig.containsKey(key));
153 assertEquals("Value of the '" + key + "' property", conf.getProperty(key), checkConfig.getProperty(key));
154 }
155
156
157 checkConfig.save();
158 }
159
160 public void testSaveMissingFilename()
161 {
162 PropertiesConfiguration pc = new PropertiesConfiguration();
163 try
164 {
165 pc.save();
166 fail("Should have throw ConfigurationException");
167 }
168 catch (ConfigurationException ce)
169 {
170
171 }
172 }
173
174 /***
175 * Tests if the base path is taken into account by the save() method.
176 * @throws Exception if an error occurs
177 */
178 public void testSaveWithBasePath() throws Exception
179 {
180
181 if (testSavePropertiesFile.exists())
182 {
183 assertTrue(testSavePropertiesFile.delete());
184 }
185
186 conf.setProperty("test", "true");
187 conf.setBasePath(testSavePropertiesFile.getParentFile().toURL().toString());
188 conf.setFileName(testSavePropertiesFile.getName());
189 conf.save();
190 assertTrue(testSavePropertiesFile.exists());
191 }
192
193 public void testLoadViaProperty() throws Exception
194 {
195 PropertiesConfiguration pc = new PropertiesConfiguration();
196 pc.setFileName(testProperties);
197 pc.load();
198
199 assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
200 }
201
202 public void testLoadViaPropertyWithBasePath() throws Exception
203 {
204 PropertiesConfiguration pc = new PropertiesConfiguration();
205 pc.setBasePath(testBasePath);
206 pc.setFileName("test.properties");
207 pc.load();
208
209 assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
210 }
211
212 public void testLoadViaPropertyWithBasePath2() throws Exception
213 {
214 PropertiesConfiguration pc = new PropertiesConfiguration();
215 pc.setBasePath(testBasePath2);
216 pc.setFileName("conf/test.properties");
217 pc.load();
218
219 assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
220
221 pc = new PropertiesConfiguration();
222 pc.setBasePath(testBasePath2);
223 pc.setFileName("conf/test.properties");
224 pc.load();
225
226 assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
227 }
228
229 public void testLoadFromFile() throws Exception
230 {
231 File file = new File("conf/test.properties");
232 conf = new PropertiesConfiguration(file);
233
234 assertEquals("true", conf.getString("configuration.loaded"));
235 }
236
237 public void testLoadUnexistingFile()
238 {
239 try
240 {
241 conf = new PropertiesConfiguration("Unexisting file");
242 fail("Unexisting file was loaded.");
243 }
244 catch(ConfigurationException cex)
245 {
246
247 }
248 }
249
250 /***
251 * Tests to load a file with enabled auto save mode.
252 */
253 public void testLoadWithAutoSave() throws Exception
254 {
255 PrintWriter out = null;
256
257 try
258 {
259 out = new PrintWriter(new FileWriter(testSavePropertiesFile));
260 out.println("a = one");
261 out.println("b = two");
262 out.println("c = three");
263 out.close();
264 out = null;
265
266 conf = new PropertiesConfiguration();
267 conf.setAutoSave(true);
268 conf.setFile(testSavePropertiesFile);
269 conf.load();
270 assertEquals("one", conf.getString("a"));
271 assertEquals("two", conf.getString("b"));
272 assertEquals("three", conf.getString("c"));
273 }
274 finally
275 {
276 if(out != null)
277 {
278 out.close();
279 }
280 }
281 }
282
283 public void testGetStringWithEscapedChars()
284 {
285 String property = conf.getString("test.unescape");
286 assertEquals("String with escaped characters", "This \n string \t contains \" escaped // characters", property);
287 }
288
289 public void testGetStringWithEscapedComma()
290 {
291 String property = conf.getString("test.unescape.list-separator");
292 assertEquals("String with an escaped list separator", "This string contains , an escaped list separator", property);
293 }
294
295 public void testUnescapeJava()
296 {
297 assertEquals("test//,test", PropertiesConfiguration.unescapeJava("test//,test", ','));
298 }
299
300 public void testEscapedKey() throws Exception
301 {
302 PropertiesConfiguration conf = new PropertiesConfiguration();
303 conf.load(new StringReader("//u0066//u006f//u006f=bar"));
304
305 assertEquals("value of the 'foo' property", "bar", conf.getString("foo"));
306 }
307
308 public void testMixedArray()
309 {
310 String[] array = conf.getStringArray("test.mixed.array");
311
312 assertEquals("array length", 4, array.length);
313 assertEquals("1st element", "a", array[0]);
314 assertEquals("2nd element", "b", array[1]);
315 assertEquals("3rd element", "c", array[2]);
316 assertEquals("4th element", "d", array[3]);
317 }
318
319 public void testMultilines()
320 {
321 String property = "This is a value spread out across several adjacent "
322 + "natural lines by escaping the line terminator with "
323 + "a backslash character.";
324
325 assertEquals("'test.multilines' property", property, conf.getString("test.multilines"));
326 }
327
328 public void testChangingDelimiter() throws Exception
329 {
330 PropertiesConfiguration pc = new PropertiesConfiguration(testProperties);
331 assertEquals(4, pc.getList("test.mixed.array").size());
332
333 char delimiter = PropertiesConfiguration.getDelimiter();
334 PropertiesConfiguration.setDelimiter('^');
335 pc = new PropertiesConfiguration(testProperties);
336 assertEquals(2, pc.getList("test.mixed.array").size());
337 PropertiesConfiguration.setDelimiter(delimiter);
338 }
339
340 /***
341 * Tests escaping of an end of line with a backslash.
342 */
343 public void testNewLineEscaping()
344 {
345 List list = conf.getList("test.path");
346 assertEquals(3, list.size());
347 assertEquals("C://path1//", list.get(0));
348 assertEquals("C://path2//", list.get(1));
349 assertEquals("C://path3//complex//test//", list.get(2));
350 }
351
352 /***
353 * Tests if included files are loaded when the source lies in the class path.
354 */
355 public void testLoadIncludeFromClassPath() throws ConfigurationException
356 {
357 conf = new PropertiesConfiguration("test.properties");
358 assertEquals("true", conf.getString("include.loaded"));
359 }
360
361 /***
362 * Test if the lines starting with # or ! are properly ignored.
363 */
364 public void testComment() {
365 assertFalse("comment line starting with '#' parsed as a property", conf.containsKey("#comment"));
366 assertFalse("comment line starting with '!' parsed as a property", conf.containsKey("!comment"));
367 }
368
369 /***
370 * Check that key/value separators can be part of a key.
371 */
372 public void testEscapedKeyValueSeparator()
373 {
374 assertEquals("Escaped separator '=' not supported in keys", "foo", conf.getProperty("test.separator=in.key"));
375 assertEquals("Escaped separator ':' not supported in keys", "bar", conf.getProperty("test.separator:in.key"));
376 assertEquals("Escaped separator '//t' not supported in keys", "foo", conf.getProperty("test.separator\tin.key"));
377 assertEquals("Escaped separator '//f' not supported in keys", "bar", conf.getProperty("test.separator\fin.key"));
378 assertEquals("Escaped separator ' ' not supported in keys" , "foo", conf.getProperty("test.separator in.key"));
379 }
380
381 /***
382 * Test all acceptable key/value separators ('=', ':' or white spaces).
383 */
384 public void testKeyValueSeparators() {
385 assertEquals("equal separator not properly parsed", "foo", conf.getProperty("test.separator.equal"));
386 assertEquals("colon separator not properly parsed", "foo", conf.getProperty("test.separator.colon"));
387 assertEquals("tab separator not properly parsed", "foo", conf.getProperty("test.separator.tab"));
388 assertEquals("formfeed separator not properly parsed", "foo", conf.getProperty("test.separator.formfeed"));
389 assertEquals("whitespace separator not properly parsed", "foo", conf.getProperty("test.separator.whitespace"));
390 }
391
392 /***
393 * Tests including properties when they are loaded from a nested directory
394 * structure.
395 */
396 public void testIncludeInSubDir() throws ConfigurationException
397 {
398 ConfigurationFactory factory = new ConfigurationFactory("conf/testFactoryPropertiesInclude.xml");
399 Configuration config = factory.getConfiguration();
400 assertEquals(true, config.getBoolean("deeptest"));
401 assertEquals(true, config.getBoolean("deepinclude"));
402 assertFalse(config.containsKey("deeptestinvalid"));
403 }
404
405 /***
406 * Tests whether the correct line separator is used.
407 */
408 public void testLineSeparator() throws ConfigurationException
409 {
410 final String EOL = System.getProperty("line.separator");
411 conf = new PropertiesConfiguration();
412 conf.setHeader("My header");
413 conf.setProperty("prop", "value");
414
415 StringWriter out = new StringWriter();
416 conf.save(out);
417 String content = out.toString();
418 assertTrue("Header could not be found", content.indexOf("# My header"
419 + EOL + EOL) == 0);
420 assertTrue("Property could not be found", content
421 .indexOf("prop = value" + EOL) > 0);
422 }
423
424 /***
425 * Tests what happens if a reloading strategy's <code>reloadingRequired()</code>
426 * implementation accesses methods of the configuration that in turn cause a reload.
427 */
428 public void testReentrantReload()
429 {
430 conf.setProperty("shouldReload", Boolean.FALSE);
431 conf.setReloadingStrategy(new FileChangedReloadingStrategy()
432 {
433 public boolean reloadingRequired()
434 {
435 return configuration.getBoolean("shouldReload");
436 }
437 });
438 assertFalse("Property has wrong value", conf.getBoolean("shouldReload"));
439 }
440 }