1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.config;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.commons.utils.StringUtils.*;
22 import static org.junit.jupiter.api.Assertions.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.apache.juneau.config.store.*;
28 import org.junit.jupiter.api.*;
29
30 class ConfigMap_Test extends TestBase {
31
32 static final String ENCODED = "*";
33 static final String BASE64 = "^";
34
35
36
37
38 @Test void a01_nonExistentConfig() throws Exception {
39 var s = MemoryStore.create().build();
40 var cm = s.getMap("A.cfg");
41 assertEquals("", cm.toString());
42 }
43
44
45
46
47 @Test void a02_blankConfig() throws Exception {
48
49 var s = initStore("A.cfg", "");
50 var cm = s.getMap("A.cfg");
51 assertEquals("", cm.toString());
52
53 s.update("A.cfg", " \n \n ");
54 s.getMap("A.cfg");
55 }
56
57
58
59
60 @Test void a03_simpleOneLine() throws Exception {
61 var s = initStore("A.cfg",
62 "foo=bar"
63 );
64 var cm = s.getMap("A.cfg");
65
66 assertEquals("foo=bar|", pipedLines(cm));
67
68 assertEquals("", join(cm.getPreLines(""), '|'));
69 assertEquals("", join(cm.getEntry("", "foo").getPreLines(), '|'));
70
71 assertEquals("bar", cm.getEntry("", "foo").getValue());
72
73
74 s.update("A.cfg", cm.toString());
75 cm = s.getMap("A.cfg");
76 assertEquals("foo=bar|", pipedLines(cm));
77 }
78
79
80
81
82 @Test void a04_simpleOneLineWithComments() throws Exception {
83 var s = initStore("A.cfg",
84 "#comment",
85 "foo=bar"
86 );
87 var cm = s.getMap("A.cfg");
88
89 assertEquals("#comment|foo=bar|", pipedLines(cm));
90
91 assertEquals("", join(cm.getPreLines(""), '|'));
92 assertEquals("#comment", join(cm.getEntry("", "foo").getPreLines(), '|'));
93
94 assertEquals("bar", cm.getEntry("", "foo").getValue());
95
96
97 s.update("A.cfg", cm.toString());
98 cm = s.getMap("A.cfg");
99 assertEquals("#comment|foo=bar|", pipedLines(cm));
100 }
101
102
103
104
105 @Test void a05_simpleSection() throws Exception {
106 var s = initStore("A.cfg",
107 "[MySection]",
108 "foo=bar"
109 );
110 var cm = s.getMap("A.cfg");
111
112 assertEquals("[MySection]|foo=bar|", pipedLines(cm));
113
114 assertEquals("", join(cm.getPreLines(""), '|'));
115 assertEquals("", join(cm.getPreLines("MySection"), '|'));
116 assertEquals("", join(cm.getEntry("MySection", "foo").getPreLines(), '|'));
117
118 assertEquals("bar", cm.getEntry("MySection", "foo").getValue());
119
120
121 s.update("A.cfg", cm.toString());
122 cm = s.getMap("A.cfg");
123 assertEquals("[MySection]|foo=bar|", pipedLines(cm));
124 }
125
126
127
128
129 @Test void a06_nonExistentValues() throws Exception {
130 var s = initStore("A.cfg",
131 "[MySection]",
132 "foo=bar"
133 );
134 var cm = s.getMap("A.cfg");
135
136 assertEquals("[MySection]|foo=bar|", pipedLines(cm));
137
138 assertEquals("", join(cm.getPreLines(""), '|'));
139
140 assertNull(cm.getPreLines("XXX"));
141
142 assertNull(cm.getEntry("XXX", "yyy"));
143 assertNull(cm.getEntry("MySection", "yyy"));
144 }
145
146
147
148
149 @Test void a07_simpleSectionWithComments() throws Exception {
150 var s = initStore("A.cfg",
151 "#S1",
152 "[S1]",
153 "#k1",
154 "k1=v1",
155 "#S2",
156 "[S2]",
157 "#k2",
158 "k2=v2"
159 );
160 var cm = s.getMap("A.cfg");
161 assertEquals("#S1|[S1]|#k1|k1=v1|#S2|[S2]|#k2|k2=v2|", pipedLines(cm));
162
163 assertEquals("", join(cm.getPreLines(""), '|'));
164 assertEquals("#S1", join(cm.getPreLines("S1"), '|'));
165 assertEquals("#k1", join(cm.getEntry("S1", "k1").getPreLines(), '|'));
166 assertEquals("#S2", join(cm.getPreLines("S2"), '|'));
167 assertEquals("#k2", join(cm.getEntry("S2", "k2").getPreLines(), '|'));
168
169 assertEquals("v1", cm.getEntry("S1", "k1").getValue());
170 assertEquals("v2", cm.getEntry("S2", "k2").getValue());
171
172
173 s.update("A.cfg", cm.toString());
174 cm = s.getMap("A.cfg");
175 assertEquals("#S1|[S1]|#k1|k1=v1|#S2|[S2]|#k2|k2=v2|", pipedLines(cm));
176 }
177
178
179
180
181 @Test void a08_simpleAndDefaultSectionsWithComments() throws Exception {
182 var s = initStore("A.cfg",
183 "#D",
184 "",
185 "#k",
186 "k=v",
187 "#S1",
188 "[S1]",
189 "#k1",
190 "k1=v1"
191 );
192 var cm = s.getMap("A.cfg");
193 assertEquals("#D||#k|k=v|#S1|[S1]|#k1|k1=v1|", pipedLines(cm));
194
195 assertEquals("#D", join(cm.getPreLines(""), '|'));
196 assertEquals("#k", join(cm.getEntry("", "k").getPreLines(), '|'));
197 assertEquals("#S1", join(cm.getPreLines("S1"), '|'));
198 assertEquals("#k1", join(cm.getEntry("S1", "k1").getPreLines(), '|'));
199
200 assertEquals("v", cm.getEntry("", "k").getValue());
201 assertEquals("v1", cm.getEntry("S1", "k1").getValue());
202
203
204 s.update("A.cfg", cm.toString());
205 cm = s.getMap("A.cfg");
206 assertEquals("#D||#k|k=v|#S1|[S1]|#k1|k1=v1|", pipedLines(cm));
207 }
208
209
210
211
212 @Test void a09_simpleAndDefaultSectionsWithCommentsAndExtraSpaces() throws Exception {
213 var s = initStore("A.cfg",
214 "#Da",
215 "#Db",
216 "",
217 "#ka",
218 "",
219 "#kb",
220 "",
221 "k=v",
222 "",
223 "#S1a",
224 "",
225 "#S1b",
226 "",
227 "[S1]",
228 "",
229 "#k1a",
230 "",
231 "#k1b",
232 "",
233 "k1=v1"
234 );
235 var cm = s.getMap("A.cfg");
236 assertEquals("#Da|#Db||#ka||#kb||k=v||#S1a||#S1b||[S1]||#k1a||#k1b||k1=v1|", pipedLines(cm));
237
238 assertEquals("#Da|#Db", join(cm.getPreLines(""), '|'));
239 assertEquals("#ka||#kb|", join(cm.getEntry("", "k").getPreLines(), '|'));
240 assertEquals("|#S1a||#S1b|", join(cm.getPreLines("S1"), '|'));
241 assertEquals("|#k1a||#k1b|", join(cm.getEntry("S1", "k1").getPreLines(), '|'));
242
243 assertEquals("v", cm.getEntry("", "k").getValue());
244 assertEquals("v1", cm.getEntry("S1", "k1").getValue());
245
246
247 s.update("A.cfg", cm.toString());
248 cm = s.getMap("A.cfg");
249 assertEquals("#Da|#Db||#ka||#kb||k=v||#S1a||#S1b||[S1]||#k1a||#k1b||k1=v1|", pipedLines(cm));
250 }
251
252
253
254
255 @Test void a10_malformedSectionHeaders() {
256
257 var test = a(
258 "[]", "[ ]",
259 "[/]", "[[]", "[]]", "[\\]",
260 "[foo/bar]", "[foo[bar]", "[foo]bar]", "[foo\\bar]",
261 "[]", "[ ]", "[\t]"
262 );
263
264 for (var t : test) {
265 var s = initStore("A.cfg", t);
266 assertThrowsWithMessage(Exception.class, "Invalid section name", ()->s.getMap("A.cfg"));
267 }
268 }
269
270 @Test void a01_duplicateSectionNames() {
271 var s = initStore("A.cfg", "[S1]", "[S1]");
272 assertThrowsWithMessage(ConfigException.class, "Duplicate section found in configuration: [S1]", ()->s.getMap("A.cfg"));
273 }
274
275 @Test void a02_duplicateEntryNames() {
276 var s = initStore("A.cfg", "[S1]", "foo=v1", "foo=v2");
277 assertThrowsWithMessage(ConfigException.class, "Duplicate entry found in section [S1] of configuration: foo", ()->s.getMap("A.cfg"));
278 }
279
280
281
282
283 @Test void a03_multipleLines() throws Exception {
284 var s = initStore("A.cfg",
285 "k1 = v1a,",
286 "\tv1b,",
287 "\tv1c",
288 "k2 = v2a,",
289 "\tv2b,",
290 "\tv2c"
291 );
292 var cm = s.getMap("A.cfg");
293
294 assertEquals("", join(cm.getEntry("", "k1").getPreLines(), '|'));
295 assertEquals("", join(cm.getEntry("", "k2").getPreLines(), '|'));
296
297 assertEquals("k1 = v1a,|\tv1b,|\tv1c|k2 = v2a,|\tv2b,|\tv2c|", pipedLines(cm));
298
299 assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("", "k1").getValue());
300 assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("", "k2").getValue());
301
302
303 s.update("A.cfg", cm.toString());
304 cm = s.getMap("A.cfg");
305 assertEquals("k1 = v1a,|\tv1b,|\tv1c|k2 = v2a,|\tv2b,|\tv2c|", pipedLines(cm));
306 }
307
308 @Test void a04_multipleLinesWithSpacesAndComments() throws Exception {
309 var s = initStore("A.cfg",
310 "",
311 "#k1",
312 "",
313 "k1 = v1a,",
314 "\tv1b,",
315 "\tv1c",
316 "",
317 "#k2",
318 "",
319 "k2 = v2a,",
320 "\tv2b,",
321 "\tv2c"
322 );
323 var cm = s.getMap("A.cfg");
324
325 assertEquals("|#k1|", join(cm.getEntry("", "k1").getPreLines(), '|'));
326 assertEquals("|#k2|", join(cm.getEntry("", "k2").getPreLines(), '|'));
327
328 assertEquals("|#k1||k1 = v1a,| v1b,| v1c||#k2||k2 = v2a,| v2b,| v2c|", pipedLines(cm));
329
330 assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("", "k1").getValue());
331 assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("", "k2").getValue());
332
333
334 s.update("A.cfg", cm.toString());
335 cm = s.getMap("A.cfg");
336 assertEquals("|#k1||k1 = v1a,| v1b,| v1c||#k2||k2 = v2a,| v2b,| v2c|", pipedLines(cm));
337 }
338
339 @Test void a05_multipleLinesInSection() throws Exception {
340 var s = initStore("A.cfg",
341 "[S1]",
342 "k1 = v1a,",
343 "\tv1b,",
344 "\tv1c",
345 "k2 = v2a,",
346 "\tv2b,",
347 "\tv2c"
348 );
349 var cm = s.getMap("A.cfg");
350
351 assertEquals("", join(cm.getEntry("S1", "k1").getPreLines(), '|'));
352 assertEquals("", join(cm.getEntry("S1", "k2").getPreLines(), '|'));
353
354 assertEquals("[S1]|k1 = v1a,|\tv1b,|\tv1c|k2 = v2a,|\tv2b,|\tv2c|", pipedLines(cm));
355
356 assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("S1", "k1").getValue());
357 assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("S1", "k2").getValue());
358
359
360 s.update("A.cfg", cm.toString());
361 cm = s.getMap("A.cfg");
362 assertEquals("[S1]|k1 = v1a,|\tv1b,|\tv1c|k2 = v2a,|\tv2b,|\tv2c|", pipedLines(cm));
363 }
364
365 @Test void a06_multipleLinesInSectionWithSpacesAndPrelines() throws Exception {
366 var s = initStore("A.cfg",
367 "",
368 "#S1",
369 "",
370 "[S1]",
371 "",
372 "#k1",
373 "",
374 "k1 = v1a,",
375 "\tv1b,",
376 "\tv1c",
377 "",
378 "#k2",
379 "",
380 "k2 = v2a,",
381 "\tv2b,",
382 "\tv2c"
383 );
384 var cm = s.getMap("A.cfg");
385
386 assertEquals("|#S1|", join(cm.getPreLines("S1"), '|'));
387 assertEquals("|#k1|", join(cm.getEntry("S1", "k1").getPreLines(), '|'));
388 assertEquals("|#k2|", join(cm.getEntry("S1", "k2").getPreLines(), '|'));
389
390 assertEquals("|#S1||[S1]||#k1||k1 = v1a,| v1b,| v1c||#k2||k2 = v2a,| v2b,| v2c|", pipedLines(cm));
391
392 assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("S1", "k1").getValue());
393 assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("S1", "k2").getValue());
394
395
396 s.update("A.cfg", cm.toString());
397 cm = s.getMap("A.cfg");
398 assertEquals("|#S1||[S1]||#k1||k1 = v1a,| v1b,| v1c||#k2||k2 = v2a,| v2b,| v2c|", pipedLines(cm));
399 }
400
401
402
403
404 @Test void a07_entriesWithComments() throws Exception {
405 var s = initStore("A.cfg",
406 "[S1]",
407 "k1 = foo # comment"
408 );
409 var cm = s.getMap("A.cfg");
410
411 assertEquals("[S1]|k1 = foo # comment|", pipedLines(cm));
412 assertEquals("foo", cm.getEntry("S1", "k1").getValue());
413 assertEquals("comment", cm.getEntry("S1", "k1").getComment());
414
415 cm.setEntry("S1", "k1", null, null, "newcomment", null);
416 assertEquals("[S1]|k1 = foo # newcomment|", pipedLines(cm));
417 assertEquals("foo", cm.getEntry("S1", "k1").getValue());
418 assertEquals("newcomment", cm.getEntry("S1", "k1").getComment());
419
420 cm.setEntry("S1", "k1", null, null, "", null);
421 assertEquals("[S1]|k1 = foo|", pipedLines(cm));
422 assertEquals("foo", cm.getEntry("S1", "k1").getValue());
423 assertEquals("", cm.getEntry("S1", "k1").getComment());
424
425 cm.setEntry("S1", "k1", null, null, null, null);
426 assertEquals("[S1]|k1 = foo|", pipedLines(cm));
427 assertEquals("foo", cm.getEntry("S1", "k1").getValue());
428 assertEquals("", cm.getEntry("S1", "k1").getComment());
429 }
430
431 @Test void a08_entriesWithOddComments() throws Exception {
432 var s = initStore("A.cfg",
433 "[S1]",
434 "k1 = foo#",
435 "k2 = foo # "
436 );
437 var cm = s.getMap("A.cfg");
438 assertEquals("[S1]|k1 = foo#|k2 = foo # |", pipedLines(cm));
439 assertEquals("", cm.getEntry("S1", "k1").getComment());
440 assertEquals("", cm.getEntry("S1", "k2").getComment());
441 }
442
443 @Test void a09_entriesWithEscapedComments() throws Exception {
444 var s = initStore("A.cfg",
445 "[S1]",
446 "k1 = foo\\#bar",
447 "k2 = foo \\# bar",
448 "k3 = foo \\# bar # real-comment"
449 );
450 var cm = s.getMap("A.cfg");
451 assertEquals("[S1]|k1 = foo\\#bar|k2 = foo \\# bar|k3 = foo \\# bar # real-comment|", pipedLines(cm));
452
453 assertEquals(null, cm.getEntry("S1", "k1").getComment());
454 assertEquals(null, cm.getEntry("S1", "k2").getComment());
455 assertEquals("real-comment", cm.getEntry("S1", "k3").getComment());
456 }
457
458
459
460
461 @Test void a10_settingEntries() throws Exception {
462 var s = initStore("A.cfg",
463 "[S1]",
464 "k1 = v1a",
465 "k2 = v2a"
466 );
467 var cm = s.getMap("A.cfg");
468
469 cm.setEntry("S1", "k1", "v1b", null, null, null);
470 cm.setEntry("S1", "k2", null, null, null, null);
471 cm.setEntry("S1", "k3", "v3b", null, null, null);
472
473 assertEquals("[S1]|k1 = v1b|k2 = v2a|k3 = v3b|", pipedLines(cm));
474
475 cm.commit();
476 assertEquals("[S1]|k1 = v1b|k2 = v2a|k3 = v3b|", pipedLines(cm));
477
478
479 cm = s.getMap("A.cfg");
480 assertEquals("[S1]|k1 = v1b|k2 = v2a|k3 = v3b|", pipedLines(cm));
481 }
482
483 @Test void a11_settingEntriesWithPreLines() throws Exception {
484 var s = initStore("A.cfg",
485 "",
486 "#S1",
487 "",
488 "[S1]",
489 "",
490 "#k1",
491 "",
492 "k1 = v1a",
493 "",
494 "#k2",
495 "",
496 "k2 = v2a"
497 );
498 var cm = s.getMap("A.cfg");
499
500 cm.setEntry("S1", "k1", "v1b", null, null, null);
501 cm.setEntry("S1", "k2", null, null, null, null);
502 cm.setEntry("S1", "k3", "v3b", null, null, null);
503 cm.setEntry("S1", "k4", "v4b", null, null, l("","#k4",""));
504
505 assertEquals("|#S1||[S1]||#k1||k1 = v1b||#k2||k2 = v2a|k3 = v3b||#k4||k4 = v4b|", pipedLines(cm));
506
507 cm.commit();
508 assertEquals("|#S1||[S1]||#k1||k1 = v1b||#k2||k2 = v2a|k3 = v3b||#k4||k4 = v4b|", pipedLines(s.read("A.cfg")));
509
510
511 cm = s.getMap("A.cfg");
512 assertEquals("|#S1||[S1]||#k1||k1 = v1b||#k2||k2 = v2a|k3 = v3b||#k4||k4 = v4b|", pipedLines(cm));
513 }
514
515 @Test void a12_settingEntriesWithNewlines() throws Exception {
516 var s = initStore("A.cfg");
517 var cm = s.getMap("A.cfg");
518
519 cm.setEntry("", "k", "v1\nv2\nv3", null, null, null);
520 cm.setEntry("S1", "k1", "v1\nv2\nv3", null, null, null);
521
522 assertEquals("k = v1| v2| v3|[S1]|k1 = v1| v2| v3|", pipedLines(cm));
523
524 assertEquals("v1\nv2\nv3", cm.getEntry("", "k").getValue());
525 assertEquals("v1\nv2\nv3", cm.getEntry("S1", "k1").getValue());
526 cm.commit();
527 assertEquals("k = v1| v2| v3|[S1]|k1 = v1| v2| v3|", pipedLines(cm));
528
529
530 cm = s.getMap("A.cfg");
531 assertEquals("k = v1| v2| v3|[S1]|k1 = v1| v2| v3|", pipedLines(cm));
532 }
533
534 @Test void a13_settingEntriesWithNewlinesAndSpaces() throws Exception {
535 var s = initStore("A.cfg");
536 var cm = s.getMap("A.cfg");
537
538 cm.setEntry("", "k", "v1 \n v2 \n v3", null, null, null);
539 cm.setEntry("S1", "k1", "v1\t\n\tv2\t\n\tv3", null, null, null);
540
541 assertEquals("k = v1 | v2 | v3|[S1]|k1 = v1 | v2 | v3|", pipedLines(cm));
542
543 assertEquals("v1 \n v2 \n v3", cm.getEntry("", "k").getValue());
544 assertEquals("v1\t\n\tv2\t\n\tv3", cm.getEntry("S1", "k1").getValue());
545 cm.commit();
546 assertEquals("k = v1 | v2 | v3|[S1]|k1 = v1 | v2 | v3|", pipedLines(cm));
547
548
549 cm = s.getMap("A.cfg");
550 assertEquals("k = v1 | v2 | v3|[S1]|k1 = v1 | v2 | v3|", pipedLines(cm));
551 }
552
553
554
555
556 @Test void a14_setSectionOnExistingSection() throws Exception {
557 var s = initStore("A.cfg",
558 "[S1]",
559 "k1 = v1"
560 );
561 var cm = s.getMap("A.cfg");
562
563 cm.setSection("S1", l("#S1"));
564 assertEquals("#S1|[S1]|k1 = v1|", pipedLines(cm));
565 cm.setSection("S1", Collections.<String>emptyList());
566 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
567 cm.setSection("S1", null);
568 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
569 }
570
571 @Test void a15_setSectionOnDefaultSection() throws Exception {
572 var s = initStore("A.cfg",
573 "[S1]",
574 "k1 = v1"
575 );
576 var cm = s.getMap("A.cfg");
577
578 cm.setSection("", l("#D"));
579 assertEquals("#D||[S1]|k1 = v1|", pipedLines(cm));
580 cm.setSection("", Collections.<String>emptyList());
581 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
582 cm.setSection("", null);
583 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
584 }
585
586 @Test void a16_setSectionOnNewSection() throws Exception {
587 var s = initStore("A.cfg",
588 "[S1]",
589 "k1 = v1"
590 );
591 var cm = s.getMap("A.cfg");
592
593 cm.setSection("S2", l("#S2"));
594 assertEquals("[S1]|k1 = v1|#S2|[S2]|", pipedLines(cm));
595 cm.setSection("S3", Collections.<String>emptyList());
596 assertEquals("[S1]|k1 = v1|#S2|[S2]|[S3]|", pipedLines(cm));
597 cm.setSection("S4", null);
598 assertEquals("[S1]|k1 = v1|#S2|[S2]|[S3]|[S4]|", pipedLines(cm));
599 }
600
601 @Test void a17_setSectionBadNames() throws Exception {
602 var s = initStore("A.cfg");
603 var cm = s.getMap("A.cfg");
604
605 var test = a(
606 "/", "[", "]",
607 "foo/bar", "foo[bar", "foo]bar",
608 " ",
609 null
610 );
611
612 for (var t : test) {
613 assertThrowsWithMessage(Exception.class, "Invalid section name", ()->cm.setSection(t, null));
614 }
615 }
616
617 @Test void a18_setSectionOkNames() throws Exception {
618 var s = initStore("A.cfg");
619 var cm = s.getMap("A.cfg");
620
621
622 String validChars = "~`!@#$%^&*()_-+={}|:;\"\'<,>.?";
623
624 for (var c : validChars.toCharArray()) {
625 var test = ""+c;
626 cm.setSection(test, l("test"));
627 cm.commit();
628 assertEquals("test", cm.getPreLines(test).get(0));
629
630 test = "foo"+c+"bar";
631 cm.setSection(test, l("test"));
632 cm.commit();
633 assertEquals("test", cm.getPreLines(test).get(0));
634 }
635 }
636
637
638
639
640 @Test void a19_removeSectionOnExistingSection() throws Exception {
641 var s = initStore("A.cfg",
642 "[S1]",
643 "k1 = v1",
644 "[S2]",
645 "k2 = v2"
646
647 );
648 var cm = s.getMap("A.cfg");
649
650 cm.removeSection("S1");
651 assertEquals("[S2]|k2 = v2|", pipedLines(cm));
652 }
653
654 @Test void a20_removeSectionOnNonExistingSection() throws Exception {
655 var s = initStore("A.cfg",
656 "[S1]",
657 "k1 = v1",
658 "[S2]",
659 "k2 = v2"
660
661 );
662 var cm = s.getMap("A.cfg");
663
664 cm.removeSection("S3");
665 assertEquals("[S1]|k1 = v1|[S2]|k2 = v2|", pipedLines(cm));
666
667 assertThrowsWithMessage(IllegalArgumentException.class, "Invalid section name: 'null'", ()->cm.removeSection(null));
668 }
669
670 @Test void a21_removeDefaultSection() throws Exception {
671 var s = initStore("A.cfg",
672 "k = v",
673 "[S1]",
674 "k1 = v1",
675 "[S2]",
676 "k2 = v2"
677
678 );
679 var cm = s.getMap("A.cfg");
680
681 cm.removeSection("");
682 assertEquals("[S1]|k1 = v1|[S2]|k2 = v2|", pipedLines(cm));
683 }
684
685 @Test void a22_removeDefaultSectionWithComments() throws Exception {
686 var s = initStore("A.cfg",
687 "#D",
688 "",
689 "#k",
690 "k = v",
691 "[S1]",
692 "k1 = v1",
693 "[S2]",
694 "k2 = v2"
695
696 );
697 var cm = s.getMap("A.cfg");
698
699 cm.removeSection("");
700 assertEquals("[S1]|k1 = v1|[S2]|k2 = v2|", pipedLines(cm));
701 }
702
703
704
705
706 @Test void a23_setPrelinesOnExistingEntry() throws Exception {
707 var s = initStore("A.cfg",
708 "[S1]",
709 "k1 = v1"
710 );
711 var cm = s.getMap("A.cfg");
712
713 cm.setEntry("S1", "k1", null, null, null, l("#k1"));
714 assertEquals("[S1]|#k1|k1 = v1|", pipedLines(cm));
715 cm.setEntry("S1", "k1", null, null, null, Collections.<String>emptyList());
716 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
717 cm.setEntry("S1", "k1", null, null, null, null);
718 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
719 }
720
721 @Test void a24_setPrelinesOnExistingEntryWithAtrributes() throws Exception {
722 var s = initStore("A.cfg",
723 "[S1]",
724 "#k1a",
725 "k1 = v1 # comment"
726 );
727 var cm = s.getMap("A.cfg");
728
729 cm.setEntry("S1", "k1", null, null, null, l("#k1b"));
730 assertEquals("[S1]|#k1b|k1 = v1 # comment|", pipedLines(cm));
731 }
732
733 @Test void a25_setPrelinesOnNonExistingEntry() throws Exception {
734 var s = initStore("A.cfg",
735 "[S1]",
736 "k1 = v1"
737 );
738 var cm = s.getMap("A.cfg");
739
740 cm.setEntry("S1", "k2", null, null, null, l("#k2"));
741 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
742 cm.setEntry("S1", "k2", null, null, null, Collections.<String>emptyList());
743 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
744 cm.setEntry("S1", "k2", null, null, null, null);
745 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
746
747 cm.setEntry("S2", "k2", null, null, null, l("#k2"));
748 assertEquals("[S1]|k1 = v1|[S2]|", pipedLines(cm));
749 cm.setEntry("S2", "k2", null, null, null, Collections.<String>emptyList());
750 assertEquals("[S1]|k1 = v1|[S2]|", pipedLines(cm));
751 cm.setEntry("S2", "k2", null, null, null, null);
752 assertEquals("[S1]|k1 = v1|[S2]|", pipedLines(cm));
753 }
754
755
756
757
758 @Test void a26_setValueOnExistingEntry() throws Exception {
759 var s = initStore("A.cfg",
760 "[S1]",
761 "k1 = v1"
762 );
763 var cm = s.getMap("A.cfg");
764
765 cm.setEntry("S1", "k1", "v2", null, null, null);
766 assertEquals("[S1]|k1 = v2|", pipedLines(cm));
767 }
768
769 @Test void a27_setValueOnExistingEntryWithAttributes() throws Exception {
770 var s = initStore("A.cfg",
771 "[S1]",
772 "#k1",
773 "k1 = v1 # comment"
774 );
775 var cm = s.getMap("A.cfg");
776
777 cm.setEntry("S1", "k1", "v2", null, null, null);
778 assertEquals("[S1]|#k1|k1 = v2 # comment|", pipedLines(cm));
779 }
780
781 @Test void a28_setValueToNullOnExistingEntry() throws Exception {
782 var s = initStore("A.cfg",
783 "[S1]",
784 "k1 = v1"
785 );
786 var cm = s.getMap("A.cfg");
787
788 cm.setEntry("S1", "k1", null, null, null, null);
789 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
790 }
791
792 @Test void a29_setValueOnNonExistingEntry() throws Exception {
793 var s = initStore("A.cfg",
794 "[S1]",
795 "k1 = v1"
796 );
797 var cm = s.getMap("A.cfg");
798
799 cm.setEntry("S1", "k2", "v2", null, null, null);
800 assertEquals("[S1]|k1 = v1|k2 = v2|", pipedLines(cm));
801 cm.setEntry("S1", "k2", null, null, null, null);
802 assertEquals("[S1]|k1 = v1|k2 = v2|", pipedLines(cm));
803 cm.setEntry("S1", "k2", null, null, null, null);
804 assertEquals("[S1]|k1 = v1|k2 = v2|", pipedLines(cm));
805 }
806
807 @Test void a30_setValueOnNonExistingEntryOnNonExistentSection() throws Exception {
808 var s = initStore("A.cfg",
809 "[S1]",
810 "k1 = v1"
811 );
812 var cm = s.getMap("A.cfg");
813
814 cm.setEntry("S2", "k2", "v2", null, null, null);
815 assertEquals("[S1]|k1 = v1|[S2]|k2 = v2|", pipedLines(cm));
816 }
817
818 @Test void a31_setValueInvalidSectionNames() throws Exception {
819 var s = initStore("A.cfg");
820 var cm = s.getMap("A.cfg");
821
822 var test = a(
823 "/", "[", "]",
824 "foo/bar", "foo[bar", "foo]bar",
825 " ",
826 null
827 );
828
829 for (var t : test) {
830 assertThrowsWithMessage(Exception.class, "Invalid section name:", ()->cm.setEntry(t, "k1", "foo", null, null, null));
831 }
832 }
833
834 @Test void a32_setValueInvalidKeyNames() throws Exception {
835 var s = initStore("A.cfg");
836 var cm = s.getMap("A.cfg");
837
838 var test = a(
839 "", " ", "\t",
840 "foo=bar", "=",
841 "foo/bar", "/",
842 "foo[bar", "]",
843 "foo]bar", "]",
844 "foo\\bar", "\\",
845 "foo#bar", "#",
846 null
847 );
848
849 for (var t : test) {
850 assertThrowsWithMessage(Exception.class, "Invalid key name", ()->cm.setEntry("S1", t, "foo", null, null, null));
851 }
852 }
853
854 @Test void a33_setValueWithCommentChars() throws Exception {
855 var s = initStore("A.cfg",
856 "[S1]",
857 "k1 = v1"
858 );
859 var cm = s.getMap("A.cfg");
860
861
862 cm.setEntry("S1", "k1", "v1 # foo", null, null, null);
863 assertEquals("[S1]|k1 = v1 \\u0023 foo|", pipedLines(cm));
864 }
865
866
867
868
869 @Test void a34_setCommentOnExistingEntry() throws Exception {
870 var s = initStore("A.cfg",
871 "[S1]",
872 "k1 = v1"
873 );
874 var cm = s.getMap("A.cfg");
875
876 cm.setEntry("S1", "k1", null, null, "c1", null);
877 assertEquals("[S1]|k1 = v1 # c1|", pipedLines(cm));
878
879 cm.setEntry("S1", "k1", null, null, "", null);
880 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
881 cm.commit();
882 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
883
884 cm.setEntry("S1", "k1", null, null, null, null);
885 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
886 }
887
888 @Test void a35_setCommentOnExistingEntryWithAttributes() throws Exception {
889 var s = initStore("A.cfg",
890 "[S1]",
891 "#k1a",
892 "k1 = v1 # c1"
893 );
894 var cm = s.getMap("A.cfg");
895
896 cm.setEntry("S1", "k1", null, null, "c2", null);
897 assertEquals("[S1]|#k1a|k1 = v1 # c2|", pipedLines(cm));
898 }
899
900 @Test void a36_setCommentOnNonExistingEntry() throws Exception {
901 var s = initStore("A.cfg",
902 "[S1]",
903 "k1 = v1"
904 );
905 var cm = s.getMap("A.cfg");
906
907 cm.setEntry("S1", "k2", null, null, "foo", null);
908 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
909 cm.setEntry("S1", "k2", null, null, null, null);
910 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
911
912 cm.setEntry("S2", "k2", null, null, "foo", null);
913 assertEquals("[S1]|k1 = v1|[S2]|", pipedLines(cm));
914 cm.setEntry("S2", "k2", null, null, null, null);
915 assertEquals("[S1]|k1 = v1|[S2]|", pipedLines(cm));
916 }
917
918
919
920
921 @Test void a37_setEntryOnExistingEntry() throws Exception {
922 var s = initStore("A.cfg",
923 "[S1]",
924 "k1 = v1"
925 );
926 var cm = s.getMap("A.cfg");
927
928 cm.setEntry("S1", "k1", "v2", null, null, null);
929 assertEquals("[S1]|k1 = v2|", pipedLines(cm));
930
931 cm.setEntry("S1", "k1", "v3", ENCODED, "c3", l("#k1a"));
932 assertEquals("[S1]|#k1a|k1<*> = v3 # c3|", pipedLines(cm));
933
934 cm.setEntry("S1", "k1", "v4", BASE64, "c4", l("#k1b"));
935 assertEquals("[S1]|#k1b|k1<^> = v4 # c4|", pipedLines(cm));
936 }
937
938 @Test void a38_setEntryOnExistingEntryWithAttributes() throws Exception {
939 var s = initStore("A.cfg",
940 "[S1]",
941 "#k1",
942 "k1 = v1 # comment"
943 );
944 var cm = s.getMap("A.cfg");
945
946 cm.setEntry("S1", "k1", "v2", null, null, null);
947 assertEquals("[S1]|#k1|k1 = v2 # comment|", pipedLines(cm));
948
949 cm.setEntry("S1", "k1", "v3", ENCODED, "c3", l("#k1a"));
950 assertEquals("[S1]|#k1a|k1<*> = v3 # c3|", pipedLines(cm));
951
952 cm.setEntry("S1", "k1", "v4", BASE64, "c4", l("#k1b"));
953 assertEquals("[S1]|#k1b|k1<^> = v4 # c4|", pipedLines(cm));
954 }
955
956 @Test void a39_setEntryToNullOnExistingEntry() throws Exception {
957 var s = initStore("A.cfg",
958 "[S1]",
959 "k1 = v1"
960 );
961 var cm = s.getMap("A.cfg");
962
963 cm.setEntry("S1", "k1", null, null, null, null);
964 assertEquals("[S1]|k1 = v1|", pipedLines(cm));
965 }
966
967 @Test void a40_setEntryOnNonExistingEntry() throws Exception {
968 var s = initStore("A.cfg",
969 "[S1]",
970 "k1 = v1"
971 );
972 var cm = s.getMap("A.cfg");
973
974 cm.setEntry("S1", "k2", "v2", null, null, null);
975 assertEquals("[S1]|k1 = v1|k2 = v2|", pipedLines(cm));
976 cm.setEntry("S1", "k2", null, null, null, null);
977 assertEquals("[S1]|k1 = v1|k2 = v2|", pipedLines(cm));
978 cm.setEntry("S1", "k2", "", null, null, null);
979 assertEquals("[S1]|k1 = v1|k2 = |", pipedLines(cm));
980 }
981
982 @Test void a41_setEntryOnNonExistingEntryOnNonExistentSection() throws Exception {
983 var s = initStore("A.cfg",
984 "[S1]",
985 "k1 = v1"
986 );
987 var cm = s.getMap("A.cfg");
988
989 cm.setEntry("S2", "k2", "v2", null, null, null);
990 assertEquals("[S1]|k1 = v1|[S2]|k2 = v2|", pipedLines(cm));
991 }
992
993 @Test void a42_setEntryInvalidSectionNames() throws Exception {
994 var s = initStore("A.cfg");
995 var cm = s.getMap("A.cfg");
996
997 var test = a(
998 "/", "[", "]",
999 "foo/bar", "foo[bar", "foo]bar",
1000 " ",
1001 null
1002 );
1003
1004 for (var t : test) {
1005 assertThrowsWithMessage(Exception.class, "Invalid section name", ()->cm.setEntry(t, "k1", "foo", null, null, null));
1006 }
1007 }
1008
1009 @Test void a43_setEntryInvalidKeyNames() throws Exception {
1010 var s = initStore("A.cfg");
1011 var cm = s.getMap("A.cfg");
1012
1013 var test = a(
1014 "", " ", "\t",
1015 "foo=bar", "=",
1016 "foo/bar", "/",
1017 "foo[bar", "]",
1018 "foo]bar", "]",
1019 "foo\\bar", "\\",
1020 "foo#bar", "#",
1021 null
1022 );
1023
1024 for (var t : test) {
1025 assertThrowsWithMessage(Exception.class, "Invalid key name", ()->cm.setEntry("S1", t, "foo", null, null, null));
1026 }
1027 }
1028
1029 @Test void a44_setEntryWithCommentChars() throws Exception {
1030 var s = initStore("A.cfg",
1031 "[S1]",
1032 "k1 = v1"
1033 );
1034 var cm = s.getMap("A.cfg");
1035
1036
1037 cm.setEntry("S1", "k1", "v1 # foo", null, null, null);
1038 assertEquals("[S1]|k1 = v1 \\u0023 foo|", pipedLines(cm));
1039 }
1040
1041
1042
1043
1044 @Test void a45_modifiers() throws Exception {
1045 var s = initStore("A.cfg",
1046 "[S1]",
1047 "k1<^> = v1",
1048 "k2<*> = v2",
1049 "k3<*^> = v3"
1050 );
1051 var cm = s.getMap("A.cfg");
1052
1053 assertEquals("[S1]|k1<^> = v1|k2<*> = v2|k3<*^> = v3|", pipedLines(cm));
1054 assertEquals("^", cm.getEntry("S1", "k1").getModifiers());
1055 assertEquals("*", cm.getEntry("S1", "k2").getModifiers());
1056 assertEquals("*^", cm.getEntry("S1", "k3").getModifiers());
1057
1058 cm.setEntry("S1", "k1", "v1", "#$%&*+^@~", null, null);
1059 assertEquals("[S1]|k1<#$%&*+^@~> = v1|k2<*> = v2|k3<*^> = v3|", pipedLines(cm));
1060 }
1061
1062 @Test void a46_invalidModifier() throws Exception {
1063 var s = initStore("A.cfg",
1064 "[S1]",
1065 "k1^ = v1",
1066 "k2* = v2",
1067 "k3*^ = v3"
1068 );
1069 var cm = s.getMap("A.cfg");
1070
1071
1072 assertDoesNotThrow(()->cm.setEntry("S1", "k1", "v1", "", null, null));
1073 }
1074
1075 private static ConfigStore initStore(String name, String...contents) {
1076 return MemoryStore.create().build().update(name, contents);
1077 }
1078 }