1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.text;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertSame;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Properties;
30
31 import org.apache.commons.lang3.SystemProperties;
32 import org.apache.commons.lang3.mutable.MutableObject;
33 import org.junit.jupiter.api.AfterEach;
34 import org.junit.jupiter.api.BeforeEach;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40
41
42 class StrSubstitutorTest {
43
44 private Map<String, String> values;
45
46 private void doTestNoReplace(final String replaceTemplate) {
47 final StrSubstitutor sub = new StrSubstitutor(values);
48
49 if (replaceTemplate == null) {
50 assertNull(sub.replace((String) null));
51 assertNull(sub.replace((String) null, 0, 100));
52 assertNull(sub.replace((char[]) null));
53 assertNull(sub.replace((char[]) null, 0, 100));
54 assertNull(sub.replace((StringBuffer) null));
55 assertNull(sub.replace((StringBuffer) null, 0, 100));
56 assertNull(sub.replace((StrBuilder) null));
57 assertNull(sub.replace((StrBuilder) null, 0, 100));
58 assertNull(sub.replace((Object) null));
59 assertFalse(sub.replaceIn((StringBuffer) null));
60 assertFalse(sub.replaceIn((StringBuffer) null, 0, 100));
61 assertFalse(sub.replaceIn((StrBuilder) null));
62 assertFalse(sub.replaceIn((StrBuilder) null, 0, 100));
63 } else {
64 assertEquals(replaceTemplate, sub.replace(replaceTemplate));
65 final StrBuilder bld = new StrBuilder(replaceTemplate);
66 assertFalse(sub.replaceIn(bld));
67 assertEquals(replaceTemplate, bld.toString());
68 }
69 }
70
71 private void doTestReplace(final String expectedResult, final String replaceTemplate, final boolean substring) {
72 final StrSubstitutor sub = new StrSubstitutor(values);
73 doTestReplace(sub, expectedResult, replaceTemplate, substring);
74 }
75
76 private void doTestReplace(final StrSubstitutor sub, final String expectedResult, final String replaceTemplate,
77 final boolean substring) {
78 final String expectedShortResult = expectedResult.substring(1, expectedResult.length() - 1);
79
80
81 assertEquals(expectedResult, sub.replace(replaceTemplate));
82 if (substring) {
83 assertEquals(expectedShortResult, sub.replace(replaceTemplate, 1, replaceTemplate.length() - 2));
84 }
85
86
87 final char[] chars = replaceTemplate.toCharArray();
88 assertEquals(expectedResult, sub.replace(chars));
89 if (substring) {
90 assertEquals(expectedShortResult, sub.replace(chars, 1, chars.length - 2));
91 }
92
93
94 StringBuffer buf = new StringBuffer(replaceTemplate);
95 assertEquals(expectedResult, sub.replace(buf));
96 if (substring) {
97 assertEquals(expectedShortResult, sub.replace(buf, 1, buf.length() - 2));
98 }
99
100
101 StringBuilder builder = new StringBuilder(replaceTemplate);
102 assertEquals(expectedResult, sub.replace(builder));
103 if (substring) {
104 assertEquals(expectedShortResult, sub.replace(builder, 1, builder.length() - 2));
105 }
106
107
108 StrBuilder bld = new StrBuilder(replaceTemplate);
109 assertEquals(expectedResult, sub.replace(bld));
110 if (substring) {
111 assertEquals(expectedShortResult, sub.replace(bld, 1, bld.length() - 2));
112 }
113
114
115 final MutableObject<String> obj = new MutableObject<>(replaceTemplate);
116 assertEquals(expectedResult, sub.replace(obj));
117
118
119 buf = new StringBuffer(replaceTemplate);
120 assertTrue(sub.replaceIn(buf));
121 assertEquals(expectedResult, buf.toString());
122 if (substring) {
123 buf = new StringBuffer(replaceTemplate);
124 assertTrue(sub.replaceIn(buf, 1, buf.length() - 2));
125 assertEquals(expectedResult, buf.toString());
126 }
127
128
129 builder = new StringBuilder(replaceTemplate);
130 assertTrue(sub.replaceIn(builder));
131 assertEquals(expectedResult, builder.toString());
132 if (substring) {
133 builder = new StringBuilder(replaceTemplate);
134 assertTrue(sub.replaceIn(builder, 1, builder.length() - 2));
135 assertEquals(expectedResult, builder.toString());
136 }
137
138
139 bld = new StrBuilder(replaceTemplate);
140 assertTrue(sub.replaceIn(bld));
141 assertEquals(expectedResult, bld.toString());
142 if (substring) {
143 bld = new StrBuilder(replaceTemplate);
144 assertTrue(sub.replaceIn(bld, 1, bld.length() - 2));
145 assertEquals(expectedResult, bld.toString());
146 }
147 }
148
149 @BeforeEach
150 public void setUp() throws Exception {
151 values = new HashMap<>();
152 values.put("animal", "quick brown fox");
153 values.put("target", "lazy dog");
154 }
155
156 @AfterEach
157 public void tearDown() throws Exception {
158 values = null;
159 }
160
161
162
163
164 @Test
165 void testConstructorMapFull() {
166 final Map<String, String> map = new HashMap<>();
167 map.put("name", "commons");
168 StrSubstitutor sub = new StrSubstitutor(map, "<", ">", '!');
169 assertEquals("Hi < commons", sub.replace("Hi !< <name>"));
170 sub = new StrSubstitutor(map, "<", ">", '!', "||");
171 assertEquals("Hi < commons", sub.replace("Hi !< <name2||commons>"));
172 }
173
174
175
176
177 @Test
178 void testConstructorMapPrefixSuffix() {
179 final Map<String, String> map = new HashMap<>();
180 map.put("name", "commons");
181 final StrSubstitutor sub = new StrSubstitutor(map, "<", ">");
182 assertEquals("Hi < commons", sub.replace("Hi $< <name>"));
183 }
184
185
186
187
188 @Test
189 void testConstructorNoArgs() {
190 final StrSubstitutor sub = new StrSubstitutor();
191 assertEquals("Hi ${name}", sub.replace("Hi ${name}"));
192 }
193
194 @Test
195 void testCreatesStrSubstitutorTakingStrLookupAndCallsReplaceTakingTwoAndThreeInts() {
196 final Map<String, CharacterPredicates> map = new HashMap<>();
197 final StrLookup<CharacterPredicates> strLookupMapStrLookup = StrLookup.mapLookup(map);
198 final StrSubstitutor strSubstitutor = new StrSubstitutor(strLookupMapStrLookup);
199
200 assertNull(strSubstitutor.replace((CharSequence) null, 0, 0));
201 assertEquals('$', strSubstitutor.getEscapeChar());
202 }
203
204
205
206
207
208 @Test
209 void testCyclicReplacement() {
210 final Map<String, String> map = new HashMap<>();
211 map.put("animal", "${critter}");
212 map.put("target", "${pet}");
213 map.put("pet", "${petCharacteristic} dog");
214 map.put("petCharacteristic", "lazy");
215 map.put("critter", "${critterSpeed} ${critterColor} ${critterType}");
216 map.put("critterSpeed", "quick");
217 map.put("critterColor", "brown");
218 map.put("critterType", "${animal}");
219 final StrSubstitutor sub = new StrSubstitutor(map);
220 assertThrows(IllegalStateException.class, () -> sub.replace("The ${animal} jumps over the ${target}."));
221
222
223 map.put("critterType", "${animal:-fox}");
224 assertThrows(IllegalStateException.class,
225 () -> new StrSubstitutor(map).replace("The ${animal} jumps over the ${target}."));
226 }
227
228 @Test
229 void testDefaultValueDelimiters() {
230 final Map<String, String> map = new HashMap<>();
231 map.put("animal", "fox");
232 map.put("target", "dog");
233
234 StrSubstitutor sub = new StrSubstitutor(map, "${", "}", '$');
235 assertEquals("The fox jumps over the lazy dog. 1234567890.",
236 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number:-1234567890}."));
237
238 sub = new StrSubstitutor(map, "${", "}", '$', "?:");
239 assertEquals("The fox jumps over the lazy dog. 1234567890.",
240 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number?:1234567890}."));
241
242 sub = new StrSubstitutor(map, "${", "}", '$', "||");
243 assertEquals("The fox jumps over the lazy dog. 1234567890.",
244 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number||1234567890}."));
245
246 sub = new StrSubstitutor(map, "${", "}", '$', "!");
247 assertEquals("The fox jumps over the lazy dog. 1234567890.",
248 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}."));
249
250 sub = new StrSubstitutor(map, "${", "}", '$', "");
251 sub.setValueDelimiterMatcher(null);
252 assertEquals("The fox jumps over the lazy dog. ${undefined.number!1234567890}.",
253 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}."));
254
255 sub = new StrSubstitutor(map, "${", "}", '$');
256 sub.setValueDelimiterMatcher(null);
257 assertEquals("The fox jumps over the lazy dog. ${undefined.number!1234567890}.",
258 sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}."));
259 }
260
261 @Test
262 void testDisableSubstitutionInValues() {
263 final StrSubstitutor sub = new StrSubstitutor(values);
264 sub.setDisableSubstitutionInValues(true);
265 values.put("animal", "${critter}");
266 values.put("target", "${pet}");
267 values.put("pet", "${petCharacteristic} dog");
268 values.put("petCharacteristic", "lazy");
269 values.put("critter", "${critterSpeed} ${critterColor} ${critterType}");
270 values.put("critterSpeed", "quick");
271 values.put("critterColor", "brown");
272 values.put("critterType", "fox");
273 doTestReplace(sub, "The ${critter} jumps over the ${pet}.", "The ${animal} jumps over the ${target}.", true);
274 }
275
276
277
278
279 @Test
280 void testGetSetEscape() {
281 final StrSubstitutor sub = new StrSubstitutor();
282 assertEquals('$', sub.getEscapeChar());
283 sub.setEscapeChar('<');
284 assertEquals('<', sub.getEscapeChar());
285 }
286
287
288
289
290 @Test
291 void testGetSetPrefix() {
292 final StrSubstitutor sub = new StrSubstitutor();
293 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
294 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
295 sub.setVariablePrefix('<');
296 StrMatcherTest.assertStrMatcherPrefixImpl("CharMatcher", sub);
297 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
298
299 sub.setVariablePrefix("<<");
300 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
301 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
302 assertThrows(IllegalArgumentException.class, () -> sub.setVariablePrefix((String) null));
303 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
304 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
305
306 final StrMatcher matcher = StrMatcher.commaMatcher();
307 sub.setVariablePrefixMatcher(matcher);
308 assertSame(matcher, sub.getVariablePrefixMatcher());
309 assertThrows(IllegalArgumentException.class, () -> sub.setVariablePrefixMatcher((StrMatcher) null));
310 assertSame(matcher, sub.getVariablePrefixMatcher());
311 }
312
313
314
315
316 @Test
317 void testGetSetSuffix() {
318 final StrSubstitutor sub = new StrSubstitutor();
319 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
320 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
321 sub.setVariableSuffix('<');
322 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
323 StrMatcherTest.assertStrMatcherSuffixImpl("CharMatcher", sub);
324
325 sub.setVariableSuffix("<<");
326 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
327 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
328 assertThrows(IllegalArgumentException.class, () -> sub.setVariableSuffix((String) null));
329 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
330 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
331
332 final StrMatcher matcher = StrMatcher.commaMatcher();
333 sub.setVariableSuffixMatcher(matcher);
334 assertSame(matcher, sub.getVariableSuffixMatcher());
335 assertThrows(IllegalArgumentException.class, () -> sub.setVariableSuffixMatcher((StrMatcher) null));
336 assertSame(matcher, sub.getVariableSuffixMatcher());
337 }
338
339
340
341
342 @Test
343 void testGetSetValueDelimiter() {
344 final StrSubstitutor sub = new StrSubstitutor();
345 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
346 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
347 sub.setValueDelimiter(':');
348 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
349 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
350
351 sub.setValueDelimiter("||");
352 StrMatcherTest.assertStrMatcherPrefixImpl("StringMatcher", sub);
353 StrMatcherTest.assertStrMatcherSuffixImpl("StringMatcher", sub);
354 sub.setValueDelimiter((String) null);
355 assertNull(sub.getValueDelimiterMatcher());
356
357 final StrMatcher matcher = StrMatcher.commaMatcher();
358 sub.setValueDelimiterMatcher(matcher);
359 assertSame(matcher, sub.getValueDelimiterMatcher());
360 sub.setValueDelimiterMatcher((StrMatcher) null);
361 assertNull(sub.getValueDelimiterMatcher());
362 }
363
364
365
366
367 @Test
368 void testLANG1055() {
369 System.setProperty("test_key", "test_value");
370
371 final String expected = StrSubstitutor.replace("test_key=${test_key}", System.getProperties());
372 final String actual = StrSubstitutor.replaceSystemProperties("test_key=${test_key}");
373 assertEquals(expected, actual);
374 }
375
376
377
378
379 @Test
380 void testReplaceAdjacentAtEnd() {
381 values.put("code", "GBP");
382 values.put("amount", "12.50");
383 final StrSubstitutor sub = new StrSubstitutor(values);
384 assertEquals("Amount is GBP12.50", sub.replace("Amount is ${code}${amount}"));
385 }
386
387
388
389
390 @Test
391 void testReplaceAdjacentAtStart() {
392 values.put("code", "GBP");
393 values.put("amount", "12.50");
394 final StrSubstitutor sub = new StrSubstitutor(values);
395 assertEquals("GBP12.50 charged", sub.replace("${code}${amount} charged"));
396 }
397
398
399
400
401 @Test
402 void testReplaceChangedMap() {
403 final StrSubstitutor sub = new StrSubstitutor(values);
404 values.put("target", "moon");
405 assertEquals("The quick brown fox jumps over the moon.",
406 sub.replace("The ${animal} jumps over the ${target}."));
407 }
408
409
410
411
412 @Test
413 void testReplaceComplexEscaping() {
414 doTestReplace("The ${quick brown fox} jumps over the lazy dog.",
415 "The $${${animal}} jumps over the ${target}.", true);
416 doTestReplace("The ${quick brown fox} jumps over the lazy dog. ${1234567890}.",
417 "The $${${animal}} jumps over the ${target}. $${${undefined.number:-1234567890}}.", true);
418 }
419
420
421
422
423 @Test
424 void testReplaceEmpty() {
425 doTestNoReplace("");
426 }
427
428
429
430
431 @Test
432 void testReplaceEmptyKeys() {
433 doTestReplace("The ${} jumps over the lazy dog.", "The ${} jumps over the ${target}.", true);
434 doTestReplace("The animal jumps over the lazy dog.", "The ${:-animal} jumps over the ${target}.", true);
435 }
436
437
438
439
440 @Test
441 void testReplaceEscaping() {
442 doTestReplace("The ${animal} jumps over the lazy dog.", "The $${animal} jumps over the ${target}.", true);
443 }
444
445
446
447
448 @Test
449 void testReplaceIncompletePrefix() {
450 doTestReplace("The {animal} jumps over the lazy dog.", "The {animal} jumps over the ${target}.", true);
451 }
452
453 @Test
454 void testReplaceInTakingStringBufferWithNonNull() {
455 final StrSubstitutor strSubstitutor =
456 new StrSubstitutor(new HashMap<>(), "WV@i#y?N*[", "WV@i#y?N*[", '*');
457
458 assertFalse(strSubstitutor.isPreserveEscapes());
459 assertFalse(strSubstitutor.replaceIn(new StringBuffer("WV@i#y?N*[")));
460 assertEquals('*', strSubstitutor.getEscapeChar());
461 }
462
463 @Test
464 void testReplaceInTakingStringBuilderWithNonNull() {
465 final StrLookup<String> strLookup = StrLookup.systemPropertiesLookup();
466 final StrSubstitutor strSubstitutor = new StrSubstitutor(strLookup, "b<H", "b<H", '\'');
467 final StringBuilder stringBuilder = new StringBuilder((CharSequence) "b<H");
468
469 assertEquals('\'', strSubstitutor.getEscapeChar());
470 assertFalse(strSubstitutor.replaceIn(stringBuilder));
471 }
472
473 @Test
474 void testReplaceInTakingStringBuilderWithNull() {
475 final Map<String, Object> map = new HashMap<>();
476 final StrSubstitutor strSubstitutor = new StrSubstitutor(map, "", "", 'T', "K+<'f");
477
478 assertFalse(strSubstitutor.replaceIn((StringBuilder) null));
479 }
480
481 @Test
482 void testReplaceInTakingTwoAndThreeIntsReturningFalse() {
483 final Map<String, Object> hashMap = new HashMap<>();
484 final StrLookup<Object> strLookupMapStrLookup = StrLookup.mapLookup(hashMap);
485 final StrMatcher strMatcher = StrMatcher.tabMatcher();
486 final StrSubstitutor strSubstitutor =
487 new StrSubstitutor(strLookupMapStrLookup, strMatcher, strMatcher, 'b', strMatcher);
488
489 assertFalse(strSubstitutor.replaceIn((StringBuilder) null, 1315, -1369));
490 assertEquals('b', strSubstitutor.getEscapeChar());
491 assertFalse(strSubstitutor.isPreserveEscapes());
492 }
493
494
495
496
497 @Test
498 void testReplaceInVariable() {
499 values.put("animal.1", "fox");
500 values.put("animal.2", "mouse");
501 values.put("species", "2");
502 final StrSubstitutor sub = new StrSubstitutor(values);
503 sub.setEnableSubstitutionInVariables(true);
504 assertEquals(
505 "The mouse jumps over the lazy dog.",
506 sub.replace("The ${animal.${species}} jumps over the ${target}."));
507 values.put("species", "1");
508 assertEquals(
509 "The fox jumps over the lazy dog.",
510 sub.replace("The ${animal.${species}} jumps over the ${target}."));
511 assertEquals(
512 "The fox jumps over the lazy dog.",
513 sub.replace("The ${unknown.animal.${unknown.species:-1}:-fox} "
514 + "jumps over the ${unknow.target:-lazy dog}."));
515 }
516
517
518
519
520 @Test
521 void testReplaceInVariableDisabled() {
522 values.put("animal.1", "fox");
523 values.put("animal.2", "mouse");
524 values.put("species", "2");
525 final StrSubstitutor sub = new StrSubstitutor(values);
526 assertEquals(
527 "The ${animal.${species}} jumps over the lazy dog.",
528 sub.replace("The ${animal.${species}} jumps over the ${target}."));
529 assertEquals(
530 "The ${animal.${species:-1}} jumps over the lazy dog.",
531 sub.replace("The ${animal.${species:-1}} jumps over the ${target}."));
532 }
533
534
535
536
537 @Test
538 void testReplaceInVariableRecursive() {
539 values.put("animal.2", "brown fox");
540 values.put("animal.1", "white mouse");
541 values.put("color", "white");
542 values.put("species.white", "1");
543 values.put("species.brown", "2");
544 final StrSubstitutor sub = new StrSubstitutor(values);
545 sub.setEnableSubstitutionInVariables(true);
546 assertEquals(
547 "The white mouse jumps over the lazy dog.",
548 sub.replace("The ${animal.${species.${color}}} jumps over the ${target}."));
549 assertEquals(
550 "The brown fox jumps over the lazy dog.",
551 sub.replace("The ${animal.${species.${unknownColor:-brown}}} jumps over the ${target}."));
552 }
553
554
555
556
557 @Test
558 void testReplaceNoPrefixNoSuffix() {
559 doTestReplace("The animal jumps over the lazy dog.", "The animal jumps over the ${target}.", true);
560 }
561
562
563
564
565 @Test
566 void testReplaceNoPrefixSuffix() {
567 doTestReplace("The animal} jumps over the lazy dog.", "The animal} jumps over the ${target}.", true);
568 }
569
570
571
572
573 @Test
574 void testReplaceNoVariables() {
575 doTestNoReplace("The balloon arrived.");
576 }
577
578
579
580
581 @Test
582 void testReplaceNull() {
583 doTestNoReplace(null);
584 }
585
586
587
588
589 @Test
590 void testReplacePartialString_noReplace() {
591 final StrSubstitutor sub = new StrSubstitutor();
592 assertEquals("${animal} jumps", sub.replace("The ${animal} jumps over the ${target}.", 4, 15));
593 }
594
595
596
597
598 @Test
599 void testReplacePrefixNoSuffix() {
600 doTestReplace("The ${animal jumps over the ${target} lazy dog.",
601 "The ${animal jumps over the ${target} ${target}.", true);
602 }
603
604
605
606
607 @Test
608 void testReplaceRecursive() {
609 values.put("animal", "${critter}");
610 values.put("target", "${pet}");
611 values.put("pet", "${petCharacteristic} dog");
612 values.put("petCharacteristic", "lazy");
613 values.put("critter", "${critterSpeed} ${critterColor} ${critterType}");
614 values.put("critterSpeed", "quick");
615 values.put("critterColor", "brown");
616 values.put("critterType", "fox");
617 doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true);
618
619 values.put("pet", "${petCharacteristicUnknown:-lazy} dog");
620 doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true);
621 }
622
623
624
625
626 @Test
627 void testReplaceSimple() {
628 doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true);
629 }
630
631
632
633
634 @Test
635 void testReplaceSolo() {
636 doTestReplace("quick brown fox", "${animal}", false);
637 }
638
639
640
641
642 @Test
643 void testReplaceSoloEscaping() {
644 doTestReplace("${animal}", "$${animal}", false);
645 }
646
647 @Test
648 void testReplaceTakingCharSequenceReturningNull() {
649 final StrSubstitutor strSubstitutor = new StrSubstitutor((StrLookup<?>) null);
650
651 assertNull(strSubstitutor.replace((CharSequence) null));
652 assertFalse(strSubstitutor.isPreserveEscapes());
653 assertEquals('$', strSubstitutor.getEscapeChar());
654 }
655
656 @Test
657 void testReplaceTakingThreeArgumentsThrowsNullPointerException() {
658 assertThrows(NullPointerException.class, () -> StrSubstitutor.replace(null, (Properties) null));
659 }
660
661
662
663
664 @Test
665 void testReplaceToIdentical() {
666 values.put("animal", "$${${thing}}");
667 values.put("thing", "animal");
668 doTestReplace("The ${animal} jumps.", "The ${animal} jumps.", true);
669 }
670
671
672
673
674 @Test
675 void testReplaceUnknownKey() {
676 doTestReplace("The ${person} jumps over the lazy dog.", "The ${person} jumps over the ${target}.", true);
677 doTestReplace("The ${person} jumps over the lazy dog. 1234567890.",
678 "The ${person} jumps over the ${target}. ${undefined.number:-1234567890}.", true);
679 }
680
681
682
683
684 @Test
685 void testReplaceWeirdPattens() {
686 doTestNoReplace("");
687 doTestNoReplace("${}");
688 doTestNoReplace("${ }");
689 doTestNoReplace("${\t}");
690 doTestNoReplace("${\n}");
691 doTestNoReplace("${\b}");
692 doTestNoReplace("${");
693 doTestNoReplace("$}");
694 doTestNoReplace("}");
695 doTestNoReplace("${}$");
696 doTestNoReplace("${${");
697 doTestNoReplace("${${}}");
698 doTestNoReplace("${$${}}");
699 doTestNoReplace("${$$${}}");
700 doTestNoReplace("${$$${$}}");
701 doTestNoReplace("${${}}");
702 doTestNoReplace("${${ }}");
703 }
704
705
706
707
708 @Test
709 void testResolveVariable() {
710 final StrBuilder builder = new StrBuilder("Hi ${name}!");
711 final Map<String, String> map = new HashMap<>();
712 map.put("name", "commons");
713 final StrSubstitutor sub = new StrSubstitutor(map) {
714 @Override
715 protected String resolveVariable(final String variableName, final StrBuilder buf, final int startPos,
716 final int endPos) {
717 assertEquals("name", variableName);
718 assertSame(builder, buf);
719 assertEquals(3, startPos);
720 assertEquals(10, endPos);
721 return "jakarta";
722 }
723 };
724 sub.replaceIn(builder);
725 assertEquals("Hi jakarta!", builder.toString());
726 }
727
728 @Test
729 void testSamePrefixAndSuffix() {
730 final Map<String, String> map = new HashMap<>();
731 map.put("greeting", "Hello");
732 map.put(" there ", "XXX");
733 map.put("name", "commons");
734 assertEquals("Hi commons!", StrSubstitutor.replace("Hi @name@!", map, "@", "@"));
735 assertEquals("Hello there commons!", StrSubstitutor.replace("@greeting@ there @name@!", map, "@", "@"));
736 }
737
738
739
740
741 @Test
742 void testStaticReplace() {
743 final Map<String, String> map = new HashMap<>();
744 map.put("name", "commons");
745 assertEquals("Hi commons!", StrSubstitutor.replace("Hi ${name}!", map));
746 }
747
748
749
750
751 @Test
752 void testStaticReplacePrefixSuffix() {
753 final Map<String, String> map = new HashMap<>();
754 map.put("name", "commons");
755 assertEquals("Hi commons!", StrSubstitutor.replace("Hi <name>!", map, "<", ">"));
756 }
757
758
759
760
761 @Test
762 void testStaticReplaceSystemProperties() {
763 final StrBuilder buf = new StrBuilder();
764 buf.append("Hi ").append(SystemProperties.getUserName());
765 buf.append(", you are working with ");
766 buf.append(SystemProperties.getOsName());
767 buf.append(", your home directory is ");
768 buf.append(SystemProperties.getUserHome()).append('.');
769 assertEquals(buf.toString(), StrSubstitutor.replaceSystemProperties("Hi ${user.name}, you are "
770 + "working with ${os.name}, your home "
771 + "directory is ${user.home}."));
772 }
773
774
775
776
777 @Test
778 void testSubstituteDefaultProperties() {
779 final String org = "${doesnotwork}";
780 System.setProperty("doesnotwork", "It works!");
781
782
783 final Properties props = new Properties(System.getProperties());
784
785 assertEquals("It works!", StrSubstitutor.replace(org, props));
786 }
787
788 @Test
789 void testSubstitutePreserveEscape() {
790 final String org = "${not-escaped} $${escaped}";
791 final Map<String, String> map = new HashMap<>();
792 map.put("not-escaped", "value");
793
794 final StrSubstitutor sub = new StrSubstitutor(map, "${", "}", '$');
795 assertFalse(sub.isPreserveEscapes());
796 assertEquals("value ${escaped}", sub.replace(org));
797
798 sub.setPreserveEscapes(true);
799 assertTrue(sub.isPreserveEscapes());
800 assertEquals("value $${escaped}", sub.replace(org));
801 }
802
803 }