blob: 9a56f1359047344e1118844a703c11f7b4b9d46c [file] [log] [blame]
package freemarker.core;
import static freemarker.template.Configuration.*;
import static org.junit.Assert.*;
import java.io.StringWriter;
import org.junit.Test;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.test.TemplateTest;
public class InterpolationSyntaxTest extends TemplateTest {
@Test
public void legacyInterpolationSyntaxTest() throws Exception {
// The default is: getConfiguration().setInterpolationSyntax(Configuration.LEGACY_INTERPOLATION_SYNTAX);
assertOutput("${1} #{1} [=1]", "1 1 [=1]");
assertOutput(
"${{'x': 1}['x']} #{{'x': 1}['x']} [={'x': 1}['x']]",
"1 1 [={'x': 1}['x']]");
assertOutput("${'a[=1]b'}", "a[=1]b");
assertOutput("${'a${1}#{2}b'}", "a12b");
assertOutput("${'a${1}#{2}b[=3]'}", "a12b[=3]");
assertOutput("<@r'${1} #{1} [=1]'?interpret />", "1 1 [=1]");
assertOutput("${'\"${1} #{1} [=1]\"'?eval}", "1 1 [=1]");
assertOutput("<#setting booleanFormat='y,n'>${2>1}", "y"); // Not an error since 2.3.28
assertOutput("[#ftl][#setting booleanFormat='y,n']${2>1}", "y"); // Not an error since 2.3.28
}
@Test
public void dollarInterpolationSyntaxTest() throws Exception {
getConfiguration().setInterpolationSyntax(DOLLAR_INTERPOLATION_SYNTAX);
assertOutput("${1} #{1} [=1]", "1 #{1} [=1]");
assertOutput(
"${{'x': 1}['x']} #{{'x': 1}['x']} [={'x': 1}['x']]",
"1 #{{'x': 1}['x']} [={'x': 1}['x']]");
assertOutput("${'a[=1]b'}", "a[=1]b");
assertOutput("${'a${1}#{2}b'}", "a1#{2}b");
assertOutput("${'a${1}#{2}b[=3]'}", "a1#{2}b[=3]");
assertOutput("<@r'${1} #{1} [=1]'?interpret />", "1 #{1} [=1]");
assertOutput("${'\"${1} #{1} [=1]\"'?eval}", "1 #{1} [=1]");
}
@Test
public void squareBracketInterpolationSyntaxTest() throws Exception {
getConfiguration().setInterpolationSyntax(SQUARE_BRACKET_INTERPOLATION_SYNTAX);
assertOutput("${1} #{1} [=1]", "${1} #{1} 1");
assertOutput(
"${{'x': 1}['x']} #{{'x': 1}['x']} [={'x': 1}['x']]",
"${{'x': 1}['x']} #{{'x': 1}['x']} 1");
assertOutput("[=1]][=2]]", "1]2]");
assertOutput("[= 1 ][= <#-- c --> 2 <#-- c --> ]", "12");
assertOutput("[ =1]", "[ =1]");
// Legacy tag closing glitch is not emulated with this:
assertErrorContains("<#if [true][0]]></#if>", "\"]\"", "nothing open");
getConfiguration().setTagSyntax(SQUARE_BRACKET_TAG_SYNTAX);
assertOutput("[#if [true][0]]>[/#if]", ">");
assertOutput("[=1][=2]${3}", "12${3}");
getConfiguration().setTagSyntax(ANGLE_BRACKET_TAG_SYNTAX);
assertOutput("[#ftl][#if [true][0]]>[/#if]", ">");
assertOutput("[#ftl][=1][=2]${3}", "12${3}");
assertOutput("[='a[=1]b']", "a1b");
assertOutput("[='a${1}#{2}b']", "a${1}#{2}b");
assertOutput("[='a${1}#{2}b[=3]']", "a${1}#{2}b3");
assertOutput("<@r'${1} #{1} [=1]'?interpret />", "${1} #{1} 1");
assertOutput("[='\"${1} #{1} [=1]\"'?eval]", "${1} #{1} 1");
assertErrorContains("[=", "end of file");
assertErrorContains("[=1", "unclosed \"[\"");
assertOutput("<#setting booleanFormat='y,n'>[=2>1]", "y");
assertOutput("[#ftl][#setting booleanFormat='y,n'][=2>1]", "y");
assertOutput("[='[\\=1]']", "[=1]");
assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation escaping glitch...
assertOutput("[=r'[=1]']", "[=1]");
StringWriter sw = new StringWriter();
new Template(null, "[= 1 + '[= 2 ]' ]", getConfiguration()).dump(sw);
assertEquals("[=1 + \"[=2]\"]", sw.toString());
}
@Test
public void squareBracketTagSyntaxStillWorks() throws Exception {
getConfiguration().setTagSyntax(SQUARE_BRACKET_TAG_SYNTAX);
for (int syntax : new int[] {
LEGACY_INTERPOLATION_SYNTAX, DOLLAR_INTERPOLATION_SYNTAX, SQUARE_BRACKET_INTERPOLATION_SYNTAX }) {
assertOutput("[#if [true][0]]t[#else]f[/#if]", "t");
assertOutput("[@r'[#if [true][0]]t[#else]f[/#if]'?interpret /]", "t");
}
}
@Test
public void legacyTagSyntaxGlitchStillWorksTest() throws Exception {
String badFtl1 = "<#if [true][0]]OK</#if>";
String badFtl2 = "<#if true>OK</#if]";
String badFtl3 = "<#assign x = 'OK'/]${x}";
String badFtl4 = " <#t/]OK\n";
getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_27);
for (int syntax : new int[] { LEGACY_INTERPOLATION_SYNTAX, DOLLAR_INTERPOLATION_SYNTAX }) {
getConfiguration().setInterpolationSyntax(syntax);
assertOutput(badFtl1, "OK");
assertOutput(badFtl2, "OK");
assertOutput(badFtl3, "OK");
assertOutput(badFtl4, "OK");
}
// Legacy tag closing glitch is not emulated with this:
getConfiguration().setInterpolationSyntax(SQUARE_BRACKET_INTERPOLATION_SYNTAX);
assertErrorContains(badFtl1, "\"]\"");
assertErrorContains(badFtl2, "\"]\"");
assertErrorContains(badFtl3, "\"]\"");
assertErrorContains(badFtl4, "\"]\"");
getConfiguration().setInterpolationSyntax(LEGACY_INTERPOLATION_SYNTAX);
getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_28);
assertErrorContains(badFtl1, "\"]\"");
assertErrorContains(badFtl2, "\"]\"");
assertErrorContains(badFtl3, "\"]\"");
assertErrorContains(badFtl4, "\"]\"");
}
@Test
public void errorMessagesAreSquareBracketInterpolationSyntaxAwareTest() throws Exception {
assertErrorContains("<#if ${x}></#if>", "${...}", "${myExpression}");
assertErrorContains("<#if #{x}></#if>", "#{...}", "#{myExpression}");
assertErrorContains("<#if [=x]></#if>", "[=...]", "[=myExpression]");
}
@Test
public void unclosedSyntaxErrorTest() throws Exception {
assertErrorContains("${1", "unclosed \"{\"");
getConfiguration().setInterpolationSyntax(SQUARE_BRACKET_INTERPOLATION_SYNTAX);
assertErrorContains("[=1", "unclosed \"[\"");
}
}