1 package org.codehaus.plexus.interpolation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
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 }