blob: 1a51178e04e27bc79836cb3733af7dc0296d3991 [file] [log] [blame]
/*
* 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 freemarker.core;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import junit.framework.TestCase;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.utility.StringUtil;
/**
* Test various generated templates (permutations), including some deliberately
* wrong ones, with various tag_syntax settings.
*/
public class TagSyntaxVariationsTest extends TestCase {
private static final String HDR_ANG = "<#ftl>";
private static final String HDR_SQU = squarify(HDR_ANG);
private static final String IF_ANG = "<#if true>i</#if>";
private static final String IF_SQU = squarify(IF_ANG);
private static final String IF_OUT = "i";
private static final String ASSIGN_ANG = "<#assign x = 1>a";
private static final String ASSIGN_SQU = squarify(ASSIGN_ANG);
private static final String ASSIGN_OUT = "a";
private static final String WRONG_ANG = "<#wrong>";
private static final String WRONG_SQU = squarify(WRONG_ANG);
private static final String WRONGC_ANG = "</#wrong>";
private static final String WRONGC_SQU = squarify(WRONGC_ANG );
private static final String CUST_ANG = "<@compress> z </@>";
private static final String CUST_SQU = squarify(CUST_ANG);
private static final String CUST_OUT = "z";
public TagSyntaxVariationsTest(String name) {
super(name);
}
private static String squarify(String s) {
return s.replace('<', '[').replace('>', ']');
}
public final void test()
throws TemplateException, IOException {
Configuration cfgBuggy = new Configuration();
// Default on 2.3.x: cfgBuggy.setEmulate23ParserBugs(true);
// Default on 2.3.x: cfgBuggy.setTagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX);
Configuration cfgFixed = new Configuration();
cfgFixed.setIncompatibleImprovements(Configuration.VERSION_2_3_19);
// Default on 2.3.x: cfgFixed.setTagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX);
// Permutations
for (int ifOrAssign = 0; ifOrAssign < 2; ifOrAssign++) {
String dir_ang = ifOrAssign == 0 ? IF_ANG : ASSIGN_ANG;
String dir_squ = ifOrAssign == 0 ? IF_SQU : ASSIGN_SQU;
String dir_out = ifOrAssign == 0 ? IF_OUT : ASSIGN_OUT;
// Permutations
for (int angOrSqu = 0; angOrSqu < 2; angOrSqu++) {
cfgBuggy.setTagSyntax(angOrSqu == 0
? Configuration.ANGLE_BRACKET_TAG_SYNTAX
: Configuration.SQUARE_BRACKET_TAG_SYNTAX);
cfgFixed.setTagSyntax(angOrSqu == 0
? Configuration.ANGLE_BRACKET_TAG_SYNTAX
: Configuration.SQUARE_BRACKET_TAG_SYNTAX);
String dir_xxx = angOrSqu == 0 ? dir_ang : dir_squ;
String cust_xxx = angOrSqu == 0 ? CUST_ANG : CUST_SQU;
String hdr_xxx = angOrSqu == 0 ? HDR_ANG : HDR_SQU;
String wrong_xxx = angOrSqu == 0 ? WRONG_ANG : WRONG_SQU;
String wrongc_xxx = angOrSqu == 0 ? WRONGC_ANG : WRONGC_SQU;
test(cfgBuggy,
dir_xxx + cust_xxx,
dir_out + CUST_OUT);
test(cfgFixed,
dir_xxx + cust_xxx,
dir_out + CUST_OUT);
// Permutations
for (int wrongOrWrongc = 0; wrongOrWrongc < 2; wrongOrWrongc++) {
String wrongx_xxx = wrongOrWrongc == 0 ? wrong_xxx : wrongc_xxx;
// Bug: initial unknown # tags are treated as static text
test(cfgBuggy,
wrongx_xxx + dir_xxx,
wrongx_xxx + dir_out);
test(cfgFixed,
wrongx_xxx + dir_xxx,
null);
// Bug: same as above
test(cfgBuggy,
wrongx_xxx + wrongx_xxx + dir_xxx,
wrongx_xxx + wrongx_xxx + dir_out);
test(cfgBuggy,
dir_xxx + wrongx_xxx,
null);
test(cfgFixed,
dir_xxx + wrongx_xxx,
null);
test(cfgBuggy,
hdr_xxx + wrongx_xxx,
null);
test(cfgFixed,
hdr_xxx + wrongx_xxx,
null);
test(cfgBuggy,
cust_xxx + wrongx_xxx + dir_xxx,
null);
test(cfgFixed,
cust_xxx + wrongx_xxx + dir_xxx,
null);
} // for wrongc
} // for squ
cfgBuggy.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
cfgFixed.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
for (int perm = 0; perm < 4; perm++) {
// All 4 permutations
String wrong_xxx = (perm & 1) == 0 ? WRONG_ANG : WRONG_SQU;
String dir_xxx = (perm & 2) == 0 ? dir_ang : dir_squ;
// Bug: Auto-detection ignores unknown # tags
test(cfgBuggy,
wrong_xxx + dir_xxx,
wrong_xxx + dir_out);
test(cfgFixed,
wrong_xxx + dir_xxx,
null);
// Bug: same as above
test(cfgBuggy,
wrong_xxx + wrong_xxx + dir_xxx,
wrong_xxx + wrong_xxx + dir_out);
} // for perm
// Permutations
for (int angOrSquStart = 0; angOrSquStart < 2; angOrSquStart++) {
String hdr_xxx = angOrSquStart == 0 ? HDR_ANG : HDR_SQU;
String cust_xxx = angOrSquStart == 0 ? CUST_ANG : CUST_SQU;
String wrong_yyy = angOrSquStart != 0 ? WRONG_ANG : WRONG_SQU;
String dir_xxx = angOrSquStart == 0 ? dir_ang : dir_squ;
String dir_yyy = angOrSquStart != 0 ? dir_ang : dir_squ;
test(cfgBuggy,
cust_xxx + wrong_yyy + dir_xxx,
CUST_OUT + wrong_yyy + dir_out);
test(cfgFixed,
cust_xxx + wrong_yyy + dir_xxx,
CUST_OUT + wrong_yyy + dir_out);
test(cfgBuggy,
hdr_xxx + wrong_yyy + dir_xxx,
wrong_yyy + dir_out);
test(cfgFixed,
hdr_xxx + wrong_yyy + dir_xxx,
wrong_yyy + dir_out);
test(cfgBuggy,
cust_xxx + wrong_yyy + dir_yyy,
CUST_OUT + wrong_yyy + dir_yyy);
test(cfgFixed,
cust_xxx + wrong_yyy + dir_yyy,
CUST_OUT + wrong_yyy + dir_yyy);
test(cfgBuggy,
hdr_xxx + wrong_yyy + dir_yyy,
wrong_yyy + dir_yyy);
test(cfgFixed,
hdr_xxx + wrong_yyy + dir_yyy,
wrong_yyy + dir_yyy);
test(cfgBuggy,
dir_xxx + wrong_yyy + dir_yyy,
dir_out + wrong_yyy + dir_yyy);
test(cfgFixed,
dir_xxx + wrong_yyy + dir_yyy,
dir_out + wrong_yyy + dir_yyy);
} // for squStart
} // for assign
}
/**
* @param expected the expected output or <tt>null</tt> if we expect
* a parsing error.
*/
private static final void test(
Configuration cfg, String template, String expected)
throws TemplateException, IOException {
Template t = null;
try {
t = new Template("string", new StringReader(template), cfg);
} catch (ParseException e) {
if (expected != null) {
fail("Couldn't create Template from "
+ StringUtil.jQuote(template) + ": " + e);
} else {
return;
}
}
if (expected == null) fail("Template parsing should have fail for "
+ StringUtil.jQuote(template));
StringWriter out = new StringWriter();
t.process(new Object(), out);
assertEquals(expected, out.toString());
}
}