1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration2;
19
20 import static org.apache.commons.configuration2.TempDirUtils.newFile;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.junit.jupiter.api.Assertions.fail;
27
28 import java.io.File;
29 import java.io.FileWriter;
30 import java.io.IOException;
31 import java.io.PrintWriter;
32 import java.io.StringReader;
33 import java.io.StringWriter;
34 import java.io.Writer;
35 import java.text.MessageFormat;
36 import java.util.Arrays;
37 import java.util.Collections;
38 import java.util.HashSet;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Set;
42 import java.util.stream.Stream;
43
44 import org.apache.commons.configuration2.SynchronizerTestImpl.Methods;
45 import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
46 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
47 import org.apache.commons.configuration2.builder.fluent.Parameters;
48 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
49 import org.apache.commons.configuration2.ex.ConfigurationException;
50 import org.apache.commons.configuration2.sync.ReadWriteSynchronizer;
51 import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
52 import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
53 import org.apache.commons.configuration2.tree.ImmutableNode;
54 import org.apache.commons.configuration2.tree.NodeHandler;
55 import org.apache.commons.configuration2.tree.NodeNameMatchers;
56 import org.junit.jupiter.api.Test;
57 import org.junit.jupiter.api.io.TempDir;
58 import org.junit.jupiter.params.ParameterizedTest;
59 import org.junit.jupiter.params.provider.Arguments;
60 import org.junit.jupiter.params.provider.MethodSource;
61
62
63
64
65 public class TestINIConfiguration {
66
67
68
69
70 private static final class GlobalSectionTestThread extends Thread {
71
72
73 private final INIConfiguration config;
74
75
76 private volatile boolean error;
77
78
79
80
81
82
83 public GlobalSectionTestThread(final INIConfiguration conf) {
84 config = conf;
85 }
86
87
88
89
90 @Override
91 public void run() {
92 final int loopCount = 250;
93
94 for (int i = 0; i < loopCount && !error; i++) {
95 try {
96 config.getSection(null);
97 } catch (final IllegalStateException istex) {
98 error = true;
99 }
100 }
101 }
102 }
103
104 private static final String LINE_SEPARATOR = System.lineSeparator();
105
106
107 private static final String INI_DATA = "[section1]" + LINE_SEPARATOR + "var1 = foo" + LINE_SEPARATOR + "var2 = 451" + LINE_SEPARATOR + LINE_SEPARATOR
108 + "[section2]" + LINE_SEPARATOR + "var1 = 123.45" + LINE_SEPARATOR + "var2 = bar" + LINE_SEPARATOR + LINE_SEPARATOR + "[section3]" + LINE_SEPARATOR
109 + "var1 = true" + LINE_SEPARATOR + "interpolated = ${section3.var1}" + LINE_SEPARATOR + "multi = foo" + LINE_SEPARATOR + "multi = bar" + LINE_SEPARATOR
110 + LINE_SEPARATOR;
111
112 private static final String INI_DATA2 = "[section4]" + LINE_SEPARATOR + "var1 = \"quoted value\"" + LINE_SEPARATOR
113 + "var2 = \"quoted value\\nwith \\\"quotes\\\"\"" + LINE_SEPARATOR + "var3 = 123 ; comment" + LINE_SEPARATOR + "var4 = \"1;2;3\" ; comment"
114 + LINE_SEPARATOR + "var5 = '\\'quoted\\' \"value\"' ; comment" + LINE_SEPARATOR + "var6 = \"\"" + LINE_SEPARATOR;
115
116 private static final String INI_DATA3 = "[section5]" + LINE_SEPARATOR + "multiLine = one \\" + LINE_SEPARATOR + " two \\" + LINE_SEPARATOR
117 + " three" + LINE_SEPARATOR + "singleLine = C:\\Temp\\" + LINE_SEPARATOR + "multiQuoted = one \\" + LINE_SEPARATOR + "\" two \" \\" + LINE_SEPARATOR
118 + " three" + LINE_SEPARATOR + "multiComment = one \\ ; a comment" + LINE_SEPARATOR + "two" + LINE_SEPARATOR
119 + "multiQuotedComment = \" one \" \\ ; comment" + LINE_SEPARATOR + "two" + LINE_SEPARATOR + "noFirstLine = \\" + LINE_SEPARATOR + " line 2"
120 + LINE_SEPARATOR + "continueNoLine = one \\" + LINE_SEPARATOR;
121
122 private static final String INI_DATA4 = "[section6]" + LINE_SEPARATOR + "key1{0}value1" + LINE_SEPARATOR + "key2{0}value2" + LINE_SEPARATOR + LINE_SEPARATOR
123 + "[section7]" + LINE_SEPARATOR + "key3{0}value3" + LINE_SEPARATOR;
124
125 private static final String INI_DATA5 = "[section4]" + LINE_SEPARATOR + "var1 = \"quoted value\"" + LINE_SEPARATOR
126 + "var2 = \"quoted value\\nwith \\\"quotes\\\"\"" + LINE_SEPARATOR + "var3 = 123 # comment" + LINE_SEPARATOR + "var4 = \"1#2;3\" # comment"
127 + LINE_SEPARATOR + "var5 = '\\'quoted\\' \"value\"' # comment" + LINE_SEPARATOR + "var6 = \"\"" + LINE_SEPARATOR;
128
129
130 private static final String INI_DATA6 = "[section1]; main section" + LINE_SEPARATOR + "var1 = foo" + LINE_SEPARATOR + LINE_SEPARATOR
131 + "[section11] ; sub-section related to [section1]" + LINE_SEPARATOR + "var1 = 123.45" + LINE_SEPARATOR;
132
133
134 private static final String INI_DATA7 = "[section1]# main section" + LINE_SEPARATOR + "var1 = foo" + LINE_SEPARATOR + LINE_SEPARATOR
135 + "[section11] # sub-section related to [section1]" + LINE_SEPARATOR + "var1 = 123.45" + LINE_SEPARATOR;
136
137 private static final String INI_DATA_SEPARATORS = "[section]" + LINE_SEPARATOR + "var1 = value1" + LINE_SEPARATOR + "var2 : value2" + LINE_SEPARATOR
138 + "var3=value3" + LINE_SEPARATOR + "var4:value4" + LINE_SEPARATOR + "var5 : value=5" + LINE_SEPARATOR + "var:6=value" + LINE_SEPARATOR
139 + "var:7=\"value7\"" + LINE_SEPARATOR + "var:8 = \"value8\"" + LINE_SEPARATOR;
140
141
142 private static final String INI_DATA_GLOBAL_ONLY = "globalVar = testGlobal" + LINE_SEPARATOR + LINE_SEPARATOR;
143
144
145 private static final String INI_DATA_GLOBAL = INI_DATA_GLOBAL_ONLY + INI_DATA;
146
147
148
149
150
151
152
153
154 private static void load(final INIConfiguration instance, final String data) throws ConfigurationException {
155 try (StringReader reader = new StringReader(data)) {
156 instance.read(reader);
157 } catch (final IOException e) {
158 throw new ConfigurationException(e);
159 }
160 }
161
162 private static Stream<Arguments> provideSectionsWithComments() {
163 return Stream.of(
164 Arguments.of(INI_DATA6, false, new String[]{null, "section11] ; sub-section related to [section1"}),
165 Arguments.of(INI_DATA7, false, new String[]{null, "section11] # sub-section related to [section1"}),
166 Arguments.of(INI_DATA6, true, new String[]{"section1", "section11"}),
167 Arguments.of(INI_DATA7, true, new String[]{"section1", "section11"})
168 );
169 }
170
171 private static Stream<Arguments> provideValuesWithComments() {
172 return Stream.of(
173 Arguments.of(INI_DATA2, "section4.var3", "123"),
174 Arguments.of(INI_DATA2, "section4.var4", "1;2;3"),
175 Arguments.of(INI_DATA2, "section4.var5", "'quoted' \"value\""),
176 Arguments.of(INI_DATA5, "section4.var3", "123"),
177 Arguments.of(INI_DATA5, "section4.var4", "1#2;3"),
178 Arguments.of(INI_DATA5, "section4.var5", "'quoted' \"value\"")
179 );
180 }
181
182
183
184
185
186
187
188
189
190 private static String saveToString(final INIConfiguration config) throws ConfigurationException {
191 final StringWriter writer = new StringWriter();
192 try {
193 config.write(writer);
194 } catch (final IOException e) {
195 throw new ConfigurationException(e);
196 }
197 return writer.toString();
198 }
199
200
201
202
203
204
205
206
207 private static INIConfiguration setUpConfig(final String data) throws ConfigurationException {
208 return setUpConfig(data, false);
209 }
210
211
212
213
214
215
216
217
218
219 private static INIConfiguration setUpConfig(final String data, final boolean inLineCommentsAllowed) throws ConfigurationException {
220
221 final INIConfiguration instance = INIConfiguration.builder()
222 .setSectionInLineCommentsAllowed(inLineCommentsAllowed)
223 .build();
224
225 instance.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
226 load(instance, data);
227 return instance;
228 }
229
230
231 @TempDir
232 public File tempFolder;
233
234
235
236
237
238
239 private void checkContent(final INIConfiguration instance) {
240 assertEquals("foo", instance.getString("section1.var1"));
241 assertEquals(451, instance.getInt("section1.var2"));
242 assertEquals(123.45, instance.getDouble("section2.var1"), .001);
243 assertEquals("bar", instance.getString("section2.var2"));
244 assertTrue(instance.getBoolean("section3.var1"));
245 assertEquals(new HashSet<>(Arrays.asList("section1", "section2", "section3")), instance.getSections());
246 }
247
248
249
250
251
252
253
254 private void checkLoad(final String data) throws ConfigurationException {
255 final INIConfiguration instance = setUpConfig(data);
256 checkContent(instance);
257 }
258
259
260
261
262
263
264
265
266 private void checkSave(final String content) throws ConfigurationException {
267 final INIConfiguration config = setUpConfig(content);
268 final String sOutput = saveToString(config);
269 assertEquals(content, sOutput);
270 }
271
272
273
274
275
276
277
278 private void checkSectionNames(final INIConfiguration config, final String[] expected) {
279 final Set<String> sectionNames = config.getSections();
280 assertEquals(new HashSet<>(Arrays.asList(expected)), sectionNames);
281 }
282
283
284
285
286
287
288
289
290 private INIConfiguration checkSectionNames(final String data, final String[] expected) throws ConfigurationException {
291 final INIConfiguration config = setUpConfig(data);
292 checkSectionNames(config, expected);
293 return config;
294 }
295
296
297
298
299 @Test
300 public void testCommentLeadingSeparatorUsedInINIInput() throws Exception {
301 final String inputCommentLeadingSeparator = ";";
302 final String input = "[section]" + LINE_SEPARATOR + "key1=a;b;c" + LINE_SEPARATOR + "key2=a#b#c" + LINE_SEPARATOR + ";key3=value3" + LINE_SEPARATOR
303 + "#key4=value4" + LINE_SEPARATOR;
304
305 final INIConfiguration instance = new FileBasedConfigurationBuilder<>(INIConfiguration.class)
306 .configure(new Parameters().ini().setCommentLeadingCharsUsedInInput(inputCommentLeadingSeparator)).getConfiguration();
307 load(instance, input);
308
309 assertEquals("a;b;c", instance.getString("section.key1"));
310 assertEquals("a#b#c", instance.getString("section.key2"));
311 assertNull(instance.getString("section.;key3"));
312 assertEquals("value4", instance.getString("section.#key4"));
313 }
314
315
316
317
318 @Test
319 public void testEmptySection() throws ConfigurationException {
320 final INIConfiguration config = setUpConfig("[]" + LINE_SEPARATOR + "key=value" + LINE_SEPARATOR);
321 final String value = config.getString(" .key");
322 assertEquals("value", value);
323 }
324
325
326
327
328 @Test
329 public void testExpressionEngineIgnoringCase() throws ConfigurationException {
330 final DefaultExpressionEngine engine = new DefaultExpressionEngine(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS, NodeNameMatchers.EQUALS_IGNORE_CASE);
331 final INIConfiguration config = new INIConfiguration();
332 config.setExpressionEngine(engine);
333 load(config, INI_DATA);
334
335 checkContent(config);
336 assertEquals("foo", config.getString("Section1.var1"));
337 assertEquals("foo", config.getString("section1.Var1"));
338 assertEquals("foo", config.getString("SECTION1.VAR1"));
339 }
340
341
342
343
344 @Test
345 public void testGetPropertyNoKey() throws ConfigurationException {
346 final String data = INI_DATA2 + LINE_SEPARATOR + "= noKey" + LINE_SEPARATOR;
347 final INIConfiguration config = setUpConfig(data);
348 assertEquals("noKey", config.getString("section4. "));
349 }
350
351
352
353
354 @Test
355 public void testGetPropertyNoValue() throws ConfigurationException {
356 final String data = INI_DATA2 + LINE_SEPARATOR + "noValue =" + LINE_SEPARATOR;
357 final INIConfiguration config = setUpConfig(data);
358 assertEquals("", config.getString("section4.noValue"));
359 }
360
361
362
363
364 @Test
365 public void testGetSectionConnected() throws ConfigurationException {
366 final INIConfiguration config = setUpConfig(INI_DATA);
367 final HierarchicalConfiguration<ImmutableNode> section = config.getSection("section1");
368 section.setProperty("var1", "foo2");
369 assertEquals("foo2", config.getString("section1.var1"));
370 }
371
372
373
374
375 @Test
376 public void testGetSectionDuplicate() {
377 final INIConfiguration config = new INIConfiguration();
378 config.addProperty("section.var1", "value1");
379 config.addProperty("section(-1).var2", "value2");
380 final HierarchicalConfiguration<ImmutableNode> section = config.getSection("section");
381 final Iterator<String> keys = section.getKeys();
382 assertEquals("var1", keys.next());
383 assertFalse(keys.hasNext());
384 }
385
386
387
388
389 @Test
390 public void testGetSectionExisting() throws ConfigurationException {
391 final INIConfiguration config = setUpConfig(INI_DATA);
392 final HierarchicalConfiguration<ImmutableNode> section = config.getSection("section1");
393 assertEquals("foo", section.getString("var1"));
394 assertEquals("451", section.getString("var2"));
395 }
396
397
398
399
400 @Test
401 public void testGetSectionGloabalMultiThreaded() throws ConfigurationException, InterruptedException {
402 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
403 config.setSynchronizer(new ReadWriteSynchronizer());
404 final int threadCount = 10;
405 final GlobalSectionTestThread[] threads = new GlobalSectionTestThread[threadCount];
406 for (int i = 0; i < threadCount; i++) {
407 threads[i] = new GlobalSectionTestThread(config);
408 threads[i].start();
409 }
410 for (int i = 0; i < threadCount; i++) {
411 threads[i].join();
412 assertFalse(threads[i].error);
413 }
414 }
415
416
417
418
419 @Test
420 public void testGetSectionGlobal() throws ConfigurationException {
421 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
422 final HierarchicalConfiguration<ImmutableNode> section = config.getSection(null);
423 assertEquals("testGlobal", section.getString("globalVar"));
424 }
425
426
427
428
429 @Test
430 public void testGetSectionGlobalNonExisting() throws ConfigurationException {
431 final INIConfiguration config = setUpConfig(INI_DATA);
432 final HierarchicalConfiguration<ImmutableNode> section = config.getSection(null);
433 assertTrue(section.isEmpty());
434 }
435
436
437
438
439 @Test
440 public void testGetSectionMerged() throws ConfigurationException {
441 final String data = INI_DATA + "[section1]" + LINE_SEPARATOR + "var3 = merged" + LINE_SEPARATOR;
442 final INIConfiguration config = setUpConfig(data);
443 final HierarchicalConfiguration<ImmutableNode> section = config.getSection("section1");
444 assertEquals("foo", section.getString("var1"));
445 assertEquals("451", section.getString("var2"));
446 assertEquals("merged", section.getString("var3"));
447 }
448
449
450
451
452 @Test
453 public void testGetSectionNonExisting() throws ConfigurationException {
454 final INIConfiguration config = setUpConfig(INI_DATA);
455 final HierarchicalConfiguration<ImmutableNode> section = config.getSection("Non existing section");
456 assertTrue(section.isEmpty());
457 }
458
459
460
461
462 @Test
463 public void testGetSectionNonExistingManipulate() throws ConfigurationException, IOException {
464 final INIConfiguration config = setUpConfig(INI_DATA);
465 HierarchicalConfiguration<ImmutableNode> section = config.getSection("newSection");
466 section.addProperty("test", "success");
467 assertEquals("success", config.getString("newSection.test"));
468 final StringWriter writer = new StringWriter();
469 config.write(writer);
470 final INIConfiguration config2 = setUpConfig(writer.toString());
471 section = config2.getSection("newSection");
472 assertEquals("success", section.getString("test"));
473 }
474
475
476
477
478 @Test
479 public void testGetSections() {
480 final INIConfiguration instance = new INIConfiguration();
481 instance.addProperty("test1.foo", "bar");
482 instance.addProperty("test2.foo", "abc");
483 final Set<String> expResult = new HashSet<>();
484 expResult.add("test1");
485 expResult.add("test2");
486 final Set<String> result = instance.getSections();
487 assertEquals(expResult, result);
488 }
489
490
491
492
493 @Test
494 public void testGetSectionsAdded() throws ConfigurationException {
495 final INIConfiguration config = setUpConfig(INI_DATA2);
496 config.addProperty("section5.test", Boolean.TRUE);
497 checkSectionNames(config, new String[] {"section4", "section5"});
498 }
499
500
501
502
503
504 @Test
505 public void testGetSectionsDottedVar() throws ConfigurationException {
506 final String data = "dotted.var = 1" + LINE_SEPARATOR + INI_DATA_GLOBAL;
507 final INIConfiguration config = checkSectionNames(data, new String[] {null, "section1", "section2", "section3"});
508 assertEquals(1, config.getInt("dotted..var"));
509 }
510
511
512
513
514 @Test
515 public void testGetSectionsGlobalOnly() throws ConfigurationException {
516 checkSectionNames(INI_DATA_GLOBAL_ONLY, new String[] {null});
517 }
518
519
520
521
522 @Test
523 public void testGetSectionsNoGlobal() throws ConfigurationException {
524 checkSectionNames(INI_DATA, new String[] {"section1", "section2", "section3"});
525 }
526
527
528
529
530 @Test
531 public void testGetSectionsSynchronized() throws ConfigurationException {
532 final INIConfiguration config = setUpConfig(INI_DATA);
533 final SynchronizerTestImpl sync = new SynchronizerTestImpl();
534 config.setSynchronizer(sync);
535 assertFalse(config.getSections().isEmpty());
536 sync.verify(Methods.BEGIN_READ, Methods.END_READ);
537 }
538
539
540
541
542 @Test
543 public void testGetSectionsWithGlobal() throws ConfigurationException {
544 checkSectionNames(INI_DATA_GLOBAL, new String[] {null, "section1", "section2", "section3"});
545 }
546
547
548
549
550 @ParameterizedTest
551 @MethodSource("provideSectionsWithComments")
552 public void testGetSectionsWithInLineComment(final String source, final boolean allowComments, final String[] results) throws ConfigurationException {
553 final INIConfiguration config = setUpConfig(source, allowComments);
554 checkSectionNames(config, results);
555 }
556
557
558
559
560 @Test
561 public void testGlobalProperty() throws ConfigurationException {
562 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
563 assertEquals("testGlobal", config.getString("globalVar"));
564 }
565
566
567
568
569 @Test
570 public void testGlobalSectionConnected() throws ConfigurationException {
571 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
572 final HierarchicalConfiguration<ImmutableNode> sub = config.getSection(null);
573 config.setProperty("globalVar", "changed");
574 assertEquals("changed", sub.getString("globalVar"));
575 }
576
577
578
579
580 @Test
581 public void testGlobalSectionNodeHandlerGetChildByIndex() throws ConfigurationException {
582 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
583 final SubnodeConfiguration sub = config.getSection(null);
584 final NodeHandler<ImmutableNode> handler = sub.getModel().getNodeHandler();
585 final ImmutableNode rootNode = handler.getRootNode();
586 final ImmutableNode child = handler.getChild(rootNode, 0);
587 assertEquals("globalVar", child.getNodeName());
588 assertThrows(IndexOutOfBoundsException.class, () -> handler.getChild(rootNode, 1));
589 }
590
591
592
593
594 @Test
595 public void testGlobalSectionNodeHandlerGetChildrenByName() throws ConfigurationException {
596 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
597 final SubnodeConfiguration sub = config.getSection(null);
598 final NodeHandler<ImmutableNode> handler = sub.getModel().getNodeHandler();
599 assertTrue(handler.getChildren(sub.getModel().getNodeHandler().getRootNode(), "section1").isEmpty());
600 }
601
602
603
604
605 @Test
606 public void testGlobalSectionNodeHandlerGetChildrenCount() throws ConfigurationException {
607 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
608 final SubnodeConfiguration sub = config.getSection(null);
609 final NodeHandler<ImmutableNode> handler = sub.getModel().getNodeHandler();
610 assertEquals(1, handler.getChildrenCount(handler.getRootNode(), null));
611 }
612
613
614
615
616 @Test
617 public void testGlobalSectionNodeHandlerIndexOfChild() throws ConfigurationException {
618 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
619 final SubnodeConfiguration sub = config.getSection(null);
620 final NodeHandler<ImmutableNode> handler = sub.getModel().getNodeHandler();
621 final List<ImmutableNode> children = handler.getRootNode().getChildren();
622 assertEquals(0, handler.indexOfChild(handler.getRootNode(), children.get(0)));
623 assertEquals(-1, handler.indexOfChild(handler.getRootNode(), children.get(1)));
624 }
625
626
627
628
629 @Test
630 public void testIsCommentLine() {
631 final INIConfiguration instance = new INIConfiguration();
632 assertTrue(instance.isCommentLine("#comment1"));
633 assertTrue(instance.isCommentLine(";comment1"));
634 assertFalse(instance.isCommentLine("nocomment=true"));
635 assertFalse(instance.isCommentLine(null));
636 }
637
638
639
640
641 @Test
642 public void testIsSectionLine() {
643 final INIConfiguration instance = new INIConfiguration();
644 assertTrue(instance.isSectionLine("[section]"));
645 assertFalse(instance.isSectionLine("nosection=true"));
646 assertFalse(instance.isSectionLine(null));
647 }
648
649
650
651
652 @Test
653 public void testKeysOfGlobalSection() throws ConfigurationException {
654 final INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
655 final HierarchicalConfiguration<ImmutableNode> sub = config.getSection(null);
656 final Iterator<String> keys = sub.getKeys();
657 assertEquals("globalVar", keys.next());
658 if (keys.hasNext()) {
659 final StringBuilder buf = new StringBuilder();
660 do {
661 buf.append(keys.next()).append(' ');
662 } while (keys.hasNext());
663 fail("Got additional keys: " + buf);
664 }
665 }
666
667
668
669
670 @Test
671 public void testLineContinuation() throws ConfigurationException {
672 final INIConfiguration config = setUpConfig(INI_DATA3);
673 assertEquals("one" + LINE_SEPARATOR + "two" + LINE_SEPARATOR + "three", config.getString("section5.multiLine"));
674 }
675
676
677
678
679 @Test
680 public void testLineContinuationAtEnd() throws ConfigurationException {
681 final INIConfiguration config = setUpConfig(INI_DATA3);
682 assertEquals("one" + LINE_SEPARATOR, config.getString("section5.continueNoLine"));
683 }
684
685
686
687
688 @Test
689 public void testLineContinuationComment() throws ConfigurationException {
690 final INIConfiguration config = setUpConfig(INI_DATA3);
691 assertEquals("one" + LINE_SEPARATOR + "two", config.getString("section5.multiComment"));
692 }
693
694
695
696
697 @Test
698 public void testLineContinuationEmptyLine() throws ConfigurationException {
699 final INIConfiguration config = setUpConfig(INI_DATA3);
700 assertEquals(LINE_SEPARATOR + "line 2", config.getString("section5.noFirstLine"));
701 }
702
703
704
705
706 @Test
707 public void testLineContinuationNone() throws ConfigurationException {
708 final INIConfiguration config = setUpConfig(INI_DATA3);
709 assertEquals("C:\\Temp\\", config.getString("section5.singleLine"));
710 }
711
712
713
714
715
716 @Test
717 public void testLineContinuationQuoted() throws ConfigurationException {
718 final INIConfiguration config = setUpConfig(INI_DATA3);
719 assertEquals("one" + LINE_SEPARATOR + " two " + LINE_SEPARATOR + "three", config.getString("section5.multiQuoted"));
720 }
721
722
723
724
725 @Test
726 public void testLineContinuationQuotedComment() throws ConfigurationException {
727 final INIConfiguration config = setUpConfig(INI_DATA3);
728 assertEquals(" one " + LINE_SEPARATOR + "two", config.getString("section5.multiQuotedComment"));
729 }
730
731
732
733
734 @Test
735 public void testListDelimiterHandling() throws ConfigurationException {
736 final INIConfiguration config = new INIConfiguration();
737 config.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
738 config.addProperty("list", "a,b,c");
739 config.addProperty("listesc", "3\\,1415");
740 final String output = saveToString(config);
741 final INIConfiguration config2 = setUpConfig(output);
742 assertEquals(Arrays.asList("a", "b", "c"), config2.getList("list"));
743 assertEquals("3,1415", config2.getString("listesc"));
744 }
745
746
747
748
749 @Test
750 public void testListDelimiterHandlingInList() throws ConfigurationException {
751 final String data = INI_DATA + "[sectest]" + LINE_SEPARATOR + "list = 3\\,1415,pi,\\\\Test\\,5" + LINE_SEPARATOR;
752 final INIConfiguration config = setUpConfig(data);
753 final INIConfiguration config2 = setUpConfig(saveToString(config));
754 final List<Object> list = config2.getList("sectest.list");
755 assertEquals(Arrays.asList("3,1415", "pi", "\\Test,5"), list);
756 }
757
758
759
760
761 @Test
762 public void testListParsingDisabled() throws ConfigurationException {
763 final INIConfiguration config = new INIConfiguration();
764 load(config, "[test]" + LINE_SEPARATOR + "nolist=1,2,3");
765 assertEquals("1,2,3", config.getString("test.nolist"));
766 }
767
768
769
770
771 @Test
772 public void testLoad() throws Exception {
773 checkLoad(INI_DATA);
774 }
775
776
777
778
779 @Test
780 public void testLoadAlternativeSeparator() throws Exception {
781 checkLoad(INI_DATA.replace('=', ':'));
782 }
783
784
785
786
787 @Test
788 public void testLoadFromBuilder() throws ConfigurationException, IOException {
789 final File file = writeTestFile(INI_DATA);
790 final FileBasedConfigurationBuilder<INIConfiguration> builder = new FileBasedConfigurationBuilder<>(INIConfiguration.class);
791 builder.configure(new FileBasedBuilderParametersImpl().setFile(file));
792 final INIConfiguration config = builder.getConfiguration();
793 checkContent(config);
794 }
795
796
797
798
799 @Test
800 public void testMergeDuplicateSection() throws ConfigurationException, IOException {
801 final String data = "[section]\nvar1 = sec1\n\n" + "[section]\nvar2 = sec2\n";
802 final INIConfiguration config = setUpConfig(data);
803 assertEquals("sec1", config.getString("section.var1"));
804 assertEquals("sec2", config.getString("section.var2"));
805 final HierarchicalConfiguration<ImmutableNode> sub = config.getSection("section");
806 assertEquals("sec1", sub.getString("var1"));
807 assertEquals("sec2", sub.getString("var2"));
808 final StringWriter writer = new StringWriter();
809 config.write(writer);
810 final String content = writer.toString();
811 final int pos = content.indexOf("[section]");
812 assertTrue(pos >= 0);
813 assertTrue(content.indexOf("[section]", pos + 1) < 0);
814 }
815
816
817
818
819 @Test
820 public void testMultipleSeparators() throws ConfigurationException {
821 final INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
822 assertEquals("value=5", config.getString("section.var5"));
823 assertEquals("6=value", config.getString("section.var"));
824 }
825
826
827
828
829 @Test
830 public void testMultipleSeparatorsQuoted() throws ConfigurationException {
831 final INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
832 assertEquals("value7", config.getString("section.var:7"));
833 assertEquals("value8", config.getString("section.var:8"));
834 }
835
836
837
838
839
840 @Test
841 public void testPropertyWithDelimiter() throws ConfigurationException {
842 final String data = INI_DATA + "key.dot = dotValue";
843 final INIConfiguration conf = new INIConfiguration();
844 load(conf, data);
845 assertEquals("dotValue", conf.getString("section3.key..dot"));
846 final String output = saveToString(conf);
847 assertTrue(output.contains("key.dot = dotValue"));
848 }
849
850 @Test
851 public void testQuotedValue() throws Exception {
852 final INIConfiguration config = setUpConfig(INI_DATA2);
853 assertEquals("quoted value", config.getString("section4.var1"));
854 }
855
856
857
858
859 @Test
860 public void testQuotedValueEmpty() throws ConfigurationException {
861 final INIConfiguration config = setUpConfig(INI_DATA2);
862 assertEquals("", config.getString("section4.var6"));
863 }
864
865 @Test
866 public void testQuotedValueWithComment() throws Exception {
867 final INIConfiguration config = setUpConfig(INI_DATA2);
868 assertEquals("1;2;3", config.getString("section4.var4"));
869 }
870
871 @Test
872 public void testQuotedValueWithQuotes() throws Exception {
873 final INIConfiguration config = setUpConfig(INI_DATA2);
874 assertEquals("quoted value\\nwith \"quotes\"", config.getString("section4.var2"));
875 }
876
877 @Test
878 public void testQuotedValueWithSingleQuotes() throws Exception {
879 final INIConfiguration config = setUpConfig(INI_DATA2);
880 assertEquals("'quoted' \"value\"", config.getString("section4.var5"));
881 }
882
883
884
885
886 @Test
887 public void testQuotedValueWithWhitespace() throws Exception {
888 final String content = "CmdPrompt = \" [test@cmd ~]$ \"";
889 final INIConfiguration config = setUpConfig(content);
890 assertEquals(" [test@cmd ~]$ ", config.getString("CmdPrompt"));
891 }
892
893
894
895
896 @Test
897 public void testQuotedValueWithWhitespaceAndComment() throws Exception {
898 final String content = "CmdPrompt = \" [test@cmd ~]$ \" ; a comment";
899 final INIConfiguration config = setUpConfig(content);
900 assertEquals(" [test@cmd ~]$ ", config.getString("CmdPrompt"));
901 }
902
903
904
905
906 @Test
907 public void testSave() throws Exception {
908 final Writer writer = new StringWriter();
909 final INIConfiguration instance = new INIConfiguration();
910 instance.addProperty("section1.var1", "foo");
911 instance.addProperty("section1.var2", "451");
912 instance.addProperty("section2.var1", "123.45");
913 instance.addProperty("section2.var2", "bar");
914 instance.addProperty("section3.var1", "true");
915 instance.addProperty("section3.interpolated", "${section3.var1}");
916 instance.addProperty("section3.multi", "foo");
917 instance.addProperty("section3.multi", "bar");
918 instance.write(writer);
919
920 assertEquals(INI_DATA, writer.toString());
921 }
922
923
924
925
926 @Test
927 public void testSaveClearedSection() throws ConfigurationException, IOException {
928 final String data = "[section]\ntest = failed\n";
929 final INIConfiguration config = setUpConfig(data);
930 SubnodeConfiguration sub = config.getSection("section");
931 assertFalse(sub.isEmpty());
932 sub.clear();
933 sub.close();
934 sub = config.getSection("section");
935 sub.setProperty("test", "success");
936 final StringWriter writer = new StringWriter();
937 config.write(writer);
938 final HierarchicalConfiguration<?> config2 = setUpConfig(writer.toString());
939 assertEquals("success", config2.getString("section.test"));
940 }
941
942
943
944
945
946 @Test
947 public void testSaveKeysWithDelimiters() throws ConfigurationException, IOException {
948 INIConfiguration conf = new INIConfiguration();
949 final String section = "Section..with..dots";
950 conf.addProperty(section + ".test1", "test1");
951 conf.addProperty(section + ".test2", "test2");
952 final StringWriter writer = new StringWriter();
953 conf.write(writer);
954 conf = new INIConfiguration();
955 conf.read(new StringReader(writer.toString()));
956 assertEquals("test1", conf.getString(section + ".test1"));
957 assertEquals("test2", conf.getString(section + ".test2"));
958 }
959
960
961
962
963 @Test
964 public void testSaveWithDelimiterParsingDisabled() throws ConfigurationException {
965 final INIConfiguration config = new INIConfiguration();
966 final String data = INI_DATA.substring(0, INI_DATA.length() - LINE_SEPARATOR.length()) + "nolist = 1,2, 3";
967 load(config, data);
968 assertEquals("1,2, 3", config.getString("section3.nolist"));
969 final String content = saveToString(config);
970 final INIConfiguration config2 = new INIConfiguration();
971 load(config2, content);
972 assertEquals("1,2, 3", config2.getString("section3.nolist"));
973 }
974
975
976
977
978 @Test
979 public void testSaveWithGlobalSection() throws ConfigurationException {
980 checkSave(INI_DATA_GLOBAL);
981 }
982
983
984
985
986 @Test
987 public void testSaveWithOnlyGlobalSection() throws ConfigurationException {
988 checkSave(INI_DATA_GLOBAL_ONLY);
989 }
990
991
992
993
994 @Test
995 public void testSeparators() throws ConfigurationException {
996 final INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
997 for (int i = 1; i <= 4; i++) {
998 assertEquals("value" + i, config.getString("section.var" + i));
999 }
1000 }
1001
1002
1003
1004
1005 @Test
1006 public void testSeparatorUsedInINIInput() throws Exception {
1007 final String inputSeparator = "=";
1008 final String input = "[section]" + LINE_SEPARATOR + "k1:v1$key1=value1" + LINE_SEPARATOR + "k1:v1,k2:v2$key2=value2" + LINE_SEPARATOR + "key3:value3"
1009 + LINE_SEPARATOR + "key4 = value4" + LINE_SEPARATOR;
1010
1011 final INIConfiguration instance = new FileBasedConfigurationBuilder<>(INIConfiguration.class)
1012 .configure(new Parameters().ini().setSeparatorUsedInInput(inputSeparator)).getConfiguration();
1013 load(instance, input);
1014
1015 assertEquals("value1", instance.getString("section.k1:v1$key1"));
1016 assertEquals("value2", instance.getString("section.k1:v1,k2:v2$key2"));
1017 assertEquals("", instance.getString("section.key3:value3"));
1018 assertEquals("value4", instance.getString("section.key4").trim());
1019 }
1020
1021
1022
1023
1024 @Test
1025 public void testSeparatorUsedInINIOutput() throws Exception {
1026 final String outputSeparator = ": ";
1027 final String input = MessageFormat.format(INI_DATA4, "=").trim();
1028 final String expectedOutput = MessageFormat.format(INI_DATA4, outputSeparator).trim();
1029
1030 final INIConfiguration instance = new FileBasedConfigurationBuilder<>(INIConfiguration.class)
1031 .configure(new Parameters().ini().setSeparatorUsedInOutput(outputSeparator)).getConfiguration();
1032 load(instance, input);
1033
1034 final Writer writer = new StringWriter();
1035 instance.write(writer);
1036 final String result = writer.toString().trim();
1037
1038 assertEquals(expectedOutput, result);
1039 }
1040
1041
1042
1043
1044 @ParameterizedTest
1045 @MethodSource("provideValuesWithComments")
1046 public void testValueWithComment(final String source, final String key, final String value) throws Exception {
1047 final INIConfiguration config = setUpConfig(source);
1048 assertEquals(value, config.getString(key));
1049 }
1050
1051
1052
1053
1054 @Test
1055 public void testValueWithDelimiters() throws ConfigurationException {
1056 final INIConfiguration config = setUpConfig("[test]" + LINE_SEPARATOR + "list=1,2,3" + LINE_SEPARATOR);
1057 final List<Object> list = config.getList("test.list");
1058 assertEquals(Arrays.asList("1", "2", "3"), list);
1059 }
1060
1061
1062
1063
1064
1065 @Test
1066 public void testValueWithSemicolon() throws ConfigurationException {
1067 final String path = "C:\\Program Files\\jar\\manage.jar;" + "C:\\Program Files\\jar\\guiLauncher.jar";
1068 final String content = "[Environment]" + LINE_SEPARATOR + "Application Type=any" + LINE_SEPARATOR + "Class Path=" + path + " ;comment" + LINE_SEPARATOR
1069 + "Path=" + path + "\t; another comment";
1070 final INIConfiguration config = setUpConfig(content);
1071 assertEquals(path, config.getString("Environment.Class Path"));
1072 assertEquals(path, config.getString("Environment.Path"));
1073 }
1074
1075
1076
1077
1078 @Test
1079 public void testWriteEmptySection() throws ConfigurationException, IOException {
1080 final String section = "[EmptySection]";
1081 final INIConfiguration config = setUpConfig(section);
1082 assertEquals(Collections.singleton("EmptySection"), config.getSections());
1083
1084 final StringWriter writer = new StringWriter();
1085 config.write(writer);
1086 assertEquals(section + LINE_SEPARATOR + LINE_SEPARATOR, writer.toString());
1087 }
1088
1089 @Test
1090 public void testWriteValueWithCommentChar() throws Exception {
1091 final INIConfiguration config = new INIConfiguration();
1092 config.setProperty("section.key1", "1;2;3");
1093
1094 final StringWriter writer = new StringWriter();
1095 config.write(writer);
1096
1097 final INIConfiguration config2 = new INIConfiguration();
1098 config2.read(new StringReader(writer.toString()));
1099
1100 assertEquals("1;2;3", config2.getString("section.key1"));
1101 }
1102
1103
1104
1105
1106
1107
1108
1109
1110 private File writeTestFile(final String content) throws IOException {
1111 final File file = newFile(tempFolder);
1112 try (PrintWriter out = new PrintWriter(new FileWriter(file))) {
1113 out.println(content);
1114 }
1115 return file;
1116 }
1117 }