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