~ubuntu-branches/ubuntu/saucy/commons-configuration/saucy

« back to all changes in this revision

Viewing changes to src/test/java/org/apache/commons/configuration/TestPropertiesConfigurationLayout.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-07-01 16:29:44 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130701162944-98waq5gogha5gpn1
Tags: 1.9-1
* New upstream release
* debian/control:
  - Updated Standards-Version to 3.9.4 (no changes)
  - Use canonical URLs for the Vcs-* fields
  - Added new build dependencies (libjavacc-maven-plugin-java, junit4)
  - Upgraded the dependency on the Servlet API (2.5 -> 3.0)
  - Removed the dependency on the Activation Framework (glassfish-activation)
  - Replaced the dependency on glassfish-mail with libgnumail-java
  - Removed the unused dependencies:
    liblog4j1.2-java-doc, libmaven-assembly-plugin-java
  - Replaced the dependency on libcommons-jexl-java by libcommons-jexl2-java
* debian/watch: Changed to point the official Apache distribution server
* Removed the obsolete file debian/ant.properties
* Installed the upstream changelog in the binary packages
* Added the report plugins to maven.ignoreRules
* Added the classpath attribute to the jar manifest

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
package org.apache.commons.configuration;
 
18
 
 
19
import static org.junit.Assert.assertEquals;
 
20
import static org.junit.Assert.assertFalse;
 
21
import static org.junit.Assert.assertNotNull;
 
22
import static org.junit.Assert.assertNull;
 
23
import static org.junit.Assert.assertSame;
 
24
import static org.junit.Assert.assertTrue;
 
25
import static org.junit.Assert.fail;
 
26
 
 
27
import java.io.Reader;
 
28
import java.io.StringReader;
 
29
import java.io.StringWriter;
 
30
import java.util.Iterator;
 
31
 
 
32
import org.apache.commons.configuration.event.ConfigurationEvent;
 
33
import org.apache.commons.configuration.event.ConfigurationListener;
 
34
import org.junit.Before;
 
35
import org.junit.Test;
 
36
 
 
37
/**
 
38
 * Test class for PropertiesConfigurationLayout.
 
39
 *
 
40
 * @author <a
 
41
 * href="http://commons.apache.org/configuration/team-list.html">Commons
 
42
 * Configuration team</a>
 
43
 * @version $Id: TestPropertiesConfigurationLayout.java 1301996 2012-03-17 20:30:39Z sebb $
 
44
 */
 
45
public class TestPropertiesConfigurationLayout
 
46
{
 
47
    /** Constant for the line break character. */
 
48
    private static final String CR = System.getProperty("line.separator");
 
49
 
 
50
    /** Constant for the normalized line break character. */
 
51
    private static final String CRNORM = "\n";
 
52
 
 
53
    /** Constant for a test property key. */
 
54
    static final String TEST_KEY = "myProperty";
 
55
 
 
56
    /** Constant for a test comment. */
 
57
    static final String TEST_COMMENT = "A comment for my test property";
 
58
 
 
59
    /** Constant for a test property value. */
 
60
    static final String TEST_VALUE = "myPropertyValue";
 
61
 
 
62
    /** The layout object under test. */
 
63
    PropertiesConfigurationLayout layout;
 
64
 
 
65
    /** The associated configuration object. */
 
66
    LayoutTestConfiguration config;
 
67
 
 
68
    /** A properties builder that can be used for testing. */
 
69
    PropertiesBuilder builder;
 
70
 
 
71
    @Before
 
72
    public void setUp() throws Exception
 
73
    {
 
74
        config = new LayoutTestConfiguration();
 
75
        layout = new PropertiesConfigurationLayout(config);
 
76
        config.setLayout(layout);
 
77
        builder = new PropertiesBuilder();
 
78
    }
 
79
 
 
80
    /**
 
81
     * Tests a newly created instance.
 
82
     */
 
83
    @Test
 
84
    public void testInit()
 
85
    {
 
86
        assertTrue("Object contains keys", layout.getKeys().isEmpty());
 
87
        assertNull("Header comment not null", layout.getHeaderComment());
 
88
        Iterator<ConfigurationListener> it = config.getConfigurationListeners().iterator();
 
89
        assertTrue("No event listener registered", it.hasNext());
 
90
        assertSame("Layout not registered as event listener", layout, it.next());
 
91
        assertFalse("Multiple event listeners registered", it.hasNext());
 
92
        assertSame("Configuration not stored", config, layout
 
93
                .getConfiguration());
 
94
        assertFalse("Force single line flag set", layout.isForceSingleLine());
 
95
        assertNull("Got a global separator", layout.getGlobalSeparator());
 
96
    }
 
97
 
 
98
    /**
 
99
     * Tests creating a layout object with a null configuration. This should
 
100
     * cause an exception.
 
101
     */
 
102
    @Test(expected = IllegalArgumentException.class)
 
103
    public void testInitNull()
 
104
    {
 
105
        new PropertiesConfigurationLayout(null);
 
106
    }
 
107
 
 
108
    /**
 
109
     * Tests reading a simple properties file.
 
110
     */
 
111
    @Test
 
112
    public void testReadSimple() throws ConfigurationException
 
113
    {
 
114
        builder.addComment(TEST_COMMENT);
 
115
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
116
        layout.load(builder.getReader());
 
117
        assertNull("A header comment was found", layout.getHeaderComment());
 
118
        assertEquals("Wrong number of properties", 1, layout.getKeys().size());
 
119
        assertTrue("Property not found", layout.getKeys().contains(TEST_KEY));
 
120
        assertEquals("Comment not found", TEST_COMMENT, layout
 
121
                .getCanonicalComment(TEST_KEY, false));
 
122
        assertEquals("Wrong number of blanc lines", 0, layout
 
123
                .getBlancLinesBefore(TEST_KEY));
 
124
        assertTrue("Wrong single line flag", layout.isSingleLine(TEST_KEY));
 
125
        assertEquals("Property not stored in config", TEST_VALUE, config
 
126
                .getString(TEST_KEY));
 
127
    }
 
128
 
 
129
    /**
 
130
     * Tests whether blanc lines before a property are correctly detected.
 
131
     */
 
132
    @Test
 
133
    public void testBlancLines() throws ConfigurationException
 
134
    {
 
135
        builder.addProperty("prop", "value");
 
136
        builder.addComment(null);
 
137
        builder.addComment(null);
 
138
        builder.addComment(TEST_COMMENT);
 
139
        builder.addComment(null);
 
140
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
141
        layout.load(builder.getReader());
 
142
        assertEquals("Wrong number of blanc lines", 2, layout
 
143
                .getBlancLinesBefore(TEST_KEY));
 
144
        assertEquals("Wrong comment", TEST_COMMENT + CRNORM, layout
 
145
                .getCanonicalComment(TEST_KEY, false));
 
146
        assertEquals("Wrong property value", TEST_VALUE, config
 
147
                .getString(TEST_KEY));
 
148
    }
 
149
 
 
150
    /**
 
151
     * Tests the single line flag for a simple property definition.
 
152
     */
 
153
    @Test
 
154
    public void testIsSingleLine() throws ConfigurationException
 
155
    {
 
156
        builder.addProperty(TEST_KEY, TEST_VALUE + "," + TEST_VALUE + "2");
 
157
        layout.load(builder.getReader());
 
158
        assertTrue("Wrong single line flag", layout.isSingleLine(TEST_KEY));
 
159
        assertEquals("Wrong number of values", 2, config.getList(TEST_KEY)
 
160
                .size());
 
161
    }
 
162
 
 
163
    /**
 
164
     * Tests the single line flag if there are multiple property definitions.
 
165
     */
 
166
    @Test
 
167
    public void testIsSingleLineMulti() throws ConfigurationException
 
168
    {
 
169
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
170
        builder.addProperty("anotherProp", "a value");
 
171
        builder.addProperty(TEST_KEY, TEST_VALUE + "2");
 
172
        layout.load(builder.getReader());
 
173
        assertFalse("Wrong single line flag", layout.isSingleLine(TEST_KEY));
 
174
        assertEquals("Wrong number of values", 2, config.getList(TEST_KEY)
 
175
                .size());
 
176
    }
 
177
 
 
178
    /**
 
179
     * Tests whether comments are combined for multiple occurrences.
 
180
     */
 
181
    @Test
 
182
    public void testCombineComments() throws ConfigurationException
 
183
    {
 
184
        builder.addComment(TEST_COMMENT);
 
185
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
186
        builder.addComment(null);
 
187
        builder.addComment(TEST_COMMENT);
 
188
        builder.addProperty(TEST_KEY, TEST_VALUE + "2");
 
189
        layout.load(builder.getReader());
 
190
        assertEquals("Wrong combined comment",
 
191
                TEST_COMMENT + CRNORM + TEST_COMMENT, layout.getCanonicalComment(
 
192
                        TEST_KEY, false));
 
193
        assertEquals("Wrong combined blanc numbers", 0, layout
 
194
                .getBlancLinesBefore(TEST_KEY));
 
195
    }
 
196
 
 
197
    /**
 
198
     * Tests if a header comment is detected.
 
199
     */
 
200
    @Test
 
201
    public void testHeaderComment() throws ConfigurationException
 
202
    {
 
203
        builder.addComment(TEST_COMMENT);
 
204
        builder.addComment(null);
 
205
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
206
        layout.load(builder.getReader());
 
207
        assertEquals("Wrong header comment", TEST_COMMENT, layout
 
208
                .getCanonicalHeaderComment(false));
 
209
        assertNull("Wrong comment for property", layout.getCanonicalComment(
 
210
                TEST_KEY, false));
 
211
    }
 
212
 
 
213
    /**
 
214
     * Tests if a header comment containing blanc lines is correctly detected.
 
215
     */
 
216
    @Test
 
217
    public void testHeaderCommentWithBlancs() throws ConfigurationException
 
218
    {
 
219
        builder.addComment(TEST_COMMENT);
 
220
        builder.addComment(null);
 
221
        builder.addComment(TEST_COMMENT);
 
222
        builder.addComment(null);
 
223
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
224
        layout.load(builder.getReader());
 
225
        assertEquals("Wrong header comment", TEST_COMMENT + CRNORM + CRNORM
 
226
                + TEST_COMMENT, layout.getCanonicalHeaderComment(false));
 
227
        assertNull("Wrong comment for property", layout.getComment(TEST_KEY));
 
228
    }
 
229
 
 
230
    /**
 
231
     * Tests if a header comment is correctly detected when it contains blanc
 
232
     * lines and the first property has a comment, too.
 
233
     */
 
234
    @Test
 
235
    public void testHeaderCommentWithBlancsAndPropComment()
 
236
            throws ConfigurationException
 
237
    {
 
238
        builder.addComment(TEST_COMMENT);
 
239
        builder.addComment(null);
 
240
        builder.addComment(TEST_COMMENT);
 
241
        builder.addComment(null);
 
242
        builder.addComment(TEST_COMMENT);
 
243
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
244
        layout.load(builder.getReader());
 
245
        assertEquals("Wrong header comment", TEST_COMMENT + CRNORM + CRNORM
 
246
                + TEST_COMMENT, layout.getCanonicalHeaderComment(false));
 
247
        assertEquals("Wrong comment for property", TEST_COMMENT, layout
 
248
                .getCanonicalComment(TEST_KEY, false));
 
249
    }
 
250
 
 
251
    /**
 
252
     * Tests fetching a canonical header comment when no comment is set.
 
253
     */
 
254
    @Test
 
255
    public void testHeaderCommentNull()
 
256
    {
 
257
        assertNull("No null comment with comment chars", layout
 
258
                .getCanonicalHeaderComment(true));
 
259
        assertNull("No null comment without comment chars", layout
 
260
                .getCanonicalHeaderComment(false));
 
261
    }
 
262
 
 
263
    /**
 
264
     * Tests if a property add event is correctly processed.
 
265
     */
 
266
    @Test
 
267
    public void testEventAdd()
 
268
    {
 
269
        ConfigurationEvent event = new ConfigurationEvent(this,
 
270
                AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY, TEST_VALUE,
 
271
                false);
 
272
        layout.configurationChanged(event);
 
273
        assertTrue("Property not stored", layout.getKeys().contains(TEST_KEY));
 
274
        assertEquals("Blanc lines before new property", 0, layout
 
275
                .getBlancLinesBefore(TEST_KEY));
 
276
        assertTrue("No single line property", layout.isSingleLine(TEST_KEY));
 
277
        assertEquals("Wrong separator", " = ", layout.getSeparator(TEST_KEY));
 
278
    }
 
279
 
 
280
    /**
 
281
     * Tests adding a property multiple time through an event. The property
 
282
     * should then be a multi-line property.
 
283
     */
 
284
    @Test
 
285
    public void testEventAddMultiple()
 
286
    {
 
287
        ConfigurationEvent event = new ConfigurationEvent(this,
 
288
                AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY, TEST_VALUE,
 
289
                false);
 
290
        layout.configurationChanged(event);
 
291
        layout.configurationChanged(event);
 
292
        assertFalse("No multi-line property", layout.isSingleLine(TEST_KEY));
 
293
    }
 
294
 
 
295
    /**
 
296
     * Tests if an add event is correctly processed if the affected property is
 
297
     * already stored in the layout object.
 
298
     */
 
299
    @Test
 
300
    public void testEventAddExisting() throws ConfigurationException
 
301
    {
 
302
        builder.addComment(TEST_COMMENT);
 
303
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
304
        layout.load(builder.getReader());
 
305
        ConfigurationEvent event = new ConfigurationEvent(this,
 
306
                AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY, TEST_VALUE,
 
307
                false);
 
308
        layout.configurationChanged(event);
 
309
        assertFalse("No multi-line property", layout.isSingleLine(TEST_KEY));
 
310
        assertEquals("Comment was modified", TEST_COMMENT, layout
 
311
                .getCanonicalComment(TEST_KEY, false));
 
312
    }
 
313
 
 
314
    /**
 
315
     * Tests if a set property event for a non existing property is correctly
 
316
     * handled.
 
317
     */
 
318
    @Test
 
319
    public void testEventSetNonExisting()
 
320
    {
 
321
        ConfigurationEvent event = new ConfigurationEvent(this,
 
322
                AbstractConfiguration.EVENT_SET_PROPERTY, TEST_KEY, TEST_VALUE,
 
323
                false);
 
324
        layout.configurationChanged(event);
 
325
        assertTrue("New property was not found", layout.getKeys().contains(
 
326
                TEST_KEY));
 
327
    }
 
328
 
 
329
    /**
 
330
     * Tests if a property delete event is correctly processed.
 
331
     */
 
332
    @Test
 
333
    public void testEventDelete()
 
334
    {
 
335
        ConfigurationEvent event = new ConfigurationEvent(this,
 
336
                AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY, TEST_VALUE,
 
337
                false);
 
338
        layout.configurationChanged(event);
 
339
        event = new ConfigurationEvent(this,
 
340
                AbstractConfiguration.EVENT_CLEAR_PROPERTY, TEST_KEY, null,
 
341
                false);
 
342
        layout.configurationChanged(event);
 
343
        assertFalse("Property still existing", layout.getKeys().contains(
 
344
                TEST_KEY));
 
345
    }
 
346
 
 
347
    /**
 
348
     * Tests if a clear event is correctly processed.
 
349
     */
 
350
    @Test
 
351
    public void testEventClearConfig() throws Exception
 
352
    {
 
353
        fillLayout();
 
354
        ConfigurationEvent event = new ConfigurationEvent(this,
 
355
                AbstractConfiguration.EVENT_CLEAR, null, null, false);
 
356
        layout.configurationChanged(event);
 
357
        assertTrue("Keys not empty", layout.getKeys().isEmpty());
 
358
        assertNull("Header comment was not reset", layout.getHeaderComment());
 
359
    }
 
360
 
 
361
    /**
 
362
     * Tests if a before update event is correctly ignored.
 
363
     */
 
364
    @Test
 
365
    public void testEventAddBefore()
 
366
    {
 
367
        ConfigurationEvent event = new ConfigurationEvent(this,
 
368
                AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY, TEST_VALUE,
 
369
                true);
 
370
        layout.configurationChanged(event);
 
371
        assertFalse("Property already stored", layout.getKeys().contains(
 
372
                TEST_KEY));
 
373
    }
 
374
 
 
375
    /**
 
376
     * Tests if a reload update is correctly processed.
 
377
     */
 
378
    @Test
 
379
    public void testEventReload()
 
380
    {
 
381
        fillLayout();
 
382
        ConfigurationEvent event = new ConfigurationEvent(this,
 
383
                AbstractFileConfiguration.EVENT_RELOAD, null, null, true);
 
384
        layout.configurationChanged(event);
 
385
        assertTrue("Keys not empty", layout.getKeys().isEmpty());
 
386
        assertNull("Header comment was not reset", layout.getHeaderComment());
 
387
    }
 
388
 
 
389
    /**
 
390
     * Tests the event after a reload has been performed. This should be
 
391
     * ignored.
 
392
     */
 
393
    @Test
 
394
    public void testEventReloadAfter()
 
395
    {
 
396
        fillLayout();
 
397
        ConfigurationEvent event = new ConfigurationEvent(this,
 
398
                AbstractFileConfiguration.EVENT_RELOAD, null, null, false);
 
399
        layout.configurationChanged(event);
 
400
        assertFalse("Keys are empty", layout.getKeys().isEmpty());
 
401
        assertNotNull("Header comment was reset", layout.getHeaderComment());
 
402
    }
 
403
 
 
404
    /**
 
405
     * Tests a recursive load call.
 
406
     */
 
407
    @Test
 
408
    public void testRecursiveLoadCall() throws ConfigurationException
 
409
    {
 
410
        PropertiesBuilder b = new PropertiesBuilder();
 
411
        b.addComment("A nested header comment.");
 
412
        b.addComment("With multiple lines");
 
413
        b.addComment(null);
 
414
        b.addComment("Second comment");
 
415
        b.addProperty(TEST_KEY, TEST_VALUE);
 
416
        b.addProperty(TEST_KEY + "2", TEST_VALUE + "2");
 
417
        config.builder = b;
 
418
 
 
419
        builder.addComment("Header comment");
 
420
        builder.addComment(null);
 
421
        builder.addComment(TEST_COMMENT);
 
422
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
423
        builder.addComment("Include file");
 
424
        builder.addProperty(PropertiesConfiguration.getInclude(), "test");
 
425
 
 
426
        layout.load(builder.getReader());
 
427
 
 
428
        assertEquals("Wrong header comment", "Header comment", layout
 
429
                .getCanonicalHeaderComment(false));
 
430
        assertFalse("Include property was stored", layout.getKeys().contains(
 
431
                PropertiesConfiguration.getInclude()));
 
432
        assertEquals("Wrong comment for property", TEST_COMMENT + CRNORM
 
433
                + "A nested header comment." + CRNORM + "With multiple lines" + CRNORM
 
434
                + CRNORM + "Second comment", layout.getCanonicalComment(TEST_KEY,
 
435
                false));
 
436
    }
 
437
 
 
438
    /**
 
439
     * Tests whether the output of the layout object is identical to the source
 
440
     * file (at least for simple properties files).
 
441
     */
 
442
    @Test
 
443
    public void testReadAndWrite() throws ConfigurationException
 
444
    {
 
445
        builder.addComment("This is my test properties file,");
 
446
        builder.addComment("which contains a header comment.");
 
447
        builder.addComment(null);
 
448
        builder.addComment(TEST_COMMENT);
 
449
        builder.addProperty(TEST_KEY, TEST_COMMENT);
 
450
        builder.addComment(null);
 
451
        builder.addComment(null);
 
452
        builder.addComment("Another comment");
 
453
        builder.addProperty("property", "and a value");
 
454
        layout.load(builder.getReader());
 
455
        checkLayoutString(builder.toString());
 
456
    }
 
457
 
 
458
    /**
 
459
     * Tests if the content of the layout object is correctly written.
 
460
     */
 
461
    @Test
 
462
    public void testSave() throws ConfigurationException
 
463
    {
 
464
        config.addProperty(TEST_KEY, TEST_VALUE);
 
465
        layout.setComment(TEST_KEY, TEST_COMMENT);
 
466
        config.addProperty(TEST_KEY, TEST_VALUE + "2");
 
467
        config.addProperty("AnotherProperty", "AnotherValue");
 
468
        config.addProperty("AnotherProperty", "3rdValue");
 
469
        layout.setComment("AnotherProperty", "AnotherComment");
 
470
        layout.setBlancLinesBefore("AnotherProperty", 2);
 
471
        layout.setSingleLine("AnotherProperty", true);
 
472
        layout.setHeaderComment("A header comment" + CRNORM + "for my properties");
 
473
        checkLayoutString("# A header comment" + CR + "# for my properties"
 
474
                + CR + CR + "# " + TEST_COMMENT + CR + TEST_KEY + " = "
 
475
                + TEST_VALUE + CR + TEST_KEY + " = " + TEST_VALUE + "2" + CR
 
476
                + CR + CR + "# AnotherComment" + CR
 
477
                + "AnotherProperty = AnotherValue,3rdValue" + CR);
 
478
    }
 
479
 
 
480
    /**
 
481
     * Tests the force single line flag.
 
482
     */
 
483
    @Test
 
484
    public void testSaveForceSingleLine() throws ConfigurationException
 
485
    {
 
486
        config.setListDelimiter(';');
 
487
        config.addProperty(TEST_KEY, TEST_VALUE);
 
488
        config.addProperty(TEST_KEY, TEST_VALUE + "2");
 
489
        config.addProperty("AnotherProperty", "value1;value2;value3");
 
490
        layout.setComment(TEST_KEY, TEST_COMMENT);
 
491
        layout.setForceSingleLine(true);
 
492
        checkLayoutString("# " + TEST_COMMENT + CR + TEST_KEY + " = "
 
493
                + TEST_VALUE + ';' + TEST_VALUE + "2" + CR
 
494
                + "AnotherProperty = value1;value2;value3" + CR);
 
495
    }
 
496
 
 
497
    /**
 
498
     * Tests the trimComment method.
 
499
     */
 
500
    @Test
 
501
    public void testTrimComment()
 
502
    {
 
503
        assertEquals("Wrong trimmed comment", "This is a comment" + CR
 
504
                + "that spans multiple" + CR + "lines in a" + CR
 
505
                + " complex way.", PropertiesConfigurationLayout.trimComment(
 
506
                "   # This is a comment" + CR + "that spans multiple" + CR
 
507
                        + "!lines in a" + CR + " complex way.", false));
 
508
    }
 
509
 
 
510
    /**
 
511
     * Tests trimming a comment with trailing CRs.
 
512
     */
 
513
    @Test
 
514
    public void testTrimCommentTrainlingCR()
 
515
    {
 
516
        assertEquals("Wrong trimmed comment", "Comment with" + CR
 
517
                + "trailing CR" + CR, PropertiesConfigurationLayout
 
518
                .trimComment("Comment with" + CR + "! trailing CR" + CR, false));
 
519
    }
 
520
 
 
521
    /**
 
522
     * Tests enforcing comment characters in a comment.
 
523
     */
 
524
    @Test
 
525
    public void testTrimCommentFalse()
 
526
    {
 
527
        assertEquals("Wrong trimmed comment", "# Comment with" + CR
 
528
                + " ! some mixed " + CR + "#comment" + CR + "# lines",
 
529
                PropertiesConfigurationLayout.trimComment("Comment with" + CR
 
530
                        + " ! some mixed " + CR + "#comment" + CR + "lines",
 
531
                        true));
 
532
    }
 
533
 
 
534
    /**
 
535
     * Tests accessing data for a property, which is not stored.
 
536
     */
 
537
    @Test
 
538
    public void testGetNonExistingLayouData()
 
539
    {
 
540
        assertNull("A comment was found", layout.getComment("unknown"));
 
541
        assertTrue("A multi-line property", layout.isSingleLine("unknown"));
 
542
        assertEquals("Leading blanc lines", 0, layout
 
543
                .getBlancLinesBefore("unknown"));
 
544
    }
 
545
 
 
546
    /**
 
547
     * Tests accessing a property with a null key. This should throw an
 
548
     * exception.
 
549
     */
 
550
    @Test(expected = IllegalArgumentException.class)
 
551
    public void testGetNullLayouttData()
 
552
    {
 
553
        layout.setComment(null, TEST_COMMENT);
 
554
    }
 
555
 
 
556
    /**
 
557
     * Tests resetting a comment.
 
558
     */
 
559
    @Test
 
560
    public void testSetNullComment()
 
561
    {
 
562
        fillLayout();
 
563
        layout.setComment(TEST_KEY, null);
 
564
        assertNull("Comment was not reset", layout.getComment(TEST_KEY));
 
565
    }
 
566
 
 
567
    /**
 
568
     * Tests saving when a comment for a non existing property is contained in
 
569
     * the layout object. This comment should be ignored.
 
570
     */
 
571
    @Test
 
572
    public void testSaveCommentForUnexistingProperty()
 
573
            throws ConfigurationException
 
574
    {
 
575
        fillLayout();
 
576
        layout.setComment("NonExistingKey", "NonExistingComment");
 
577
        String output = getLayoutString();
 
578
        assertTrue("Non existing key was found", output
 
579
                .indexOf("NonExistingKey") < 0);
 
580
        assertTrue("Non existing comment was found", output
 
581
                .indexOf("NonExistingComment") < 0);
 
582
    }
 
583
 
 
584
    /**
 
585
     * Tests saving an empty layout object.
 
586
     */
 
587
    @Test
 
588
    public void testSaveEmptyLayout() throws ConfigurationException
 
589
    {
 
590
        checkLayoutString("");
 
591
    }
 
592
 
 
593
    /**
 
594
     * Tests the copy constructor.
 
595
     */
 
596
    @Test
 
597
    public void testInitCopy()
 
598
    {
 
599
        fillLayout();
 
600
        PropertiesConfigurationLayout l2 = new PropertiesConfigurationLayout(
 
601
                config, layout);
 
602
        assertEquals("Wrong number of keys", layout.getKeys().size(), l2
 
603
                .getKeys().size());
 
604
        for (Iterator<String> it = layout.getKeys().iterator(); it.hasNext();)
 
605
        {
 
606
            Object key = it.next();
 
607
            assertTrue("Key was not found: " + key, l2.getKeys().contains(key));
 
608
        }
 
609
    }
 
610
 
 
611
    /**
 
612
     * Tests if the copy and the original are independent from each other.
 
613
     */
 
614
    @Test
 
615
    public void testInitCopyModify()
 
616
    {
 
617
        fillLayout();
 
618
        PropertiesConfigurationLayout l2 = new PropertiesConfigurationLayout(
 
619
                config, layout);
 
620
        assertEquals("Comments are not equal", layout.getComment(TEST_KEY), l2
 
621
                .getComment(TEST_KEY));
 
622
        layout.setComment(TEST_KEY, "A new comment");
 
623
        assertEquals("Comment was changed", TEST_COMMENT, l2
 
624
                .getCanonicalComment(TEST_KEY, false));
 
625
        l2.setBlancLinesBefore(TEST_KEY, l2.getBlancLinesBefore(TEST_KEY) + 1);
 
626
        assertFalse("Blanc lines do not differ", layout
 
627
                .getBlancLinesBefore(TEST_KEY) == l2
 
628
                .getBlancLinesBefore(TEST_KEY));
 
629
    }
 
630
 
 
631
    /**
 
632
     * Tests changing the separator for a property.
 
633
     */
 
634
    @Test
 
635
    public void testSetSeparator() throws ConfigurationException
 
636
    {
 
637
        config.addProperty(TEST_KEY, TEST_VALUE);
 
638
        layout.setSeparator(TEST_KEY, ":");
 
639
        checkLayoutString(TEST_KEY + ":" + TEST_VALUE + CR);
 
640
    }
 
641
 
 
642
    /**
 
643
     * Tests setting the global separator. This separator should override the
 
644
     * separators for all properties.
 
645
     */
 
646
    @Test
 
647
    public void testSetGlobalSeparator() throws ConfigurationException
 
648
    {
 
649
        final String sep = "=";
 
650
        config.addProperty(TEST_KEY, TEST_VALUE);
 
651
        config.addProperty("key2", "value2");
 
652
        layout.setSeparator(TEST_KEY, " : ");
 
653
        layout.setGlobalSeparator(sep);
 
654
        checkLayoutString(TEST_KEY + sep + TEST_VALUE + CR + "key2" + sep
 
655
                + "value2" + CR);
 
656
    }
 
657
 
 
658
    /**
 
659
     * Tests setting the line separator.
 
660
     */
 
661
    @Test
 
662
    public void testSetLineSeparator() throws ConfigurationException
 
663
    {
 
664
        final String lf = CR + CR;
 
665
        config.addProperty(TEST_KEY, TEST_VALUE);
 
666
        layout.setBlancLinesBefore(TEST_KEY, 2);
 
667
        layout.setComment(TEST_KEY, TEST_COMMENT);
 
668
        layout.setHeaderComment("Header comment");
 
669
        layout.setLineSeparator(lf);
 
670
        checkLayoutString("# Header comment" + lf + lf + lf + lf + "# "
 
671
                + TEST_COMMENT + lf + TEST_KEY + " = " + TEST_VALUE + lf);
 
672
    }
 
673
 
 
674
    /**
 
675
     * Tests whether the line separator is also taken into account within
 
676
     * comments.
 
677
     */
 
678
    @Test
 
679
    public void testSetLineSeparatorInComments() throws ConfigurationException
 
680
    {
 
681
        final String lf = "<-\n";
 
682
        config.addProperty(TEST_KEY, TEST_VALUE);
 
683
        layout.setComment(TEST_KEY, TEST_COMMENT + "\nMore comment");
 
684
        layout.setHeaderComment("Header\ncomment");
 
685
        layout.setLineSeparator(lf);
 
686
        checkLayoutString("# Header" + lf + "# comment" + lf + lf + "# "
 
687
                + TEST_COMMENT + lf + "# More comment" + lf + TEST_KEY + " = "
 
688
                + TEST_VALUE + lf);
 
689
    }
 
690
 
 
691
    /**
 
692
     * Helper method for filling the layout object with some properties.
 
693
     */
 
694
    private void fillLayout()
 
695
    {
 
696
        builder.addComment("A header comment");
 
697
        builder.addComment(null);
 
698
        builder.addProperty("prop", "value");
 
699
        builder.addComment(TEST_COMMENT);
 
700
        builder.addProperty(TEST_KEY, TEST_VALUE);
 
701
        builder.addProperty("anotherProp", "anotherValue");
 
702
        try
 
703
        {
 
704
            layout.load(builder.getReader());
 
705
        }
 
706
        catch (ConfigurationException cex)
 
707
        {
 
708
            // should not happen
 
709
            fail("Exception was thrown: " + cex);
 
710
        }
 
711
    }
 
712
 
 
713
    /**
 
714
     * Writes the layout's data into a string.
 
715
     *
 
716
     * @return the layout file's content as string
 
717
     * @throws ConfigurationException if an error occurs
 
718
     */
 
719
    private String getLayoutString() throws ConfigurationException
 
720
    {
 
721
        StringWriter out = new StringWriter();
 
722
        layout.save(out);
 
723
        return out.toString();
 
724
    }
 
725
 
 
726
    /**
 
727
     * Checks if the layout's output is correct.
 
728
     *
 
729
     * @param expected the expected result
 
730
     * @throws ConfigurationException if an error occurs
 
731
     */
 
732
    private void checkLayoutString(String expected)
 
733
            throws ConfigurationException
 
734
    {
 
735
        assertEquals("Wrong layout file content", expected, getLayoutString());
 
736
    }
 
737
 
 
738
    /**
 
739
     * A helper class used for constructing test properties files.
 
740
     */
 
741
    static class PropertiesBuilder
 
742
    {
 
743
        /** A buffer for storing the data. */
 
744
        private StringBuilder buf = new StringBuilder();
 
745
 
 
746
        /** A counter for varying the comment character. */
 
747
        private int commentCounter;
 
748
 
 
749
        /**
 
750
         * Adds a property to the simulated file.
 
751
         *
 
752
         * @param key the property key
 
753
         * @param value the value
 
754
         */
 
755
        public void addProperty(String key, String value)
 
756
        {
 
757
            buf.append(key).append(" = ").append(value).append(CR);
 
758
        }
 
759
 
 
760
        /**
 
761
         * Adds a comment line.
 
762
         *
 
763
         * @param s the comment (can be <b>null</b>, then a blanc line is
 
764
         * added)
 
765
         */
 
766
        public void addComment(String s)
 
767
        {
 
768
            if (s != null)
 
769
            {
 
770
                if (commentCounter % 2 == 0)
 
771
                {
 
772
                    buf.append("# ");
 
773
                }
 
774
                else
 
775
                {
 
776
                    buf.append("! ");
 
777
                }
 
778
                buf.append(s);
 
779
                commentCounter++;
 
780
            }
 
781
            buf.append(CR);
 
782
        }
 
783
 
 
784
        /**
 
785
         * Returns a reader for the simulated properties.
 
786
         *
 
787
         * @return a reader
 
788
         */
 
789
        public Reader getReader()
 
790
        {
 
791
            return new StringReader(buf.toString());
 
792
        }
 
793
 
 
794
        /**
 
795
         * Returns a string representation of the buffer's content.
 
796
         *
 
797
         * @return the buffer as string
 
798
         */
 
799
        @Override
 
800
        public String toString()
 
801
        {
 
802
            return buf.toString();
 
803
        }
 
804
    }
 
805
 
 
806
    /**
 
807
     * A mock properties configuration implementation that is used to check
 
808
     * whether some expected methods are called.
 
809
     */
 
810
    static class LayoutTestConfiguration extends PropertiesConfiguration
 
811
    {
 
812
        /** Stores a builder object. */
 
813
        public PropertiesBuilder builder;
 
814
 
 
815
        /**
 
816
         * Simulates the propertyLoaded() callback. If a builder was set, a
 
817
         * load() call on the layout is invoked.
 
818
         */
 
819
        @Override
 
820
        boolean propertyLoaded(String key, String value)
 
821
                throws ConfigurationException
 
822
        {
 
823
            if (builder == null)
 
824
            {
 
825
                return super.propertyLoaded(key, value);
 
826
            }
 
827
            else
 
828
            {
 
829
                if (PropertiesConfiguration.getInclude().equals(key))
 
830
                {
 
831
                    getLayout().load(builder.getReader());
 
832
                    return false;
 
833
                }
 
834
                else
 
835
                {
 
836
                    return true;
 
837
                }
 
838
            }
 
839
        }
 
840
    }
 
841
}