1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.settings;
18
19 import static org.apache.juneau.commons.utils.Utils.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.io.File;
23 import java.net.URI;
24 import java.nio.charset.Charset;
25 import java.nio.file.Paths;
26 import java.util.concurrent.atomic.AtomicInteger;
27
28 import org.apache.juneau.*;
29 import org.apache.juneau.commons.function.*;
30 import org.junit.jupiter.api.*;
31
32 class Settings_Test extends TestBase {
33
34 private static final String TEST_PROP = "juneau.test.property";
35 private static final String TEST_PROP_2 = "juneau.test.property2";
36
37 @BeforeEach
38 void setUp() {
39
40 Settings.get().clearLocal();
41 Settings.get().clearGlobal();
42
43 System.clearProperty(TEST_PROP);
44 System.clearProperty(TEST_PROP_2);
45 }
46
47 @AfterEach
48 void tearDown() {
49
50 Settings.get().clearLocal();
51 Settings.get().clearGlobal();
52 System.clearProperty(TEST_PROP);
53 System.clearProperty(TEST_PROP_2);
54 }
55
56
57
58
59 @Test
60 void a01_get_fromSystemProperty() {
61 System.setProperty(TEST_PROP, "system-value");
62 var result = Settings.get().get(TEST_PROP);
63 assertTrue(result.isPresent());
64 assertEquals("system-value", result.get());
65 }
66
67 @Test
68 void a02_get_notFound() {
69 var result = Settings.get().get("nonexistent.property");
70 assertFalse(result.isPresent());
71 }
72
73 @Test
74 void a03_get_fromGlobalOverride() {
75 Settings.get().setGlobal(TEST_PROP, "global-value");
76 var result = Settings.get().get(TEST_PROP);
77 assertTrue(result.isPresent());
78 assertEquals("global-value", result.get());
79 }
80
81 @Test
82 void a04_get_fromLocalOverride() {
83 Settings.get().setLocal(TEST_PROP, "local-value");
84 var result = Settings.get().get(TEST_PROP);
85 assertTrue(result.isPresent());
86 assertEquals("local-value", result.get());
87 }
88
89 @Test
90 void a05_get_lookupOrder_localOverridesGlobal() {
91 System.setProperty(TEST_PROP, "system-value");
92 Settings.get().setGlobal(TEST_PROP, "global-value");
93 Settings.get().setLocal(TEST_PROP, "local-value");
94 var result = Settings.get().get(TEST_PROP);
95 assertTrue(result.isPresent());
96 assertEquals("local-value", result.get());
97 }
98
99 @Test
100 void a06_get_lookupOrder_globalOverridesSystem() {
101 System.setProperty(TEST_PROP, "system-value");
102 Settings.get().setGlobal(TEST_PROP, "global-value");
103 var result = Settings.get().get(TEST_PROP);
104 assertTrue(result.isPresent());
105 assertEquals("global-value", result.get());
106 }
107
108 @Test
109 void a07_get_nullValue() {
110 Settings.get().setLocal(TEST_PROP, null);
111 var result = Settings.get().get(TEST_PROP);
112 assertFalse(result.isPresent());
113 }
114
115
116
117
118 @Test
119 void b01_getInteger_valid() {
120 System.setProperty(TEST_PROP, "123");
121 var result = Settings.get().get(TEST_PROP).asInteger();
122 assertTrue(result.isPresent());
123 assertEquals(123, result.get());
124 }
125
126 @Test
127 void b02_getInteger_invalid() {
128 System.setProperty(TEST_PROP, "not-a-number");
129 var result = Settings.get().get(TEST_PROP).asInteger();
130 assertFalse(result.isPresent());
131 }
132
133 @Test
134 void b03_getInteger_notFound() {
135 var result = Settings.get().get("nonexistent.property").asInteger();
136 assertFalse(result.isPresent());
137 }
138
139 @Test
140 void b04_getInteger_fromOverride() {
141 Settings.get().setLocal(TEST_PROP, "456");
142 var result = Settings.get().get(TEST_PROP).asInteger();
143 assertTrue(result.isPresent());
144 assertEquals(456, result.get());
145 }
146
147
148
149
150 @Test
151 void c01_getLong_valid() {
152 System.setProperty(TEST_PROP, "123456789");
153 var result = Settings.get().get(TEST_PROP).asLong();
154 assertTrue(result.isPresent());
155 assertEquals(123456789L, result.get());
156 }
157
158 @Test
159 void c02_getLong_invalid() {
160 System.setProperty(TEST_PROP, "not-a-number");
161 var result = Settings.get().get(TEST_PROP).asLong();
162 assertFalse(result.isPresent());
163 }
164
165 @Test
166 void c03_getLong_fromOverride() {
167 Settings.get().setLocal(TEST_PROP, "987654321");
168 var result = Settings.get().get(TEST_PROP).asLong();
169 assertTrue(result.isPresent());
170 assertEquals(987654321L, result.get());
171 }
172
173
174
175
176 @Test
177 void d01_getBoolean_true() {
178 System.setProperty(TEST_PROP, "true");
179 var result = Settings.get().get(TEST_PROP).asBoolean();
180 assertTrue(result.isPresent());
181 assertTrue(result.get());
182 }
183
184 @Test
185 void d02_getBoolean_false() {
186 System.setProperty(TEST_PROP, "false");
187 var result = Settings.get().get(TEST_PROP).asBoolean();
188 assertTrue(result.isPresent());
189 assertFalse(result.get());
190 }
191
192 @Test
193 void d03_getBoolean_caseInsensitive() {
194 System.setProperty(TEST_PROP, "TRUE");
195 var result = Settings.get().get(TEST_PROP).asBoolean();
196 assertTrue(result.isPresent());
197 assertTrue(result.get());
198 }
199
200 @Test
201 void d04_getBoolean_nonTrueValue() {
202 System.setProperty(TEST_PROP, "anything");
203 var result = Settings.get().get(TEST_PROP).asBoolean();
204 assertTrue(result.isPresent());
205 assertFalse(result.get());
206 }
207
208 @Test
209 void d05_getBoolean_notFound() {
210 var result = Settings.get().get("nonexistent.property").asBoolean();
211 assertFalse(result.isPresent());
212 }
213
214
215
216
217 @Test
218 void e01_getDouble_valid() {
219 System.setProperty(TEST_PROP, "123.456");
220 var result = Settings.get().get(TEST_PROP).asDouble();
221 assertTrue(result.isPresent());
222 assertEquals(123.456, result.get(), 0.0001);
223 }
224
225 @Test
226 void e02_getDouble_invalid() {
227 System.setProperty(TEST_PROP, "not-a-number");
228 var result = Settings.get().get(TEST_PROP).asDouble();
229 assertFalse(result.isPresent());
230 }
231
232
233
234
235 @Test
236 void f01_getFloat_valid() {
237 System.setProperty(TEST_PROP, "123.456");
238 var result = Settings.get().get(TEST_PROP).asFloat();
239 assertTrue(result.isPresent());
240 assertEquals(123.456f, result.get(), 0.0001f);
241 }
242
243 @Test
244 void f02_getFloat_invalid() {
245 System.setProperty(TEST_PROP, "not-a-number");
246 var result = Settings.get().get(TEST_PROP).asFloat();
247 assertFalse(result.isPresent());
248 }
249
250
251
252
253 @Test
254 void g01_getFile_valid() {
255 System.setProperty(TEST_PROP, "/tmp/test.txt");
256 var result = Settings.get().get(TEST_PROP).asFile();
257 assertTrue(result.isPresent());
258 assertEquals(new File("/tmp/test.txt"), result.get());
259 }
260
261 @Test
262 void g02_getFile_notFound() {
263 var result = Settings.get().get("nonexistent.property").asFile();
264 assertFalse(result.isPresent());
265 }
266
267
268
269
270 @Test
271 void h01_getPath_valid() {
272 System.setProperty(TEST_PROP, "/tmp/test.txt");
273 var result = Settings.get().get(TEST_PROP).asPath();
274 assertTrue(result.isPresent());
275 assertEquals(Paths.get("/tmp/test.txt"), result.get());
276 }
277
278 @Test
279 void h02_getPath_invalid() {
280
281
282 System.setProperty(TEST_PROP, "\0invalid");
283 var result = Settings.get().get(TEST_PROP).asPath();
284
285 assertNotNull(result);
286 }
287
288
289
290
291 @Test
292 void i01_getURI_valid() {
293 System.setProperty(TEST_PROP, "http://example.com/test");
294 var result = Settings.get().get(TEST_PROP).asURI();
295 assertTrue(result.isPresent());
296 assertEquals(URI.create("http://example.com/test"), result.get());
297 }
298
299 @Test
300 void i02_getURI_invalid() {
301 System.setProperty(TEST_PROP, "not a valid uri");
302 var result = Settings.get().get(TEST_PROP).asURI();
303 assertFalse(result.isPresent());
304 }
305
306
307
308
309 @Test
310 void j01_getCharset_valid() {
311 System.setProperty(TEST_PROP, "UTF-8");
312 var result = Settings.get().get(TEST_PROP).asCharset();
313 assertTrue(result.isPresent());
314 assertEquals(Charset.forName("UTF-8"), result.get());
315 }
316
317 @Test
318 void j02_getCharset_invalid() {
319 System.setProperty(TEST_PROP, "INVALID-CHARSET");
320 var result = Settings.get().get(TEST_PROP).asCharset();
321 assertFalse(result.isPresent());
322 }
323
324
325
326
327 @Test
328 void k01_setGlobal() {
329 Settings.get().setGlobal(TEST_PROP, "global-value");
330 var result = Settings.get().get(TEST_PROP);
331 assertTrue(result.isPresent());
332 assertEquals("global-value", result.get());
333 }
334
335 @Test
336 void k02_unsetGlobal() {
337 Settings.get().setGlobal(TEST_PROP, "global-value");
338 Settings.get().unsetGlobal(TEST_PROP);
339 var result = Settings.get().get(TEST_PROP);
340 assertFalse(result.isPresent());
341 }
342
343 @Test
344 void k03_clearGlobal() {
345 Settings.get().setGlobal(TEST_PROP, "value1");
346 Settings.get().setGlobal(TEST_PROP_2, "value2");
347 Settings.get().clearGlobal();
348 assertFalse(Settings.get().get(TEST_PROP).isPresent());
349 assertFalse(Settings.get().get(TEST_PROP_2).isPresent());
350 }
351
352 @Test
353 void k04_setGlobal_nullValue() {
354 Settings.get().setGlobal(TEST_PROP, null);
355 var result = Settings.get().get(TEST_PROP);
356 assertFalse(result.isPresent());
357 }
358
359
360
361
362 @Test
363 void l01_setLocal() {
364 Settings.get().setLocal(TEST_PROP, "local-value");
365 var result = Settings.get().get(TEST_PROP);
366 assertTrue(result.isPresent());
367 assertEquals("local-value", result.get());
368 }
369
370 @Test
371 void l02_unsetLocal() {
372 Settings.get().setLocal(TEST_PROP, "local-value");
373 Settings.get().unsetLocal(TEST_PROP);
374 var result = Settings.get().get(TEST_PROP);
375 assertFalse(result.isPresent());
376 }
377
378 @Test
379 void l07_unsetLocal_whenNoLocalSource() {
380
381 Settings.get().unsetLocal(TEST_PROP);
382
383 var result = Settings.get().get(TEST_PROP);
384 assertFalse(result.isPresent());
385 }
386
387 @Test
388 void l03_clearLocal() {
389 Settings.get().setLocal(TEST_PROP, "value1");
390 Settings.get().setLocal(TEST_PROP_2, "value2");
391 Settings.get().clearLocal();
392 assertFalse(Settings.get().get(TEST_PROP).isPresent());
393 assertFalse(Settings.get().get(TEST_PROP_2).isPresent());
394 }
395
396 @Test
397 void l04_setLocal_nullValue() {
398 Settings.get().setLocal(TEST_PROP, null);
399 var result = Settings.get().get(TEST_PROP);
400 assertFalse(result.isPresent());
401 }
402
403 @Test
404 void l05_setLocal_overridesGlobal() {
405 Settings.get().setGlobal(TEST_PROP, "global-value");
406 Settings.get().setLocal(TEST_PROP, "local-value");
407 var result = Settings.get().get(TEST_PROP);
408 assertTrue(result.isPresent());
409 assertEquals("local-value", result.get());
410 }
411
412 @Test
413 void l06_setLocal_overridesSystemProperty() {
414 System.setProperty(TEST_PROP, "system-value");
415 Settings.get().setLocal(TEST_PROP, "local-value");
416 var result = Settings.get().get(TEST_PROP);
417 assertTrue(result.isPresent());
418 assertEquals("local-value", result.get());
419 }
420
421
422
423
424 @Test
425 void m01_localOverride_threadIsolation() throws InterruptedException {
426 Settings.get().setLocal(TEST_PROP, "thread1-value");
427
428 var thread2 = new Thread(() -> {
429 Settings.get().setLocal(TEST_PROP, "thread2-value");
430 var result = Settings.get().get(TEST_PROP);
431 assertTrue(result.isPresent());
432 assertEquals("thread2-value", result.get());
433 });
434
435 thread2.start();
436 thread2.join();
437
438
439 var result = Settings.get().get(TEST_PROP);
440 assertTrue(result.isPresent());
441 assertEquals("thread1-value", result.get());
442 }
443
444 @Test
445 void m02_globalOverride_sharedAcrossThreads() throws InterruptedException {
446 Settings.get().setGlobal(TEST_PROP, "global-value");
447
448 var thread2 = new Thread(() -> {
449 var result = Settings.get().get(TEST_PROP);
450 assertTrue(result.isPresent());
451 assertEquals("global-value", result.get());
452 });
453
454 thread2.start();
455 thread2.join();
456
457
458 var result = Settings.get().get(TEST_PROP);
459 assertTrue(result.isPresent());
460 assertEquals("global-value", result.get());
461 }
462
463
464
465
466 @Test
467 void n01_get_returnsSameInstance() {
468 var instance1 = Settings.get();
469 var instance2 = Settings.get();
470 assertSame(instance1, instance2);
471 }
472
473
474
475
476 @Test
477 void o01_addSource() {
478 var source = new MapStore();
479 source.set(TEST_PROP, "source-value");
480 var settings = Settings.create()
481 .addSource(source)
482 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
483 .addSource(Settings.SYSTEM_ENV_SOURCE)
484 .build();
485
486 var result = settings.get(TEST_PROP);
487 assertTrue(result.isPresent());
488 assertEquals("source-value", result.get());
489 }
490
491 @Test
492 void o02_addSource_reverseOrder() {
493 var source1 = new MapStore();
494 source1.set(TEST_PROP, "source1-value");
495
496 var source2 = new MapStore();
497 source2.set(TEST_PROP, "source2-value");
498
499 var settings = Settings.create()
500 .addSource(source1)
501 .addSource(source2)
502 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
503 .addSource(Settings.SYSTEM_ENV_SOURCE)
504 .build();
505
506
507 var result = settings.get(TEST_PROP);
508 assertTrue(result.isPresent());
509 assertEquals("source2-value", result.get());
510 }
511
512 @Test
513 void o03_addSource_afterGlobalOverride() {
514 var settings = Settings.create()
515 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
516 .addSource(Settings.SYSTEM_ENV_SOURCE)
517 .build();
518
519 settings.setGlobal(TEST_PROP, "global-value");
520
521 var source = new MapStore();
522 source.set(TEST_PROP, "source-value");
523
524 var settingsWithSource = Settings.create()
525 .addSource(source)
526 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
527 .addSource(Settings.SYSTEM_ENV_SOURCE)
528 .build();
529 settingsWithSource.setGlobal(TEST_PROP, "global-value");
530
531
532 var result = settingsWithSource.get(TEST_PROP);
533 assertTrue(result.isPresent());
534 assertEquals("global-value", result.get());
535 }
536
537 @Test
538 void o04_addSource_beforeSystemProperty() {
539 System.setProperty(TEST_PROP, "system-value");
540
541 var source = new MapStore();
542 source.set(TEST_PROP, "source-value");
543
544 var settings = Settings.create()
545 .addSource(Settings.SYSTEM_ENV_SOURCE)
546 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
547 .addSource(source)
548 .build();
549
550
551 var result = settings.get(TEST_PROP);
552 assertTrue(result.isPresent());
553 assertEquals("source-value", result.get());
554 }
555
556 @Test
557 void o05_addSource_fallbackToSystemProperty() {
558 var source = new MapStore();
559
560
561 System.setProperty(TEST_PROP, "system-value");
562 var settings = Settings.create()
563 .addSource(source)
564 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
565 .addSource(Settings.SYSTEM_ENV_SOURCE)
566 .build();
567
568
569 var result = settings.get(TEST_PROP);
570 assertTrue(result.isPresent());
571 assertEquals("system-value", result.get());
572 }
573
574 @Test
575 void o06_setSources() {
576 var source1 = new MapStore();
577 source1.set(TEST_PROP, "source1-value");
578
579 var source2 = new MapStore();
580 source2.set(TEST_PROP, "source2-value");
581
582 var settings = Settings.create()
583 .setSources(source1, source2, Settings.SYSTEM_PROPERTY_SOURCE, Settings.SYSTEM_ENV_SOURCE)
584 .build();
585
586
587 var result = settings.get(TEST_PROP);
588 assertTrue(result.isPresent());
589 assertEquals("source2-value", result.get());
590 }
591
592 @Test
593 void o07_setSources_clearsExisting() {
594 var source1 = new MapStore();
595 source1.set(TEST_PROP, "source1-value");
596
597 var source2 = new MapStore();
598 source2.set(TEST_PROP, "source2-value");
599
600 var settings = Settings.create()
601 .addSource(source1)
602 .setSources(source2, Settings.SYSTEM_PROPERTY_SOURCE, Settings.SYSTEM_ENV_SOURCE)
603 .build();
604
605
606 var result = settings.get(TEST_PROP);
607 assertTrue(result.isPresent());
608 assertEquals("source2-value", result.get());
609 }
610
611 @Test
612 void o08_addSource_nullValue() {
613 var source = new MapStore();
614 source.set(TEST_PROP, null);
615 System.setProperty(TEST_PROP, "system-value");
616
617
618 var settings = Settings.create()
619 .addSource(Settings.SYSTEM_ENV_SOURCE)
620 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
621 .addSource(source)
622 .build();
623
624
625
626 var result = settings.get(TEST_PROP);
627 assertFalse(result.isPresent());
628 }
629
630 @Test
631 void o09_addSource_nullSource() {
632 assertThrows(IllegalArgumentException.class, () -> {
633 Settings.create().addSource(null);
634 });
635 }
636
637 @Test
638 void o10_setSources_nullSource() {
639 var source1 = new MapStore();
640 assertThrows(IllegalArgumentException.class, () -> {
641 Settings.create().setSources(source1, null);
642 });
643 }
644
645 @Test
646 void o11_source_springPropertiesExample() {
647
648 var springSource = new MapStore();
649 springSource.set("spring.datasource.url", "jdbc:postgresql://localhost/db");
650 springSource.set("spring.datasource.username", "admin");
651
652 var settings = Settings.create()
653 .addSource(springSource)
654 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
655 .addSource(Settings.SYSTEM_ENV_SOURCE)
656 .build();
657
658 var url = settings.get("spring.datasource.url");
659 assertTrue(url.isPresent());
660 assertEquals("jdbc:postgresql://localhost/db", url.get());
661
662 var username = settings.get("spring.datasource.username");
663 assertTrue(username.isPresent());
664 assertEquals("admin", username.get());
665 }
666
667
668
669
670 @Test
671 void p01_addSource_functionalSource() {
672
673 var source = (FunctionalSource) name -> opt(System.getProperty(name));
674 System.setProperty(TEST_PROP, "system-value");
675 var settings = Settings.create()
676 .addSource(source)
677 .addSource(Settings.SYSTEM_ENV_SOURCE)
678 .build();
679 var result = settings.get(TEST_PROP);
680 assertTrue(result.isPresent());
681 assertEquals("system-value", result.get());
682 }
683
684 @Test
685 void p02_addSource_functionalSource_factoryMethod() {
686
687 var source = FunctionalSource.of(System::getProperty);
688 System.setProperty(TEST_PROP, "system-value");
689 var settings = Settings.create()
690 .addSource(source)
691 .addSource(Settings.SYSTEM_ENV_SOURCE)
692 .build();
693 var result = settings.get(TEST_PROP);
694 assertTrue(result.isPresent());
695 assertEquals("system-value", result.get());
696 }
697
698
699
700
701 @Test
702 void q01_writeableFunctionalSource_basic() {
703
704 var source = FunctionalStore.of(
705 System::getProperty,
706 (k, v) -> System.setProperty(k, v),
707 k -> System.clearProperty(k),
708 () -> { }
709 );
710
711
712 source.set(TEST_PROP, "test-value");
713 var result = source.get(TEST_PROP);
714 assertNotNull(result);
715 assertTrue(result.isPresent());
716 assertEquals("test-value", result.get());
717
718
719 source.unset(TEST_PROP);
720 result = source.get(TEST_PROP);
721 assertNull(result);
722
723
724 System.clearProperty(TEST_PROP);
725 }
726
727 @Test
728 void q02_writeableFunctionalSource_withSettings() {
729
730 var source = FunctionalStore.of(
731 System::getProperty,
732 (k, v) -> System.setProperty(k, v),
733 k -> System.clearProperty(k),
734 () -> { }
735 );
736
737 var settings = Settings.create()
738 .addSource(source)
739 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
740 .addSource(Settings.SYSTEM_ENV_SOURCE)
741 .build();
742
743
744 source.set(TEST_PROP, "source-value");
745
746
747 var result = settings.get(TEST_PROP);
748 assertTrue(result.isPresent());
749 assertEquals("source-value", result.get());
750
751
752 source.unset(TEST_PROP);
753 System.clearProperty(TEST_PROP);
754 }
755
756 @Test
757 void q03_writeableFunctionalSource_clear() {
758
759 var map = new java.util.HashMap<String, String>();
760 var source = FunctionalStore.of(
761 map::get,
762 map::put,
763 map::remove,
764 map::clear
765 );
766
767 source.set(TEST_PROP, "test-value");
768 source.set(TEST_PROP_2, "test-value-2");
769
770
771 var result1 = source.get(TEST_PROP);
772 assertNotNull(result1);
773 assertTrue(result1.isPresent());
774 assertEquals("test-value", result1.get());
775
776 var result2 = source.get(TEST_PROP_2);
777 assertNotNull(result2);
778 assertTrue(result2.isPresent());
779 assertEquals("test-value-2", result2.get());
780
781
782 source.clear();
783
784
785 result1 = source.get(TEST_PROP);
786 assertNull(result1);
787
788 result2 = source.get(TEST_PROP_2);
789 assertNull(result2);
790 }
791
792
793
794
795 @Test
796 void r01_localStore() {
797
798 var settings = Settings.create()
799 .localStore(OptionalSupplier.of(() -> new MapStore()))
800 .build();
801
802 settings.setLocal(TEST_PROP, "test-value");
803 var result = settings.get(TEST_PROP);
804 assertTrue(result.isPresent());
805 assertEquals("test-value", result.get());
806 }
807
808
809
810
811 @Test
812 void s01_setGlobal_whenGlobalStoreDisabled() {
813
814 var settings = Settings.create()
815 .globalStore(OptionalSupplier.empty())
816 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
817 .addSource(Settings.SYSTEM_ENV_SOURCE)
818 .build();
819
820
821 assertThrows(IllegalStateException.class, () -> {
822 settings.setGlobal(TEST_PROP, "value");
823 });
824 }
825
826 @Test
827 void s02_unsetGlobal_whenGlobalStoreDisabled() {
828
829 var settings = Settings.create()
830 .globalStore(OptionalSupplier.empty())
831 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
832 .addSource(Settings.SYSTEM_ENV_SOURCE)
833 .build();
834
835
836 assertThrows(IllegalStateException.class, () -> {
837 settings.unsetGlobal(TEST_PROP);
838 });
839 }
840
841 @Test
842 void s03_clearGlobal_whenGlobalStoreDisabled() {
843
844 var settings = Settings.create()
845 .globalStore(OptionalSupplier.empty())
846 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
847 .addSource(Settings.SYSTEM_ENV_SOURCE)
848 .build();
849
850
851 assertThrows(IllegalStateException.class, () -> {
852 settings.clearGlobal();
853 });
854 }
855
856
857
858
859 @Test
860 void t01_mapStore_unset_whenMapNotInitialized() {
861
862
863 var store = new MapStore();
864
865
866
867 store.unset(TEST_PROP);
868
869
870
871 var result = store.get(TEST_PROP);
872 assertNull(result);
873 }
874
875
876
877
878 @Test
879 void u01_get_withDefaultString_found() {
880 System.setProperty(TEST_PROP, "found-value");
881 var result = Settings.get().get(TEST_PROP, "default-value");
882 assertEquals("found-value", result);
883 }
884
885 @Test
886 void u02_get_withDefaultString_notFound() {
887 var result = Settings.get().get("nonexistent.property", "default-value");
888 assertEquals("default-value", result);
889 }
890
891 @Test
892 void u03_get_withDefaultBoolean_found() {
893 System.setProperty(TEST_PROP, "true");
894 var result = Settings.get().get(TEST_PROP, false);
895 assertTrue(result);
896 }
897
898 @Test
899 void u04_get_withDefaultBoolean_notFound() {
900 var result = Settings.get().get("nonexistent.property", true);
901 assertTrue(result);
902 }
903
904 @Test
905 void u05_get_withDefaultBoolean_falseValue() {
906 System.setProperty(TEST_PROP, "false");
907 var result = Settings.get().get(TEST_PROP, true);
908 assertFalse(result);
909 }
910
911 @Test
912 void u07_get_withDefaultCharset_notFound() {
913
914 var defaultCharset = Charset.forName("UTF-8");
915 var result = Settings.get().get("nonexistent.property", defaultCharset);
916 assertEquals(defaultCharset, result);
917 }
918
919 @Test
920 void u08_get_withDefaultEnum_found() {
921 enum TestEnum { VALUE1, VALUE2, VALUE3 }
922 System.setProperty(TEST_PROP, "VALUE2");
923 var result = Settings.get().get(TEST_PROP, TestEnum.VALUE1);
924 assertEquals(TestEnum.VALUE2, result);
925 }
926
927 @Test
928 void u09_get_withDefaultEnum_notFound() {
929 enum TestEnum { VALUE1, VALUE2, VALUE3 }
930 var result = Settings.get().get("nonexistent.property", TestEnum.VALUE1);
931 assertEquals(TestEnum.VALUE1, result);
932 }
933
934 @Test
935 void u10_get_withDefaultString_nullDefault() {
936
937 System.setProperty(TEST_PROP, "found-value");
938 assertThrows(IllegalArgumentException.class, () -> {
939 Settings.get().get(TEST_PROP, (String)null);
940 });
941 }
942
943 @Test
944 void u11_get_withDefaultString_nullProperty() {
945 Settings.get().setLocal(TEST_PROP, null);
946 var result = Settings.get().get(TEST_PROP, "default-value");
947
948 assertEquals("default-value", result);
949 }
950
951
952
953
954 @Test
955 void v01_addTypeFunction_customType() {
956
957 var settings = Settings.create()
958 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
959 .addSource(Settings.SYSTEM_ENV_SOURCE)
960 .addTypeFunction(Integer.class, Integer::valueOf)
961 .build();
962
963 System.setProperty(TEST_PROP, "123");
964 var result = settings.get(TEST_PROP, 0);
965 assertEquals(123, result.intValue());
966 }
967
968 @Test
969 void v02_addTypeFunction_customType_notFound() {
970
971 var settings = Settings.create()
972 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
973 .addSource(Settings.SYSTEM_ENV_SOURCE)
974 .addTypeFunction(Integer.class, Integer::valueOf)
975 .build();
976
977 var result = settings.get("nonexistent.property", 999);
978 assertEquals(999, result.intValue());
979 }
980
981 @Test
982 void v03_addTypeFunction_overridesDefault() {
983
984 var settings = Settings.create()
985 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
986 .addSource(Settings.SYSTEM_ENV_SOURCE)
987 .addTypeFunction(Boolean.class, s -> !Boolean.valueOf(s))
988 .build();
989
990 System.setProperty(TEST_PROP, "true");
991 var result = settings.get(TEST_PROP, false);
992
993 assertFalse(result);
994 }
995
996 @Test
997 void v04_addTypeFunction_multipleTypes() {
998
999 var settings = Settings.create()
1000 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1001 .addSource(Settings.SYSTEM_ENV_SOURCE)
1002 .addTypeFunction(Integer.class, Integer::valueOf)
1003 .addTypeFunction(Long.class, Long::valueOf)
1004 .build();
1005
1006 System.setProperty(TEST_PROP, "123");
1007 var intResult = settings.get(TEST_PROP, 0);
1008 assertEquals(123, intResult.intValue());
1009
1010 System.setProperty(TEST_PROP_2, "456");
1011 var longResult = settings.get(TEST_PROP_2, 0L);
1012 assertEquals(456L, longResult.longValue());
1013 }
1014
1015 @Test
1016 void v05_addTypeFunction_customClass() {
1017
1018
1019 var settings = Settings.create()
1020 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1021 .addSource(Settings.SYSTEM_ENV_SOURCE)
1022 .addTypeFunction(String.class, s -> "custom-" + s)
1023 .build();
1024
1025 System.setProperty(TEST_PROP, "value");
1026
1027 var result = settings.get(TEST_PROP, "default");
1028 assertEquals("custom-value", result);
1029 }
1030
1031 @Test
1032 void v06_addTypeFunction_nullType() {
1033 assertThrows(IllegalArgumentException.class, () -> {
1034 Settings.create().addTypeFunction(null, Integer::valueOf);
1035 });
1036 }
1037
1038 @Test
1039 void v07_addTypeFunction_nullFunction() {
1040 assertThrows(IllegalArgumentException.class, () -> {
1041 Settings.create().addTypeFunction(Integer.class, null);
1042 });
1043 }
1044
1045 @Test
1046 void v08_addTypeFunction_unsupportedType() {
1047
1048
1049 class UnsupportedType {
1050 @SuppressWarnings("unused")
1051 private final int value;
1052 UnsupportedType(int value) { this.value = value; }
1053 }
1054
1055 var settings = Settings.create()
1056 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1057 .addSource(Settings.SYSTEM_ENV_SOURCE)
1058 .build();
1059
1060 System.setProperty(TEST_PROP, "123");
1061 assertThrows(RuntimeException.class, () -> {
1062 settings.get(TEST_PROP, new UnsupportedType(0));
1063 });
1064 }
1065
1066 @Test
1067 void v09_addTypeFunction_usesReflectionWhenCustomNotRegistered() {
1068
1069 var settings = Settings.create()
1070 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1071 .addSource(Settings.SYSTEM_ENV_SOURCE)
1072 .build();
1073
1074
1075 System.setProperty(TEST_PROP, "true");
1076 var result = settings.get(TEST_PROP, false);
1077 assertTrue(result);
1078
1079
1080 System.setProperty(TEST_PROP_2, "123");
1081 var intResult = settings.get(TEST_PROP_2, 0);
1082 assertEquals(123, intResult.intValue());
1083 }
1084
1085
1086
1087
1088 @Test
1089 void r01_stringSetting_filter_returnsStringSetting() {
1090 System.setProperty(TEST_PROP, "hello");
1091 var setting = Settings.get().get(TEST_PROP);
1092 var filtered = setting.filter(s -> s.length() > 3);
1093 assertEquals("hello", filtered.get());
1094 }
1095
1096 @Test
1097 void r02_stringSetting_filter_noMatch() {
1098 System.setProperty(TEST_PROP, "hi");
1099 var setting = Settings.get().get(TEST_PROP);
1100 var filtered = setting.filter(s -> s.length() > 3);
1101 assertNull(filtered.get());
1102 }
1103
1104 @Test
1105 void r03_stringSetting_filter_empty() {
1106 var setting = Settings.get().get("nonexistent.property");
1107 var filtered = setting.filter(s -> s.length() > 3);
1108 assertNull(filtered.get());
1109 }
1110
1111 @Test
1112 void r04_stringSetting_filter_cached() {
1113 var callCount = new AtomicInteger();
1114 var settings = Settings.create()
1115 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1116 .addSource(Settings.SYSTEM_ENV_SOURCE)
1117 .build();
1118 System.setProperty(TEST_PROP, "hello");
1119 var setting = settings.get(TEST_PROP);
1120 var filtered = setting.filter(s -> {
1121 callCount.incrementAndGet();
1122 return s.length() > 3;
1123 });
1124
1125
1126 assertEquals("hello", filtered.get());
1127 assertEquals(1, callCount.get());
1128
1129
1130 assertEquals("hello", filtered.get());
1131 assertEquals(1, callCount.get());
1132 }
1133
1134 @Test
1135 void r05_stringSetting_filter_independent() {
1136 System.setProperty(TEST_PROP, "hello");
1137 var setting = Settings.get().get(TEST_PROP);
1138 var filtered = setting.filter(s -> s.length() > 3);
1139
1140
1141 setting.reset();
1142
1143 assertEquals("hello", filtered.get());
1144 }
1145
1146
1147
1148
1149 @Test
1150 void s01_stringSetting_mapString_returnsStringSetting() {
1151 System.setProperty(TEST_PROP, "hello");
1152 var setting = Settings.get().get(TEST_PROP);
1153 var mapped = setting.mapString(String::toUpperCase);
1154 assertEquals("HELLO", mapped.get());
1155 }
1156
1157 @Test
1158 void s02_stringSetting_mapString_empty() {
1159 var setting = Settings.get().get("nonexistent.property");
1160 var mapped = setting.mapString(String::toUpperCase);
1161 assertNull(mapped.get());
1162 }
1163
1164 @Test
1165 void s03_stringSetting_mapString_cached() {
1166 var callCount = new AtomicInteger();
1167 var settings = Settings.create()
1168 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1169 .addSource(Settings.SYSTEM_ENV_SOURCE)
1170 .build();
1171 System.setProperty(TEST_PROP, "hello");
1172 var setting = settings.get(TEST_PROP);
1173 var mapped = setting.mapString(s -> {
1174 callCount.incrementAndGet();
1175 return s.toUpperCase();
1176 });
1177
1178
1179 assertEquals("HELLO", mapped.get());
1180 assertEquals(1, callCount.get());
1181
1182
1183 assertEquals("HELLO", mapped.get());
1184 assertEquals(1, callCount.get());
1185 }
1186
1187 @Test
1188 void s04_stringSetting_mapString_independent() {
1189 System.setProperty(TEST_PROP, "hello");
1190 var setting = Settings.get().get(TEST_PROP);
1191 var mapped = setting.mapString(String::toUpperCase);
1192
1193
1194 setting.reset();
1195
1196 assertEquals("HELLO", mapped.get());
1197 }
1198
1199 @Test
1200 void s05_stringSetting_mapString_returnsNull() {
1201 System.setProperty(TEST_PROP, "hello");
1202 var setting = Settings.get().get(TEST_PROP);
1203 var mapped = setting.mapString(s -> null);
1204 assertNull(mapped.get());
1205 }
1206
1207
1208
1209
1210 @Test
1211 void t01_setting_asOptional_present() {
1212 System.setProperty(TEST_PROP, "value");
1213 var setting = Settings.get().get(TEST_PROP);
1214 var optional = setting.asOptional();
1215 assertTrue(optional.isPresent());
1216 assertEquals("value", optional.get());
1217 }
1218
1219 @Test
1220 void t02_setting_asOptional_empty() {
1221 var setting = Settings.get().get("nonexistent.property");
1222 var optional = setting.asOptional();
1223 assertFalse(optional.isPresent());
1224 }
1225
1226 @Test
1227 void t03_setting_asOptional_snapshot() {
1228 var settings = Settings.create()
1229 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1230 .addSource(Settings.SYSTEM_ENV_SOURCE)
1231 .build();
1232 System.setProperty(TEST_PROP, "value1");
1233 var setting = settings.get(TEST_PROP);
1234 var optional1 = setting.asOptional();
1235 assertTrue(optional1.isPresent());
1236 assertEquals("value1", optional1.get());
1237
1238
1239 System.setProperty(TEST_PROP, "value2");
1240 setting.reset();
1241
1242
1243 assertTrue(optional1.isPresent());
1244 assertEquals("value1", optional1.get());
1245
1246
1247 var optional2 = setting.asOptional();
1248 assertTrue(optional2.isPresent());
1249 assertEquals("value2", optional2.get());
1250 }
1251
1252 @Test
1253 void t04_setting_asOptional_resetDoesNotAffect() {
1254 var settings = Settings.create()
1255 .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
1256 .addSource(Settings.SYSTEM_ENV_SOURCE)
1257 .build();
1258 System.setProperty(TEST_PROP, "value1");
1259 var setting = settings.get(TEST_PROP);
1260 var optional = setting.asOptional();
1261 assertTrue(optional.isPresent());
1262 assertEquals("value1", optional.get());
1263
1264
1265 setting.reset();
1266
1267
1268 assertTrue(optional.isPresent());
1269 assertEquals("value1", optional.get());
1270
1271
1272 var optional2 = setting.asOptional();
1273 assertTrue(optional2.isPresent());
1274 assertEquals("value1", optional2.get());
1275 }
1276 }
1277