| /* |
| * 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()); |
| } |
| |
| } |