You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/05/15 21:23:50 UTC
[34/51] [abbrv] [partial] incubator-freemarker git commit:
Restructured project so that freemarker-test-utils depends on freemarker-core
(and hence can provide common classes for testing templates,
and can use utility classes defined in the core). As a c
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/Product.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/Product.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/Product.java
new file mode 100644
index 0000000..fcb34e8
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/Product.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.freemarker.manualtest;
+
+/**
+ * Product bean; note that it must be a public class!
+ */
+public class Product {
+
+ private String url;
+ private String name;
+
+ // As per the JavaBeans spec., this defines the "url" bean property
+ // It must be public!
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ // As per the JavaBean spec., this defines the "name" bean property
+ // It must be public!
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
new file mode 100644
index 0000000..8c515bd
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.freemarker.manualtest;
+
+import static org.junit.Assert.*;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateConfiguration;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.PlainTextOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat;
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileExtensionMatcher;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.FirstMatchTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.MergingTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.OrMatcher;
+import org.apache.freemarker.core.templateresolver.PathGlobMatcher;
+import org.apache.freemarker.core.util._DateUtil;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class TemplateConfigurationExamples extends TemplateTest {
+
+ @Test
+ public void example1JavaCfg() throws Exception {
+ example1(true);
+ }
+
+ @Test
+ public void example1PropertiesCfg() throws Exception {
+ example1(false);
+ }
+
+ private void example1(boolean javaCfg) throws Exception {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder(this.getClass());
+ if (javaCfg) {
+ cfgB.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory(
+ new FileExtensionMatcher("xml"),
+ new TemplateConfiguration.Builder()
+ .sourceEncoding(StandardCharsets.UTF_8)
+ .outputFormat(XMLOutputFormat.INSTANCE)
+ .build()));
+
+ } else {
+ cfgB.setTemplateConfigurations(null);
+ cfgB.setSettings(loadPropertiesFile("TemplateConfigurationExamples1.properties"));
+ }
+ setConfiguration(cfgB.build());
+
+ addTemplate("t.xml", "");
+
+ Template t = getConfiguration().getTemplate("t.xml");
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
+ }
+
+ @Test
+ public void example2JavaCfg() throws Exception {
+ example2(true);
+ }
+
+ @Test
+ public void example2PropertiesCfg() throws Exception {
+ example2(false);
+ }
+
+ private void example2(boolean javaCfg) throws Exception {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder(this.getClass());
+ if (javaCfg) {
+ cfgB.setTemplateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new PathGlobMatcher("mail/**"),
+ new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*.subject.*"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(PlainTextOutputFormat.INSTANCE)
+ .build()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*.body.*"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(HTMLOutputFormat.INSTANCE)
+ .build())
+ )
+ .noMatchErrorDetails(
+ "Mail template names must contain \".subject.\" or \".body.\"!")));
+ } else{
+ cfgB.setSettings(loadPropertiesFile("TemplateConfigurationExamples2.properties"));
+ }
+ setConfiguration(cfgB.build());
+
+ addTemplate("t.subject.ftl", "");
+ addTemplate("mail/t.subject.ftl", "");
+ addTemplate("mail/t.body.ftl", "");
+
+ Configuration cfg = getConfiguration();
+ assertEquals(UndefinedOutputFormat.INSTANCE, cfg.getTemplate("t.subject.ftl").getOutputFormat());
+ assertEquals(PlainTextOutputFormat.INSTANCE, cfg.getTemplate("mail/t.subject.ftl").getOutputFormat());
+ assertEquals(HTMLOutputFormat.INSTANCE, cfg.getTemplate("mail/t.body.ftl").getOutputFormat());
+ }
+
+ @Test
+ public void example3JavaCfg() throws Exception {
+ example3(true);
+ }
+
+ @Test
+ public void example3PropertiesCfg() throws Exception {
+ example3(false);
+ }
+
+ private void example3(boolean javaCfg) throws Exception {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder(this.getClass())
+ .sourceEncoding(StandardCharsets.ISO_8859_1);
+ if (javaCfg) {
+ cfgB.setTemplateConfigurations(
+ new MergingTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*.stats.*"),
+ new TemplateConfiguration.Builder()
+ .dateTimeFormat("iso")
+ .dateFormat("iso")
+ .timeFormat("iso")
+ .timeZone(_DateUtil.UTC)
+ .build()),
+ new ConditionalTemplateConfigurationFactory(
+ new PathGlobMatcher("mail/**"),
+ new TemplateConfiguration.Builder()
+ .sourceEncoding(StandardCharsets.UTF_8)
+ .build()),
+ new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileExtensionMatcher("xml"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(XMLOutputFormat.INSTANCE)
+ .build()),
+ new ConditionalTemplateConfigurationFactory(
+ new OrMatcher(
+ new FileExtensionMatcher("html"),
+ new FileExtensionMatcher("htm")),
+ new TemplateConfiguration.Builder()
+ .outputFormat(HTMLOutputFormat.INSTANCE)
+ .build())
+ ).allowNoMatch(true)));
+ } else {
+ cfgB.setSettings(loadPropertiesFile("TemplateConfigurationExamples3.properties"));
+ }
+ setConfiguration(cfgB.build());
+
+ addTemplate("t.stats.html", "${ts?datetime} ${ts?date} ${ts?time}");
+ addTemplate("t.html", "");
+ addTemplate("t.htm", "");
+ addTemplate("t.xml", "");
+ addTemplate("mail/t.html", "");
+
+ addToDataModel("ts", new Date(1440431606011L));
+
+ Configuration cfg = getConfiguration();
+ assertEquals(HTMLOutputFormat.INSTANCE, cfg.getTemplate("t.html").getOutputFormat());
+ assertEquals(StandardCharsets.ISO_8859_1, cfg.getTemplate("t.html").getActualSourceEncoding());
+ assertEquals(HTMLOutputFormat.INSTANCE, cfg.getTemplate("t.htm").getOutputFormat());
+ assertEquals(XMLOutputFormat.INSTANCE, cfg.getTemplate("t.xml").getOutputFormat());
+ assertEquals(HTMLOutputFormat.INSTANCE, cfg.getTemplate("t.stats.html").getOutputFormat());
+ assertOutputForNamed("t.stats.html", "2015-08-24T15:53:26.011Z 2015-08-24 15:53:26.011Z");
+ assertEquals(StandardCharsets.UTF_8, cfg.getTemplate("mail/t.html").getActualSourceEncoding());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
new file mode 100644
index 0000000..89f20fa
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.freemarker.manualtest;
+
+import java.util.Locale;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
+
+/**
+ * A number format that takes any other number format as parameter (specified as a string, as
+ * usual in FreeMarker), then if the model is a {@link UnitAwareTemplateNumberModel}, it shows
+ * the unit after the number formatted with the other format, otherwise it just shows the formatted
+ * number without unit.
+ */
+public class UnitAwareTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
+
+ public static final UnitAwareTemplateNumberFormatFactory INSTANCE
+ = new UnitAwareTemplateNumberFormatFactory();
+
+ private UnitAwareTemplateNumberFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateNumberFormat get(String params, Locale locale, Environment env)
+ throws TemplateValueFormatException {
+ return new UnitAwareNumberFormat(env.getTemplateNumberFormat(params, locale));
+ }
+
+ private static class UnitAwareNumberFormat extends TemplateNumberFormat {
+
+ private final TemplateNumberFormat innerFormat;
+
+ private UnitAwareNumberFormat(TemplateNumberFormat innerFormat) {
+ this.innerFormat = innerFormat;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateNumberModel numberModel)
+ throws TemplateModelException, TemplateValueFormatException {
+ String innerResult = innerFormat.formatToPlainText(numberModel);
+ return numberModel instanceof UnitAwareTemplateNumberModel
+ ? innerResult + " " + ((UnitAwareTemplateNumberModel) numberModel).getUnit()
+ : innerResult;
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return innerFormat.isLocaleBound();
+ }
+
+ @Override
+ public String getDescription() {
+ return "unit-aware " + innerFormat.getDescription();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
new file mode 100644
index 0000000..1e54254
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
@@ -0,0 +1,43 @@
+/*
+ * 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 org.apache.freemarker.manualtest;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+
+public class UnitAwareTemplateNumberModel implements TemplateNumberModel {
+
+ private final Number value;
+ private final String unit;
+
+ public UnitAwareTemplateNumberModel(Number value, String unit) {
+ this.value = value;
+ this.unit = unit;
+ }
+
+ @Override
+ public Number getAsNumber() throws TemplateModelException {
+ return value;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
new file mode 100644
index 0000000..cf3c0f7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
@@ -0,0 +1,515 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.TreeSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.freemarker.core.ASTPrinter;
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.ConfigurationException;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.Version;
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateNodeModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.DefaultNonListCollectionAdapter;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.ResourceBundleModel;
+import org.apache.freemarker.core.model.impl.SimpleCollection;
+import org.apache.freemarker.core.model.impl.SimpleDate;
+import org.apache.freemarker.core.model.impl.SimpleNumber;
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.apache.freemarker.core.util._NullArgumentException;
+import org.apache.freemarker.core.util._NullWriter;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.dom.NodeModel;
+import org.apache.freemarker.test.CopyrightCommentRemoverTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.apache.freemarker.test.templatesuite.models.BooleanAndStringTemplateModel;
+import org.apache.freemarker.test.templatesuite.models.BooleanHash1;
+import org.apache.freemarker.test.templatesuite.models.BooleanHash2;
+import org.apache.freemarker.test.templatesuite.models.BooleanList1;
+import org.apache.freemarker.test.templatesuite.models.BooleanList2;
+import org.apache.freemarker.test.templatesuite.models.BooleanVsStringMethods;
+import org.apache.freemarker.test.templatesuite.models.JavaObjectInfo;
+import org.apache.freemarker.test.templatesuite.models.Listables;
+import org.apache.freemarker.test.templatesuite.models.MultiModel1;
+import org.apache.freemarker.test.templatesuite.models.OverloadedMethods2;
+import org.apache.freemarker.test.templatesuite.models.VarArgTestModel;
+import org.apache.freemarker.test.templateutil.AssertDirective;
+import org.apache.freemarker.test.templateutil.AssertEqualsDirective;
+import org.apache.freemarker.test.templateutil.AssertFailsDirective;
+import org.apache.freemarker.test.FileTestCase;
+import org.apache.freemarker.test.templateutil.NoOutputDirective;
+import org.apache.freemarker.test.XMLLoader;
+import org.junit.Ignore;
+import org.xml.sax.InputSource;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Instances of this are created and called by {@link TemplateTestSuite}. (It's on "Ignore" so that Eclipse doesn't try
+ * to run this alone.)
+ */
+@Ignore
+public class TemplateTestCase extends FileTestCase {
+
+ // Name of variables exposed to all test FTL-s:
+ private static final String ICI_INT_VALUE_VAR_NAME = "iciIntValue";
+ private static final String TEST_NAME_VAR_NAME = "testName";
+ private static final String JAVA_OBJECT_INFO_VAR_NAME = "javaObjectInfo";
+ private static final String NO_OUTPUT_VAR_NAME = "noOutput";
+ private static final String ASSERT_FAILS_VAR_NAME = "assertFails";
+ private static final String ASSERT_EQUALS_VAR_NAME = "assertEquals";
+ private static final String ASSERT_VAR_NAME = "assert";
+
+ private final String simpleTestName;
+ private final String templateName;
+ private final String expectedFileName;
+ private final boolean noOutput;
+
+ private final Configuration.ExtendableBuilder confB;
+ private final HashMap<String, Object> dataModel = new HashMap<>();
+
+ public TemplateTestCase(String testName, String simpleTestName, String templateName, String expectedFileName, boolean noOutput,
+ Version incompatibleImprovements) {
+ super(testName);
+ _NullArgumentException.check("testName", testName);
+
+ _NullArgumentException.check("simpleTestName", simpleTestName);
+ this.simpleTestName = simpleTestName;
+
+ _NullArgumentException.check("templateName", templateName);
+ this.templateName = templateName;
+
+ _NullArgumentException.check("expectedFileName", expectedFileName);
+ this.expectedFileName = expectedFileName;
+
+ this.noOutput = noOutput;
+
+ confB = new TestConfigurationBuilder(incompatibleImprovements);
+ }
+
+ public void setSetting(String param, String value) throws IOException {
+ if ("auto_import".equals(param)) {
+ StringTokenizer st = new StringTokenizer(value);
+ if (!st.hasMoreTokens()) fail("Expecting libname");
+ String libname = st.nextToken();
+ if (!st.hasMoreTokens()) fail("Expecting 'as <alias>' in autoimport");
+ String as = st.nextToken();
+ if (!as.equals("as")) fail("Expecting 'as <alias>' in autoimport");
+ if (!st.hasMoreTokens()) fail("Expecting alias after 'as' in autoimport");
+ String alias = st.nextToken();
+ confB.addAutoImport(alias, libname);
+ } else if ("source_encoding".equals(param)) {
+ confB.setSourceEncoding(Charset.forName(value));
+ // INCOMPATIBLE_IMPROVEMENTS is a list here, and was already set in the constructor.
+ } else if (!Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY.equals(param)) {
+ try {
+ confB.setSetting(param, value);
+ } catch (ConfigurationException e) {
+ throw new RuntimeException(
+ "Failed to set setting " +
+ _StringUtil.jQuote(param) + " to " +
+ _StringUtil.jQuote(value) + "; see cause exception.",
+ e);
+ }
+ }
+ }
+
+ /*
+ * This method just contains all the code to seed the data model
+ * ported over from the individual classes. This seems ugly and unnecessary.
+ * We really might as well just expose pretty much
+ * the same tree to all our tests. (JR)
+ */
+ @Override
+ @SuppressWarnings("boxing")
+ public void setUp() throws Exception {
+ confB.setTemplateLoader(
+ new CopyrightCommentRemoverTemplateLoader(
+ new ClassTemplateLoader(TemplateTestCase.class, "templates")));
+
+ DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ dataModel.put(ASSERT_VAR_NAME, AssertDirective.INSTANCE);
+ dataModel.put(ASSERT_EQUALS_VAR_NAME, AssertEqualsDirective.INSTANCE);
+ dataModel.put(ASSERT_FAILS_VAR_NAME, AssertFailsDirective.INSTANCE);
+ dataModel.put(NO_OUTPUT_VAR_NAME, NoOutputDirective.INSTANCE);
+
+ dataModel.put(JAVA_OBJECT_INFO_VAR_NAME, JavaObjectInfo.INSTANCE);
+ dataModel.put(TEST_NAME_VAR_NAME, simpleTestName);
+ dataModel.put(ICI_INT_VALUE_VAR_NAME, confB.getIncompatibleImprovements().intValue());
+
+ dataModel.put("message", "Hello, world!");
+
+ if (simpleTestName.startsWith("api-builtin")) {
+ dataModel.put("map", ImmutableMap.of(1, "a", 2, "b", 3, "c"));
+ dataModel.put("list", ImmutableList.of(1, 2, 3));
+ dataModel.put("set", ImmutableSet.of("a", "b", "c"));
+ dataModel.put("s", "test");
+ } else if (simpleTestName.equals("default-object-wrapper")) {
+ dataModel.put("array", new String[] { "array-0", "array-1"});
+ dataModel.put("list", Arrays.asList("list-0", "list-1", "list-2"));
+ Map<Object, Object> tmap = new HashMap<>();
+ tmap.put("key", "value");
+ Object objKey = new Object();
+ tmap.put(objKey, "objValue");
+ dataModel.put("map", tmap);
+ dataModel.put("objKey", objKey);
+ dataModel.put("obj", new org.apache.freemarker.test.templatesuite.models.BeanTestClass());
+ dataModel.put("resourceBundle",
+ new ResourceBundleModel(ResourceBundle.getBundle(
+ "org.apache.freemarker.test.templatesuite.models.BeansTestResources"), dow));
+ dataModel.put("date", new GregorianCalendar(1974, 10, 14).getTime());
+ dataModel.put("statics", dow.getStaticModels());
+ dataModel.put("enums", dow.getEnumModels());
+ } else if (simpleTestName.equals("boolean")) {
+ dataModel.put( "boolean1", TemplateBooleanModel.FALSE);
+ dataModel.put( "boolean2", TemplateBooleanModel.TRUE);
+ dataModel.put( "boolean3", TemplateBooleanModel.TRUE);
+ dataModel.put( "boolean4", TemplateBooleanModel.TRUE);
+ dataModel.put( "boolean5", TemplateBooleanModel.FALSE);
+
+ dataModel.put( "list1", new BooleanList1(dow) );
+ dataModel.put( "list2", new BooleanList2(dow) );
+
+ dataModel.put( "hash1", new BooleanHash1() );
+ dataModel.put( "hash2", new BooleanHash2() );
+ } else if (simpleTestName.startsWith("dateformat")) {
+ GregorianCalendar cal = new GregorianCalendar(2002, 10, 15, 14, 54, 13);
+ cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ dataModel.put("date", new SimpleDate(cal.getTime(), TemplateDateModel.DATETIME));
+ dataModel.put("unknownDate", new SimpleDate(cal.getTime(), TemplateDateModel.UNKNOWN));
+ dataModel.put("javaGMT02", TimeZone.getTimeZone("GMT+02"));
+ dataModel.put("javaUTC", TimeZone.getTimeZone("UTC"));
+ dataModel.put("adaptedToStringScalar", new Object() {
+ @Override
+ public String toString() {
+ return "GMT+02";
+ }
+ });
+ dataModel.put("sqlDate", new java.sql.Date(1273955885023L));
+ dataModel.put("sqlTime", new java.sql.Time(74285023L));
+ } else if (
+ templateName.equals("list.ftl") || templateName.equals("list2.ftl") || templateName.equals("list3.ftl")
+ || simpleTestName.equals("listhash")) {
+ dataModel.put("listables", new Listables());
+ } else if (simpleTestName.startsWith("number-format")) {
+ dataModel.put("int", new SimpleNumber(Integer.valueOf(1)));
+ dataModel.put("double", new SimpleNumber(Double.valueOf(1.0)));
+ dataModel.put("double2", new SimpleNumber(Double.valueOf(1 + 1e-15)));
+ dataModel.put("double3", new SimpleNumber(Double.valueOf(1e-16)));
+ dataModel.put("double4", new SimpleNumber(Double.valueOf(-1e-16)));
+ dataModel.put("bigDecimal", new SimpleNumber(java.math.BigDecimal.valueOf(1)));
+ dataModel.put("bigDecimal2", new SimpleNumber(java.math.BigDecimal.valueOf(1, 16)));
+ } else if (simpleTestName.equals("simplehash-char-key")) {
+ HashMap<String, String> mStringC = new HashMap<>();
+ mStringC.put("c", "string");
+ dataModel.put("mStringC", mStringC);
+
+ HashMap<String, String> mStringCNull = new HashMap<>();
+ mStringCNull.put("c", null);
+ dataModel.put("mStringCNull", mStringCNull);
+
+ HashMap<Character, String> mCharC = new HashMap<>();
+ mCharC.put(Character.valueOf('c'), "char");
+ dataModel.put("mCharC", mCharC);
+
+ HashMap<String, String> mCharCNull = new HashMap<>();
+ mCharCNull.put("c", null);
+ dataModel.put("mCharCNull", mCharCNull);
+
+ HashMap<Object, String> mMixed = new HashMap<>();
+ mMixed.put(Character.valueOf('c'), "char");
+ mMixed.put("s", "string");
+ mMixed.put("s2", "string2");
+ mMixed.put("s2n", null);
+ dataModel.put("mMixed", mMixed);
+ } else if (simpleTestName.equals("default-xmlns")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/defaultxmlns1.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.equals("multimodels")) {
+ dataModel.put("test", "selftest");
+ dataModel.put("self", "self");
+ dataModel.put("zero", Integer.valueOf(0));
+ dataModel.put("data", new MultiModel1());
+ } else if (simpleTestName.equals("stringbimethods")) {
+ dataModel.put("multi", new TestBoolean());
+ } else if (simpleTestName.startsWith("type-builtins")) {
+ dataModel.put("testmethod", new TestMethod());
+ dataModel.put("testnode", new TestNode());
+ dataModel.put("testcollection", new SimpleCollection(new ArrayList<>(), dow));
+ dataModel.put("testcollectionEx", DefaultNonListCollectionAdapter.adapt(new HashSet<>(), dow));
+ dataModel.put("bean", new TestBean());
+ } else if (simpleTestName.equals("date-type-builtins")) {
+ GregorianCalendar cal = new GregorianCalendar(2003, 4 - 1, 5, 6, 7, 8);
+ cal.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date d = cal.getTime();
+ dataModel.put("unknown", d);
+ dataModel.put("timeOnly", new java.sql.Time(d.getTime()));
+ dataModel.put("dateOnly", new java.sql.Date(d.getTime()));
+ dataModel.put("dateTime", new java.sql.Timestamp(d.getTime()));
+ } else if (simpleTestName.equals("var-layers")) {
+ dataModel.put("x", Integer.valueOf(4));
+ dataModel.put("z", Integer.valueOf(4));
+ confB.setSharedVariable("y", Integer.valueOf(7));
+ } else if (simpleTestName.equals("xml-fragment")) {
+ DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+ f.setNamespaceAware(true);
+ DocumentBuilder db = f.newDocumentBuilder();
+ org.w3c.dom.Document doc = db.parse(new InputSource(getClass().getResourceAsStream("models/xmlfragment.xml")));
+ NodeModel.simplify(doc);
+ dataModel.put("node", NodeModel.wrap(doc.getDocumentElement().getFirstChild().getFirstChild()));
+ } else if (simpleTestName.equals("xmlns1")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/xmlns.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.equals("xmlns2")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/xmlns2.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.equals("xmlns3") || simpleTestName.equals("xmlns4")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/xmlns3.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.equals("xmlns5")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/defaultxmlns1.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.equals("xml-ns_prefix-scope")) {
+ InputSource is = new InputSource(getClass().getResourceAsStream("models/xml-ns_prefix-scope.xml"));
+ NodeModel nm = XMLLoader.toModel(is);
+ dataModel.put("doc", nm);
+ } else if (simpleTestName.startsWith("sequence-builtins")) {
+ Set<String> abcSet = new TreeSet<>();
+ abcSet.add("a");
+ abcSet.add("b");
+ abcSet.add("c");
+ dataModel.put("abcSet", abcSet);
+ dataModel.put("abcSetNonSeq", DefaultNonListCollectionAdapter.adapt(abcSet, dow));
+
+ List<String> listWithNull = new ArrayList<>();
+ listWithNull.add("a");
+ listWithNull.add(null);
+ listWithNull.add("c");
+ dataModel.put("listWithNull", listWithNull);
+
+ List<String> listWithNullsOnly = new ArrayList<>();
+ listWithNull.add(null);
+ listWithNull.add(null);
+ listWithNull.add(null);
+ dataModel.put("listWithNullsOnly", listWithNullsOnly);
+
+ dataModel.put("abcCollection", new SimpleCollection(abcSet, dow));
+
+ Set<String> set = new HashSet<>();
+ set.add("a");
+ set.add("b");
+ set.add("c");
+ dataModel.put("set", set);
+ } else if (simpleTestName.equals("number-to-date")) {
+ dataModel.put("bigInteger", new BigInteger("1305575275540"));
+ dataModel.put("bigDecimal", new BigDecimal("1305575275539.5"));
+ } else if (simpleTestName.equals("varargs")) {
+ dataModel.put("m", new VarArgTestModel());
+ } else if (simpleTestName.startsWith("boolean-formatting")) {
+ dataModel.put("booleanAndString", new BooleanAndStringTemplateModel());
+ dataModel.put("booleanVsStringMethods", new BooleanVsStringMethods());
+ } else if (simpleTestName.startsWith("number-math-builtins")) {
+ dataModel.put("fNan", Float.valueOf(Float.NaN));
+ dataModel.put("dNan", Double.valueOf(Double.NaN));
+ dataModel.put("fNinf", Float.valueOf(Float.NEGATIVE_INFINITY));
+ dataModel.put("dPinf", Double.valueOf(Double.POSITIVE_INFINITY));
+
+ dataModel.put("fn", Float.valueOf(-0.05f));
+ dataModel.put("dn", Double.valueOf(-0.05));
+ dataModel.put("ineg", Integer.valueOf(-5));
+ dataModel.put("ln", Long.valueOf(-5));
+ dataModel.put("sn", Short.valueOf((short) -5));
+ dataModel.put("bn", Byte.valueOf((byte) -5));
+ dataModel.put("bin", BigInteger.valueOf(5));
+ dataModel.put("bdn", BigDecimal.valueOf(-0.05));
+
+ dataModel.put("fp", Float.valueOf(0.05f));
+ dataModel.put("dp", Double.valueOf(0.05));
+ dataModel.put("ip", Integer.valueOf(5));
+ dataModel.put("lp", Long.valueOf(5));
+ dataModel.put("sp", Short.valueOf((short) 5));
+ dataModel.put("bp", Byte.valueOf((byte) 5));
+ dataModel.put("bip", BigInteger.valueOf(5));
+ dataModel.put("bdp", BigDecimal.valueOf(0.05));
+ } else if (simpleTestName.startsWith("overloaded-methods")) {
+ dataModel.put("obj", new OverloadedMethods2());
+ }
+ }
+
+ @Override
+ public void runTest() throws IOException, ConfigurationException {
+ Template template;
+ try {
+ template = confB.build().getTemplate(templateName);
+ } catch (IOException e) {
+ throw new AssertionFailedError(
+ "Could not load template " + _StringUtil.jQuote(templateName) + ":\n" + getStackTrace(e));
+ }
+ ASTPrinter.validateAST(template);
+
+ StringWriter out = noOutput ? null : new StringWriter();
+ try {
+ template.process(dataModel, out != null ? out : _NullWriter.INSTANCE);
+ } catch (TemplateException e) {
+ throw new AssertionFailedError("Template " + _StringUtil.jQuote(templateName) + " has stopped with error:\n"
+ + getStackTrace(e));
+ }
+
+ if (out != null) {
+ assertExpectedFileEqualsString(expectedFileName, out.toString());
+ }
+ }
+
+ private String getStackTrace(Throwable e) {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ return sw.toString();
+ }
+
+ @Override
+ protected String getExpectedContentFileDirectoryResourcePath() throws IOException {
+ return joinResourcePaths(super.getExpectedContentFileDirectoryResourcePath(), "expected");
+ }
+
+ @Override
+ protected Charset getTestResourceDefaultCharset() {
+ return confB.getOutputEncoding() != null ? confB.getOutputEncoding() : StandardCharsets.UTF_8;
+ }
+
+ static class TestBoolean implements TemplateBooleanModel, TemplateScalarModel {
+ @Override
+ public boolean getAsBoolean() {
+ return true;
+ }
+
+ @Override
+ public String getAsString() {
+ return "de";
+ }
+ }
+
+ static class TestMethod implements TemplateMethodModel {
+ @Override
+ public Object exec(List arguments) {
+ return "x";
+ }
+ }
+
+ static class TestNode implements TemplateNodeModel {
+
+ @Override
+ public String getNodeName() {
+ return "name";
+ }
+
+ @Override
+ public TemplateNodeModel getParentNode() {
+ return null;
+ }
+
+ @Override
+ public String getNodeType() {
+ return "element";
+ }
+
+ @Override
+ public TemplateSequenceModel getChildNodes() {
+ return null;
+ }
+
+ @Override
+ public String getNodeNamespace() {
+ return null;
+ }
+ }
+
+ public Object getTestMapBean() {
+ Map<String, Object> testBean = new TestMapBean();
+ testBean.put("name", "Chris");
+ testBean.put("location", "San Francisco");
+ testBean.put("age", Integer.valueOf(27));
+ return testBean;
+ }
+
+ public static class TestMapBean extends HashMap<String, Object> {
+ public String getName() {
+ return "Christopher";
+ }
+ public int getLuckyNumber() {
+ return 7;
+ }
+ }
+
+ public static class TestBean {
+
+ public int m(int n) {
+ return n * 10;
+ }
+
+ public int mOverloaded(int n) {
+ return n * 10;
+ }
+
+ public String mOverloaded(String s) {
+ return s.toUpperCase();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
new file mode 100644
index 0000000..0edae99
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
@@ -0,0 +1,298 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Version;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.dom.NodeModel;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import junit.framework.TestSuite;
+
+/**
+ * Test suite where the test cases are defined in testcases.xml, and usually process
+ * templates and compare their output with the expected output.
+ *
+ * If you only want to run certain tests, you can specify a regular expression for
+ * the test name in the {@link #TEST_FILTER_PROPERTY_NAME} system property.
+ */
+public class TemplateTestSuite extends TestSuite {
+
+ private static final String ELEM_TEST_CASE = "testCase";
+
+ private static final String ELEM_SETTING = "setting";
+
+ private static final String ATTR_NO_OUTPUT = "noOutput";
+
+ private static final String ATTR_EXPECTED = "expected";
+
+ private static final String ATTR_TEMPLATE = "template";
+
+ private static final String END_TEMPLATE_NAME_MARK = "[#endTN]";
+
+ public static final String CONFIGURATION_XML_FILE_NAME = "testcases.xml";
+
+ /**
+ * When setting this system property, only the tests whose name matches the
+ * given regular expression will be executed.
+ */
+ public static final String TEST_FILTER_PROPERTY_NAME = "freemareker.templateTestSuite.testFilter";
+
+ /**
+ * Comma separated list of "incompatible improvements" versions to run the test cases with.
+ */
+ public static final String INCOMPATIBLE_IMPROVEMENTS_PROPERTY_NAME
+ = "freemareker.templateTestSuite.incompatibleImprovements";
+
+ private final Map<String, String> testSuiteSettings = new LinkedHashMap<>();
+
+ private final ArrayList<Version> testSuiteIcis;
+
+ private final Pattern testCaseNameFilter;
+
+ public static TestSuite suite() throws Exception {
+ return new TemplateTestSuite();
+ }
+
+ public TemplateTestSuite() throws Exception {
+ NodeModel.useJaxenXPathSupport();
+
+ String filterStr = System.getProperty(TEST_FILTER_PROPERTY_NAME);
+ testCaseNameFilter = filterStr != null ? Pattern.compile(filterStr) : null;
+ if (testCaseNameFilter != null) {
+ System.out.println("Note: " + TEST_FILTER_PROPERTY_NAME + " is " + _StringUtil.jQuote(testCaseNameFilter));
+ }
+
+ testSuiteIcis = new ArrayList<>();
+ String testedIcIsStr = System.getProperty(INCOMPATIBLE_IMPROVEMENTS_PROPERTY_NAME);
+ if (testedIcIsStr != null) {
+ for (String iciStr : testedIcIsStr.split(",")) {
+ iciStr = iciStr.trim();
+ if (iciStr.length() != 0) {
+ testSuiteIcis.add(new Version(iciStr));
+ }
+ }
+ }
+ if (testSuiteIcis.isEmpty()) {
+ testSuiteIcis.add(getMinIcIVersion());
+ testSuiteIcis.add(getMaxIcIVersion());
+ }
+
+ java.net.URL url = TemplateTestSuite.class.getResource(CONFIGURATION_XML_FILE_NAME);
+ if (url == null) {
+ throw new IOException("Resource not found: "
+ + TemplateTestSuite.class.getName() + ", " + CONFIGURATION_XML_FILE_NAME);
+ }
+ processConfigXML(url.toURI());
+ }
+
+ /**
+ * Read the test case configurations file and build up the test suite.
+ */
+ public void processConfigXML(URI uri) throws Exception {
+ Element testCasesElem = loadXMLFromURL(uri);
+
+ NodeList children = testCasesElem.getChildNodes();
+ for (int childIdx = 0; childIdx < children.getLength(); childIdx++) {
+ Node n = children.item(childIdx);
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ final String nodeName = n.getNodeName();
+ if (nodeName.equals(ELEM_SETTING)) {
+ NamedNodeMap attrs = n.getAttributes();
+ for (int attrIdx = 0; attrIdx < attrs.getLength(); attrIdx++) {
+ Attr attr = (Attr) attrs.item(attrIdx);
+ testSuiteSettings.put(attr.getName(), attr.getValue());
+ }
+ } else if (nodeName.equals(ELEM_TEST_CASE)) {
+ for (TemplateTestCase testCase : createTestCasesFromElement((Element) n)) {
+ addTest(testCase);
+ }
+ }
+ }
+ }
+ }
+
+ private Element loadXMLFromURL(URI uri) throws ParserConfigurationException, SAXException, IOException {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ // dbf.setValidating(true);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document d = db.parse(uri.toString());
+ return d.getDocumentElement();
+ }
+
+ String getTextInElement(Element e) {
+ StringBuilder buf = new StringBuilder();
+ NodeList children = e.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node n = children.item(i);
+ short type = n.getNodeType();
+ if (type == Node.TEXT_NODE || type == Node.CDATA_SECTION_NODE) {
+ buf.append(n.getNodeValue());
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Returns the list of test cases generated from the {@link #ELEM_TEST_CASE} element.
+ * There can be multiple generated test cases because of "incompatible improvements" variations, or none because
+ * of the {@code nameFilter}.
+ */
+ private List<TemplateTestCase> createTestCasesFromElement(Element testCaseElem)
+ throws Exception {
+ final String caseName = _StringUtil.emptyToNull(testCaseElem.getAttribute("name"));
+ if (caseName == null) throw new Exception("Invalid XML: the \"name\" attribute is mandatory.");
+
+ if (testCaseNameFilter != null
+ && !testCaseNameFilter.matcher(caseName).matches()) {
+ return Collections.emptyList();
+ }
+
+ final String templateName;
+ final String expectedFileName;
+ {
+ final String beforeEndTN;
+ final String afterEndTN;
+ {
+ int tBNameSep = caseName.indexOf(END_TEMPLATE_NAME_MARK);
+ beforeEndTN = tBNameSep == -1 ? caseName : caseName.substring(0, tBNameSep);
+ afterEndTN = tBNameSep == -1
+ ? "" : caseName.substring(tBNameSep + END_TEMPLATE_NAME_MARK.length());
+ }
+
+ {
+ String s = _StringUtil.emptyToNull(testCaseElem.getAttribute(ATTR_TEMPLATE));
+ templateName = s != null ? s : beforeEndTN + ".ftl";
+ }
+
+ {
+ String s = _StringUtil.emptyToNull(testCaseElem.getAttribute(ATTR_EXPECTED));
+ expectedFileName = s != null ? s : beforeEndTN + afterEndTN + ".txt";
+ }
+ }
+
+ final boolean noOutput;
+ {
+ String s = _StringUtil.emptyToNull(testCaseElem.getAttribute(ATTR_NO_OUTPUT));
+ noOutput = s != null && _StringUtil.getYesNo(s);
+ }
+
+ final Map<String, String> testCaseSettings = getCaseFMSettings(testCaseElem);
+
+ final List<Version> icisToTest;
+ {
+ final String testCaseIcis = testCaseSettings.get(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY);
+
+ icisToTest = testCaseIcis != null ? parseVersionList(testCaseIcis) : testSuiteIcis;
+ if (icisToTest.isEmpty()) {
+ throw new Exception("The incompatible_improvement list was empty");
+ }
+ }
+
+ List<TemplateTestCase> result = new ArrayList<>();
+ for (Version iciToTest : icisToTest) {
+ TemplateTestCase testCase = new TemplateTestCase(
+ caseName + "(ici=" + iciToTest + ")", caseName,
+ templateName, expectedFileName, noOutput, iciToTest);
+ for (Map.Entry<String, String> setting : testSuiteSettings.entrySet()) {
+ testCase.setSetting(setting.getKey(), setting.getValue());
+ }
+ for (Map.Entry<String, String> setting : testCaseSettings.entrySet()) {
+ testCase.setSetting(setting.getKey(), setting.getValue());
+ }
+
+ result.add(testCase);
+ }
+
+ return result;
+ }
+
+ private List<Version> parseVersionList(String versionsStr) {
+ List<Version> versions = new ArrayList<>();
+ for (String versionStr : versionsStr.split(",")) {
+ versionStr = versionStr.trim();
+ if (versionStr.length() != 0) {
+ final Version v;
+ if ("min".equals(versionStr)) {
+ v = getMinIcIVersion();
+ } else if ("max".equals(versionStr)) {
+ v = getMaxIcIVersion();
+ } else {
+ v = new Version(versionStr);
+ }
+ if (!versions.contains(v)) {
+ versions.add(v);
+ }
+ }
+ }
+ return versions;
+ }
+
+ private Version getMaxIcIVersion() {
+ Version v = Configuration.getVersion();
+ // Remove nightly, RC and such:
+ return new Version(v.getMajor(), v.getMinor(), v.getMicro());
+ }
+
+ private Version getMinIcIVersion() {
+ return Configuration.VERSION_3_0_0;
+ }
+
+ private Map<String, String> getCaseFMSettings(Element e) {
+ final Map<String, String> caseFMSettings;
+ caseFMSettings = new LinkedHashMap<>();
+ NodeList settingElems = e.getElementsByTagName(ELEM_SETTING);
+ for (int elemIdx = 0; elemIdx < settingElems.getLength(); elemIdx++) {
+ NamedNodeMap attrs = settingElems.item(elemIdx).getAttributes();
+ for (int attrIdx = 0; attrIdx < attrs.getLength(); attrIdx++) {
+ Attr attr = (Attr) attrs.item(attrIdx);
+
+ final String settingName = attr.getName();
+ caseFMSettings.put(settingName, attr.getValue());
+ }
+ }
+ return caseFMSettings;
+ }
+
+ public static void main (String[] args) throws Exception {
+ junit.textui.TestRunner.run(new TemplateTestSuite());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
new file mode 100644
index 0000000..974b3f9
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
@@ -0,0 +1,128 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import java.util.Date;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateModelIterator;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * Implements all template models that are interesting when calling overloaded Java methods.
+ */
+public class AllTemplateModels implements
+ TemplateScalarModel, TemplateNumberModel, TemplateDateModel, TemplateBooleanModel,
+ TemplateHashModelEx, TemplateSequenceModel, TemplateCollectionModel {
+
+ public static final AllTemplateModels INSTANCE = new AllTemplateModels();
+
+ private final TemplateModelIterator EMPTY_ITERATOR = new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ return null;
+ }
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return false;
+ }
+
+ };
+
+ private final TemplateCollectionModel EMPTY_COLLECTION = new TemplateCollectionModel() {
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return EMPTY_ITERATOR;
+ }
+ };
+
+ @Override
+ public TemplateModel get(String key) throws TemplateModelException {
+ return new SimpleScalar("value for key " + key);
+ }
+
+ @Override
+ public boolean isEmpty() throws TemplateModelException {
+ return true;
+ }
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return EMPTY_ITERATOR;
+ }
+
+ @Override
+ public TemplateModel get(int index) throws TemplateModelException {
+ return null;
+ }
+
+ @Override
+ public int size() throws TemplateModelException {
+ return 0;
+ }
+
+ @Override
+ public TemplateCollectionModel keys() throws TemplateModelException {
+ return EMPTY_COLLECTION;
+ }
+
+ @Override
+ public TemplateCollectionModel values() throws TemplateModelException {
+ return EMPTY_COLLECTION;
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return true;
+ }
+
+ @Override
+ public Date getAsDate() throws TemplateModelException {
+ return new Date(0);
+ }
+
+ @Override
+ public int getDateType() {
+ return TemplateDateModel.DATETIME;
+ }
+
+ @Override
+ @SuppressWarnings("boxing")
+ public Number getAsNumber() throws TemplateModelException {
+ return 1;
+ }
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return "s";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
new file mode 100644
index 0000000..7e7fa82
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
@@ -0,0 +1,93 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+/**
+ */
+public class BeanTestClass extends BeanTestSuperclass implements BeanTestInterface<Integer> {
+ public static final String STATIC_FINAL_FIELD = "static-final-field";
+ public static String STATIC_FIELD = "static-field";
+
+ public String getFoo() {
+ return "foo-value";
+ }
+
+ public String getBar(int index) {
+ return "bar-value-" + index;
+ }
+
+ public String[] getBar() {
+ return new String[] { "bar-value-0", "bar-value-1", "bar-value-2" };
+ }
+
+ public String overloaded(int i) {
+ return "overloaded-int-" + i;
+ }
+
+ public String overloaded(String s) {
+ return "overloaded-String-" + s;
+ }
+
+ public static String staticMethod() {
+ return "static-method";
+ }
+
+ public static String staticOverloaded(int i) {
+ return "static-overloaded-int-" + i;
+ }
+
+ public static String staticOverloaded(String s) {
+ return "static-overloaded-String-" + s;
+ }
+
+ public PrivateInner getPrivateInner() {
+ return new PrivateInner();
+ }
+
+ public PublicInner getPublicInner() {
+ return new PublicInner();
+ }
+
+ public class PublicInner {
+
+ public int getX() {
+ return 1;
+ }
+
+ public String m() {
+ return "m";
+ }
+
+ }
+
+ @SuppressWarnings("unused")
+ private class PrivateInner {
+
+ public int getX() {
+ return 2;
+ }
+
+ public String m() {
+ return "M";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
new file mode 100644
index 0000000..6737b87
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
@@ -0,0 +1,25 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+public interface BeanTestInterface<T> {
+ T getSomething();
+ void setSomething(T s);
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
new file mode 100644
index 0000000..b462e9a
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
@@ -0,0 +1,30 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+public class BeanTestSuperclass {
+ public Integer getSomething() {
+ return 42;
+ }
+
+ public void setSomething(Integer x) {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
new file mode 100644
index 0000000..4af030e
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+
+public class BooleanAndScalarModel implements TemplateBooleanModel, TemplateScalarModel {
+
+ public static final BooleanAndScalarModel INSTANCE = new BooleanAndScalarModel();
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return "s";
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
new file mode 100644
index 0000000..d87b65c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
@@ -0,0 +1,38 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+
+public class BooleanAndStringTemplateModel implements TemplateBooleanModel, TemplateScalarModel {
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return "theStringValue";
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
new file mode 100644
index 0000000..524d003
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * Tests the impact that the isEmpty() has on template hash models.
+ */
+public class BooleanHash1 implements TemplateHashModel {
+
+ /**
+ * Gets a <tt>TemplateModel</tt> from the hash.
+ *
+ * @param key the name by which the <tt>TemplateModel</tt>
+ * is identified in the template.
+ * @return the <tt>TemplateModel</tt> referred to by the key,
+ * or null if not found.
+ */
+ @Override
+ public TemplateModel get(String key) {
+ if ( key.equals( "temp" )) {
+ return new SimpleScalar( "Hello, world." );
+ } else if ( key.equals( "boolean" )) {
+ return TemplateBooleanModel.FALSE;
+ } else {
+ return new SimpleScalar( "Just another key..." );
+ }
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
new file mode 100644
index 0000000..8bae7ab
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModel;
+
+/**
+ * Tests the impact that the isEmpty() has on template hash models.
+ */
+public class BooleanHash2 implements TemplateHashModel {
+
+ /**
+ * Gets a <tt>TemplateModel</tt> from the hash.
+ *
+ * @param key the name by which the <tt>TemplateModel</tt>
+ * is identified in the template.
+ * @return the <tt>TemplateModel</tt> referred to by the key,
+ * or null if not found.
+ */
+ @Override
+ public TemplateModel get(String key) {
+ return null;
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
new file mode 100644
index 0000000..3e0a69c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Model for testing the impact of isEmpty() on template list models. Every
+ * other method simply delegates to a SimpleList model.
+ */
+public class BooleanList1 implements TemplateSequenceModel {
+
+ private SimpleSequence cList;
+
+ /** Creates new BooleanList1 */
+ public BooleanList1(ObjectWrapper ow) {
+ cList = new SimpleSequence(ow);
+ cList.add( "false" );
+ cList.add( "0" );
+ cList.add(TemplateBooleanModel.FALSE);
+ cList.add(TemplateBooleanModel.TRUE);
+ cList.add(TemplateBooleanModel.TRUE);
+ cList.add(TemplateBooleanModel.TRUE);
+ cList.add(TemplateBooleanModel.FALSE);
+ }
+
+ /**
+ * @return the specified index in the list
+ */
+ @Override
+ public TemplateModel get(int i) throws TemplateModelException {
+ return cList.get(i);
+ }
+
+ @Override
+ public int size() {
+ return cList.size();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
new file mode 100644
index 0000000..939fb5f
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
@@ -0,0 +1,53 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Model for testing list models. Every
+ * other method simply delegates to a SimpleList model.
+ */
+public class BooleanList2 implements TemplateSequenceModel {
+
+ private SimpleSequence cList;
+
+ /** Creates new BooleanList2 */
+ public BooleanList2(ObjectWrapper ow) {
+ cList = new SimpleSequence(ow);
+ }
+
+ /**
+ * @return the specified index in the list
+ */
+ @Override
+ public TemplateModel get(int i) throws TemplateModelException {
+ return cList.get(i);
+ }
+
+ @Override
+ public int size() {
+ return cList.size();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
new file mode 100644
index 0000000..3e13623
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+public class BooleanVsStringMethods {
+
+ public String expectsString(String s) {
+ return s;
+ }
+
+ public boolean expectsBoolean(boolean b) {
+ return b;
+ }
+
+ public String overloaded(String s) {
+ return "String " + s;
+ }
+
+ public String overloaded(boolean s) {
+ return "boolean " + s;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
new file mode 100644
index 0000000..359e4a4
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+/**
+ */
+public enum EnumTestClass
+{
+ ONE,
+ TWO,
+ THREE;
+
+ @Override
+ public String toString() {
+ return name() + "x";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
new file mode 100644
index 0000000..ca0f9be
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.freemarker.test.templatesuite.models;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+
+/**
+ * A template that always throws an exception whenever we call getAsString()
+ */
+public class ExceptionModel implements TemplateScalarModel {
+
+ /**
+ * Returns the scalar's value as a String.
+ *
+ * @return the String value of this scalar.
+ */
+ @Override
+ public String getAsString () throws TemplateModelException {
+ throw new TemplateModelException( "Throwing from ExceptionModel!" );
+ }
+}