| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.commons.text; |
| |
| import static org.assertj.core.api.Assertions.assertThatNullPointerException; |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertSame; |
| import static org.junit.jupiter.api.Assertions.assertThrows; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.apache.commons.lang3.mutable.MutableObject; |
| import org.junit.jupiter.api.AfterEach; |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.Test; |
| |
| /** |
| * Test class for {@link StrSubstitutor}. |
| * |
| * @deprecated This class will be removed in 2.0. |
| */ |
| @Deprecated |
| public class StrSubstitutorTest { |
| |
| private Map<String, String> values; |
| |
| private void doTestNoReplace(final String replaceTemplate) { |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| |
| if (replaceTemplate == null) { |
| assertNull(sub.replace((String) null)); |
| assertNull(sub.replace((String) null, 0, 100)); |
| assertNull(sub.replace((char[]) null)); |
| assertNull(sub.replace((char[]) null, 0, 100)); |
| assertNull(sub.replace((StringBuffer) null)); |
| assertNull(sub.replace((StringBuffer) null, 0, 100)); |
| assertNull(sub.replace((StrBuilder) null)); |
| assertNull(sub.replace((StrBuilder) null, 0, 100)); |
| assertNull(sub.replace((Object) null)); |
| assertFalse(sub.replaceIn((StringBuffer) null)); |
| assertFalse(sub.replaceIn((StringBuffer) null, 0, 100)); |
| assertFalse(sub.replaceIn((StrBuilder) null)); |
| assertFalse(sub.replaceIn((StrBuilder) null, 0, 100)); |
| } else { |
| assertEquals(replaceTemplate, sub.replace(replaceTemplate)); |
| final StrBuilder bld = new StrBuilder(replaceTemplate); |
| assertFalse(sub.replaceIn(bld)); |
| assertEquals(replaceTemplate, bld.toString()); |
| } |
| } |
| |
| private void doTestReplace(final String expectedResult, final String replaceTemplate, final boolean substring) { |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| doTestReplace(sub, expectedResult, replaceTemplate, substring); |
| } |
| |
| //----------------------------------------------------------------------- |
| private void doTestReplace(final StrSubstitutor sub, final String expectedResult, final String replaceTemplate, |
| final boolean substring) { |
| final String expectedShortResult = expectedResult.substring(1, expectedResult.length() - 1); |
| |
| // replace using String |
| assertEquals(expectedResult, sub.replace(replaceTemplate)); |
| if (substring) { |
| assertEquals(expectedShortResult, sub.replace(replaceTemplate, 1, replaceTemplate.length() - 2)); |
| } |
| |
| // replace using char[] |
| final char[] chars = replaceTemplate.toCharArray(); |
| assertEquals(expectedResult, sub.replace(chars)); |
| if (substring) { |
| assertEquals(expectedShortResult, sub.replace(chars, 1, chars.length - 2)); |
| } |
| |
| // replace using StringBuffer |
| StringBuffer buf = new StringBuffer(replaceTemplate); |
| assertEquals(expectedResult, sub.replace(buf)); |
| if (substring) { |
| assertEquals(expectedShortResult, sub.replace(buf, 1, buf.length() - 2)); |
| } |
| |
| // replace using StringBuilder |
| StringBuilder builder = new StringBuilder(replaceTemplate); |
| assertEquals(expectedResult, sub.replace(builder)); |
| if (substring) { |
| assertEquals(expectedShortResult, sub.replace(builder, 1, builder.length() - 2)); |
| } |
| |
| // replace using StrBuilder |
| StrBuilder bld = new StrBuilder(replaceTemplate); |
| assertEquals(expectedResult, sub.replace(bld)); |
| if (substring) { |
| assertEquals(expectedShortResult, sub.replace(bld, 1, bld.length() - 2)); |
| } |
| |
| // replace using object |
| final MutableObject<String> obj = new MutableObject<>(replaceTemplate); // toString returns template |
| assertEquals(expectedResult, sub.replace(obj)); |
| |
| // replace in StringBuffer |
| buf = new StringBuffer(replaceTemplate); |
| assertTrue(sub.replaceIn(buf)); |
| assertEquals(expectedResult, buf.toString()); |
| if (substring) { |
| buf = new StringBuffer(replaceTemplate); |
| assertTrue(sub.replaceIn(buf, 1, buf.length() - 2)); |
| assertEquals(expectedResult, buf.toString()); // expect full result as remainder is untouched |
| } |
| |
| // replace in StringBuilder |
| builder = new StringBuilder(replaceTemplate); |
| assertTrue(sub.replaceIn(builder)); |
| assertEquals(expectedResult, builder.toString()); |
| if (substring) { |
| builder = new StringBuilder(replaceTemplate); |
| assertTrue(sub.replaceIn(builder, 1, builder.length() - 2)); |
| assertEquals(expectedResult, builder.toString()); // expect full result as remainder is untouched |
| } |
| |
| // replace in StrBuilder |
| bld = new StrBuilder(replaceTemplate); |
| assertTrue(sub.replaceIn(bld)); |
| assertEquals(expectedResult, bld.toString()); |
| if (substring) { |
| bld = new StrBuilder(replaceTemplate); |
| assertTrue(sub.replaceIn(bld, 1, bld.length() - 2)); |
| assertEquals(expectedResult, bld.toString()); // expect full result as remainder is untouched |
| } |
| } |
| |
| @BeforeEach |
| public void setUp() throws Exception { |
| values = new HashMap<>(); |
| values.put("animal", "quick brown fox"); |
| values.put("target", "lazy dog"); |
| } |
| |
| @AfterEach |
| public void tearDown() throws Exception { |
| values = null; |
| } |
| |
| /** |
| * Tests constructor. |
| */ |
| @Test |
| public void testConstructorMapFull() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("name", "commons"); |
| StrSubstitutor sub = new StrSubstitutor(map, "<", ">", '!'); |
| assertEquals("Hi < commons", sub.replace("Hi !< <name>")); |
| sub = new StrSubstitutor(map, "<", ">", '!', "||"); |
| assertEquals("Hi < commons", sub.replace("Hi !< <name2||commons>")); |
| } |
| |
| /** |
| * Tests constructor. |
| */ |
| @Test |
| public void testConstructorMapPrefixSuffix() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("name", "commons"); |
| final StrSubstitutor sub = new StrSubstitutor(map, "<", ">"); |
| assertEquals("Hi < commons", sub.replace("Hi $< <name>")); |
| } |
| |
| //----------------------------------------------------------------------- |
| /** |
| * Tests constructor. |
| */ |
| @Test |
| public void testConstructorNoArgs() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertEquals("Hi ${name}", sub.replace("Hi ${name}")); |
| } |
| |
| @Test |
| public void testCreatesStrSubstitutorTakingStrLookupAndCallsReplaceTakingTwoAndThreeInts() { |
| final Map<String, CharacterPredicates> map = new HashMap<>(); |
| final StrLookup.MapStrLookup<CharacterPredicates> strLookupMapStrLookup = new StrLookup.MapStrLookup<>(map); |
| final StrSubstitutor strSubstitutor = new StrSubstitutor(strLookupMapStrLookup); |
| |
| assertNull(strSubstitutor.replace((CharSequence) null, 0, 0)); |
| assertEquals('$', strSubstitutor.getEscapeChar()); |
| } |
| |
| /** |
| * Tests a cyclic replace operation. |
| * The cycle should be detected and cause an exception to be thrown. |
| */ |
| @Test |
| public void testCyclicReplacement() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("animal", "${critter}"); |
| map.put("target", "${pet}"); |
| map.put("pet", "${petCharacteristic} dog"); |
| map.put("petCharacteristic", "lazy"); |
| map.put("critter", "${critterSpeed} ${critterColor} ${critterType}"); |
| map.put("critterSpeed", "quick"); |
| map.put("critterColor", "brown"); |
| map.put("critterType", "${animal}"); |
| final StrSubstitutor sub = new StrSubstitutor(map); |
| assertThrows(IllegalStateException.class, () -> sub.replace("The ${animal} jumps over the ${target}.")); |
| |
| // also check even when default value is set. |
| map.put("critterType", "${animal:-fox}"); |
| assertThrows(IllegalStateException.class, |
| () -> new StrSubstitutor(map).replace("The ${animal} jumps over the ${target}.")); |
| } |
| |
| @Test |
| public void testDefaultValueDelimiters() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("animal", "fox"); |
| map.put("target", "dog"); |
| |
| StrSubstitutor sub = new StrSubstitutor(map, "${", "}", '$'); |
| assertEquals("The fox jumps over the lazy dog. 1234567890.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number:-1234567890}.")); |
| |
| sub = new StrSubstitutor(map, "${", "}", '$', "?:"); |
| assertEquals("The fox jumps over the lazy dog. 1234567890.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number?:1234567890}.")); |
| |
| sub = new StrSubstitutor(map, "${", "}", '$', "||"); |
| assertEquals("The fox jumps over the lazy dog. 1234567890.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number||1234567890}.")); |
| |
| sub = new StrSubstitutor(map, "${", "}", '$', "!"); |
| assertEquals("The fox jumps over the lazy dog. 1234567890.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}.")); |
| |
| sub = new StrSubstitutor(map, "${", "}", '$', ""); |
| sub.setValueDelimiterMatcher(null); |
| assertEquals("The fox jumps over the lazy dog. ${undefined.number!1234567890}.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}.")); |
| |
| sub = new StrSubstitutor(map, "${", "}", '$'); |
| sub.setValueDelimiterMatcher(null); |
| assertEquals("The fox jumps over the lazy dog. ${undefined.number!1234567890}.", |
| sub.replace("The ${animal} jumps over the lazy ${target}. ${undefined.number!1234567890}.")); |
| } |
| |
| @Test |
| public void testDisableSubstitutionInValues() { |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| sub.setDisableSubstitutionInValues(true); |
| values.put("animal", "${critter}"); |
| values.put("target", "${pet}"); |
| values.put("pet", "${petCharacteristic} dog"); |
| values.put("petCharacteristic", "lazy"); |
| values.put("critter", "${critterSpeed} ${critterColor} ${critterType}"); |
| values.put("critterSpeed", "quick"); |
| values.put("critterColor", "brown"); |
| values.put("critterType", "fox"); |
| doTestReplace(sub, "The ${critter} jumps over the ${pet}.", "The ${animal} jumps over the ${target}.", true); |
| } |
| |
| //----------------------------------------------------------------------- |
| /** |
| * Tests get set. |
| */ |
| @Test |
| public void testGetSetEscape() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertEquals('$', sub.getEscapeChar()); |
| sub.setEscapeChar('<'); |
| assertEquals('<', sub.getEscapeChar()); |
| } |
| |
| /** |
| * Tests get set. |
| */ |
| @Test |
| public void testGetSetPrefix() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertTrue(sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher); |
| sub.setVariablePrefix('<'); |
| assertTrue(sub.getVariablePrefixMatcher() instanceof StrMatcher.CharMatcher); |
| |
| sub.setVariablePrefix("<<"); |
| assertTrue(sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher); |
| assertThrows(IllegalArgumentException.class, () -> sub.setVariablePrefix((String) null)); |
| assertTrue(sub.getVariablePrefixMatcher() instanceof StrMatcher.StringMatcher); |
| |
| final StrMatcher matcher = StrMatcher.commaMatcher(); |
| sub.setVariablePrefixMatcher(matcher); |
| assertSame(matcher, sub.getVariablePrefixMatcher()); |
| assertThrows(IllegalArgumentException.class, () -> sub.setVariablePrefixMatcher((StrMatcher) null)); |
| assertSame(matcher, sub.getVariablePrefixMatcher()); |
| } |
| |
| /** |
| * Tests get set. |
| */ |
| @Test |
| public void testGetSetSuffix() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertTrue(sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher); |
| sub.setVariableSuffix('<'); |
| assertTrue(sub.getVariableSuffixMatcher() instanceof StrMatcher.CharMatcher); |
| |
| sub.setVariableSuffix("<<"); |
| assertTrue(sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher); |
| assertThrows(IllegalArgumentException.class, () -> sub.setVariableSuffix((String) null)); |
| assertTrue(sub.getVariableSuffixMatcher() instanceof StrMatcher.StringMatcher); |
| |
| final StrMatcher matcher = StrMatcher.commaMatcher(); |
| sub.setVariableSuffixMatcher(matcher); |
| assertSame(matcher, sub.getVariableSuffixMatcher()); |
| assertThrows(IllegalArgumentException.class, () -> sub.setVariableSuffixMatcher((StrMatcher) null)); |
| assertSame(matcher, sub.getVariableSuffixMatcher()); |
| } |
| |
| /** |
| * Tests get set. |
| */ |
| @Test |
| public void testGetSetValueDelimiter() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertTrue(sub.getValueDelimiterMatcher() instanceof StrMatcher.StringMatcher); |
| sub.setValueDelimiter(':'); |
| assertTrue(sub.getValueDelimiterMatcher() instanceof StrMatcher.CharMatcher); |
| |
| sub.setValueDelimiter("||"); |
| assertTrue(sub.getValueDelimiterMatcher() instanceof StrMatcher.StringMatcher); |
| sub.setValueDelimiter((String) null); |
| assertNull(sub.getValueDelimiterMatcher()); |
| |
| final StrMatcher matcher = StrMatcher.commaMatcher(); |
| sub.setValueDelimiterMatcher(matcher); |
| assertSame(matcher, sub.getValueDelimiterMatcher()); |
| sub.setValueDelimiterMatcher((StrMatcher) null); |
| assertNull(sub.getValueDelimiterMatcher()); |
| } |
| |
| /** |
| * Test for LANG-1055: StrSubstitutor.replaceSystemProperties does not work consistently |
| */ |
| @Test |
| public void testLANG1055() { |
| System.setProperty("test_key", "test_value"); |
| |
| final String expected = StrSubstitutor.replace("test_key=${test_key}", System.getProperties()); |
| final String actual = StrSubstitutor.replaceSystemProperties("test_key=${test_key}"); |
| assertEquals(expected, actual); |
| } |
| |
| /** |
| * Tests adjacent keys. |
| */ |
| @Test |
| public void testReplaceAdjacentAtEnd() { |
| values.put("code", "GBP"); |
| values.put("amount", "12.50"); |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| assertEquals("Amount is GBP12.50", sub.replace("Amount is ${code}${amount}")); |
| } |
| |
| /** |
| * Tests adjacent keys. |
| */ |
| @Test |
| public void testReplaceAdjacentAtStart() { |
| values.put("code", "GBP"); |
| values.put("amount", "12.50"); |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| assertEquals("GBP12.50 charged", sub.replace("${code}${amount} charged")); |
| } |
| |
| /** |
| * Tests key replace changing map after initialization (not recommended). |
| */ |
| @Test |
| public void testReplaceChangedMap() { |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| values.put("target", "moon"); |
| assertEquals("The quick brown fox jumps over the moon.", |
| sub.replace("The ${animal} jumps over the ${target}.")); |
| } |
| |
| /** |
| * Tests complex escaping. |
| */ |
| @Test |
| public void testReplaceComplexEscaping() { |
| doTestReplace("The ${quick brown fox} jumps over the lazy dog.", |
| "The $${${animal}} jumps over the ${target}.", true); |
| doTestReplace("The ${quick brown fox} jumps over the lazy dog. ${1234567890}.", |
| "The $${${animal}} jumps over the ${target}. $${${undefined.number:-1234567890}}.", true); |
| } |
| |
| /** |
| * Tests replace with null. |
| */ |
| @Test |
| public void testReplaceEmpty() { |
| doTestNoReplace(""); |
| } |
| |
| /** |
| * Tests when no variable name. |
| */ |
| @Test |
| public void testReplaceEmptyKeys() { |
| doTestReplace("The ${} jumps over the lazy dog.", "The ${} jumps over the ${target}.", true); |
| doTestReplace("The animal jumps over the lazy dog.", "The ${:-animal} jumps over the ${target}.", true); |
| } |
| |
| /** |
| * Tests escaping. |
| */ |
| @Test |
| public void testReplaceEscaping() { |
| doTestReplace("The ${animal} jumps over the lazy dog.", "The $${animal} jumps over the ${target}.", true); |
| } |
| |
| /** |
| * Tests when no incomplete prefix. |
| */ |
| @Test |
| public void testReplaceIncompletePrefix() { |
| doTestReplace("The {animal} jumps over the lazy dog.", "The {animal} jumps over the ${target}.", true); |
| } |
| |
| @Test |
| public void testReplaceInTakingStringBufferWithNonNull() { |
| final StrSubstitutor strSubstitutor = |
| new StrSubstitutor(new HashMap<String, String>(), "WV@i#y?N*[", "WV@i#y?N*[", '*'); |
| |
| assertFalse(strSubstitutor.isPreserveEscapes()); |
| assertFalse(strSubstitutor.replaceIn(new StringBuffer("WV@i#y?N*["))); |
| assertEquals('*', strSubstitutor.getEscapeChar()); |
| } |
| |
| @Test |
| public void testReplaceInTakingStringBuilderWithNonNull() { |
| final StrLookup<String> strLookup = StrLookup.systemPropertiesLookup(); |
| final StrSubstitutor strSubstitutor = new StrSubstitutor(strLookup, "b<H", "b<H", '\''); |
| final StringBuilder stringBuilder = new StringBuilder((CharSequence) "b<H"); |
| |
| assertEquals('\'', strSubstitutor.getEscapeChar()); |
| assertFalse(strSubstitutor.replaceIn(stringBuilder)); |
| } |
| |
| @Test |
| public void testReplaceInTakingStringBuilderWithNull() { |
| final Map<String, Object> map = new HashMap<>(); |
| final StrSubstitutor strSubstitutor = new StrSubstitutor(map, "", "", 'T', "K+<'f"); |
| |
| assertFalse(strSubstitutor.replaceIn((StringBuilder) null)); |
| } |
| |
| @Test |
| public void testReplaceInTakingTwoAndThreeIntsReturningFalse() { |
| final Map<String, Object> hashMap = new HashMap<>(); |
| final StrLookup.MapStrLookup<Object> strLookupMapStrLookup = new StrLookup.MapStrLookup<>(hashMap); |
| final StrMatcher strMatcher = StrMatcher.tabMatcher(); |
| final StrSubstitutor strSubstitutor = |
| new StrSubstitutor(strLookupMapStrLookup, strMatcher, strMatcher, 'b', strMatcher); |
| |
| assertFalse(strSubstitutor.replaceIn((StringBuilder) null, 1315, (-1369))); |
| assertEquals('b', strSubstitutor.getEscapeChar()); |
| assertFalse(strSubstitutor.isPreserveEscapes()); |
| } |
| |
| /** |
| * Tests whether a variable can be replaced in a variable name. |
| */ |
| @Test |
| public void testReplaceInVariable() { |
| values.put("animal.1", "fox"); |
| values.put("animal.2", "mouse"); |
| values.put("species", "2"); |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| sub.setEnableSubstitutionInVariables(true); |
| assertEquals( |
| "The mouse jumps over the lazy dog.", |
| sub.replace("The ${animal.${species}} jumps over the ${target}.")); |
| values.put("species", "1"); |
| assertEquals( |
| "The fox jumps over the lazy dog.", |
| sub.replace("The ${animal.${species}} jumps over the ${target}.")); |
| assertEquals( |
| "The fox jumps over the lazy dog.", |
| sub.replace("The ${unknown.animal.${unknown.species:-1}:-fox} " |
| + "jumps over the ${unknow.target:-lazy dog}.")); |
| } |
| |
| /** |
| * Tests whether substitution in variable names is disabled per default. |
| */ |
| @Test |
| public void testReplaceInVariableDisabled() { |
| values.put("animal.1", "fox"); |
| values.put("animal.2", "mouse"); |
| values.put("species", "2"); |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| assertEquals( |
| "The ${animal.${species}} jumps over the lazy dog.", |
| sub.replace("The ${animal.${species}} jumps over the ${target}.")); |
| assertEquals( |
| "The ${animal.${species:-1}} jumps over the lazy dog.", |
| sub.replace("The ${animal.${species:-1}} jumps over the ${target}.")); |
| } |
| |
| /** |
| * Tests complex and recursive substitution in variable names. |
| */ |
| @Test |
| public void testReplaceInVariableRecursive() { |
| values.put("animal.2", "brown fox"); |
| values.put("animal.1", "white mouse"); |
| values.put("color", "white"); |
| values.put("species.white", "1"); |
| values.put("species.brown", "2"); |
| final StrSubstitutor sub = new StrSubstitutor(values); |
| sub.setEnableSubstitutionInVariables(true); |
| assertEquals( |
| "The white mouse jumps over the lazy dog.", |
| sub.replace("The ${animal.${species.${color}}} jumps over the ${target}.")); |
| assertEquals( |
| "The brown fox jumps over the lazy dog.", |
| sub.replace("The ${animal.${species.${unknownColor:-brown}}} jumps over the ${target}.")); |
| } |
| |
| /** |
| * Tests when no prefix or suffix. |
| */ |
| @Test |
| public void testReplaceNoPrefixNoSuffix() { |
| doTestReplace("The animal jumps over the lazy dog.", "The animal jumps over the ${target}.", true); |
| } |
| |
| /** |
| * Tests when suffix but no prefix. |
| */ |
| @Test |
| public void testReplaceNoPrefixSuffix() { |
| doTestReplace("The animal} jumps over the lazy dog.", "The animal} jumps over the ${target}.", true); |
| } |
| |
| /** |
| * Tests replace with no variables. |
| */ |
| @Test |
| public void testReplaceNoVariables() { |
| doTestNoReplace("The balloon arrived."); |
| } |
| |
| /** |
| * Tests replace with null. |
| */ |
| @Test |
| public void testReplaceNull() { |
| doTestNoReplace(null); |
| } |
| |
| /** |
| * Tests simple key replace. |
| */ |
| @Test |
| public void testReplacePartialString_noReplace() { |
| final StrSubstitutor sub = new StrSubstitutor(); |
| assertEquals("${animal} jumps", sub.replace("The ${animal} jumps over the ${target}.", 4, 15)); |
| } |
| |
| /** |
| * Tests when prefix but no suffix. |
| */ |
| @Test |
| public void testReplacePrefixNoSuffix() { |
| doTestReplace("The ${animal jumps over the ${target} lazy dog.", |
| "The ${animal jumps over the ${target} ${target}.", true); |
| } |
| |
| /** |
| * Tests simple recursive replace. |
| */ |
| @Test |
| public void testReplaceRecursive() { |
| values.put("animal", "${critter}"); |
| values.put("target", "${pet}"); |
| values.put("pet", "${petCharacteristic} dog"); |
| values.put("petCharacteristic", "lazy"); |
| values.put("critter", "${critterSpeed} ${critterColor} ${critterType}"); |
| values.put("critterSpeed", "quick"); |
| values.put("critterColor", "brown"); |
| values.put("critterType", "fox"); |
| doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true); |
| |
| values.put("pet", "${petCharacteristicUnknown:-lazy} dog"); |
| doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true); |
| } |
| |
| //----------------------------------------------------------------------- |
| /** |
| * Tests simple key replace. |
| */ |
| @Test |
| public void testReplaceSimple() { |
| doTestReplace("The quick brown fox jumps over the lazy dog.", "The ${animal} jumps over the ${target}.", true); |
| } |
| |
| /** |
| * Tests simple key replace. |
| */ |
| @Test |
| public void testReplaceSolo() { |
| doTestReplace("quick brown fox", "${animal}", false); |
| } |
| |
| /** |
| * Tests escaping. |
| */ |
| @Test |
| public void testReplaceSoloEscaping() { |
| doTestReplace("${animal}", "$${animal}", false); |
| } |
| |
| @Test |
| public void testReplaceTakingCharSequenceReturningNull() { |
| final StrSubstitutor strSubstitutor = new StrSubstitutor((StrLookup<?>) null); |
| |
| assertNull(strSubstitutor.replace((CharSequence) null)); |
| assertFalse(strSubstitutor.isPreserveEscapes()); |
| assertEquals('$', strSubstitutor.getEscapeChar()); |
| } |
| |
| @Test |
| public void testReplaceTakingThreeArgumentsThrowsNullPointerException() { |
| assertThatNullPointerException().isThrownBy(() -> StrSubstitutor.replace(null, (Properties) null)); |
| } |
| |
| /** |
| * Tests replace creates output same as input. |
| */ |
| @Test |
| public void testReplaceToIdentical() { |
| values.put("animal", "$${${thing}}"); |
| values.put("thing", "animal"); |
| doTestReplace("The ${animal} jumps.", "The ${animal} jumps.", true); |
| } |
| |
| /** |
| * Tests unknown key replace. |
| */ |
| @Test |
| public void testReplaceUnknownKey() { |
| doTestReplace("The ${person} jumps over the lazy dog.", "The ${person} jumps over the ${target}.", true); |
| doTestReplace("The ${person} jumps over the lazy dog. 1234567890.", |
| "The ${person} jumps over the ${target}. ${undefined.number:-1234567890}.", true); |
| } |
| |
| /** |
| * Tests interpolation with weird boundary patterns. |
| */ |
| @Test |
| public void testReplaceWeirdPattens() { |
| doTestNoReplace(""); |
| doTestNoReplace("${}"); |
| doTestNoReplace("${ }"); |
| doTestNoReplace("${\t}"); |
| doTestNoReplace("${\n}"); |
| doTestNoReplace("${\b}"); |
| doTestNoReplace("${"); |
| doTestNoReplace("$}"); |
| doTestNoReplace("}"); |
| doTestNoReplace("${}$"); |
| doTestNoReplace("${${"); |
| doTestNoReplace("${${}}"); |
| doTestNoReplace("${$${}}"); |
| doTestNoReplace("${$$${}}"); |
| doTestNoReplace("${$$${$}}"); |
| doTestNoReplace("${${}}"); |
| doTestNoReplace("${${ }}"); |
| } |
| |
| //----------------------------------------------------------------------- |
| /** |
| * Tests protected. |
| */ |
| @Test |
| public void testResolveVariable() { |
| final StrBuilder builder = new StrBuilder("Hi ${name}!"); |
| final Map<String, String> map = new HashMap<>(); |
| map.put("name", "commons"); |
| final StrSubstitutor sub = new StrSubstitutor(map) { |
| @Override |
| protected String resolveVariable(final String variableName, final StrBuilder buf, final int startPos, |
| final int endPos) { |
| assertEquals("name", variableName); |
| assertSame(builder, buf); |
| assertEquals(3, startPos); |
| assertEquals(10, endPos); |
| return "jakarta"; |
| } |
| }; |
| sub.replaceIn(builder); |
| assertEquals("Hi jakarta!", builder.toString()); |
| } |
| |
| @Test |
| public void testSamePrefixAndSuffix() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("greeting", "Hello"); |
| map.put(" there ", "XXX"); |
| map.put("name", "commons"); |
| assertEquals("Hi commons!", StrSubstitutor.replace("Hi @name@!", map, "@", "@")); |
| assertEquals("Hello there commons!", StrSubstitutor.replace("@greeting@ there @name@!", map, "@", "@")); |
| } |
| |
| //----------------------------------------------------------------------- |
| /** |
| * Tests static. |
| */ |
| @Test |
| public void testStaticReplace() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("name", "commons"); |
| assertEquals("Hi commons!", StrSubstitutor.replace("Hi ${name}!", map)); |
| } |
| |
| /** |
| * Tests static. |
| */ |
| @Test |
| public void testStaticReplacePrefixSuffix() { |
| final Map<String, String> map = new HashMap<>(); |
| map.put("name", "commons"); |
| assertEquals("Hi commons!", StrSubstitutor.replace("Hi <name>!", map, "<", ">")); |
| } |
| |
| /** |
| * Tests interpolation with system properties. |
| */ |
| @Test |
| public void testStaticReplaceSystemProperties() { |
| final StrBuilder buf = new StrBuilder(); |
| buf.append("Hi ").append(System.getProperty("user.name")); |
| buf.append(", you are working with "); |
| buf.append(System.getProperty("os.name")); |
| buf.append(", your home directory is "); |
| buf.append(System.getProperty("user.home")).append('.'); |
| assertEquals(buf.toString(), StrSubstitutor.replaceSystemProperties("Hi ${user.name}, you are " |
| + "working with ${os.name}, your home " |
| + "directory is ${user.home}.")); |
| } |
| |
| /** |
| * Test the replace of a properties object |
| */ |
| @Test |
| public void testSubstituteDefaultProperties() { |
| final String org = "${doesnotwork}"; |
| System.setProperty("doesnotwork", "It works!"); |
| |
| // create a new Properties object with the System.getProperties as default |
| final Properties props = new Properties(System.getProperties()); |
| |
| assertEquals("It works!", StrSubstitutor.replace(org, props)); |
| } |
| |
| @Test |
| public void testSubstitutePreserveEscape() { |
| final String org = "${not-escaped} $${escaped}"; |
| final Map<String, String> map = new HashMap<>(); |
| map.put("not-escaped", "value"); |
| |
| final StrSubstitutor sub = new StrSubstitutor(map, "${", "}", '$'); |
| assertFalse(sub.isPreserveEscapes()); |
| assertEquals("value ${escaped}", sub.replace(org)); |
| |
| sub.setPreserveEscapes(true); |
| assertTrue(sub.isPreserveEscapes()); |
| assertEquals("value $${escaped}", sub.replace(org)); |
| } |
| |
| } |