View Javadoc
1   package org.codehaus.plexus.interpolation;
2   
3   /*
4    * Copyright 2001-2008 Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.IOException;
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  import org.codehaus.plexus.interpolation.os.OperatingSystemUtils;
28  import org.junit.jupiter.api.BeforeEach;
29  import org.junit.jupiter.api.Test;
30  
31  import static org.junit.jupiter.api.Assertions.assertEquals;
32  import static org.junit.jupiter.api.Assertions.fail;
33  
34  public class StringSearchInterpolatorTest {
35  
36      @BeforeEach
37      public void setUp() {
38          EnvarBasedValueSource.resetStatics();
39      }
40  
41      @Test
42      public void testLongDelimitersInContext() throws InterpolationException {
43          String src = "This is a <expression>test.label</expression> for long delimiters in context.";
44          String result = "This is a test for long delimiters in context.";
45  
46          Properties p = new Properties();
47          p.setProperty("test.label", "test");
48  
49          StringSearchInterpolator interpolator = new StringSearchInterpolator("<expression>", "</expression>");
50          interpolator.addValueSource(new PropertiesBasedValueSource(p));
51  
52          assertEquals(result, interpolator.interpolate(src));
53      }
54  
55      @Test
56      public void testLongDelimitersWithNoStartContext() throws InterpolationException {
57          String src = "<expression>test.label</expression> for long delimiters in context.";
58          String result = "test for long delimiters in context.";
59  
60          Properties p = new Properties();
61          p.setProperty("test.label", "test");
62  
63          StringSearchInterpolator interpolator = new StringSearchInterpolator("<expression>", "</expression>");
64          interpolator.addValueSource(new PropertiesBasedValueSource(p));
65  
66          assertEquals(result, interpolator.interpolate(src));
67      }
68  
69      @Test
70      public void testLongDelimitersWithNoEndContext() throws InterpolationException {
71          String src = "This is a <expression>test.label</expression>";
72          String result = "This is a test";
73  
74          Properties p = new Properties();
75          p.setProperty("test.label", "test");
76  
77          StringSearchInterpolator interpolator = new StringSearchInterpolator("<expression>", "</expression>");
78          interpolator.addValueSource(new PropertiesBasedValueSource(p));
79  
80          assertEquals(result, interpolator.interpolate(src));
81      }
82  
83      @Test
84      public void testLongDelimitersWithNoContext() throws InterpolationException {
85          String src = "<expression>test.label</expression>";
86          String result = "test";
87  
88          Properties p = new Properties();
89          p.setProperty("test.label", "test");
90  
91          StringSearchInterpolator interpolator = new StringSearchInterpolator("<expression>", "</expression>");
92          interpolator.addValueSource(new PropertiesBasedValueSource(p));
93  
94          assertEquals(result, interpolator.interpolate(src));
95      }
96  
97      @Test
98      public void testSimpleSubstitution() throws InterpolationException {
99          Properties p = new Properties();
100         p.setProperty("key", "value");
101 
102         StringSearchInterpolator interpolator = new StringSearchInterpolator();
103         interpolator.addValueSource(new PropertiesBasedValueSource(p));
104 
105         assertEquals("This is a test value.", interpolator.interpolate("This is a test ${key}."));
106     }
107 
108     @Test
109     public void testSimpleSubstitution_TwoExpressions() throws InterpolationException {
110         Properties p = new Properties();
111         p.setProperty("key", "value");
112         p.setProperty("key2", "value2");
113 
114         StringSearchInterpolator interpolator = new StringSearchInterpolator();
115         interpolator.addValueSource(new PropertiesBasedValueSource(p));
116 
117         assertEquals("value-value2", interpolator.interpolate("${key}-${key2}"));
118     }
119 
120     @Test
121     public void testBrokenExpression_LeaveItAlone() throws InterpolationException {
122         Properties p = new Properties();
123         p.setProperty("key", "value");
124 
125         StringSearchInterpolator interpolator = new StringSearchInterpolator();
126         interpolator.addValueSource(new PropertiesBasedValueSource(p));
127 
128         assertEquals("This is a test ${key.", interpolator.interpolate("This is a test ${key."));
129     }
130 
131     @Test
132     public void testShouldFailOnExpressionCycle() {
133         Properties props = new Properties();
134         props.setProperty("key1", "${key2}");
135         props.setProperty("key2", "${key1}");
136 
137         StringSearchInterpolator rbi = new StringSearchInterpolator();
138         rbi.addValueSource(new PropertiesBasedValueSource(props));
139 
140         try {
141             rbi.interpolate("${key1}", new SimpleRecursionInterceptor());
142 
143             fail("Should detect expression cycle and fail.");
144         } catch (InterpolationException e) {
145             // expected
146         }
147     }
148 
149     @Test
150     public void testShouldResolveByUsingObject_List_Map() throws InterpolationException {
151         StringSearchInterpolator rbi = new StringSearchInterpolator();
152         rbi.addValueSource(new ObjectBasedValueSource(this));
153         String result =
154                 rbi.interpolate("this is a ${var} ${list[1].name} ${anArray[2].name} ${map(Key with spaces).name}");
155 
156         assertEquals("this is a testVar testIndexedWithList testIndexedWithArray testMap", result);
157     }
158 
159     @Test
160     public void testShouldResolveByContextValue() throws InterpolationException {
161         StringSearchInterpolator rbi = new StringSearchInterpolator();
162 
163         Map context = new HashMap();
164         context.put("var", "testVar");
165 
166         rbi.addValueSource(new MapBasedValueSource(context));
167 
168         String result = rbi.interpolate("this is a ${var}");
169 
170         assertEquals("this is a testVar", result);
171     }
172 
173     @Test
174     public void testShouldResolveByEnvar() throws IOException, InterpolationException {
175         OperatingSystemUtils.setEnvVarSource(new OperatingSystemUtils.EnvVarSource() {
176             public Map<String, String> getEnvMap() {
177                 HashMap<String, String> map = new HashMap<String, String>();
178                 map.put("SOME_ENV", "variable");
179                 map.put("OTHER_ENV", "other variable");
180                 return map;
181             }
182         });
183 
184         StringSearchInterpolator rbi = new StringSearchInterpolator();
185 
186         rbi.addValueSource(new EnvarBasedValueSource(false));
187 
188         String result = rbi.interpolate("this is a ${env.SOME_ENV} ${env.OTHER_ENV}");
189 
190         assertEquals("this is a variable other variable", result);
191     }
192 
193     @Test
194     public void testUsePostProcessor_DoesNotChangeValue() throws InterpolationException {
195         StringSearchInterpolator rbi = new StringSearchInterpolator();
196 
197         Map context = new HashMap();
198         context.put("test.var", "testVar");
199 
200         rbi.addValueSource(new MapBasedValueSource(context));
201 
202         rbi.addPostProcessor(new InterpolationPostProcessor() {
203             public Object execute(String expression, Object value) {
204                 return null;
205             }
206         });
207 
208         String result = rbi.interpolate("this is a ${test.var}");
209 
210         assertEquals("this is a testVar", result);
211     }
212 
213     @Test
214     public void testUsePostProcessor_ChangesValue() throws InterpolationException {
215 
216         StringSearchInterpolator rbi = new StringSearchInterpolator();
217 
218         Map context = new HashMap();
219         context.put("test.var", "testVar");
220 
221         rbi.addValueSource(new MapBasedValueSource(context));
222 
223         rbi.addPostProcessor(new InterpolationPostProcessor() {
224             public Object execute(String expression, Object value) {
225                 return value + "2";
226             }
227         });
228 
229         String result = rbi.interpolate("this is a ${test.var}");
230 
231         assertEquals("this is a testVar2", result);
232     }
233 
234     @Test
235     public void testSimpleSubstitutionWithDefinedExpr() throws InterpolationException {
236         Properties p = new Properties();
237         p.setProperty("key", "value");
238 
239         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
240         interpolator.addValueSource(new PropertiesBasedValueSource(p));
241 
242         assertEquals("This is a test value.", interpolator.interpolate("This is a test @{key}."));
243     }
244 
245     @Test
246     public void testEscape() throws InterpolationException {
247         Properties p = new Properties();
248         p.setProperty("key", "value");
249 
250         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
251         interpolator.setEscapeString("\\");
252         interpolator.addValueSource(new PropertiesBasedValueSource(p));
253 
254         String result = interpolator.interpolate("This is a test \\@{key}.");
255 
256         assertEquals("This is a test @{key}.", result);
257     }
258 
259     @Test
260     public void testEscapeWithLongEscapeStr() throws InterpolationException {
261         Properties p = new Properties();
262         p.setProperty("key", "value");
263 
264         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
265         interpolator.setEscapeString("$$");
266         interpolator.addValueSource(new PropertiesBasedValueSource(p));
267 
268         String result = interpolator.interpolate("This is a test $$@{key}.");
269 
270         assertEquals("This is a test @{key}.", result);
271     }
272 
273     @Test
274     public void testEscapeWithLongEscapeStrAtStart() throws InterpolationException {
275         Properties p = new Properties();
276         p.setProperty("key", "value");
277 
278         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
279         interpolator.setEscapeString("$$");
280         interpolator.addValueSource(new PropertiesBasedValueSource(p));
281 
282         String result = interpolator.interpolate("$$@{key} This is a test.");
283 
284         assertEquals("@{key} This is a test.", result);
285     }
286 
287     @Test
288     public void testNotEscapeWithLongEscapeStrAtStart() throws InterpolationException {
289         Properties p = new Properties();
290         p.setProperty("key", "value");
291 
292         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
293         interpolator.setEscapeString("$$");
294         interpolator.addValueSource(new PropertiesBasedValueSource(p));
295 
296         String result = interpolator.interpolate("@{key} This is a test.");
297 
298         assertEquals("value This is a test.", result);
299     }
300 
301     @Test
302     public void testEscapeNotFailWithNullEscapeStr() throws InterpolationException {
303         Properties p = new Properties();
304         p.setProperty("key", "value");
305 
306         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
307         interpolator.setEscapeString(null);
308         interpolator.addValueSource(new PropertiesBasedValueSource(p));
309 
310         String result = interpolator.interpolate("This is a test @{key}.");
311 
312         assertEquals("This is a test value.", result);
313     }
314 
315     @Test
316     public void testOnlyEscapeExprAtStart() throws InterpolationException {
317         Properties p = new Properties();
318         p.setProperty("key", "value");
319 
320         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
321         interpolator.setEscapeString("\\");
322         interpolator.addValueSource(new PropertiesBasedValueSource(p));
323 
324         String result = interpolator.interpolate("\\@{key} This is a test.");
325 
326         assertEquals("@{key} This is a test.", result);
327     }
328 
329     @Test
330     public void testNotEscapeExprAtStart() throws InterpolationException {
331         Properties p = new Properties();
332         p.setProperty("key", "value");
333 
334         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
335         interpolator.setEscapeString("\\");
336         interpolator.addValueSource(new PropertiesBasedValueSource(p));
337 
338         String result = interpolator.interpolate("@{key} This is a test.");
339 
340         assertEquals("value This is a test.", result);
341     }
342 
343     @Test
344     public void testEscapeExprAtStart() throws InterpolationException {
345         Properties p = new Properties();
346         p.setProperty("key", "value");
347 
348         StringSearchInterpolator interpolator = new StringSearchInterpolator("@", "@");
349         interpolator.setEscapeString("\\");
350         interpolator.addValueSource(new PropertiesBasedValueSource(p));
351 
352         String result = interpolator.interpolate("\\@key@ This is a test @key@.");
353 
354         assertEquals("@key@ This is a test value.", result);
355     }
356 
357     @Test
358     public void testNPEFree() throws InterpolationException {
359         Properties p = new Properties();
360         p.setProperty("key", "value");
361 
362         StringSearchInterpolator interpolator = new StringSearchInterpolator("@{", "}");
363         interpolator.setEscapeString("\\");
364         interpolator.addValueSource(new PropertiesBasedValueSource(p));
365 
366         String result = interpolator.interpolate(null);
367 
368         assertEquals("", result);
369     }
370 
371     @Test
372     public void testInterruptedInterpolate() throws InterpolationException {
373         Interpolator interpolator = new StringSearchInterpolator();
374         RecursionInterceptor recursionInterceptor = new SimpleRecursionInterceptor();
375         final boolean[] error = new boolean[] {false};
376         interpolator.addValueSource(new ValueSource() {
377             public Object getValue(String expression) {
378                 if (expression.equals("key")) {
379                     if (error[0]) {
380                         throw new IllegalStateException("broken");
381                     }
382                     return "val";
383                 } else {
384                     return null;
385                 }
386             }
387 
388             public List getFeedback() {
389                 return Collections.EMPTY_LIST;
390             }
391 
392             public void clearFeedback() {}
393         });
394         assertEquals("-val-", interpolator.interpolate("-${key}-", recursionInterceptor), "control case");
395         error[0] = true;
396         try {
397             interpolator.interpolate("-${key}-", recursionInterceptor);
398             fail("should have thrown exception");
399         } catch (IllegalStateException x) {
400             // right
401         }
402         error[0] = false;
403         assertEquals(
404                 "-val-",
405                 interpolator.interpolate("-${key}-", recursionInterceptor),
406                 "should not believe there is a cycle here");
407     }
408 
409     public String getVar() {
410         return "testVar";
411     }
412 
413     public Person[] getAnArray() {
414         Person[] array = new Person[3];
415         array[0] = new Person("Gabriel");
416         array[1] = new Person("Daniela");
417         array[2] = new Person("testIndexedWithArray");
418         return array;
419     }
420 
421     public List<Person> getList() {
422         List<Person> list = new ArrayList<Person>();
423         list.add(new Person("Gabriel"));
424         list.add(new Person("testIndexedWithList"));
425         list.add(new Person("Daniela"));
426         return list;
427     }
428 
429     public Map<String, Person> getMap() {
430         Map<String, Person> map = new HashMap<String, StringSearchInterpolatorTest.Person>();
431         map.put("Key with spaces", new Person("testMap"));
432         return map;
433     }
434 
435     public static class Person {
436         private String name;
437 
438         public Person(String name) {
439             this.name = name;
440         }
441 
442         public String getName() {
443             return name;
444         }
445     }
446 }