Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ private String interpolate(
// but this could result in multiple lookups of stringValue, and replaceAll is not correct behaviour
result = StringUtils.replace(result, wholeExpr, String.valueOf(value));

if (cacheAnswers) {
existingAnswers.put(realExpr, value);
}

matcher.reset(result);
}
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ private String interpolate(String input, RecursionInterceptor recursionIntercept
// behaviour
result.append(String.valueOf(value));
resolved = true;

if (cacheAnswers) {
existingAnswers.put(realExpr, value);
}
} else {
unresolvable.add(wholeExpr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,73 @@ public Object execute(String expression, Object value) {

System.out.println("time with pattern reuse and RegexBasedInterpolator instance reuse " + (end - start));
}

@Test
public void testCacheAnswersTrue() throws InterpolationException {
Map ctx = new HashMap();
ctx.put("key", "value");

final int[] valueSourceCallCount = {0};

ValueSource vs = new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
valueSourceCallCount[0]++;
return ctx.get(expression);
}
};

RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
interpolator.setCacheAnswers(true);
interpolator.addValueSource(vs);

// First interpolation
String result = interpolator.interpolate("${key}-${key}-${key}-${key}");
assertEquals("value-value-value-value", result);
assertEquals(1, valueSourceCallCount[0]);

// Second interpolation - cache should be used, no new ValueSource calls
result = interpolator.interpolate("${key}-${key}-${key}-${key}");
assertEquals("value-value-value-value", result);
assertEquals(1, valueSourceCallCount[0]); // still 1, cache was used

// Third interpolation with different expression that also uses cached value
result = interpolator.interpolate("The value is ${key}");
assertEquals("The value is value", result);
assertEquals(1, valueSourceCallCount[0]); // still 1, cache was used
}

@Test
public void testCacheAnswersFalse() throws InterpolationException {
Map ctx = new HashMap();
ctx.put("key", "value");

final int[] valueSourceCallCount = {0};

ValueSource vs = new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
valueSourceCallCount[0]++;
return ctx.get(expression);
}
};

RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
interpolator.addValueSource(vs);

// First interpolation
String result = interpolator.interpolate("${key}-${key}-${key}-${key}");
assertEquals("value-value-value-value", result);
assertEquals(1, valueSourceCallCount[0]);

// Second interpolation - without caching, ValueSource is called again
result = interpolator.interpolate("${key}-${key}-${key}-${key}");
assertEquals("value-value-value-value", result);
assertEquals(2, valueSourceCallCount[0]); // incremented to 2

// Third interpolation
result = interpolator.interpolate("The value is ${key}");
assertEquals("The value is value", result);
assertEquals(3, valueSourceCallCount[0]); // incremented to 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,62 @@ public Object getValue(String expression) {

assertEquals("test", interpolator.interpolate("#(test)"));
}

@Test
public void testCacheAnswersTrue() throws InterpolationException {
Map ctx = new HashMap();
ctx.put("key", "value");

final int[] valueSourceCallCount = {0};

ValueSource vs = new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
valueSourceCallCount[0]++;
return ctx.get(expression);
}
};

MultiDelimiterStringSearchInterpolator interpolator = new MultiDelimiterStringSearchInterpolator();
interpolator.setCacheAnswers(true);
interpolator.addValueSource(vs);

String result = interpolator.interpolate("${key}-${key}-${key}-${key}");

assertEquals("value-value-value-value", result);
// first value is interpolated and saved, then the 3 next answers came from existing answer Map
assertEquals(1, valueSourceCallCount[0]);

// answers are preserved between calls:
result = interpolator.interpolate("${key}-${key}-${key}-${key}");
assertEquals("value-value-value-value", result);
// still 1 from first call as cache is preserved
assertEquals(1, valueSourceCallCount[0]);
}

@Test
public void testCacheAnswersFalse() throws InterpolationException {
Map ctx = new HashMap();
ctx.put("key", "value");

final int[] valueSourceCallCount = {0};

ValueSource vs = new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
valueSourceCallCount[0]++;
return ctx.get(expression);
}
};

MultiDelimiterStringSearchInterpolator interpolator = new MultiDelimiterStringSearchInterpolator();
interpolator.addValueSource(vs);

String result = interpolator.interpolate("${key}-${key}-${key}-${key}");

assertEquals("value-value-value-value", result);
// Without caching, expressions are evaluated multiple times due to multi-pass resolution
// In this case: 4 expressions evaluated in 2 passes = 8 calls
assertEquals(8, valueSourceCallCount[0]);
}
}