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:17 UTC
[01/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
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 3fd560629 -> 28a276c80
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
deleted file mode 100644
index 6b7f986..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Transformation Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Hello, world!</p>
-
-<P>Now try the Utility package:</p>
-<p>Utility transformations</p>
-
-<p>Utility transformations</p>
-
-<p>Now some nested transforms:</p>
-<p >This tests the compress transformation</p ><p >This tests the compress transformation</p ><p >This tests the compress transformation</p >
-<p>Now try method and transform interactions:</p>
-<p>This isn't a valid XML string.</p>
-<p>This isn't a valid HTML string.</p>
-
-<p>A more advanced interaction involves getting a TemplateMethodModel
-to initialise a TemplateTransformModel, as follow:</p>
-
-Comment: This is a comment
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish & Chips.</p>
-
-Comment: This is a second comment
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish & Chips.</p>
-Comment: This is a third comment
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-Comment: Utility transformations
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish & Chips.</p>
-
-</body>
-</html>
[22/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
deleted file mode 100644
index dcefa3f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
+++ /dev/null
@@ -1,1486 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
-import org.apache.freemarker.core.outputformat.OutputFormat;
-import org.apache.freemarker.core.outputformat.UnregisteredOutputFormatException;
-import org.apache.freemarker.core.outputformat.impl.CombinedMarkupOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat;
-import org.apache.freemarker.core.templateresolver.CacheStorageWithGetSize;
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
-import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
-import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormatFM2;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
-import org.apache.freemarker.core.templateresolver.impl.NullCacheStorage;
-import org.apache.freemarker.core.templateresolver.impl.SoftCacheStorage;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
-import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat;
-import org.apache.freemarker.core.userpkg.DummyOutputFormat;
-import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
-import org.apache.freemarker.core.util._DateUtil;
-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.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import junit.framework.TestCase;
-
-public class ConfigurationTest extends TestCase {
-
- private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
-
- public ConfigurationTest(String name) {
- super(name);
- }
-
- public void testUnsetAndIsSet() throws Exception {
- Configuration.ExtendableBuilder<?> cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertFalse(cfgB.isLogTemplateExceptionsSet());
- assertFalse(cfgB.getLogTemplateExceptions());
- //
- cfgB.setLogTemplateExceptions(true);
- {
- Configuration cfg = cfgB.build();
- assertTrue(cfgB.isLogTemplateExceptionsSet());
- assertTrue(cfg.isLogTemplateExceptionsSet());
- assertTrue(cfgB.getLogTemplateExceptions());
- assertTrue(cfg.getLogTemplateExceptions());
- }
- //
- for (int i = 0; i < 2; i++) {
- cfgB.unsetLogTemplateExceptions();
- Configuration cfg = cfgB.build();
- assertFalse(cfgB.isLogTemplateExceptionsSet());
- assertTrue(cfg.isLogTemplateExceptionsSet());
- assertFalse(cfgB.getLogTemplateExceptions());
- assertFalse(cfg.getLogTemplateExceptions());
- }
-
- DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertFalse(cfgB.isObjectWrapperSet());
- assertSame(dow, cfgB.getObjectWrapper());
- //
- RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- cfgB.setObjectWrapper(ow);
- assertTrue(cfgB.isObjectWrapperSet());
- assertSame(ow, cfgB.getObjectWrapper());
- //
- for (int i = 0; i < 2; i++) {
- cfgB.unsetObjectWrapper();
- assertFalse(cfgB.isObjectWrapperSet());
- assertSame(dow, cfgB.getObjectWrapper());
- }
-
- assertFalse(cfgB.isTemplateExceptionHandlerSet());
- assertSame(TemplateExceptionHandler.DEBUG_HANDLER, cfgB.getTemplateExceptionHandler());
- //
- cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
- assertTrue(cfgB.isTemplateExceptionHandlerSet());
- assertSame(TemplateExceptionHandler.RETHROW_HANDLER, cfgB.getTemplateExceptionHandler());
- //
- for (int i = 0; i < 2; i++) {
- cfgB.unsetTemplateExceptionHandler();
- assertFalse(cfgB.isTemplateExceptionHandlerSet());
- assertSame(TemplateExceptionHandler.DEBUG_HANDLER, cfgB.getTemplateExceptionHandler());
- }
-
- assertFalse(cfgB.isTemplateLoaderSet());
- assertNull(cfgB.getTemplateLoader());
- //
- cfgB.setTemplateLoader(null);
- assertTrue(cfgB.isTemplateLoaderSet());
- assertNull(cfgB.getTemplateLoader());
- //
- for (int i = 0; i < 3; i++) {
- if (i == 2) {
- cfgB.setTemplateLoader(new StringTemplateLoader());
- }
- cfgB.unsetTemplateLoader();
- assertFalse(cfgB.isTemplateLoaderSet());
- assertNull(cfgB.getTemplateLoader());
- }
-
- assertFalse(cfgB.isTemplateLookupStrategySet());
- assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
- //
- cfgB.setTemplateLookupStrategy(DefaultTemplateLookupStrategy.INSTANCE);
- assertTrue(cfgB.isTemplateLookupStrategySet());
- //
- for (int i = 0; i < 2; i++) {
- cfgB.unsetTemplateLookupStrategy();
- assertFalse(cfgB.isTemplateLookupStrategySet());
- }
-
- assertFalse(cfgB.isTemplateNameFormatSet());
- assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
- //
- cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE);
- assertTrue(cfgB.isTemplateNameFormatSet());
- assertSame(DefaultTemplateNameFormat.INSTANCE, cfgB.getTemplateNameFormat());
- //
- for (int i = 0; i < 2; i++) {
- cfgB.unsetTemplateNameFormat();
- assertFalse(cfgB.isTemplateNameFormatSet());
- assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
- }
-
- assertFalse(cfgB.isCacheStorageSet());
- assertTrue(cfgB.getCacheStorage() instanceof SoftCacheStorage);
- //
- cfgB.setCacheStorage(NullCacheStorage.INSTANCE);
- assertTrue(cfgB.isCacheStorageSet());
- assertSame(NullCacheStorage.INSTANCE, cfgB.getCacheStorage());
- //
- for (int i = 0; i < 3; i++) {
- if (i == 2) {
- cfgB.setCacheStorage(cfgB.getCacheStorage());
- }
- cfgB.unsetCacheStorage();
- assertFalse(cfgB.isCacheStorageSet());
- assertTrue(cfgB.getCacheStorage() instanceof SoftCacheStorage);
- }
- }
-
- public void testTemplateLoadingErrors() throws Exception {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(new ClassTemplateLoader(getClass(), "nosuchpackage"))
- .build();
- try {
- cfg.getTemplate("missing.ftl");
- fail();
- } catch (TemplateNotFoundException e) {
- assertThat(e.getMessage(), not(containsString("wasn't set")));
- }
- }
-
- public void testVersion() {
- Version v = Configuration.getVersion();
- assertTrue(v.intValue() >= _CoreAPI.VERSION_INT_3_0_0);
-
- try {
- new Configuration.Builder(new Version(999, 1, 2));
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("upgrade"));
- }
-
- try {
- new Configuration.Builder(new Version(2, 3, 0));
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("3.0.0"));
- }
- }
-
- public void testShowErrorTips() throws Exception {
- try {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
- new Template(null, "${x}", cfg).process(null, _NullWriter.INSTANCE);
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsString("Tip:"));
- }
-
- try {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).showErrorTips(false).build();
- new Template(null, "${x}", cfg).process(null, _NullWriter.INSTANCE);
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), not(containsString("Tip:")));
- }
- }
-
- @Test
- @SuppressWarnings("boxing")
- public void testGetTemplateOverloads() throws Exception {
- final Locale hu = new Locale("hu", "HU");
- final String tFtl = "t.ftl";
- final String tHuFtl = "t_hu.ftl";
- final String tEnFtl = "t_en.ftl";
- final String tUtf8Ftl = "utf8.ftl";
- final Serializable custLookupCond = 12345;
-
- ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
- tl.putTemplate(tFtl, "${1}".getBytes(StandardCharsets.UTF_8));
- tl.putTemplate(tEnFtl, "${1}".getBytes(StandardCharsets.UTF_8));
- tl.putTemplate(tHuFtl, "${1}".getBytes(StandardCharsets.UTF_8));
- tl.putTemplate(tUtf8Ftl, "<#ftl encoding='utf-8'>".getBytes(StandardCharsets.UTF_8));
-
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .locale(Locale.GERMAN)
- .sourceEncoding(StandardCharsets.ISO_8859_1)
- .templateLoader(tl)
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*_hu.*"),
- new TemplateConfiguration.Builder().sourceEncoding(ISO_8859_2).build()))
- .build();
-
- // 1 args:
- {
- Template t = cfg.getTemplate(tFtl);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tFtl, t.getSourceName());
- assertEquals(Locale.GERMAN, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tUtf8Ftl);
- assertEquals(tUtf8Ftl, t.getLookupName());
- assertEquals(tUtf8Ftl, t.getSourceName());
- assertEquals(Locale.GERMAN, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- }
-
- // 2 args:
- {
- Template t = cfg.getTemplate(tFtl, Locale.GERMAN);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tFtl, t.getSourceName());
- assertEquals(Locale.GERMAN, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tFtl, (Locale) null);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tFtl, t.getSourceName());
- assertEquals(Locale.GERMAN, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tFtl, Locale.US);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tEnFtl, t.getSourceName());
- assertEquals(Locale.US, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tUtf8Ftl, Locale.US);
- assertEquals(tUtf8Ftl, t.getLookupName());
- assertEquals(tUtf8Ftl, t.getSourceName());
- assertEquals(Locale.US, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tFtl, hu);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tHuFtl, t.getSourceName());
- assertEquals(hu, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(ISO_8859_2, t.getActualSourceEncoding());
- }
- {
- Template t = cfg.getTemplate(tUtf8Ftl, hu);
- assertEquals(tUtf8Ftl, t.getLookupName());
- assertEquals(tUtf8Ftl, t.getSourceName());
- assertEquals(hu, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- }
-
- // 4 args:
- try {
- cfg.getTemplate("missing.ftl", hu, custLookupCond, false);
- fail();
- } catch (TemplateNotFoundException e) {
- // Expected
- }
- assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, true));
- {
- Template t = cfg.getTemplate(tFtl, hu, custLookupCond, false);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tHuFtl, t.getSourceName());
- assertEquals(hu, t.getLocale());
- assertEquals(custLookupCond, t.getCustomLookupCondition());
- assertEquals(ISO_8859_2, t.getActualSourceEncoding());
- assertOutputEquals("1", t);
- }
- {
- Template t = cfg.getTemplate(tFtl, null, custLookupCond, false);
- assertEquals(tFtl, t.getLookupName());
- assertEquals(tFtl, t.getSourceName());
- assertEquals(Locale.GERMAN, t.getLocale());
- assertEquals(custLookupCond, t.getCustomLookupCondition());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- assertOutputEquals("1", t);
- }
- }
-
- private void assertOutputEquals(final String expectedContent, final Template t) throws ConfigurationException,
- IOException, TemplateException {
- StringWriter sw = new StringWriter();
- t.process(null, sw);
- assertEquals(expectedContent, sw.toString());
- }
-
- public void testTemplateResolverCache() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- CacheStorageWithGetSize cache = (CacheStorageWithGetSize) cfgB.getCacheStorage();
- assertEquals(0, cache.getSize());
- cfgB.setCacheStorage(new StrongCacheStorage());
- cache = (CacheStorageWithGetSize) cfgB.getCacheStorage();
- assertEquals(0, cache.getSize());
- cfgB.setTemplateLoader(new ClassTemplateLoader(ConfigurationTest.class, ""));
- Configuration cfg = cfgB.build();
- assertEquals(0, cache.getSize());
- cfg.getTemplate("toCache1.ftl");
- assertEquals(1, cache.getSize());
- cfg.getTemplate("toCache2.ftl");
- assertEquals(2, cache.getSize());
- cfg.clearTemplateCache();
- assertEquals(0, cache.getSize());
- cfg.getTemplate("toCache1.ftl");
- assertEquals(1, cache.getSize());
- cfgB.setTemplateLoader(cfgB.getTemplateLoader());
- assertEquals(1, cache.getSize());
- }
-
- public void testTemplateNameFormat() throws Exception {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("a/b.ftl", "In a/b.ftl");
- tl.putTemplate("b.ftl", "In b.ftl");
-
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(tl);
-
- {
- cfgB.setTemplateNameFormat(DefaultTemplateNameFormatFM2.INSTANCE);
- final Template template = cfgB.build().getTemplate("a/./../b.ftl");
- assertEquals("a/b.ftl", template.getLookupName());
- assertEquals("a/b.ftl", template.getSourceName());
- assertEquals("In a/b.ftl", template.toString());
- }
-
- {
- cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE);
- final Template template = cfgB.build().getTemplate("a/./../b.ftl");
- assertEquals("b.ftl", template.getLookupName());
- assertEquals("b.ftl", template.getSourceName());
- assertEquals("In b.ftl", template.toString());
- }
- }
-
- public void testTemplateNameFormatSetSetting() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defAult_2_4_0");
- assertSame(DefaultTemplateNameFormat.INSTANCE, cfgB.getTemplateNameFormat());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defaUlt_2_3_0");
- assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
- assertTrue(cfgB.isTemplateNameFormatSet());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defauLt");
- assertFalse(cfgB.isTemplateNameFormatSet());
- }
-
- public void testObjectWrapperSetSetting() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- {
- cfgB.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "defAult");
- DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertSame(dow, cfgB.getObjectWrapper());
- assertEquals(Configuration.VERSION_3_0_0, dow.getIncompatibleImprovements());
- }
-
- {
- cfgB.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "restricted");
- assertThat(cfgB.getObjectWrapper(), instanceOf(RestrictedObjectWrapper.class));
- }
- }
-
- public void testTemplateLookupStrategyDefaultAndSet() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
- assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.build().getTemplateLookupStrategy());
-
- cfgB.setTemplateLoader(new ClassTemplateLoader(ConfigurationTest.class, ""));
- assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
- Configuration cfg = cfgB.build();
- assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfg.getTemplateLookupStrategy());
- cfg.getTemplate("toCache1.ftl");
-
- final TemplateLookupStrategy myStrategy = new TemplateLookupStrategy() {
- @Override
- public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
- return ctx.lookupWithAcquisitionStrategy("toCache2.ftl");
- }
- };
- cfgB.setTemplateLookupStrategy(myStrategy);
- assertSame(myStrategy, cfgB.getTemplateLookupStrategy());
- cfg = cfgB.build();
- cfg.clearTemplateCache();
- assertSame(myStrategy, cfg.getTemplateLookupStrategy());
- Template template = cfg.getTemplate("toCache1.ftl");
- assertEquals("toCache2.ftl", template.getSourceName());
- }
-
- public void testSetTemplateConfigurations() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertNull(cfgB.getTemplateConfigurations());
-
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("t.de.ftlh", "");
- tl.putTemplate("t.fr.ftlx", "");
- tl.putTemplate("t.ftlx", "");
- tl.putTemplate("Stat/t.de.ftlx", "");
- cfgB.setTemplateLoader(tl);
-
- cfgB.setTimeZone(TimeZone.getTimeZone("GMT+09"));
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_CONFIGURATIONS_KEY,
- "MergingTemplateConfigurationFactory("
- + "FirstMatchTemplateConfigurationFactory("
- + "ConditionalTemplateConfigurationFactory("
- + "FileNameGlobMatcher('*.de.*'), TemplateConfiguration(timeZone=TimeZone('GMT+01'))), "
- + "ConditionalTemplateConfigurationFactory("
- + "FileNameGlobMatcher('*.fr.*'), TemplateConfiguration(timeZone=TimeZone('GMT'))), "
- + "allowNoMatch=true"
- + "), "
- + "FirstMatchTemplateConfigurationFactory("
- + "ConditionalTemplateConfigurationFactory("
- + "FileExtensionMatcher('ftlh'), TemplateConfiguration(booleanFormat='TODO,HTML')), "
- + "ConditionalTemplateConfigurationFactory("
- + "FileExtensionMatcher('ftlx'), TemplateConfiguration(booleanFormat='TODO,XML')), "
- + "noMatchErrorDetails='Unrecognized template file extension'"
- + "), "
- + "ConditionalTemplateConfigurationFactory("
- + "PathGlobMatcher('stat/**', caseInsensitive=true), "
- + "TemplateConfiguration(timeZone=TimeZone('UTC'))"
- + ")"
- + ")");
-
- Configuration cfg = cfgB.build();
- {
- Template t = cfg.getTemplate("t.de.ftlh");
- assertEquals("TODO,HTML", t.getBooleanFormat());
- assertEquals(TimeZone.getTimeZone("GMT+01"), t.getTimeZone());
- }
- {
- Template t = cfg.getTemplate("t.fr.ftlx");
- assertEquals("TODO,XML", t.getBooleanFormat());
- assertEquals(TimeZone.getTimeZone("GMT"), t.getTimeZone());
- }
- {
- Template t = cfg.getTemplate("t.ftlx");
- assertEquals("TODO,XML", t.getBooleanFormat());
- assertEquals(TimeZone.getTimeZone("GMT+09"), t.getTimeZone());
- }
- {
- Template t = cfg.getTemplate("Stat/t.de.ftlx");
- assertEquals("TODO,XML", t.getBooleanFormat());
- assertEquals(_DateUtil.UTC, t.getTimeZone());
- }
-
- assertNotNull(cfgB.getTemplateConfigurations());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_CONFIGURATIONS_KEY, "null");
- assertNull(cfgB.getTemplateConfigurations());
- }
-
- public void testSetAutoEscaping() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY);
- assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY);
- assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
- assertEquals(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enableIfSupported");
- assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enable_if_supported");
- assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enableIfDefault");
- assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enable_if_default");
- assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "disable");
- assertEquals(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- try {
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- public void testSetOutputFormat() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(UndefinedOutputFormat.INSTANCE, cfgB.getOutputFormat());
- assertFalse(cfgB.isOutputFormatSet());
-
- try {
- cfgB.setOutputFormat(null);
- fail();
- } catch (_NullArgumentException e) {
- // Expected
- }
-
- assertFalse(cfgB.isOutputFormatSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE, XMLOutputFormat.class.getSimpleName());
- assertEquals(XMLOutputFormat.INSTANCE, cfgB.getOutputFormat());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_SNAKE_CASE, HTMLOutputFormat.class.getSimpleName());
- assertEquals(HTMLOutputFormat.INSTANCE, cfgB.getOutputFormat());
-
- cfgB.unsetOutputFormat();
- assertEquals(UndefinedOutputFormat.INSTANCE, cfgB.getOutputFormat());
- assertFalse(cfgB.isOutputFormatSet());
-
- cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
- assertTrue(cfgB.isOutputFormatSet());
- cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE, "default");
- assertFalse(cfgB.isOutputFormatSet());
-
- try {
- cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY, "null");
- } catch (ConfigurationSettingValueException e) {
- assertThat(e.getCause().getMessage(), containsString(UndefinedOutputFormat.class.getSimpleName()));
- }
- }
-
- @Test
- public void testGetOutputFormatByName() throws Exception {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
-
- assertSame(HTMLOutputFormat.INSTANCE, cfg.getOutputFormat(HTMLOutputFormat.INSTANCE.getName()));
-
- try {
- cfg.getOutputFormat("noSuchFormat");
- fail();
- } catch (UnregisteredOutputFormatException e) {
- assertThat(e.getMessage(), containsString("noSuchFormat"));
- }
-
- try {
- cfg.getOutputFormat("HTML}");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("'{'"));
- }
-
- {
- OutputFormat of = cfg.getOutputFormat("HTML{RTF}");
- assertThat(of, instanceOf(CombinedMarkupOutputFormat.class));
- CombinedMarkupOutputFormat combinedOF = (CombinedMarkupOutputFormat) of;
- assertSame(HTMLOutputFormat.INSTANCE, combinedOF.getOuterOutputFormat());
- assertSame(RTFOutputFormat.INSTANCE, combinedOF.getInnerOutputFormat());
- }
-
- {
- OutputFormat of = cfg.getOutputFormat("XML{HTML{RTF}}");
- assertThat(of, instanceOf(CombinedMarkupOutputFormat.class));
- CombinedMarkupOutputFormat combinedOF = (CombinedMarkupOutputFormat) of;
- assertSame(XMLOutputFormat.INSTANCE, combinedOF.getOuterOutputFormat());
- MarkupOutputFormat innerOF = combinedOF.getInnerOutputFormat();
- assertThat(innerOF, instanceOf(CombinedMarkupOutputFormat.class));
- CombinedMarkupOutputFormat innerCombinedOF = (CombinedMarkupOutputFormat) innerOF;
- assertSame(HTMLOutputFormat.INSTANCE, innerCombinedOF.getOuterOutputFormat());
- assertSame(RTFOutputFormat.INSTANCE, innerCombinedOF.getInnerOutputFormat());
- }
-
- try {
- cfg.getOutputFormat("plainText{HTML}");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), allOf(containsString("plainText"), containsString("markup")));
- }
- try {
- cfg.getOutputFormat("HTML{plainText}");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), allOf(containsString("plainText"), containsString("markup")));
- }
- }
-
- public void testSetRegisteredCustomOutputFormats() throws Exception {
- Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertTrue(cfg.getRegisteredCustomOutputFormats().isEmpty());
-
- cfg.setSetting(Configuration.ExtendableBuilder.REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE,
- "[org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat(), "
- + "org.apache.freemarker.core.userpkg.DummyOutputFormat()]");
- assertEquals(
- ImmutableList.of(CustomHTMLOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE),
- new ArrayList(cfg.getRegisteredCustomOutputFormats()));
-
- try {
- cfg.setSetting(Configuration.ExtendableBuilder.REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE, "[TemplateConfiguration()]");
- fail();
- } catch (ConfigurationSettingValueException e) {
- assertThat(e.getMessage(), containsString(OutputFormat.class.getSimpleName()));
- }
- }
-
- public void testSetRecognizeStandardFileExtensions() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertTrue(cfgB.getRecognizeStandardFileExtensions());
- assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
-
- cfgB.setRecognizeStandardFileExtensions(false);
- assertFalse(cfgB.getRecognizeStandardFileExtensions());
- assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
-
- cfgB.unsetRecognizeStandardFileExtensions();
- assertTrue(cfgB.getRecognizeStandardFileExtensions());
- assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
-
- cfgB.setRecognizeStandardFileExtensions(true);
- assertTrue(cfgB.getRecognizeStandardFileExtensions());
- assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE, "false");
- assertFalse(cfgB.getRecognizeStandardFileExtensions());
- assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE, "default");
- assertTrue(cfgB.getRecognizeStandardFileExtensions());
- assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
- }
-
- public void testSetTimeZone() throws ConfigurationException {
- TimeZone origSysDefTZ = TimeZone.getDefault();
- try {
- TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01");
- TimeZone.setDefault(sysDefTZ);
-
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertEquals(sysDefTZ, cfgB.getTimeZone());
- cfgB.setSetting(MutableProcessingConfiguration.TIME_ZONE_KEY, "JVM default");
- assertEquals(sysDefTZ, cfgB.getTimeZone());
-
- TimeZone newSysDefTZ = TimeZone.getTimeZone("GMT+09");
- TimeZone.setDefault(newSysDefTZ);
- assertEquals(sysDefTZ, cfgB.getTimeZone());
- cfgB.setSetting(MutableProcessingConfiguration.TIME_ZONE_KEY, "JVM default");
- assertEquals(newSysDefTZ, cfgB.getTimeZone());
- } finally {
- TimeZone.setDefault(origSysDefTZ);
- }
- }
-
- public void testSetSQLDateAndTimeTimeZone() throws ConfigurationException {
- TimeZone origSysDefTZ = TimeZone.getDefault();
- try {
- TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01");
- TimeZone.setDefault(sysDefTZ);
-
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertNull(cfgB.getSQLDateAndTimeTimeZone());
-
- cfgB.setSQLDateAndTimeTimeZone(null);
- assertNull(cfgB.getSQLDateAndTimeTimeZone());
-
- cfgB.setSetting(MutableProcessingConfiguration.SQL_DATE_AND_TIME_TIME_ZONE_KEY, "JVM default");
- assertEquals(sysDefTZ, cfgB.getSQLDateAndTimeTimeZone());
-
- cfgB.setSetting(MutableProcessingConfiguration.SQL_DATE_AND_TIME_TIME_ZONE_KEY, "null");
- assertNull(cfgB.getSQLDateAndTimeTimeZone());
- } finally {
- TimeZone.setDefault(origSysDefTZ);
- }
- }
-
- public void testTimeZoneLayers() throws Exception {
- TimeZone localTZ = TimeZone.getTimeZone("Europe/Brussels");
-
- {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
- Template t = new Template(null, "", cfg);
- Environment env1 = t.createProcessingEnvironment(null, new StringWriter());
- Environment env2 = t.createProcessingEnvironment(null, new StringWriter());
-
- // cfg:
- assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
- assertNull(cfg.getSQLDateAndTimeTimeZone());
- // env:
- assertEquals(TimeZone.getDefault(), env1.getTimeZone());
- assertNull(env1.getSQLDateAndTimeTimeZone());
- // env 2:
- assertEquals(TimeZone.getDefault(), env2.getTimeZone());
- assertNull(env2.getSQLDateAndTimeTimeZone());
-
- env1.setSQLDateAndTimeTimeZone(_DateUtil.UTC);
- // cfg:
- assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
- assertNull(cfg.getSQLDateAndTimeTimeZone());
- // env:
- assertEquals(TimeZone.getDefault(), env1.getTimeZone());
- assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
-
- env1.setTimeZone(localTZ);
- // cfg:
- assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
- assertNull(cfg.getSQLDateAndTimeTimeZone());
- // env:
- assertEquals(localTZ, env1.getTimeZone());
- assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
- // env 2:
- assertEquals(TimeZone.getDefault(), env2.getTimeZone());
- assertNull(env2.getSQLDateAndTimeTimeZone());
- }
-
- {
- TimeZone otherTZ1 = TimeZone.getTimeZone("GMT+05");
- TimeZone otherTZ2 = TimeZone.getTimeZone("GMT+06");
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .timeZone(otherTZ1)
- .sqlDateAndTimeTimeZone(otherTZ2)
- .build();
-
- Template t = new Template(null, "", cfg);
- Environment env1 = t.createProcessingEnvironment(null, new StringWriter());
- Environment env2 = t.createProcessingEnvironment(null, new StringWriter());
-
- env1.setTimeZone(localTZ);
- env1.setSQLDateAndTimeTimeZone(_DateUtil.UTC);
-
- // cfg:
- assertEquals(otherTZ1, cfg.getTimeZone());
- assertEquals(otherTZ2, cfg.getSQLDateAndTimeTimeZone());
- // env:
- assertEquals(localTZ, env1.getTimeZone());
- assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
- // env 2:
- assertEquals(otherTZ1, env2.getTimeZone());
- assertEquals(otherTZ2, env2.getSQLDateAndTimeTimeZone());
-
- try {
- setTimeZoneToNull(env2);
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
- env2.setSQLDateAndTimeTimeZone(null);
- assertEquals(otherTZ1, env2.getTimeZone());
- assertNull(env2.getSQLDateAndTimeTimeZone());
- }
- }
-
- @SuppressFBWarnings(value="NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS", justification="Expected to fail")
- private void setTimeZoneToNull(Environment env2) {
- env2.setTimeZone(null);
- }
-
- public void testSetICIViaSetSettingAPI() throws ConfigurationException {
- Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertEquals(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS, cfg.getIncompatibleImprovements());
- // This is the only valid value ATM:
- cfg.setSetting(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY, "3.0.0");
- assertEquals(Configuration.VERSION_3_0_0, cfg.getIncompatibleImprovements());
- }
-
- public void testSetLogTemplateExceptionsViaSetSettingAPI() throws ConfigurationException {
- Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertFalse(cfg.getLogTemplateExceptions());
- cfg.setSetting(MutableProcessingConfiguration.LOG_TEMPLATE_EXCEPTIONS_KEY, "true");
- assertTrue(cfg.getLogTemplateExceptions());
- }
-
- public void testSharedVariables() throws TemplateException, IOException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- Map<String, Object> vars = new HashMap<>();
- vars.put("a", "aa");
- vars.put("b", "bb");
- vars.put("c", new MyScalarModel());
- cfgB.setSharedVariables(vars);
-
- assertNull(cfgB.getSharedVariable("erased"));
-
- {
- Configuration cfg = cfgB.build();
-
- TemplateScalarModel aVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("a");
- assertEquals("aa", aVal.getAsString());
- assertEquals(SimpleScalar.class, aVal.getClass());
-
- TemplateScalarModel bVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("b");
- assertEquals("bb", bVal.getAsString());
- assertEquals(SimpleScalar.class, bVal.getClass());
-
- TemplateScalarModel cVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("c");
- assertEquals("my", cVal.getAsString());
- assertEquals(MyScalarModel.class, cfg.getWrappedSharedVariable("c").getClass());
-
- // See if it actually works in templates:
- StringWriter sw = new StringWriter();
- new Template(null, "${a} ${b}", cfg)
- .process(ImmutableMap.of("a", "aaDM"), sw);
- assertEquals("aaDM bb", sw.toString());
- }
-
- cfgB.setSharedVariable("b", "bbLegacy");
-
- {
- Configuration cfg = cfgB.build();
-
- TemplateScalarModel aVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("a");
- assertEquals("aa", aVal.getAsString());
- assertEquals(SimpleScalar.class, aVal.getClass());
-
- TemplateScalarModel bVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("b");
- assertEquals("bbLegacy", bVal.getAsString());
- assertEquals(SimpleScalar.class, bVal.getClass());
- }
- }
-
- @Test
- public void testApiBuiltinEnabled() throws Exception {
- try {
- new Template(
- null, "${1?api}",
- new Configuration.Builder(Configuration.VERSION_3_0_0).build())
- .process(null, _NullWriter.INSTANCE);
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsString(MutableProcessingConfiguration.API_BUILTIN_ENABLED_KEY));
- }
-
- new Template(
- null, "${m?api.hashCode()}",
- new Configuration.Builder(Configuration.VERSION_3_0_0).apiBuiltinEnabled(true).build())
- .process(Collections.singletonMap("m", new HashMap()), _NullWriter.INSTANCE);
- }
-
- @Test
- public void testTemplateUpdateDelay() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(DefaultTemplateResolver.DEFAULT_TEMPLATE_UPDATE_DELAY_MILLIS, cfgB.getTemplateUpdateDelayMilliseconds());
-
- cfgB.setTemplateUpdateDelayMilliseconds(4000);
- assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds());
-
- cfgB.setTemplateUpdateDelayMilliseconds(100);
- assertEquals(100L, cfgB.getTemplateUpdateDelayMilliseconds());
-
- try {
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5");
- assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds());
- } catch (ConfigurationSettingValueException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("unit must be specified"));
- }
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "0");
- assertEquals(0L, cfgB.getTemplateUpdateDelayMilliseconds());
- try {
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5 foo");
- assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds());
- } catch (ConfigurationSettingValueException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("\"foo\""));
- }
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 ms");
- assertEquals(3L, cfgB.getTemplateUpdateDelayMilliseconds());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4ms");
- assertEquals(4L, cfgB.getTemplateUpdateDelayMilliseconds());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 s");
- assertEquals(3000L, cfgB.getTemplateUpdateDelayMilliseconds());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4s");
- assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 m");
- assertEquals(1000L * 60 * 3, cfgB.getTemplateUpdateDelayMilliseconds());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4m");
- assertEquals(1000L * 60 * 4, cfgB.getTemplateUpdateDelayMilliseconds());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "1 h");
- assertEquals(1000L * 60 * 60, cfgB.getTemplateUpdateDelayMilliseconds());
- cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "2h");
- assertEquals(1000L * 60 * 60 * 2, cfgB.getTemplateUpdateDelayMilliseconds());
- }
-
- @Test
- @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS ", justification = "Testing wrong args")
- public void testSetCustomNumberFormat() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- try {
- cfgB.setCustomNumberFormats(null);
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("null"));
- }
-
- try {
- cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
- "", HexTemplateNumberFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("0 length"));
- }
-
- try {
- cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
- "a_b", HexTemplateNumberFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("a_b"));
- }
-
- try {
- cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
- "a b", HexTemplateNumberFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("a b"));
- }
-
- try {
- cfgB.setCustomNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
- "a", HexTemplateNumberFormatFactory.INSTANCE,
- "@wrong", HexTemplateNumberFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("@wrong"));
- }
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE,
- "{ 'base': " + BaseNTemplateNumberFormatFactory.class.getName() + "() }");
- assertEquals(
- Collections.singletonMap("base", BaseNTemplateNumberFormatFactory.INSTANCE),
- cfgB.getCustomNumberFormats());
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_SNAKE_CASE,
- "{ "
- + "'base': " + BaseNTemplateNumberFormatFactory.class.getName() + "(), "
- + "'hex': " + HexTemplateNumberFormatFactory.class.getName() + "()"
- + " }");
- assertEquals(
- ImmutableMap.of(
- "base", BaseNTemplateNumberFormatFactory.INSTANCE,
- "hex", HexTemplateNumberFormatFactory.INSTANCE),
- cfgB.getCustomNumberFormats());
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY, "{}");
- assertEquals(Collections.emptyMap(), cfgB.getCustomNumberFormats());
-
- try {
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE,
- "{ 'x': " + EpochMillisTemplateDateFormatFactory.class.getName() + "() }");
- fail();
- } catch (ConfigurationException e) {
- assertThat(e.getCause().getMessage(), allOf(
- containsString(EpochMillisTemplateDateFormatFactory.class.getName()),
- containsString(TemplateNumberFormatFactory.class.getName())));
- }
- }
-
- @Test
- public void testSetTabSize() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- String ftl = "${\t}";
-
- try {
- new Template(null, ftl, cfgB.build());
- fail();
- } catch (ParseException e) {
- assertEquals(9, e.getColumnNumber());
- }
-
- cfgB.setTabSize(1);
- try {
- new Template(null, ftl, cfgB.build());
- fail();
- } catch (ParseException e) {
- assertEquals(4, e.getColumnNumber());
- }
-
- try {
- cfgB.setTabSize(0);
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
-
- try {
- cfgB.setTabSize(257);
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testTabSizeSetting() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- assertEquals(8, cfgB.getTabSize());
- cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_CAMEL_CASE, "4");
- assertEquals(4, cfgB.getTabSize());
- cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_SNAKE_CASE, "1");
- assertEquals(1, cfgB.getTabSize());
-
- try {
- cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_SNAKE_CASE, "x");
- fail();
- } catch (ConfigurationException e) {
- assertThat(e.getCause(), instanceOf(NumberFormatException.class));
- }
- }
-
- @SuppressFBWarnings(value="NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS", justification="We test failures")
- @Test
- public void testSetCustomDateFormat() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- try {
- cfgB.setCustomDateFormats(null);
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("null"));
- }
-
- try {
- cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
- "", EpochMillisTemplateDateFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("0 length"));
- }
-
- try {
- cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
- "a_b", EpochMillisTemplateDateFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("a_b"));
- }
-
- try {
- cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
- "a b", EpochMillisTemplateDateFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("a b"));
- }
-
- try {
- cfgB.setCustomDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
- "a", EpochMillisTemplateDateFormatFactory.INSTANCE,
- "@wrong", EpochMillisTemplateDateFormatFactory.INSTANCE));
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("@wrong"));
- }
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE,
- "{ 'epoch': " + EpochMillisTemplateDateFormatFactory.class.getName() + "() }");
- assertEquals(
- Collections.singletonMap("epoch", EpochMillisTemplateDateFormatFactory.INSTANCE),
- cfgB.getCustomDateFormats());
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_SNAKE_CASE,
- "{ "
- + "'epoch': " + EpochMillisTemplateDateFormatFactory.class.getName() + "(), "
- + "'epochDiv': " + EpochMillisDivTemplateDateFormatFactory.class.getName() + "()"
- + " }");
- assertEquals(
- ImmutableMap.of(
- "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
- "epochDiv", EpochMillisDivTemplateDateFormatFactory.INSTANCE),
- cfgB.getCustomDateFormats());
-
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY, "{}");
- assertEquals(Collections.emptyMap(), cfgB.getCustomDateFormats());
-
- try {
- cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE,
- "{ 'x': " + HexTemplateNumberFormatFactory.class.getName() + "() }");
- fail();
- } catch (ConfigurationException e) {
- assertThat(e.getCause().getMessage(), allOf(
- containsString(HexTemplateNumberFormatFactory.class.getName()),
- containsString(TemplateDateFormatFactory.class.getName())));
- }
- }
-
- public void testNamingConventionSetSetting() throws ConfigurationException {
- Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention());
-
- cfg.setSetting("naming_convention", "legacy");
- assertEquals(ParsingConfiguration.LEGACY_NAMING_CONVENTION, cfg.getNamingConvention());
-
- cfg.setSetting("naming_convention", "camel_case");
- assertEquals(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION, cfg.getNamingConvention());
-
- cfg.setSetting("naming_convention", "auto_detect");
- assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention());
- }
-
- public void testLazyImportsSetSetting() throws ConfigurationException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertFalse(cfgB.getLazyImports());
- assertFalse(cfgB.isLazyImportsSet());
- cfgB.setSetting("lazy_imports", "true");
- assertTrue(cfgB.getLazyImports());
- cfgB.setSetting("lazyImports", "false");
- assertFalse(cfgB.getLazyImports());
- assertTrue(cfgB.isLazyImportsSet());
- }
-
- public void testLazyAutoImportsSetSetting() throws ConfigurationException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertNull(cfgB.getLazyAutoImports());
- assertFalse(cfgB.isLazyAutoImportsSet());
- cfgB.setSetting("lazy_auto_imports", "true");
- assertEquals(Boolean.TRUE, cfgB.getLazyAutoImports());
- assertTrue(cfgB.isLazyAutoImportsSet());
- cfgB.setSetting("lazyAutoImports", "false");
- assertEquals(Boolean.FALSE, cfgB.getLazyAutoImports());
- cfgB.setSetting("lazyAutoImports", "null");
- assertNull(cfgB.getLazyAutoImports());
- assertTrue(cfgB.isLazyAutoImportsSet());
- cfgB.unsetLazyAutoImports();
- assertNull(cfgB.getLazyAutoImports());
- assertFalse(cfgB.isLazyAutoImportsSet());
- }
-
- public void testLocaleSetting() throws TemplateException, ConfigurationException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(Locale.getDefault(), cfgB.getLocale());
- assertFalse(cfgB.isLocaleSet());
-
- Locale nonDefault = Locale.getDefault().equals(Locale.GERMANY) ? Locale.FRANCE : Locale.GERMANY;
- cfgB.setLocale(nonDefault);
- assertTrue(cfgB.isLocaleSet());
- assertEquals(nonDefault, cfgB.getLocale());
-
- cfgB.unsetLocale();
- assertEquals(Locale.getDefault(), cfgB.getLocale());
- assertFalse(cfgB.isLocaleSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.LOCALE_KEY, "JVM default");
- assertEquals(Locale.getDefault(), cfgB.getLocale());
- assertTrue(cfgB.isLocaleSet());
- }
-
- public void testDefaultEncodingSetting() throws TemplateException, ConfigurationException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
- assertFalse(cfgB.isSourceEncodingSet());
-
- Charset nonDefault = Charset.defaultCharset().equals(StandardCharsets.UTF_8) ? StandardCharsets.ISO_8859_1
- : StandardCharsets.UTF_8;
- cfgB.setSourceEncoding(nonDefault);
- assertTrue(cfgB.isSourceEncodingSet());
- assertEquals(nonDefault, cfgB.getSourceEncoding());
-
- cfgB.unsetSourceEncoding();
- assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
- assertFalse(cfgB.isSourceEncodingSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY, "JVM default");
- assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
- assertTrue(cfgB.isSourceEncodingSet());
- }
-
- public void testTimeZoneSetting() throws TemplateException, ConfigurationException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
- assertFalse(cfgB.isTimeZoneSet());
-
- TimeZone nonDefault = TimeZone.getDefault().equals(_DateUtil.UTC) ? TimeZone.getTimeZone("PST") : _DateUtil.UTC;
- cfgB.setTimeZone(nonDefault);
- assertTrue(cfgB.isTimeZoneSet());
- assertEquals(nonDefault, cfgB.getTimeZone());
-
- cfgB.unsetTimeZone();
- assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
- assertFalse(cfgB.isTimeZoneSet());
-
- cfgB.setSetting(Configuration.ExtendableBuilder.TIME_ZONE_KEY, "JVM default");
- assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
- assertTrue(cfgB.isTimeZoneSet());
- }
-
- @Test
- public void testGetSettingNamesAreSorted() throws Exception {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
- for (boolean camelCase : new boolean[] { false, true }) {
- List<String> names = new ArrayList<>(Configuration.Builder.getSettingNames(camelCase));
- List<String> procCfgNames = new ArrayList<>(new Template(null, "", cfg)
- .createProcessingEnvironment(null, _NullWriter.INSTANCE)
- .getSettingNames(camelCase));
- assertStartsWith(names, procCfgNames);
-
- String prevName = null;
- for (int i = procCfgNames.size(); i < names.size(); i++) {
- String name = names.get(i);
- if (prevName != null) {
- assertThat(name, greaterThan(prevName));
- }
- prevName = name;
- }
- }
- }
-
- @Test
- @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
- public void testGetSettingNamesNameConventionsContainTheSame() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- ConfigurableTest.testGetSettingNamesNameConventionsContainTheSame(
- new ArrayList<>(cfgB.getSettingNames(false)),
- new ArrayList<>(cfgB.getSettingNames(true)));
- }
-
- @Test
- @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
- public void testStaticFieldKeysCoverAllGetSettingNames() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- List<String> names = new ArrayList<>(cfgB.getSettingNames(false));
- List<String> cfgableNames = new ArrayList<>(cfgB.getSettingNames(false));
- assertStartsWith(names, cfgableNames);
-
- for (int i = cfgableNames.size(); i < names.size(); i++) {
- String name = names.get(i);
- assertTrue("No field was found for " + name, keyFieldExists(name));
- }
- }
-
- @Test
- public void testGetSettingNamesCoversAllStaticKeyFields() throws Exception {
- Collection<String> names = new Configuration.Builder(Configuration.VERSION_3_0_0).getSettingNames(false);
-
- for (Class<? extends MutableProcessingConfiguration> cfgableClass : new Class[] { Configuration.class, MutableProcessingConfiguration.class }) {
- for (Field f : cfgableClass.getFields()) {
- if (f.getName().endsWith("_KEY")) {
- final Object name = f.get(null);
- assertTrue("Missing setting name: " + name, names.contains(name));
- }
- }
- }
- }
-
- @Test
- public void testKeyStaticFieldsHasAllVariationsAndCorrectFormat() throws IllegalArgumentException, IllegalAccessException {
- ConfigurableTest.testKeyStaticFieldsHasAllVariationsAndCorrectFormat(Configuration.ExtendableBuilder.class);
- }
-
- @Test
- public void testGetSettingNamesCoversAllSettingNames() throws Exception {
- Collection<String> names = new Configuration.Builder(Configuration.VERSION_3_0_0).getSettingNames(false);
-
- for (Field f : MutableProcessingConfiguration.class.getFields()) {
- if (f.getName().endsWith("_KEY")) {
- final Object name = f.get(null);
- assertTrue("Missing setting name: " + name, names.contains(name));
- }
- }
- }
-
- @Test
- public void testSetSettingSupportsBothNamingConventions() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_CAMEL_CASE, StandardCharsets.UTF_16LE.name());
- assertEquals(StandardCharsets.UTF_16LE, cfgB.getSourceEncoding());
- cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_SNAKE_CASE, StandardCharsets.UTF_8.name());
- assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
-
- for (String nameCC : cfgB.getSettingNames(true)) {
- for (String value : new String[] { "1", "default", "true" }) {
- Exception resultCC = null;
- try {
- cfgB.setSetting(nameCC, value);
- } catch (Exception e) {
- assertThat(e, not(instanceOf(UnknownConfigurationSettingException.class)));
- resultCC = e;
- }
-
- String nameSC = _StringUtil.camelCaseToUnderscored(nameCC);
- Exception resultSC = null;
- try {
- cfgB.setSetting(nameSC, value);
- } catch (Exception e) {
- assertThat(e, not(instanceOf(UnknownConfigurationSettingException.class)));
- resultSC = e;
- }
-
- if (resultCC == null) {
- assertNull(resultSC);
- } else {
- assertNotNull(resultSC);
- assertEquals(resultCC.getClass(), resultSC.getClass());
- }
- }
- }
- }
-
- @Test
- public void testGetSupportedBuiltInDirectiveNames() {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
-
- Set<String> allNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
- Set<String> lNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- Set<String> cNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
-
- checkNamingConventionNameSets(allNames, lNames, cNames);
-
- for (String name : cNames) {
- assertThat(name.toLowerCase(), isIn(lNames));
- }
- }
-
- @Test
- public void testGetSupportedBuiltInNames() {
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
-
- Set<String> allNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
- Set<String> lNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- Set<String> cNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
-
- checkNamingConventionNameSets(allNames, lNames, cNames);
- }
-
- private void checkNamingConventionNameSets(Set<String> allNames, Set<String> lNames, Set<String> cNames) {
- for (String name : lNames) {
- assertThat(allNames, hasItem(name));
- assertTrue("Should be all-lowercase: " + name, name.equals(name.toLowerCase()));
- }
- for (String name : cNames) {
- assertThat(allNames, hasItem(name));
- }
- for (String name : allNames) {
- assertThat(name, anyOf(isIn(lNames), isIn(cNames)));
- }
- assertEquals(lNames.size(), cNames.size());
- }
-
- @Test
- public void testRemovedSettings() {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- try {
- cfgB.setSetting("classic_compatible", "true");
- fail();
- } catch (ConfigurationException e) {
- assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0")));
- }
- try {
- cfgB.setSetting("strict_syntax", "true");
- fail();
- } catch (ConfigurationException e) {
- assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0")));
- }
- }
-
- @SuppressWarnings("boxing")
- private void assertStartsWith(List<String> list, List<String> headList) {
- int index = 0;
- for (String name : headList) {
- assertThat(index, lessThan(list.size()));
- assertEquals(name, list.get(index));
- index++;
- }
- }
-
- private boolean keyFieldExists(String name) throws Exception {
- Field field;
- try {
- field = Configuration.class.getField(name.toUpperCase() + "_KEY");
- } catch (NoSuchFieldException e) {
- return false;
- }
- assertEquals(name, field.get(null));
- return true;
- }
-
- private static class MyScalarModel implements TemplateScalarModel {
-
- @Override
- public String getAsString() throws TemplateModelException {
- return "my";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
deleted file mode 100644
index 6714fc3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.util.Locale;
-
-import org.apache.freemarker.core.util._LocaleUtil;
-import org.junit.Test;
-
-public class CoreLocaleUtilsTest {
-
- @Test
- public void testGetLessSpecificLocale() {
- Locale locale;
-
- locale = new Locale("ru", "RU", "Linux");
- assertEquals("ru_RU_Linux", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertEquals("ru_RU", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertEquals("ru", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
-
- locale = new Locale("ch", "CH");
- assertEquals("ch_CH", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertEquals("ch", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
-
- locale = new Locale("ja");
- assertEquals("ja", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
-
- locale = new Locale("ja", "", "");
- assertEquals("ja", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
-
- locale = new Locale("");
- assertEquals("", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
-
- locale = new Locale("hu", "", "Linux");
- assertEquals("hu__Linux", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertEquals("hu", locale.toString());
- locale = _LocaleUtil.getLessSpecificLocale(locale);
- assertNull(locale);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
deleted file mode 100644
index 726a20c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-@SuppressWarnings("boxing")
-public class CustomAttributeTest {
-
- private static final String KEY_1 = "key1";
- private static final String KEY_2 = "key2";
- private static final String KEY_3 = "key3";
- private static final Integer KEY_4 = 4;
-
- private static final Integer VALUE_1 = 1; // Serializable
- private static final Object VALUE_2 = new Object();
- private static final Object VALUE_3 = new Object();
- private static final Object VALUE_4 = new Object();
- private static final Object VALUE_LIST = ImmutableList.<Object>of(
- "s", BigDecimal.valueOf(2), Boolean.TRUE, ImmutableMap.of("a", "A"));
- private static final Object VALUE_BIGDECIMAL = BigDecimal.valueOf(22);
-
- private static final Object CUST_ATT_KEY = new Object();
-
- @Test
- public void testStringKey() throws Exception {
- // Need some MutableProcessingConfiguration:
- TemplateConfiguration.Builder mpc = new TemplateConfiguration.Builder();
-
- assertEquals(0, mpc.getCustomAttributeNames().length);
- assertNull(mpc.getCustomAttribute(KEY_1));
-
- mpc.setCustomAttribute(KEY_1, VALUE_1);
- assertArrayEquals(new String[] { KEY_1 }, mpc.getCustomAttributeNames());
- assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
-
- mpc.setCustomAttribute(KEY_2, VALUE_2);
- assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
- assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
- assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
-
- mpc.setCustomAttribute(KEY_1, VALUE_2);
- assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
- assertSame(VALUE_2, mpc.getCustomAttribute(KEY_1));
- assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
-
- mpc.setCustomAttribute(KEY_1, null);
- assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
- assertNull(mpc.getCustomAttribute(KEY_1));
- assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
-
- mpc.removeCustomAttribute(KEY_1);
- assertArrayEquals(new String[] { KEY_2 }, mpc.getCustomAttributeNames());
- assertNull(mpc.getCustomAttribute(KEY_1));
- assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
- }
-
- @Test
- public void testRemoveFromEmptySet() throws Exception {
- // Need some MutableProcessingConfiguration:
- TemplateConfiguration.Builder mpc = new TemplateConfiguration.Builder();
-
- mpc.removeCustomAttribute(KEY_1);
- assertEquals(0, mpc.getCustomAttributeNames().length);
- assertNull(mpc.getCustomAttribute(KEY_1));
-
- mpc.setCustomAttribute(KEY_1, VALUE_1);
- assertArrayEquals(new String[] { KEY_1 }, mpc.getCustomAttributeNames());
- assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
- }
-
- @Test
- public void testAttrsFromFtlHeaderOnly() throws Exception {
- Template t = new Template(null, "<#ftl attributes={"
- + "'" + KEY_1 + "': [ 's', 2, true, { 'a': 'A' } ], "
- + "'" + KEY_2 + "': " + VALUE_BIGDECIMAL + " "
- + "}>",
- new Configuration.Builder(Configuration.VERSION_3_0_0).build());
-
- assertEquals(ImmutableSet.of(KEY_1, KEY_2), t.getCustomAttributes().keySet());
- assertEquals(VALUE_LIST, t.getCustomAttribute(KEY_1));
- assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
-
- t.setCustomAttribute(KEY_1, VALUE_1);
- assertEquals(VALUE_1, t.getCustomAttribute(KEY_1));
- assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
-
- t.setCustomAttribute(KEY_1, null);
- assertEquals(ImmutableSet.of(KEY_1, KEY_2), t.getCustomAttributes().keySet());
- assertNull(t.getCustomAttribute(KEY_1));
- }
-
- @Test
- public void testAttrsFromFtlHeaderAndFromTemplateConfiguration() throws Exception {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setCustomAttribute(KEY_3, VALUE_3);
- tcb.setCustomAttribute(KEY_4, VALUE_4);
- Template t = new Template(null, "<#ftl attributes={"
- + "'" + KEY_1 + "': 'a', "
- + "'" + KEY_2 + "': 'b', "
- + "'" + KEY_3 + "': 'c' "
- + "}>",
- new Configuration.Builder(Configuration.VERSION_3_0_0).build(),
- tcb.build());
-
- assertEquals(ImmutableSet.of(KEY_1, KEY_2, KEY_3, KEY_4), t.getCustomAttributes().keySet());
- assertEquals("a", t.getCustomAttribute(KEY_1));
- assertEquals("b", t.getCustomAttribute(KEY_2));
- assertEquals("c", t.getCustomAttribute(KEY_3)); // Has overridden TC attribute
- assertEquals(VALUE_4, t.getCustomAttribute(KEY_4)); // Inherited TC attribute
-
- t.setCustomAttribute(KEY_3, null);
- assertEquals(ImmutableSet.of(KEY_1, KEY_2, KEY_3, KEY_4), t.getCustomAttributes().keySet());
- assertNull("null value shouldn't cause fallback to TC attribute", t.getCustomAttribute(KEY_3));
- }
-
-
- @Test
- public void testAttrsFromTemplateConfigurationOnly() throws Exception {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setCustomAttribute(KEY_3, VALUE_3);
- tcb.setCustomAttribute(KEY_4, VALUE_4);
- Template t = new Template(null, "",
- new Configuration.Builder(Configuration.VERSION_3_0_0).build(),
- tcb.build());
-
- assertEquals(ImmutableSet.of(KEY_3, KEY_4), t.getCustomAttributes().keySet());
- assertEquals(VALUE_3, t.getCustomAttribute(KEY_3));
- assertEquals(VALUE_4, t.getCustomAttribute(KEY_4));
- }
-
- private Object[] sort(String[] customAttributeNames) {
- Arrays.sort(customAttributeNames);
- return customAttributeNames;
- }
-
-}
[27/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-object-wrapper.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-object-wrapper.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-object-wrapper.ftl
new file mode 100644
index 0000000..bcf903d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-object-wrapper.ftl
@@ -0,0 +1,59 @@
+<#--
+ 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.
+-->
+<#list array as item>
+${item}
+</#list>
+${array?size}
+${array[0]}
+${array[1]}
+<#list list as item>
+${item}
+</#list>
+${list?size}
+${list?hasContent?then('not empty', 'empty')}
+${list[0]}
+${map.key}
+${map?api.get(objKey)}
+${obj.foo}
+<#if obj.foo?exists>hasfoo<#else>nofoo</#if>
+<#if obj.baz?exists>hasbaz<#else>nobaz</#if>
+${obj.bar[0]}
+${obj.getFoo()}
+${obj.overloaded(1?int)}
+${obj.overloaded("String")}
+${resourceBundle.message}
+${resourceBundle("format", date)}
+<#assign static = statics["org.apache.freemarker.test.templatesuite.models.BeanTestClass"]>
+${static.staticMethod()}
+${static.staticOverloaded(1)}
+${static.staticOverloaded("String")}
+${static.STATIC_FINAL_FIELD}
+${static.STATIC_FIELD}
+<#assign enum = enums["org.apache.freemarker.test.templatesuite.models.EnumTestClass"]>
+${enum.ONE}
+${enum.TWO}
+${enum.THREE}
+${(enum.ONE == enum.ONE)?string("true", "false")}
+${(enum.ONE == enum.TWO)?string("true", "false")}
+${enums["org.apache.freemarker.test.templatesuite.models.BeanTestClass"]?exists?string("true", "false")}
+${obj.something}
+${obj.publicInner.x}
+${obj.publicInner.m()}
+<@assertFails message="obj.privateInner.x">${obj.privateInner.x}</@>
+<@assertFails message="obj.privateInner.m">${obj.privateInner.m()}</@>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-xmlns.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-xmlns.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-xmlns.ftl
new file mode 100644
index 0000000..4f01835
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default-xmlns.ftl
@@ -0,0 +1,28 @@
+<#ftl ns_prefixes={"D" : "http://x.com", "y" : "http://y.com"}>
+<#--
+ 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.
+-->
+<#assign r = doc.*[0]>
+${r["N:t1"]?default('-')} = No NS
+${r["t2"]?default('-')} = x NS
+${r["y:t3"]?default('-')} = y NS
+${r["./D:t4"]?default('-')} = x NS
+
+<#assign bool = doc["true()"]>
+${bool?string}
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default.ftl
new file mode 100644
index 0000000..6ecf8b3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/default.ftl
@@ -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.
+-->
+${UNDEFINED!"foo"}
+
+<#assign duck = (FOO.BAR)!"luck">
+${duck}
+
+<#list UNDEFINED![] as item>
+ ${item}
+</#list>
+
+${UNDEFINED![]?size}
+
+<#if UNDEFINED??>
+ UNDEFINED is defined.
+<#else>
+ UNDEFINED is undefined.
+</#if>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/encoding-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/encoding-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/encoding-builtins.ftl
new file mode 100644
index 0000000..6ee2a26
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/encoding-builtins.ftl
@@ -0,0 +1,52 @@
+<#--
+ 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.
+-->
+FreeMarker: Encoding built-in tests
+
+<#assign x = "&<>\"'{}\\a/">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+rtf: [${x?rtf}]
+<#assign x = "a&a<a>a\"a'a{a}a\\">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+rtf: [${x?rtf}]
+<#assign x = "<<<<<">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+<#assign x = "{{{{{">
+rtf: [${x?rtf}]
+<#assign x = "">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+rtf: [${x?rtf}]
+<#assign x = "a">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+rtf: [${x?rtf}]
+<#assign x = "&">
+html: [${x?html}]
+xml: [${x?xml}]
+xhtml: [${x?xhtml}]
+<#assign x = "{">
+rtf: [${x?rtf}]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/escapes.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/escapes.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/escapes.ftl
new file mode 100644
index 0000000..20efc67
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/escapes.ftl
@@ -0,0 +1,79 @@
+<#--
+ 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.
+-->
+<#assign h=["","a","b","c"]>
+<#assign g={"x":1,"y":2,"z":3}>
+<#escape x as h[x]>
+${1}
+${2}
+${3}
+<#escape x as g[x]>
+${"x"}
+${"y"}
+${"z"}
+<#noescape>${1}</#noescape>
+<#noescape><#noescape>${1}</#noescape></#noescape>
+</#escape>
+${1}
+${2}
+${3}
+</#escape>
+<#escape x as x?html>
+${"<&>"}
+<#escape x as x?xml>
+${"<&>"}
+</#escape>
+${"<&>"}
+</#escape>
+---
+<#assign x = "<Mooo>">
+${x} = <Mooo>
+<#escape x as x?upper_case>
+ ${x} = <MOOO>
+ <#escape x as x?html>
+ ${x} = <MOOO>
+ <#noescape>
+ ${x} = <MOOO>
+ </#noescape>
+ ${x} = <MOOO>
+ </#escape>
+ ${x} = <MOOO>
+ <#noescape>
+ ${x} = <Mooo>
+ <#escape x as x?html>
+ ${x} = <Mooo>
+ <#noescape>
+ ${x} = <Mooo>
+ </#noescape>
+ ${x} = <Mooo>
+ </#escape>
+ ${x} = <Mooo>
+ </#noescape>
+ ${x} = <MOOO>
+</#escape>
+<#escape az as ["red", "green", "blue"][az-1]>
+ ${1} ${2} ${3}
+</#escape>
+---
+<#assign s = 'A&B'>
+<#escape x as '<' + x?html + '>[' + x?lower_case + '](' + x + ')'>
+ ${s} ${s + 2}
+ <#escape x as '{' + x?lower_case + '}' + x>
+ ${s} ${s + 2}
+ </#escape>
+</#escape>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception.ftl
new file mode 100644
index 0000000..83ae356
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception.ftl
@@ -0,0 +1,31 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Exception Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message} <br />
+${test}</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception2.ftl
new file mode 100644
index 0000000..83ae356
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception2.ftl
@@ -0,0 +1,31 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Exception Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message} <br />
+${test}</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception3.ftl
new file mode 100644
index 0000000..f386fec
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/exception3.ftl
@@ -0,0 +1,31 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Exception Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message} <br />
+${%@#$test}</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/existence-operators.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/existence-operators.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/existence-operators.ftl
new file mode 100644
index 0000000..2f9bdce
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/existence-operators.ftl
@@ -0,0 +1,141 @@
+<#--
+ 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.
+-->
+<@isIRE>${v}</@>
+<@isIRE>${w}</@>
+<@isNonFastIRE>${v}</@> <#-- To check that it isn't an IRE.FAST_INSTANCE -->
+
+<@assertEquals actual=v!'-' expected='-' />
+<@assertEquals actual=(v)!'-' expected='-' />
+<@assertEquals actual=(v!) expected='' />
+<@assertEquals actual=((v)!) expected='' />
+<@isNonFastIRE>${v}</@> <#-- To check that it isn't an IRE.FAST_INSTANCE -->
+<@assertEquals actual=v?? expected=false />
+<@assertEquals actual=(v)?? expected=false />
+<@assertEquals actual=v?default('-') expected='-' />
+<@assertEquals actual=(v)?default('-') expected='-' />
+<@isNonFastIRE>${v}</@> <#-- To check that it isn't an IRE.FAST_INSTANCE -->
+<@assertEquals actual=v?exists expected=false />
+<@assertEquals actual=(v)?exists expected=false />
+<@assertEquals actual=v?if_exists expected='' />
+<@assertEquals actual=(v)?if_exists expected='' />
+<@assertEquals actual=v?has_content expected=false />
+<@assertEquals actual=(v)?has_content expected=false />
+
+<@assertEquals actual=v?default(w, '-') expected='-' />
+<@assertEquals actual=v!w!'-' expected='-' />
+<#assign w = 'W'>
+<@assertEquals actual=v?default(w, '-') expected='W' />
+<@assertEquals actual=v!w!'-' expected='W' />
+
+<#list ['V', 1.5] as v>
+ <@assertEquals actual=v!'-' expected=v />
+ <@assertEquals actual=(v)!'-' expected=v />
+ <@assert test=v?? />
+ <@assert test=(v)?? />
+ <@assertEquals actual=v?default('-') expected=v />
+ <@assertEquals actual=(v)?default('-') expected=v />
+ <@assert test=v?exists />
+ <@assert test=(v)?exists />
+ <@assertEquals actual=v?if_exists expected=v />
+ <@assertEquals actual=(v)?if_exists expected=v />
+ <@assert test=v?has_content />
+ <@assert test=(v)?has_content />
+</#list>
+<@assert test=!v?? />
+<@assert test=!v?exists />
+<@isNonFastIRE>${v}</@> <#-- To check that it isn't an IRE.FAST_INSTANCE -->
+
+<@isIRE>${u.v!'-'}</@>
+<@assertEquals actual=(u.v)!'-' expected='-' />
+<@isIRE>${u.v??}</@>
+<@assertEquals actual=(u.v)?? expected=false />
+<@isIRE>${u.v?default('-')}</@>
+<@assertEquals actual=(u.v)?default('-') expected='-' />
+<@isIRE>${u.v?exists}</@>
+<@assertEquals actual=(u.v)?exists expected=false />
+<@isIRE>${u.v?if_exists}</@>
+<@assertEquals actual=(u.v)?if_exists expected='' />
+<@isIRE>${u.v?has_content}</@>
+<@assertEquals actual=(u.v)?has_content expected=false />
+
+<#assign u = { 'x': 'X' } >
+<@assertEquals actual=u.v!'-' expected='-' />
+<@assertEquals actual=(u.v)!'-' expected='-' />
+<@assertEquals actual=u.v?? expected=false />
+<@assertEquals actual=(u.v)?? expected=false />
+<@assertEquals actual=u.v?default('-') expected='-' />
+<@assertEquals actual=(u.v)?default('-') expected='-' />
+<@assertEquals actual=u.v?exists expected=false />
+<@assertEquals actual=(u.v)?exists expected=false />
+<@assertEquals actual=u.v?if_exists expected='' />
+<@assertEquals actual=(u.v)?if_exists expected='' />
+<@assertEquals actual=u.v?has_content expected=false />
+<@assertEquals actual=(u.v)?has_content expected=false />
+
+<#assign u = { 'v': 'V' } >
+<@assertEquals actual=u.v!'-' expected='V' />
+<@assertEquals actual=(u.v)!'-' expected='V' />
+<@assert test=u.v?? />
+<@assert test=(u.v)?? />
+<@assertEquals actual=u.v?default('-') expected='V' />
+<@assertEquals actual=(u.v)?default('-') expected='V' />
+<@assert test=u.v?exists />
+<@assert test=(u.v)?exists />
+<@assertEquals actual=u.v?if_exists expected='V' />
+<@assertEquals actual=(u.v)?if_exists expected='V' />
+<@assert test=u.v?has_content />
+<@assert test=(u.v)?has_content />
+
+<#list 1..4 as i>
+ <#if i == 3><#assign x = 'X'></#if>
+ <@assertEquals actual=((x!'-') == '-') expected=(i < 3) />
+</#list>
+
+<#macro attemptTest>
+ <#attempt>
+ ${fails}
+ <#recover>
+ <@assert test=isNonFastIREMessage(.error) />
+ </#attempt>
+</#macro>
+<@attemptTest />
+${(callMacroFromExpression(attemptTest))!}
+
+<#macro interpretTest><@'$\{fails}'?interpret /></#macro>
+<#attempt>
+ <@interpretTest />
+<#recover>
+ <@assert test=isNonFastIREMessage(.error) />
+</#attempt>
+<#attempt>
+ ${(callMacroFromExpression(interpretTest))!}
+<#recover>
+ <@assert test=isNonFastIREMessage(.error) />
+</#attempt>
+
+<@assertEquals actual='fails'?eval!'-' expected='-' />
+<@assertEquals actual=('fails')?eval!'-' expected='-' />
+
+<#macro isIRE><@assertFails exception="InvalidReferenceException"><#nested></@></#macro>
+<#macro isNonFastIRE><@assertFails exception="InvalidReferenceException" message="Tip:"><#nested></@></#macro>
+<#function isNonFastIREMessage msg><#return msg?contains('Tip:') && msg?contains('null or missing')></#function>
+<#function callMacroFromExpression m>
+ <#local captured><@m /></#local>
+ <#return captured>
+</#function>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashconcat.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashconcat.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashconcat.ftl
new file mode 100644
index 0000000..127d828
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashconcat.ftl
@@ -0,0 +1,60 @@
+[#ftl]
+[#--
+ 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.
+--]
+[#assign a = {"a":1, "b":2, "c":3, "X": 4}]
+[#assign b = {"d":10, "e":20, "f":30, "X": 40}]
+
+a:
+[@dump a /]
+
+B:
+[@dump b /]
+
+a + B:
+[@dump a + b /]
+
+B + a:
+[@dump b + a /]
+
+a + a:
+[@dump a + a /]
+
+{} + a:
+[@dump {} + a /]
+
+a + {}:
+[@dump a + {} /]
+
+{} + {}:
+[@dump {} + {} /]
+
+a + b + {} + b + {} + a:
+[@dump a + b + {} + b + {} + a /]
+
+
+[#macro dump s]
+[#list s?keys as k]
+ ${k} = ${s[k]}
+[/#list]
+ ---
+[#list s?values as v]
+ ${v}
+[/#list]
+ ---
+[/#macro]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashliteral.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashliteral.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashliteral.ftl
new file mode 100644
index 0000000..0a02a3a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/hashliteral.ftl
@@ -0,0 +1,100 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Hash Literal Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now perform a hash assignment:</p>
+
+<#assign mymessage = "hello", foo="bar", one="1">
+<#assign test = { "test1": "test23",
+ "test45" : message,
+ mymessage : "hello all",
+ foo: one}>
+
+${test.test1}
+${test.test45}
+${test.hello}
+${test.bar}
+
+<p>Now update the assignment and repeat:</p>
+
+<#assign mymessage = "world">
+
+${test.test1}
+${test.test45}
+${test.hello}
+
+${test.bar}
+
+<p>Now reassign the list and repeat:</p>
+
+<#assign hash= {"temp" : "Temporary"}>
+<#assign test = { "test1" : "test23",
+ "test45" : message,
+ mymessage : "hello all",
+ foo : one,
+ "hash" : hash[ "temp" ],
+ "true" : hash.temp,
+ "newhash" : hash}>
+
+${test.test1}
+${test.test45}
+${test.hello?if_exists}
+
+${test.bar}
+${test.hash}
+${test.true}
+${test.newhash.temp}
+
+<p>Pathological case: zero item hash:</p>
+
+<#assign test = {}>
+${test.test1?if_exists}
+
+<p>Hash of number literals:</p>
+<#assign test = {"1" : 2}>
+${test["1"]}
+
+<p>Hash concatenation:</p>
+<#assign cc = { "a" : 1, "b" : 2 } + { "b" : 3, "c" : 4 }>
+<#list cc?keys?sort as key>
+${key} => ${cc[key]}
+</#list>
+
+<p>Empty hash concatenation:</p>
+${({} + { "a" : "foo" }).a}, ${({ "a" : "bar" } + {}).a}
+
+</body>
+</html>
+<@noOutput>
+
+<#assign m = { 'a': 1, 'b', 2, 'a': 3 }>
+<@assertEquals expected="a, b" actual=m?keys?join(', ') />
+<@assertEquals expected="3, 2" actual=m?values?join(', ') />
+<@assertEquals expected=3 actual=m['a'] />
+<@assertEquals expected=2 actual=m['b'] />
+
+</...@noOutput>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/helloworld.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/helloworld.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/helloworld.ftl
new file mode 100644
index 0000000..91816f6
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/helloworld.ftl
@@ -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.
+-->
+<html>
+<head>
+<title>FreeMarker: Exec Model Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${exec( "java freemarker.test.HelloWorld" )}</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-escaping.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-escaping.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-escaping.ftl
new file mode 100644
index 0000000..9b39235
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-escaping.ftl
@@ -0,0 +1,81 @@
+<#--
+ 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.
+-->
+<#macro m\-a data\-color>
+ <#local \.namespace = 123>
+ <a-b>${data\-color}<#nested \.namespace></a-b><#t>
+</#macro>
+<#macro "m-b2"></#macro>
+<#macro "m/b2"></#macro>
+
+<@m\-a data\-color="red"; loop\-var>${loop\-var}</@>
+
+<#function f\-a p\-a>
+ <#return p\-a + " works">
+</#function>
+${f\-a("f-a")}
+
+<#assign \-\-\-\.\: = 'dash-dash-dash etc.'>
+${\-\-\-\.\:}
+${.vars['---.:']}
+<#assign hash = { '--moz-prop': 'propVal' }>
+${hash.\-\-moz\-prop}
+${hash['--moz-prop']}
+
+<#assign ls\:a = 1..3>
+List: <#list ls\:a as \:i>${\:i}</#list>
+
+<#assign sw\-a=1>
+Switch: <#switch sw\-a>
+ <#case 1>OK<#break>
+ <#default>Fails
+</#switch>
+
+<#escape \-x as \-x?upper_case>${'escaped'}</#escape>
+
+<#if false && sw\-a == 1>
+ <#visit x\-y2 using x\-y1>
+ <#recurse x\-y2 using x\-y1>
+ <#import i\-a as i\-b>
+ <#include i\-c>
+</#if>
+
+<#assign @as@_a = 'as1'>
+${@as@_a}
+<#assign 'as-c' = 'as2'>
+${.vars['as-c']}
+<#assign "as/b" = 'as3'>
+${.vars["as/b"]}
+<#assign "as'c" = 'as4'>
+${.vars["as'c"]}
+<#assign 'as"d' = 'as5'>
+${.vars['as"d']}
+
+<#global g\-a=1 g\-b=2 "g-c"=3>
+
+<#macro catchAll x y attrs...>
+<catchAll x=${x} y=${y}<#list attrs?keys?sort as k> ${k}=${attrs[k]}</#list> />
+</#macro>
+<@catchAll x=1 y=2 z=3 data\-foo=4 a\:b\.c=5 />
+
+<#macro dumpNS>
+ <#list .namespace?keys?sort as k>
+ ${k} = <#local v = .namespace[k]><#if v?is_string>${v}<#else>...</#if><#lt>
+ </#list>
+</#macro>
+<@dumpNS />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-non-ascii.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-non-ascii.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-non-ascii.ftl
new file mode 100644
index 0000000..59a4b0e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/identifier-non-ascii.ftl
@@ -0,0 +1,21 @@
+<#--
+ 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.
+-->
+<#macro árvíztűrőTükörfúrógép טֶקסט>${טֶקסט}</#macro>
+<#assign 한국어_키보드="Korean Keyboard">
+<@árvíztűrőTükörfúrógép 한국어_키보드 />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/if.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/if.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/if.ftl
new file mode 100644
index 0000000..97c3f4b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/if.ftl
@@ -0,0 +1,109 @@
+<#--
+ 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.
+-->
+<#assign x = 1>
+
+- <#if x == 1>good</#if>
+- <#if x == 1></#if>good
+- <#if x == 1>goo${missing!'d'}</#if>
+- <#if x == 0>wrong</#if>good
+
+- <#if x == 1>good<#else>wrong</#if>
+- <#if x == 0>wrong<#else>good</#if>
+
+- <#if x == 1>good<#elseif x == 2>wrong<#else>wrong</#if>
+- <#if x == 1>good<#elseif x == 1>wrong<#else>wrong</#if>
+- <#if x == 0>wrong<#elseif x == 1>good<#else>wrong</#if>
+- <#if x == 0>wrong<#elseif x == 2>wrong<#else>good</#if>
+
+- <#if x == 1>good<#elseif x == 1>wrong</#if>
+- <#if x == 0>wrong<#elseif x == 1>good</#if>
+- <#if x == 0>wrong<#elseif x == 2>wrong</#if>good
+- <#if x == 0>wrong<#elseif x == 1><#else>wrong</#if>good
+
+<#-- Same with pre-calculable results, just in case later the dead code will be optimized out: -->
+- <#if 1 == 1>good</#if>
+- <#if 1 == 0>wrong</#if>good
+- <#if 1 == 1>goo${missing!'d'}</#if>
+- <#if 1 == 0>wrong</#if>good
+
+- <#if 1 == 1>good<#else>wrong</#if>
+- <#if 1 == 0>wrong<#else>good</#if>
+
+- <#if 1 == 1>good<#elseif 1 == 2>wrong<#else>wrong</#if>
+- <#if 1 == 1>good<#elseif 1 == 1>wrong<#else>wrong</#if>
+- <#if 1 == 0>wrong<#elseif 1 == 1>good<#else>wrong</#if>
+- <#if 1 == 0>wrong<#elseif 1 == 2>wrong<#else>good</#if>
+
+- <#if 1 == 1>good<#elseif 1 == 1>wrong</#if>
+- <#if 1 == 0>wrong<#elseif 1 == 1>good</#if>
+- <#if 1 == 0>wrong<#elseif 1 == 2>wrong</#if>good
+- <#if 1 == 0>wrong<#elseif 1 == 1><#else>wrong</#if>good
+
+<#-- Varying branch choice of the same AST nodes: -->
+<#list [1, 2, 3, 4] as x>
+- <#if x == 1>1</#if>
+- <#if x == 2>2</#if>
+- <#if x == 3>3</#if>
+- <#if x == 1>is 1<#else>isn't 1</#if>
+- <#if x == 2>is 2<#else>isn't 2</#if>
+- <#if x == 3>is 3<#else>isn't 3</#if>
+- Finally, it's: <#if x == 1>1<#elseif x == 2>2<#elseif x == 3>3<#else>4</#if>
+</#list>
+
+<#-- nested -->
+<#list [1, 2, 3] as x><#list [1, 2, 3] as y>
+ <#assign y = x * x>
+ <#if x == 1>
+ 1:
+ <#if (x > y)>
+ > ${y}
+ <#elseif x == y>
+ == ${y}
+ <#else>
+ <= ${y}
+ </#if>
+ <#elseif x == 2>
+ 2:
+ <#if (x > y)>
+ > ${y}
+ <#elseif x == y>
+ == ${y}
+ <#else>
+ <= ${y}
+ </#if>
+ <#else>
+ 3:
+ <#if (x > y)>
+ > ${y}
+ <#elseif x == y>
+ == ${y}
+ <#else>
+ <= ${y}
+ </#if>
+ <#if x == 3 && y == 3>
+ End
+ </#if>
+ </#if>
+</#list></#list>
+
+<#-- parsing errors -->
+<@assertFails message="valid #if-#elseif-#else"><@"<#if t><#else><#elseif t2></#if>"?interpret /></@>
+<@assertFails message="valid #if-#elseif-#else"><@"<#if t><#else><#else></#if>"?interpret /></@>
+<@assertFails message="valid #if-#elseif-#else"><@"<#else></#else>"?interpret /></@>
+<@assertFails message="valid #if-#elseif-#else"><@"<#elseif t></#elseif>"?interpret /></@>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import.ftl
new file mode 100644
index 0000000..bddd857
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import.ftl
@@ -0,0 +1,45 @@
+<#--
+ 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.
+-->
+--
+<#-- import "/import_lib.ftl" as my -->
+--
+
+<#if mail?exists || test?exists>
+ <#stop "mail or test should not exist">
+</#if>
+
+${my.mail}
+<@my.test foo="bar"/>
+
+<#assign mail="jsmith@other1.com">
+${my.mail}
+<@my.test foo="bar"/>
+
+<#assign mail in my>
+ jsmith@other2.com<#t>
+</#assign>
+${my.mail}
+<@my.test foo="bar"/>
+
+<#import "/import_lib.ftl" as my2>
+${my2.mail}
+<#assign mail="jsmith@other3.com" in my2>
+${my.mail}
+
+${my2.doubleUp("foobar")}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import_lib.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import_lib.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import_lib.ftl
new file mode 100644
index 0000000..3329af9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/import_lib.ftl
@@ -0,0 +1,31 @@
+<#--
+ 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.
+-->
+<#macro test foo>
+ Test ${foo}.
+ Email: ${mail}
+ <#if .main.mail?exists>
+ Email in the root: ${.main.mail}
+ </#if>
+</#macro>
+
+<#function doubleUp foo>
+ <#return foo+foo>
+</#function>
+
+<#assign mail = "jsmith@acme.com">
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include.ftl
new file mode 100644
index 0000000..3e997e7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Include Instruction Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+${message}
+
+<#if message?exists>
+ <p>Message exists!
+</#if>
+
+<p>Test normal includes:</p>
+<#include "included.ftl">
+
+${foo}
+${nestedMessage}
+
+<@twice>
+Kilroy
+</...@twice>
+
+<p>Test subdir includes:</p>
+<#include "subdir/include-subdir.ftl">
+</body>
+</html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2-included.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2-included.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2-included.ftl
new file mode 100644
index 0000000..db9dfc1
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2-included.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+${'A'} próba
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2.ftl
new file mode 100644
index 0000000..5f3ccc3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/include2.ftl
@@ -0,0 +1,32 @@
+<#--
+ 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.
+-->
+<#include "include2" + "-included.ftl">
+<#assign s = "de">
+<#include "inclu" + s + "2-included.ftl">
+
+<#assign bTrue=true>
+<#assign bFalse=false>
+<#include "include2-included.ftl" ignore_missing=true>
+<#include "include2-included.ftl" ignore_missing=bTrue>
+<#include "include2-included.ftl" ignore_missing=false>
+<#include "include2-included.ftl" ignore_missing=bFalse>
+
+<@assertFails message="not found"><#include "missing.ftl"></@>
+[<#include "missing.ftl" ignore_missing=true>]
+[<#include "missing.ftl" ignore_missing=bTrue>]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/included.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/included.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/included.ftl
new file mode 100644
index 0000000..f711a67
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/included.ftl
@@ -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.
+-->
+<p>A test of included files:</p>
+
+<#if .globals.message?exists>
+ <p>Message exists!:<br />
+ ${.globals.message}</p>
+<#else>
+ <p>No message :(</p>
+</#if>
+
+<#assign foo="assigning from included template", bar=" Can you see me? ">
+<#macro twice><#nested/>${bar}<#nested/></#macro>
+<#include "nestedinclude.ftl">
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/interpret.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/interpret.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/interpret.ftl
new file mode 100644
index 0000000..41f8425
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/interpret.ftl
@@ -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.
+-->
+<#global x=["a", "b", "c"]>
+<#global templateSource = r"<#list x as y>${y}</#list>">
+<@templateSource?interpret>def</@>
+<@[templateSource]?interpret>def</@>
+<@[templateSource,"id"]?interpret>def</@>
+
+<#assign t = '<#macro m>M</#macro>'?interpret><@t /><@m/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/iterators.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/iterators.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/iterators.ftl
new file mode 100644
index 0000000..389abf3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/iterators.ftl
@@ -0,0 +1,71 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: List Iterator Test</title>
+</head>
+<body>
+<#assign list= ["one", "two", "three", "four", "five"]>
+<#assign hash = {"key", list}>
+<#assign hash2 = {"value", hash}>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now iterate over a list:</p>
+
+<#list list as item>
+<p>${item}</p>
+</#list>
+
+<p>Now iterate again:</p>
+
+<#list list as item>
+<p>${item_index}. ${item}</p>
+</#list>
+
+<p>Iterate over a list in a hash:</p>
+
+<#list hash.key as item>
+<p>${item}</p>
+</#list>
+
+<#list hash.key as item>
+<p>${item}</p>
+</#list>
+
+<#list hash[ "key" ] as item>
+<p>${item}</p>
+</#list>
+
+<#list hash["key"] as item>
+<p>${item}</p>
+</#list>
+
+<#list hash2["value"].key as key>
+<p>${key}</p>
+</#list>
+
+<#list hash2.value.key as az>
+<p>${az}</p>
+</#list>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/lastcharacter.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/lastcharacter.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/lastcharacter.ftl
new file mode 100644
index 0000000..e762356
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/lastcharacter.ftl
@@ -0,0 +1,31 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Last Character Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+ #{message?capitalize?length}
+
+ ${message [1..] ? upper_case}
+
+ message: ${message ?capitalize[0..10]}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list-bis.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list-bis.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list-bis.ftl
new file mode 100644
index 0000000..e52307f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list-bis.ftl
@@ -0,0 +1,48 @@
+<#--
+ 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.
+-->
+<#list ['a', 'b', 'c'] as x>
+ ${x?index}: ${x} [<#list ['A', 'B', 'C'] as x>${x?index}:${x}<#sep>, </#list>]
+</#list>
+
+<#list ['a', 'b', 'c'] as i>
+ ${i?index}: ${i} <#list ['A', 'B', 'C'] as j>${i?index}${i}/${j?index}${j}<#sep>, </#list>
+</#list>
+
+<#list ['a', 'b', 'c']><#items as x>${x?index}:${x}<#sep>, </#items></#list>
+<#list ['a', 'b', 'c']><#items as x>${x?counter}. ${x};<#sep> </#items></#list>
+
+<#list ['a', 'b', 'c'] as x>${x}<#if x?hasNext>, </#if></#list>
+<#list ['a', 'b', 'c'] as x\-y>${x\-y}<#if x\-y?hasNext>, </#if></#list>
+
+<#list ['a', 'b', 'c'] as x><#if x?isFirst>${x?capFirst}<#else>${x}</#if><#sep>, </#sep><#if x?isLast>.</#if></#list>
+
+<#list ['a', 'b', 'c'] as x>${x?isOddItem?c}/${x?isEvenItem?c}<#sep> </#list>
+
+<#list ['a', 'b', 'c'] as x>
+ <td class="${x?itemParity}Row">${x}</td>
+</#list>
+
+<#list ['a', 'b', 'c'] as x>
+ <td class="row${x?itemParityCap}">${x}</td>
+</#list>
+
+<#list ['a', 'b', 'c', 'd', 'e', 'f', 'g'] as x>
+ <td class="${x?itemCycle('R', 'G', 'B')}">${x}</td>
+</#list>
+<@assertFails message="expects 1"><#list 1..1 as x>${x?itemCycle()}</#list></@>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list.ftl
new file mode 100644
index 0000000..280491c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list.ftl
@@ -0,0 +1,44 @@
+<#--
+ 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.
+-->
+<@testList ["aardvark", "bear", "cat", "dog"] />
+
+<@testList ["aardvark"] />
+
+<@testList [] />
+
+<@testList listables.list />
+
+<@testList listables.linkedList />
+
+<@testList listables.set />
+
+<@testList listables.iterator />
+
+<@testList listables.emptyList />
+
+<@testList listables.emptyLinkedList />
+
+<@testList listables.emptySet />
+
+<@testList listables.emptyIterator />
+
+<#macro testList seq>
+Size: <#attempt>${seq?size}<#recover>failed</#attempt>
+Items: <#list seq as i>@${i_index} ${i}<#if i_has_next>, <#else>.</#if></#list>
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list2.ftl
new file mode 100644
index 0000000..db64a4b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list2.ftl
@@ -0,0 +1,90 @@
+<#--
+ 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.
+-->
+<@testList ["aardvark", "bear", "cat", "dog"] />
+
+<@testList ["aardvark"] />
+
+<@testList [] />
+
+<@testList listables.list />
+
+<@testList listables.set />
+
+<@testList listables.getIterator />
+
+<@testList listables.emptyList />
+
+<@testList listables.emptySet />
+
+<@testList listables.getEmptyIterator />
+
+<#macro testList xs>
+=== [${resolve(xs)?join(", ")}] ===
+<#assign resolveCallCnt = 0>
+
+-- List+sep:
+<#list resolve(xs) as x>
+ ${x}<#sep>,</#sep>
+</#list>
+-- List+else:
+<#list resolve(xs) as x>
+ ${x}
+<#else>
+ Empty!
+</#list>
+-- List+items:
+<#list resolve(xs)>
+ [
+ <#items as x>
+ ${x!'U'}
+ </#items>
+ ]
+</#list>
+-- List+items+else:
+<#list resolve(xs)>
+ [
+ <#items as x>
+ ${x!'U'}
+ </#items>
+ ]
+<#else>
+ Empty!
+</#list>
+-- List+items+sep+else:
+<#list resolve(xs)>
+ [
+ <#items as x>
+ ${x!'U'}<#sep>,</#sep>
+ </#items>
+ ]
+<#else>
+ Empty!
+</#list>
+<@assertEquals expected=5 actual=resolveCallCnt />
+--
+</#macro>
+
+<#function resolve xs>
+ <#assign resolveCallCnt = (resolveCallCnt!0) + 1>
+ <#if xs?isMethod>
+ <#return xs()>
+ <#else>
+ <#return xs>
+ </#if>
+</#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list3.ftl
new file mode 100644
index 0000000..d2fcf71
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/list3.ftl
@@ -0,0 +1,70 @@
+<#--
+ 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.
+-->
+[
+<#list listables.list as i>
+ [<#list listables.list as j>(${i}@${i_index}, ${j}@${j_index})<#sep>, </#sep></#list>]<#sep>,</#sep>
+</#list>
+]
+
+<#macro hits xs style="">
+ <#list xs>
+ <p>${xs?size} hits:
+ <div class="hits">
+ <#switch style>
+ <#case "hidden">
+ ...
+ <#break>
+ <#case "other">
+ <#items as x>
+ <div class="hitOther">${x}</div>
+ </#items>
+ <#break>
+ <#case "none">
+ <#default>
+ <#items as x>
+ <div class="hit">${x}</div>
+ </#items>
+ <#break>
+ </#switch>
+ </div>
+ <#else>
+ <p>Nothing.
+ </#list>
+</#macro>
+
+<@hits ['a', 'b'] />
+
+<@hits ['a', 'b'], "other" />
+
+<@hits ['a', 'b'], "hidden" />
+
+<@hits [] />
+
+<#list listables.list as i><#if i_index gt 1>...<#break></#if>${i}<#sep>, </#sep></#list>
+<#list listables.list>[<#items as i><#if i_index gt 1>...<#break></#if>${i}<#sep>, </#sep></#items>]</#list>
+
+<@testAutoClosedSep 1..3 />
+<@testAutoClosedSep [1] />
+<@testAutoClosedSep [] />
+
+<#macro testAutoClosedSep xs>
+<#list xs as x>${x}<#sep>, <#else>Empty</#list>
+<#list xs as x>${x}<#sep><#if x_index == 0> /*first*/, <#else>, </#if><#else>Empty</#list>
+<#list xs>[<#items as x>${x}<#sep>, </#items>]<#else>Empty</#list>
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhash.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhash.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhash.ftl
new file mode 100644
index 0000000..6f22b43
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhash.ftl
@@ -0,0 +1,70 @@
+<#--
+ 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.
+-->
+<#setting booleanFormat='Y,N'>
+
+<#macro listings maps>
+ <#list maps as m>
+ Map:
+
+ [
+ <#list m as k, v>
+ ${k!'null'} = ${v!'null'}
+ </#list>
+ ]
+
+ [
+ <#list m as k, v>
+ ${k!'null'} = ${v!'null'}<#sep>;</#sep> // @${k?index}=@${v?index}; ${k?itemParity}=${v?itemParity}; ${k?hasNext}=${v?hasNext}
+ <#else>
+ Empty
+ </#list>
+ ]
+
+ {
+ <#list m>
+ [
+ <#items as k, v>
+ ${k!'null'} = ${v!'null'}<#sep>;</#sep> // @${k?index}=@${v?index}; ${k?itemParity}=${v?itemParity}; ${k?hasNext}=${v?hasNext}
+ </#items>
+ ]
+ <#else>
+ Empty
+ </#list>
+ }
+
+ </#list>
+</#macro>
+
+Non-empty maps:
+
+<@listings listables.hashEx2s />
+<@listings [ listables.hashNonEx2 ] />
+
+Empty maps:
+
+<@listings listables.emptyHashes />
+
+<#list { 'a': { 'aa': 11 }, 'b': { 'ba': 21, 'bb': 22 }, 'c': {} } as k1, v1>
+ ${k1} @ ${k1?index}, ${v1?size}
+ <#list v1 as k2, v2>
+ ${k2} = ${v2} @ ${k2?index} // inside ${k1} @ ${k1?index}, ${v1?size}
+ </#list>
+ ${k1} @ ${k1?index}, ${v1?size}
+ --
+</#list>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhashliteral.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhashliteral.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhashliteral.ftl
new file mode 100644
index 0000000..06694c9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listhashliteral.ftl
@@ -0,0 +1,35 @@
+<#--
+ 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.
+-->
+<#list [ { "a": 1, "b": 2, "a": 3 }, { } ] as h>
+ KVPs:
+ <#list h as k, v>
+ ${k} = ${v}
+ </#list>
+
+ Keys:
+ <#list h?keys as k>
+ ${k}
+ </#list>
+
+ Values:
+ <#list h?values as v>
+ ${v}
+ </#list>
+
+</#list>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listliteral.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listliteral.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listliteral.ftl
new file mode 100644
index 0000000..d48578c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/listliteral.ftl
@@ -0,0 +1,84 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: List Literal Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now perform a list assignment:</p>
+
+<#assign hash = {"temp", "Temporary"}>
+<#assign mymessage = "hello">
+<#assign test = [ "test1", "test23", "test45", message, mymessage]>
+
+The list contains #{test?size} items.
+
+<#list test as item>
+<p>${item}</p>
+</#list>
+
+<p>Now update the assignment and repeat:</p>
+
+<#assign mymessage = "world">
+
+<#list test as item>
+<p>${item}</p>
+</#list>
+
+<p>Now reassign the list and repeat:</p>
+
+<#assign test = [ hash.temp, "test1", "test23", "test45", mymessage, "hash", hash["temp"]]>
+<#assign test = [ "foo", "bar" ] + test>
+
+<#list test[1..4] as item>
+<p>${item}</p>
+</#list>
+
+<p>Silly, but necessary tests, for one and zero element lists:</p>
+
+<#assign test = [ "Hello, world" ]>
+
+<#list test as item>
+<p>${item}</p>
+</#list>
+
+<p>Zero item test:</p>
+
+<#assign test = []>
+
+<#list test as item>
+<p>${item}</p>
+</#list>
+
+<p>Dumb test for number literals -- these weren't working as expected:</p>
+
+<#assign test = [] + [1, 2,3, 5, 7]>
+
+<#list test as item>
+<p>${item}</p>
+<#if item == 5><#break></#if>
+</#list>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization.ftl
new file mode 100644
index 0000000..cf46fbf
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization.ftl
@@ -0,0 +1,32 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Localization Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Hello, in the default language.</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en.ftl
new file mode 100644
index 0000000..f8292bc
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en.ftl
@@ -0,0 +1,32 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Localization Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Hello, in the English language.</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en_AU.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en_AU.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en_AU.ftl
new file mode 100644
index 0000000..938f681
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/localization_en_AU.ftl
@@ -0,0 +1,32 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Localization Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>G'day, mate!</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/logging.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/logging.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/logging.ftl
new file mode 100644
index 0000000..c44d6b8
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/logging.ftl
@@ -0,0 +1,42 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Logging Test</title>
+</head>
+<body>
+
+A simple test follows:
+
+${message.test[ "me" ]}
+
+<if message>
+ <p>Message exists!
+ <transform message.sdf>
+ ...and even generates output!
+ </transform>
+ </p>
+</if>
+
+<compress>
+Try this for size.
+</compress>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/loopvariable.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/loopvariable.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/loopvariable.ftl
new file mode 100644
index 0000000..bc77b82
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/loopvariable.ftl
@@ -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.
+-->
+<#setting locale="en_US">
+---
+<#macro myLoop from to>
+ <#list from..to as x>
+ - <#nested x></#list>*
+</#macro>
+<#list 2..1 as i>
+ ${i}
+ <@myLoop from=1 to=3; i>
+ L1 ${i}
+ <@myLoop from=1 to=2; i>
+ L2 ${i}: <#list 1..3 as i>${i}; </#list>
+ </@>
+ </@>
+</#list>
+---
+<#macro repeat count>
+ <#list 1..count as x>
+ <#nested x, x/2, x==count>
+ </#list>
+</#macro>
+<#macro test2>
+<#local c = 123>
+<@repeat count=4 ; c, halfc, last>
+ <#local c = .locals.c + 0.1>
+ ${c} ${halfc}<#if last> Last!</#if>
+</...@repeat>
+${c}
+</#macro>
+<@test2/>
+---
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros-return.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros-return.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros-return.ftl
new file mode 100644
index 0000000..220fa2a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros-return.ftl
@@ -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.
+-->
+<#macro m>m{<#return>}</#macro>
+<@m/>
+
+<#macro m><#if true>m{<#return>}</#if></#macro>
+<@m/>
+
+<#macro m><#if true>m{<#return></#if>}</#macro>
+<@m/>
+
+<#macro b>b{<#nested>}</#macro>
+<#macro m><@b><#return></@></#macro>
+<@m/>
+
+<#macro b>b{<#nested>}</#macro>
+<#macro m>m:<@b><#return></@></#macro>
+<@m/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros.ftl
new file mode 100644
index 0000000..9d8f456
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros.ftl
@@ -0,0 +1,101 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Function Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now perform function tests:</p>
+
+<#assign urls = {"home" : "/home.html", "about" : "/about.html"}>
+<#assign images = {"home" : "/images/home.png", "about" : "/image/about-us.jpeg"}>
+<#assign preferences = {"showImages" : true}>
+<#assign "español" = français><#macro français(url, image, alt)>
+ <#local var = "Kilroy">
+ <a href="${url}">
+ <#if preferences.showImages>
+ <img src="${image}" border="0" alt="${alt}">
+ <#else>
+ ${alt}
+ </#if>
+ </a>
+ ${var} was here.
+</#macro>
+
+<p>Function is defined, now let's call it:</p>
+
+ <@español urls.home images.home "Home" /><#t>
+
+<p>Again, but with different parameters:</p>
+
+<@français
+ url=urls.about
+ image=images.about
+ alt="About Us"
+/>
+
+<#if var?exists>
+ Something is wrong here.
+<#else>
+ Good.
+</#if>
+
+<p>A recursive function call:</p>
+
+<#macro recurse(dummy, a=3)>
+ <#if (a > 0)>
+ <@recurse dummy a - 1 />
+ </#if>
+ ${a}
+</#macro>
+
+<@recurse urls />
+
+<p>Test "catch-all" macro parameter:</p>
+
+<#macro "catch-all" foo bar...>
+foo=${foo} baz=[<#list bar?keys?sort as key>${key}=${bar[key]}<#if key_has_next>, </#if></#list>]
+</#macro>
+<#assign catchall = .namespace["catch-all"]>
+
+<@catchall foo="a"/>
+<@catchall foo="a" bar="b"/>
+<@catchall foo="a" bar="b" baz="c"/>
+
+<#macro fmt pattern args...>
+ <#list args as arg>
+ <#local pattern = pattern?replace("{" + arg_index + "}", arg)>
+ </#list>
+ ${pattern}<#lt>
+</#macro>
+
+<#macro m a=1 b=2>
+</#macro>
+<@assertFails message='"c"'><@m c=3 /></@>
+<@assertFails message='3'><@m 9 8 7 /></@>
+
+<@fmt "Hello {0}! Today is {1}.", "World", "Monday" />
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros2.ftl
new file mode 100644
index 0000000..55ceefd
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/macros2.ftl
@@ -0,0 +1,35 @@
+<#--
+ 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.
+-->
+<#macro m1 a b=a>
+${a} ${b}
+</#macro>
+<@m1 a="1"/>
+<#macro m2 a=b b="">
+${a} ${b}
+</#macro>
+<@m2 b="2"/>
+<#macro m3 d b=c[a] a=d c={"3":"4"}>
+${b}
+</#macro>
+<@m3 d="3"/>
+<#attempt>
+<@m3 d="4"/>
+<#recover>
+m3 with d="4" Failed!
+</#attempt>
\ No newline at end of file
[31/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
new file mode 100644
index 0000000..321721e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #text // o.a.f.c.ASTStaticText
+ - content: "1. " // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: m // o.a.f.c.ASTExpVariable
+ - argument name: "x" // String
+ - argument value: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: e1 // o.a.f.c.ASTExpVariable
+ - argument name: "y" // String
+ - argument value: "$\\{e2}" // o.a.f.c.ASTExpStringLiteral
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n2. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: "a" // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: "b" // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: "c" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n3. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: "b" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n4. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: "a" // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n5. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: #{...} // o.a.f.c.ASTHashInterpolation
+ - content: y // o.a.f.c.ASTExpVariable
+ - minimum decimals: "0" // Integer
+ - maximum decimals: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n6. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: "a b " // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: " c d" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n7. " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ - value part: " a b " // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: y // o.a.f.c.ASTExpVariable
+ - value part: " c$d" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
new file mode 100644
index 0000000..cd86f2f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
@@ -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.
+-->
+1. <@m x='${e1}' y='$\\{e2}' />
+2. ${'a${x}b${x}c'}
+3. ${'${x}b'}
+4. ${'a${x}'}
+5. ${'${x}#{y}'}
+6. ${'a b ${x} c d'}
+7. ${'${x} a b ${y} c$d'}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
new file mode 100644
index 0000000..868fc69
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "xs" // String
+ - assignment operator: "=" // String
+ - assignment source: [...] // o.a.f.c.ASTExpListLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ #list // o.a.f.c.ASTDirList
+ - list source: x // o.a.f.c.ASTExpVariable
+ - target loop variable: "xs" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: " " // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "a" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "b" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: b // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: " x\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: c // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: d // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\na\n" // String
+ #--...-- // o.a.f.c.ASTComment
+ - content: " comment " // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "b" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
new file mode 100644
index 0000000..cba7289
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
@@ -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.
+-->
+
+
+<#assign xs = []>
+
+<#list x as xs>
+ ${x}
+</#list>
+
+<#assign a = 1>
+<#assign b = 1>
+
+<@b>
+ x
+</...@b>
+
+<@c />
+
+<@d...@d>
+
+a
+<#-- comment -->
+b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
new file mode 100644
index 0000000..24c8984
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
@@ -0,0 +1,35 @@
+<#ftl stripWhitespace=false>
+<#--
+ 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.
+-->
+<#assign x = 1>
+<#assign x = 1, y = 2>
+<#assign x = 1 in ns>
+<#assign x = 1, y = 2 in ns>
+<#assign a += b + c>
+<#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
+<#global x = 1>
+<#global x = 1, y = 2>
+<#global x++>
+<#macro m>
+ <#local x = 1>
+ <#local x = 1, y = 2>
+</#macro>
+<#assign x>
+ foo ${bar}
+</#assign>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
new file mode 100644
index 0000000..3dd2307
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
@@ -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.
+ */
+<#assign x = 1>
+<#assign x = 1, y = 2>
+<#assign x = 1 in ns>
+<#assign x = 1, y = 2 in ns>
+<#assign a += b + c>
+<#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
+<#global x = 1>
+<#global x = 1, y = 2>
+<#global x++>
+<#macro m>
+ <#local x = 1>
+ <#local x = 1, y = 2>
+</#macro>
+<#assign x>
+ foo ${bar}
+</#assign>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
new file mode 100644
index 0000000..74aee52
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
@@ -0,0 +1,23 @@
+<#--
+ 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.
+-->
+${x?trim}
+${x?left_pad(5)}
+${x?left_pad(5, '-')}
+${x?then('y', 'n')}
+${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
new file mode 100644
index 0000000..3c62974
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+${x?trim}
+${x?left_pad(5)}
+${x?left_pad(5, "-")}
+${x?then("y", "n")}
+${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
new file mode 100644
index 0000000..75d52f1
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
@@ -0,0 +1,76 @@
+<#--
+ 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.
+-->
+<#macro m\-a data\-color>
+ <#local \.namespace = 123>
+ <a-b>${data\-color}<#nested \.namespace></a-b><#t>
+</#macro>
+<#macro "m-b2"></#macro>
+<#macro "m/b2"></#macro>
+
+<@m\-a data\-color="red"; loop\-var, loopVar2>${loop\-var}</@>
+
+<#function f\-a p\-a>
+ <#return p\-a + " works">
+</#function>
+${f\-a("f-a")}
+
+<#assign \-\-\-\.\: = 'dash-dash-dash etc.'>
+${\-\-\-\.\:}
+${.vars['---.:']}
+<#assign hash = { '--moz-prop': 'propVal' }>
+${hash.\-\-moz\-prop}
+${hash['--moz-prop']}
+
+<#assign ls\:a = 1..3>
+List: <#list ls\:a as \:i>${\:i}</#list>
+
+<#assign sw\-a=1>
+Switch: <#switch sw\-a>
+ <#case 1>OK<#break>
+ <#default>Fails
+</#switch>
+
+<#escape \-x as \-x?upper_case>${'escaped'}</#escape>
+
+<#if false && sw\-a == 1>
+ <#visit x\-y2 using x\-y1>
+ <#recurse x\-y2 using x\-y1>
+ <#import i\-a as i\-b>
+ <#include i\-c>
+</#if>
+
+<#assign @as@_a = 'as1'>
+${@as@_a}
+<#assign 'as-c' = 'as2'>
+${.vars['as-c']}
+<#assign "as/b" = 'as3'>
+${.vars["as/b"]}
+<#assign "as'c" = 'as4'>
+${.vars["as'c"]}
+<#assign 'as"d' = 'as5'>
+${.vars['as"d']}
+
+<#global g\-a=1 g\-b=2 "g-c"=3>
+
+<#macro dumpNS>
+ <#list .namespace?keys?sort as k>
+ ${k} = <#local v = .namespace[k]><#if v?is_string>${v}<#else>...</#if><#lt>
+ </#list>
+</#macro>
+<@dumpNS />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
new file mode 100644
index 0000000..17e2b4e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+<#macro m\-a data\-color><#local \.namespace = 123><a-b>${data\-color}<#nested \.namespace></a-b></#macro><#macro m\-b2></#macro><#macro "m/b2"></#macro>
+<@m\-a data\-color="red"; loop\-var, loopVar2>${loop\-var}</@m\-a>
+
+<#function f\-a(p\-a)><#return p\-a + " works"/></#function>${f\-a("f-a")}
+
+<#assign \-\-\-\.\: = "dash-dash-dash etc.">${\-\-\-\.\:}
+${.vars["---.:"]}
+<#assign hash = {"--moz-prop": "propVal"}>${hash.\-\-moz\-prop}
+${hash["--moz-prop"]}
+
+<#assign ls\:a = 1..3>List: <#list ls\:a as \:i>${\:i}</#list>
+
+<#assign sw\-a = 1>Switch: <#switch sw\-a><#case 1>OK<#break/>
+ <#default>Fails
+</#switch>
+<#escape \-x as \-x?upper_case>${"escaped"}</#escape>
+
+<#if false && sw\-a == 1><#visit x\-y2 using x\-y1/><#recurse x\-y2 using x\-y1/><#import i\-a as i\-b/><#include i\-c/></#if>
+<#assign @as@_a = "as1">${@as@_a}
+<#assign as\-c = "as2">${.vars["as-c"]}
+<#assign "as/b" = "as3">${.vars["as/b"]}
+<#assign "as'c" = "as4">${.vars["as'c"]}
+<#assign 'as"d' = "as5">${.vars['as"d']}
+
+<#global g\-a = 1, g\-b = 2, g\-c = 3><#macro dumpNS><#list .namespace?keys?sort as k>${k} = <#local v = .namespace[k]><#if v?is_string>${v}<#else>...</#if>
+</#list></#macro><@dumpNS/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
new file mode 100644
index 0000000..9288e63
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
@@ -0,0 +1,29 @@
+<#ftl stripWhitespace=false>
+<#--
+ 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.
+-->
+<#macro m></#macro>
+<#macro m a></#macro>
+<#macro m a b></#macro>
+<#macro m a b c...></#macro>
+<#macro m a...></#macro>
+<#function f()></#function>
+<#function f(a)></#function>
+<#function f(a, b)></#function>
+<#function f(a, b, c...)></#function>
+<#function f(a...)></#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
new file mode 100644
index 0000000..ad49cae
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+<#macro m></#macro>
+<#macro m a></#macro>
+<#macro m a b></#macro>
+<#macro m a b c...></#macro>
+<#macro m a...></#macro>
+<#function f()></#function>
+<#function f(a)></#function>
+<#function f(a, b)></#function>
+<#function f(a, b, c...)></#function>
+<#function f(a...)></#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
new file mode 100644
index 0000000..85189a4
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+<@m x='${e1 + "a\'b${x}"}#{x; M2}' y='$\{e2}' />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
new file mode 100644
index 0000000..754c225
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+<@m x="${e1 + \"a'b$\{x}\"}#{x ; m0M2}" y="$\{e2}"/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
new file mode 100644
index 0000000..e0382c7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
@@ -0,0 +1,20 @@
+<#ftl encoding="ISO-8859-1">
+<#--
+ 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.
+-->
+B�ka
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
new file mode 100644
index 0000000..5948e30
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
@@ -0,0 +1,20 @@
+<#ftl encoding="UTF-8">
+<#--
+ 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.
+-->
+Béka
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
new file mode 100644
index 0000000..fb3f45d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+dummy
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache1.ftl
new file mode 100644
index 0000000..462f1ae
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache1.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+Template 1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache2.ftl
new file mode 100644
index 0000000..f59424c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/toCache2.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+Template 2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
new file mode 100644
index 0000000..d1fe3dc
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<person>
+ <gender>male</gender>
+ <name>pradeep</name>
+ <dob>12th August</dob><address>Chennai, India</address>
+ <!--This is a comment Node -->
+ <?xml-stylesheet type="text/css" href="style.css"?>
+ <profession>Software Engineer</profession>
+ <![CDATA[ ]]>
+ <hobby>gardening</hobby>
+ <![CDATA[this is a valid cdata]]>
+ <phone>12345678</phone>
+</person>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
new file mode 100644
index 0000000..24bd0ee
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
@@ -0,0 +1,21 @@
+<#--
+ 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.
+-->
+<#assign captured><b>Test</b></#assign>
+Just a string: ${"<b>Test</b>"}
+Captured output: ${captured}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
new file mode 100644
index 0000000..cf0da7e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+Just a string: <b>Test</b>
+Captured output: <b>Test</b>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
new file mode 100644
index 0000000..e0d3348
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
@@ -0,0 +1,27 @@
+<#--
+ 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.
+-->
+<#assign mo1 = "Foo's bar {}"?esc>
+HTLM: ${mo1}
+XML: <#outputformat 'XML'>${mo1}</#outputformat>
+RTF: <#outputformat 'RTF'>${mo1}</#outputformat>
+
+<#assign mo2><p>Test</#assign>
+HTML: ${mo2}
+XML: <#attempt><#outputformat 'XML'>${mo2}</#outputformat><#recover>Failed</#attempt>
+RTF: <#attempt><#outputformat 'RTF'>${mo2}</#outputformat><#recover>Failed</#attempt>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
new file mode 100644
index 0000000..65be2a0
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
@@ -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.
+ */
+HTLM: Foo's bar {}
+XML: Foo's bar {}
+RTF: Foo's bar \{\}
+
+HTML: <p>Test
+XML: Failed
+RTF: Failed
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
new file mode 100644
index 0000000..80ae292
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
@@ -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.
+-->
+<#outputformat "HTML"><#assign htmlMO><p>Test</#assign></#outputformat>
+<#outputformat "XML"><#assign xmlMO><p>Test</p></#assign></#outputformat>
+<#outputformat "RTF"><#assign rtfMO>\par Test</#assign></#outputformat>
+<#-- We assume that we have "undefined" output format here. -->
+HTML: ${htmlMO}
+XML: ${xmlMO}
+RTF: ${rtfMO}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
new file mode 100644
index 0000000..cd84bd2
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+HTML: <p>Test
+XML: <p>Test</p>
+RTF: \par Test
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
new file mode 100644
index 0000000..9b8dbd9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
@@ -0,0 +1,26 @@
+<#--
+ 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.
+-->
+<@infoBox "Foo & bar" />
+<@infoBox "Foo <b>bar</b>"?no_esc />
+
+<#macro infoBox message>
+ <div class="infoBox">
+ ${message}
+ </div>
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
new file mode 100644
index 0000000..9471ab7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
@@ -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.
+ */
+ <div class="infoBox">
+ Foo & bar
+ </div>
+ <div class="infoBox">
+ Foo <b>bar</b>
+ </div>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
new file mode 100644
index 0000000..f9deeae
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
@@ -0,0 +1,28 @@
+<#--
+ 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.
+-->
+<#assign markupOutput1="<b>Test</b>"?no_esc>
+<#assign markupOutput2="Foo & bar"?esc>
+
+As expected:
+${markupOutput1}
+${markupOutput2}
+
+Double escaping:
+${markupOutput1?markup_string}
+${markupOutput2?markup_string}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
new file mode 100644
index 0000000..0420cca
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+As expected:
+<b>Test</b>
+Foo & bar
+
+Double escaping:
+<b>Test</b>
+Foo &amp; bar
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
new file mode 100644
index 0000000..f7884bb
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
new file mode 100644
index 0000000..d016072
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+<h1>Foo & bar</h1>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
new file mode 100644
index 0000000..4904f60
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
@@ -0,0 +1,21 @@
+<#--
+ 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.
+-->
+<#assign s = "Foo & bar">
+${s}
+${"${s} & baz"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
new file mode 100644
index 0000000..c6bd10d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+Foo & bar
+Foo & bar & baz
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
new file mode 100644
index 0000000..52db70b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
@@ -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.
+-->
+<#-- Markup output value created by escaping plain text: -->
+<#assign mo1 = "Foo & bar"?esc>
+<#-- Markup output value created outherwise: -->
+<#assign mo2 = "<p>Foo"?no_esc>
+
+${"${mo1} baz"}
+${"${mo2} baz"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
new file mode 100644
index 0000000..f47e521
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+Foo & bar baz
+<p>Foo baz
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
new file mode 100644
index 0000000..0df9e33
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
@@ -0,0 +1,21 @@
+# 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.
+
+templateConfigurations = \
+ ConditionalTemplateConfigurationFactory( \
+ PathGlobMatcher("mail/**"), \
+ TemplateConfiguration(outputFormat = HTMLOutputFormat()))
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
new file mode 100644
index 0000000..5d2a738
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
@@ -0,0 +1,31 @@
+# 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.
+
+templateConfigurations = \
+ FirstMatchTemplateConfigurationFactory( \
+ ConditionalTemplateConfigurationFactory( \
+ FileExtensionMatcher("xml"), \
+ TemplateConfiguration(outputFormat = XMLOutputFormat())), \
+ ConditionalTemplateConfigurationFactory( \
+ OrMatcher( \
+ FileExtensionMatcher("html"), \
+ FileExtensionMatcher("htm")), \
+ TemplateConfiguration(outputFormat = HTMLOutputFormat())), \
+ ConditionalTemplateConfigurationFactory( \
+ FileExtensionMatcher("rtf"), \
+ TemplateConfiguration(outputFormat = RTFOutputFormat())), \
+ allowNoMatch = true)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
new file mode 100644
index 0000000..fe9690c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
@@ -0,0 +1,22 @@
+<#--
+ 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.
+-->
+${p?string.@price}
+${w?string.@weight}
+${fd?string.@fileDate}
+${let?datetime?string.@logEventTime}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
new file mode 100644
index 0000000..717431f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+10,000.00
+10.31
+23/Dec/15 10:09 PM
+2015-12-23T21:09:04.213Z
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
new file mode 100644
index 0000000..624950f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+${10?string.@oct}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
new file mode 100644
index 0000000..08d0fea
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+12
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
new file mode 100644
index 0000000..9a34ac0
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
@@ -0,0 +1,20 @@
+<#--
+ 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.
+-->
+${10.12356}
+${weight}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
new file mode 100644
index 0000000..25d6155
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+10.1236
+1.5 kg
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
new file mode 100644
index 0000000..faf8592
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
@@ -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.
+
+templateConfigurations = \
+ ConditionalTemplateConfigurationFactory( \
+ FileExtensionMatcher("xml"), \
+ TemplateConfiguration( \
+ sourceEncoding = Charset("utf-8"), \
+ outputFormat = XMLOutputFormat() \
+ ) \
+ )
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
new file mode 100644
index 0000000..f879e70
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
@@ -0,0 +1,32 @@
+# 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.
+
+templateConfigurations = \
+ ConditionalTemplateConfigurationFactory( \
+ PathGlobMatcher("mail/**"), \
+ FirstMatchTemplateConfigurationFactory( \
+ ConditionalTemplateConfigurationFactory( \
+ FileNameGlobMatcher("*.subject.*"), \
+ TemplateConfiguration(outputFormat = PlainTextOutputFormat()) \
+ ), \
+ ConditionalTemplateConfigurationFactory( \
+ FileNameGlobMatcher("*.body.*"), \
+ TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
+ ), \
+ noMatchErrorDetails = 'Mail template names must contain ".subject." or ".body."!' \
+ ) \
+ )
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
new file mode 100644
index 0000000..ce72fef
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
@@ -0,0 +1,47 @@
+# 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.
+
+templateConfigurations = \
+ MergingTemplateConfigurationFactory( \
+ ConditionalTemplateConfigurationFactory( \
+ FileNameGlobMatcher("*.stats.*"), \
+ TemplateConfiguration( \
+ dateTimeFormat = "iso", \
+ dateFormat = "iso", \
+ timeFormat = "iso", \
+ timeZone = TimeZone("UTC") \
+ ) \
+ ), \
+ ConditionalTemplateConfigurationFactory( \
+ PathGlobMatcher("mail/**"), \
+ TemplateConfiguration(sourceEncoding = Charset("utf-8")) \
+ ), \
+ FirstMatchTemplateConfigurationFactory( \
+ ConditionalTemplateConfigurationFactory( \
+ FileExtensionMatcher("xml"), \
+ TemplateConfiguration(outputFormat = XMLOutputFormat()) \
+ ), \
+ ConditionalTemplateConfigurationFactory( \
+ OrMatcher( \
+ FileExtensionMatcher("html"), \
+ FileExtensionMatcher("htm") \
+ ), \
+ TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
+ ), \
+ allowNoMatch = true \
+ ) \
+ )
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/test.ftlh b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
new file mode 100644
index 0000000..852b82b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
@@ -0,0 +1,28 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>Welcome ${user}!</h1>
+ <p>Our latest product:
+ <a href="${latestProduct.url}">${latestProduct.name}</a>!
+</body>
+</html>
\ No newline at end of file
[05/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/FileTestCase.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/FileTestCase.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/FileTestCase.java
deleted file mode 100644
index b7e4c1d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/FileTestCase.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.util;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.freemarker.core.util._NullArgumentException;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TestUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-/**
- * Test case that needs to compare a string to a reference (expected) text file, or two text files.
- */
-public abstract class FileTestCase extends TestCase {
-
- public static final Logger LOG = LoggerFactory.getLogger(FileTestCase.class);
-
- public FileTestCase(String name) {
- super(name);
- }
-
- protected void assertExpectedFileEqualsString(String expectedFileName, String actualContent) {
- try {
- final URL expectedFile = getExpectedContentFileURL(expectedFileName);
-
- try {
- multilineAssertEquals(loadTestTextResource(expectedFile), actualContent);
- } catch (AssertionFailedError | FileNotFoundException e) {
- File actualFile = getActualContentFileFor(expectedFile);
- if (actualFile != null) {
- FileUtils.write(actualFile, actualContent);
- reportActualFileSaved(actualFile);
- }
-
- throw e;
- }
- } catch (IOException e) {
- throw new RuntimeException("Failed to do assertion", e);
- }
- }
-
- private void multilineAssertEquals(String expected, String actual) {
- String normExpected = _StringUtil.normalizeEOLs(expected);
- final String normActual = _StringUtil.normalizeEOLs(actual);
-
- // Ignore final line-break difference:
- if (normActual.endsWith("\n") && !normExpected.endsWith("\n")) {
- normExpected += "\n";
- } else if (!normActual.endsWith("\n") && normExpected.endsWith("\n")) {
- normExpected = normExpected.substring(0, normExpected.length() - 1);
- }
-
- assertEquals(normExpected, normActual);
- }
-
- protected void reportActualFileSaved(File actualContentFile) {
- LOG.info("Saved actual output of the failed test to here: {}", actualContentFile.getAbsolutePath());
- }
-
- /**
- * Convenience method for calling {@link #getTestFileURL(String, String)} with {@link
- * #getExpectedContentFileDirectoryResourcePath()} as the first argument.
- */
- protected final URL getExpectedContentFileURL(String expectedContentFileName) throws IOException {
- return getTestFileURL(getExpectedContentFileDirectoryResourcePath(), expectedContentFileName);
- }
-
- /**
- * Gets the URL of the test file that contains the expected result.
- *
- * @param directoryResourcePath
- * The class-loader resource path of the containing directory; if relative, it's interpreted relatively to
- * the package of {@link #getTestResourcesBaseClass()}.
- *
- * @return Not {@code null}; if the file isn't found, throw {@link FileNotFoundException}
- *
- * @throws FileNotFoundException
- * If the requested file wasn't found.
- */
- protected final URL getTestFileURL(String directoryResourcePath, String fileName) throws IOException {
- _NullArgumentException.check("directoryResourcePath", directoryResourcePath);
- _NullArgumentException.check("testCaseFileName", fileName);
-
- Class baseClass = getTestResourcesBaseClass();
- String resourcePath = joinResourcePaths(directoryResourcePath, fileName);
- // It's important that we only query an URL for the file (not for the parent package directory), because the
- // parent URL can depend on the file name if the class loader uses multiple directories/jars.
- URL resource = baseClass.getResource(resourcePath);
- if (resource == null) {
- throw new FileNotFoundException("Class-loader resource not found for: "
- + "baseClass: " + baseClass.getName() + "; "
- + "resourcePath (shown quoted): " + _StringUtil.jQuote(resourcePath));
- }
- return resource;
- }
-
- /**
- * Concatenates two resource paths, taking care of the edge cases due to leading and trailing "/"
- * characters in them.
- */
- protected final String joinResourcePaths(String dirPath, String tailPath) {
- if (tailPath.startsWith("/") || dirPath.isEmpty()) {
- return tailPath;
- }
- return dirPath.endsWith("/") ? dirPath + tailPath : dirPath + "/" + tailPath;
- }
-
- /**
- * Gets the actual content file to create which belongs to an expected content file. Actual content files are
- * created when the expected and the actual content differs.
- *
- * @return {@code null} if there's no place to write the files that contain the actual content
- */
- protected File getActualContentFileFor(URL expectedContentFile) throws IOException {
- _NullArgumentException.check("expectedContentFile", expectedContentFile);
-
- File actualContentFileDir = getActualContentFileDirectory(expectedContentFile);
- if (actualContentFileDir == null) {
- return null;
- }
-
- String expectedContentFileName = expectedContentFile.getPath();
- int lastSlashIdx = expectedContentFileName.lastIndexOf('/');
- if (lastSlashIdx != -1) {
- expectedContentFileName = expectedContentFileName.substring(lastSlashIdx + 1);
- }
-
- return new File(actualContentFileDir, deduceActualContentFileName(expectedContentFileName));
- }
-
- /**
- * Deduces the actual content file name from the expected content file name.
- *
- * @return Not {@code null}
- */
- protected String deduceActualContentFileName(String expectedContentFileName) {
- _NullArgumentException.check("expectedContentFileName", expectedContentFileName);
-
- int lastDotIdx = expectedContentFileName.lastIndexOf('.');
- return lastDotIdx == -1
- ? expectedContentFileName + ".actual"
- : expectedContentFileName.substring(0, lastDotIdx) + "-actual" + expectedContentFileName.substring(lastDotIdx);
- }
-
- /**
- * The class loader resource path of the directory that contains the expected files; must start and end with "/"!
- */
- protected String getExpectedContentFileDirectoryResourcePath() throws IOException {
- return getTestClassDirectoryResourcePath();
- }
-
- /**
- * @return {@code null} if there's no directory to write the actual files to
- */
- protected File getActualContentFileDirectory(URL expectedFile) throws IOException {
- return FileUtils.toFile(expectedFile).getParentFile();
- }
-
- /**
- * The class loader resource path of the directory that contains the test files; must not end with "/"!
- */
- protected String getTestClassDirectoryResourcePath() throws IOException {
- return "";
- }
-
- /**
- * Resource paths are loaded using this class's {@link Class#getResourceAsStream(String)} method; thus, if
- * {@link #getTestClassDirectoryResourcePath()} and such return a relative paths, they will be relative to the
- * package of this class.
- */
- protected Class getTestResourcesBaseClass() {
- return getClass();
- }
-
- protected String loadTestTextResource(URL resource) throws IOException {
- return loadTestTextResource(resource, getTestResourceDefaultCharset());
- }
-
- protected String loadTestTextResource(URL resource, Charset charset) throws IOException {
- return TestUtil.removeTxtCopyrightComment(
- IOUtils.toString(resource, charset.name()));
- }
-
- protected Charset getTestResourceDefaultCharset() {
- return StandardCharsets.UTF_8;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/MissingRequiredParameterException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/MissingRequiredParameterException.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/MissingRequiredParameterException.java
deleted file mode 100644
index 0bc37a3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/MissingRequiredParameterException.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * Indicates that a named directive/function parameter is missing.
- * This is will be public and go into the org.apache.freemarker.core.ast when the directive/method stuff was reworked.
- */
-class MissingRequiredParameterException extends ParameterException {
-
- public MissingRequiredParameterException(String parameterName, Environment env) {
- this(parameterName, null, null, env);
- }
-
- public MissingRequiredParameterException(String parameterName, Exception cause, Environment env) {
- this(parameterName, null, cause, env);
- }
-
- public MissingRequiredParameterException(String parameterName, String description, Environment env) {
- this(parameterName, description, null, env);
- }
-
- public MissingRequiredParameterException(String parameterName, String description, Exception cause, Environment env) {
- super(parameterName,
- "Required parameter " + _StringUtil.jQuote(parameterName) + " is missing, "
- + "or the parameter value was null."
- + (description != null ? " " + _StringUtil.jQuote(description) : ""),
- cause, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/NoOutputDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/NoOutputDirective.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/NoOutputDirective.java
deleted file mode 100644
index d504bd5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/NoOutputDirective.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.util._NullWriter;
-
-public class NoOutputDirective implements TemplateDirectiveModel {
-
- public static final NoOutputDirective INSTANCE = new NoOutputDirective();
-
- private NoOutputDirective() {
- //
- }
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- if (!params.isEmpty()) {
- throw new TemplateModelException("This directivey doesn't support any parameters.");
- }
- body.render(_NullWriter.INSTANCE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/ParameterException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/ParameterException.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/ParameterException.java
deleted file mode 100644
index 47220d5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/ParameterException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * An exception that is related to a named parameter of a directive or function.
- * This is will be public and go into the org.apache.freemarker.core.ast when the method/directive stuff was reworked.
- */
-abstract class ParameterException extends TemplateException {
-
- private final String parameterName;
-
- public ParameterException(String parameterName, Environment env) {
- this(parameterName, null, null, env);
- }
-
- public ParameterException(String parameterName, Exception cause, Environment env) {
- this(parameterName, null, cause, env);
- }
-
- public ParameterException(String parameterName, String description, Environment env) {
- this(parameterName, description, null, env);
- }
-
- public ParameterException(String parameterName, String description, Exception cause, Environment env) {
- super(description, cause, env);
- this.parameterName = parameterName;
- }
-
- public String getParameterName() {
- return parameterName;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/SimpleMapAndCollectionObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/SimpleMapAndCollectionObjectWrapper.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/SimpleMapAndCollectionObjectWrapper.java
deleted file mode 100644
index c1da1c4..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/SimpleMapAndCollectionObjectWrapper.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.freemarker.core.Version;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-import org.apache.freemarker.core.model.impl.SimpleSequence;
-
-/**
- * Forces using "simple" models for {@link Map}-s, {@link Collection}-s and arrays. This is mostly useful for template
- * test cases that wish to test with these models, but otherwise need to able to wrap beans and such.
- */
-public class SimpleMapAndCollectionObjectWrapper extends DefaultObjectWrapper {
-
- public SimpleMapAndCollectionObjectWrapper(Version incompatibleImprovements) {
- super(new DefaultObjectWrapper.Builder(incompatibleImprovements), true);
- }
-
- @Override
- public TemplateModel wrap(Object obj) throws TemplateModelException {
- if (obj == null) {
- return super.wrap(null);
- }
- if (obj.getClass().isArray()) {
- obj = Arrays.asList((Object[]) obj);
- }
- if (obj instanceof Collection) {
- return new SimpleSequence((Collection<?>) obj, this);
- }
- if (obj instanceof Map) {
- return new SimpleHash((Map<?, ?>) obj, this);
- }
-
- return super.wrap(obj);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/UnsupportedParameterException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/UnsupportedParameterException.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/UnsupportedParameterException.java
deleted file mode 100644
index ac4d528..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/UnsupportedParameterException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * Indicates that a named directive/function parameter is unsupported (like a typo).
- * This is will be public and go into the org.apache.freemarker.core.ast when the directive/method stuff was reworked.
- */
-class UnsupportedParameterException extends ParameterException {
-
- public UnsupportedParameterException(String parameterName, Environment env) {
- this(parameterName, null, null, env);
- }
-
- public UnsupportedParameterException(String parameterName, Exception cause, Environment env) {
- this(parameterName, null, cause, env);
- }
-
- public UnsupportedParameterException(String parameterName, String description, Environment env) {
- this(parameterName, description, null, env);
- }
-
- public UnsupportedParameterException(String parameterName, String description, Exception cause, Environment env) {
- super(parameterName,
- "Unsuppored parameter: " + _StringUtil.jQuote(parameterName)
- + (description == null ? "." : ". " + _StringUtil.jQuote(description)),
- cause, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/XMLLoader.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/XMLLoader.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/XMLLoader.java
deleted file mode 100644
index 90763a0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/XMLLoader.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.MalformedURLException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.dom.NodeModel;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public final class XMLLoader {
-
- private static final Object STATIC_LOCK = new Object();
-
- static private DocumentBuilderFactory docBuilderFactory;
-
- private XMLLoader() {
- //
- }
-
- /**
- * Convenience method to invoke a {@link NodeModel} from a SAX {@link InputSource}.
- */
- static public NodeModel toModel(InputSource is, boolean simplify)
- throws SAXException, IOException, ParserConfigurationException {
- DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
- final Document doc;
- try {
- doc = builder.parse(is);
- } catch (MalformedURLException e) {
- // This typical error has an error message that is hard to understand, so let's translate it:
- if (is.getSystemId() == null && is.getCharacterStream() == null && is.getByteStream() == null) {
- throw new MalformedURLException(
- "The SAX InputSource has systemId == null && characterStream == null && byteStream == null. "
- + "This is often because it was created with a null InputStream or Reader, which is often because "
- + "the XML file it should point to was not found. "
- + "(The original exception was: " + e + ")");
- } else {
- throw e;
- }
- }
- if (simplify) {
- NodeModel.simplify(doc);
- }
- return NodeModel.wrap(doc);
- }
-
- /**
- * Same as {@link #toModel(InputSource, boolean) parse(is, true)}.
- */
- static public NodeModel toModel(InputSource is) throws SAXException, IOException, ParserConfigurationException {
- return toModel(is, true);
- }
-
- /**
- * Same as {@link #toModel(InputSource, boolean)}, but loads from a {@link File}; don't miss the security
- * warnings documented there.
- */
- static public NodeModel toModel(File f, boolean simplify)
- throws SAXException, IOException, ParserConfigurationException {
- DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
- Document doc = builder.parse(f);
- if (simplify) {
- NodeModel.simplify(doc);
- }
- return NodeModel.wrap(doc);
- }
-
- /**
- * Same as {@link #toModel(InputSource, boolean) parse(source, true)}, but loads from a {@link String}.
- */
- static public NodeModel toModel(File f) throws SAXException, IOException, ParserConfigurationException {
- return toModel(f, true);
- }
-
- /**
- * Same as {@link #toModel(InputSource, boolean)}, but loads from a {@link File}; don't miss the security
- * warnings documented there.
- */
- static public NodeModel toModel(String content, boolean simplify)
- throws SAXException, IOException, ParserConfigurationException {
- return toModel(toInputSource(content));
- }
-
- /**
- * Same as {@link #toModel(InputSource, boolean) parse(source, true)}, but loads from a {@link String}.
- */
- static public NodeModel toModel(String content) throws SAXException, IOException, ParserConfigurationException {
- return toModel(content, true);
- }
-
- public static Document toDOM(String content) throws SAXException, IOException, ParserConfigurationException {
- DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
- return builder.parse(toInputSource(content));
- }
-
- static private DocumentBuilderFactory getDocumentBuilderFactory() {
- synchronized (STATIC_LOCK) {
- if (docBuilderFactory == null) {
- DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
- newFactory.setNamespaceAware(true);
- newFactory.setIgnoringElementContentWhitespace(true);
- docBuilderFactory = newFactory; // We only write it out when the initialization was full
- }
- return docBuilderFactory;
- }
- }
-
- private static InputSource toInputSource(String content) {
- return new InputSource(new StringReader(content));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ast
deleted file mode 100644
index 1cdd496..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ast
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #text // o.a.f.c.ASTStaticText
- - content: "1 " // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: foo // o.a.f.c.ASTExpVariable
- - argument name: "x" // String
- - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
- - argument name: "y" // String
- - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
- - target loop variable: "b1" // String
- - target loop variable: "b2" // String
- #text // o.a.f.c.ASTStaticText
- - content: "x" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n2 " // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: . // o.a.f.c.ASTExpDot
- - left-hand operand: ns // o.a.f.c.ASTExpVariable
- - right-hand operand: "bar" // String
- - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
- - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
- - target loop variable: "b1" // String
- - target loop variable: "b2" // String
- #text // o.a.f.c.ASTStaticText
- - content: "y" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n3 " // String
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: ns // o.a.f.c.ASTExpVariable
- #global // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "3" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n4 " // String
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: == // o.a.f.c.ASTExpComparison
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "foo" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: y // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "bar" // String
- #else // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: null // Null
- - AST-node subtype: "1" // Integer
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: "static" // o.a.f.c.ASTExpStringLiteral
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: "x" // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: * // o.a.f.c.ArithmeticExpression
- - left-hand operand: baaz // o.a.f.c.ASTExpVariable
- - right-hand operand: 10 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "1" // Integer
- - value part: "y" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n5 " // String
- #switch // o.a.f.c.ASTDirSwitch
- - value: x // o.a.f.c.ASTExpVariable
- #case // o.a.f.c.ASTDirCase
- - condition: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "one" // String
- #case // o.a.f.c.ASTDirCase
- - condition: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "two" // String
- #default // o.a.f.c.ASTDirCase
- - condition: null // Null
- - AST-node subtype: "1" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "more" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n6 " // String
- #macro // o.a.f.c.ASTDirMacro
- - assignment target: "foo" // String
- - parameter name: "x" // String
- - parameter default: null // Null
- - parameter name: "y" // String
- - parameter default: 2 // o.a.f.c.ASTExpNumberLiteral
- - parameter name: "z" // String
- - parameter default: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: y // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - catch-all parameter name: "q" // String
- - AST-node subtype: "0" // Integer
- #nested // o.a.f.c.ASTDirNested
- - passed value: x // o.a.f.c.ASTExpVariable
- - passed value: y // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n7 " // String
- #function // o.a.f.c.ASTDirMacro
- - assignment target: "foo" // String
- - parameter name: "x" // String
- - parameter default: null // Null
- - parameter name: "y" // String
- - parameter default: null // Null
- - catch-all parameter name: null // Null
- - AST-node subtype: "1" // Integer
- #local // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "2" // Integer
- - namespace: null // Null
- #return // o.a.f.c.ASTDirReturn
- - value: 1 // o.a.f.c.ASTExpNumberLiteral
- #text // o.a.f.c.ASTStaticText
- - content: "\n8 " // String
- #list // o.a.f.c.ASTDirList
- - list source: xs // o.a.f.c.ASTExpVariable
- - target loop variable: "x" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n9 " // String
- #list-#else-container // o.a.f.c.ASTDirListElseContainer
- #list // o.a.f.c.ASTDirList
- - list source: xs // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "[" // String
- #items // o.a.f.c.ASTDirItems
- - target loop variable: "x" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- #sep // o.a.f.c.ASTDirSep
- #text // o.a.f.c.ASTStaticText
- - content: ", " // String
- #text // o.a.f.c.ASTStaticText
- - content: "]" // String
- #else // o.a.f.c.ASTDirElseOfList
- #text // o.a.f.c.ASTStaticText
- - content: "None" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n10 " // String
- #--...-- // o.a.f.c.ASTComment
- - content: " A comment " // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n11 " // String
- #outputformat // o.a.f.c.ASTDirOutputFormat
- - value: "XML" // o.a.f.c.ASTExpStringLiteral
- #noautoesc // o.a.f.c.ASTDirNoAutoEsc
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: a // o.a.f.c.ASTExpVariable
- #autoesc // o.a.f.c.ASTDirAutoEsc
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: b // o.a.f.c.ASTExpVariable
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: c // o.a.f.c.ASTExpVariable
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ftl
deleted file mode 100644
index 8c8953a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-1.ftl
+++ /dev/null
@@ -1,29 +0,0 @@
-<#--
- 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.
--->
-1 <@foo x=1 y=2; b1, b2>x</...@foo>
-2 <@ns.bar 1 2; b1, b2>y</@>
-3 <#assign x = 123><#assign x = 123 in ns><#global x = 123>
-4 <#if x + 1 == 0>foo${y}bar<#else>${"static"}${'x${baaz * 10}y'}</#if>
-5 <#switch x><#case 1>one<#case 2>two<#default>more</#switch>
-6 <#macro foo x y=2 z=y+1 q...><#nested x y></#macro>
-7 <#function foo x y><#local x = 123><#return 1></#function>
-8 <#list xs as x></#list>
-9 <#list xs>[<#items as x>${x}<#sep>, </#items>]<#else>None</#list>
-10 <#-- A comment -->
-11 <#outputFormat "XML"><#noAutoEsc>${a}<#autoEsc>${b}</#autoEsc>${c}</#noAutoEsc></#outputFormat>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
deleted file mode 100644
index 4839892..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #text // o.a.f.c.ASTStaticText
- - content: "1 " // String
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n2 " // String
- #assign // o.a.f.c.ASTDirAssignmentsContainer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "y" // String
- - assignment operator: "=" // String
- - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n3 " // String
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: ns // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n4 " // String
- #assign // o.a.f.c.ASTDirAssignmentsContainer
- - variable scope: "1" // Integer
- - namespace: ns // o.a.f.c.ASTExpVariable
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: ns // o.a.f.c.ASTExpVariable
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "y" // String
- - assignment operator: "=" // String
- - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: ns // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n5 " // String
- #global // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "3" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n6 " // String
- #global // o.a.f.c.ASTDirAssignmentsContainer
- - variable scope: "3" // Integer
- - namespace: null // Null
- #global // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "3" // Integer
- - namespace: null // Null
- #global // o.a.f.c.ASTDirAssignment
- - assignment target: "y" // String
- - assignment operator: "=" // String
- - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "3" // Integer
- - namespace: null // Null
- #macro // o.a.f.c.ASTDirMacro
- - assignment target: "m" // String
- - catch-all parameter name: null // Null
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: " 7 " // String
- #local // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "2" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n 8 " // String
- #local // o.a.f.c.ASTDirAssignmentsContainer
- - variable scope: "2" // Integer
- - namespace: null // Null
- #local // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "2" // Integer
- - namespace: null // Null
- #local // o.a.f.c.ASTDirAssignment
- - assignment target: "y" // String
- - assignment operator: "=" // String
- - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "2" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "9 " // String
- #assign // o.a.f.c.ASTDirAssignmentsContainer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "a" // String
- - assignment operator: "+=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "b" // String
- - assignment operator: "-=" // String
- - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "c" // String
- - assignment operator: "*=" // String
- - assignment source: 3 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "d" // String
- - assignment operator: "/=" // String
- - assignment source: 4 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "e" // String
- - assignment operator: "%=" // String
- - assignment source: 5 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "f" // String
- - assignment operator: "++" // String
- - assignment source: null // Null
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "g" // String
- - assignment operator: "--" // String
- - assignment source: null // Null
- - variable scope: "1" // Integer
- - namespace: null // Null
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
deleted file mode 100644
index c070635..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
+++ /dev/null
@@ -1,29 +0,0 @@
-<#--
- 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.
--->
-1 <#assign x = 1>
-2 <#assign x = 1, y = 2>
-3 <#assign x = 1 in ns>
-4 <#assign x = 1, y = 2 in ns>
-5 <#global x = 1>
-6 <#global x = 1, y = 2>
-<#macro m>
- 7 <#local x = 1>
- 8 <#local x = 1, y = 2>
-</#macro>
-9 <#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
deleted file mode 100644
index b8b696f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ?trim // o.a.f.c.BuiltInsForStringsBasic$trimBI
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: "trim" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
- - callee: ?left_pad // o.a.f.c.BuiltInsForStringsBasic$padBI
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: "left_pad" // String
- - argument value: 5 // o.a.f.c.ASTExpNumberLiteral
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
- - callee: ?left_pad // o.a.f.c.BuiltInsForStringsBasic$padBI
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: "left_pad" // String
- - argument value: 5 // o.a.f.c.ASTExpNumberLiteral
- - argument value: "-" // o.a.f.c.ASTExpStringLiteral
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ?then(...) // o.a.f.c.BuiltInsWithParseTimeParameters$then_BI
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: "then" // String
- - argument value: "y" // o.a.f.c.ASTExpStringLiteral
- - argument value: "n" // o.a.f.c.ASTExpStringLiteral
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ?switch(...) // o.a.f.c.BuiltInsWithParseTimeParameters$switch_BI
- - left-hand operand: x // o.a.f.c.ASTExpVariable
- - right-hand operand: "switch" // String
- - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
- - argument value: 11 // o.a.f.c.ASTExpNumberLiteral
- - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
- - argument value: 22 // o.a.f.c.ASTExpNumberLiteral
- - argument value: 33 // o.a.f.c.ASTExpNumberLiteral
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
deleted file mode 100644
index 74aee52..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
+++ /dev/null
@@ -1,23 +0,0 @@
-<#--
- 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.
--->
-${x?trim}
-${x?left_pad(5)}
-${x?left_pad(5, '-')}
-${x?then('y', 'n')}
-${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ast
deleted file mode 100644
index 7770d72..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ast
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent; Location 1:1-18:8
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 1:1-1:15
- - condition: exp // o.a.f.c.ASTExpVariable; Location 1:6-1:8
- - AST-node subtype: "0" // Integer
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 2:1-2:16
- - condition: exp // o.a.f.c.ASTExpVariable; Location 2:6-2:8
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText; Location 2:10-2:10
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 2:17-2:17
- - content: "\n" // String
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 3:1-3:20
- - condition: exp // o.a.f.c.ASTExpVariable; Location 3:6-3:8
- - AST-node subtype: "0" // Integer
- ${...} // o.a.f.c.ASTDollarInterpolation; Location 3:10-3:13
- - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 3:12-3:12
- #text // o.a.f.c.ASTStaticText; Location 3:14-3:14
- - content: "2" // String
- #text // o.a.f.c.ASTStaticText; Location 3:21-3:21
- - content: "\n" // String
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 4:1-4:22
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 4:1-4:9
- - condition: exp // o.a.f.c.ASTExpVariable; Location 4:6-4:8
- - AST-node subtype: "0" // Integer
- #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 4:10-4:16
- - condition: null // Null
- - AST-node subtype: "1" // Integer
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 5:1-5:24
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 5:1-5:10
- - condition: exp // o.a.f.c.ASTExpVariable; Location 5:6-5:8
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText; Location 5:10-5:10
- - content: "1" // String
- #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 5:11-5:18
- - condition: null // Null
- - AST-node subtype: "1" // Integer
- #text // o.a.f.c.ASTStaticText; Location 5:18-5:18
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 5:25-5:25
- - content: "\n" // String
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 6:1-6:32
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 6:1-6:14
- - condition: exp // o.a.f.c.ASTExpVariable; Location 6:6-6:8
- - AST-node subtype: "0" // Integer
- ${...} // o.a.f.c.ASTDollarInterpolation; Location 6:10-6:13
- - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 6:12-6:12
- #text // o.a.f.c.ASTStaticText; Location 6:14-6:14
- - content: "2" // String
- #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 6:15-6:26
- - condition: null // Null
- - AST-node subtype: "1" // Integer
- ${...} // o.a.f.c.ASTDollarInterpolation; Location 6:22-6:25
- - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 6:24-6:24
- #text // o.a.f.c.ASTStaticText; Location 6:26-6:26
- - content: "2" // String
- #text // o.a.f.c.ASTStaticText; Location 6:33-6:33
- - content: "\n" // String
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 7:1-7:28
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 7:1-7:9
- - condition: exp // o.a.f.c.ASTExpVariable; Location 7:6-7:8
- - AST-node subtype: "0" // Integer
- #elseif // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 7:10-7:22
- - condition: exp // o.a.f.c.ASTExpVariable; Location 7:19-7:21
- - AST-node subtype: "2" // Integer
- #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 8:1-8:29
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 8:1-8:9
- - condition: exp // o.a.f.c.ASTExpVariable; Location 8:6-8:8
- - AST-node subtype: "0" // Integer
- #elseif // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 8:10-8:23
- - condition: exp // o.a.f.c.ASTExpVariable; Location 8:19-8:21
- - AST-node subtype: "2" // Integer
- #text // o.a.f.c.ASTStaticText; Location 8:23-8:23
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 8:30-8:30
- - content: "\n" // String
- #attempt // o.a.f.c.ASTDirAttemptRecoverContainer; Location 9:1-9:31
- - error handler: #recover // o.a.f.c.ASTDirRecover; Location 9:11-9:20
- #recover // o.a.f.c.ASTDirRecover; Location 9:11-9:20
- #attempt // o.a.f.c.ASTDirAttemptRecoverContainer; Location 10:1-10:33
- - error handler: #recover // o.a.f.c.ASTDirRecover; Location 10:12-10:22
- #text // o.a.f.c.ASTStaticText; Location 10:22-10:22
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 10:11-10:11
- - content: "1" // String
- #recover // o.a.f.c.ASTDirRecover; Location 10:12-10:22
- #text // o.a.f.c.ASTStaticText; Location 10:22-10:22
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 10:34-10:34
- - content: "\n" // String
- #list // o.a.f.c.ASTDirList; Location 11:1-11:22
- - list source: s // o.a.f.c.ASTExpVariable; Location 11:8-11:8
- - target loop variable: "i" // String
- #list // o.a.f.c.ASTDirList; Location 12:1-12:23
- - list source: s // o.a.f.c.ASTExpVariable; Location 12:8-12:8
- - target loop variable: "i" // String
- #text // o.a.f.c.ASTStaticText; Location 12:15-12:15
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 12:24-12:24
- - content: "\n" // String
- #list // o.a.f.c.ASTDirList; Location 13:1-13:28
- - list source: s // o.a.f.c.ASTExpVariable; Location 13:8-13:8
- - target loop variable: "i" // String
- #sep // o.a.f.c.ASTDirSep; Location 13:15-13:20
- #list // o.a.f.c.ASTDirList; Location 14:1-14:30
- - list source: s // o.a.f.c.ASTExpVariable; Location 14:8-14:8
- - target loop variable: "i" // String
- #text // o.a.f.c.ASTStaticText; Location 14:15-14:15
- - content: "1" // String
- #sep // o.a.f.c.ASTDirSep; Location 14:16-14:22
- #text // o.a.f.c.ASTStaticText; Location 14:22-14:22
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 14:31-14:31
- - content: "\n" // String
- #list // o.a.f.c.ASTDirList; Location 15:1-15:45
- - list source: s // o.a.f.c.ASTExpVariable; Location 15:8-15:8
- #items // o.a.f.c.ASTDirItems; Location 15:10-15:37
- - target loop variable: "i" // String
- #sep // o.a.f.c.ASTDirSep; Location 15:23-15:28
- #list // o.a.f.c.ASTDirList; Location 16:1-16:49
- - list source: s // o.a.f.c.ASTExpVariable; Location 16:8-16:8
- #text // o.a.f.c.ASTStaticText; Location 16:10-16:10
- - content: "1" // String
- #items // o.a.f.c.ASTDirItems; Location 16:11-16:40
- - target loop variable: "i" // String
- #text // o.a.f.c.ASTStaticText; Location 16:24-16:24
- - content: "1" // String
- #sep // o.a.f.c.ASTDirSep; Location 16:25-16:31
- #text // o.a.f.c.ASTStaticText; Location 16:31-16:31
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 16:41-16:41
- - content: "1" // String
- #text // o.a.f.c.ASTStaticText; Location 16:50-17:2
- - content: "\n1\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation; Location 18:1-18:8
- - content: + // o.a.f.c.ASTExpAddOrConcat; Location 18:3-18:7
- - left-hand operand: x // o.a.f.c.ASTExpVariable; Location 18:3-18:3
- - right-hand operand: y // o.a.f.c.ASTExpVariable; Location 18:7-18:7
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
deleted file mode 100644
index 99fa244..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
+++ /dev/null
@@ -1,36 +0,0 @@
-<#--
- 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.
--->
-<#if exp></#if>
-<#if exp>1</#if>
-<#if exp>${1}2</#if>
-<#if exp><#else></#if>
-<#if exp>1<#else>1</#if>
-<#if exp>${1}2<#else>${1}2</#if>
-<#if exp><#elseif exp></#if>
-<#if exp><#elseif exp>1</#if>
-<#attempt><#recover></#attempt>
-<#attempt>1<#recover>1</#attempt>
-<#list s as i></#list>
-<#list s as i>1</#list>
-<#list s as i><#sep></#list>
-<#list s as i>1<#sep>1</#list>
-<#list s><#items as i><#sep></#items></#list>
-<#list s>1<#items as i>1<#sep>1</#items>1</#list>
-1
-${x + y}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
deleted file mode 100644
index 41fc90b..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-#if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: true // o.a.f.c.ASTExpBooleanLiteral
- - AST-node subtype: "0" // Integer
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: true // o.a.f.c.ASTExpBooleanLiteral
- - AST-node subtype: "0" // Integer
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: true // o.a.f.c.ASTExpBooleanLiteral
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: " text\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: " " // String
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: true // o.a.f.c.ASTExpBooleanLiteral
- - AST-node subtype: "0" // Integer
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
deleted file mode 100644
index 53716e4..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
+++ /dev/null
@@ -1,26 +0,0 @@
-<#--
- 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.
--->
-<#if true>
- <#if true>
- </#if>
- <#if true>
- text
- </#if>
- <#if true>${x}</#if>
-</#if>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
deleted file mode 100644
index 7675522..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #text // o.a.f.c.ASTStaticText
- - content: "a\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "b\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "c\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "d\n" // String
- #if // o.a.f.c.ASTDirIfOrElseOrElseIf
- - condition: true // o.a.f.c.ASTExpBooleanLiteral
- - AST-node subtype: "0" // Integer
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
deleted file mode 100644
index 501802a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
+++ /dev/null
@@ -1,33 +0,0 @@
-<#--
- 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.
--->
-a
-<#compress></#compress>
-b
-<#compress></#compress>
-<#compress></#compress>
-c
-<#compress></#compress>
-<#compress></#compress>
-<#compress></#compress>
-d
-<#if true>
- <#compress></#compress>
- <#compress></#compress>
- <#compress></#compress>
-</#if>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
deleted file mode 100644
index eefa5b1..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-#outputformat // o.a.f.c.ASTDirOutputFormat
- - value: "HTML" // o.a.f.c.ASTExpStringLiteral
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
deleted file mode 100644
index fbdb342..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-<#outputFormat 'HTML'><#outputFormat 'HTML'><#outputFormat 'HTML'></#outputFormat></#outputFormat></#outputFormat>
\ No newline at end of file
[38/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
new file mode 100644
index 0000000..fe11d1c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
@@ -0,0 +1,671 @@
+/*
+ * 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.core.model.impl;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.freemarker.core.Configuration;
+
+import junit.framework.TestCase;
+
+public class TypeFlagsTest extends TestCase {
+
+ public TypeFlagsTest(String name) {
+ super(name);
+ }
+
+ private final DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ public void testSingleNumType() {
+ checkTypeFlags(SingleNumTypeC.class, "mInt",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.INTEGER | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ | TypeFlags.ACCEPTS_STRING);
+ checkTypeFlags(SingleNumTypeC.class, "mLong",
+ TypeFlags.LONG | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mShort",
+ TypeFlags.SHORT | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mByte",
+ TypeFlags.BYTE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.ACCEPTS_ANY_OBJECT);
+ checkTypeFlags(SingleNumTypeC.class, "mDouble",
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mFloat",
+ TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mUnknown",
+ TypeFlags.UNKNOWN_NUMERICAL_TYPE | TypeFlags.ACCEPTS_NUMBER);
+
+ checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
+ TypeFlags.BIG_DECIMAL | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
+ TypeFlags.BIG_INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER);
+ }
+
+ static public class SingleNumTypeC {
+ public void mInt(int a1, String a2) { }
+ public void mInt(int a1, int a2) { }
+ public void mLong(long a1) { }
+ public void mLong(Long a1) { }
+ public void mShort(short a1) { }
+ public void mByte(byte a1, boolean a2) { }
+ public void mByte(byte a1, String a2) { }
+ public void mByte(byte a1, Object a2) { }
+ public void mDouble(double a1) { }
+ public void mFloat(float a1) { }
+ public void mUnknown(RationalNumber a1) { };
+
+ public void mVarParamCnt(BigDecimal a1) { }
+ public void mVarParamCnt(BigInteger a1, Double a2) { }
+ public void mVarParamCnt(Double a1, Float a2, Integer a3) { }
+ public void mVarParamCnt(Object a1, char a2, boolean a3, File a4, Map a5, Boolean a6) { }
+ public void mVarParamCnt(Long a1, int a2, short a3, byte a4, double a5, float a6) { }
+ }
+
+ public void testMultipleNumTypes() {
+ checkTypeFlags(MultiNumTypeC.class, "m1",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.BYTE | TypeFlags.DOUBLE | TypeFlags.INTEGER
+ | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(MultiNumTypeC.class, "m2",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.SHORT | TypeFlags.LONG | TypeFlags.FLOAT
+ | TypeFlags.ACCEPTS_NUMBER | TypeFlags.CHARACTER
+ );
+
+ checkTypeFlags(MultiNumTypeC.class, "m3",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.BIG_DECIMAL | TypeFlags.BIG_INTEGER
+ | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.BIG_INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.BIG_DECIMAL | TypeFlags.UNKNOWN_NUMERICAL_TYPE
+ | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(MultiNumTypeC.class, "m4",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER
+ | TypeFlags.CHARACTER
+ );
+
+ checkTypeFlags(MultiNumTypeC.class, "m5",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.FLOAT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(MultiNumTypeC.class, "m6",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
+ );
+ assertSame(getTypeFlags(MultiNumTypeC.class, "m6", false, 2), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
+ assertSame(getTypeFlags(MultiNumTypeC.class, "m6", true, 2), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
+ assertSame(getTypeFlags(MultiNumTypeC.class, "m6", false, 3), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
+ assertSame(getTypeFlags(MultiNumTypeC.class, "m6", true, 3), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
+ checkTypeFlags(MultiNumTypeC.class, "m6",
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ 0
+ );
+ }
+
+ static public class MultiNumTypeC {
+ public void m1(byte a1) { };
+ public void m1(int a1) { };
+ public void m1(double a2) { };
+
+ public void m2(short a1) { };
+ public void m2(long a1) { };
+ public void m2(float a1) { };
+ public void m2(char a1) { };
+
+ public void m3(BigInteger a1, BigInteger a2, BigDecimal a3) { };
+ public void m3(BigDecimal a1, BigInteger a2, RationalNumber a3) { };
+
+ public void m4(float a1) { };
+ public void m4(char a1) { };
+
+ public void m5(Float a1) { };
+ public void m5(Double a1) { };
+ public void m5(Enum a1) { };
+
+ public void m6(int a1) { };
+ public void m6(File a1, Throwable a2) { };
+ public void m6(File a1, Throwable a2, StringBuilder a3) { };
+ public void m6(File a1, Throwable a2, Throwable a3) { };
+ public void m6(double a1, int a2, File a3, File a4) { };
+ public void m6(File a1, int a2, double a3, File a4) { };
+ }
+
+ public void testVarargsNums() {
+ checkTypeFlags(VarArgsC.class, "m1",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m2",
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m3",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m3",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.INTEGER
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m3",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.INTEGER
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.INTEGER
+ | TypeFlags.BIG_DECIMAL | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m4",
+ TypeFlags.INTEGER | TypeFlags.LONG
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m5",
+ TypeFlags.LONG | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m6",
+ TypeFlags.LONG | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ | TypeFlags.ACCEPTS_STRING
+ );
+
+ checkTypeFlags(VarArgsC.class, "m7",
+ TypeFlags.INTEGER | TypeFlags.BYTE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.FLOAT
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m8",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.FLOAT
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m9",
+ TypeFlags.INTEGER | TypeFlags.BYTE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m10",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m10",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.LONG | TypeFlags.DOUBLE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m11",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.SHORT | TypeFlags.ACCEPTS_NUMBER
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m11",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.SHORT
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.LONG | TypeFlags.DOUBLE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m12",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
+ );
+ checkTypeFlags(VarArgsC.class, "m12",
+ TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.SHORT
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.BYTE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.LONG | TypeFlags.DOUBLE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+
+ checkTypeFlags(VarArgsC.class, "m13",
+ TypeFlags.CHARACTER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
+ checkTypeFlags(VarArgsC.class, "m13",
+ TypeFlags.CHARACTER,
+ TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.UNKNOWN_NUMERICAL_TYPE
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
+ TypeFlags.DOUBLE | TypeFlags.LONG
+ | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
+ );
+ }
+
+ static public class VarArgsC {
+ public void m1(int... va) { }
+
+ public void m2(double a1, int... va) { }
+
+ public void m3(int... va) { }
+ public void m3(int a1, double... va) { }
+ public void m3(int a1, double a2, BigDecimal... va) { }
+
+ public void m4(int... va) { }
+ public void m4(long... va) { }
+
+ public void m5(Long... va) { }
+ public void m5(long... va) { }
+
+ public void m6(long... va) { }
+ public void m6(String... va) { }
+
+ public void m7(int a1, double... va) { }
+ public void m7(byte a1, float... va) { }
+
+ public void m8(int a1, double... va) { }
+ public void m8(int a1, float... va) { }
+
+ public void m9(int a1, double... va) { }
+ public void m9(byte a1, double... va) { }
+
+ public void m10(int a1, double a2, long... va) { }
+ public void m10(int a1, double... va) { }
+
+ public void m11(int a1, short a2, long... va) { }
+ public void m11(int a1, double... va) { }
+
+ public void m12(int a1, short a2, byte a3, long... va) { }
+ public void m12(int a1, double... va) { }
+
+ public void m13(char a1, double a2, RationalNumber a3, Long... va) { }
+ public void m13(char a1, Double... va) { }
+ }
+
+ public void testAllZeros() {
+ for (boolean reverse : new boolean[] { true, false }) {
+ assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m1", reverse, 0));
+ assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m2", reverse, 2));
+ assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m3", reverse, 1));
+ }
+ }
+
+ static public class AllZeroC {
+ public void m1() {}
+
+ public void m2(File a1, File a2) {}
+
+ public void m3(File a1) {}
+ public void m3(StringBuilder a1) {}
+ }
+
+ public void testAcceptanceNonOverloaded() {
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber1", TypeFlags.ACCEPTS_NUMBER | TypeFlags.UNKNOWN_NUMERICAL_TYPE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber2", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BYTE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber3", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BYTE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber4", TypeFlags.ACCEPTS_NUMBER | TypeFlags.SHORT);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber5", TypeFlags.ACCEPTS_NUMBER | TypeFlags.SHORT);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber6", TypeFlags.ACCEPTS_NUMBER | TypeFlags.INTEGER);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber7", TypeFlags.ACCEPTS_NUMBER | TypeFlags.INTEGER);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber8", TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber9", TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber10", TypeFlags.ACCEPTS_NUMBER | TypeFlags.FLOAT);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber11", TypeFlags.ACCEPTS_NUMBER | TypeFlags.FLOAT);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber12", TypeFlags.ACCEPTS_NUMBER | TypeFlags.DOUBLE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber13", TypeFlags.ACCEPTS_NUMBER | TypeFlags.DOUBLE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber14", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BIG_INTEGER);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber15", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BIG_DECIMAL);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber16", TypeFlags.ACCEPTS_NUMBER | TypeFlags.UNKNOWN_NUMERICAL_TYPE);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mDate", TypeFlags.ACCEPTS_DATE);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mSQLDate1", 0);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mSQLDate2", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mString", TypeFlags.ACCEPTS_STRING);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mCharSequence", TypeFlags.ACCEPTS_STRING);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mStringBuilder", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mBool", TypeFlags.ACCEPTS_BOOLEAN);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mBoolean", TypeFlags.ACCEPTS_BOOLEAN);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mMap1", TypeFlags.ACCEPTS_MAP);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mMap2", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mList1", TypeFlags.ACCEPTS_LIST);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mList2", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mSet1", TypeFlags.ACCEPTS_SET);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mSet2", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mCollection", TypeFlags.ACCEPTS_SET | TypeFlags.ACCEPTS_LIST);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mChar1", TypeFlags.CHARACTER);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mChar2", TypeFlags.CHARACTER);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray1", TypeFlags.ACCEPTS_ARRAY);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray2", TypeFlags.ACCEPTS_ARRAY);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray3", TypeFlags.ACCEPTS_ARRAY);
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray4", TypeFlags.ACCEPTS_ARRAY);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mObject", TypeFlags.ACCEPTS_ANY_OBJECT);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_NUMBER) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_STRING) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_BOOLEAN) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_MAP) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_LIST) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_SET) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_ARRAY) != 0);
+ assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.CHARACTER) == 0); // deliberatly 0
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mMapDate", 0);
+
+ checkTypeFlags(AcceptanceNonoverloadedC.class, "mDateBooleanList",
+ TypeFlags.ACCEPTS_DATE, TypeFlags.ACCEPTS_BOOLEAN, TypeFlags.ACCEPTS_LIST);
+ }
+
+ static public class AcceptanceNonoverloadedC {
+ public void mNumber1(Number a1) {}
+ public void mNumber2(Byte a1) {}
+ public void mNumber3(byte a1) {}
+ public void mNumber4(Short a1) {}
+ public void mNumber5(short a1) {}
+ public void mNumber6(Integer a1) {}
+ public void mNumber7(int a1) {}
+ public void mNumber8(Long a1) {}
+ public void mNumber9(long a1) {}
+ public void mNumber10(Float a1) {}
+ public void mNumber11(float a1) {}
+ public void mNumber12(Double a1) {}
+ public void mNumber13(double a1) {}
+ public void mNumber14(BigInteger a1) {}
+ public void mNumber15(BigDecimal a1) {}
+ public void mNumber16(RationalNumber a1) {}
+
+ public void mDate(Date a1) {}
+ public void mSQLDate1(java.sql.Date a1) {}
+ public void mSQLDate2(java.sql.Timestamp a1) {}
+
+ public void mString(String a1) {}
+ public void mCharSequence(CharSequence a1) {}
+ public void mStringBuilder(StringBuilder a1) {}
+
+ public void mBool(boolean a1) {}
+ public void mBoolean(Boolean a1) {}
+
+ public void mMap1(Map a1) {}
+ public void mMap2(LinkedHashMap a1) {}
+
+ public void mList1(List a1) {}
+ public void mList2(ArrayList a1) {}
+
+ public void mSet1(Set a1) {}
+ public void mSet2(HashSet a1) {}
+
+ public void mCollection(Collection a1) {}
+
+ public void mMapDate(MapDate a1) {}
+
+ public void mChar1(Character a1) {}
+ public void mChar2(char a1) {}
+
+ public void mArray1(Object[] a1) {}
+ public void mArray2(int[] a1) {}
+ public void mArray3(Integer[] a1) {}
+ public void mArray4(Void[] a1) {}
+
+ public void mObject(Object a1) {}
+
+ public void mDateBooleanList(Date a1, boolean a2, List a3) {}
+ }
+
+ public void testAcceptanceOverloaded() {
+ checkTypeFlags(AcceptanceOverloadedC.class, "mLongDateList",
+ TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
+ | TypeFlags.ACCEPTS_DATE | TypeFlags.ACCEPTS_LIST);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mBoolean", TypeFlags.ACCEPTS_BOOLEAN);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mStringChar",
+ TypeFlags.ACCEPTS_STRING | TypeFlags.CHARACTER);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mStringFile", TypeFlags.ACCEPTS_STRING);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mMapObject", TypeFlags.ACCEPTS_ANY_OBJECT);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mSetMap", TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_SET);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mCollectionMap",
+ TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_SET | TypeFlags.ACCEPTS_LIST);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mArray", TypeFlags.ACCEPTS_ARRAY);
+ checkTypeFlags(AcceptanceOverloadedC.class, "mArrayList", TypeFlags.ACCEPTS_ARRAY | TypeFlags.ACCEPTS_LIST);
+
+ checkTypeFlags(AcceptanceOverloadedC.class, "mStringCollectionThenBooleanThenMapList",
+ TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_LIST | TypeFlags.ACCEPTS_SET,
+ TypeFlags.ACCEPTS_BOOLEAN,
+ TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_LIST);
+ }
+
+ static public class AcceptanceOverloadedC {
+ public void mLongDateList(long a1) {}
+ public void mLongDateList(Date a1) {}
+ public void mLongDateList(List a1) {}
+
+ public void mBoolean(boolean a1) {}
+ public void mBoolean(Boolean a1) {}
+
+ public void mDate(Date a1) {}
+ public void mDate(java.sql.Date a1) {}
+ public void mDate(java.sql.Timestamp a1) {}
+
+ public void mStringChar(String a1) {}
+ public void mStringChar(char a1) {}
+ public void mStringChar(Character a1) {}
+
+ public void mStringFile(String a1) {}
+ public void mStringFile(File a1) {}
+
+ public void mMapObject(Map a1) {}
+ public void mMapObject(Object a1) {}
+
+ public void mSetMap(Set a1) {}
+ public void mSetMap(Map a1) {}
+
+ public void mCollectionMap(Collection a1) {}
+ public void mCollectionMap(Map a1) {}
+
+ public void mArray(Object[] a1) {}
+ public void mArray(int[] a1) {}
+ public void mArray(Integer[] a1) {}
+ public void mArray(Void[] a1) {}
+
+ public void mArrayList(String[] a1) {}
+ public void mArrayList(List a1) {}
+
+ public void mStringCollectionThenBooleanThenMapList(String a1, boolean a2, Map a3) {}
+ public void mStringCollectionThenBooleanThenMapList(Collection a1, boolean a2, Map a3) {}
+ public void mStringCollectionThenBooleanThenMapList(String a1, boolean a2, List a3) {}
+ }
+
+ public void testAcceptanceVarargsC() {
+ checkTypeFlags(AcceptanceVarArgsC.class, "m1",
+ TypeFlags.ACCEPTS_LIST | TypeFlags.ACCEPTS_STRING);
+
+ checkTypeFlags(AcceptanceVarArgsC.class, "m2",
+ TypeFlags.ACCEPTS_MAP,
+ TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_BOOLEAN,
+ TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING);
+ checkTypeFlags(AcceptanceVarArgsC.class, "m2",
+ TypeFlags.ACCEPTS_MAP,
+ TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_BOOLEAN);
+ checkTypeFlags(AcceptanceVarArgsC.class, "m2",
+ TypeFlags.ACCEPTS_MAP);
+
+ checkTypeFlags(AcceptanceVarArgsC.class, "m3",
+ TypeFlags.ACCEPTS_BOOLEAN);
+ checkTypeFlags(AcceptanceVarArgsC.class, "m3",
+ TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.ACCEPTS_STRING,
+ TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.ACCEPTS_MAP,
+ TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.CHARACTER,
+ TypeFlags.ACCEPTS_BOOLEAN);
+ }
+
+ static public class AcceptanceVarArgsC {
+ public void m1(List... a1) {}
+ public void m1(String... a1) {}
+
+ public void m2(Map a1, String... a2) {}
+ public void m2(Map a1, boolean a2, String... a3) {}
+ public void m2(Map... a1) {}
+
+ public void m3(String a1, Map a2, char a3, Boolean... a4) {}
+ public void m3(boolean... a1) {}
+ }
+
+ static public class MapDate extends Date implements Map {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return false;
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return false;
+ }
+
+ @Override
+ public Object get(Object key) {
+ return null;
+ }
+
+ @Override
+ public Object put(Object key, Object value) {
+ return null;
+ }
+
+ @Override
+ public Object remove(Object key) {
+ return null;
+ }
+
+ @Override
+ public void putAll(Map m) {
+ }
+
+ @Override
+ public void clear() {
+ }
+
+ @Override
+ public Set keySet() {
+ return null;
+ }
+
+ @Override
+ public Collection values() {
+ return null;
+ }
+
+ @Override
+ public Set entrySet() {
+ return null;
+ }
+
+ }
+
+ private OverloadedMethodsSubset newOverloadedMethodsSubset(Class cl, String methodName, final boolean desc) {
+ final Method[] ms = cl.getMethods();
+
+ final List<Method> filteredMethods = new ArrayList();
+ for (Method m : ms) {
+ if (m.getName().equals(methodName)) {
+ filteredMethods.add(m);
+ }
+ }
+ // As the order in which getMethods() returns the methods is undefined, we sort them for test predictability:
+ Collections.sort(filteredMethods, new Comparator<Method>() {
+ @Override
+ public int compare(Method o1, Method o2) {
+ int res = o1.toString().compareTo(o2.toString());
+ return desc ? -res : res;
+ }
+ });
+
+ final OverloadedMethodsSubset oms = cl.getName().indexOf("VarArgs") == -1
+ ? new OverloadedFixArgsMethods() : new OverloadedVarArgsMethods();
+ for (Method m : filteredMethods) {
+ oms.addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(m, m.getParameterTypes()));
+ }
+ return oms;
+ }
+
+ private void checkTypeFlags(Class cl, String methodName, int... expectedTypeFlags) {
+ checkTypeFlags(cl, methodName, false, expectedTypeFlags);
+ checkTypeFlags(cl, methodName, true, expectedTypeFlags);
+ }
+
+ private void checkTypeFlags(Class cl, String methodName, boolean revMetOrder, int... expectedTypeFlags) {
+ int[] actualParamTypes = getTypeFlags(cl, methodName, revMetOrder, expectedTypeFlags.length);
+ assertNotNull("Method " + methodName + "(#" + expectedTypeFlags.length + ") doesn't exist", actualParamTypes);
+ if (actualParamTypes != OverloadedMethodsSubset.ALL_ZEROS_ARRAY) {
+ assertEquals(expectedTypeFlags.length, actualParamTypes.length);
+ for (int i = 0; i < expectedTypeFlags.length; i++) {
+ assertEquals(expectedTypeFlags[i], actualParamTypes[i]);
+ }
+ } else {
+ for (int expectedTypeFlag : expectedTypeFlags) {
+ assertEquals(expectedTypeFlag, 0);
+ }
+ }
+ }
+
+ private int[] getTypeFlags(Class cl, String methodName, boolean revMetOrder, int paramCnt) {
+ OverloadedMethodsSubset oms = newOverloadedMethodsSubset(cl, methodName, revMetOrder);
+ int[] actualParamTypes = oms.getTypeFlags(paramCnt);
+ return actualParamTypes;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
new file mode 100644
index 0000000..0a479aa
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
@@ -0,0 +1,35 @@
+/*
+ * 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.core.outputformat;
+
+public final class _OutputFormatTestAPI {
+
+ private _OutputFormatTestAPI() {
+ //
+ }
+
+ public static String getMarkupContent(CommonTemplateMarkupOutputModel<?> tm) {
+ return tm.getMarkupContent();
+ }
+
+ public static String getPlainTextContent(CommonTemplateMarkupOutputModel<?> tm) {
+ return tm.getPlainTextContent();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
new file mode 100644
index 0000000..19e45de
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.core.outputformat.impl;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
+import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
+import org.junit.Test;
+
+public class CombinedMarkupOutputFormatTest {
+
+ private static final CombinedMarkupOutputFormat HTML_RTF = new CombinedMarkupOutputFormat(
+ HTMLOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE);
+ private static final CombinedMarkupOutputFormat XML_XML = new CombinedMarkupOutputFormat(
+ XMLOutputFormat.INSTANCE, XMLOutputFormat.INSTANCE);
+
+ @Test
+ public void testName() {
+ assertEquals("HTML{RTF}", HTML_RTF.getName());
+ assertEquals("XML{XML}", XML_XML.getName());
+ }
+
+ @Test
+ public void testOutputMO() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ HTML_RTF.output(HTML_RTF.fromMarkup("<pre>\\par Test "), out);
+ HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("foo { bar } \\ "), out);
+ HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("& baaz "), out);
+ HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("\\par & qwe"), out);
+ HTML_RTF.output(HTML_RTF.fromMarkup("\\par{0} End</pre>"), out);
+
+ assertEquals(
+ "<pre>\\par Test "
+ + "foo \\{ bar \\} \\\\ "
+ + "& baaz "
+ + "\\\\par & qwe"
+ + "\\par{0} End</pre>",
+ out.toString());
+ }
+
+ @Test
+ public void testOutputMO2() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ XML_XML.output(XML_XML.fromMarkup("<pre><p> Test "), out);
+ XML_XML.output(XML_XML.fromPlainTextByEscaping("a & b < c"), out);
+ XML_XML.output(XML_XML.fromMarkup(" End</pre>"), out);
+
+ assertEquals(
+ "<pre><p> Test "
+ + "a &amp; b &lt; c"
+ + " End</pre>",
+ out.toString());
+ }
+
+ @Test
+ public void testOutputMO3() throws TemplateModelException, IOException {
+ MarkupOutputFormat outputFormat = new CombinedMarkupOutputFormat(
+ RTFOutputFormat.INSTANCE,
+ new CombinedMarkupOutputFormat(RTFOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE));
+ StringWriter out = new StringWriter();
+
+ outputFormat.output(outputFormat.fromPlainTextByEscaping("b{}"), out);
+ outputFormat.output(outputFormat.fromMarkup("a{}"), out);
+
+ assertEquals(
+ "b\\\\\\\\\\\\\\{\\\\\\\\\\\\\\}"
+ + "a{}",
+ out.toString());
+ }
+
+ @Test
+ public void testOutputString() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ HTML_RTF.output("a", out);
+ HTML_RTF.output("{", out);
+ HTML_RTF.output("<b>}c", out);
+
+ assertEquals("a\\{<b>\\}c", out.toString());
+ }
+
+ @Test
+ public void testOutputString2() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ XML_XML.output("a", out);
+ XML_XML.output("&", out);
+ XML_XML.output("<b>", out);
+
+ assertEquals("a&amp;&lt;b&gt;", out.toString());
+ }
+
+ @Test
+ public void testFromPlainTextByEscaping() throws TemplateModelException {
+ String plainText = "a\\b&c";
+ TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromPlainTextByEscaping(plainText);
+ assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testFromMarkup() throws TemplateModelException {
+ String markup = "a \\par <b>";
+ TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromMarkup(markup);
+ assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
+ assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testGetMarkup() throws TemplateModelException {
+ {
+ String markup = "a \\par <b>";
+ TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromMarkup(markup);
+ assertSame(markup, HTML_RTF.getMarkupString(mo));
+ }
+
+ {
+ String safe = "abc";
+ TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromPlainTextByEscaping(safe);
+ assertSame(safe, HTML_RTF.getMarkupString(mo));
+ }
+ }
+
+ @Test
+ public void testConcat() throws Exception {
+ assertMO(
+ "ab", null,
+ HTML_RTF.concat(
+ new TemplateCombinedMarkupOutputModel("a", null, HTML_RTF),
+ new TemplateCombinedMarkupOutputModel("b", null, HTML_RTF)));
+ assertMO(
+ null, "ab",
+ HTML_RTF.concat(
+ new TemplateCombinedMarkupOutputModel(null, "a", HTML_RTF),
+ new TemplateCombinedMarkupOutputModel(null, "b", HTML_RTF)));
+ assertMO(
+ null, "{<a>}\\{<b>\\}",
+ HTML_RTF.concat(
+ new TemplateCombinedMarkupOutputModel(null, "{<a>}", HTML_RTF),
+ new TemplateCombinedMarkupOutputModel("{<b>}", null, HTML_RTF)));
+ assertMO(
+ null, "\\{<a>\\}{<b>}",
+ HTML_RTF.concat(
+ new TemplateCombinedMarkupOutputModel("{<a>}", null, HTML_RTF),
+ new TemplateCombinedMarkupOutputModel(null, "{<b>}", HTML_RTF)));
+ }
+
+ @Test
+ public void testEscaplePlainText() throws TemplateModelException {
+ assertEquals("", HTML_RTF.escapePlainText(""));
+ assertEquals("a", HTML_RTF.escapePlainText("a"));
+ assertEquals("\\{a\\\\b&\\}", HTML_RTF.escapePlainText("{a\\b&}"));
+ assertEquals("a\\\\b&", HTML_RTF.escapePlainText("a\\b&"));
+ assertEquals("\\{\\}&", HTML_RTF.escapePlainText("{}&"));
+
+ assertEquals("a", XML_XML.escapePlainText("a"));
+ assertEquals("a&apos;b", XML_XML.escapePlainText("a'b"));
+ }
+
+ private void assertMO(String pc, String mc, TemplateCombinedMarkupOutputModel mo) {
+ assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("text/html", HTML_RTF.getMimeType());
+ assertEquals("application/xml", XML_XML.getMimeType());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
new file mode 100644
index 0000000..2199179
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.core.outputformat.impl;
+
+import static org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
+import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
+import org.junit.Test;
+
+/**
+ * This actually more a {@link CommonMarkupOutputFormat} test.
+ */
+public class HTMLOutputFormatTest {
+
+ @Test
+ public void testOutputMO() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ INSTANCE.output(INSTANCE.fromMarkup("<p>Test "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("foo & bar "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("baaz "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("<b>A</b> <b>B</b> <b>C</b>"), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping(""), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("\"' x's \"y\" \""), out);
+ INSTANCE.output(INSTANCE.fromMarkup("</p>"), out);
+
+ assertEquals(
+ "<p>Test "
+ + "foo & bar "
+ + "baaz "
+ + "<b>A</b> <b>B</b> <b>C</b>"
+ + ""' x's "y" ""
+ + "</p>",
+ out.toString());
+ }
+
+ @Test
+ public void testOutputString() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ INSTANCE.output("a", out);
+ INSTANCE.output("<", out);
+ INSTANCE.output("b'c", out);
+
+ assertEquals("a<b'c", out.toString());
+ }
+
+ @Test
+ public void testFromPlainTextByEscaping() throws TemplateModelException {
+ String plainText = "a&b";
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(plainText);
+ assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testFromMarkup() throws TemplateModelException {
+ String markup = "a&b";
+ TemplateHTMLOutputModel mo = INSTANCE.fromMarkup(markup);
+ assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
+ assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testGetMarkup() throws TemplateModelException {
+ {
+ String markup = "a&b";
+ TemplateHTMLOutputModel mo = INSTANCE.fromMarkup(markup);
+ assertSame(markup, INSTANCE.getMarkupString(mo));
+ }
+
+ {
+ String safe = "abc";
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
+ assertSame(safe, INSTANCE.getMarkupString(mo));
+ }
+ {
+ String safe = "";
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
+ assertSame(safe, INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<abc");
+ assertEquals("<abc", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("abc>");
+ assertEquals("abc>", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<abc>");
+ assertEquals("<abc>", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a&bc");
+ assertEquals("a&bc", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a&b&c");
+ assertEquals("a&b&c", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a<&>b&c");
+ assertEquals("a<&>b&c", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("\"<a<&>b&c>\"");
+ assertEquals(""<a<&>b&c>"", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<");
+ assertEquals("<", INSTANCE.getMarkupString(mo));
+ }
+ {
+ TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("'");
+ String mc = INSTANCE.getMarkupString(mo);
+ assertEquals("'", mc);
+ assertSame(mc, INSTANCE.getMarkupString(mo)); // cached
+ }
+ }
+
+ @Test
+ public void testConcat() throws Exception {
+ assertMO(
+ "ab", null,
+ INSTANCE.concat(new TemplateHTMLOutputModel("a", null), new TemplateHTMLOutputModel("b", null)));
+ assertMO(
+ null, "ab",
+ INSTANCE.concat(new TemplateHTMLOutputModel(null, "a"), new TemplateHTMLOutputModel(null, "b")));
+ assertMO(
+ null, "<a><b>",
+ INSTANCE.concat(new TemplateHTMLOutputModel(null, "<a>"), new TemplateHTMLOutputModel("<b>", null)));
+ assertMO(
+ null, "<a><b>",
+ INSTANCE.concat(new TemplateHTMLOutputModel("<a>", null), new TemplateHTMLOutputModel(null, "<b>")));
+ }
+
+ @Test
+ public void testEscaplePlainText() {
+ assertEquals("", INSTANCE.escapePlainText(""));
+ assertEquals("a", INSTANCE.escapePlainText("a"));
+ assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
+ assertEquals("a&b", INSTANCE.escapePlainText("a&b"));
+ assertEquals("<>", INSTANCE.escapePlainText("<>"));
+ }
+
+ @Test
+ public void testIsEmpty() throws Exception {
+ assertTrue(INSTANCE.isEmpty(INSTANCE.fromMarkup("")));
+ assertTrue(INSTANCE.isEmpty(INSTANCE.fromPlainTextByEscaping("")));
+ assertFalse(INSTANCE.isEmpty(INSTANCE.fromMarkup(" ")));
+ assertFalse(INSTANCE.isEmpty(INSTANCE.fromPlainTextByEscaping(" ")));
+ }
+
+ private void assertMO(String pc, String mc, TemplateHTMLOutputModel mo) {
+ assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("text/html", INSTANCE.getMimeType());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
new file mode 100644
index 0000000..13563f5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.core.outputformat.impl;
+
+import static org.apache.freemarker.core.outputformat.impl.RTFOutputFormat.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
+import org.junit.Test;
+
+public class RTFOutputFormatTest {
+
+ @Test
+ public void testOutputMO() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ INSTANCE.output(INSTANCE.fromMarkup("\\par Test "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("foo { bar } \\ "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("baaz "), out);
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("\\par qweqwe"), out);
+ INSTANCE.output(INSTANCE.fromMarkup("\\par{0} End"), out);
+
+ assertEquals(
+ "\\par Test "
+ + "foo \\{ bar \\} \\\\ "
+ + "baaz "
+ + "\\\\par qweqwe"
+ + "\\par{0} End",
+ out.toString());
+ }
+
+ @Test
+ public void testOutputString() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+
+ INSTANCE.output("a", out);
+ INSTANCE.output("{", out);
+ INSTANCE.output("b}c", out);
+
+ assertEquals("a\\{b\\}c", out.toString());
+ }
+
+ @Test
+ public void testFromPlainTextByEscaping() throws TemplateModelException {
+ String plainText = "a\\b";
+ TemplateRTFOutputModel mo = INSTANCE.fromPlainTextByEscaping(plainText);
+ assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testFromMarkup() throws TemplateModelException {
+ String markup = "a \\par b";
+ TemplateRTFOutputModel mo = INSTANCE.fromMarkup(markup);
+ assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
+ assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
+ }
+
+ @Test
+ public void testGetMarkup() throws TemplateModelException {
+ {
+ String markup = "a \\par b";
+ TemplateRTFOutputModel mo = INSTANCE.fromMarkup(markup);
+ assertSame(markup, INSTANCE.getMarkupString(mo));
+ }
+
+ {
+ String safe = "abc";
+ TemplateRTFOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
+ assertSame(safe, INSTANCE.getMarkupString(mo));
+ }
+ }
+
+ @Test
+ public void testConcat() throws Exception {
+ assertMO(
+ "ab", null,
+ INSTANCE.concat(new TemplateRTFOutputModel("a", null), new TemplateRTFOutputModel("b", null)));
+ assertMO(
+ null, "ab",
+ INSTANCE.concat(new TemplateRTFOutputModel(null, "a"), new TemplateRTFOutputModel(null, "b")));
+ assertMO(
+ null, "{a}\\{b\\}",
+ INSTANCE.concat(new TemplateRTFOutputModel(null, "{a}"), new TemplateRTFOutputModel("{b}", null)));
+ assertMO(
+ null, "\\{a\\}{b}",
+ INSTANCE.concat(new TemplateRTFOutputModel("{a}", null), new TemplateRTFOutputModel(null, "{b}")));
+ }
+
+ @Test
+ public void testEscaplePlainText() {
+ assertEquals("", INSTANCE.escapePlainText(""));
+ assertEquals("a", INSTANCE.escapePlainText("a"));
+ assertEquals("\\{a\\\\b\\}", INSTANCE.escapePlainText("{a\\b}"));
+ assertEquals("a\\\\b", INSTANCE.escapePlainText("a\\b"));
+ assertEquals("\\{\\}", INSTANCE.escapePlainText("{}"));
+ }
+
+ private void assertMO(String pc, String mc, TemplateRTFOutputModel mo) {
+ assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
+ assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("application/rtf", INSTANCE.getMimeType());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
new file mode 100644
index 0000000..a7063fd
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
@@ -0,0 +1,365 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
+import org.apache.freemarker.test.MonitoredTemplateLoader;
+import org.apache.freemarker.test.MonitoredTemplateLoader.CloseSessionEvent;
+import org.apache.freemarker.test.MonitoredTemplateLoader.CreateSessionEvent;
+import org.apache.freemarker.test.MonitoredTemplateLoader.LoadEvent;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class DefaultTemplateResolverTest {
+
+ @Test
+ public void testCachedException() throws Exception {
+ MockTemplateLoader loader = new MockTemplateLoader();
+ DefaultTemplateResolver tr = new DefaultTemplateResolver(
+ loader,
+ new StrongCacheStorage(), 1000L,
+ DefaultTemplateLookupStrategy.INSTANCE, true,
+ DefaultTemplateNameFormat.INSTANCE,
+ null,
+ new TestConfigurationBuilder().build());
+ loader.setThrowException(true);
+ try {
+ tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
+ fail();
+ } catch (IOException e) {
+ assertEquals("mock IO exception", e.getMessage());
+ assertEquals(1, loader.getLoadAttemptCount());
+ try {
+ tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
+ fail();
+ } catch (IOException e2) {
+ // Still 1 - returned cached exception
+ assertThat(e2.getMessage(),
+ Matchers.allOf(Matchers.containsString("There was an error loading the template on an " +
+ "earlier attempt")));
+ assertSame(e, e2.getCause());
+ assertEquals(1, loader.getLoadAttemptCount());
+ try {
+ Thread.sleep(1100L);
+ tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
+ fail();
+ } catch (IOException e3) {
+ // Cache had to retest
+ assertEquals("mock IO exception", e.getMessage());
+ assertEquals(2, loader.getLoadAttemptCount());
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testCachedNotFound() throws Exception {
+ MockTemplateLoader loader = new MockTemplateLoader();
+ DefaultTemplateResolver cache = new DefaultTemplateResolver(
+ loader,
+ new StrongCacheStorage(), 1000L,
+ DefaultTemplateLookupStrategy.INSTANCE, false,
+ DefaultTemplateNameFormat.INSTANCE,
+ null, new TestConfigurationBuilder().build());
+ assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
+ assertEquals(1, loader.getLoadAttemptCount());
+ assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
+ // Still 1 - returned cached exception
+ assertEquals(1, loader.getLoadAttemptCount());
+ Thread.sleep(1100L);
+ assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
+ // Cache had to retest
+ assertEquals(2, loader.getLoadAttemptCount());
+ }
+
+ private static class MockTemplateLoader implements TemplateLoader {
+ private boolean throwException;
+ private int loadAttemptCount;
+
+ public void setThrowException(boolean throwException) {
+ this.throwException = throwException;
+ }
+
+ public int getLoadAttemptCount() {
+ return loadAttemptCount;
+ }
+
+ @Override
+ public TemplateLoaderSession createSession() {
+ return null;
+ }
+
+ @Override
+ public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom,
+ Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException {
+ ++loadAttemptCount;
+ if (throwException) {
+ throw new IOException("mock IO exception");
+ }
+ return TemplateLoadingResult.NOT_FOUND;
+ }
+
+ @Override
+ public void resetState() {
+ //
+ }
+
+ }
+
+ @Test
+ public void testManualRemovalPlain() throws Exception {
+ StringTemplateLoader loader = new StringTemplateLoader();
+ Configuration cfg = new TestConfigurationBuilder()
+ .cacheStorage(new StrongCacheStorage())
+ .templateLoader(loader)
+ .templateUpdateDelayMilliseconds(Long.MAX_VALUE)
+ .build();
+
+ loader.putTemplate("1.ftl", "1 v1");
+ loader.putTemplate("2.ftl", "2 v1");
+ assertEquals("1 v1", cfg.getTemplate("1.ftl").toString());
+ assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
+
+ loader.putTemplate("1.ftl", "1 v2");
+ loader.putTemplate("2.ftl", "2 v2");
+ assertEquals("1 v1", cfg.getTemplate("1.ftl").toString()); // no change
+ assertEquals("2 v1", cfg.getTemplate("2.ftl").toString()); // no change
+
+ cfg.removeTemplateFromCache("1.ftl", cfg.getLocale(), null);
+ assertEquals("1 v2", cfg.getTemplate("1.ftl").toString()); // changed
+ assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
+
+ cfg.removeTemplateFromCache("2.ftl", cfg.getLocale(), null);
+ assertEquals("1 v2", cfg.getTemplate("1.ftl").toString());
+ assertEquals("2 v2", cfg.getTemplate("2.ftl").toString()); // changed
+ }
+
+ @Test
+ public void testManualRemovalI18ed() throws Exception {
+ StringTemplateLoader loader = new StringTemplateLoader();
+ Configuration cfg = new TestConfigurationBuilder()
+ .cacheStorage(new StrongCacheStorage())
+ .templateLoader(loader)
+ .templateUpdateDelayMilliseconds(Long.MAX_VALUE)
+ .build();
+
+ loader.putTemplate("1_en_US.ftl", "1_en_US v1");
+ loader.putTemplate("1_en.ftl", "1_en v1");
+ loader.putTemplate("1.ftl", "1 v1");
+
+ assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());
+ assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
+ assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
+
+ loader.putTemplate("1_en_US.ftl", "1_en_US v2");
+ loader.putTemplate("1_en.ftl", "1_en v2");
+ loader.putTemplate("1.ftl", "1 v2");
+ assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());
+ assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
+ assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
+
+ cfg.removeTemplateFromCache("1.ftl", cfg.getLocale(), null);
+ assertEquals("1_en_US v2", cfg.getTemplate("1.ftl").toString());
+ assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
+ assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
+ assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.ITALY).toString());
+
+ cfg.removeTemplateFromCache("1.ftl", Locale.GERMANY, null);
+ assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
+ assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
+
+ cfg.removeTemplateFromCache("1.ftl", Locale.CANADA, null);
+ assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
+
+ cfg.removeTemplateFromCache("1.ftl", Locale.UK, null);
+ assertEquals("1_en v2", cfg.getTemplate("1.ftl", Locale.UK).toString());
+ }
+
+ @Test
+ public void testZeroUpdateDelay() throws Exception {
+ MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
+ .cacheStorage(new StrongCacheStorage())
+ .templateLoader(loader)
+ .templateUpdateDelayMilliseconds(0);
+
+ Configuration cfg = cfgB.build();
+
+ for (int i = 1; i <= 3; i++) {
+ loader.putTextTemplate("t.ftl", "v" + i);
+ assertEquals("v" + i, cfg.getTemplate("t.ftl").toString());
+ }
+
+ loader.clearEvents();
+ loader.putTextTemplate("t.ftl", "v8");
+ assertEquals("v8", cfg.getTemplate("t.ftl").toString());
+ assertEquals("v8", cfg.getTemplate("t.ftl").toString());
+ loader.putTextTemplate("t.ftl", "v9");
+ assertEquals("v9", cfg.getTemplate("t.ftl").toString());
+ assertEquals("v9", cfg.getTemplate("t.ftl").toString());
+ assertEquals(
+ ImmutableList.of(
+ new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8
+ new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED),
+
+ new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8
+ new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
+
+ new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9
+ new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED),
+
+ new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9
+ new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED)
+ ),
+ loader.getEvents(LoadEvent.class));
+
+ cfg = cfgB.localizedLookup(false).build();
+ loader.clearEvents();
+ loader.putTextTemplate("t.ftl", "v10");
+ assertEquals("v10", cfg.getTemplate("t.ftl").toString());
+ loader.putTextTemplate("t.ftl", "v11"); // same time stamp, different content
+ assertEquals("v11", cfg.getTemplate("t.ftl").toString());
+ assertEquals("v11", cfg.getTemplate("t.ftl").toString());
+ assertEquals("v11", cfg.getTemplate("t.ftl").toString());
+ Thread.sleep(17L);
+ assertEquals("v11", cfg.getTemplate("t.ftl").toString());
+ loader.putTextTemplate("t.ftl", "v12");
+ assertEquals("v12", cfg.getTemplate("t.ftl").toString());
+ assertEquals("v12", cfg.getTemplate("t.ftl").toString());
+ assertEquals(
+ ImmutableList.of(
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v10
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v11
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v12
+ new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED)
+ ),
+ loader.getEvents(LoadEvent.class));
+ }
+
+ @Test
+ public void testWrongEncodingReload() throws Exception {
+ MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
+ loader.putBinaryTemplate("utf-8_en.ftl", "<#ftl encoding='utf-8'>Béka");
+ loader.putBinaryTemplate("utf-8.ftl", "Bar");
+ loader.putBinaryTemplate("iso-8859-1_en_US.ftl", "<#ftl encoding='ISO-8859-1'>Béka",
+ StandardCharsets.ISO_8859_1, "v1");
+ Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
+
+ {
+ Template t = cfg.getTemplate("utf-8.ftl");
+ assertEquals("utf-8.ftl", t.getLookupName());
+ assertEquals("utf-8_en.ftl", t.getSourceName());
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ assertEquals("Béka", t.toString());
+
+ assertEquals(
+ ImmutableList.of(
+ CreateSessionEvent.INSTANCE,
+ new LoadEvent("utf-8_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("utf-8_en.ftl", TemplateLoadingResultStatus.OPENED),
+ CloseSessionEvent.INSTANCE),
+ loader.getEvents());
+ }
+
+ {
+ loader.clearEvents();
+
+ Template t = cfg.getTemplate("iso-8859-1.ftl");
+ assertEquals("iso-8859-1.ftl", t.getLookupName());
+ assertEquals("iso-8859-1_en_US.ftl", t.getSourceName());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ assertEquals("Béka", t.toString());
+
+ assertEquals(
+ ImmutableList.of(
+ CreateSessionEvent.INSTANCE,
+ new LoadEvent("iso-8859-1_en_US.ftl", TemplateLoadingResultStatus.OPENED),
+ CloseSessionEvent.INSTANCE),
+ loader.getEvents());
+ }
+ }
+
+ @Test
+ public void testNoWrongEncodingForTemplateLoader2WithReader() throws Exception {
+ MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
+ loader.putTextTemplate("foo_en.ftl", "<#ftl encoding='utf-8'>ő");
+ loader.putTextTemplate("foo.ftl", "B");
+ Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
+
+ {
+ Template t = cfg.getTemplate("foo.ftl");
+ assertEquals("foo.ftl", t.getLookupName());
+ assertEquals("foo_en.ftl", t.getSourceName());
+ assertNull(t.getActualSourceEncoding());
+ assertEquals("ő", t.toString());
+
+ assertEquals(
+ ImmutableList.of(
+ CreateSessionEvent.INSTANCE,
+ new LoadEvent("foo_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND),
+ new LoadEvent("foo_en.ftl", TemplateLoadingResultStatus.OPENED),
+ CloseSessionEvent.INSTANCE),
+ loader.getEvents());
+ }
+ }
+
+ @Test
+ public void testTemplateNameFormatException() throws Exception {
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateNameFormat(DefaultTemplateNameFormat.INSTANCE)
+ .build();
+ try {
+ cfg.getTemplate("../x");
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ // expected
+ }
+ try {
+ cfg.getTemplate("\\x");
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ // expected
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
new file mode 100644
index 0000000..393dbae
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.TemplateNotFoundException;
+import org.apache.freemarker.core.templateresolver.impl.FileTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+
+public class FileTemplateLoaderTest {
+
+ private File templateRootDir;
+
+ private Configuration cfg;
+
+ @Before
+ public void setup() throws IOException {
+ templateRootDir = Files.createTempDir();
+ File sub1Dir = new File(templateRootDir, "sub1");
+ File sub2Dir = new File(sub1Dir, "sub2");
+ if (!sub2Dir.mkdirs()) {
+ throw new IOException("Failed to invoke subdirectories");
+ }
+ File tFile = new File(sub2Dir, "t.ftl");
+ FileUtils.write(tFile, "foo");
+
+ cfg = new TestConfigurationBuilder().templateLoader(new FileTemplateLoader(templateRootDir)).build();
+ }
+
+ @Test
+ public void testSuccessful() throws Exception {
+ for (int i = 0; i < 2; i++) {
+ assertEquals("foo", cfg.getTemplate("sub1/sub2/t.ftl").toString());
+ }
+ }
+
+ @Test
+ public void testSuccessful2() throws Exception {
+ ((FileTemplateLoader) cfg.getTemplateLoader()).setEmulateCaseSensitiveFileSystem(true);
+ for (int i = 0; i < 2; i++) {
+ cfg.clearTemplateCache();
+ assertEquals("foo", cfg.getTemplate("sub1/sub2/t.ftl").toString());
+ }
+ }
+
+
+ @Test
+ public void testNotFound() throws Exception {
+ for (int i = 0; i < 2; i++) {
+ try {
+ cfg.getTemplate("sub1X/sub2/t.ftl");
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertThat(e.getMessage(), containsString("sub1X"));
+ assertNull(e.getCause());
+ }
+ }
+ }
+
+ @Test
+ public void testCaseSensitivity() throws Exception {
+ for (boolean emuCaseSensFS : new boolean[] { false, true }) {
+ for (String nameWithBadCase : new String[] { "SUB1/sub2/t.ftl", "sub1/SUB2/t.ftl", "sub1/sub2/T.FTL" }) {
+ ((FileTemplateLoader) cfg.getTemplateLoader()).setEmulateCaseSensitiveFileSystem(emuCaseSensFS);
+ cfg.clearTemplateCache();
+
+ if ((SystemUtils.IS_OS_WINDOWS || SystemUtils.IS_OS_MAC_OSX) && !emuCaseSensFS) {
+ assertEquals("foo", cfg.getTemplate(nameWithBadCase).toString());
+ } else {
+ assertEquals("foo", cfg.getTemplate(nameWithBadCase.toLowerCase()).toString());
+ try {
+ cfg.getTemplate(nameWithBadCase);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertThat(e.getMessage(), containsString(nameWithBadCase));
+ assertNull(e.getCause());
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testDefault() throws IOException {
+ assertFalse(new FileTemplateLoader(templateRootDir).getEmulateCaseSensitiveFileSystem());
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ FileUtils.deleteDirectory(templateRootDir);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
new file mode 100644
index 0000000..c8531c5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.junit.Test;
+
+public class MultiTemplateLoaderTest {
+
+ @Test
+ public void testBasics() throws IOException {
+ StringTemplateLoader stl1 = new StringTemplateLoader();
+ stl1.putTemplate("1.ftl", "1");
+ stl1.putTemplate("both.ftl", "both 1");
+
+ StringTemplateLoader stl2 = new StringTemplateLoader();
+ stl2.putTemplate("2.ftl", "2");
+ stl2.putTemplate("both.ftl", "both 2");
+
+ MultiTemplateLoader mtl = new MultiTemplateLoader(stl1, stl2);
+ assertEquals("1", getTemplateContent(mtl, "1.ftl"));
+ assertEquals("2", getTemplateContent(mtl, "2.ftl"));
+ assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
+ assertNull(getTemplateContent(mtl, "neither.ftl"));
+ }
+
+ @Test
+ public void testSticky() throws IOException {
+ testStickiness(true);
+ }
+
+ @Test
+ public void testNonSticky() throws IOException {
+ testStickiness(false);
+ }
+
+ private void testStickiness(boolean sticky) throws IOException {
+ StringTemplateLoader stl1 = new StringTemplateLoader();
+ stl1.putTemplate("both.ftl", "both 1");
+
+ ByteArrayTemplateLoader stl2 = new ByteArrayTemplateLoader();
+ stl2.putTemplate("both.ftl", "both 2".getBytes(StandardCharsets.UTF_8));
+
+ MultiTemplateLoader mtl = new MultiTemplateLoader(stl1, stl2);
+ mtl.setSticky(sticky);
+
+ assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
+ assertTrue(stl1.removeTemplate("both.ftl"));
+ assertEquals("both 2", getTemplateContent(mtl, "both.ftl"));
+ stl1.putTemplate("both.ftl", "both 1");
+ assertEquals(sticky ? "both 2" : "both 1", getTemplateContent(mtl, "both.ftl"));
+ assertTrue(stl2.removeTemplate("both.ftl"));
+ assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
+ }
+
+ private String getTemplateContent(TemplateLoader tl, String name) throws IOException {
+ TemplateLoaderSession ses = tl.createSession();
+ try {
+ TemplateLoadingResult res = tl.load(name, null, null, ses);
+ if (res.getStatus() == TemplateLoadingResultStatus.NOT_FOUND) {
+ return null;
+ }
+ return IOUtils.toString(
+ res.getReader() != null
+ ? res.getReader()
+ : new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8));
+ } finally {
+ if (ses != null) {
+ ses.close();
+ }
+ }
+ }
+
+}
[42/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
new file mode 100644
index 0000000..4b5bf59
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
+import org.apache.freemarker.test.MonitoredTemplateLoader;
+import org.junit.Test;
+
+public class TemplateGetEncodingTest {
+
+ private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
+
+ @Test
+ public void test() throws IOException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ {
+ cfgB.setSourceEncoding(ISO_8859_2);
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putBinaryTemplate("bin", "test");
+ tl.putBinaryTemplate("bin-static", "<#test>");
+ tl.putTextTemplate("text", "test");
+ tl.putTextTemplate("text-static", "<#test>");
+ TemplateConfiguration.Builder staticTextTCB = new TemplateConfiguration.Builder();
+ staticTextTCB.setTemplateLanguage(TemplateLanguage.STATIC_TEXT);
+ cfgB.setTemplateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*-static*"), staticTextTCB.build()));
+ cfgB.setTemplateLoader(tl);
+ cfgB.setCacheStorage(new StrongCacheStorage());
+ }
+
+ Configuration cfg = cfgB.build();
+ assertEquals(ISO_8859_2, cfg.getTemplate("bin").getActualSourceEncoding());
+ assertEquals(ISO_8859_2, cfg.getTemplate("bin-static").getActualSourceEncoding());
+ assertNull(cfg.getTemplate("text").getActualSourceEncoding());
+ assertNull(cfg.getTemplate("text-static").getActualSourceEncoding());
+ assertNull(new Template(null, "test", cfg).getActualSourceEncoding());
+ assertNull(Template.createPlainTextTemplate(null, "<#test>", cfg).getActualSourceEncoding());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
new file mode 100644
index 0000000..f0e63a8
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
@@ -0,0 +1,669 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.core.Configuration.ExtendableBuilder.TEMPLATE_LOOKUP_STRATEGY_KEY;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.Locale;
+
+import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
+import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
+import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
+import org.apache.freemarker.test.MonitoredTemplateLoader;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TemplateLookupStrategyTest {
+
+ @Test
+ public void testSetSetting() throws Exception {
+ assertSame(
+ DefaultTemplateLookupStrategy.INSTANCE,
+ new Configuration.Builder(Configuration.VERSION_3_0_0).build()
+ .getTemplateLookupStrategy());
+
+ assertTrue(
+ new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .setting(TEMPLATE_LOOKUP_STRATEGY_KEY, MyTemplateLookupStrategy.class.getName() + "()")
+ .build()
+ .getTemplateLookupStrategy() instanceof MyTemplateLookupStrategy);
+
+ assertSame(
+ DefaultTemplateLookupStrategy.INSTANCE,
+ new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .setting(TEMPLATE_LOOKUP_STRATEGY_KEY, "dEfault")
+ .build()
+ .getTemplateLookupStrategy());
+ }
+
+ @Test
+ public void testCustomStrategy() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("test.ftl", "");
+ tl.putTextTemplate("aa/test.ftl", "");
+
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(tl)
+ .templateLookupStrategy(MyTemplateLookupStrategy.INSTANCE)
+ .build();
+
+ final Locale locale = new Locale("aa", "BB", "CC_DD");
+
+ try {
+ cfg.getTemplate("missing.ftl", locale);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("missing.ftl", e.getTemplateName());
+ assertEquals(ImmutableList.of("aa/missing.ftl", "missing.ftl"), tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Template t = cfg.getTemplate("test.ftl", locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("aa/test.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(ImmutableList.of("aa/test.ftl"), tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+ }
+
+ @Test
+ public void testDefaultStrategy() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("test.ftl", "");
+ tl.putTextTemplate("test_aa.ftl", "");
+ tl.putTextTemplate("test_aa_BB.ftl", "");
+ tl.putTextTemplate("test_aa_BB_CC.ftl", "");
+ tl.putTextTemplate("test_aa_BB_CC_DD.ftl", "");
+
+ try {
+ new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate("missing.ftl", new Locale("aa", "BB", "CC_DD"));
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("missing.ftl", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of(
+ "missing_aa_BB_CC_DD.ftl",
+ "missing_aa_BB_CC.ftl",
+ "missing_aa_BB.ftl",
+ "missing_aa.ftl",
+ "missing.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ try {
+ new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
+ .locale(new Locale("xx")).build()
+ .getTemplate("missing.ftl");
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("missing.ftl", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of("missing_xx.ftl", "missing.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ try {
+ new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
+ .locale(new Locale("xx"))
+ .localizedLookup(false).build()
+ .getTemplate("missing.ftl");
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("missing.ftl", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of("missing.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ try {
+ new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate("_a_b_.ftl", new Locale("xx", "yy"));
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("_a_b_.ftl", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of("_a_b__xx_YY.ftl", "_a_b__xx.ftl", "_a_b_.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ for (String templateName : new String[] { "test.ftl", "./test.ftl", "/test.ftl", "x/foo/../../test.ftl" }) {
+ {
+ final Locale locale = new Locale("aa", "BB", "CC_DD");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate("test.ftl", locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test_aa_BB_CC_DD.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(ImmutableList.of("test_aa_BB_CC_DD.ftl"), tl.getLoadNames());
+ assertNull(t.getCustomLookupCondition());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("aa", "BB", "CC_XX");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test_aa_BB_CC.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(ImmutableList.of("test_aa_BB_CC_XX.ftl", "test_aa_BB_CC.ftl"), tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("aa", "BB", "XX_XX");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test_aa_BB.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of("test_aa_BB_XX_XX.ftl", "test_aa_BB_XX.ftl", "test_aa_BB.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("aa", "BB", "XX_XX");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
+ .localizedLookup(false).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of("test.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("aa", "XX", "XX_XX");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test_aa.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of("test_aa_XX_XX_XX.ftl", "test_aa_XX_XX.ftl", "test_aa_XX.ftl", "test_aa.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("xx", "XX", "XX_XX");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of(
+ "test_xx_XX_XX_XX.ftl", "test_xx_XX_XX.ftl", "test_xx_XX.ftl", "test_xx.ftl", "test.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ {
+ final Locale locale = new Locale("xx", "BB", "CC_DD");
+ final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
+ .getTemplate(templateName, locale);
+ assertEquals("test.ftl", t.getLookupName());
+ assertEquals("test.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of(
+ "test_xx_BB_CC_DD.ftl", "test_xx_BB_CC.ftl", "test_xx_BB.ftl", "test_xx.ftl", "test.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+ }
+ }
+
+ @Test
+ public void testAcquisition() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("t.ftl", "");
+ tl.putTextTemplate("sub/i.ftl", "");
+ tl.putTextTemplate("x/sub/i.ftl", "");
+
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
+
+ final Locale locale = new Locale("xx");
+
+ {
+ final Template t = cfg.getTemplate("/./moo/../x/y/*/sub/i.ftl", locale);
+ assertEquals("x/y/*/sub/i.ftl", t.getLookupName());
+ assertEquals("x/sub/i.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of(
+ "x/y/sub/i_xx.ftl", "x/sub/i_xx.ftl", "sub/i_xx.ftl",
+ "x/y/sub/i.ftl", "x/sub/i.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Template t = cfg.getTemplate("a/b/*/./sub/i.ftl", locale);
+ assertEquals("a/b/*/sub/i.ftl", t.getLookupName());
+ assertEquals("sub/i.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(
+ ImmutableList.of(
+ "a/b/sub/i_xx.ftl", "a/sub/i_xx.ftl", "sub/i_xx.ftl",
+ "a/b/sub/i.ftl", "a/sub/i.ftl", "sub/i.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+ }
+
+ @Test
+ public void testCustomLookupCondition() throws IOException, TemplateException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+
+ final Configuration cfg;
+ final Configuration cfgNoLocLU;
+ {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(tl)
+ .templateLookupStrategy(new DomainTemplateLookupStrategy());
+ cfg = cfgB.build();
+ cfgNoLocLU = cfgB.localizedLookup(false).build();
+ }
+
+ final String iAtDefaultContent = "i at default";
+ final String iXxAtDefaultContent = "i_xx at default";
+ final String iAtBaazComContent = "i at baaz.com";
+ final String iAtFooComContent = "i at foo.com";
+ final String tAtDefaultWithoutIncludeContent = "t at default ";
+ final String tAtDefaultContent = toCanonicalFTL(tAtDefaultWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
+ final String tAtBarComWithoutIncludeContent = "t at bar.com ";
+ final String tAtBarComContent = toCanonicalFTL(tAtBarComWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
+ final String tAtFooComWithoutIncludeContent = "t at foo.com ";
+ final String tAtFooComContent = toCanonicalFTL(tAtFooComWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
+ final String t2XxLocaleExpectedOutput = "i3_xx at foo.com";
+ final String t2OtherLocaleExpectedOutput = "i3 at foo.com";
+
+ tl.putTextTemplate("@foo.com/t.ftl", tAtFooComContent);
+ tl.putTextTemplate("@bar.com/t.ftl", tAtBarComContent);
+ tl.putTextTemplate("@default/t.ftl", tAtDefaultContent);
+ tl.putTextTemplate("@foo.com/i.ftl", iAtFooComContent);
+ tl.putTextTemplate("@baaz.com/i.ftl", iAtBaazComContent);
+ tl.putTextTemplate("@default/i_xx.ftl", iXxAtDefaultContent);
+ tl.putTextTemplate("@default/i.ftl", iAtDefaultContent);
+ tl.putTextTemplate("@foo.com/t2.ftl", "<#import 'i2.ftl' as i2 />${proof}");
+ tl.putTextTemplate("@default/i2.ftl", "<#import 'i3.ftl' as i3 />");
+ tl.putTextTemplate("@foo.com/i3.ftl", "<#global proof = '" + t2OtherLocaleExpectedOutput + "'>");
+ tl.putTextTemplate("@foo.com/i3_xx.ftl", "<#global proof = '" + t2XxLocaleExpectedOutput + "'>");
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("foo.com");
+ final Template t = cfg.getTemplate("t.ftl", locale, domain);
+ assertEquals("t.ftl", t.getLookupName());
+ assertEquals("@foo.com/t.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertEquals(domain, t.getCustomLookupCondition());
+ assertEquals(tAtFooComContent, t.toString());
+ assertEquals(
+ ImmutableList.of("@foo.com/t_xx.ftl", "@foo.com/t.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ assertOutputEquals(tAtFooComWithoutIncludeContent + iAtFooComContent, t);
+ assertEquals(
+ ImmutableList.of("@foo.com/i_xx.ftl", "@foo.com/i.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("bar.com");
+ final Template t = cfg.getTemplate("t.ftl", locale, domain);
+ assertEquals("t.ftl", t.getLookupName());
+ assertEquals("@bar.com/t.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertEquals(domain, t.getCustomLookupCondition());
+ assertEquals(tAtBarComContent, t.toString());
+ assertEquals(
+ ImmutableList.of("@bar.com/t_xx.ftl", "@bar.com/t.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ assertOutputEquals(tAtBarComWithoutIncludeContent + iXxAtDefaultContent, t);
+ assertEquals(
+ ImmutableList.of(
+ "@bar.com/i_xx.ftl", "@bar.com/i.ftl",
+ "@default/i_xx.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx", "YY");
+ final Domain domain = new Domain("baaz.com");
+ final Template t = cfg.getTemplate("t.ftl", locale, domain);
+ assertEquals("t.ftl", t.getLookupName());
+ assertEquals("@default/t.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertEquals(domain, t.getCustomLookupCondition());
+ assertEquals(tAtDefaultContent, t.toString());
+ assertEquals(
+ ImmutableList.of(
+ "@baaz.com/t_xx_YY.ftl", "@baaz.com/t_xx.ftl", "@baaz.com/t.ftl",
+ "@default/t_xx_YY.ftl", "@default/t_xx.ftl", "@default/t.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ assertOutputEquals(tAtDefaultWithoutIncludeContent + iAtBaazComContent, t);
+ assertEquals(
+ ImmutableList.of("@baaz.com/i_xx_YY.ftl", "@baaz.com/i_xx.ftl", "@baaz.com/i.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx", "YY");
+ final Domain domain = new Domain("nosuch.com");
+ final Template t = cfg.getTemplate("i.ftl", locale, domain);
+ assertEquals("i.ftl", t.getLookupName());
+ assertEquals("@default/i_xx.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertEquals(domain, t.getCustomLookupCondition());
+ assertEquals(iXxAtDefaultContent, t.toString());
+ assertEquals(
+ ImmutableList.of(
+ "@nosuch.com/i_xx_YY.ftl", "@nosuch.com/i_xx.ftl", "@nosuch.com/i.ftl",
+ "@default/i_xx_YY.ftl", "@default/i_xx.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx", "YY");
+ final Domain domain = new Domain("nosuch.com");
+ final Template t = cfgNoLocLU.getTemplate("i.ftl", locale, domain);
+ assertEquals("i.ftl", t.getLookupName());
+ assertEquals("@default/i.ftl", t.getSourceName());
+ assertEquals(locale, t.getLocale());
+ assertEquals(domain, t.getCustomLookupCondition());
+ assertEquals(iAtDefaultContent, t.toString());
+ assertEquals(
+ ImmutableList.of("@nosuch.com/i.ftl", "@default/i.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfgNoLocLU.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("foo.com");
+ final Template t = cfg.getTemplate("t2.ftl", locale, domain);
+ assertOutputEquals(t2XxLocaleExpectedOutput, t);
+ assertEquals(
+ ImmutableList.of(
+ "@foo.com/t2_xx.ftl", "@foo.com/t2.ftl",
+ "@foo.com/i2_xx.ftl", "@foo.com/i2.ftl", "@default/i2_xx.ftl", "@default/i2.ftl",
+ "@foo.com/i3_xx.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("yy");
+ final Domain domain = new Domain("foo.com");
+ final Template t = cfg.getTemplate("t2.ftl", locale, domain);
+ assertOutputEquals(t2OtherLocaleExpectedOutput, t);
+ assertEquals(
+ ImmutableList.of(
+ "@foo.com/t2_yy.ftl", "@foo.com/t2.ftl",
+ "@foo.com/i2_yy.ftl", "@foo.com/i2.ftl", "@default/i2_yy.ftl", "@default/i2.ftl",
+ "@foo.com/i3_yy.ftl", "@foo.com/i3.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("foo.com");
+ final Template t = cfgNoLocLU.getTemplate("t2.ftl", locale, domain);
+ assertOutputEquals(t2OtherLocaleExpectedOutput, t);
+ assertEquals(
+ ImmutableList.of(
+ "@foo.com/t2.ftl",
+ "@foo.com/i2.ftl", "@default/i2.ftl",
+ "@foo.com/i3.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfgNoLocLU.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("foo.com");
+ cfg.getTemplate("i3.ftl", locale, domain);
+ assertEquals(
+ ImmutableList.of("@foo.com/i3_xx.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final Locale locale = new Locale("xx");
+ final Domain domain = new Domain("bar.com");
+ try {
+ cfg.getTemplate("i3.ftl", locale, domain);
+ } catch (TemplateNotFoundException e) {
+ assertEquals("i3.ftl", e.getTemplateName());
+ assertEquals(domain, e.getCustomLookupCondition());
+ }
+ assertEquals(
+ ImmutableList.of(
+ "@bar.com/i3_xx.ftl", "@bar.com/i3.ftl",
+ "@default/i3_xx.ftl", "@default/i3.ftl"),
+ tl.getLoadNames());
+
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ }
+
+ public static class Domain implements Serializable {
+ private final String name;
+
+ public Domain(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Domain domain = (Domain) o;
+
+ return name != null ? name.equals(domain.name) : domain.name == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return name != null ? name.hashCode() : 0;
+ }
+ }
+
+ @Test
+ public void testNonparsed() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("test.txt", "");
+ tl.putTextTemplate("test_aa.txt", "");
+
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
+
+ try {
+ cfg.getTemplate("missing.txt", new Locale("aa", "BB"), null, false);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("missing.txt", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of(
+ "missing_aa_BB.txt",
+ "missing_aa.txt",
+ "missing.txt"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ Template t = cfg.getTemplate("test.txt", new Locale("aa", "BB"), null, false);
+ assertEquals("test.txt", t.getLookupName());
+ assertEquals("test_aa.txt", t.getSourceName());
+ assertEquals(
+ ImmutableList.of(
+ "test_aa_BB.txt",
+ "test_aa.txt"),
+ tl.getLoadNames());
+ }
+ }
+
+ @Test
+ public void testParseError() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("test.ftl", "");
+ tl.putTextTemplate("test_aa.ftl", "<#wrong>");
+
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
+
+ try {
+ cfg.getTemplate("test.ftl", new Locale("aa", "BB"));
+ fail();
+ } catch (ParseException e) {
+ assertEquals("test_aa.ftl", e.getTemplateSourceName());
+ assertEquals("test.ftl", e.getTemplateLookupName());
+ }
+ }
+
+ private String toCanonicalFTL(String ftl, Configuration cfg) throws IOException {
+ return new Template(null, ftl, cfg).toString();
+ }
+
+ private void assertOutputEquals(final String expectedContent, final Template t) throws TemplateException,
+ IOException {
+ StringWriter sw = new StringWriter();
+ t.process(null, sw);
+ assertEquals(expectedContent, sw.toString());
+ }
+
+ public static class MyTemplateLookupStrategy extends TemplateLookupStrategy {
+
+ public static final MyTemplateLookupStrategy INSTANCE = new MyTemplateLookupStrategy();
+
+ private MyTemplateLookupStrategy() { }
+
+ @Override
+ public <R extends TemplateLookupResult> R lookup(TemplateLookupContext<R> ctx) throws IOException {
+ String lang = ctx.getTemplateLocale().getLanguage().toLowerCase();
+ R lookupResult = ctx.lookupWithAcquisitionStrategy(lang + "/" + ctx.getTemplateName());
+ if (lookupResult.isPositive()) {
+ return lookupResult;
+ }
+
+ return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
+ }
+
+ }
+
+ public static class DomainTemplateLookupStrategy extends TemplateLookupStrategy {
+
+ public static final DomainTemplateLookupStrategy INSTANCE = new DomainTemplateLookupStrategy();
+
+ @Override
+ public <R extends TemplateLookupResult> R lookup(TemplateLookupContext<R> ctx) throws IOException {
+ Domain domain = (Domain) ctx.getCustomLookupCondition();
+ if (domain == null) {
+ throw new NullPointerException("The domain wasn't specified");
+ }
+
+ final String templateName = ctx.getTemplateName();
+
+ // Disallow addressing the domain roots directly:
+ if (templateName.startsWith("@")) {
+ return ctx.createNegativeLookupResult();
+ }
+
+ R lookupResult = ctx.lookupWithLocalizedThenAcquisitionStrategy(
+ "@" + domain.name + "/" + templateName,
+ ctx.getTemplateLocale());
+ if (lookupResult.isPositive()) {
+ return lookupResult;
+ }
+
+ return ctx.lookupWithLocalizedThenAcquisitionStrategy("@default/" + templateName, ctx.getTemplateLocale());
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
new file mode 100644
index 0000000..7c9a98f
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class TemplateNameSpecialVariablesTest extends TemplateTest {
+
+ private static final String PRINT_ALL_FTL
+ = "ct=${.currentTemplateName!'-'}, mt=${.mainTemplateName!'-'}";
+
+ @Test
+ public void testMainTemplateName() throws IOException, TemplateException {
+ addTemplateNameTestTemplates(".mainTemplateName");
+ assertOutputForNamed("main.ftl",
+ "In main: main.ftl\n"
+ + "In imp: main.ftl\n"
+ + "In main: main.ftl\n"
+ + "main.ftl\n"
+ + "{main.ftl}\n"
+ + "In imp call imp:\n"
+ + "main.ftl\n"
+ + "{main.ftl}\n"
+ + "After: main.ftl\n"
+ + "In main: main.ftl\n"
+ + "In inc: main.ftl\n"
+ + "In inc call imp:\n"
+ + "main.ftl\n"
+ + "{main.ftl}\n"
+ + "In main: main.ftl\n"
+ + "main.ftl\n"
+ + "{main.ftl}\n"
+ + "In inc call imp:\n"
+ + "main.ftl\n"
+ + "{main.ftl}\n"
+ + "In main: main.ftl\n");
+ }
+
+ @Test
+ public void testCurrentTemplateName() throws IOException, TemplateException {
+ addTemplateNameTestTemplates(".currentTemplateName");
+ assertOutputForNamed("main.ftl",
+ "In main: main.ftl\n"
+ + "In imp: imp.ftl\n"
+ + "In main: main.ftl\n"
+ + "imp.ftl\n"
+ + "{main.ftl}\n"
+ + "In imp call imp:\n"
+ + "imp.ftl\n"
+ + "{imp.ftl}\n"
+ + "After: imp.ftl\n"
+ + "In main: main.ftl\n"
+ + "In inc: inc.ftl\n"
+ + "In inc call imp:\n"
+ + "imp.ftl\n"
+ + "{inc.ftl}\n"
+ + "In main: main.ftl\n"
+ + "inc.ftl\n"
+ + "{main.ftl}\n"
+ + "In inc call imp:\n"
+ + "imp.ftl\n"
+ + "{inc.ftl}\n"
+ + "In main: main.ftl\n");
+ }
+
+ private void addTemplateNameTestTemplates(String specVar) {
+ addTemplate("main.ftl",
+ "In main: ${" + specVar + "}\n"
+ + "<#import 'imp.ftl' as i>"
+ + "In imp: ${inImp}\n"
+ + "In main: ${" + specVar + "}\n"
+ + "<@i.impM>${" + specVar + "}</@>\n"
+ + "<@i.impM2 />\n"
+ + "In main: ${" + specVar + "}\n"
+ + "<#include 'inc.ftl'>"
+ + "In main: ${" + specVar + "}\n"
+ + "<@incM>${" + specVar + "}</@>\n"
+ + "<@incM2 />\n"
+ + "In main: ${" + specVar + "}\n"
+ );
+ addTemplate("imp.ftl",
+ "<#global inImp = " + specVar + ">"
+ + "<#macro impM>"
+ + "${" + specVar + "}\n"
+ + "{<#nested>}"
+ + "</#macro>"
+ + "<#macro impM2>"
+ + "In imp call imp:\n"
+ + "<@impM>${" + specVar + "}</@>\n"
+ + "After: ${" + specVar + "}"
+ + "</#macro>"
+ );
+ addTemplate("inc.ftl",
+ "In inc: ${" + specVar + "}\n"
+ + "In inc call imp:\n"
+ + "<@i.impM>${" + specVar + "}</@>\n"
+ + "<#macro incM>"
+ + "${" + specVar + "}\n"
+ + "{<#nested>}"
+ + "</#macro>"
+ + "<#macro incM2>"
+ + "In inc call imp:\n"
+ + "<@i.impM>${" + specVar + "}</@>"
+ + "</#macro>"
+ );
+ }
+
+ @Test
+ public void testInAdhocTemplate() throws TemplateException, IOException {
+ addTemplate("inc.ftl", "Inc: " + PRINT_ALL_FTL);
+
+ // In nameless templates, the deprecated .templateName is "", but the new variables are missing values.
+ assertOutput(new Template(null, PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
+ "ct=-, mt=-; Inc: ct=inc.ftl, mt=-");
+
+ assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
+ "ct=foo.ftl, mt=foo.ftl; Inc: ct=inc.ftl, mt=foo.ftl");
+ }
+
+ @Test
+ public void testInInterpretTemplate() throws TemplateException, IOException {
+ addToDataModel("t", PRINT_ALL_FTL);
+ assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
+ "ct=foo.ftl, mt=foo.ftl; "
+ + "ct=foo.ftl->anonymous_interpreted, mt=foo.ftl");
+ assertOutput(new Template(null, PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
+ "ct=-, mt=-; "
+ + "ct=nameless_template->anonymous_interpreted, mt=-");
+ assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@[t,'bar']?interpret />", getConfiguration()),
+ "ct=foo.ftl, mt=foo.ftl; "
+ + "ct=foo.ftl->bar, mt=foo.ftl");
+ }
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return new TestConfigurationBuilder().whitespaceStripping(false).build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
new file mode 100644
index 0000000..66331ad
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
+import org.apache.freemarker.core.templateresolver.TemplateLoader;
+import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
+import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
+import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.FileTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.junit.Test;
+
+public class TemplateNotFoundMessageTest {
+
+ @Test
+ public void testFileTemplateLoader() throws IOException {
+ final File baseDir = new File(System.getProperty("user.home"));
+ final String errMsg = failWith(new FileTemplateLoader(baseDir));
+ showErrorMessage(errMsg);
+ assertThat(errMsg, containsString(baseDir.toString()));
+ assertThat(errMsg, containsString("FileTemplateLoader"));
+ }
+
+ @Test
+ public void testClassTemplateLoader() throws IOException {
+ final String errMsg = failWith(new ClassTemplateLoader(getClass(), "foo/bar"));
+ showErrorMessage(errMsg);
+ assertThat(errMsg, containsString("ClassTemplateLoader"));
+ assertThat(errMsg, containsString("foo/bar"));
+ }
+
+ @Test
+ public void testStringTemplateLoader() throws IOException {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("aaa", "A");
+ tl.putTemplate("bbb", "B");
+ tl.putTemplate("ccc", "C");
+ final String errMsg = failWith(tl);
+ showErrorMessage(errMsg);
+ assertThat(errMsg, containsString("StringTemplateLoader"));
+ assertThat(errMsg, containsString("aaa"));
+ assertThat(errMsg, containsString("bbb"));
+ assertThat(errMsg, containsString("ccc"));
+ }
+
+ @Test
+ public void testMultiTemplateLoader() throws IOException {
+ final String errMsg = failWith(new MultiTemplateLoader(new TemplateLoader[] {
+ new StringTemplateLoader(),
+ new ClassTemplateLoader(getClass(), "foo/bar")
+ }));
+ showErrorMessage(errMsg);
+ assertThat(errMsg, containsString("MultiTemplateLoader"));
+ assertThat(errMsg, containsString("StringTemplateLoader"));
+ assertThat(errMsg, containsString("ClassTemplateLoader"));
+ assertThat(errMsg, containsString("foo/bar"));
+ }
+
+ @Test
+ public void testDefaultTemplateLoader() throws IOException {
+ String errMsg = failWith(null);
+ showErrorMessage(errMsg);
+ assertThat(errMsg, allOf(containsString("setTemplateLoader"), containsString("null")));
+ }
+
+ @Test
+ public void testOtherMessageDetails() throws IOException {
+ // Non-null TemplateLoader:
+ StringTemplateLoader emptyLoader = new StringTemplateLoader();
+ {
+ String errMsg = failWith(emptyLoader, "../x");
+ showErrorMessage(errMsg);
+ assertThat(errMsg,
+ allOf(
+ containsStringIgnoringCase("Malformed template name"),
+ containsStringIgnoringCase("root directory")));
+ }
+ {
+ String errMsg = failWith(emptyLoader, "x\u0000y");
+ showErrorMessage(errMsg);
+ assertThat(errMsg,
+ allOf(
+ containsStringIgnoringCase("Malformed template name"),
+ containsStringIgnoringCase("null character")));
+ }
+ {
+ String errMsg = failWith(emptyLoader, "x\\y");
+ showErrorMessage(errMsg);
+ assertThat(errMsg,
+ allOf(containsStringIgnoringCase("warning"), containsStringIgnoringCase("backslash")));
+ }
+ {
+ String errMsg = failWith(emptyLoader, "x/./y");
+ showErrorMessage(errMsg);
+ assertThat(errMsg,
+ allOf(containsStringIgnoringCase("normalized"), containsStringIgnoringCase("x/y")));
+ }
+ {
+ String errMsg = failWith(emptyLoader, "/x/y");
+ showErrorMessage(errMsg);
+ assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
+ }
+ {
+ String errMsg = failWith(emptyLoader, "x/y");
+ showErrorMessage(errMsg);
+ assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
+ assertThat(errMsg, not(containsStringIgnoringCase("lookup strategy")));
+ }
+
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(new StringTemplateLoader())
+ .templateLookupStrategy(
+ new TemplateLookupStrategy() {
+ @Override
+ public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
+ return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
+ }
+ }
+ );
+ {
+ String errMsg = failWith(emptyLoader, "x/y",
+ new TemplateLookupStrategy() {
+ @Override
+ public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
+ return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
+ }
+ }
+ );
+ showErrorMessage(errMsg);
+ assertThat(errMsg, containsStringIgnoringCase("lookup strategy"));
+ }
+
+ try {
+ cfgB.build().getTemplate("./missing", null, new DomainLookupCondition());
+ fail();
+ } catch (TemplateNotFoundException e) {
+ showErrorMessage(e.getMessage());
+ assertThat(e.getMessage(), containsStringIgnoringCase("example.com"));
+ }
+ }
+
+ private void showErrorMessage(String errMsg) {
+ // System.out.println(errMsg);
+ }
+
+ private String failWith(TemplateLoader tl, String name, TemplateLookupStrategy templateLookupStrategy) {
+ try {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ cfgB.setTemplateLoader(tl);
+ if (templateLookupStrategy != null) {
+ cfgB.setTemplateLookupStrategy(templateLookupStrategy);
+ }
+ cfgB.build().getTemplate(name);
+ fail();
+ } catch (TemplateNotFoundException | MalformedTemplateNameException e) {
+ return e.getMessage();
+ } catch (IOException e) {
+ fail("Unexpected exception: " + e);
+ }
+ return null;
+ }
+
+ private String failWith(TemplateLoader tl, String name) {
+ return failWith(tl, name, null);
+ }
+
+ private String failWith(TemplateLoader tl) {
+ return failWith(tl, "missing.ftl", null);
+ }
+
+ @SuppressWarnings("serial")
+ private static final class DomainLookupCondition implements Serializable {
+ @Override
+ public String toString() {
+ return "example.com";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
new file mode 100644
index 0000000..a0174b3
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.freemarker.core.ThreadInterruptionSupportTemplatePostProcessor.TemplateProcessingThreadInterruptedException;
+import org.apache.freemarker.core.model.TemplateDirectiveBody;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util._NullWriter;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TheadInterruptingSupportTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TheadInterruptingSupportTest.class);
+
+ private static final int TEMPLATE_INTERRUPTION_TIMEOUT = 5000;
+ private final Configuration cfg = new TestConfigurationBuilder().build();
+
+ @Test
+ public void test() throws IOException, InterruptedException {
+ assertCanBeInterrupted("<#list 1.. as x></#list>");
+ assertCanBeInterrupted("<#list 1.. as x>${x}</#list>");
+ assertCanBeInterrupted("<#list 1.. as x>t${x}</#list>");
+ assertCanBeInterrupted("<#list 1.. as x><#list 1.. as y>${y}</#list></#list>");
+ assertCanBeInterrupted("<#list 1.. as x>${x}<#else>nope</#list>");
+ assertCanBeInterrupted("<#list 1..>[<#items as x>${x}</#items>]<#else>nope</#list>");
+ assertCanBeInterrupted("<@customLoopDirective />");
+ assertCanBeInterrupted("<@customLoopDirective>x</@>");
+ assertCanBeInterrupted("<@customLoopDirective><#if true>x</#if></@>");
+ assertCanBeInterrupted("<#macro selfCalling><@sleepDirective/><@selfCalling /></#macro><@selfCalling />");
+ assertCanBeInterrupted("<#function selfCalling><@sleepDirective/>${selfCalling()}</#function>${selfCalling()}");
+ assertCanBeInterrupted("<#list 1.. as _><#attempt><@sleepDirective/><#recover>suppress</#attempt></#list>");
+ assertCanBeInterrupted("<#attempt><#list 1.. as _></#list><#recover>suppress</#attempt>");
+ }
+
+ private void assertCanBeInterrupted(final String templateSourceCode) throws IOException, InterruptedException {
+ TemplateRunnerThread trt = new TemplateRunnerThread(templateSourceCode);
+ trt.start();
+ synchronized (trt) {
+ while (!trt.isStarted()) {
+ trt.wait();
+ }
+ }
+ Thread.sleep(50); // Just to ensure (hope...) that the template execution reaches "deep" enough
+ trt.interrupt();
+ trt.join(TEMPLATE_INTERRUPTION_TIMEOUT);
+ assertTrue(trt.isTemplateProcessingInterrupted());
+ }
+
+ public class TemplateRunnerThread extends Thread {
+
+ private final Template template;
+ private boolean started;
+ private boolean templateProcessingInterrupted;
+
+ public TemplateRunnerThread(String templateSourceCode) throws IOException {
+ template = new Template(null, "<@startedDirective/>" + templateSourceCode, cfg);
+ _CoreAPI.addThreadInterruptedChecks(template);
+ }
+
+ @Override
+ public void run() {
+ try {
+ template.process(this, _NullWriter.INSTANCE);
+ } catch (TemplateProcessingThreadInterruptedException e) {
+ //LOG.debug("Template processing interrupted", e);
+ synchronized (this) {
+ templateProcessingInterrupted = true;
+ }
+ } catch (Throwable e) {
+ LOG.error("Template processing failed", e);
+ }
+ }
+
+ public synchronized boolean isTemplateProcessingInterrupted() {
+ return templateProcessingInterrupted;
+ }
+
+ public synchronized boolean isStarted() {
+ return started;
+ }
+
+ public TemplateDirectiveModel getStartedDirective() {
+ return new StartedDirective();
+ }
+
+ public TemplateDirectiveModel getCustomLoopDirective() {
+ return new CustomLoopDirective();
+ }
+
+ public TemplateDirectiveModel getSleepDirective() {
+ return new SleepDirective();
+ }
+
+ public class StartedDirective implements TemplateDirectiveModel {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ synchronized (TemplateRunnerThread.this) {
+ started = true;
+ TemplateRunnerThread.this.notifyAll();
+ }
+ }
+
+ }
+
+ public class CustomLoopDirective implements TemplateDirectiveModel {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ // Deliberate infinite loop
+ while (true) {
+ body.render(_NullWriter.INSTANCE);
+ }
+ }
+
+ }
+
+ public class SleepDirective implements TemplateDirectiveModel {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Thread.sleep has reset the interrupted flag (because it has thrown InterruptedException).
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
new file mode 100644
index 0000000..749d057
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.core;
+
+import java.io.StringReader;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+public class TypeErrorMessagesTest extends TemplateTest {
+
+ static final Document doc;
+ static {
+ try {
+ DocumentBuilder docBuilder;
+ docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ doc = docBuilder.parse(new InputSource(new StringReader(
+ "<a><b>123</b><c a='true'>1</c><c a='false'>2</c></a>")));
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to build data-model", e);
+ }
+ }
+
+ @Test
+ public void testNumericalBinaryOperator() {
+ assertErrorContains("${n - s}", "\"-\"", "right-hand", "number", "string");
+ assertErrorContains("${s - n}", "\"-\"", "left-hand", "number", "string");
+ }
+
+ @Test
+ public void testGetterMistake() {
+ assertErrorContains("${bean.getX}", "${...}",
+ "number", "string", "method", "obj.getSomething", "obj.something");
+ assertErrorContains("${1 * bean.getX}", "right-hand",
+ "number", "\\!string", "method", "obj.getSomething", "obj.something");
+ assertErrorContains("<#if bean.isB></#if>", "condition",
+ "boolean", "method", "obj.isSomething", "obj.something");
+ assertErrorContains("<#if bean.isB></#if>", "condition",
+ "boolean", "method", "obj.isSomething", "obj.something");
+ assertErrorContains("${bean.voidM}",
+ "string", "method", "\\!()");
+ assertErrorContains("${bean.intM}",
+ "string", "method", "obj.something()");
+ assertErrorContains("${bean.intMP}",
+ "string", "method", "obj.something(params)");
+ }
+
+ @Test
+ public void testXMLTypeMismarches() throws Exception {
+ assertErrorContains("${doc.a.c}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.c?boolean}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.d}",
+ "used as string", "query result", "0", "no matches");
+ assertErrorContains("${doc.a.d?boolean}",
+ "used as string", "query result", "0", "no matches");
+
+ assertErrorContains("${doc.a.c.@a}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.d.@b}",
+ "used as string", "query result", "x", "no matches");
+
+ assertErrorContains("${doc.a.b * 2}",
+ "used as number", "text", "explicit conversion");
+ assertErrorContains("<#if doc.a.b></#if>",
+ "used as number", "text", "explicit conversion");
+
+ assertErrorContains("${doc.a.d?nodeName}",
+ "used as node", "query result", "0", "no matches");
+ assertErrorContains("${doc.a.c?nodeName}",
+ "used as node", "query result", "2", "multiple matches");
+ }
+
+ @Override
+ protected Object createDataModel() {
+ Map<String, Object> dataModel = createCommonTestValuesDataModel();
+ dataModel.put("doc", doc);
+ return dataModel;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
new file mode 100644
index 0000000..99bf5d3
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class UnclosedCommentTest extends TemplateTest {
+
+ @Test
+ public void test() throws IOException, TemplateException {
+ assertErrorContains("foo<#--", "end of file"); // Not too good...
+ assertErrorContains("foo<#-- ", "Unclosed", "<#--");
+ assertErrorContains("foo<#--bar", "Unclosed", "<#--");
+ assertErrorContains("foo\n<#--\n", "Unclosed", "<#--");
+ assertErrorContains("foo<#noparse>", "end of file"); // Not too good...
+ assertErrorContains("foo<#noparse> ", "Unclosed", "#noparse");
+ assertErrorContains("foo<#noparse>bar", "Unclosed", "#noparse");
+ assertErrorContains("foo\n<#noparse>\n", "Unclosed", "#noparse");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/VersionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/VersionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/VersionTest.java
new file mode 100644
index 0000000..8c54df5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/VersionTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.sql.Date;
+
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class VersionTest {
+
+ @Test
+ public void testFromNumber() {
+ Version v = new Version(1, 2, 3);
+ assertEquals("1.2.3", v.toString());
+ assertEquals(1002003, v.intValue());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ assertNull(v.getExtraInfo());
+ assertNull(v.isGAECompliant());
+ assertNull(v.getBuildDate());
+ }
+
+ @Test
+ public void testFromNumber2() {
+ Version v = new Version(1, 2, 3, "beta8", Boolean.TRUE, new Date(5000));
+ assertEquals("1.2.3-beta8", v.toString());
+ assertEquals("beta8", v.getExtraInfo());
+ assertTrue(v.isGAECompliant().booleanValue());
+ assertEquals(new Date(5000), v.getBuildDate());
+ }
+
+ @Test
+ public void testFromNumber3() {
+ Version v = new Version(new Version(1, 2, 3).intValue());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ }
+
+ public void testFromNumberIncubating() {
+ Version v = new Version(2, 3, 24, "rc01-incubating", Boolean.FALSE, new Date(5000));
+ assertEquals("2.3.24-rc01-incubating", v.toString());
+ assertEquals("rc01-incubating", v.getExtraInfo());
+ assertFalse(v.isGAECompliant().booleanValue());
+ assertEquals(new Date(5000), v.getBuildDate());
+ }
+
+ @Test
+ public void testFromString() {
+ Version v = new Version("1.2.3-beta2");
+ assertEquals("1.2.3-beta2", v.toString());
+ assertEquals(1002003, v.intValue());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ assertEquals("beta2", v.getExtraInfo());
+ assertNull(v.isGAECompliant());
+ assertNull(v.getBuildDate());
+ }
+
+ @Test
+ public void testFromString2() {
+ Version v = new Version("10.20.30", Boolean.TRUE, new Date(5000));
+ assertEquals("10.20.30", v.toString());
+ assertEquals(10020030, v.intValue());
+ assertEquals(10, v.getMajor());
+ assertEquals(20, v.getMinor());
+ assertEquals(30, v.getMicro());
+ assertNull(v.getExtraInfo());
+ assertTrue(v.isGAECompliant().booleanValue());
+ assertEquals(new Date(5000), v.getBuildDate());
+ }
+
+ @Test
+ public void testFromString3() {
+ Version v = new Version("01.002.0003-20130524");
+ assertEquals("01.002.0003-20130524", v.toString());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ assertEquals("20130524", v.getExtraInfo());
+
+ v = new Version("01.002.0003.4");
+ assertEquals("01.002.0003.4", v.toString());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ assertEquals("4", v.getExtraInfo());
+
+ v = new Version("1.2.3.FC");
+ assertEquals("1.2.3.FC", v.toString());
+ assertEquals("FC", v.getExtraInfo());
+
+ v = new Version("1.2.3mod");
+ assertEquals("1.2.3mod", v.toString());
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getMicro());
+ assertEquals("mod", v.getExtraInfo());
+
+ }
+
+ @Test
+ public void testFromStringIncubating() {
+ Version v = new Version("2.3.24-rc01-incubating");
+ assertEquals("2.3.24-rc01-incubating", v.toString());
+ assertEquals(2, v.getMajor());
+ assertEquals(3, v.getMinor());
+ assertEquals(24, v.getMicro());
+ assertEquals("rc01-incubating", v.getExtraInfo());
+ }
+
+ @Test
+ public void testHashAndEquals() {
+ Version v1 = new Version("1.2.3-beta2");
+ Version v2 = new Version(1, 2, 3, "beta2", null, null);
+ assertEquals(v1, v2);
+ assertEquals(v1.hashCode(), v2.hashCode());
+
+ v2 = new Version("1.2.3-beta3");
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version(1, 2, 3, "beta2", true, null);
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version(1, 2, 3, "beta2", null, new Date(5000));
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version("1.2.9-beta2");
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version("1.9.3-beta2");
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version("9.2.3-beta2");
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+
+ v2 = new Version("1.2.3");
+ assertTrue(!v1.equals(v2));
+ assertTrue(v1.hashCode() != v2.hashCode());
+ }
+
+ @Test
+ public void testShortForms() {
+ Version v = new Version("1.0.0-beta2");
+ assertEquals(v, new Version("1.0-beta2"));
+ assertEquals(v, new Version("1-beta2"));
+
+ v = new Version("1.0.0");
+ assertEquals(v, new Version("1.0"));
+ assertEquals(v, new Version("1"));
+ }
+
+ @Test
+ public void testMalformed() {
+ try {
+ new Version("1.2.");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new Version("1.2.3.");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new Version("1..3");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new Version(".2");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new Version("a");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new Version("-a");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
new file mode 100644
index 0000000..8e5b52e
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class WhitespaceStrippingTest extends TemplateTest {
+
+ @Test
+ public void testBasics() throws Exception {
+ assertOutput("<#assign x = 1>\n<#assign y = 2>\n${x}\n${y}", "1\n2", "\n\n1\n2");
+ assertOutput(" <#assign x = 1> \n <#assign y = 2> \n${x}\n${y}", "1\n2", " \n \n1\n2");
+ }
+
+ @Test
+ public void testFTLHeader() throws Exception {
+ assertOutput("<#ftl>x", "x", "x");
+ assertOutput(" <#ftl> x", " x", " x");
+ assertOutput("\n<#ftl>\nx", "x", "x");
+ assertOutput("\n<#ftl>\t \nx", "x", "x");
+ assertOutput(" \n \n <#ftl> \n \n x", " \n x", " \n x");
+ }
+
+ @Test
+ public void testComment() throws Exception {
+ assertOutput(" a <#-- --> b ", " a b ", " a b ");
+ assertOutput(" a \n<#-- -->\n b ", " a \n b ", " a \n\n b ");
+ // These are wrong, but needed for 2.3.0 compatibility:
+ assertOutput(" a \n <#-- --> \n b ", " a \n b ", " a \n \n b ");
+ assertOutput(" a \n\t<#-- --> \n b ", " a \n\t b ", " a \n\t \n b ");
+ }
+
+ private void assertOutput(String ftl, String expectedOutStripped, String expectedOutNonStripped)
+ throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder().build());
+ assertOutput(ftl, expectedOutStripped);
+
+ setConfiguration(new TestConfigurationBuilder().whitespaceStripping(false).build());
+ assertOutput(ftl, expectedOutNonStripped);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
new file mode 100644
index 0000000..77951ed
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.core.outputformat.impl.XHTMLOutputFormat.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.junit.Test;
+
+public class XHTMLOutputFormatTest {
+
+ @Test
+ public void testOutputMO() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("a'b"), out);
+ assertEquals("a'b", out.toString());
+ }
+
+ @Test
+ public void testOutputString() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+ INSTANCE.output("a'b", out);
+ assertEquals("a'b", out.toString());
+ }
+
+ @Test
+ public void testEscaplePlainText() {
+ assertEquals("", INSTANCE.escapePlainText(""));
+ assertEquals("a", INSTANCE.escapePlainText("a"));
+ assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
+ assertEquals("<>", INSTANCE.escapePlainText("<>"));
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("application/xhtml+xml", INSTANCE.getMimeType());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
new file mode 100644
index 0000000..7e95e6d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.core.outputformat.impl.XMLOutputFormat.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.junit.Test;
+
+public class XMLOutputFormatTest {
+
+ @Test
+ public void testOutputMO() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+ INSTANCE.output(INSTANCE.fromPlainTextByEscaping("a'b"), out);
+ assertEquals("a'b", out.toString());
+ }
+
+ @Test
+ public void testOutputString() throws TemplateModelException, IOException {
+ StringWriter out = new StringWriter();
+ INSTANCE.output("a'b", out);
+ assertEquals("a'b", out.toString());
+ }
+
+ @Test
+ public void testEscaplePlainText() {
+ assertEquals("", INSTANCE.escapePlainText(""));
+ assertEquals("a", INSTANCE.escapePlainText("a"));
+ assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
+ assertEquals("<>", INSTANCE.escapePlainText("<>"));
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("application/xml", INSTANCE.getMimeType());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
new file mode 100644
index 0000000..bdb9a56
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.core.model.impl;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+
+import junit.framework.TestCase;
+
+public abstract class AbstractParallelIntrospectionTest extends TestCase {
+
+ private static final int NUM_THREADS = 8;
+ private static final int NUM_ENTITYES = 8;
+ private static final int NUM_MEMBERS = 8;
+ private static final int ITERATIONS = 20000;
+ private static final double CACHE_CLEARING_CHANCE = 0.01;
+
+ private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .usePrivateCaches(true).build();
+
+ public AbstractParallelIntrospectionTest(String name) {
+ super(name);
+ }
+
+ public void testReliability() {
+ testReliability(ITERATIONS);
+ }
+
+ public void testReliability(int iterations) {
+ TestThread[] ts = new TestThread[NUM_THREADS];
+ for (int i = 0; i < NUM_THREADS; i++) {
+ ts[i] = new TestThread(iterations);
+ ts[i].start();
+ }
+
+ for (int i = 0; i < NUM_THREADS; i++) {
+ try {
+ ts[i].join();
+ if (ts[i].error != null) {
+ throw new AssertionError(ts[i].error);
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ protected abstract TemplateHashModel getWrappedEntity(int objIdx) throws TemplateModelException;
+
+ protected final DefaultObjectWrapper getObjectWrapper() {
+ return ow;
+ }
+
+ private class TestThread extends Thread {
+
+ private final int iterations;
+
+ private Throwable error;
+
+ private TestThread(int iterations) {
+ this.iterations = iterations;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < iterations; i++) {
+ if (Math.random() < CACHE_CLEARING_CHANCE) {
+ ow.clearClassIntrospecitonCache();
+ }
+ int objIdx = (int) (Math.random() * NUM_ENTITYES);
+ TemplateHashModel h = getWrappedEntity(objIdx);
+ int mIdx = (int) (Math.random() * NUM_MEMBERS);
+ testProperty(h, objIdx, mIdx);
+ testMethod(h, objIdx, mIdx);
+ }
+ } catch (Throwable e) {
+ error = e;
+ }
+ }
+
+ private void testProperty(TemplateHashModel h, int objIdx, int mIdx)
+ throws TemplateModelException, AssertionError {
+ TemplateNumberModel pv = (TemplateNumberModel) h.get("p" + mIdx);
+ final int expected = objIdx * 1000 + mIdx;
+ final int got = pv.getAsNumber().intValue();
+ if (got != expected) {
+ throw new AssertionError("Property assertation failed; " +
+ "expected " + expected + ", but got " + got);
+ }
+ }
+
+ private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
+ throws TemplateModelException, AssertionError {
+ TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
+ final int expected = objIdx * 1000 + mIdx;
+ final int got = ((TemplateNumberModel) pv.exec(null)).getAsNumber().intValue();
+ if (got != expected) {
+ throw new AssertionError("Method assertation failed; " +
+ "expected " + expected + ", but got " + got);
+ }
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
new file mode 100644
index 0000000..149ad0d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
@@ -0,0 +1,45 @@
+/*
+ * 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.core.model.impl;
+
+import java.beans.MethodDescriptor;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+class AlphabeticalMethodSorter implements MethodSorter {
+
+ private final boolean desc;
+
+ public AlphabeticalMethodSorter(boolean desc) {
+ this.desc = desc;
+ }
+
+ @Override
+ public void sortMethodDescriptors(List<MethodDescriptor> methodDescriptors) {
+ Collections.sort(methodDescriptors, new Comparator<MethodDescriptor>() {
+ public int compare(MethodDescriptor o1, MethodDescriptor o2) {
+ int res = o1.getMethod().toString().compareTo(o2.getMethod().toString());
+ return desc ? -res : res;
+ }
+ });
+ }
+
+}
\ No newline at end of file
[18/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/OutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
deleted file mode 100644
index eedb4d1..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.core.ParsingConfiguration.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Collections;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.OutputFormat;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.PlainTextOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
-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.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.OrMatcher;
-import org.apache.freemarker.core.templateresolver.impl.NullCacheStorage;
-import org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat;
-import org.apache.freemarker.core.userpkg.DummyOutputFormat;
-import org.apache.freemarker.core.userpkg.SeldomEscapedOutputFormat;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class OutputFormatTest extends TemplateTest {
-
- @Test
- public void testOutputFormatSettingLayers() throws Exception {
- addTemplate("t", "${.outputFormat}");
- addTemplate("t.xml", "${.outputFormat}");
- addTemplate("tWithHeader", "<#ftl outputFormat='HTML'>${.outputFormat}");
-
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
- for (OutputFormat cfgOutputFormat
- : new OutputFormat[] { UndefinedOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE } ) {
- if (!cfgOutputFormat.equals(UndefinedOutputFormat.INSTANCE)) {
- cfgB.setOutputFormat(cfgOutputFormat);
- }
- setConfiguration(cfgB.build());
-
- assertEquals(cfgOutputFormat, getConfiguration().getOutputFormat());
-
- {
- Template t = getConfiguration().getTemplate("t");
- assertEquals(cfgOutputFormat, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- {
- Template t = getConfiguration().getTemplate("t.xml");
- assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- {
- Template t = getConfiguration().getTemplate("tWithHeader");
- assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- getConfiguration().clearTemplateCache();
- }
- }
-
- @Test
- public void testStandardFileExtensions() throws Exception {
- String commonContent = "${.outputFormat}";
- addTemplate("t", commonContent);
- addTemplate("t.ftl", commonContent);
- addTemplate("t.ftlh", commonContent);
- addTemplate("t.FTLH", commonContent);
- addTemplate("t.fTlH", commonContent);
- addTemplate("t.ftlx", commonContent);
- addTemplate("t.FTLX", commonContent);
- addTemplate("t.fTlX", commonContent);
- addTemplate("tWithHeader.ftlx", "<#ftl outputFormat='HTML'>" + commonContent);
-
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
- for (int setupNumber = 1; setupNumber <= 3; setupNumber++) {
- final OutputFormat cfgOutputFormat;
- final OutputFormat ftlhOutputFormat;
- final OutputFormat ftlxOutputFormat;
- switch (setupNumber) {
- case 1:
- cfgOutputFormat = UndefinedOutputFormat.INSTANCE;
- ftlhOutputFormat = HTMLOutputFormat.INSTANCE;
- ftlxOutputFormat = XMLOutputFormat.INSTANCE;
- break;
- case 2:
- cfgOutputFormat = RTFOutputFormat.INSTANCE;
- cfgB.setOutputFormat(cfgOutputFormat);
- ftlhOutputFormat = HTMLOutputFormat.INSTANCE;
- ftlxOutputFormat = XMLOutputFormat.INSTANCE;
- break;
- case 3:
- cfgOutputFormat = UndefinedOutputFormat.INSTANCE;
- cfgB.unsetOutputFormat();
- TemplateConfiguration.Builder tcbXML = new TemplateConfiguration.Builder();
- tcbXML.setOutputFormat(XMLOutputFormat.INSTANCE);
- cfgB.setTemplateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new OrMatcher(
- new FileNameGlobMatcher("*.ftlh"),
- new FileNameGlobMatcher("*.FTLH"),
- new FileNameGlobMatcher("*.fTlH")),
- tcbXML.build()));
- ftlhOutputFormat = HTMLOutputFormat.INSTANCE; // can't be overidden
- ftlxOutputFormat = XMLOutputFormat.INSTANCE;
- break;
- default:
- throw new AssertionError();
- }
-
- setConfiguration(cfgB.build());
- assertEquals(cfgOutputFormat, getConfiguration().getOutputFormat());
-
- {
- Template t = getConfiguration().getTemplate("t");
- assertEquals(cfgOutputFormat, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- {
- Template t = getConfiguration().getTemplate("t.ftl");
- assertEquals(cfgOutputFormat, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- for (String name : new String[] { "t.ftlh", "t.FTLH", "t.fTlH" }) {
- Template t = getConfiguration().getTemplate(name);
- assertEquals(ftlhOutputFormat, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- for (String name : new String[] { "t.ftlx", "t.FTLX", "t.fTlX" }) {
- Template t = getConfiguration().getTemplate(name);
- assertEquals(ftlxOutputFormat, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- {
- Template t = getConfiguration().getTemplate("tWithHeader.ftlx");
- assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
- assertOutput(t, t.getOutputFormat().getName());
- }
-
- getConfiguration().clearTemplateCache();
- }
- }
-
- @Test
- public void testStandardFileExtensionsSettingOverriding() throws Exception {
- addTemplate("t.ftlx",
- "${\"'\"} ${\"'\"?esc} ${\"'\"?noEsc}");
- addTemplate("t.ftl",
- "${'{}'} ${'{}'?esc} ${'{}'?noEsc}");
-
- ConditionalTemplateConfigurationFactory tcfHTML = new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("t.*"),
- new TemplateConfiguration.Builder()
- .outputFormat(HTMLOutputFormat.INSTANCE)
- .build());
-
- ConditionalTemplateConfigurationFactory tcfNoAutoEsc = new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("t.*"),
- new TemplateConfiguration.Builder()
- .autoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY)
- .build());
-
- {
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
-
- setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- }
-
- {
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
-
- setConfiguration(cfgB.recognizeStandardFileExtensions(false).build());
- assertErrorContainsForNamed("t.ftlx", UndefinedOutputFormat.INSTANCE.getName());
- setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build());
- assertOutputForNamed("t.ftlx", "' ' '");
- setConfiguration(cfgB.outputFormat(XMLOutputFormat.INSTANCE).build());
- assertOutputForNamed("t.ftlx", "' ' '");
- setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
- assertOutputForNamed("t.ftlx", "' ' '");
- setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
- assertOutputForNamed("t.ftlx", "' ' '");
- }
-
- {
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
- cfgB.setRecognizeStandardFileExtensions(true);
-
- setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- }
-
- {
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
-
- setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
- assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
- setConfiguration(cfgB.recognizeStandardFileExtensions(false).build());
- assertOutputForNamed("t.ftlx", "' ' '");
- }
- }
-
- @Test
- public void testStandardFileExtensionsWithConstructor() throws Exception {
- Configuration cfg = getConfiguration();
- String commonFTL = "${'\\''}";
- {
- Template t = new Template("foo.ftl", commonFTL, cfg);
- assertSame(UndefinedOutputFormat.INSTANCE, t.getOutputFormat());
- StringWriter out = new StringWriter();
- t.process(null, out);
- assertEquals("'", out.toString());
- }
- {
- Template t = new Template("foo.ftlx", commonFTL, cfg);
- assertSame(XMLOutputFormat.INSTANCE, t.getOutputFormat());
- StringWriter out = new StringWriter();
- t.process(null, out);
- assertEquals("'", out.toString());
- }
- {
- Template t = new Template("foo.ftlh", commonFTL, cfg);
- assertSame(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
- StringWriter out = new StringWriter();
- t.process(null, out);
- assertEquals("'", out.toString());
- }
- }
-
- @Test
- public void testStandardFileExtensionsFormatterImplOverriding() throws Exception {
- addTemplate("t.ftlh", "${'a&x'}");
-
- assertOutputForNamed("t.ftlh", "a&x");
-
- setConfiguration(new TestConfigurationBuilder()
- .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(CustomHTMLOutputFormat.INSTANCE))
- .build());
- assertOutputForNamed("t.ftlh", "a&X");
-
- setConfiguration(new TestConfigurationBuilder()
- .registeredCustomOutputFormats(Collections.<OutputFormat>emptyList())
- .build());
- assertOutputForNamed("t.ftlh", "a&x");
- }
-
- @Test
- public void testAutoEscapingSettingLayers() throws Exception {
- addTemplate("t", "${'a&b'}");
- addTemplate("tWithHeaderFalse", "<#ftl autoEsc=false>${'a&b'}");
- addTemplate("tWithHeaderTrue", "<#ftl autoEsc=true>${'a&b'}");
-
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder().outputFormat(XMLOutputFormat.INSTANCE);
- assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- for (boolean cfgAutoEscaping : new boolean[] { true, false }) {
- if (!cfgAutoEscaping) {
- cfgB.setAutoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY);
- }
- setConfiguration(cfgB.build());
-
- {
- Template t = getConfiguration().getTemplate("t");
- if (cfgAutoEscaping) {
- assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
- assertOutput(t, "a&b");
- } else {
- assertEquals(DISABLE_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
- assertOutput(t, "a&b");
- }
- }
-
- {
- Template t = getConfiguration().getTemplate("tWithHeaderFalse");
- assertEquals(DISABLE_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
- assertOutput(t, "a&b");
- }
-
- {
- Template t = getConfiguration().getTemplate("tWithHeaderTrue");
- assertEquals(ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
- assertOutput(t, "a&b");
- }
-
- getConfiguration().clearTemplateCache();
- }
- }
-
- @Test
- public void testNumericalInterpolation() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(DummyOutputFormat.INSTANCE))
- .build());
- assertOutput(
- "<#ftl outputFormat='dummy'>#{1.5}; #{1.5; m3}; ${'a.b'}",
- "1\\.5; 1\\.500; a\\.b");
- assertOutput(
- "<#ftl outputFormat='dummy' autoEsc=false>#{1.5}; #{1.5; m3}; ${'a.b'}; ${'a.b'?esc}",
- "1.5; 1.500; a.b; a\\.b");
- assertOutput("<#ftl outputFormat='plainText'>#{1.5}", "1.5");
- assertOutput("<#ftl outputFormat='HTML'>#{1.5}", "1.5");
- assertOutput("#{1.5}", "1.5");
- }
-
- @Test
- public void testUndefinedOutputFormat() throws IOException, TemplateException {
- assertOutput("${'a < b'}; ${htmlPlain}; ${htmlMarkup}", "a < b; a < {h'}; <p>c");
- assertErrorContains("${'x'?esc}", "undefined", "escaping", "?esc");
- assertErrorContains("${'x'?noEsc}", "undefined", "escaping", "?noEsc");
- }
-
- @Test
- public void testPlainTextOutputFormat() throws IOException, TemplateException {
- assertOutput("<#ftl outputFormat='plainText'>${'a < b'}; ${htmlPlain}", "a < b; a < {h'}");
- assertErrorContains("<#ftl outputFormat='plainText'>${htmlMarkup}", "plainText", "HTML", "conversion");
- assertErrorContains("<#ftl outputFormat='plainText'>${'x'?esc}", "plainText", "escaping", "?esc");
- assertErrorContains("<#ftl outputFormat='plainText'>${'x'?noEsc}", "plainText", "escaping", "?noEsc");
- }
-
- @Test
- public void testAutoEscapingOnMOs() throws IOException, TemplateException {
- for (boolean cfgAutoEscaping : new boolean[] { true, false }) {
- String commonAutoEscFtl = "<#ftl outputFormat='HTML'>${'&'}";
- if (cfgAutoEscaping) {
- // Cfg default is autoEscaping true
- assertOutput(commonAutoEscFtl, "&");
- } else {
- setConfiguration(createDefaultConfigurationBuilder()
- .autoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY)
- .build());
- assertOutput(commonAutoEscFtl, "&");
- }
-
- assertOutput(
- "<#ftl outputFormat='RTF'>"
- + "${rtfPlain} ${rtfMarkup} "
- + "${htmlPlain} "
- + "${xmlPlain}",
- "\\\\par a & b \\par c "
- + "a < \\{h'\\} "
- + "a < \\{x'\\}");
- assertOutput(
- "<#ftl outputFormat='HTML'>"
- + "${htmlPlain} ${htmlMarkup} "
- + "${xmlPlain} "
- + "${rtfPlain}",
- "a < {h'} <p>c "
- + "a < {x'} "
- + "\\par a & b");
- assertOutput(
- "<#ftl outputFormat='XML'>"
- + "${xmlPlain} ${xmlMarkup} "
- + "${htmlPlain} "
- + "${rtfPlain}",
- "a < {x'} <p>c</p> "
- + "a < {h'} "
- + "\\par a & b");
- assertErrorContains("<#ftl outputFormat='RTF'>${htmlMarkup}", "output format", "RTF", "HTML");
- assertErrorContains("<#ftl outputFormat='RTF'>${xmlMarkup}", "output format", "RTF", "XML");
- assertErrorContains("<#ftl outputFormat='HTML'>${rtfMarkup}", "output format", "HTML", "RTF");
- assertErrorContains("<#ftl outputFormat='HTML'>${xmlMarkup}", "output format", "HTML", "XML");
- assertErrorContains("<#ftl outputFormat='XML'>${rtfMarkup}", "output format", "XML", "RTF");
- assertErrorContains("<#ftl outputFormat='XML'>${htmlMarkup}", "output format", "XML", "HTML");
-
- for (int hasHeader = 0; hasHeader < 2; hasHeader++) {
- assertOutput(
- (hasHeader == 1 ? "<#ftl outputFormat='undefined'>" : "")
- + "${xmlPlain} ${xmlMarkup} "
- + "${htmlPlain} ${htmlMarkup} "
- + "${rtfPlain} ${rtfMarkup}",
- "a < {x'} <p>c</p> "
- + "a < {h'} <p>c "
- + "\\\\par a & b \\par c");
- }
- }
- }
-
- @Test
- public void testStringLiteralsUseUndefinedOF() throws IOException, TemplateException {
- String expectedOut = "& (&) &";
- String ftl = "<#ftl outputFormat='XML'>${'&'} ${\"(${'&'})\"?noEsc} ${'&'}";
-
- assertOutput(ftl, expectedOut);
-
- addTemplate("t.xml", ftl);
- assertOutputForNamed("t.xml", expectedOut);
- }
-
- @Test
- public void testUnparsedTemplate() throws IOException, TemplateException {
- String content = "<#ftl>a<#foo>b${x}";
- {
- Template t = Template.createPlainTextTemplate("x", content, getConfiguration());
- Writer sw = new StringWriter();
- t.process(null, sw);
- assertEquals(content, sw.toString());
- assertEquals(UndefinedOutputFormat.INSTANCE, t.getOutputFormat());
- }
-
- {
- setConfiguration(new TestConfigurationBuilder().outputFormat(HTMLOutputFormat.INSTANCE).build());
- Template t = Template.createPlainTextTemplate("x", content, getConfiguration());
- Writer sw = new StringWriter();
- t.process(null, sw);
- assertEquals(content, sw.toString());
- assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
- }
- }
-
- @Test
- public void testStringLiteralInterpolation() throws IOException, TemplateException {
- Template t = new Template(null, "<#ftl outputFormat='XML'>${'&'} ${\"(${'&'})\"?noEsc}", getConfiguration());
- assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
-
- assertOutput("${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
- "undefined undefined undefined");
- assertOutput("<#ftl outputFormat='HTML'>${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
- "HTML HTML HTML");
- assertOutput("${.outputFormat} <#outputFormat 'XML'>${'${.outputFormat}'}</#outputFormat> ${.outputFormat}",
- "undefined XML undefined");
- assertOutput("${'foo ${xmlPlain}'}", "foo a < {x'}");
- assertOutput("${'${xmlMarkup}'}", "<p>c</p>");
- assertErrorContains("${'${\"x\"?esc}'}", "?esc", "undefined");
- assertOutput("<#ftl outputFormat='XML'>${'${xmlMarkup?esc} ${\"<\"?esc} ${\">\"} ${\"&\"?noEsc}'}",
- "<p>c</p> < > &");
- }
-
- @Test
- public void testStringBIsFail() {
- assertErrorContains("<#ftl outputFormat='HTML'>${'<b>foo</b>'?esc?upperCase}", "string", "markup_output");
- }
-
- @Test
- public void testConcatWithMOs() throws IOException, TemplateException {
- assertOutput(
- "${'\\'' + htmlMarkup} ${htmlMarkup + '\\''} ${htmlMarkup + htmlMarkup}",
- "'<p>c <p>c' <p>c<p>c");
- assertOutput(
- "${'\\'' + htmlPlain} ${htmlPlain + '\\''} ${htmlPlain + htmlPlain}",
- "'a < {h'} a < {h'}' a < {h'}a < {h'}");
- assertErrorContains(
- "<#ftl outputFormat='XML'>${'\\'' + htmlMarkup}",
- "HTML", "XML", "conversion");
- assertErrorContains(
- "${xmlMarkup + htmlMarkup}",
- "HTML", "XML", "Conversion", "common");
- assertOutput(
- "${xmlMarkup + htmlPlain}",
- "<p>c</p>a < {h'}");
- assertOutput(
- "${xmlPlain + htmlMarkup}",
- "a < {x'}<p>c");
- assertOutput(
- "${xmlPlain + htmlPlain}",
- "a < {x'}a < {h'}");
- assertOutput(
- "${xmlPlain + htmlPlain + '\\''}",
- "a < {x'}a < {h'}'");
- assertOutput(
- "${htmlPlain + xmlPlain + '\\''}",
- "a < {h'}a < {x'}'");
- assertOutput(
- "${xmlPlain + htmlPlain + '\\''}",
- "a < {x'}a < {h'}'");
- assertOutput(
- "<#ftl outputFormat='XML'>${htmlPlain + xmlPlain + '\\''}",
- "a < {h'}a < {x'}'");
- assertOutput(
- "<#ftl outputFormat='RTF'>${htmlPlain + xmlPlain + '\\''}",
- "a < \\{h'\\}a < \\{x'\\}'");
- assertOutput(
- "<#ftl outputFormat='XML'>${'\\'' + htmlPlain}",
- "'a < {h'}");
- assertOutput(
- "<#ftl outputFormat='HTML'>${'\\'' + htmlPlain}",
- "'a < {h'}");
- assertOutput(
- "<#ftl outputFormat='HTML'>${'\\'' + xmlPlain}",
- "'a < {x'}");
- assertOutput(
- "<#ftl outputFormat='RTF'>${'\\'' + xmlPlain}",
- "'a < \\{x'\\}");
-
- assertOutput(
- "<#assign x = '\\''><#assign x += xmlMarkup>${x}",
- "'<p>c</p>");
- assertOutput(
- "<#assign x = xmlMarkup><#assign x += '\\''>${x}",
- "<p>c</p>'");
- assertOutput(
- "<#assign x = xmlMarkup><#assign x += htmlPlain>${x}",
- "<p>c</p>a < {h'}");
- assertErrorContains(
- "<#assign x = xmlMarkup><#assign x += htmlMarkup>${x}",
- "HTML", "XML", "Conversion", "common");
- }
-
- @Test
- public void testBlockAssignment() throws Exception {
- for (String d : new String[] { "assign", "global", "local" }) {
- String commonFTL =
- "<#macro m>"
- + "<#" + d + " x><p>${'&'}</#" + d + ">${x?isString?c} ${x} ${'&'} "
- + "<#" + d + " x></#" + d + ">${x?isString?c}"
- + "</#macro><@m />";
- assertOutput(
- commonFTL,
- "true <p>& & true");
- assertOutput(
- "<#ftl outputFormat='HTML'>" + commonFTL,
- "false <p>& & false");
- }
- }
-
- @Test
- public void testSpecialVariables() throws Exception {
- String commonFTL = "${.outputFormat} ${.autoEsc?c}";
-
- addTemplate("t.ftlx", commonFTL);
- assertOutputForNamed("t.ftlx", "XML true");
-
- addTemplate("t.ftlh", commonFTL);
- assertOutputForNamed("t.ftlh", "HTML true");
-
- addTemplate("t.ftl", commonFTL);
- assertOutputForNamed("t.ftl", "undefined false");
-
- addTemplate("tX.ftl", "<#ftl outputFormat='XML'>" + commonFTL);
- addTemplate("tX.ftlx", commonFTL);
- assertOutputForNamed("t.ftlx", "XML true");
-
- addTemplate("tN.ftl", "<#ftl outputFormat='RTF' autoEsc=false>" + commonFTL);
- assertOutputForNamed("tN.ftl", "RTF false");
-
- assertOutput("${.output_format} ${.auto_esc?c}", "undefined false");
- }
-
- @Test
- public void testEscAndNoEscBIBasics() throws IOException, TemplateException {
- String commonFTL = "${'<x>'} ${'<x>'?esc} ${'<x>'?noEsc}";
- addTemplate("t.ftlh", commonFTL);
- addTemplate("t-noAuto.ftlh", "<#ftl autoEsc=false>" + commonFTL);
- addTemplate("t.ftl", commonFTL);
- assertOutputForNamed("t.ftlh", "<x> <x> <x>");
- assertOutputForNamed("t-noAuto.ftlh", "<x> <x> <x>");
- assertErrorContainsForNamed("t.ftl", "output format", "undefined");
- }
-
- @Test
- public void testEscAndNoEscBIsOnMOs() throws IOException, TemplateException {
- String xmlHdr = "<#ftl outputFormat='XML'>";
-
- assertOutput(
- xmlHdr + "${'&'?esc?esc} ${'&'?esc?noEsc} ${'&'?noEsc?esc} ${'&'?noEsc?noEsc}",
- "& & & &");
-
- for (String bi : new String[] { "esc", "noEsc" } ) {
- assertOutput(
- xmlHdr + "${rtfPlain?" + bi + "}",
- "\\par a & b");
- assertOutput(
- xmlHdr + "<#setting numberFormat='0.0'>${1?" + bi + "}",
- "1.0");
- assertOutput(
- xmlHdr + "<#setting booleanFormat='&y,&n'>${true?" + bi + "}",
- bi.equals("esc") ? "&y" : "&y");
- assertErrorContains(
- xmlHdr + "${rtfMarkup?" + bi + "}",
- "?" + bi, "output format", "RTF", "XML");
- assertErrorContains(
- xmlHdr + "${noSuchVar?" + bi + "}",
- "noSuchVar", "null or missing");
- assertErrorContains(
- xmlHdr + "${[]?" + bi + "}",
- "?" + bi, "xpected", "string", "sequence");
- }
- }
-
- @Test
- public void testMarkupStringBI() throws Exception {
- assertOutput(
- "${htmlPlain?markupString} ${htmlMarkup?markupString}",
- "a < {h'} <p>c");
- assertErrorContains(
- "${noSuchVar?markupString}",
- "noSuchVar", "null or missing");
- assertErrorContains(
- "${'x'?markupString}",
- "xpected", "markup output", "string");
- }
-
- @Test
- public void testOutputFormatDirective() throws Exception {
- assertOutput(
- "${.outputFormat}${'\\''} "
- + "<#outputFormat 'HTML'>"
- + "${.outputFormat}${'\\''} "
- + "<#outputFormat 'XML'>${.outputFormat}${'\\''}</#outputFormat> "
- + "${.outputFormat}${'\\''} "
- + "</#outputFormat>"
- + "${.outputFormat}${'\\''}",
- "undefined' HTML' XML' HTML' undefined'");
- assertOutput(
- "<#ftl output_format='XML'>"
- + "${.output_format}${'\\''} "
- + "<#outputformat 'HTML'>${.output_format}${'\\''}</#outputformat> "
- + "${.output_format}${'\\''}",
- "XML' HTML' XML'");
-
- // Custom format:
- assertErrorContains(
- "<#outputFormat 'dummy'></#outputFormat>",
- "dummy", "nregistered");
- setConfiguration(new TestConfigurationBuilder()
- .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(DummyOutputFormat.INSTANCE))
- .build());
- assertOutput(
- "<#outputFormat 'dummy'>${.outputFormat}</#outputFormat>",
- "dummy");
-
- // Parse-time param expression:
- assertOutput(
- "<#outputFormat 'plain' + 'Text'>${.outputFormat}</#outputFormat>",
- "plainText");
- assertErrorContains(
- "<#outputFormat 'plain' + someVar + 'Text'></#outputFormat>",
- "someVar", "parse-time");
- assertErrorContains(
- "<#outputFormat 'plainText'?upperCase></#outputFormat>",
- "?upperCase", "parse-time");
- assertErrorContains(
- "<#outputFormat true></#outputFormat>",
- "string", "boolean");
-
- // Naming convention:
- assertErrorContains(
- "<#outputFormat 'HTML'></#outputformat>",
- "convention", "#outputFormat", "#outputformat");
- assertErrorContains(
- "<#outputformat 'HTML'></#outputFormat>",
- "convention", "#outputFormat", "#outputformat");
-
- // Empty block:
- assertOutput(
- "${.output_format} "
- + "<#outputformat 'HTML'></#outputformat>"
- + "${.output_format}",
- "undefined undefined");
-
- // WS stripping:
- assertOutput(
- "${.output_format}\n"
- + "<#outputformat 'HTML'>\n"
- + " x\n"
- + "</#outputformat>\n"
- + "${.output_format}",
- "undefined\n x\nundefined");
- }
-
- @Test
- public void testAutoEscAndNoAutoEscDirectives() throws Exception {
- assertOutput(
- "<#ftl outputFormat='XML'>"
- + "${.autoEsc?c}${'&'} "
- + "<#noAutoEsc>"
- + "${.autoEsc?c}${'&'} "
- + "<#autoEsc>${.autoEsc?c}${'&'}</#autoEsc> "
- + "${.autoEsc?c}${'&'} "
- + "</#noAutoEsc>"
- + "${.autoEsc?c}${'&'}",
- "true& false& true& false& true&");
- assertOutput(
- "<#ftl auto_esc=false output_format='XML'>"
- + "${.auto_esc?c}${'&'} "
- + "<#autoesc>${.auto_esc?c}${'&'}</#autoesc> "
- + "${.auto_esc?c}${'&'}",
- "false& true& false&");
-
- // Bad came case:
- assertErrorContains(
- "<#noAutoesc></#noAutoesc>",
- "Unknown directive");
- assertErrorContains(
- "<#noautoEsc></#noautoEsc>",
- "Unknown directive");
-
- setConfiguration(new TestConfigurationBuilder()
- .outputFormat(XMLOutputFormat.INSTANCE)
- .build());
-
- // Empty block:
- assertOutput(
- "${.auto_esc?c} "
- + "<#noautoesc></#noautoesc>"
- + "${.auto_esc?c}",
- "true true");
-
- // WS stripping:
- assertOutput(
- "${.auto_esc?c}\n"
- + "<#noautoesc>\n"
- + " x\n"
- + "</#noautoesc>\n"
- + "${.auto_esc?c}",
- "true\n x\ntrue");
-
-
- // Naming convention:
- assertErrorContains(
- "<#autoEsc></#autoesc>",
- "convention", "#autoEsc", "#autoesc");
- assertErrorContains(
- "<#autoesc></#autoEsc>",
- "convention", "#autoEsc", "#autoesc");
- assertErrorContains(
- "<#noAutoEsc></#noautoesc>",
- "convention", "#noAutoEsc", "#noautoesc");
- assertErrorContains(
- "<#noautoesc></#noAutoEsc>",
- "convention", "#noAutoEsc", "#noautoesc");
- }
-
- @Test
- public void testExplicitAutoEscBannedForNonMarkup() throws Exception {
- // While this restriction is technically unnecessary, we can catch a dangerous and probably common user
- // misunderstanding.
- assertErrorContains("<#ftl autoEsc=true>", "can't do escaping", "undefined");
- assertErrorContains("<#ftl outputFormat='plainText' autoEsc=true>", "can't do escaping", "plainText");
- assertErrorContains("<#ftl autoEsc=true outputFormat='plainText'>", "can't do escaping", "plainText");
- assertOutput("<#ftl autoEsc=true outputFormat='HTML'>", "");
- assertOutput("<#ftl outputFormat='HTML' autoEsc=true>", "");
- assertOutput("<#ftl autoEsc=false>", "");
-
- assertErrorContains("<#autoEsc></#autoEsc>", "can't do escaping", "undefined");
- assertErrorContains("<#ftl outputFormat='plainText'><#autoEsc></#autoEsc>", "can't do escaping", "plainText");
- assertOutput("<#ftl outputFormat='plainText'><#outputFormat 'XML'><#autoEsc></#autoEsc></#outputFormat>", "");
- assertOutput("<#ftl outputFormat='HTML'><#autoEsc></#autoEsc>", "");
- assertOutput("<#noAutoEsc></#noAutoEsc>", "");
- }
-
- @Test
- public void testAutoEscPolicy() throws Exception {
- TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
- cfgB.setRegisteredCustomOutputFormats(ImmutableList.<OutputFormat>of(
- SeldomEscapedOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE));
- assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
-
- String commonFTL = "${'.'} ${.autoEsc?c}";
- String notEsced = ". false";
- String esced = "\\. true";
-
- for (int autoEscPolicy : new int[] {
- ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY,
- ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY,
- DISABLE_AUTO_ESCAPING_POLICY }) {
- cfgB.setAutoEscapingPolicy(autoEscPolicy);
-
- String sExpted = autoEscPolicy == ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY ? esced : notEsced;
- cfgB.setOutputFormat(SeldomEscapedOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput(commonFTL, sExpted);
- cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("<#ftl outputFormat='seldomEscaped'>" + commonFTL, sExpted);
- assertOutput("<#outputFormat 'seldomEscaped'>" + commonFTL + "</#outputFormat>", sExpted);
-
- String dExpted = autoEscPolicy == DISABLE_AUTO_ESCAPING_POLICY ? notEsced : esced;
- cfgB.setOutputFormat(DummyOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput(commonFTL, dExpted);
- cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("<#ftl outputFormat='dummy'>" + commonFTL, dExpted);
- assertOutput("<#outputFormat 'dummy'>" + commonFTL + "</#outputFormat>", dExpted);
-
- cfgB.setOutputFormat(DummyOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput(
- commonFTL
- + "<#outputFormat 'seldomEscaped'>"
- + commonFTL
- + "<#outputFormat 'dummy'>"
- + commonFTL
- + "</#outputFormat>"
- + commonFTL
- + "<#outputFormat 'plainText'>"
- + commonFTL
- + "</#outputFormat>"
- + commonFTL
- + "<#noAutoEsc>"
- + commonFTL
- + "</#noAutoEsc>"
- + commonFTL
- + "<#autoEsc>"
- + commonFTL
- + "</#autoEsc>"
- + commonFTL
- + "</#outputFormat>"
- + commonFTL
- + "<#noAutoEsc>"
- + commonFTL
- + "</#noAutoEsc>"
- + commonFTL
- + "<#autoEsc>"
- + commonFTL
- + "</#autoEsc>"
- + commonFTL
- ,
- dExpted
- + sExpted
- + dExpted
- + sExpted
- + notEsced
- + sExpted
- + notEsced
- + sExpted
- + esced
- + sExpted
- + dExpted
- + notEsced
- + dExpted
- + esced
- + dExpted);
- }
- }
-
- @Test
- public void testDynamicParsingBIsInherticContextOutputFormat() throws Exception {
- // Dynamic parser BI-s are supposed to use the ParsingConfiguration of the calling template, and ignore anything
- // inside the calling template itself. Except, the outputFormat and autoEscapingPolicy has to come from the
- // calling lexical context.
-
- String commonFTL
- = "Eval: ${'.outputFormat'?eval}; "
- + "Interpret: <#assign ipd = r\"${.outputFormat} ${'{&}'}\"?interpret><@ipd/>";
- addTemplate("t.ftlh", commonFTL);
- addTemplate("t2.ftlh", "<#outputFormat 'RTF'>" + commonFTL + "</#outputFormat>");
-
- assertOutputForNamed(
- "t.ftlh",
- "Eval: HTML; Interpret: HTML {&}");
- assertOutputForNamed(
- "t2.ftlh",
- "Eval: RTF; Interpret: RTF \\{&\\}");
- assertOutput(
- commonFTL,
- "Eval: undefined; Interpret: undefined {&}");
- assertOutput(
- "<#ftl outputFormat='RTF'>" + commonFTL + "\n"
- + "<#outputFormat 'XML'>" + commonFTL + "</#outputFormat>",
- "Eval: RTF; Interpret: RTF \\{&\\}\n"
- + "Eval: XML; Interpret: XML {&}");
-
- // parser.autoEscapingPolicy is inherited too:
- assertOutput(
- "<#ftl autoEsc=false outputFormat='XML'>"
- + commonFTL + " ${'.autoEsc'?eval?c}",
- "Eval: XML; Interpret: XML {&} false");
- assertOutput(
- "<#ftl outputFormat='XML'>"
- + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>",
- "Eval: XML; Interpret: XML {&} false");
- assertOutput(
- "<#ftl autoEsc=false outputFormat='XML'>"
- + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>",
- "Eval: XML; Interpret: XML {&} false");
- assertOutput(
- "<#ftl autoEsc=false outputFormat='XML'>"
- + "<#autoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#autoEsc>",
- "Eval: XML; Interpret: XML {&} true");
- assertOutput(
- "${.outputFormat}<#assign ftl='<#ftl outputFormat=\\'RTF\\'>$\\{.outputFormat}'> <@ftl?interpret/>",
- "undefined RTF");
- assertOutput(
- "${.outputFormat}<#outputFormat 'RTF'>"
- + "<#assign ftl='$\\{.outputFormat}'> <@ftl?interpret/> ${'.outputFormat'?eval}"
- + "</#outputFormat>",
- "undefined RTF RTF");
- }
-
- @Test
- public void testBannedBIsWhenAutoEscaping() throws Exception {
- for (String biName : new String[] { "html", "xhtml", "rtf", "xml" }) {
- String commonFTL = "${'x'?" + biName + "}";
- assertOutput(commonFTL, "x");
- assertErrorContains("<#ftl outputFormat='HTML'>" + commonFTL,
- "?" + biName, "HTML", "double-escaping");
- assertErrorContains("<#ftl outputFormat='HTML'>${'${\"x\"?" + biName + "}'}",
- "?" + biName, "HTML", "double-escaping");
- assertOutput("<#ftl outputFormat='plainText'>" + commonFTL, "x");
- assertOutput("<#ftl outputFormat='HTML' autoEsc=false>" + commonFTL, "x");
- assertOutput("<#ftl outputFormat='HTML'><#noAutoEsc>" + commonFTL + "</#noAutoEsc>", "x");
- assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>",
- "x");
- }
- }
-
- @Test
- public void testLegacyEscaperBIsBypassMOs() throws Exception {
- assertOutput("${htmlPlain?html} ${htmlMarkup?html}", "a < {h'} <p>c");
- assertErrorContains("${xmlPlain?html}", "?html", "string", "markup_output", "XML");
- assertErrorContains("${xmlMarkup?html}", "?html", "string", "markup_output", "XML");
- assertErrorContains("${rtfPlain?html}", "?html", "string", "markup_output", "RTF");
- assertErrorContains("${rtfMarkup?html}", "?html", "string", "markup_output", "RTF");
-
- assertOutput("${htmlPlain?xhtml} ${htmlMarkup?xhtml}", "a < {h'} <p>c");
- assertErrorContains("${xmlPlain?xhtml}", "?xhtml", "string", "markup_output", "XML");
- assertErrorContains("${xmlMarkup?xhtml}", "?xhtml", "string", "markup_output", "XML");
- assertErrorContains("${rtfPlain?xhtml}", "?xhtml", "string", "markup_output", "RTF");
- assertErrorContains("${rtfMarkup?xhtml}", "?xhtml", "string", "markup_output", "RTF");
-
- assertOutput("${xmlPlain?xml} ${xmlMarkup?xml}", "a < {x'} <p>c</p>");
- assertOutput("${htmlPlain?xml} ${htmlMarkup?xml}", "a < {h'} <p>c");
- assertErrorContains("${rtfPlain?xml}", "?xml", "string", "markup_output", "RTF");
- assertErrorContains("${rtfMarkup?xml}", "?xml", "string", "markup_output", "RTF");
-
- assertOutput("${rtfPlain?rtf} ${rtfMarkup?rtf}", "\\\\par a & b \\par c");
- assertErrorContains("${xmlPlain?rtf}", "?rtf", "string", "markup_output", "XML");
- assertErrorContains("${xmlMarkup?rtf}", "?rtf", "string", "markup_output", "XML");
- assertErrorContains("${htmlPlain?rtf}", "?rtf", "string", "markup_output", "HTML");
- assertErrorContains("${htmlMarkup?rtf}", "?rtf", "string", "markup_output", "HTML");
- }
-
- @Test
- public void testBannedDirectivesWhenAutoEscaping() throws Exception {
- String commonFTL = "<#escape x as x?html>x</#escape>";
- assertOutput(commonFTL, "x");
- assertErrorContains("<#ftl outputFormat='HTML'>" + commonFTL, "escape", "HTML", "double-escaping");
- assertOutput("<#ftl outputFormat='plainText'>" + commonFTL, "x");
- assertOutput("<#ftl outputFormat='HTML' autoEsc=false>" + commonFTL, "x");
- assertOutput("<#ftl outputFormat='HTML'><#noAutoEsc>" + commonFTL + "</#noAutoEsc>", "x");
- assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>", "x");
- }
-
- @Test
- public void testCombinedOutputFormats() throws Exception {
- assertOutput(
- "<#outputFormat 'XML{HTML}'>${'\\''}</#outputFormat>",
- "&#39;");
- assertOutput(
- "<#outputFormat 'HTML{RTF{XML}}'>${'<a=\\'{}\\' />'}</#outputFormat>",
- "&lt;a=&apos;\\{\\}&apos; /&gt;");
-
- String commonFtl = "${'\\''} <#outputFormat '{HTML}'>${'\\''}</#outputFormat>";
- String commonOutput = "' &#39;";
- assertOutput(
- "<#outputFormat 'XML'>" + commonFtl + "</#outputFormat>",
- commonOutput);
- assertOutput(
- "<#ftl outputFormat='XML'>" + commonFtl,
- commonOutput);
- addTemplate("t.ftlx", commonFtl);
- assertOutputForNamed(
- "t.ftlx",
- commonOutput);
-
- assertErrorContains(
- commonFtl,
- ParseException.class, "{...}", "markup", UndefinedOutputFormat.INSTANCE.getName());
- assertErrorContains(
- "<#ftl outputFormat='plainText'>" + commonFtl,
- ParseException.class, "{...}", "markup", PlainTextOutputFormat.INSTANCE.getName());
- assertErrorContains(
- "<#ftl outputFormat='RTF'><#outputFormat '{plainText}'></#outputFormat>",
- ParseException.class, "{...}", "markup", PlainTextOutputFormat.INSTANCE.getName());
- assertErrorContains(
- "<#ftl outputFormat='RTF'><#outputFormat '{noSuchFormat}'></#outputFormat>",
- ParseException.class, "noSuchFormat", "registered");
- assertErrorContains(
- "<#outputFormat 'noSuchFormat{HTML}'></#outputFormat>",
- ParseException.class, "noSuchFormat", "registered");
- assertErrorContains(
- "<#outputFormat 'HTML{noSuchFormat}'></#outputFormat>",
- ParseException.class, "noSuchFormat", "registered");
- }
-
- @Test
- public void testHasContentBI() throws Exception {
- assertOutput("${htmlMarkup?hasContent?c} ${htmlPlain?hasContent?c}", "true true");
- assertOutput("<#ftl outputFormat='HTML'>${''?esc?hasContent?c} ${''?noEsc?hasContent?c}", "false false");
- }
-
- @Test
- public void testMissingVariables() throws Exception {
- for (String ftl : new String[] {
- "${noSuchVar}",
- "<#ftl outputFormat='XML'>${noSuchVar}",
- "<#ftl outputFormat='XML'>${noSuchVar?esc}",
- "<#ftl outputFormat='XML'>${'x'?esc + noSuchVar}"
- }) {
- assertErrorContains(ftl, InvalidReferenceException.class, "noSuchVar", "null or missing");
- }
- }
-
- @Test
- public void testIsMarkupOutputBI() throws Exception {
- addToDataModel("m1", HTMLOutputFormat.INSTANCE.fromPlainTextByEscaping("x"));
- addToDataModel("m2", HTMLOutputFormat.INSTANCE.fromMarkup("x"));
- addToDataModel("s", "x");
- assertOutput("${m1?isMarkupOutput?c} ${m2?isMarkupOutput?c} ${s?isMarkupOutput?c}", "true true false");
- assertOutput("${m1?is_markup_output?c}", "true");
- }
-
- private TestConfigurationBuilder createDefaultConfigurationBuilder() throws TemplateModelException {
- return new TestConfigurationBuilder()
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*.xml"),
- new TemplateConfiguration.Builder()
- .outputFormat(XMLOutputFormat.INSTANCE)
- .build()))
- .cacheStorage(NullCacheStorage.INSTANCE); // Prevent caching as we change the cfgB between build().
- }
-
- @Before
- public void addCommonDataModelVariables() throws TemplateModelException {
- addToDataModel("rtfPlain", RTFOutputFormat.INSTANCE.fromPlainTextByEscaping("\\par a & b"));
- addToDataModel("rtfMarkup", RTFOutputFormat.INSTANCE.fromMarkup("\\par c"));
- addToDataModel("htmlPlain", HTMLOutputFormat.INSTANCE.fromPlainTextByEscaping("a < {h'}"));
- addToDataModel("htmlMarkup", HTMLOutputFormat.INSTANCE.fromMarkup("<p>c"));
- addToDataModel("xmlPlain", XMLOutputFormat.INSTANCE.fromPlainTextByEscaping("a < {x'}"));
- addToDataModel("xmlMarkup", XMLOutputFormat.INSTANCE.fromMarkup("<p>c</p>"));
- }
-
- @Override
- protected Configuration createDefaultConfiguration() throws TemplateModelException {
- return createDefaultConfigurationBuilder().build();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
deleted file mode 100644
index 77b46de..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.core;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class ParseTimeParameterBIErrorMessagesTest extends TemplateTest {
-
- @Test
- public void testThen() throws Exception {
- assertErrorContains("${true?then}", "expecting", "\"(\"");
- assertErrorContains("${true?then + 1}", "expecting", "\"(\"");
- assertErrorContains("${true?then()}", "?then", "2 parameters");
- assertErrorContains("${true?then(1)}", "?then", "2 parameters");
- assertOutput("${true?then(1, 2)}", "1");
- assertErrorContains("${true?then(1, 2, 3)}", "?then", "2 parameters");
- }
-
- @Test
- public void testSwitch() throws Exception {
- assertErrorContains("${true?switch}", "expecting", "\"(\"");
- assertErrorContains("${true?switch + 1}", "expecting", "\"(\"");
- assertErrorContains("${true?switch()}", "at least 2 parameters");
- assertErrorContains("${true?switch(true)}", "at least 2 parameters");
- assertOutput("${true?switch(true, 1)}", "1");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
deleted file mode 100644
index 8f20d6c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class ParsingErrorMessagesTest {
-
- private Configuration cfg = new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
- .build();
-
- @Test
- public void testNeedlessInterpolation() {
- assertErrorContains("<#if ${x} == 3></#if>", "instead of ${");
- assertErrorContains("<#if ${x == 3}></#if>", "instead of ${");
- assertErrorContains("<@foo ${x == 3} />", "instead of ${");
- }
-
- @Test
- public void testWrongDirectiveNames() {
- assertErrorContains("<#foo />", "nknown directive", "#foo");
- assertErrorContains("<#set x = 1 />", "nknown directive", "#set", "#assign");
- assertErrorContains("<#iterator></#iterator>", "nknown directive", "#iterator", "#list");
- }
-
- @Test
- public void testBug402() {
- assertErrorContains("<#list 1..i as k>${k}<#list>", "existing directive", "malformed", "#list");
- assertErrorContains("<#assign>", "existing directive", "malformed", "#assign");
- assertErrorContains("</#if x>", "existing directive", "malformed", "#if");
- assertErrorContains("<#compress x>", "existing directive", "malformed", "#compress");
- }
-
- @Test
- public void testUnclosedDirectives() {
- assertErrorContains("<#macro x>", "#macro", "unclosed");
- assertErrorContains("<#function x>", "#macro", "unclosed");
- assertErrorContains("<#assign x>", "#assign", "unclosed");
- assertErrorContains("<#macro m><#local x>", "#local", "unclosed");
- assertErrorContains("<#global x>", "#global", "unclosed");
- assertErrorContains("<@foo>", "@...", "unclosed");
- assertErrorContains("<#list xs as x>", "#list", "unclosed");
- assertErrorContains("<#list xs as x><#if x>", "#if", "unclosed");
- assertErrorContains("<#list xs as x><#if x><#if q><#else>", "#if", "unclosed");
- assertErrorContains("<#list xs as x><#if x><#if q><#else><#macro x>qwe", "#macro", "unclosed");
- assertErrorContains("${(blah", "\"(\"", "unclosed");
- assertErrorContains("${blah", "\"{\"", "unclosed");
- }
-
- @Test
- public void testInterpolatingClosingsErrors() {
- assertErrorContains("${x", "unclosed");
- assertErrorContains("<#assign x = x}>", "\"}\"", "open");
- // TODO assertErrorContains("<#assign x = '${x'>", "unclosed");
- }
-
- private void assertErrorContains(String ftl, String... expectedSubstrings) {
- assertErrorContains(false, ftl, expectedSubstrings);
- assertErrorContains(true, ftl, expectedSubstrings);
- }
-
- private void assertErrorContains(boolean squareTags, String ftl, String... expectedSubstrings) {
- try {
- if (squareTags) {
- ftl = ftl.replace('<', '[').replace('>', ']');
- }
- new Template("adhoc", ftl, cfg);
- fail("The template had to fail");
- } catch (ParseException e) {
- String msg = e.getMessage();
- for (String needle: expectedSubstrings) {
- if (needle.startsWith("\\!")) {
- String netNeedle = needle.substring(2);
- if (msg.contains(netNeedle)) {
- fail("The message shouldn't contain substring " + _StringUtil.jQuote(netNeedle) + ":\n" + msg);
- }
- } else if (!msg.contains(needle)) {
- fail("The message didn't contain substring " + _StringUtil.jQuote(needle) + ":\n" + msg);
- }
- }
- showError(e);
- } catch (IOException e) {
- // Won't happen
- throw new RuntimeException(e);
- }
- }
-
- private void showError(Throwable e) {
- //System.out.println(e);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
deleted file mode 100644
index 702a254..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-
-import javax.annotation.PostConstruct;
-
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.DefaultArrayAdapter;
-import org.apache.freemarker.core.model.impl.DefaultListAdapter;
-import org.apache.freemarker.core.model.impl.DefaultMapAdapter;
-import org.apache.freemarker.core.model.impl.DefaultNonListCollectionAdapter;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapperTest.TestBean;
-import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleDate;
-import org.apache.freemarker.core.model.impl.SimpleNumber;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.junit.Test;
-
-public class RestrictedObjectWrapperTest {
-
- @Test
- public void testBasics() throws TemplateModelException {
- PostConstruct.class.toString();
- RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- testCustomizationCommonPart(ow);
- assertTrue(ow.wrap(Collections.emptyMap()) instanceof DefaultMapAdapter);
- assertTrue(ow.wrap(Collections.emptyList()) instanceof DefaultListAdapter);
- assertTrue(ow.wrap(new boolean[] { }) instanceof DefaultArrayAdapter);
- assertTrue(ow.wrap(new HashSet()) instanceof DefaultNonListCollectionAdapter);
- }
-
- @SuppressWarnings("boxing")
- private void testCustomizationCommonPart(RestrictedObjectWrapper ow) throws TemplateModelException {
- assertTrue(ow.wrap("x") instanceof SimpleScalar);
- assertTrue(ow.wrap(1.5) instanceof SimpleNumber);
- assertTrue(ow.wrap(new Date()) instanceof SimpleDate);
- assertEquals(TemplateBooleanModel.TRUE, ow.wrap(true));
-
- try {
- ow.wrap(new TestBean());
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("type"));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
deleted file mode 100644
index 43ff3bf..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateCollectionModelEx;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx2;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateModelWithAPISupport;
-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.RestrictedObjectWrapper;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public class RestrictedObjetWrapperTest {
-
- @Test
- public void testDoesNotAllowAPIBuiltin() throws TemplateModelException {
- RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- TemplateModelWithAPISupport map = (TemplateModelWithAPISupport) sow.wrap(new HashMap());
- try {
- map.getAPI();
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsString("?api"));
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testCanWrapBasicTypes() throws TemplateModelException {
- RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertTrue(sow.wrap("s") instanceof TemplateScalarModel);
- assertTrue(sow.wrap(1) instanceof TemplateNumberModel);
- assertTrue(sow.wrap(true) instanceof TemplateBooleanModel);
- assertTrue(sow.wrap(new Date()) instanceof TemplateDateModel);
- assertTrue(sow.wrap(new ArrayList()) instanceof TemplateSequenceModel);
- assertTrue(sow.wrap(new String[0]) instanceof TemplateSequenceModel);
- assertTrue(sow.wrap(new ArrayList().iterator()) instanceof TemplateCollectionModel);
- assertTrue(sow.wrap(new HashSet()) instanceof TemplateCollectionModelEx);
- assertTrue(sow.wrap(new HashMap()) instanceof TemplateHashModelEx2);
- assertNull(sow.wrap(null));
- }
-
- @Test
- public void testWontWrapDOM() throws SAXException, IOException, ParserConfigurationException,
- TemplateModelException {
- DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- InputSource is = new InputSource();
- is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
- Document doc = db.parse(is);
-
- RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- try {
- sow.wrap(doc);
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("won't wrap"));
- }
- }
-
- @Test
- public void testWontWrapGenericObjects() {
- RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- try {
- sow.wrap(new File("/x"));
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("won't wrap"));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
deleted file mode 100644
index cf14b93..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.util._DateUtil;
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class SQLTimeZoneTest extends TemplateTest {
-
- private final static TimeZone GMT_P02 = TimeZone.getTimeZone("GMT+02");
-
- private TimeZone lastDefaultTimeZone;
-
- private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
- {
- df.setTimeZone(_DateUtil.UTC);
- }
-
- // Values that JDBC in GMT+02 would produce
- private final java.sql.Date sqlDate = new java.sql.Date(utcToLong("2014-07-11T22:00:00")); // 2014-07-12
- private final Time sqlTime = new Time(utcToLong("1970-01-01T10:30:05")); // 12:30:05
- private final Timestamp sqlTimestamp = new Timestamp(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05
- private final Date javaDate = new Date(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05
- private final Date javaDayErrorDate = new Date(utcToLong("2014-07-11T22:00:00")); // 2014-07-12T12:30:05
-
- public TimeZone getLastDefaultTimeZone() {
- return lastDefaultTimeZone;
- }
-
- public void setLastDefaultTimeZone(TimeZone lastDefaultTimeZone) {
- this.lastDefaultTimeZone = lastDefaultTimeZone;
- }
-
- public java.sql.Date getSqlDate() {
- return sqlDate;
- }
-
- public Time getSqlTime() {
- return sqlTime;
- }
-
- public Timestamp getSqlTimestamp() {
- return sqlTimestamp;
- }
-
- public Date getJavaDate() {
- return javaDate;
- }
-
- public Date getJavaDayErrorDate() {
- return javaDayErrorDate;
- }
-
- private static final String FTL =
- "${sqlDate} ${sqlTime} ${sqlTimestamp} ${javaDate?datetime}\n"
- + "${sqlDate?string.iso_fz} ${sqlTime?string.iso_fz} "
- + "${sqlTimestamp?string.iso_fz} ${javaDate?datetime?string.iso_fz}\n"
- + "${sqlDate?string.xs_fz} ${sqlTime?string.xs_fz} "
- + "${sqlTimestamp?string.xs_fz} ${javaDate?datetime?string.xs_fz}\n"
- + "${sqlDate?string.xs} ${sqlTime?string.xs} "
- + "${sqlTimestamp?string.xs} ${javaDate?datetime?string.xs}\n"
- + "<#setting time_zone='GMT'>\n"
- + "${sqlDate} ${sqlTime} ${sqlTimestamp} ${javaDate?datetime}\n"
- + "${sqlDate?string.iso_fz} ${sqlTime?string.iso_fz} "
- + "${sqlTimestamp?string.iso_fz} ${javaDate?datetime?string.iso_fz}\n"
- + "${sqlDate?string.xs_fz} ${sqlTime?string.xs_fz} "
- + "${sqlTimestamp?string.xs_fz} ${javaDate?datetime?string.xs_fz}\n"
- + "${sqlDate?string.xs} ${sqlTime?string.xs} "
- + "${sqlTimestamp?string.xs} ${javaDate?datetime?string.xs}\n";
-
- private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2
- = "2014-07-12 12:30:05 2014-07-12T12:30:05 2014-07-12T12:30:05\n"
- + "2014-07-12 12:30:05+02:00 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n"
- + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n"
- + "2014-07-12 12:30:05 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n";
-
- private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_DIFFERENT
- = "2014-07-12 12:30:05 2014-07-12T11:30:05 2014-07-12T11:30:05\n"
- + "2014-07-12 12:30:05+02:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
- + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
- + "2014-07-12 12:30:05 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n";
-
- private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_SAME
- = "2014-07-11 11:30:05 2014-07-12T11:30:05 2014-07-12T11:30:05\n"
- + "2014-07-11 11:30:05+01:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
- + "2014-07-11+01:00 11:30:05+01:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
- + "2014-07-11 11:30:05 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n";
-
- private static final String OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME
- = "2014-07-11 10:30:05 2014-07-12T10:30:05 2014-07-12T10:30:05\n"
- + "2014-07-11 10:30:05Z 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
- + "2014-07-11Z 10:30:05Z 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
- + "2014-07-11 10:30:05 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n";
-
- private static final String OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT
- = "2014-07-12 12:30:05 2014-07-12T10:30:05 2014-07-12T10:30:05\n"
- + "2014-07-12 12:30:05+02:00 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
- + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
- + "2014-07-12 12:30:05 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n";
-
- @Test
- public void testWithDefaultTZAndNullSQL() throws Exception {
- TimeZone prevSysDefTz = TimeZone.getDefault();
- TimeZone.setDefault(GMT_P02);
- try {
- Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder();
- cfgB.unsetTimeZone();
- setConfiguration(cfgB.build());
-
- assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
- assertEquals(TimeZone.getDefault(), getConfiguration().getTimeZone());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
- } finally {
- TimeZone.setDefault(prevSysDefTz);
- }
- }
-
- @Test
- public void testWithDefaultTZAndGMT2SQL() throws Exception {
- TimeZone prevSysDefTz = TimeZone.getDefault();
- TimeZone.setDefault(GMT_P02);
- try {
- Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder();
- cfgB.sqlDateAndTimeTimeZone(GMT_P02).unsetTimeZone();
- setConfiguration(cfgB.build());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
- } finally {
- TimeZone.setDefault(prevSysDefTz);
- }
- }
-
- @Test
- public void testWithGMT1AndNullSQL() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .timeZone(TimeZone.getTimeZone("GMT+01:00"))
- .build());
- assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_SAME + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
- }
-
- @Test
- public void testWithGMT1AndGMT2SQL() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .sqlDateAndTimeTimeZone(GMT_P02)
- .timeZone(TimeZone.getTimeZone("GMT+01:00"))
- .build());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_DIFFERENT + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
- }
-
- @Test
- public void testWithGMT2AndNullSQL() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .timeZone(TimeZone.getTimeZone("GMT+02"))
- .build());
- assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
- }
-
- @Test
- public void testWithGMT2AndGMT2SQL() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .sqlDateAndTimeTimeZone(GMT_P02)
- .timeZone(TimeZone.getTimeZone("GMT+02"))
- .build());
-
- assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
- }
-
- @Test
- public void testCacheFlushings() throws Exception {
- Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder()
- .timeZone(_DateUtil.UTC)
- .dateFormat("yyyy-MM-dd E")
- .timeFormat("HH:mm:ss E")
- .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss E");
-
- setConfiguration(cfgB.build());
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting locale='de'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-11 Fr, 10:30:05 Do, 2014-07-12T10:30:05 Sa, 2014-07-12T10:30:05 Sa, 2014-07-12 Sa, 10:30:05 Sa\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting date_format='yyyy-MM-dd'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-11, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12, 10:30:05 Sat\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting time_format='HH:mm:ss'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-11 Fri, 10:30:05, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting datetime_format='yyyy-MM-dd\\'T\\'HH:mm:ss'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n");
-
- setConfiguration(cfgB.sqlDateAndTimeTimeZone(GMT_P02).build());
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting locale='de'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-12 Sa, 12:30:05 Do, 2014-07-12T10:30:05 Sa, 2014-07-12T10:30:05 Sa, 2014-07-12 Sa, 10:30:05 Sa\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting date_format='yyyy-MM-dd'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-12, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12, 10:30:05 Sat\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting time_format='HH:mm:ss'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-12 Sat, 12:30:05, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05\n");
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
- + "<#setting datetime_format='yyyy-MM-dd\\'T\\'HH:mm:ss'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
- "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
- + "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n");
- }
-
- @Test
- public void testDateAndTimeBuiltInsHasNoEffect() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .timeZone(_DateUtil.UTC)
- .sqlDateAndTimeTimeZone(GMT_P02)
- .build());
-
- assertOutput(
- "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
- + "${sqlDate?date} ${sqlTime?time}\n"
- + "<#setting time_zone='GMT+02'>\n"
- + "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
- + "${sqlDate?date} ${sqlTime?time}\n"
- + "<#setting time_zone='GMT-11'>\n"
- + "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
- + "${sqlDate?date} ${sqlTime?time}\n",
- "2014-07-11 22:00:00 2014-07-12 10:30:05 2014-07-12 12:30:05\n"
- + "2014-07-12 00:00:00 2014-07-12 12:30:05 2014-07-12 12:30:05\n"
- + "2014-07-11 11:00:00 2014-07-11 23:30:05 2014-07-12 12:30:05\n");
- }
-
- @Test
- public void testChangeSettingInTemplate() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .timeZone(_DateUtil.UTC)
- .build());
-
- assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
-
- assertOutput(
- "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting sql_date_and_time_time_zone='GMT+02'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting sql_date_and_time_time_zone='null'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting time_zone='GMT+03'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting sql_date_and_time_time_zone='GMT+02'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting sql_date_and_time_time_zone='GMT-11'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting date_format='xs fz'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting time_format='xs fz'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
- + "<#setting datetime_format='iso m'>\n"
- + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n",
- "2014-07-11, 10:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
- + "2014-07-12, 12:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
- + "2014-07-11, 10:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
- + "2014-07-12, 13:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
- + "2014-07-12, 12:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
- + "2014-07-11, 23:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
- + "2014-07-11-11:00, 23:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
- + "2014-07-11-11:00, 23:30:05-11:00, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
- + "2014-07-11-11:00, 23:30:05-11:00, 2014-07-12T13:30+03:00, 2014-07-12T13:30+03:00\n");
- }
-
- @Test
- public void testFormatUTCFlagHasNoEffect() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .sqlDateAndTimeTimeZone(GMT_P02)
- .timeZone(TimeZone.getTimeZone("GMT-01"))
- .build());
-
- assertOutput(
- "<#setting date_format='xs fz'><#setting time_format='xs fz'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
- + "<#setting date_format='xs fz u'><#setting time_format='xs fz u'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
- + "<#setting sql_date_and_time_time_zone='GMT+03'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
- + "<#setting sql_date_and_time_time_zone='null'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
- + "<#setting date_format='xs fz'><#setting time_format='xs fz'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
- + "<#setting date_format='xs fz fu'><#setting time_format='xs fz fu'>\n"
- + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n",
- "2014-07-12+02:00, 12:30:05+02:00, 09:30:05-01:00\n"
- + "2014-07-12+02:00, 12:30:05+02:00, 10:30:05Z\n"
- + "2014-07-12+03:00, 13:30:05+03:00, 10:30:05Z\n"
- + "2014-07-11-01:00, 09:30:05-01:00, 10:30:05Z\n"
- + "2014-07-11-01:00, 09:30:05-01:00, 09:30:05-01:00\n"
- + "2014-07-11Z, 10:30:05Z, 10:30:05Z\n");
- }
-
- private Configuration.ExtendableBuilder<?> createConfigurationBuilder() {
- return new Configuration.Builder(Configuration.VERSION_3_0_0)
- .locale(Locale.US)
- .dateFormat("yyyy-MM-dd")
- .timeFormat("HH:mm:ss")
- .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss");
- }
-
- @Override
- protected Object createDataModel() {
- return this;
- }
-
- private long utcToLong(String isoDateTime) {
- try {
- return df.parse(isoDateTime).getTime();
- } catch (ParseException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
[24/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/type-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/type-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/type-builtins.ftl
new file mode 100644
index 0000000..cb0f576
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/type-builtins.ftl
@@ -0,0 +1,44 @@
+<#--
+ 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.
+-->
+<#setting boolean_format="1,0">
+StNuBoMeTaMaHaHxSeCoCxEnInDiNo
+<#list [
+ "a", 1, false,
+ testmethod, testmacro, html_escape,
+ {"a":1}, [1], testcollection, testcollectionEx,
+ testnode,
+ bean, bean.m, bean.mOverloaded
+] as x>
+ ${x?is_string} <#t>
+ ${x?is_number} <#t>
+ ${x?is_boolean} <#t>
+ ${x?is_method} <#t>
+ ${x?is_macro} <#t>
+ ${x?is_transform} <#t>
+ ${x?is_hash} <#t>
+ ${x?is_hash_ex} <#t>
+ ${x?is_sequence} <#t>
+ ${x?is_collection} <#t>
+ ${x?is_collection_ex} <#t>
+ ${x?is_enumerable} <#t>
+ ${x?is_indexable} <#t>
+ ${x?is_directive} <#t>
+ ${x?is_node}<#lt>
+</#list>
+<#macro testmacro></#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/undefined.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/undefined.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/undefined.ftl
new file mode 100644
index 0000000..2ca96ac
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/undefined.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+${undefined_variable}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/url.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/url.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/url.ftl
new file mode 100644
index 0000000..814de80
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/url.ftl
@@ -0,0 +1,24 @@
+<#--
+ 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.
+-->
+<#setting url_escaping_charset="utf-8">
+<#assign s = 'a/báb?c/x;y=1' />
+<@assertEquals expected='a%2Fb%E1b%3Fc%2Fx%3By%3D1' actual=s?url('ISO-8859-1') />
+<@assertEquals expected='a%2Fb%C3%A1b%3Fc%2Fx%3By%3D1' actual=s?url />
+<@assertEquals expected='a/b%E1b%3Fc/x%3By%3D1' actual=s?url_path('ISO-8859-1') />
+<@assertEquals expected='a/b%C3%A1b%3Fc/x%3By%3D1' actual=s?url_path />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/var-layers.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/var-layers.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/var-layers.ftl
new file mode 100644
index 0000000..25333de
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/var-layers.ftl
@@ -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.
+-->
+<#import "varlayers_lib.ftl" as lib>
+<@foo 1/>
+${x} = ${.data_model.x} = ${.globals.x}
+<#assign x = 5>
+${x} = ${.main.x} = ${.namespace.x}
+<#global x = 6>
+${.globals.x} but ${.data_model.x} = 4
+${y} = ${.globals.y} = ${.data_model.y?default("ERROR")}
+Invisiblity test 1.: <#if .main.y?exists || .namespace.y?exists>failed<#else>passed</#if>
+Invisiblity test 2.: <#if .main.z?exists || .namespace.z?exists>failed<#else>passed</#if>
+Invisiblity test 3.: <#global q = 1><#if .main.q?exists || .namespace.q?exists || .data_model.q?exists>failed<#else>passed</#if>
+--
+<@lib.foo/>
+--
+<#macro foo x>
+ ${x} = ${.locals.x}
+ <#local x = 2>
+ ${x} = ${.locals.x}
+ <#local y = 3>
+ ${y} = ${.locals.y}
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varargs.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varargs.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varargs.ftl
new file mode 100644
index 0000000..5e79aa7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varargs.ftl
@@ -0,0 +1,45 @@
+<#--
+ 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.
+-->
+<#setting number_format="#">
+
+${m.bar()} == 0
+${m.bar([])} == 0
+${m.bar(11)} == 11
+${m.bar(null, 11)} == 11
+${m.bar(11, 22)} == 1122
+${m.bar(11.6, 22.4)} == 1122
+${m.bar(11, 22, 33)} == 112233
+${m.bar([11, 22, 33])} == 112233
+
+${m.bar2(11, [22, 33, 44])} == -22334411
+${m.bar2(11, 22, 33)} == -223311
+${m.bar2(11, 22)} == -2211
+${m.bar2(11)} == -11
+
+${m.overloaded()} == 0
+${m.overloaded(11)} == -11
+${m.overloaded(11, 22)} == 1122
+${m.overloaded(11, 22, 33)} == -112233
+${m.overloaded(11, 22, 33, 44)} == -11223344
+${m.overloaded([11, 22, 33, 44, 55])} == -1122334455
+
+${m.overloaded(11, 22)} == 1122
+${m.overloaded([11, 22])} == -1122
+
+${m.noVarArgs("string", true, 123, 1000000?number_to_date)} == string, true, 123, 1000000
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/variables.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/variables.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/variables.ftl
new file mode 100644
index 0000000..b927381
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/variables.ftl
@@ -0,0 +1,70 @@
+[#ftl]
+[#--
+ 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.
+--]
+<html>
+<head>
+<title>FreeMarker: Variable Test</title>
+</head>
+<body>
+[#assign list = ["one", "two", "three", "four", "five"]]
+[#assign hash = {"output" : "My message.", "key" : list}]
+[#assign hash2 = {"value" : hash}]
+[#assign items = {"mykey" : "key", "_test", "out"}]
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now get into variable nesting:</p>
+
+<p>${hash.output}</p>
+<p>${hash["output"]}</p>
+<p>${hash. output}</p>
+<p>${hash .output}</p>
+<p>${hash
+ .output}</p>
+<p>${hash
+ . output}</p>
+<p>${hash ["output"]}</p>
+<p>${hash
+ [ "output" ]}</p>
+
+<p>More deep nesting...</p>
+
+<p>${hash2.value.output}</p>
+<p>${hash2.value.key[0]}</p>
+<p>${hash2["value"]["key"][0]}</p>
+
+
+<p>Nesting inside nesting...</p>
+
+<p>${hash2.value[ items.mykey ][ 1 ]}</p>
+<p>${hash2.value[ items[ "mykey" ]][ 1 ]}</p>
+<p>${hash2.value[ items[ "my" + items.mykey ]][ 1 ]}</p>
+<p>${hash2.value[ items[ "my" + items["mykey"] ]][ 1 ]}</p>
+
+<p>Test underscores...</p>
+
+<p>${items[ "_test" ]}</p>
+<p>${items._test}</p>
+
+${"God save the queen."?word_list[1]?upper_case}
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varlayers_lib.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varlayers_lib.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varlayers_lib.ftl
new file mode 100644
index 0000000..9a1a471
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/varlayers_lib.ftl
@@ -0,0 +1,28 @@
+<#--
+ 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.
+-->
+<#assign x1 = .data_model.x>
+<#assign x2 = x>
+<#assign z2 = z>
+<#macro foo>
+<@.main.foo 1/>
+ ${z} = ${z2} = ${x1} = ${.data_model.x}
+ 5
+ ${x} == ${.globals.x}
+ ${y} == ${.globals.y} == ${.data_model.y?default("ERROR")}
+</#macro>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/whitespace-trim.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/whitespace-trim.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/whitespace-trim.ftl
new file mode 100644
index 0000000..9c10dd9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/whitespace-trim.ftl
@@ -0,0 +1,102 @@
+<#--
+ 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.
+-->
+ LB<#lt>
+ LB<#lt>
+ LB<#lt>
+LB<#lt>
+ IB
+ IC1<#rt>
+ IC2<#rt>
+C1<#rt>
+C2<#rt>
+ ICS <#rt>
+CS1 <#rt>
+ CS2 <#t>
+ C3<#t>
+ C1<#t>
+C2
+B
+B
+ C1<#t>
+CB
+C1
+ C2<#t>
+ ICB
+ IC<#rt>
+ ICB
+ IC<#rt>
+ CB<#lt>
+--
+<#macro x t>${t}</#macro>
+ ${""}<@x t="LB"/><#lt>
+ <@x t="LB"/><#lt>${""}
+ <@x t="LB"/><#lt>${""}
+<@x t="LB"/><#lt>${""}
+ <@x t="IB"/>${""}
+${""} <@x t="IC1"/><#rt>
+ <@x t="IC2"/><#rt>${""}
+${""}<@x t="C1"/><#rt>
+<@x t="C2"/><#rt>${""}
+ <@x t="ICS"/> <#rt>${""}
+<@x t="CS1"/> <#rt>${""}
+ <@x t="CS2"/> <#t>${""}
+ <@x t="C3"/><#t>
+ <@x t="C1"/><#t>
+<@x t="C2"/>${""}
+<#nt><@x t="B"/>
+<@x t="B"/><#nt>
+ <@x t="C1"/><#t>
+<@x t="CB"/>${""}
+<@x t="C1"/>${""}
+ <@x t="C2"/><#t>${""}
+ <@x t="ICB"/>${""}
+ ${""}<@x t="IC"/><#rt>
+ <@x t="ICB"/>${""}
+${""} <@x t="IC"/><#rt>
+ <@x t="CB"/>${""}<#lt>
+--
+ <#lt> IB
+ IC1<#rt>
+ <#assign x = 1> <#-- just a comment -->
+ C2<#t>
+ <#assign x = 1>
+ IB
+1<#t>
+ <#assign x = 1>
+2
+---
+<#t>1
+ <#t> 2
+ <#lt>3
+ 4
+ <#rt>5
+ 6
+---
+a
+ <#assign x = 1><#t>
+b<#t>
+c
+---
+ <#if true>
+ <#t>foo
+ </#if>
+---
+ <#if true><#-- just a comment -->
+ foo<#t>
+ </#if>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wsstripinheader_inc.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wsstripinheader_inc.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wsstripinheader_inc.ftl
new file mode 100644
index 0000000..03cbfbe
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wsstripinheader_inc.ftl
@@ -0,0 +1,22 @@
+<#ftl strip_whitespace="yes">
+<#--
+ 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.
+-->
+a
+<#assign x = 1>
+b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wstrip-in-header.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wstrip-in-header.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wstrip-in-header.ftl
new file mode 100644
index 0000000..0dce83c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/wstrip-in-header.ftl
@@ -0,0 +1,26 @@
+
+
+
+ <#ftl strip_whitespace="no">
+<#--
+ 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.
+-->
+a
+<#assign x = 1>
+b
+<#include "wsstripinheader_inc.ftl">
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-fragment.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-fragment.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-fragment.ftl
new file mode 100644
index 0000000..226215b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-fragment.ftl
@@ -0,0 +1,26 @@
+<#ftl ns_prefixes = {"n" : "http://x"}>
+<#--
+ 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.
+-->
+${node?node_name} = b
+${node?root?node_name} = @document
+${node['/']?node_name} = @document
+
+${node['n:c']} = C<>&"']]>
+
+${node?root.@@markup}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-lib.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
new file mode 100644
index 0000000..0f0bde2
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
@@ -0,0 +1,23 @@
+<#ftl ns_prefixes={ "n": "http://freemarker.org/test/bar", "D": "http://freemarker.org/test/namespace-test" }>
+<#--
+ 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.
+-->
+<#global libResult>//n:e: ${doc['//n:e']}, ${doc.root['n:e']}</#global>
+<#macro m>
+//n:e: ${doc['//n:e']}, ${doc.root['n:e']}
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-main.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-main.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-main.ftl
new file mode 100644
index 0000000..5b7ce24
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml-ns_prefix-scope-main.ftl
@@ -0,0 +1,36 @@
+<#ftl ns_prefixes={
+ "D": "http://freemarker.org/test/namespace-test",
+ "n": "http://freemarker.org/test/foo",
+ "bar": "http://freemarker.org/test/bar"
+}>
+<#--
+ 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.
+-->
+//e: ${doc['//D:e']}, ${doc.root.e}
+//n:e: ${doc['//n:e']}, ${doc.root['n:e']}
+//bar:e: ${doc['//bar:e']}, ${doc.root['bar:e']}
+
+Included:
+<#include "xml-ns_prefix-scope-lib.ftl">
+${libResult}
+<@m />
+
+Imported:
+<#import "xml-ns_prefix-scope-lib.ftl" as lib>
+${libResult}
+<@lib.m />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml.ftl
new file mode 100644
index 0000000..b85fc03
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xml.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<#-- test processing instructions -->
+<#global PIs = doc._content._ftype("p")>
+<#list PIs as pi>
+ ${pi}
+ ${pi["@target"]._text}
+ ${pi["@data"]._text}
+</#list>
+${PIs?size}
+<#global firstPi = PIs[0]>
+${firstPi._type}
+${firstPi["@customKey"]}
+${doc._registerNamespace("ns", "http://www.foo.com/ns1/")}
+${doc._descendant["ns:e11"]}
+${doc._descendant["ns:e12"]}
+<#global docRoot = doc["ns:root"]>
+${docRoot["ns:e1"]}
+${doc("//ns:e11")}
+${docRoot["ns:e1"]["@a1"]._name}
+${docRoot["ns:e1"]["@a2"]._text}
+${docRoot._children._parent._name}
+${docRoot._children._parent._unique._name}
+<#list doc._descendant as d>
+ ${d._name}
+</#list>
+<#list doc._descendant._ancestorOrSelf as d>
+ ${d._name}
+</#list>
+${docRoot["ns:e2"]["ns:e12"]._text}
+${docRoot["ns:e2"]["ns:e12"]._plaintext}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns1.ftl
new file mode 100644
index 0000000..8aa893e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns1.ftl
@@ -0,0 +1,53 @@
+<#ftl ns_prefixes = {"D" : "http://example.com/eBook"}>
+<#--
+ 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.
+-->
+
+${doc.@@markup}
+
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node.title></title>
+ </head>
+ <body>
+ <h1><#recurse .node.title></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node.title></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro title>
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns3.ftl
new file mode 100644
index 0000000..c84ec69
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns3.ftl
@@ -0,0 +1,70 @@
+<#ftl ns_prefixes = {"x" : "http://x", "y" : "http://y"}>
+<#--
+ 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.
+-->
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node["x:title"]></title>
+ </head>
+ <body>
+ <h1><#recurse .node["x:title"]></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro "x:chapter">
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro "x:para">
+ <p><#recurse>
+</#macro>
+
+<#macro "y:para">
+ <p><#recurse>
+</#macro>
+
+<#macro "x:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro "y:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns4.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns4.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns4.ftl
new file mode 100644
index 0000000..e97bfc0
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns4.ftl
@@ -0,0 +1,70 @@
+<#ftl ns_prefixes = {"x" : "http://x", "y" : "http://y"}>
+<#--
+ 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.
+-->
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node["x:title"]></title>
+ </head>
+ <body>
+ <h1><#recurse .node["x:title"]></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro 'x:chapter'>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro 'x:para'>
+ <p><#recurse>
+</#macro>
+
+<#macro 'y:para'>
+ <p><#recurse>
+</#macro>
+
+<#macro "x:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro "y:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns5.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns5.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns5.ftl
new file mode 100644
index 0000000..edc3b4a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/xmlns5.ftl
@@ -0,0 +1,28 @@
+<#ftl ns_prefixes = {"D": "http://y.com", "xx" : "http://x.com"}>
+<#--
+ 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.
+-->
+<#assign r = doc["N:root"]>
+${r["N:t1"][0]?default('-')} = No NS
+${r["xx:t2"][0]?default('-')} = x NS
+${r["t3"][0]?default('-')} = y NS
+${r["xx:t4"][0]?default('-')} = x NS
+${r["//t1"][0]?default('-')} = No NS
+${r["//t2"][0]?default('-')} = -
+${r["//t3"][0]?default('-')} = -
+${r["//t4"][0]?default('-')} = -
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/testcases.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/testcases.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/testcases.xml
new file mode 100644
index 0000000..2cfe290
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/testcases.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" ?>
+<!--
+ 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.
+-->
+
+<!DOCTYPE testCases [
+ <!ELEMENT testCases (setting?, testCase*)>
+ <!ELEMENT testCase (setting?)>
+ <!ATTLIST testCase
+ name CDATA #REQUIRED
+ template CDATA #IMPLIED
+ expected CDATA #IMPLIED
+ noOutput CDATA #IMPLIED
+ >
+ <!-- The default of `template` is "${name?keep_before('[#endTN]')}.ftl" -->
+ <!-- The default of `expected` is "${name}.txt" -->
+ <!-- The default of `noOutput` is false -->
+
+ <!ELEMENT setting EMPTY>
+ <!ATTLIST setting
+ auto_import CDATA #IMPLIED
+ source_encoding CDATA #IMPLIED
+ locale CDATA #IMPLIED
+ object_wrapper CDATA #IMPLIED
+ output_encoding CDATA #IMPLIED
+ output_dir CDATA #IMPLIED
+ new_builtin_class_resolver CDATA #IMPLIED
+ url_escaping_charset CDATA #IMPLIED
+ incompatible_improvements CDATA #IMPLIED
+ time_zone CDATA #IMPLIED
+ api_builtin_enabled CDATA #IMPLIED
+ >
+]>
+<!--
+Note that for the incompatible_improvements setting you can specify a list of versions, for example:
+<setting incompatible_improvements="min, 3.0.5, max" />
+-->
+
+<testCases>
+ <setting source_encoding="UTF-8" output_encoding="UTF-8" />
+
+ <testCase name="api-builtins" noOutput="true">
+ <setting api_builtin_enabled="true" />
+ </testCase>
+ <testCase name="arithmetic" />
+ <testCase name="assignments" noOutput="true" />
+ <testCase name="boolean" />
+ <testCase name="charset-in-header" />
+ <testCase name="comment" />
+ <testCase name="comparisons" />
+ <testCase name="compress" />
+ <testCase name="then-builtin" noOutput="true" />
+ <testCase name="dateformat-java" />
+ <testCase name="dateformat-iso-like" noOutput="true" />
+ <testCase name="dateformat-iso-bi" noOutput="true" />
+ <testCase name="dateparsing" noOutput="true" />
+ <testCase name="default"/>
+ <testCase name="default-object-wrapper">
+ <setting api_builtin_enabled="true" />
+ </testCase>
+ <testCase name="default-xmlns" />
+ <testCase name="encoding-builtins" />
+ <testCase name="escapes" />
+ <testCase name="hashliteral" />
+ <testCase name="identifier-non-ascii" />
+ <testCase name="identifier-escaping" />
+ <testCase name="import">
+ <setting auto_import="import_lib.ftl as my"/>
+ </testCase>
+ <testCase name="include" />
+ <testCase name="include2">
+ <setting source_encoding="utf-8" />
+ </testCase>
+ <testCase name="interpret"/>
+ <testCase name="iterators"/>
+ <testCase name="lastcharacter"/>
+ <testCase name="list[#endTN]-simpleTemplateModels" expected="list.txt">
+ <setting object_wrapper="org.apache.freemarker.test.templatesuite.models.SimpleMapAndCollectionObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list[#endTN]-collectionAdapter" expected="list.txt">
+ <setting object_wrapper="DefaultObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list2[#endTN]-simpleTemplateModels" expected="list2.txt">
+ <setting object_wrapper="org.apache.freemarker.test.templatesuite.models.SimpleMapAndCollectionObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list2[#endTN]-collectionAdapter" expected="list2.txt">
+ <setting object_wrapper="DefaultObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list3[#endTN]-simpleTemplateModels" expected="list3.txt">
+ <setting object_wrapper="org.apache.freemarker.test.templatesuite.models.SimpleMapAndCollectionObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list3[#endTN]-collectionAdapter" expected="list3.txt">
+ <setting object_wrapper="DefaultObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="list-bis" />
+ <testCase name="list-bis[#endTN]-collectionAdapter" expected="list-bis.txt">
+ <setting object_wrapper="DefaultObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="listhash" />
+ <testCase name="listhashliteral" />
+ <testCase name="listliteral" />
+ <testCase name="localization" >
+ <setting locale="en_AU"/>
+ </testCase>
+ <testCase name="loopvariable" />
+ <testCase name="macros"/>
+ <testCase name="macros2"/>
+ <testCase name="macros-return"/>
+ <testCase name="multimodels"/>
+ <testCase name="nested" />
+ <testCase name="newlines1" />
+ <testCase name="newlines2" />
+ <testCase name="noparse" />
+ <testCase name="number-format" />
+ <testCase name="number-literal" >
+ <setting locale="fr_FR"/>
+ </testCase>
+ <testCase name="numerical-cast" />
+ <testCase name="output-encoding1"/>
+ <testCase name="output-encoding2">
+ <setting output_encoding="UTF-16"/>
+ </testCase>
+ <testCase name="output-encoding3">
+ <setting output_encoding="ISO-8859-1" url_escaping_charset="UTF-16" />
+ </testCase>
+ <testCase name="precedence"/>
+ <testCase name="range" noOutput="true" />
+ <testCase name="recover" />
+ <testCase name="root" />
+ <testCase name="setting" noOutput="true" />
+ <testCase name="sequence-builtins[#endTN]-with-SimpleTemplateModel" expected="sequence-builtins.txt">
+ <setting object_wrapper="org.apache.freemarker.test.templatesuite.models.SimpleMapAndCollectionObjectWrapper(3.0.0)" />
+ </testCase>
+ <testCase name="sequence-builtins[#endTN]-with-DefaultObjectWrapper" expected="sequence-builtins.txt">
+ <setting object_wrapper="default"/>
+ </testCase>
+ <testCase name="sequence-builtins[#endTN]-with-DefaultObjectWrapper-collAdapters" expected="sequence-builtins.txt">
+ <setting object_wrapper="DefaultObjectWrapper(3.0.0)"/>
+ </testCase>
+ <testCase name="simplehash-char-key" noOutput="true" />
+ <testCase name="existence-operators" noOutput="true" />
+ <testCase name="string-builtins1" />
+ <testCase name="string-builtins2" />
+ <testCase name="string-builtins3" noOutput="true" />
+ <testCase name="string-builtins-regexps" />
+ <testCase name="string-builtins-regexps-matches" />
+ <testCase name="stringbimethods" />
+ <testCase name="stringliteral"/>
+ <testCase name="if" />
+ <testCase name="switch" />
+ <testCase name="switch-builtin" noOutput="true" />
+ <testCase name="transforms"/>
+ <testCase name="type-builtins" />
+ <testCase name="date-type-builtins" noOutput="true" />
+ <testCase name="url" noOutput="true" />
+ <testCase name="var-layers"/>
+ <testCase name="variables"/>
+ <testCase name="whitespace-trim"/>
+ <testCase name="wstrip-in-header"/>
+ <testCase name="xml-fragment" />
+ <testCase name="xmlns1" />
+ <testCase name="xmlns2" template="xmlns1.ftl" expected="xmlns1.txt" />
+ <testCase name="xmlns3" />
+ <testCase name="xmlns4" />
+ <testCase name="xmlns5" />
+ <testCase name="xml-ns_prefix-scope" template="xml-ns_prefix-scope-main.ftl" />
+ <testCase name="hashconcat"/>
+ <testCase name="new-defaultresolver" />
+ <testCase name="new-unrestricted" template="new-defaultresolver.ftl" expected="new-defaultresolver.txt">
+ <setting new_builtin_class_resolver="unrestricted"/>
+ </testCase>
+ <testCase name="new-allowsnothing" template="new-defaultresolver.ftl">
+ <setting new_builtin_class_resolver="allows_nothing"/>
+ </testCase>
+ <testCase name="new-optin">
+ <setting new_builtin_class_resolver="
+ allowed_classes: org.apache.freemarker.test.templatesuite.models.NewTestModel,
+ trusted_templates: subdir/new-optin.ftl, subdir/subsub/*"
+ />
+ </testCase>
+ <testCase name="specialvars">
+ <setting locale="en_US" output_encoding="utf-8" url_escaping_charset="iso-8859-1"/>
+ </testCase>
+ <testCase name="number-to-date" />
+ <testCase name="varargs" />
+ <testCase name="boolean-formatting" />
+ <testCase name="number-math-builtins" noOutput="true" />
+ <testCase name="string-builtin-coercion" noOutput="true" />
+
+ <testCase name="overloaded-methods[#endTN]-inc-dow" noOutput="true">
+ <setting object_wrapper="org.apache.freemarker.core.model.impl.DefaultObjectWrapperInc"/>
+ </testCase>
+ <testCase name="overloaded-methods[#endTN]-desc-dow" noOutput="true">
+ <setting object_wrapper="org.apache.freemarker.core.model.impl.DefaultObjectWrapperDesc"/>
+ </testCase>
+</testCases>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/README.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/README.txt b/freemarker-core/src/test/README.txt
new file mode 100644
index 0000000..fe68269
--- /dev/null
+++ b/freemarker-core/src/test/README.txt
@@ -0,0 +1,7 @@
+The tests were moved to the freemarker-core-test and freemarker-core-test-java8 projects.
+(This was necessary to avoid dependency loops. Some utility classes that are useful for testing
+the core are also useful for testing the other modules. This those classes had to be moved into
+a separate module, freemarker-test-utils, which however depends on freemarker-core to provide
+template testing facilities and such. Hence, freemarker-core can't depend on freemarker-test-utils,
+yet the classes in it are needed for testing freemarker-core, thus, yet another project had to be
+added.)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
deleted file mode 100644
index 10d63b3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Map;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class ASTBasedErrorMessagesTest extends TemplateTest {
-
- @Test
- public void testInvalidRefBasic() {
- assertErrorContains("${foo}", "foo", "specify a default");
- assertErrorContains("${map[foo]}", "foo", "\\!map[", "specify a default");
- }
-
- @Test
- public void testInvalidRefDollar() {
- assertErrorContains("${$x}", "$x", "must not start with \"$\"", "specify a default");
- assertErrorContains("${map.$x}", "map.$x", "must not start with \"$\"", "specify a default");
- }
-
- @Test
- public void testInvalidRefAfterDot() {
- assertErrorContains("${map.foo.bar}", "map.foo", "\\!foo.bar", "after the last dot", "specify a default");
- }
-
- @Test
- public void testInvalidRefInSquareBrackets() {
- assertErrorContains("${map['foo']}", "map", "final [] step", "specify a default");
- }
-
- @Test
- public void testInvalidRefSize() {
- assertErrorContains("${map.size()}", "map.size", "?size", "specify a default");
- assertErrorContains("${map.length()}", "map.length", "?length", "specify a default");
- }
-
- @Override
- protected Object createDataModel() {
- Map<String, Object> dataModel = createCommonTestValuesDataModel();
- dataModel.put("overloads", new Overloads());
- return dataModel;
- }
-
- public static class Overloads {
-
- @SuppressWarnings("unused")
- public void m(String s) {}
-
- @SuppressWarnings("unused")
- public void m(int i) {}
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ASTPrinter.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTPrinter.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ASTPrinter.java
deleted file mode 100644
index 3518b29..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTPrinter.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * 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.core;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.nio.ByteBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.StandardCharsets;
-import java.util.Enumeration;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util.FTLUtil;
-import org.apache.freemarker.core.util._ClassUtil;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-
-/**
- * Static methods and command-line tool for printing the AST of a template.
- */
-public class ASTPrinter {
-
- private final Configuration cfg;
- private int successfulCounter;
- private int failedCounter;
-
- static public void main(String[] args) throws IOException {
- if (args.length == 0) {
- usage();
- System.exit(-1);
- }
-
- ASTPrinter astp = new ASTPrinter();
- if (args[0].equalsIgnoreCase("-r")) {
- astp.mainRecursive(args);
- } else {
- astp.mainSingleTemplate(args);
- }
- }
-
- private ASTPrinter() {
- cfg = new TestConfigurationBuilder(Configuration.VERSION_3_0_0).build();
- }
-
- private void mainSingleTemplate(String[] args) throws IOException, FileNotFoundException {
- final String templateFileName;
- final String templateContent;
- if (args[0].startsWith("ftl:")) {
- templateFileName = null;
- templateContent = args[0];
- } else {
- templateFileName = args[0];
- templateContent = null;
- }
-
- Template t = new Template(
- templateFileName,
- templateFileName == null ? new StringReader(templateContent) : new FileReader(templateFileName),
- cfg);
-
- p(getASTAsString(t));
- }
-
- private void mainRecursive(String[] args) throws IOException {
- if (args.length != 4) {
- p("Number of arguments must be 4, but was: " + args.length);
- usage();
- System.exit(-1);
- }
-
- final String srcDirPath = args[1].trim();
- File srcDir = new File(srcDirPath);
- if (!srcDir.isDirectory()) {
- p("This should be an existing directory: " + srcDirPath);
- System.exit(-1);
- }
-
- Pattern fnPattern;
- try {
- fnPattern = Pattern.compile(args[2]);
- } catch (PatternSyntaxException e) {
- p(_StringUtil.jQuote(args[2]) + " is not a valid regular expression");
- System.exit(-1);
- return;
- }
-
- final String dstDirPath = args[3].trim();
- File dstDir = new File(dstDirPath);
- if (!dstDir.isDirectory()) {
- p("This should be an existing directory: " + dstDirPath);
- System.exit(-1);
- }
-
- long startTime = System.currentTimeMillis();
- recurse(srcDir, fnPattern, dstDir);
- long endTime = System.currentTimeMillis();
-
- p("Templates successfully processed " + successfulCounter + ", failed " + failedCounter
- + ". Time taken: " + (endTime - startTime) / 1000.0 + " s");
- }
-
- private void recurse(File srcDir, Pattern fnPattern, File dstDir) throws IOException {
- File[] files = srcDir.listFiles();
- if (files == null) {
- throw new IOException("Failed to kust directory: " + srcDir);
- }
- for (File file : files) {
- if (file.isDirectory()) {
- recurse(file, fnPattern, new File(dstDir, file.getName()));
- } else {
- if (fnPattern.matcher(file.getName()).matches()) {
- File dstFile = new File(dstDir, file.getName());
- String res;
- try {
- Template t = new Template(file.getPath().replace('\\', '/'), loadIntoString(file), cfg);
- res = getASTAsString(t);
- successfulCounter++;
- } catch (ParseException e) {
- res = "<<<FAILED>>>\n" + e.getMessage();
- failedCounter++;
- p("");
- p("-------------------------failed-------------------------");
- p("Error message was saved into: " + dstFile.getAbsolutePath());
- p("");
- p(e.getMessage());
- }
- save(res, dstFile);
- }
- }
- }
- }
-
- private String loadIntoString(File file) throws IOException {
- long ln = file.length();
- if (ln < 0) {
- throw new IOException("Failed to get the length of " + file);
- }
- byte[] buffer = new byte[(int) ln];
- InputStream in = new FileInputStream(file);
- try {
- int offset = 0;
- int bytesRead;
- while (offset < buffer.length) {
- bytesRead = in.read(buffer, offset, buffer.length - offset);
- if (bytesRead == -1) {
- throw new IOException("Unexpected end of file: " + file);
- }
- offset += bytesRead;
- }
- } finally {
- in.close();
- }
-
- try {
- return decode(buffer, StandardCharsets.UTF_8);
- } catch (CharacterCodingException e) {
- return decode(buffer, StandardCharsets.ISO_8859_1);
- }
- }
-
- private String decode(byte[] buffer, Charset charset) throws CharacterCodingException {
- return charset.newDecoder()
- .onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT)
- .decode(ByteBuffer.wrap(buffer)).toString();
- }
-
- private void save(String astStr, File file) throws IOException {
- File parentDir = file.getParentFile();
- if (!parentDir.isDirectory() && !parentDir.mkdirs()) {
- throw new IOException("Failed to invoke parent directory: " + parentDir);
- }
-
- Writer w = new BufferedWriter(new FileWriter(file));
- try {
- w.write(astStr);
- } finally {
- w.close();
- }
- }
-
- private static void usage() {
- p("Prints template Abstract Syntax Tree (AST) as plain text.");
- p("Usage:");
- p(" java org.apache.freemarker.core.PrintAST <templateFile>");
- p(" java org.apache.freemarker.core.PrintAST ftl:<templateSource>");
- p(" java org.apache.freemarker.core.PrintAST -r <src-directory> <regexp> <dst-directory>");
- }
-
- private static final String INDENTATION = " ";
-
- public static String getASTAsString(String ftl) throws IOException {
- return getASTAsString(ftl, (Options) null);
- }
-
- public static String getASTAsString(String ftl, Options opts) throws IOException {
- return getASTAsString(null, ftl, opts);
- }
-
- public static String getASTAsString(String templateName, String ftl) throws IOException {
- return getASTAsString(templateName, ftl, null);
- }
-
- public static String getASTAsString(String templateName, String ftl, Options opts) throws IOException {
- Template t = new Template(templateName, ftl, new TestConfigurationBuilder().build());
- return getASTAsString(t, opts);
- }
-
- public static String getASTAsString(Template t) throws IOException {
- return getASTAsString(t, null);
- }
-
- public static String getASTAsString(Template t, Options opts) throws IOException {
- validateAST(t);
-
- StringWriter out = new StringWriter();
- printNode(t.getRootASTNode(), "", null, opts != null ? opts : Options.DEFAULT_INSTANCE, out);
- return out.toString();
- }
-
- public static void validateAST(Template t) throws InvalidASTException {
- final ASTElement node = t.getRootASTNode();
- if (node.getParent() != null) {
- throw new InvalidASTException("Root node parent must be null."
- + "\nRoot node: " + node.dump(false)
- + "\nParent"
- + ": " + node.getParent().getClass() + ", " + node.getParent().dump(false));
- }
- validateAST(node);
- }
-
- private static void validateAST(ASTElement te) {
- int childCount = te.getChildCount();
- for (int i = 0; i < childCount; i++) {
- ASTElement child = te.getChild(i);
- ASTElement parentElement = child.getParent();
- // As ASTImplicitParent.accept does nothing but returns its children, it's optimized out in the final
- // AST tree. While it will be present as a child, the parent element also will have children
- // that contains the children of the ASTImplicitParent directly.
- if (parentElement instanceof ASTImplicitParent && parentElement.getParent() != null) {
- parentElement = parentElement.getParent();
- }
- if (parentElement != te) {
- throw new InvalidASTException("Wrong parent node."
- + "\nNode: " + child.dump(false)
- + "\nExpected parent: " + te.dump(false)
- + "\nActual parent: " + parentElement.dump(false));
- }
- if (child.getIndex() != i) {
- throw new InvalidASTException("Wrong node index."
- + "\nNode: " + child.dump(false)
- + "\nExpected index: " + i
- + "\nActual index: " + child.getIndex());
- }
- }
- if (te instanceof ASTImplicitParent && te.getChildCount() < 2) {
- throw new InvalidASTException("Mixed content with child count less than 2 should removed by optimizatoin, "
- + "but found one with " + te.getChildCount() + " child(ren).");
- }
- ASTElement[] children = te.getChildBuffer();
- if (children != null) {
- if (childCount == 0) {
- throw new InvalidASTException(
- "Children must be null when childCount is 0."
- + "\nNode: " + te.dump(false));
- }
- for (int i = 0; i < te.getChildCount(); i++) {
- if (children[i] == null) {
- throw new InvalidASTException(
- "Child can't be null at index " + i
- + "\nNode: " + te.dump(false));
- }
- }
- for (int i = te.getChildCount(); i < children.length; i++) {
- if (children[i] != null) {
- throw new InvalidASTException(
- "Children can't be non-null at index " + i
- + "\nNode: " + te.dump(false));
- }
- }
- } else {
- if (childCount != 0) {
- throw new InvalidASTException(
- "Children mustn't be null when child count isn't 0."
- + "\nNode: " + te.dump(false));
- }
- }
- }
-
- private static void printNode(Object node, String ind, ParameterRole paramRole, Options opts, Writer out) throws IOException {
- if (node instanceof ASTNode) {
- ASTNode tObj = (ASTNode) node;
-
- printNodeLineStart(paramRole, ind, out);
- out.write(tObj.getNodeTypeSymbol());
- printNodeLineEnd(node, out, opts);
-
- if (opts.getShowConstantValue() && node instanceof ASTExpression) {
- TemplateModel tm = ((ASTExpression) node).constantValue;
- if (tm != null) {
- out.write(INDENTATION);
- out.write(ind);
- out.write("= const ");
- out.write(FTLUtil.getTypeDescription(tm));
- out.write(' ');
- out.write(tm.toString());
- out.write('\n');
- }
- }
-
- int paramCnt = tObj.getParameterCount();
- for (int i = 0; i < paramCnt; i++) {
- ParameterRole role = tObj.getParameterRole(i);
- if (role == null) throw new NullPointerException("parameter role");
- Object value = tObj.getParameterValue(i);
- printNode(value, ind + INDENTATION, role, opts, out);
- }
- if (tObj instanceof ASTElement) {
- Enumeration enu = ((ASTElement) tObj).children();
- while (enu.hasMoreElements()) {
- printNode(enu.nextElement(), INDENTATION + ind, null, opts, out);
- }
- }
- } else {
- printNodeLineStart(paramRole, ind, out);
- out.write(_StringUtil.jQuote(node));
- printNodeLineEnd(node, out, opts);
- }
- }
-
- protected static void printNodeLineEnd(Object node, Writer out, Options opts) throws IOException {
- boolean commentStared = false;
- if (opts.getShowJavaClass()) {
- out.write(" // ");
- commentStared = true;
- out.write(_ClassUtil.getShortClassNameOfObject(node, true));
- }
- if (opts.getShowLocation() && node instanceof ASTNode) {
- if (!commentStared) {
- out.write(" // ");
- commentStared = true;
- } else {
- out.write("; ");
- }
- ASTNode tObj = (ASTNode) node;
- out.write("Location " + tObj.beginLine + ":" + tObj.beginColumn + "-" + tObj.endLine + ":" + tObj.endColumn);
- }
- out.write('\n');
- }
-
- private static void printNodeLineStart(ParameterRole paramRole, String ind, Writer out) throws IOException {
- out.write(ind);
- if (paramRole != null) {
- out.write("- ");
- out.write(paramRole.toString());
- out.write(": ");
- }
- }
-
- public static class Options {
-
- private final static Options DEFAULT_INSTANCE = new Options();
-
- private boolean showJavaClass = true;
- private boolean showConstantValue = false;
- private boolean showLocation = false;
-
- public boolean getShowJavaClass() {
- return showJavaClass;
- }
-
- public void setShowJavaClass(boolean showJavaClass) {
- this.showJavaClass = showJavaClass;
- }
-
- public boolean getShowConstantValue() {
- return showConstantValue;
- }
-
- public void setShowConstantValue(boolean showConstantValue) {
- this.showConstantValue = showConstantValue;
- }
-
- public boolean getShowLocation() {
- return showLocation;
- }
-
- public void setShowLocation(boolean showLocation) {
- this.showLocation = showLocation;
- }
-
- }
-
- private static void p(Object obj) {
- System.out.println(obj);
- }
-
- public static class InvalidASTException extends RuntimeException {
-
- public InvalidASTException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public InvalidASTException(String message) {
- super(message);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ASTTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ASTTest.java
deleted file mode 100644
index 96f173a..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ASTTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.core;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import org.apache.freemarker.core.ASTPrinter.Options;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.util.FileTestCase;
-import org.apache.freemarker.test.TestUtil;
-
-public class ASTTest extends FileTestCase {
-
- public ASTTest(String name) {
- super(name);
- }
-
- public void test1() throws Exception {
- testAST("ast-1");
- }
-
- public void testRange() throws Exception {
- testAST("ast-range");
- }
-
- public void testAssignments() throws Exception {
- testAST("ast-assignments");
- }
-
- public void testBuiltins() throws Exception {
- testAST("ast-builtins");
- }
-
- public void testStringLiteralInterpolation() throws Exception {
- testAST("ast-strlitinterpolation");
- }
-
- public void testWhitespaceStripping() throws Exception {
- testAST("ast-whitespacestripping");
- }
-
- public void testMixedContentSimplifications() throws Exception {
- testAST("ast-mixedcontentsimplifications");
- }
-
- public void testMultipleIgnoredChildren() throws Exception {
- testAST("ast-multipleignoredchildren");
- }
-
- public void testNestedIgnoredChildren() throws Exception {
- testAST("ast-nestedignoredchildren");
- }
-
- public void testLocations() throws Exception {
- testASTWithLocations("ast-locations");
- }
-
- private void testAST(String testName) throws FileNotFoundException, IOException {
- testAST(testName, null);
- }
-
- private void testASTWithLocations(String testName) throws FileNotFoundException, IOException {
- Options options = new Options();
- options.setShowLocation(true);
- testAST(testName, options);
- }
-
- private void testAST(String testName, Options ops) throws FileNotFoundException, IOException {
- final String templateName = testName + ".ftl";
- assertExpectedFileEqualsString(
- testName + ".ast",
- ASTPrinter.getASTAsString(templateName,
- TestUtil.removeFTLCopyrightComment(
- normalizeLineBreaks(
- loadTestTextResource(
- getTestFileURL(
- getExpectedContentFileDirectoryResourcePath(), templateName)))
- ), ops));
- }
-
- private String normalizeLineBreaks(final String s) throws FileNotFoundException, IOException {
- return _StringUtil.replace(s, "\r\n", "\n").replace('\r', '\n');
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
deleted file mode 100644
index 57e40fa..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class ActualNamingConvetionTest {
-
- @Test
- public void testUndetectable() throws IOException {
- final String ftl = "<#if true>${x?size}</#if>";
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
- }
-
- @Test
- public void testLegacyDetected() throws IOException {
- final String ftl = "${x?upper_case}";
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- }
-
- @Test
- public void testCamelCaseDetected() throws IOException {
- final String ftl = "${x?upperCase}";
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
- assertEquals(getActualNamingConvention(ftl,
- ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
- }
-
- private int getActualNamingConvention(String ftl, int namingConvention) throws IOException {
- return new Template(null, ftl,
- new TestConfigurationBuilder().namingConvention(namingConvention).build())
- .getActualNamingConvention();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
deleted file mode 100644
index 88f0646..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.core.ParsingConfiguration.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class ActualTagSyntaxTest {
-
- @Test
- public void testWithFtlHeader() throws IOException {
- testWithFtlHeader(AUTO_DETECT_TAG_SYNTAX);
- testWithFtlHeader(ANGLE_BRACKET_TAG_SYNTAX);
- testWithFtlHeader(SQUARE_BRACKET_TAG_SYNTAX);
- }
-
- private void testWithFtlHeader(int cfgTagSyntax) throws IOException {
- assertEquals(getActualTagSyntax("[#ftl]foo", cfgTagSyntax), SQUARE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("<#ftl>foo", cfgTagSyntax), ANGLE_BRACKET_TAG_SYNTAX);
- }
-
- @Test
- public void testUndecidable() throws IOException {
- assertEquals(getActualTagSyntax("foo", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
- }
-
- @Test
- public void testDecidableWithoutFtlHeader() throws IOException {
- assertEquals(getActualTagSyntax("foo<#if true></#if>", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo<#if true></#if>", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo<#if true></#if>", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
-
- assertEquals(getActualTagSyntax("foo[#if true][/#if]", AUTO_DETECT_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo[#if true][/#if]", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
- assertEquals(getActualTagSyntax("foo[#if true][/#if]", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
- }
-
- private int getActualTagSyntax(String ftl, int cfgTagSyntax) throws IOException {
- return new Template(
- null, ftl,
- new TestConfigurationBuilder().tagSyntax(cfgTagSyntax).build()).getActualTagSyntax();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
deleted file mode 100644
index 61ba02b..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class BreakPlacementTest extends TemplateTest {
-
- private static final String BREAK_NESTING_ERROR_MESSAGE_PART = "<#break> must be nested";
-
- @Test
- public void testValidPlacements() throws IOException, TemplateException {
- assertOutput("<#assign x = 1><#switch x><#case 1>one<#break><#case 2>two</#switch>", "one");
- assertOutput("<#list 1..2 as x>${x}<#break></#list>", "1");
- assertOutput("<#list 1..2>[<#items as x>${x}<#break></#items>]</#list>", "[1]");
- assertOutput("<#list 1..2 as x>${x}<#list 1..3>B<#break>E<#items as y></#items></#list>E</#list>.", "1B.");
- assertOutput("<#list 1..2 as x>${x}<#list 3..4 as x>${x}<#break></#list>;</#list>", "13;23;");
- assertOutput("<#list [1..2, 3..4, [], 5..6] as xs>[<#list xs as x>${x}<#else><#break></#list>]</#list>.",
- "[12][34][.");
- assertOutput("<#list [1..2, 3..4, [], 5..6] as xs>"
- + "<#list xs>[<#items as x>${x}</#items>]<#else><#break></#list>"
- + "</#list>.",
- "[12][34].");
- }
-
- @Test
- public void testInvalidPlacements() throws IOException, TemplateException {
- assertErrorContains("<#break>", BREAK_NESTING_ERROR_MESSAGE_PART);
- assertErrorContains("<#list 1..2 as x>${x}</#list><#break>", BREAK_NESTING_ERROR_MESSAGE_PART);
- assertErrorContains("<#if false><#break></#if>", BREAK_NESTING_ERROR_MESSAGE_PART);
- assertErrorContains("<#list xs><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
- assertErrorContains("<#list 1..2 as x>${x}<#else><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
- assertErrorContains("<#list 1..2 as x>${x}<#macro m><#break></#macro></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
- }
-
-}
[02/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
deleted file mode 100644
index e251238..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- */
-
-Non-empty maps:
-
- Map:
-
- [
- k1 = v1
- 2 = v2
- k3 = v3
- null = v4
- Y = v5
- N = null
- ]
-
- [
- k1 = v1; // @0=@0; odd=odd; Y=Y
- 2 = v2; // @1=@1; even=even; Y=Y
- k3 = v3; // @2=@2; odd=odd; Y=Y
- null = v4; // @3=@3; even=even; Y=Y
- Y = v5; // @4=@4; odd=odd; Y=Y
- N = null // @5=@5; even=even; N=N
- ]
-
- {
- [
- k1 = v1; // @0=@0; odd=odd; Y=Y
- 2 = v2; // @1=@1; even=even; Y=Y
- k3 = v3; // @2=@2; odd=odd; Y=Y
- null = v4; // @3=@3; even=even; Y=Y
- Y = v5; // @4=@4; odd=odd; Y=Y
- N = null // @5=@5; even=even; N=N
- ]
- }
-
- Map:
-
- [
- k1 = v1
- 2 = v2
- k3 = v3
- null = v4
- Y = v5
- N = null
- ]
-
- [
- k1 = v1; // @0=@0; odd=odd; Y=Y
- 2 = v2; // @1=@1; even=even; Y=Y
- k3 = v3; // @2=@2; odd=odd; Y=Y
- null = v4; // @3=@3; even=even; Y=Y
- Y = v5; // @4=@4; odd=odd; Y=Y
- N = null // @5=@5; even=even; N=N
- ]
-
- {
- [
- k1 = v1; // @0=@0; odd=odd; Y=Y
- 2 = v2; // @1=@1; even=even; Y=Y
- k3 = v3; // @2=@2; odd=odd; Y=Y
- null = v4; // @3=@3; even=even; Y=Y
- Y = v5; // @4=@4; odd=odd; Y=Y
- N = null // @5=@5; even=even; N=N
- ]
- }
-
- Map:
-
- [
- k1 = 11
- k2 = 22
- ]
-
- [
- k1 = 11; // @0=@0; odd=odd; Y=Y
- k2 = 22 // @1=@1; even=even; N=N
- ]
-
- {
- [
- k1 = 11; // @0=@0; odd=odd; Y=Y
- k2 = 22 // @1=@1; even=even; N=N
- ]
- }
-
-
-Empty maps:
-
- Map:
-
- [
- ]
-
- [
- Empty
- ]
-
- {
- Empty
- }
-
- Map:
-
- [
- ]
-
- [
- Empty
- ]
-
- {
- Empty
- }
-
- Map:
-
- [
- ]
-
- [
- Empty
- ]
-
- {
- Empty
- }
-
-
- a @ 0, 1
- aa = 11 @ 0 // inside a @ 0, 1
- a @ 0, 1
- --
- b @ 1, 2
- ba = 21 @ 0 // inside b @ 1, 2
- bb = 22 @ 1 // inside b @ 1, 2
- b @ 1, 2
- --
- c @ 2, 0
- c @ 2, 0
- --
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
deleted file mode 100644
index 937f0ea..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
- KVPs:
- a = 3
- b = 2
-
- Keys:
- a
- b
-
- Values:
- 3
- 2
-
- KVPs:
-
- Keys:
-
- Values:
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
deleted file mode 100644
index 2048ac5..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: List Literal Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Now perform a list assignment:</p>
-
-
-The list contains 5 items.
-
-<p>test1</p>
-<p>test23</p>
-<p>test45</p>
-<p>Hello, world!</p>
-<p>hello</p>
-
-<p>Now update the assignment and repeat:</p>
-
-
-<p>test1</p>
-<p>test23</p>
-<p>test45</p>
-<p>Hello, world!</p>
-<p>hello</p>
-
-<p>Now reassign the list and repeat:</p>
-
-
-<p>bar</p>
-<p>Temporary</p>
-<p>test1</p>
-<p>test23</p>
-
-<p>Silly, but necessary tests, for one and zero element lists:</p>
-
-
-<p>Hello, world</p>
-
-<p>Zero item test:</p>
-
-
-
-<p>Dumb test for number literals -- these weren't working as expected:</p>
-
-
-<p>1</p>
-<p>2</p>
-<p>3</p>
-<p>5</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
deleted file mode 100644
index bd3c87d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Localization Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>G'day, mate!</p>
-
-</body>
-</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
deleted file mode 100644
index 4fa6b2a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Logging Test</title>
-</head>
-<body>
-
-A simple test follows:
-
-ERROR [org.apache.freemarker.core.Template]: message is not a TemplateHashModel, it's a freemarker.template.SimpleScalar.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
deleted file mode 100644
index 25c20ac..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
----
- 2
- - L1 1
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
- - L1 2
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
- - L1 3
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
-*
- 1
- - L1 1
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
- - L1 2
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
- - L1 3
- - L2 1: 1; 2; 3;
- - L2 2: 1; 2; 3;
-*
-*
----
- 1 0.5
- 2 1
- 3 1.5
- 4 2 Last!
-123.4
----
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
deleted file mode 100644
index 5aa47ff..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-m{
-m{
-m{
-b{
-m:b{
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
deleted file mode 100644
index 680a08e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Function Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Now perform function tests:</p>
-
-
-<p>Function is defined, now let's call it:</p>
-
- <a href="/home.html">
- <img src="/images/home.png" border="0" alt="Home">
- </a>
- Kilroy was here.
-
-<p>Again, but with different parameters:</p>
-
- <a href="/about.html">
- <img src="/image/about-us.jpeg" border="0" alt="About Us">
- </a>
- Kilroy was here.
-
- Good.
-
-<p>A recursive function call:</p>
-
-
- 0
- 1
- 2
- 3
-
-<p>Test "catch-all" macro parameter:</p>
-
-
-foo=a baz=[]
-foo=a baz=[bar=b]
-foo=a baz=[bar=b, baz=c]
-
-
-Hello World! Today is Monday.
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
deleted file mode 100644
index 1b4e007..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.
- */
-1 1
-2 2
-4
-m3 with d="4" Failed!
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
deleted file mode 100644
index 54ec68d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Test of Multiple Model implementations</title>
-</head>
-<body>
-
-<p>Let's begin with a simple model:</p>
-<p>Hello, world!</p>
-
-<p>Cool, now get into the first model. This implements a scalar, list, and
-hash as a single class. Let's try some tests...</p>
-
-<p>MultiModel1 as a string!</p>
-
-<p>Now as a list...</p>
-
-Model1 value: 0<br />
-Model1 value: 1<br />
-Model1 value: 2<br />
-Model1 value: 3<br />
-Model1 value: 4<br />
-Model1 value: 5<br />
-Model1 value: 6<br />
-Model1 value: 7<br />
-Model1 value: 8<br />
-Model1 value: 9<br />
-Model3 is alive!<br />
-
-<p>Index into a list...</p>
-<p>Model1 value: 1</p>
-<p>List size is: Nasty!</p>
-<p>List size is: Nasty!</p>
-
-<p>Now, again, as a hash. First using dot notation, then using [] notation:</p>
-
-<p>Selftest of a hash from MultiModel1</p>
-<p>Selftest of a hash from MultiModel1</p>
-
-<p>Now for the tricky stuff... use a model to index into another model...</p>
-<p>selftest</p>
-<p>Selftest of a hash from MultiModel1</p>
-<p>self</p>
-<p>Selftest of a hash from MultiModel1</p>
-
-<p>Same thing, this time a List index...</p>
-<p>0</p>
-<p>Model1 value: 0</p>
-<p>Model1 value: 1</p>
-
-<p>Now, do the same recursively...</p>
-<p>MultiModel1 as a string!</p>
-<p>Model2 is alive!</p>
-<p>Arguments are:<br />test<br /></p>
-<p>Arguments are:<br />MultiModel1 as a string!<br />Selftest of a hash from MultiModel1<br />Hello, world!<br /></p>
-
-<p>Does this really not work?</p>
-<p>Model3 is alive!</p>
-<p>Selftest from MultiModel3!</p>
-<p>Hello world from MultiModel3!</p>
-
-<p>(Again, with Hashes)</p>
-<p>Model3 is alive!</p>
-<p>Selftest from MultiModel3!</p>
-
-<p>Model3 is alive!</p>
-<p>Selftest from MultiModel3!</p>
-<p>Selftest from MultiModel3!</p>
-
-<p>As I suspected! (Manual on Expressions needs updating.)</p>
-
-<p>Second test on list size</p>
-<p>Key size, not the listSize method.</p>
-<p>Key size, not the listSize method.</p>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
deleted file mode 100644
index bcfb104..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
- test 3/1: undefined undefined undefined
- test 3/2: undefined undefined undefined
- test 3/3: undefined undefined undefined
-
- test 3/1: Y X Count 1
- test 3/2: Y X Count 2
- test 3/3: Y X Count 3
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
deleted file mode 100644
index b8384c7..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-fails
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
deleted file mode 100644
index 35e7a3e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-works
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
deleted file mode 100644
index 9d8e883..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-works
-fails
-
-works
-works
-
-works
-fails
-
-works
-fails
-
-works
-works
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
deleted file mode 100644
index bc58731..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Newlines Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-</body>
-</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
deleted file mode 100644
index c131421..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Newlines the Second Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>Hello, world!
-</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
deleted file mode 100644
index 5e8486c..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: NoParse Test</title>
-</head>
-<body>
-
-A simple test follows:
-
-${message}
-
-A more rigorous test, showing that we're not faking it:
-
-${message@#$%&}
-
- <p>Message exists!
- ...and even generates output!
- <#if message>
- Nested statements are ok, too.
- </#if>
- </p>
-
-Here's another edge case, this time, trying to output a <noparse>
-inside another <noparse>
-
-
-This is what the noparse instruction looks like:
-
-<#noparse>This part of the template wont be parsed by the
-FreeMarker parser. Instead, it will be treated as verbatim text information,
-and output as such.</#noparse>
-
-The rest of the template appears here.
-
-Simple.
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
deleted file mode 100644
index a6f8475..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-1
-1
-1 234 567,89
-1234567.886
-1,00
-1
-1234567,89
-1234567.886
-1
-1
-1.000000000000001
-0.0000000000000001
--0.0000000000000001
-1
-0.0000000000000001
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
deleted file mode 100644
index b80bc85..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Number Literal Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Now perform a number assignment:</p>
-
-1,3
-
-
-My number is: 1,8
-My float is: 1.800000
-The int part is: 1
-
-
-1.83
-
-<p>Now use numbers in assignment</p>
-
-6
-
-8
-
-<p>Try numbers in tests</p>
-
-MyMessage is not 152, its: 8.
-
-<if (mymessage > 5)>
- MyMessage is greater than five.
-</if
-
- MyMessage is: 8.
-
-<p>Now for numbers in dynamic keys:</p>
-
-
-one
-three
-
-<p>Numbers in hashes:</p>
-
-twelve
-twelve
-twelve
-
-
-<p>Numbers in method calls:</p>
-
-Single argument value is: 1
-Single argument value is: 1
-Single argument value is: 12
-Single argument value is: 3
-Single argument value is: 3
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
deleted file mode 100644
index bc8a10e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
-2011-05-16 == 2011-05-16
-19:47:55.54Z == 19:47:55.54Z
-
-2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
-2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
-2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
-2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
-1970-01-01T00:00:01Z == 1970-01-01T00:00:01Z
-1970-01-01T00:00:01Z == 1970-01-01T00:00:01Z
-1970-01-01T00:00:00Z == 1970-01-01T00:00:00Z
-
-failed
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
deleted file mode 100644
index 3bf6cd0..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * 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.
- */
-
-?int:
- 0?int=0
- 1?int=1
- -1?int=-1
- 0.5?int=0
- 1.5?int=1
- -0.5?int=0
- -1.5?int=-1
- 0.25?int=0
- -0.25?int=0
- 1.75?int=1
- -1.75?int=-1
- 1.01?int=1
- -1.01?int=-1
- 0.01?int=0
- -0.01?int=0
- 127?int=127
- 128?int=128
- -127?int=-127
- -128?int=-128
- 32767?int=32767
- 32768?int=32768
- -32767?int=-32767
- -32768?int=-32768
- 2147483647?int=2147483647
- 2147483648?int=-2147483648
- -2147483647?int=-2147483647
- -2147483648?int=-2147483648
- 4294967295?int=-1
- 4294967296?int=0
- -4294967295?int=1
- -4294967296?int=0
- 2147483647.1?int=2147483647
- 2147483648.1?int=-2147483648
- -2147483647.1?int=-2147483647
- -2147483648.1?int=-2147483648
- 4294967295.1?int=-1
- 4294967296.1?int=0
- -4294967295.1?int=1
- -4294967296.1?int=0
- 2147483647.5?int=2147483647
- 2147483648.5?int=-2147483648
- -2147483647.5?int=-2147483647
- -2147483648.5?int=-2147483648
- 4294967295.5?int=-1
- 4294967296.5?int=0
- -4294967295.5?int=1
- -4294967296.5?int=0
-
-?double
- 0?double=0
- 1?double=1
- -1?double=-1
- 0.5?double=0.5
- 1.5?double=1.5
- -0.5?double=-0.5
- -1.5?double=-1.5
- 0.25?double=0.25
- -0.25?double=-0.25
- 1.75?double=1.75
- -1.75?double=-1.75
- 1.01?double=1.01
- -1.01?double=-1.01
- 0.01?double=0.01
- -0.01?double=-0.01
- 127?double=127
- 128?double=128
- -127?double=-127
- -128?double=-128
- 32767?double=32767
- 32768?double=32768
- -32767?double=-32767
- -32768?double=-32768
- 2147483647?double=2147483647
- 2147483648?double=2147483648
- -2147483647?double=-2147483647
- -2147483648?double=-2147483648
- 4294967295?double=4294967295
- 4294967296?double=4294967296
- -4294967295?double=-4294967295
- -4294967296?double=-4294967296
- 2147483647.1?double=2147483647.1
- 2147483648.1?double=2147483648.1
- -2147483647.1?double=-2147483647.1
- -2147483648.1?double=-2147483648.1
- 4294967295.1?double=4294967295.1
- 4294967296.1?double=4294967296.1
- -4294967295.1?double=-4294967295.1
- -4294967296.1?double=-4294967296.1
- 2147483647.5?double=2147483647.5
- 2147483648.5?double=2147483648.5
- -2147483647.5?double=-2147483647.5
- -2147483648.5?double=-2147483648.5
- 4294967295.5?double=4294967295.5
- 4294967296.5?double=4294967296.5
- -4294967295.5?double=-4294967295.5
- -4294967296.5?double=-4294967296.5
-
-?long
- 0?long=0
- 1?long=1
- -1?long=-1
- 0.5?long=0
- 1.5?long=1
- -0.5?long=0
- -1.5?long=-1
- 0.25?long=0
- -0.25?long=0
- 1.75?long=1
- -1.75?long=-1
- 1.01?long=1
- -1.01?long=-1
- 0.01?long=0
- -0.01?long=0
- 127?long=127
- 128?long=128
- -127?long=-127
- -128?long=-128
- 32767?long=32767
- 32768?long=32768
- -32767?long=-32767
- -32768?long=-32768
- 2147483647?long=2147483647
- 2147483648?long=2147483648
- -2147483647?long=-2147483647
- -2147483648?long=-2147483648
- 4294967295?long=4294967295
- 4294967296?long=4294967296
- -4294967295?long=-4294967295
- -4294967296?long=-4294967296
- 2147483647.1?long=2147483647
- 2147483648.1?long=2147483648
- -2147483647.1?long=-2147483647
- -2147483648.1?long=-2147483648
- 4294967295.1?long=4294967295
- 4294967296.1?long=4294967296
- -4294967295.1?long=-4294967295
- -4294967296.1?long=-4294967296
- 2147483647.5?long=2147483647
- 2147483648.5?long=2147483648
- -2147483647.5?long=-2147483647
- -2147483648.5?long=-2147483648
- 4294967295.5?long=4294967295
- 4294967296.5?long=4294967296
- -4294967295.5?long=-4294967295
- -4294967296.5?long=-4294967296
-
-?long from date
- 1304877615000 = 1304877615000
-
-?float
- 0?float=0
- 1?float=1
- -1?float=-1
- 0.5?float=0.5
- 1.5?float=1.5
- -0.5?float=-0.5
- -1.5?float=-1.5
- 0.25?float=0.25
- -0.25?float=-0.25
- 1.75?float=1.75
- -1.75?float=-1.75
- 1.01?float=1.00999999
- -1.01?float=-1.00999999
- 0.01?float=0.01
- -0.01?float=-0.01
- 127?float=127
- 128?float=128
- -127?float=-127
- -128?float=-128
- 32767?float=32767
- 32768?float=32768
- -32767?float=-32767
- -32768?float=-32768
- 2147483647?float=2147483648
- 2147483648?float=2147483648
- -2147483647?float=-2147483648
- -2147483648?float=-2147483648
- 4294967295?float=4294967296
- 4294967296?float=4294967296
- -4294967295?float=-4294967296
- -4294967296?float=-4294967296
- 2147483647.1?float=2147483648
- 2147483648.1?float=2147483648
- -2147483647.1?float=-2147483648
- -2147483648.1?float=-2147483648
- 4294967295.1?float=4294967296
- 4294967296.1?float=4294967296
- -4294967295.1?float=-4294967296
- -4294967296.1?float=-4294967296
- 2147483647.5?float=2147483648
- 2147483648.5?float=2147483648
- -2147483647.5?float=-2147483648
- -2147483648.5?float=-2147483648
- 4294967295.5?float=4294967296
- 4294967296.5?float=4294967296
- -4294967295.5?float=-4294967296
- -4294967296.5?float=-4294967296
-
-?byte
- 0?byte=0
- 1?byte=1
- -1?byte=-1
- 0.5?byte=0
- 1.5?byte=1
- -0.5?byte=0
- -1.5?byte=-1
- 0.25?byte=0
- -0.25?byte=0
- 1.75?byte=1
- -1.75?byte=-1
- 1.01?byte=1
- -1.01?byte=-1
- 0.01?byte=0
- -0.01?byte=0
- 127?byte=127
- 128?byte=-128
- -127?byte=-127
- -128?byte=-128
- 32767?byte=-1
- 32768?byte=0
- -32767?byte=1
- -32768?byte=0
- 2147483647?byte=-1
- 2147483648?byte=0
- -2147483647?byte=1
- -2147483648?byte=0
- 4294967295?byte=-1
- 4294967296?byte=0
- -4294967295?byte=1
- -4294967296?byte=0
- 2147483647.1?byte=-1
- 2147483648.1?byte=0
- -2147483647.1?byte=1
- -2147483648.1?byte=0
- 4294967295.1?byte=-1
- 4294967296.1?byte=0
- -4294967295.1?byte=1
- -4294967296.1?byte=0
- 2147483647.5?byte=-1
- 2147483648.5?byte=0
- -2147483647.5?byte=1
- -2147483648.5?byte=0
- 4294967295.5?byte=-1
- 4294967296.5?byte=0
- -4294967295.5?byte=1
- -4294967296.5?byte=0
-
-?short
- 0?short=0
- 1?short=1
- -1?short=-1
- 0.5?short=0
- 1.5?short=1
- -0.5?short=0
- -1.5?short=-1
- 0.25?short=0
- -0.25?short=0
- 1.75?short=1
- -1.75?short=-1
- 1.01?short=1
- -1.01?short=-1
- 0.01?short=0
- -0.01?short=0
- 127?short=127
- 128?short=128
- -127?short=-127
- -128?short=-128
- 32767?short=32767
- 32768?short=-32768
- -32767?short=-32767
- -32768?short=-32768
- 2147483647?short=-1
- 2147483648?short=0
- -2147483647?short=1
- -2147483648?short=0
- 4294967295?short=-1
- 4294967296?short=0
- -4294967295?short=1
- -4294967296?short=0
- 2147483647.1?short=-1
- 2147483648.1?short=0
- -2147483647.1?short=1
- -2147483648.1?short=0
- 4294967295.1?short=-1
- 4294967296.1?short=0
- -4294967295.1?short=1
- -4294967296.1?short=0
- 2147483647.5?short=-1
- 2147483648.5?short=0
- -2147483647.5?short=1
- -2147483648.5?short=0
- 4294967295.5?short=-1
- 4294967296.5?short=0
- -4294967295.5?short=1
- -4294967296.5?short=0
-
-?floor
- 0?floor=0
- 1?floor=1
- -1?floor=-1
- 0.5?floor=0
- 1.5?floor=1
- -0.5?floor=-1
- -1.5?floor=-2
- 0.25?floor=0
- -0.25?floor=-1
- 1.75?floor=1
- -1.75?floor=-2
- 1.01?floor=1
- -1.01?floor=-2
- 0.01?floor=0
- -0.01?floor=-1
- 127?floor=127
- 128?floor=128
- -127?floor=-127
- -128?floor=-128
- 32767?floor=32767
- 32768?floor=32768
- -32767?floor=-32767
- -32768?floor=-32768
- 2147483647?floor=2147483647
- 2147483648?floor=2147483648
- -2147483647?floor=-2147483647
- -2147483648?floor=-2147483648
- 4294967295?floor=4294967295
- 4294967296?floor=4294967296
- -4294967295?floor=-4294967295
- -4294967296?floor=-4294967296
- 2147483647.1?floor=2147483647
- 2147483648.1?floor=2147483648
- -2147483647.1?floor=-2147483648
- -2147483648.1?floor=-2147483649
- 4294967295.1?floor=4294967295
- 4294967296.1?floor=4294967296
- -4294967295.1?floor=-4294967296
- -4294967296.1?floor=-4294967297
- 2147483647.5?floor=2147483647
- 2147483648.5?floor=2147483648
- -2147483647.5?floor=-2147483648
- -2147483648.5?floor=-2147483649
- 4294967295.5?floor=4294967295
- 4294967296.5?floor=4294967296
- -4294967295.5?floor=-4294967296
- -4294967296.5?floor=-4294967297
-
-?ceiling
- 0?ceiling=0
- 1?ceiling=1
- -1?ceiling=-1
- 0.5?ceiling=1
- 1.5?ceiling=2
- -0.5?ceiling=0
- -1.5?ceiling=-1
- 0.25?ceiling=1
- -0.25?ceiling=0
- 1.75?ceiling=2
- -1.75?ceiling=-1
- 1.01?ceiling=2
- -1.01?ceiling=-1
- 0.01?ceiling=1
- -0.01?ceiling=0
- 127?ceiling=127
- 128?ceiling=128
- -127?ceiling=-127
- -128?ceiling=-128
- 32767?ceiling=32767
- 32768?ceiling=32768
- -32767?ceiling=-32767
- -32768?ceiling=-32768
- 2147483647?ceiling=2147483647
- 2147483648?ceiling=2147483648
- -2147483647?ceiling=-2147483647
- -2147483648?ceiling=-2147483648
- 4294967295?ceiling=4294967295
- 4294967296?ceiling=4294967296
- -4294967295?ceiling=-4294967295
- -4294967296?ceiling=-4294967296
- 2147483647.1?ceiling=2147483648
- 2147483648.1?ceiling=2147483649
- -2147483647.1?ceiling=-2147483647
- -2147483648.1?ceiling=-2147483648
- 4294967295.1?ceiling=4294967296
- 4294967296.1?ceiling=4294967297
- -4294967295.1?ceiling=-4294967295
- -4294967296.1?ceiling=-4294967296
- 2147483647.5?ceiling=2147483648
- 2147483648.5?ceiling=2147483649
- -2147483647.5?ceiling=-2147483647
- -2147483648.5?ceiling=-2147483648
- 4294967295.5?ceiling=4294967296
- 4294967296.5?ceiling=4294967297
- -4294967295.5?ceiling=-4294967295
- -4294967296.5?ceiling=-4294967296
-
-?round
- 0?round=0
- 1?round=1
- -1?round=-1
- 0.5?round=1
- 1.5?round=2
- -0.5?round=0
- -1.5?round=-1
- 0.25?round=0
- -0.25?round=0
- 1.75?round=2
- -1.75?round=-2
- 1.01?round=1
- -1.01?round=-1
- 0.01?round=0
- -0.01?round=0
- 127?round=127
- 128?round=128
- -127?round=-127
- -128?round=-128
- 32767?round=32767
- 32768?round=32768
- -32767?round=-32767
- -32768?round=-32768
- 2147483647?round=2147483647
- 2147483648?round=2147483648
- -2147483647?round=-2147483647
- -2147483648?round=-2147483648
- 4294967295?round=4294967295
- 4294967296?round=4294967296
- -4294967295?round=-4294967295
- -4294967296?round=-4294967296
- 2147483647.1?round=2147483647
- 2147483648.1?round=2147483648
- -2147483647.1?round=-2147483647
- -2147483648.1?round=-2147483648
- 4294967295.1?round=4294967295
- 4294967296.1?round=4294967296
- -4294967295.1?round=-4294967295
- -4294967296.1?round=-4294967296
- 2147483647.5?round=2147483648
- 2147483648.5?round=2147483649
- -2147483647.5?round=-2147483647
- -2147483648.5?round=-2147483648
- 4294967295.5?round=4294967296
- 4294967296.5?round=4294967297
- -4294967295.5?round=-4294967295
- -4294967296.5?round=-4294967296
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
deleted file mode 100644
index 3b5215a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-Output charset: UTF-8
-URL escaping charset: undefined
-
-a%FE%FF%00%2F%00%25b
-a%FE%FF%00%2F%00%25b
-a%2F%25b
-a%2F%25b
-a%FE%FF%00%2F%00%25b
-a%2F%25b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt
deleted file mode 100644
index 6956b6c..0000000
Binary files a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
deleted file mode 100644
index c0369f6..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-Output charset: ISO-8859-1
-URL escaping charset: UTF-16
-
-UTF-16: a%FE%FF%00%2F%00%25b
-ISO-8859-1: a%2F%25b
-UTF-16: a%FE%FF%00%2F%00%25b
-ISO-8859-1: a%2F%25b
-ISO-8859-1: a%2F%25b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
deleted file mode 100644
index b19cb31..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Operator Precedence Test</title>
-</head>
-<body>
-
-@@@@@@@@@@@
-
-<br />
-<br />
-
-##########
-
-<br />
-<br />
-
-&&&&&&&&&&&
-
-<br />
-<br />
-
-!!!!!!!!!!!
-
-<br />
-<br />
-
-$$$$$$$$$$$
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
deleted file mode 100644
index 880cea3..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
- Hello, World
- Well, that did not work.
- Now we nest another attempt/recover here:
- Oops...
- Remember, freeMarker sequences are zero-based! Hello, World
- Now we check the current error message.
- The template is not currently available
- The included template had a problem.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
deleted file mode 100644
index 041222c..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Root Lookup Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Access the same variable via the root variable (dot syntax):</p>
-
-<p>Hello, world!</p>
-
-<p>Access the same variable via the root variable (bracket syntax):</p>
-
-<p>Hello, world!</p>
-
-<p>Ensure that root lookups are unaffected by local variables:</p>
-
-
- Hello, world!
- Hello, world! Part Deux
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
deleted file mode 100644
index 4f7796a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.
- */
-Sorting scalars:
-----------------
-
-String order:
-- aardvark
-- Barbara
-- beetroot
-- whale
-- zeppelin
-
-First: aardvark
-Last: zeppelin
-Size 5
-
-Numerical order:
-- -324
-- -34
-- 0
-- 0.1
-- 0.11
-- 1
-- 5
-- 111
-- 123
-- 543
-
-First: -324
-Last: 543
-Size 10
-
-Date/time order:
-- 06:05
-- 08:05
-- 08:15
-- 18:00
-
-Boolean order:
-- false
-- false
-- true
-- true
-
-
-Sorting hashes:
----------------
-
-Order by name:
-- aardvark: 30
-- Barbara: 53
-- beetroot: 0.3
-- whale: 2000
-- zeppelin: -200
-
-Order by weight:
-- zeppelin: -200
-- beetroot: 0.3
-- aardvark: 30
-- Barbara: 53
-- whale: 2000
-
-Order by a.x.v:
-- aqweqw
-- dfgdf
-- qweqw
-- utyu
-
-Order by a.y, which is a date:
-- 1998-02-20
-- 1999-01-20
-- 1999-04-19
-- 1999-04-20
-
-Reverse:
---------
-
-Order by weight desc:
-- whale: 2000
-- Barbara: 53
-- aardvark: 30
-- beetroot: 0.3
-- zeppelin: -200
-
-Order by weight desc desc:
-- zeppelin: -200
-- beetroot: 0.3
-- aardvark: 30
-- Barbara: 53
-- whale: 2000
-
-Order by weight desc desc desc:
-- whale: 2000
-- Barbara: 53
-- aardvark: 30
-- beetroot: 0.3
-- zeppelin: -200
-
-Contains:
----------
-
-True:
-true
-true
-true
-true
-true
-true
-true
-
-False:
-false
-false
-false
-false
-false
-false
-false
-
-False: false
-
-Index_of:
----------
-
-0 = 0
-1 = 1
-2 = 2
-6 = 6
-0 = 0
-1 = 1
-2 = 2
-
--1 = -1
--1 = -1
--1 = -1
--1 = -1
--1 = -1
--1 = -1
--1 = -1
-
--1 = -1
-
-Last_index_of:
---------------
-
-6 = 6
-1 = 1
-2 = 2
-7 = 7
--1 = -1
-0 = 0
-1 = 1
-2 = 2
--1 = -1
-
-Index_of and last_index_of with starting indices
-------------------------------------------------
-
-seq_index_of "Joe":
-0 = 0
-0 = 0
-0 = 0
-2 = 2
-2 = 2
--1 = -1
--1 = -1
-
-seq_last_index_of "Joe":
--1 = -1
--1 = -1
-0 = 0
-0 = 0
-2 = 2
-2 = 2
-2 = 2
-
-seq_index_of "Susan":
-3 = 3
-3 = 3
-3 = 3
-3 = 3
-3 = 3
-3 = 3
--1 = -1
-
-seq_last_index_of "Susan":
--1 = -1
--1 = -1
--1 = -1
--1 = -1
--1 = -1
-3 = 3
-3 = 3
-
-seq_index_of "a":
-0 = 0
-0 = 0
-0 = 0
--1 = -1
--1 = -1
--1 = -1
--1 = -1
-
-seq_index_of "b":
-1 = 1
-1 = 1
-1 = 1
-1 = 1
--1 = -1
--1 = -1
-
-seq_index_of "c":
-2 = 2
-2 = 2
-2 = 2
-2 = 2
-2 = 2
--1 = -1
-
-seq_last_index_of "a":
--1 = -1
--1 = -1
-0 = 0
-0 = 0
-0 = 0
-0 = 0
-0 = 0
-
-seq_last_index_of "b":
--1 = -1
--1 = -1
--1 = -1
-1 = 1
-1 = 1
-1 = 1
-
-seq_last_index_of "c":
--1 = -1
--1 = -1
--1 = -1
--1 = -1
-2 = 2
-2 = 2
-
-Sequence builtins ignoring nulls
---------------------------------
-
-true = true
-2 = 2
-0 = 0
-
-These should throw exception, but for BC they don't:
-false = false
--1 = -1
--1 = -1
-
-Sequence built-ins failing on date-type mismatch
-------------------------------------------------
-
-
-Chunk
------
-
-columns = 1, fill = NULL:
- Rows: 7
- a <-- Columns: 1
- b <-- Columns: 1
- c <-- Columns: 1
- d <-- Columns: 1
- e <-- Columns: 1
- f <-- Columns: 1
- g <-- Columns: 1
-
-columns = 2, fill = NULL:
- Rows: 4
- a b <-- Columns: 2
- c d <-- Columns: 2
- e f <-- Columns: 2
- g <-- Columns: 1
-
-columns = 3, fill = NULL:
- Rows: 3
- a b c <-- Columns: 3
- d e f <-- Columns: 3
- g <-- Columns: 1
-
-columns = 4, fill = NULL:
- Rows: 2
- a b c d <-- Columns: 4
- e f g <-- Columns: 3
-
-columns = 5, fill = NULL:
- Rows: 2
- a b c d e <-- Columns: 5
- f g <-- Columns: 2
-
-columns = 10, fill = NULL:
- Rows: 1
- a b c d e f g <-- Columns: 7
-
-columns = 1, fill = -:
- Rows: 7
- a <-- Columns: 1
- b <-- Columns: 1
- c <-- Columns: 1
- d <-- Columns: 1
- e <-- Columns: 1
- f <-- Columns: 1
- g <-- Columns: 1
-
-columns = 2, fill = -:
- Rows: 4
- a b <-- Columns: 2
- c d <-- Columns: 2
- e f <-- Columns: 2
- g - <-- Columns: 2
-
-columns = 3, fill = -:
- Rows: 3
- a b c <-- Columns: 3
- d e f <-- Columns: 3
- g - - <-- Columns: 3
-
-columns = 4, fill = -:
- Rows: 2
- a b c d <-- Columns: 4
- e f g - <-- Columns: 4
-
-columns = 5, fill = -:
- Rows: 2
- a b c d e <-- Columns: 5
- f g - - - <-- Columns: 5
-
-columns = 10, fill = -:
- Rows: 1
- a b c d e f g - - - <-- Columns: 10
-
-columns = 3, fill = NULL:
- Rows: 3
- 1 2 3 <-- Columns: 3
- 4 5 6 <-- Columns: 3
- 7 8 9 <-- Columns: 3
-
-columns = 3, fill = -:
- Rows: 3
- 1 2 3 <-- Columns: 3
- 4 5 6 <-- Columns: 3
- 7 8 9 <-- Columns: 3
-
-columns = 3, fill = NULL:
- Rows: 1
- 1 <-- Columns: 1
-
-columns = 3, fill = -:
- Rows: 1
- 1 - - <-- Columns: 3
-
-columns = 3, fill = NULL:
- Rows: 0
-
-columns = 3, fill = -:
- Rows: 0
-
-
-
-
-Join
-----
-
-- 1, two, three, 4
--
-- 1, two, three, 4.
-- (empty)
-- a, c
-- a, c
-- a, c.
--
-- (empty)
-- (empty)
-- a, b, c.
-- a, b, c.
-
-
-Misc
-----
-
-First of set 1: a
-First of set 2: a
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
deleted file mode 100644
index e2fa13e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-en == en
-en_US == en_US
-utf-8 == utf-8
-specialvars.ftl == specialvars.ftl
-iso-8859-1 == iso-8859-1
-x == x
-true == true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
deleted file mode 100644
index ba14e7f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.
- */
-
-List mode:
-Size: 4
-[L16][L27][L38][L49]
-[L16][L27][L38][L49]
-
-Iterator mode:
-[L16][L27][L38][L49]
-[L16(L16, L27, L38, L49)][L27(L16, L27, L38, L49)][L38(L16, L27, L38, L49)][L49(L16, L27, L38, L49)]
-[L16][L27][L38][L49]
-
-Iterator mode changes to list mode:
-[L16]/4[L27]/4[L38]/4[L49]/4
-[L16][L27][L38][L49]
-
-Iterator mode changes to list mode 2:
-[L16][L27][L38][L49]
-[L16]/4[L27]/4[L38]/4[L49]/4
-
-List mode with embedded iteration:
-[L16(L16, L27, L38, L49)][L27(L16, L27, L38, L49)][L38(L16, L27, L38, L49)][L49(L16, L27, L38, L49)]
-
-Entire input match:
-- M: L16
- - G: L16
- - G: 1
- - G: 6
-- M: L27
- - G: L27
- - G: 2
- - G: 7
-- M: L38
- - G: L38
- - G: 3
- - G: 8
-- M: L49
- - G: L49
- - G: 4
- - G: 9
-firstGS was: L16, 1, 6
-
-Entire input match 2:
-Matches: true
-- G: x12
-- G: 1
-- G: 2
-As list:
-- M: x12
- - G: x12
- - G: 1
- - G: 2
-Groups again:
-- G: x12
-- G: 1
-- G: 2
-
-Entire input match 3:
-Matches: false
-
-Entire input match 4:
-Matches: true
-- G: x12
-- G: 1
-- G: 2
-
-Substring match nested into entire input match:
-- G: x12 ([x12{x12, 1, 2}])
-- G: 1 ([x12{x12, 1, 2}])
-- G: 2 ([x12{x12, 1, 2}])
-
-Different entire input and substring matches:
-123, 123
-- M: 1 (Gs: 1, 1)
-- M: 2 (Gs: 2, 2)
-- M: 3 (Gs: 3, 3)
-
-Different entire input and substring matches 2:
-123
-- M: 1 (Gs: 1)
-- M: 2 (Gs: 2)
-- M: 3 (Gs: 3)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
deleted file mode 100644
index c54dc96..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.
- */
-true == true
-true == true
-
-false == false
-true == true
-
-false == false
-true == true
-
-false == false
-true == true
-
-false == false
-false == false
-false == false
-true == true
-true == true
-true == true
-
-false == false
-false == false
-true == true
-true == true
-true == true
-true == true
-
-
-Lower 'c'-words:
-- coverage
-- considered
-
-Any 'c'-words:
-- Code
-- coverage
-- considered
-
-Lower line-last words:
-- coverage
-
-Any line-last words:
-- coverage
-- BROKEN
-
-Any last words:
-- BROKEN
-
-c-word with follower:
-- "Code without"
- Groups: "Code without", "Code", "without"
-- "coverage\nis"
- Groups: "coverage\nis", "coverage", "is"
-- "considered to"
- Groups: "considered to", "considered", "to"
-
-c-word with follower in the same line:
-- Code without
-- considered to
-
-Lower c-word with follower in the same line:
-- considered to
-
- Ignored but logged in 2.3: False == False
- Ignored but logged in 2.3: False == False
-
-FOObar == FOObar
-Foobar == Foobar
-FOObar == FOObar
-FOObarFOO == FOObarFOO
-FOObarfOO == FOObarfOO
-FOObarfOO == FOObarfOO
-Foobar == Foobar
-FOObar == FOObar
-FOObarFOO == FOObarFOO
-FOObarfOO == FOObarfOO
-FOObarfOO == FOObarfOO
-foobar == foobar
-foobar == foobar
-FOObar == FOObar
-FOObarFOO == FOObarFOO
-FOObarfOo == FOObarfOo
-FAlse == FAlse
-FAlse == FAlse
-
- Ignored but logged in 2.3: FOObar
-
-[foo, barxbaaz] == [foo, barxbaaz]
-[foo, barxbaaz] == [foo, barxbaaz]
-[foo, bar, baaz] == [foo, bar, baaz]
-[foo, barxbaaz] == [foo, barxbaaz]
-[foo, bar, baaz] == [foo, bar, baaz]
-[fooXXbarxxbaaz] == [fooXXbarxxbaaz]
-[foo, bar, baaz] == [foo, bar, baaz]
-[F, ls] == [F, ls]
-[Fals, ] == [Fals, ]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
deleted file mode 100644
index 6e689ac..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.
- */
-FreeMarker: Encoding string built-in tests
-
-
-cap_first: DieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-uncap_first: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-uncap_first:blah
-capitalize: Diebugsdie! * Vazzze 123456 --cdc-- --<<--@ X ${"kigyo"?upper_case}
-html: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-length: 71
-lower_case: diebugsdie! * vazzze 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-rtf: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x $\{"kigyo"?upper_case\}
-trim: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-trim2: foo bar
-trim3: foo bar
-trim4: foo bar
-upper_case: DIEBUGSDIE! * VAZZZE 123456 --CDC-- --<<--@ X ${"KIGYO"?UPPER_CASE}
-xml: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
-xhtml: "Blah's is > 1 & < 2"
-
-word_list:
-- dieBugsDie!
-- *
-- vazzZE
-- 123456
-- --cdc--
-- --<<--@
-- x
-- ${"kigyo"?upper_case}
-
-interpret: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x KIGYO
-number: -122,35
-1500
-5
-0
-0
-true
-true
-true
-true
-true
-
-default constructor
-1
-xxx
-xxx:yyy
-
-
-In The Sacred, Holy beginning, God created The Sacred, Holy Heavens and The Sacred, Holy Earth.
-In the very beginning, God created the Heavens and The Earth.
-|I|n| |t|h|e| |b|e|g|i|n|n|i|n|g|,| |G|o|d| |c|r|e|a|t|e|d| |t|h|e| |H|e|a|v|e|n|s| |a|n|d| |T|h|e| |E|a|r|t|h|.|
-|In the beginning, God created the Heavens and The Earth.
-
-In the beginning, God created the sky and The Earth.
-
-matches
-
- the beginning
- the sacred beginning
- the Heavens
- the sacred Heavens
- The Earth
- The sacred Earth
-
-In the beginning, God created the Heavens and The Earth.
-beginning
-the Heavens and The Earth.
-
- foo
- bar
- baz
- foobar
-
-
-FOOBAR
-
-[a] = [a]
-[a\\'x'\nb] = [a\\'x'\nb]
-[\u0001\u001a ] = [\u0001\u001a ]
-
-[a] = [a]
-[a\\\'x\'\nb] = [a\\\'x\'\nb]
-[\x01\x1A ] = [\x01\x1A ]
-[\x3C![CDATA[] = [\x3C![CDATA[]
-[]]\>] = []]\>]
-
-[a] = [a]
-[a\\'x'\nb] = [a\\'x'\nb]
-[\u0001\u001A ] = [\u0001\u001A ]
-[\n\r\t\f\b\"] = [\n\r\t\f\b\"]
-[\/] = [\/]
-[a/b] = [a/b]
-[<\/script>] = [<\/script>]
-[\u003C![CDATA[] = [\u003C![CDATA[]
-[]]\u003E] = []]\u003E]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
deleted file mode 100644
index f5eebd9..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.
- */
---
-1 = 1
-5 = 5
-0 = 0
---
-5 = 5
-1 = 1
-7 = 7
---
-true = true
-false = false
-true = true
---
-true = true
-false = false
-true = true
---
-true = true
-true = true
-true = true
-false = false
-true = true
---
-[abbcdbb] = [abbcdbb]
-[qwe] = [qwe]
-[qwe] = [qwe]
-[qwe] = [qwe]
-[qwe
-] = [qwe
-]
-[qwe
-] = [qwe
-]
---
-[abbcdbb] = [abbcdbb]
-[abb-dbb] = [abb-dbb]
-[a-=*cd-=*] = [a-=*cd-=*]
---
-[a][][cd][][] == [a][][cd][][]
-[][die][maggots][!] == [][die][maggots][!]
-[Die maggots!] == [Die maggots!]
---
-[ ]
-[ a]
-[ ab]
-[ abc]
-[ abcd]
-[abcde]
-[abcdef]
-[abcdefg]
-[abcdefgh]
-[-----]
-[----a]
-[---ab]
-[--abc]
-[-abcd]
-[abcde]
-[abcdef]
-[abcdefg]
-[abcdefgh]
-[.oO.oO.o]
-[.oO.oO.a]
-[.oO.oOab]
-[.oO.oabc]
-[.oO.abcd]
-[.oOabcde]
-[.oabcdef]
-[.abcdefg]
-[abcdefgh]
-[abcdefghi]
-[abcdefghij]
-[]
-[/]
-[/\]
-[/\_]
-[/\_/]
-[/\_/\]
-[/\_/\_]
-[/\_/\_/]
---
-[ ]
-[a ]
-[ab ]
-[abc ]
-[abcd ]
-[abcde]
-[abcdef]
-[abcdefg]
-[abcdefgh]
-[-----]
-[a----]
-[ab---]
-[abc--]
-[abcd-]
-[abcde]
-[abcdef]
-[abcdefg]
-[abcdefgh]
-[.oO.oO.o]
-[aoO.oO.o]
-[abO.oO.o]
-[abc.oO.o]
-[abcdoO.o]
-[abcdeO.o]
-[abcdef.o]
-[abcdefgo]
-[abcdefgh]
-[abcdefghi]
-[abcdefghij]
-[]
-[/]
-[/\]
-[/\_]
-[/\_/]
-[/\_/\]
-[/\_/\_]
-[/\_/\_/]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
deleted file mode 100644
index 8ef415d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-3.00
-3.00
-01:02:03.000
-01:02:03.000
----
-de
-true false
-yes no
-igen nem
-0.0 1.0
-true true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt
deleted file mode 100644
index 3d9d4c9..0000000
Binary files a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
deleted file mode 100644
index 5d42785..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Switch-Case Test</title>
-</head>
-<body>
-
-<p>Here we iterate over a list of animals.</p>
-
-<p>Animal is: aardvark.<br />
- This is the HTML for other animals.
-</p>
-<p>Animal is: kiwi.<br />
- This is the HTML for the user's favorite animal.
-</p>
-<p>Animal is: gecko.<br />
- This is the HTML for small animals.
-</p>
-<p>Animal is: cat.<br />
- This is the HTML for other animals.
-</p>
-<p>Animal is: dog.<br />
- This is the HTML for other animals.
-</p>
-<p>Animal is: elephant.<br />
- This is the HTML for large animals.
-</p>
-<p>Animal is: squirrel.<br />
- This is the HTML for small animals.
-</p>
-<p>Animal is: zebra.<br />
- This is the HTML for a large stripey animal.
- This is the HTML for large animals.
-</p>
-
- 1
- i2
- 2
- i4
- ft
- ft
- 3
- i4
- 3
- i6
-
-[]
-
- ""
- "1234"
- "234"
- "34"
- "4"
-
- "12default45"
- "2default45"
- "default"
- "45"
- "5"
-
-
-</body>
-</html>
[06/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
deleted file mode 100644
index 4e80e71..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * 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.io.File;
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.AdapterTemplateModel;
-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.TemplateNumberModel;
-import org.apache.freemarker.core.model.WrapperTemplateModel;
-import org.apache.freemarker.core.model.impl.RationalNumber;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TestUtil;
-
-public class OverloadedMethods2 {
-
- public String mVarargs(String... a1) {
- StringBuilder sb = new StringBuilder();
- for (String s : a1) {
- sb.append(s);
- }
- return "mVarargs(String... a1 = " + sb + ")";
- }
-
- public BigInteger bigInteger(BigDecimal n) {
- return n.toBigInteger();
- }
-
- public RationalNumber rational(int a, int b) {
- return new RationalNumber(a, b);
- }
-
- public String mVarargs(File a1, String... a2) {
- return "mVarargs(File a1, String... a2)";
- }
-
- public NumberAndStringModel getNnS(String s) {
- return new NumberAndStringModel(s);
- }
-
- public String mNull1(String a1) {
- return "mNull1(String a1 = " + a1 + ")";
- }
-
- public String mNull1(int a1) {
- return "mNull1(int a1 = " + a1 + ")";
- }
-
- public String mNull2(String a1) {
- return "mNull2(String a1 = " + a1 + ")";
- }
-
- public String mNull2(Object a1) {
- return "mNull2(Object a1 = " + a1 + ")";
- }
-
- public String mSpecificity(Object a1, String a2) {
- return "mSpecificity(Object a1, String a2)";
- }
-
- public String mSpecificity(String a1, Object a2) {
- return "mSpecificity(String a1, Object a2)";
- }
-
- public String mChar(char a1) {
- return "mChar(char a1 = " + a1 + ")";
- }
-
- public String mChar(Character a1) {
- return "mChar(Character a1 = " + a1 + ")";
- }
-
- public String mBoolean(boolean a1) {
- return "mBoolean(boolean a1 = " + a1 + ")";
- }
-
- public String mBoolean(Boolean a1) {
- return "mBoolean(Boolean a1 = " + a1 + ")";
- }
-
- public int mIntNonOverloaded(int a1) {
- return a1;
- }
-
- public String mIntPrimVSBoxed(int a1) {
- return "mIntPrimVSBoxed(int a1 = " + a1 + ")";
- }
-
- public String mIntPrimVSBoxed(Integer a1) {
- return "mIntPrimVSBoxed(Integer a1 = " + a1 + ")";
- }
-
- public String mNumPrimVSPrim(short a1) {
- return "mNumPrimVSPrim(short a1 = " + a1 + ")";
- }
-
- public String mNumPrimVSPrim(long a1) {
- return "mNumPrimVSPrim(long a1 = " + a1 + ")";
- }
-
- public String mNumBoxedVSBoxed(Short a1) {
- return "mNumBoxedVSBoxed(Short a1 = " + a1 + ")";
- }
-
- public String mNumBoxedVSBoxed(Long a1) {
- return "mNumBoxedVSBoxed(Long a1 = " + a1 + ")";
- }
-
- public String mNumUnambigous(Short a1, boolean otherOverload) {
- return "mmNumUnambigous won't be called";
- }
-
- public String mNumUnambigous(Integer a1) {
- return "mNumUnambigous(Integer a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Byte a1) {
- return "mNumBoxedAll(Byte a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Short a1) {
- return "mNumBoxedAll(Short a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Integer a1) {
- return "mNumBoxedAll(Integer a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Long a1) {
- return "mNumBoxedAll(Long a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Float a1) {
- return "mNumBoxedAll(Float a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(Double a1) {
- return "mNumBoxedAll(Double a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(BigInteger a1) {
- return "mNumBoxedAll(BigInteger a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll(BigDecimal a1) {
- return "mNumBoxedAll(BigDecimal a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(byte a1) {
- return "mNumPrimAll(byte a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(short a1) {
- return "mNumPrimAll(short a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(int a1) {
- return "mNumPrimAll(int a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(long a1) {
- return "mNumPrimAll(long a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(float a1) {
- return "mNumPrimAll(float a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(double a1) {
- return "mNumPrimAll(double a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(BigInteger a1) {
- return "mNumPrimAll(BigInteger a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll(BigDecimal a1) {
- return "mNumPrimAll(BigDecimal a1 = " + a1 + ")";
- }
-
-
- public String mNumBoxedAll2nd(Short a1) {
- return "mNumBoxedAll2nd(Short a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll2nd(Long a1) {
- return "mNumBoxedAll2nd(Long a1 = " + a1 + ")";
- }
-
- public String mNumBoxedAll2nd(Double a1) {
- return "mNumBoxedAll2nd(Double a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll2nd(short a1) {
- return "mNumPrimAll2nd(short a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll2nd(long a1) {
- return "mNumPrimAll2nd(long a1 = " + a1 + ")";
- }
-
- public String mNumPrimAll2nd(double a1) {
- return "mNumPrimAll2nd(double a1 = " + a1 + ")";
- }
-
- public String mNumPrimFallbackToNumber(long a1) {
- return "mNumPrimFallbackToNumber(long a1 = " + a1 + ")";
- }
-
- public String mNumPrimFallbackToNumber(Number a1) {
- return "mNumPrimFallbackToNumber(Number a1 = " + a1 + ")";
- }
-
- public String mNumPrimFallbackToNumber(Object a1) {
- return "mNumPrimFallbackToNumber(Object a1 = " + a1 + ")";
- }
-
- public String mNumBoxedFallbackToNumber(Long a1) {
- return "mNumBoxedFallbackToNumber(Long a1 = " + a1 + ")";
- }
-
- public String mNumBoxedFallbackToNumber(Number a1) {
- return "mNumBoxedFallbackToNumber(Number a1 = " + a1 + ")";
- }
-
- public String mNumBoxedFallbackToNumber(Object a1) {
- return "mNumBoxedFallbackToNumber(Object a1 = " + a1 + ")";
- }
-
- public String mDecimalLoss(int a1) {
- return "mDecimalLoss(int a1 = " + a1 + ")";
- }
-
- public String mDecimalLoss(double a1) {
- return "mDecimalLoss(double a1 = " + a1 + ")";
- }
-
- public String mNumConversionLoses1(byte i, Object o1, Object o2) {
- return "byte " + i;
- }
-
- public String mNumConversionLoses1(double i, Object o1, Object o2) {
- return "double " + i;
- }
-
- public String mNumConversionLoses1(Number i, String o1, String o2) {
- return "Number " + i + " " + i.getClass().getName();
- }
-
- public String mNumConversionLoses2(int i, Object o1, Object o2) {
- return "int " + i;
- }
-
- public String mNumConversionLoses2(long i, Object o1, Object o2) {
- return "long " + i;
- }
-
- public String mNumConversionLoses2(Number i, String o1, String o2) {
- return "Number " + i + " " + i.getClass().getName();
- }
-
- public String mNumConversionLoses3(int i, Object o1, Object o2) {
- return "int " + i;
- }
-
- public String mNumConversionLoses3(Serializable i, String o1, String o2) {
- return "Serializable " + i + " " + i.getClass().getName();
- }
-
- public String nIntAndLong(int i) {
- return "nIntAndLong(int " + i + ")";
- }
-
- public String nIntAndLong(long i) {
- return "nIntAndLong(long " + i + ")";
- }
-
- public String nIntAndShort(int i) {
- return "nIntAndShort(int " + i + ")";
- }
-
- public String nIntAndShort(short i) {
- return "nIntAndShort(short " + i + ")";
- }
-
- public String nLongAndShort(long i) {
- return "nLongAndShort(long " + i + ")";
- }
-
- public String nLongAndShort(short i) {
- return "nLongAndShort(short " + i + ")";
- }
-
- public String varargs1(String s, int... xs) {
- return "varargs1(String s = " + _StringUtil.jQuote(s) + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs1(String s, double... xs) {
- return "varargs1(String s = " + _StringUtil.jQuote(s) + ", double... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs1(String s, Object... xs) {
- return "varargs1(String s = " + _StringUtil.jQuote(s) + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs1(Object s, Object... xs) {
- return "varargs1(Object s = " + s + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs2(int... xs) {
- return "varargs2(int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs2(double... xs) {
- return "varargs2(double... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs3(String... xs) {
- return "varargs3(String... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs3(Comparable... xs) {
- return "varargs3(Comparable... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs3(Object... xs) {
- return "varargs3(Object... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs4(Integer... xs) {
- return "varargs4(Integer... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs4(int... xs) {
- return "varargs4(int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs5(int... xs) {
- return "varargs5(int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs5(int a1, int... xs) {
- return "varargs5(int a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs5(int a1, int a2, int... xs) {
- return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs5(int a1, int a2, int a3, int... xs) {
- return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int a3 = " + a3
- + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs6(String a1, int... xs) {
- return "varargs6(String a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs6(Object a1, int a2, int... xs) {
- return "varargs6(Object a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs7(int... xs) {
- return "varargs7(int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String varargs7(short a1, int... xs) {
- return "varargs7(short a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
- }
-
- public String mNullAmbiguous(String s) {
- return "mNullAmbiguous(String s = " + s + ")";
- }
-
- public String mNullAmbiguous(int i) {
- return "mNullAmbiguous(int i = " + i + ")";
- }
-
- public String mNullAmbiguous(File f) {
- return "mNullAmbiguous(File f = " + f + ")";
- }
-
- public String mNullAmbiguous2(String s) {
- return "mNullNonAmbiguous(String s = " + s + ")";
- }
-
- public String mNullAmbiguous2(File f) {
- return "mNullAmbiguous(File f = " + f + ")";
- }
-
- public String mNullAmbiguous2(Object o) {
- return "mNullAmbiguous(Object o = " + o + ")";
- }
-
- public String mNullNonAmbiguous(String s) {
- return "mNullNonAmbiguous(String s = " + s + ")";
- }
-
- public String mNullNonAmbiguous(int i) {
- return "mNullNonAmbiguous(int i = " + i + ")";
- }
-
- public String mVarargsIgnoredTail(int i, double... ds) {
- return "mVarargsIgnoredTail(int i = " + i + ", double... ds = " + TestUtil.arrayToString(ds) + ")";
- }
-
- public String mVarargsIgnoredTail(int... is) {
- return "mVarargsIgnoredTail(int... is = " + TestUtil.arrayToString(is) + ")";
- }
-
- public String mLowRankWins(int x, int y, Object o) {
- return "mLowRankWins(int x = " + x + ", int y = " + y + ", Object o = " + o + ")";
- }
-
- public String mLowRankWins(Integer x, Integer y, String s) {
- return "mLowRankWins(Integer x = " + x + ", Integer y = " + y + ", String s = " + s + ")";
- }
-
- public String mRareWrappings(File f, double d1, Double d2, double d3, boolean b) {
- return "mRareWrappings(File f = " + f + ", double d1 = " + d1 + ", Double d2 = " + d2
- + ", double d3 = " + d3 + ", b = " + b + ")";
- }
-
- public String mRareWrappings(Object o, double d1, Double d2, Double d3, boolean b) {
- return "mRareWrappings(Object o = " + o + ", double d1 = " + d1 + ", Double d2 = " + d2
- + ", double d3 = " + d3 + ", b = " + b + ")";
- }
-
- public String mRareWrappings(String s, double d1, Double d2, Double d3, boolean b) {
- return "mRareWrappings(String s = " + s + ", double d1 = " + d1 + ", Double d2 = " + d2
- + ", double d3 = " + d3 + ", b = " + b + ")";
- }
-
- public String mRareWrappings2(String s) {
- return "mRareWrappings2(String s = " + s + ")";
- }
-
- public String mRareWrappings2(byte b) {
- return "mRareWrappings2(byte b = " + b + ")";
- }
-
- public File getFile() {
- return new File("file");
- }
-
- public String mSeqToArrayNonOverloaded(String[] items, String s) {
- return "mSeqToArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
- }
-
- public String mSeqToArrayGoodHint(String[] items, String s) {
- return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
- }
-
- public String mSeqToArrayGoodHint(String[] items, int i) {
- return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
- }
-
- public String mSeqToArrayGoodHint2(String[] items, String s) {
- return "mSeqToArrayGoodHint2(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
- }
-
- public String mSeqToArrayGoodHint2(String item) {
- return "mSeqToArrayGoodHint2(String " + item + ")";
- }
-
- public String mSeqToArrayPoorHint(String[] items, String s) {
- return "mSeqToArrayPoorHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
- }
-
- public String mSeqToArrayPoorHint(String item, int i) {
- return "mSeqToArrayPoorHint(String " + item + ", int " + i + ")";
- }
-
- public String mSeqToArrayPoorHint2(String[] items) {
- return "mSeqToArrayPoorHint2(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mSeqToArrayPoorHint2(String item) {
- return "mSeqToArrayPoorHint2(String " + item + ")";
- }
-
- public String mSeqToArrayPoorHint3(String[] items) {
- return "mSeqToArrayPoorHint3(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mSeqToArrayPoorHint3(int[] items) {
- return "mSeqToArrayPoorHint3(int[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVsListPreference(String[] items) {
- return "mStringArrayVsListPreference(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVsListPreference(List items) {
- return "mStringArrayVsListPreference(List " + TestUtil.listToString(items) + ")";
- }
-
- public String mStringArrayVsObjectArrayPreference(String[] items) {
- return "mStringArrayVsObjectArrayPreference(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVsObjectArrayPreference(Object[] items) {
- return "mStringArrayVsObjectArrayPreference(Object[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntArrayVsIntegerArrayPreference(int[] items) {
- return "mIntArrayVsIntegerArrayPreference(int[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntArrayVsIntegerArrayPreference(Integer[] items) {
- return "mIntArrayVsIntegerArrayPreference(Integer[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntArrayNonOverloaded(int[] items) {
- return "mIntArrayNonOverloaded(int[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntegerArrayNonOverloaded(Integer[] items) {
- return "mIntegerArrayNonOverloaded(Integer[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntegerListNonOverloaded(List<Integer> items) {
- return "mIntegerListNonOverloaded(List<Integer> " + items + ")";
- }
-
- public String mStringListNonOverloaded(List<String> items) {
- return "mStringListNonOverloaded(List<String> " + items + ")";
- }
-
- public String mStringArrayNonOverloaded(String[] items) {
- return "mStringArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mObjectListNonOverloaded(List<Object> items) {
- return "mObjectListNonOverloaded(List<Object> " + items + ")";
- }
-
- public String mObjectArrayNonOverloaded(Object[] items) {
- return "mObjectArrayNonOverloaded(Object[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mIntegerArrayOverloaded(Integer[] items, int i) {
- return "mIntegerArrayOverloaded(Integer[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
- }
-
- public String mIntegerArrayOverloaded(Object obj, boolean b) {
- return "mIntegerArrayOverloaded(Object " + obj + ", boolean " + b + ")";
- }
-
- public String mStringArrayOverloaded(String[] items, int i) {
- return "mStringArrayOverloaded(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
- }
-
- public String mStringArrayOverloaded(Object obj, boolean b) {
- return "mStringArrayOverloaded(Object " + obj + ", boolean " + b + ")";
- }
-
- public String mCharArrayOverloaded(char[] items, int i) {
- return "mCharArrayOverloaded(char[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
- }
-
- public String mCharArrayOverloaded(Character[] items, String s) {
- return "mCharArrayOverloaded(Character[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
- }
-
- public String mCharArrayOverloaded(Object obj, boolean b) {
- return "mCharArrayOverloaded(Object " + obj + ", boolean " + b + ")";
- }
-
- public String mStringArrayArrayOverloaded(String[][] arrayArray, int i) {
- return "mStringArrayArrayOverloaded(String[][] " + TestUtil.arrayToString(arrayArray) + ", int " + i + ")";
- }
-
- public String mStringArrayArrayOverloaded(Object obj, boolean b) {
- return "mStringArrayArrayOverloaded(Object " + obj + ", boolean " + b + ")";
- }
-
- public String mIntArrayArrayOverloaded(int[][] xss) {
- return "mIntArrayArrayOverloaded(" + TestUtil.arrayToString(xss) + ")";
- }
-
- public String mIntArrayArrayOverloaded(String s) {
- return "mIntArrayArrayOverloaded(" + s + ")";
- }
-
- public String mArrayOfListsOverloaded(List[] xss) {
- return "mArrayOfListsOverloaded(" + TestUtil.arrayToString(xss) + ")";
- }
-
- public String mArrayOfListsOverloaded(String x) {
- return "mArrayOfListsOverloaded(" + x + ")";
- }
-
- public String mIntArrayArrayNonOverloaded(int[][] xss) {
- return "mIntArrayArrayNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
- }
-
- public String mArrayOfListsNonOverloaded(List[] xss) {
- return "mArrayOfListsNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
- }
-
- public String mStringArrayVarargsNonOverloaded(String... items) {
- return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded(String... items) {
- return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded1(String... items) {
- return "mStringArrayVarargsOverloaded1(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded1(List<String> items) {
- return "mStringArrayVarargsOverloaded1(List " + TestUtil.listToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded2(String... items) {
- return "mStringArrayVarargsOverloaded2(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded2(String item) {
- return "mStringArrayVarargsOverloaded2(String " + item + ")";
- }
-
- public String mStringArrayVarargsOverloaded3(String... items) {
- return "mStringArrayVarargsOverloaded3(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded3(String item1, String item2) {
- return "mStringArrayVarargsOverloaded3(String " + item1 + ", String " + item2 + ")";
- }
-
- public String mStringArrayVarargsOverloaded4(String... items) {
- return "mStringArrayVarargsOverloaded4(String[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mStringArrayVarargsOverloaded4(List... items) {
- return "mStringArrayVarargsOverloaded4(List[] " + TestUtil.arrayToString(items) + ")";
- }
-
- public String mListOrString(List<String> items) {
- return "mListOrString(List " + TestUtil.listToString(items) + ")";
- }
-
- public String mListOrString(String item) {
- return "mListOrString(String " + item + ")";
- }
-
- public String mListListOrString(List<List<Object>> items) {
- return "mListListOrString(List " + TestUtil.listToString(items) + ")";
- }
-
- public String mListListOrString(String item) {
- return "mListListOrString(String " + item + ")";
- }
-
- public String mMapOrBoolean(Map v) {
- return "mMapOrBoolean(Map " + v + ")";
- }
-
- public String mMapOrBoolean(boolean v) {
- return "mMapOrBoolean(boolean " + v + ")";
- }
-
- public String mMapOrBooleanVarargs(Map... v) {
- return "mMapOrBooleanVarargs(Map... " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mMapOrBooleanVarargs(boolean... v) {
- return "mMapOrBooleanVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mMapOrBooleanFixedAndVarargs(Map v) {
- return "mMapOrBooleanFixedAndVarargs(Map " + v + ")";
- }
-
- public String mMapOrBooleanFixedAndVarargs(boolean v) {
- return "mMapOrBooleanFixedAndVarargs(boolean " + v + ")";
- }
-
- public String mMapOrBooleanFixedAndVarargs(Map... v) {
- return "mMapOrBooleanFixedAndVarargs(Map... " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mMapOrBooleanFixedAndVarargs(boolean... v) {
- return "mMapOrBooleanFixedAndVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mNumberOrArray(Number v) {
- return "mNumberOrArray(Number " + v + ")";
- }
-
- public String mNumberOrArray(Object[] v) {
- return "mNumberOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mIntOrArray(int v) {
- return "mIntOrArray(int " + v + ")";
- }
-
- public String mIntOrArray(Object[] v) {
- return "mIntOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mDateOrArray(Date v) {
- return "mDateOrArray(Date " + v.getTime() + ")";
- }
-
- public String mDateOrArray(Object[] v) {
- return "mDateOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mStringOrArray(String v) {
- return "mStringOrArray(String " + v + ")";
- }
-
- public String mStringOrArray(Object[] v) {
- return "mStringOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mBooleanOrArray(boolean v) {
- return "mBooleanOrArray(boolean " + v + ")";
- }
-
- public String mBooleanOrArray(Object[] v) {
- return "mBooleanOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mMapOrArray(Map v) {
- return "mMapOrArray(Map " + v + ")";
- }
-
- public String mMapOrArray(Object[] v) {
- return "mMapOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mListOrArray(List v) {
- return "mListOrArray(List " + v + ")";
- }
-
- public String mListOrArray(Object[] v) {
- return "mListOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mSetOrArray(Set v) {
- return "mSetOrArray(Set " + v + ")";
- }
-
- public String mSetOrArray(Object[] v) {
- return "mSetOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
- }
-
- public String mCharNonOverloaded(char c) {
- return "mCharNonOverloaded(char " + c + ")";
- }
-
- public String mCharacterNonOverloaded(Character c) {
- return "mCharacterNonOverloaded(Character " + c + ")";
- }
-
- public String mCharOrCharacterOverloaded(char c) {
- return "mCharOrCharacterOverloaded(char " + c + ")";
- }
-
- public String mCharOrCharacterOverloaded(Character c) {
- return "mCharOrCharacterOverloaded(Character " + c + ")";
- }
-
- public String mCharOrBooleanOverloaded(char c) {
- return "mCharOrBooleanOverloaded(char " + c + ")";
- }
-
- public String mCharOrBooleanOverloaded(boolean b) {
- return "mCharOrBooleanOverloaded(boolean " + b + ")";
- }
-
- public String mCharOrStringOverloaded(char c, boolean b) {
- return "mCharOrStringOverloaded(char " + c + ", boolean " + b + ")";
- }
-
- public String mCharOrStringOverloaded(String s, int i) {
- return "mCharOrStringOverloaded(String " + s + ", int " + i + ")";
- }
-
- public String mCharacterOrStringOverloaded(Character c, boolean b) {
- return "mCharacterOrStringOverloaded(Character " + c + ", boolean " + b + ")";
- }
-
- public String mCharacterOrStringOverloaded(String s, int i) {
- return "mCharacterOrStringOverloaded(String " + s + ", int " + i + ")";
- }
-
- public String mCharOrStringOverloaded2(String s) {
- return "mCharOrStringOverloaded2(String " + s + ")";
- }
-
- public String mCharOrStringOverloaded2(char c) {
- return "mCharOrStringOverloaded2(char " + c + ")";
- }
-
- public String mCharacterOrStringOverloaded2(String s) {
- return "mCharacterOrStringOverloaded2(String " + s + ")";
- }
-
- public String mCharacterOrStringOverloaded2(Character c) {
- return "mCharacterOrStringOverloaded2(Character " + c + ")";
- }
-
-
- public String getJavaString() {
- return "s";
- }
-
- public List getJavaStringList() {
- List list = new ArrayList();
- list.add("a");
- list.add("b");
- return list;
- }
-
- public List getJavaString2List() {
- List list = new ArrayList();
- list.add("aa");
- list.add("bb");
- return list;
- }
-
- public List getJavaStringListList() {
- List listList = new ArrayList();
- {
- List list = new ArrayList();
- list.add("a");
- list.add("b");
-
- listList.add(list);
- }
- {
- List list = new ArrayList();
- list.add("c");
-
- listList.add(list);
- }
- return listList;
- }
-
- public List getJavaStringSequenceList() throws TemplateModelException {
- ObjectWrapper ow = Environment.getCurrentEnvironment().getObjectWrapper();
-
- List listList = new ArrayList();
- {
- List list = new ArrayList();
- list.add("a");
- list.add("b");
-
- listList.add(ow.wrap(list));
- }
- {
- List list = new ArrayList();
- list.add("c");
-
- listList.add(ow.wrap(list));
- }
- return listList;
- }
-
- public List<int[]> getJavaListOfIntArrays() {
- List list = new ArrayList();
- list.add(new int[] {1, 2, 3});
- list.add(new int[] {});
- list.add(new int[] {4});
- return list;
- }
-
- @SuppressWarnings("boxing")
- public List getJavaIntegerListList() {
- List listList = new ArrayList();
- {
- List list = new ArrayList();
- list.add(1);
- list.add(2);
-
- listList.add(list);
- }
- {
- List list = new ArrayList();
- list.add(3);
-
- listList.add(list);
- }
- return listList;
- }
-
- @SuppressWarnings("boxing")
- public List<Integer> getJavaIntegerList() {
- List<Integer> list = new ArrayList<>();
- list.add(1);
- list.add(2);
- return list;
- }
-
- @SuppressWarnings("boxing")
- public List<Byte> getJavaByteList() {
- List<Byte> list = new ArrayList<>();
- list.add((byte) 1);
- list.add((byte) 2);
- return list;
- }
-
- @SuppressWarnings("boxing")
- public List<Character> getJavaCharacterList() {
- List<Character> list = new ArrayList<>();
- list.add('c');
- list.add('C');
- return list;
- }
-
- public String[] getJavaStringArray() {
- return new String[] { "a", "b" };
- }
-
- public int[] getJavaIntArray() {
- return new int[] { 11, 22 };
- }
-
- public Integer[] getJavaIntegerArray() {
- return new Integer[] { Integer.valueOf(11), Integer.valueOf(22) };
- }
-
- public String[] getJavaEmptyStringArray() {
- return new String[] { };
- }
-
- public String[][] getJavaStringArrayArray() {
- return new String[][] { new String[] { "a", "b" }, new String[] { }, new String[] { "c" } };
- }
-
- public Object[] getJavaObjectArray() {
- return new Object[] { "a", "b" };
- }
-
- public TemplateModel getHashAndScalarModel() {
- return HashAndScalarModel.INSTANCE;
- }
-
- public TemplateModel getBooleanAndScalarModel() {
- return BooleanAndScalarModel.INSTANCE;
- }
-
- public TemplateModel getAllModels() {
- return AllTemplateModels.INSTANCE;
- }
-
- public TemplateNumberModel getAdaptedNumber() {
- return new MyAdapterNumberModel();
- }
-
- public TemplateNumberModel getWrapperNumber() {
- return new MyWrapperNumberModel();
- }
-
- public TemplateBooleanModel getStringAdaptedToBoolean() {
- return new MyStringAdaptedToBooleanModel();
- }
-
- public TemplateBooleanModel getStringAdaptedToBoolean2() {
- return new MyStringAdaptedToBooleanModel2();
- }
-
- public TemplateBooleanModel getStringWrappedAsBoolean() {
- return new MyStringWrapperAsBooleanModel();
- }
-
- public TemplateBooleanModel getBooleanWrappedAsAnotherBoolean() {
- return new MyBooleanWrapperAsAnotherBooleanModel();
- }
-
- public String bugReport363(Map<String, ?> fields, List<?> listField) {
- return "Executed: testMethod(Map fields, List listField) on input: fields=" + fields
- + " and listField=" + listField;
- }
-
- public String bugReport363(Object... fields) {
- return "Executed: testMethod(Object... fields) on input: fields=" + TestUtil.arrayToString(fields);
- }
-
- private static class MyAdapterNumberModel implements TemplateNumberModel, AdapterTemplateModel {
-
- @Override
- public Object getAdaptedObject(Class hint) {
- if (hint == double.class) {
- return Double.valueOf(123.0001);
- } else if (hint == Double.class) {
- return Double.valueOf(123.0002);
- } else {
- return Long.valueOf(124L);
- }
- }
-
- @Override
- public Number getAsNumber() throws TemplateModelException {
- return Integer.valueOf(122);
- }
-
- }
-
- private static class MyWrapperNumberModel implements TemplateNumberModel, WrapperTemplateModel {
-
- @Override
- public Number getAsNumber() throws TemplateModelException {
- return Integer.valueOf(122);
- }
-
- @Override
- public Object getWrappedObject() {
- return Double.valueOf(123.0001);
- }
-
- }
-
- private static class MyStringWrapperAsBooleanModel implements TemplateBooleanModel, WrapperTemplateModel {
-
- @Override
- public Object getWrappedObject() {
- return "yes";
- }
-
- @Override
- public boolean getAsBoolean() throws TemplateModelException {
- return true;
- }
-
- }
-
- private static class MyBooleanWrapperAsAnotherBooleanModel implements TemplateBooleanModel, WrapperTemplateModel {
-
- @Override
- public Object getWrappedObject() {
- return Boolean.TRUE;
- }
-
- @Override
- public boolean getAsBoolean() throws TemplateModelException {
- return false;
- }
-
- }
-
- private static class MyStringAdaptedToBooleanModel implements TemplateBooleanModel, AdapterTemplateModel {
-
- @Override
- public Object getAdaptedObject(Class hint) {
- if (hint != Boolean.class && hint != boolean.class) {
- return "yes";
- } else {
- return Boolean.TRUE;
- }
- }
-
- @Override
- public boolean getAsBoolean() throws TemplateModelException {
- return false;
- }
-
- }
-
- private static class MyStringAdaptedToBooleanModel2 implements TemplateBooleanModel, AdapterTemplateModel {
-
- @Override
- public Object getAdaptedObject(Class hint) {
- return "yes";
- }
-
- @Override
- public boolean getAsBoolean() throws TemplateModelException {
- return true;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java
deleted file mode 100644
index 85e27d7..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * A simple method model used as a test bed.
- */
-public class SimpleTestMethod implements TemplateMethodModel {
-
- /**
- * Executes a method call.
- *
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
- * the values of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
- @Override
- public Object exec(List arguments) {
- if ( arguments.size() == 0 ) {
- return new SimpleScalar( "Empty list provided" );
- } else if ( arguments.size() > 1 ) {
- return new SimpleScalar( "Argument size is: " + arguments.size() );
- } else {
- return new SimpleScalar( "Single argument value is: " + arguments.get(0) );
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
deleted file mode 100644
index 4602b67..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.Configuration;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-import org.apache.freemarker.core.util.HtmlEscape;
-import org.apache.freemarker.core.util.StandardCompress;
-
-/**
- * Part of the TestTransform testcase suite.
- */
-public class TransformHashWrapper implements TemplateHashModel,
- TemplateScalarModel {
-
- private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- private SimpleHash m_cHashModel = new SimpleHash(ow);
-
- /** Creates new TransformHashWrapper */
- public TransformHashWrapper() {
- m_cHashModel.put( "htmlEscape", new HtmlEscape() );
- m_cHashModel.put( "compress", new StandardCompress() );
- m_cHashModel.put( "escape", new TransformMethodWrapper1() );
- m_cHashModel.put( "special", new TransformMethodWrapper2() );
- }
-
- /**
- * 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) throws TemplateModelException {
- return m_cHashModel.get( key );
- }
-
- /**
- * @return true if this object is empty.
- */
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- /**
- * Returns the scalar's value as a String.
- * @return the String value of this scalar.
- */
- @Override
- public String getAsString() {
- return "Utility transformations";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java
deleted file mode 100644
index 8311134..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.util.HtmlEscape;
-import org.apache.freemarker.core.util.XmlEscape;
-
-/**
- * Simple test of the interaction between MethodModels and TransformModels.
- */
-public class TransformMethodWrapper1 implements TemplateMethodModel {
-
- /**
- * Executes a method call.
- *
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
- * the values of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
- @Override
- public Object exec(List arguments) {
-
- if (( arguments.size() > 0 ) && ( arguments.get( 0 ).toString().equals( "xml" ))) {
- return new XmlEscape();
- } else {
- return new HtmlEscape();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
deleted file mode 100644
index 96eb1a5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-
-/**
- * Another test of the interaction between MethodModels and TransformModels.
- */
-public class TransformMethodWrapper2 implements TemplateMethodModel {
-
- /**
- * Executes a method call.
- *
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
- * the values of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
- @Override
- public Object exec(List arguments) {
- TransformModel1 cTransformer = new TransformModel1();
- Iterator iArgument = arguments.iterator();
-
- // Sets up properties of the Transform model based on the arguments
- // passed into this method
-
- while ( iArgument.hasNext() ) {
- String aArgument = (String) iArgument.next();
-
- if ( aArgument.equals( "quote" )) {
- cTransformer.setQuotes( true );
- } else if ( aArgument.equals( "tag" )) {
- cTransformer.setTags( true );
- } else if ( aArgument.equals( "ampersand" )) {
- cTransformer.setAmpersands( true );
- } else {
- cTransformer.setComment( aArgument );
- }
- }
-
- // Now return the transform class.
- return cTransformer;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
deleted file mode 100644
index 0875679..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * A TemplateTransformModel that includes properties. These properties can be
- * set at model construction time, or, for the purposes of this demonstration,
- * can be passed in from a wrapper TemplateMethodModel.
- */
-public class TransformModel1 implements TemplateTransformModel {
-
- private boolean m_bAmpersands = false;
- private boolean m_bQuotes = false;
- private boolean m_bTags = false;
- private String m_aComment = "";
-
- private static final int READER_BUFFER_SIZE = 4096;
-
- @Override
- public Writer getWriter(final Writer out,
- final Map args) {
- final StringBuilder buf = new StringBuilder();
- return new Writer(out) {
- @Override
- public void write(char cbuf[], int off, int len) {
- buf.append(cbuf, off, len);
- }
-
- @Override
- public void flush() {
- }
-
- @Override
- public void close() throws IOException {
- StringReader sr = new StringReader(buf.toString());
- StringWriter sw = new StringWriter();
- transform(sr, sw);
- out.write(sw.toString());
- }
- };
- }
-
-
- /**
- * Indicates whether we escape ampersands. This property can be set either
- * while the model is being constructed, or via a property passed in through
- * a <code>TemplateMethodModel</code>.
- */
- public void setAmpersands( boolean bAmpersands ) {
- m_bAmpersands = bAmpersands;
- }
-
- /**
- * Indicates whether we escape quotes. This property can be set either
- * while the model is being constructed, or via a property passed in through
- * a <code>TemplateMethodModel</code>.
- */
- public void setQuotes( boolean bQuotes ) {
- m_bQuotes = bQuotes;
- }
-
- /**
- * Indicates whether we escape tags. This property can be set either
- * while the model is being constructed, or via a property passed in through
- * a <code>TemplateMethodModel</code>.
- */
- public void setTags( boolean bTags ) {
- m_bTags = bTags;
- }
-
- /**
- * Sets a comment for this transformation. This property can be set either
- * while the model is being constructed, or via a property passed in through
- * a <code>TemplateMethodModel</code>.
- */
- public void setComment( String aComment ) {
- m_aComment = aComment;
- }
-
- /**
- * Performs a transformation/filter on FreeMarker output.
- *
- * @param source the input to be transformed
- * @param output the destination of the transformation
- */
- public void transform(Reader source, Writer output)
- throws IOException {
- // Output the source, converting unsafe certain characters to their
- // equivalent entities.
- int n = 0;
- boolean bCommentSent = false;
- char[] aBuffer = new char[ READER_BUFFER_SIZE ];
- int i = source.read( aBuffer );
- while (i >= 0) {
- for ( int j = 0; j < i; j++ ) {
- char c = aBuffer[j];
- switch (c) {
- case '&':
- if ( m_bAmpersands ) {
- output.write("&");
- } else {
- output.write( c );
- }
- break;
- case '<':
- if ( m_bTags ) {
- output.write("<");
- } else {
- output.write( c );
- }
- break;
- case '>':
- if ( m_bTags ) {
- output.write(">");
- } else {
- output.write( c );
- }
- break;
- case '"':
- if ( m_bQuotes ) {
- output.write(""");
- } else {
- output.write( c );
- }
- break;
- case '\'':
- if ( m_bQuotes ) {
- output.write("'");
- } else {
- output.write( c );
- }
- break;
- case '*':
- if ( ! bCommentSent ) {
- output.write( m_aComment );
- bCommentSent = true;
- } else {
- output.write( c );
- }
- break;
- default:
- output.write(c);
- }
- n++;
- }
- i = source.read( aBuffer );
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
deleted file mode 100644
index 940cb17..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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;
-
-public class VarArgTestModel {
-
- public int bar(Integer... xs) {
- int sum = 0;
- for (Integer x : xs) {
- if (x != null) {
- sum *= 100;
- sum += x;
- }
- }
- return sum;
- }
-
- public int bar2(int first, int... xs) {
- int sum = 0;
- for (int x : xs) {
- sum *= 100;
- sum += x;
- }
- return -(sum * 100 + first);
- }
-
- public int overloaded(int x, int y) {
- return x * 100 + y;
- }
-
- public int overloaded(int... xs) {
- int sum = 0;
- for (int x : xs) {
- sum *= 100;
- sum += x;
- }
- return -sum;
- }
-
- public String noVarArgs(String s, boolean b, int i, Date d) {
- return s + ", " + b + ", " + i + ", " + d.getTime();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/package.html
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/package.html b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/package.html
deleted file mode 100644
index cabffb0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/package.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!--
- 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.
--->
-<html>
-<head>
-</head>
-<body>
-
-<p>JUnit test-suite that processes FreeMarker templates and compare their
-output to reference files.</p>
-
-<p>To add a test-case, go to
-<tt>src/test/resources/freemarker/test/templatesuite/</tt> and inside that
-directory:</p>
-<ol>
- <li>Add a template to under <tt>templates/</tt> with whatever meaningful
- file name</li>
- <li>Add the expected output to <tt>references/</tt> with exactly the same
- file name</li>
- <li>Add a new <tt>testcase</tt> elemen to <tt>testcases.xml</tt></li>
- <li>If you want to add items to the data-model or do something else special,
- modify the <tt>setUp()</tt> method in
- <tt>src/test/java/freemarker/test/templatesuite/TemplateTestCase.java</tt>
- </li>
-</ol>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertDirective.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertDirective.java
deleted file mode 100644
index 8f31680..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertDirective.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.NestedContentNotSupportedException;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util.FTLUtil;
-
-public class AssertDirective implements TemplateDirectiveModel {
-
- public static AssertDirective INSTANCE = new AssertDirective();
-
- private static final String TEST_PARAM = "test";
-
- private AssertDirective() { }
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- TemplateModel test = null;
- for (Object paramEnt : params.entrySet()) {
- Map.Entry<String, TemplateModel> param = (Map.Entry) paramEnt;
- String paramName = param.getKey();
- if (paramName.equals(TEST_PARAM)) {
- test = param.getValue();
- } else {
- throw new UnsupportedParameterException(paramName, env);
- }
- }
- if (test == null) {
- throw new MissingRequiredParameterException(TEST_PARAM, env);
- }
- NestedContentNotSupportedException.check(body);
-
- if (!(test instanceof TemplateBooleanModel)) {
- throw new AssertationFailedInTemplateException("Assertion failed:\n"
- + "The value had to be boolean, but it was of type" + FTLUtil.getTypeDescription(test),
- env);
- }
- if (!((TemplateBooleanModel) test).getAsBoolean()) {
- throw new AssertationFailedInTemplateException("Assertion failed:\n"
- + "the value was false.",
- env);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertEqualsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertEqualsDirective.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertEqualsDirective.java
deleted file mode 100644
index 63a9ebc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertEqualsDirective.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.NestedContentNotSupportedException;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.util._StringUtil;
-
-public class AssertEqualsDirective implements TemplateDirectiveModel {
-
- public static AssertEqualsDirective INSTANCE = new AssertEqualsDirective();
-
- private static final String ACTUAL_PARAM = "actual";
- private static final String EXPECTED_PARAM = "expected";
-
- private AssertEqualsDirective() { }
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- TemplateModel actual = null;
- TemplateModel expected = null;
- for (Object paramEnt : params.entrySet()) {
- Map.Entry<String, TemplateModel> param = (Map.Entry) paramEnt;
- String paramName = param.getKey();
- if (paramName.equals(ACTUAL_PARAM)) {
- actual = param.getValue();
- } else if (paramName.equals(EXPECTED_PARAM)) {
- expected = param.getValue();
- } else {
- throw new UnsupportedParameterException(paramName, env);
- }
- }
- if (actual == null) {
- throw new MissingRequiredParameterException(ACTUAL_PARAM, env);
- }
- if (expected == null) {
- throw new MissingRequiredParameterException(EXPECTED_PARAM, env);
- }
- NestedContentNotSupportedException.check(body);
-
- if (!env.applyEqualsOperatorLenient(actual, expected)) {
- throw new AssertationFailedInTemplateException("Assertion failed:\n"
- + "Expected: " + tryUnwrapp(expected) + "\n"
- + "Actual: " + tryUnwrapp(actual),
- env);
- }
-
- }
-
- private String tryUnwrapp(TemplateModel value) throws TemplateModelException {
- if (value == null) return "null";
- // This is the same order as comparison goes:
- else if (value instanceof TemplateNumberModel) return ((TemplateNumberModel) value).getAsNumber().toString();
- else if (value instanceof TemplateDateModel) return ((TemplateDateModel) value).getAsDate().toString();
- else if (value instanceof TemplateScalarModel) return _StringUtil.jQuote(((TemplateScalarModel) value).getAsString());
- else if (value instanceof TemplateBooleanModel) return String.valueOf(((TemplateBooleanModel) value).getAsBoolean());
- // This shouldn't be reached, as the comparison should have failed earlier:
- else return value.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertFailsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertFailsDirective.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertFailsDirective.java
deleted file mode 100644
index bd18d8d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertFailsDirective.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.util;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.util._NullWriter;
-import org.apache.freemarker.core.util._StringUtil;
-
-public class AssertFailsDirective implements TemplateDirectiveModel {
-
- public static AssertFailsDirective INSTANCE = new AssertFailsDirective();
-
- private static final String MESSAGE_PARAM = "message";
- private static final String MESSAGE_REGEXP_PARAM = "messageRegexp";
- private static final String EXCEPTION_PARAM = "exception";
- private static final String CAUSE_NESTING_LEVEL_PARAM = "causeNestingLevel";
-
- private AssertFailsDirective() { }
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- String message = null;
- Pattern messageRegexp = null;
- String exception = null;
- int causeNestingLevel = 0;
- for (Object paramEnt : params.entrySet()) {
- Map.Entry<String, TemplateModel> param = (Map.Entry) paramEnt;
- String paramName = param.getKey();
- if (paramName.equals(MESSAGE_PARAM)) {
- message = getAsString(param.getValue(), MESSAGE_PARAM, env);
- } else if (paramName.equals(MESSAGE_REGEXP_PARAM)) {
- messageRegexp = Pattern.compile(
- getAsString(param.getValue(), MESSAGE_REGEXP_PARAM, env),
- Pattern.CASE_INSENSITIVE);
- } else if (paramName.equals(EXCEPTION_PARAM)) {
- exception = getAsString(param.getValue(), EXCEPTION_PARAM, env);
- } else if (paramName.equals(CAUSE_NESTING_LEVEL_PARAM)) {
- causeNestingLevel = getAsInt(param.getValue(), CAUSE_NESTING_LEVEL_PARAM, env);
- } else {
- throw new UnsupportedParameterException(paramName, env);
- }
- }
-
- if (body != null) {
- boolean blockFailed;
- try {
- body.render(_NullWriter.INSTANCE);
- blockFailed = false;
- } catch (Throwable e) {
- blockFailed = true;
-
- int causeNestingLevelCountDown = causeNestingLevel;
- while (causeNestingLevelCountDown != 0) {
- e = e.getCause();
- if (e == null) {
- throw new AssertationFailedInTemplateException(
- "Failure is not like expected: The cause exception nesting dept was lower than "
- + causeNestingLevel + ".",
- env);
- }
- causeNestingLevelCountDown--;
- }
-
- if (message != null || messageRegexp != null) {
- if (e.getMessage() == null) {
- throw new AssertationFailedInTemplateException(
- "Failure is not like expected. The exception message was null, "
- + "and thus it doesn't contain:\n" + _StringUtil.jQuote(message) + ".",
- env);
- }
- if (message != null) {
- String actualMessage = e instanceof TemplateException
- ? ((TemplateException) e).getMessageWithoutStackTop() : e.getMessage();
- if (actualMessage.toLowerCase().indexOf(message.toLowerCase()) == -1) {
- throw new AssertationFailedInTemplateException(
- "Failure is not like expected. The exception message:\n" + _StringUtil.jQuote(actualMessage)
- + "\ndoesn't contain:\n" + _StringUtil.jQuote(message) + ".",
- env);
- }
- }
- if (messageRegexp != null) {
- if (!messageRegexp.matcher(e.getMessage()).find()) {
- throw new AssertationFailedInTemplateException(
- "Failure is not like expected. The exception message:\n" + _StringUtil.jQuote(e.getMessage())
- + "\ndoesn't match this regexp:\n" + _StringUtil.jQuote(messageRegexp.toString())
- + ".",
- env);
- }
- }
- }
- if (exception != null && e.getClass().getName().indexOf(exception) == -1) {
- throw new AssertationFailedInTemplateException(
- "Failure is not like expected. The exception class name " + _StringUtil.jQuote(e.getClass().getName())
- + " doesn't contain " + _StringUtil.jQuote(message) + ".",
- env);
- }
- }
- if (!blockFailed) {
- throw new AssertationFailedInTemplateException(
- "Block was expected to fail, but it didn't.",
- env);
- }
- }
- }
-
- private String getAsString(TemplateModel value, String paramName, Environment env)
- throws BadParameterTypeException, TemplateModelException {
- if (value instanceof TemplateScalarModel) {
- return ((TemplateScalarModel) value).getAsString();
- } else {
- throw new BadParameterTypeException(paramName, "string", value, env);
- }
- }
-
- private int getAsInt(TemplateModel value, String paramName, Environment env) throws BadParameterTypeException, TemplateModelException {
- if (value instanceof TemplateNumberModel) {
- return ((TemplateNumberModel) value).getAsNumber().intValue();
- } else {
- throw new BadParameterTypeException(paramName, "number", value, env);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertationFailedInTemplateException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertationFailedInTemplateException.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertationFailedInTemplateException.java
deleted file mode 100644
index 7a65c42..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/AssertationFailedInTemplateException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * Fills the role of {@link junit.framework.AssertionFailedError}, but carries the template location information.
- */
-public class AssertationFailedInTemplateException extends TemplateException {
-
- public AssertationFailedInTemplateException(Environment env) {
- super(env);
- }
-
- public AssertationFailedInTemplateException(String description, Environment env) {
- super(description, env);
- }
-
- public AssertationFailedInTemplateException(Exception cause, Environment env) {
- super(cause, env);
- }
-
- public AssertationFailedInTemplateException(String description, Exception cause, Environment env) {
- super(description, cause, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/BadParameterTypeException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/BadParameterTypeException.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/BadParameterTypeException.java
deleted file mode 100644
index f1230be..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/BadParameterTypeException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.util;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * Indicates that a named directive/function parameter is not of the expected type.
- * This is will be public and go into the org.apache.freemarker.core.ast when the directive/method stuff was reworked.
- */
-public class BadParameterTypeException extends ParameterException {
-
- public BadParameterTypeException(String parameterName, String expectedType, TemplateModel value, Environment env) {
- this(parameterName, expectedType, value, null, null, env);
- }
-
- public BadParameterTypeException(String parameterName, String expectedType, TemplateModel value,
- Exception cause, Environment env) {
- this(parameterName, expectedType, value, null, cause, env);
- }
-
- public BadParameterTypeException(String parameterName, String expectedType, TemplateModel value,
- String description, Environment env) {
- this(parameterName, expectedType, value, description, null, env);
- }
-
- public BadParameterTypeException(
- String parameterName, String expectedType, TemplateModel value, String description, Exception cause, Environment env) {
- super(parameterName,
- "The type of the parameter " + _StringUtil.jQuote(parameterName) + " should be " + expectedType
- + ", but the actual value was " + getTypeDescription(value) + "."
- + (description != null ? " " + _StringUtil.jQuote(description) : ""),
- cause, env);
- }
-
- private static String getTypeDescription(TemplateModel value) {
- //FIXME: This should call EvaluationUtil.getTypeDescriptionForDebugging, but that's not visible from here yet.
- return value == null ? "Null" : value.getClass().getName();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/CoreTestUtil.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/CoreTestUtil.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/CoreTestUtil.java
deleted file mode 100644
index d9770fc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/CoreTestUtil.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.apache.freemarker.test.util;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Version;
-
-public final class CoreTestUtil {
-
- private CoreTestUtil() {
- // Not meant to be instantiated
- }
-
- /**
- * Returns the closes FreeMarker version number that doesn't exit yet (so it's illegal).
- */
- public static Version getClosestFutureVersion() {
- Version v = Configuration.getVersion();
- return new Version(v.getMajor(), v.getMinor(), v.getMicro() + 1);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/util/EntirelyCustomObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/util/EntirelyCustomObjectWrapper.java b/freemarker-core/src/test/java/org/apache/freemarker/test/util/EntirelyCustomObjectWrapper.java
deleted file mode 100644
index cdcde1f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/util/EntirelyCustomObjectWrapper.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelAdapter;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleDate;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-import org.apache.freemarker.core.model.impl.SimpleNumber;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.model.impl.SimpleSequence;
-
-/**
- * An object wrapper that doesn't extend {@link DefaultObjectWrapper}.
- */
-public class EntirelyCustomObjectWrapper implements ObjectWrapper {
-
- @Override
- public TemplateModel wrap(Object obj) throws TemplateModelException {
- if (obj == null) {
- return null;
- }
-
- if (obj instanceof TemplateModel) {
- return (TemplateModel) obj;
- }
- if (obj instanceof TemplateModelAdapter) {
- return ((TemplateModelAdapter) obj).getTemplateModel();
- }
-
- if (obj instanceof String) {
- return new SimpleScalar((String) obj);
- }
- if (obj instanceof Number) {
- return new SimpleNumber((Number) obj);
- }
- if (obj instanceof Boolean) {
- return obj.equals(Boolean.TRUE) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
- }
- if (obj instanceof java.util.Date) {
- if (obj instanceof java.sql.Date) {
- return new SimpleDate((java.sql.Date) obj);
- }
- if (obj instanceof java.sql.Time) {
- return new SimpleDate((java.sql.Time) obj);
- }
- if (obj instanceof java.sql.Timestamp) {
- return new SimpleDate((java.sql.Timestamp) obj);
- }
- return new SimpleDate((java.util.Date) obj, TemplateDateModel.UNKNOWN);
- }
-
- if (obj.getClass().isArray()) {
- obj = Arrays.asList((Object[]) obj);
- }
- if (obj instanceof Collection) {
- return new SimpleSequence((Collection<?>) obj, this);
- }
- if (obj instanceof Map) {
- return new SimpleHash((Map<?, ?>) obj, this);
- }
-
- return null;
- }
-}
[51/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
Posted by dd...@apache.org.
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 consequence of this, freemarker-core tests were moved into their own project, freemarker-core-test (and freemarker-core-test-java8, which has existed earlier too).
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/28a276c8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/28a276c8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/28a276c8
Branch: refs/heads/3
Commit: 28a276c80496b164b35a8dc04d6ad87ea1ddc800
Parents: b053951
Author: ddekany <dd...@apache.org>
Authored: Mon May 15 20:46:41 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Mon May 15 23:22:55 2017 +0200
----------------------------------------------------------------------
freemarker-core-java8-test/build.gradle | 19 -
.../src/main/resources/META-INF/DISCLAIMER | 8 -
.../src/main/resources/META-INF/LICENSE | 202 ---
.../core/model/impl/BridgeMethodsBean.java | 30 -
.../core/model/impl/BridgeMethodsBeanBase.java | 29 -
...Java8BridgeMethodsWithDefaultMethodBean.java | 29 -
...ava8BridgeMethodsWithDefaultMethodBean2.java | 23 -
...8BridgeMethodsWithDefaultMethodBeanBase.java | 31 -
...BridgeMethodsWithDefaultMethodBeanBase2.java | 28 -
.../model/impl/Java8DefaultMethodsBean.java | 84 -
.../model/impl/Java8DefaultMethodsBeanBase.java | 97 --
...a8DefaultObjectWrapperBridgeMethodsTest.java | 65 -
.../impl/Java8DefaultObjectWrapperTest.java | 160 --
freemarker-core-test-java8/build.gradle | 25 +
.../src/main/resources/META-INF/DISCLAIMER | 8 +
.../src/main/resources/META-INF/LICENSE | 202 +++
.../core/model/impl/BridgeMethodsBean.java | 30 +
.../core/model/impl/BridgeMethodsBeanBase.java | 29 +
...Java8BridgeMethodsWithDefaultMethodBean.java | 29 +
...ava8BridgeMethodsWithDefaultMethodBean2.java | 23 +
...8BridgeMethodsWithDefaultMethodBeanBase.java | 31 +
...BridgeMethodsWithDefaultMethodBeanBase2.java | 28 +
.../model/impl/Java8DefaultMethodsBean.java | 84 +
.../model/impl/Java8DefaultMethodsBeanBase.java | 97 ++
...a8DefaultObjectWrapperBridgeMethodsTest.java | 65 +
.../impl/Java8DefaultObjectWrapperTest.java | 160 ++
freemarker-core-test/build.gradle | 19 +
.../core/ASTBasedErrorMessagesTest.java | 74 +
.../org/apache/freemarker/core/ASTPrinter.java | 438 +++++
.../org/apache/freemarker/core/ASTTest.java | 103 ++
.../core/ActualNamingConvetionTest.java | 66 +
.../freemarker/core/ActualTagSyntaxTest.java | 68 +
.../freemarker/core/BreakPlacementTest.java | 56 +
.../apache/freemarker/core/CamelCaseTest.java | 486 ++++++
.../freemarker/core/CanonicalFormTest.java | 68 +
.../freemarker/core/CoercionToTextualTest.java | 149 ++
.../freemarker/core/ConfigurableTest.java | 176 ++
.../freemarker/core/ConfigurationTest.java | 1486 +++++++++++++++++
.../freemarker/core/CoreLocaleUtilsTest.java | 73 +
.../freemarker/core/CustomAttributeTest.java | 163 ++
.../apache/freemarker/core/DateFormatTest.java | 464 ++++++
.../freemarker/core/DirectiveCallPlaceTest.java | 249 +++
.../freemarker/core/EncodingOverrideTest.java | 62 +
.../EnvironmentGetTemplateVariantsTest.java | 214 +++
.../apache/freemarker/core/ExceptionTest.java | 115 ++
.../apache/freemarker/core/GetSourceTest.java | 52 +
.../freemarker/core/HeaderParsingTest.java | 60 +
.../IncludeAndImportConfigurableLayersTest.java | 354 +++++
.../freemarker/core/IncludeAndImportTest.java | 270 ++++
.../freemarker/core/IncudeFromNamelessTest.java | 58 +
.../core/InterpretAndEvalTemplateNameTest.java | 70 +
.../core/InterpretSettingInheritanceTest.java | 104 ++
.../freemarker/core/IteratorIssuesTest.java | 64 +
.../core/JavaCCExceptionAsEOFFixTest.java | 126 ++
.../apache/freemarker/core/ListErrorsTest.java | 130 ++
.../freemarker/core/MiscErrorMessagesTest.java | 48 +
.../core/MistakenlyPublicImportAPIsTest.java | 104 ++
.../core/MistakenlyPublicMacroAPIsTest.java | 88 +
.../core/NewBiObjectWrapperRestrictionTest.java | 117 ++
.../core/ObjectBuilderSettingsTest.java | 1499 ++++++++++++++++++
.../core/OptInTemplateClassResolverTest.java | 230 +++
.../freemarker/core/OutputFormatTest.java | 1068 +++++++++++++
.../ParseTimeParameterBIErrorMessagesTest.java | 46 +
.../core/ParsingErrorMessagesTest.java | 116 ++
.../core/RestrictedObjectWrapperTest.java | 72 +
.../core/RestrictedObjetWrapperTest.java | 112 ++
.../apache/freemarker/core/SQLTimeZoneTest.java | 371 +++++
.../freemarker/core/SettingDirectiveTest.java | 40 +
.../freemarker/core/SpecialVariableTest.java | 114 ++
.../core/StringLiteralInterpolationTest.java | 135 ++
.../org/apache/freemarker/core/TabSizeTest.java | 91 ++
.../core/TagSyntaxVariationsTest.java | 186 +++
.../core/TemplateConfigurationTest.java | 909 +++++++++++
...gurationWithDefaultTemplateResolverTest.java | 267 ++++
.../core/TemplateConstructorsTest.java | 113 ++
.../core/TemplateGetEncodingTest.java | 64 +
.../core/TemplateLookupStrategyTest.java | 669 ++++++++
.../core/TemplateNameSpecialVariablesTest.java | 159 ++
.../core/TemplateNotFoundMessageTest.java | 207 +++
.../core/TheadInterruptingSupportTest.java | 163 ++
.../freemarker/core/TypeErrorMessagesTest.java | 105 ++
.../freemarker/core/UnclosedCommentTest.java | 41 +
.../org/apache/freemarker/core/VersionTest.java | 227 +++
.../core/WhitespaceStrippingTest.java | 63 +
.../freemarker/core/XHTMLOutputFormatTest.java | 59 +
.../freemarker/core/XMLOutputFormatTest.java | 59 +
.../impl/AbstractParallelIntrospectionTest.java | 126 ++
.../model/impl/AlphabeticalMethodSorter.java | 45 +
.../CommonSupertypeForUnwrappingHintTest.java | 129 ++
.../model/impl/DefaultObjectWrapperDesc.java | 31 +
.../model/impl/DefaultObjectWrapperInc.java | 31 +
...jectWrapperModelFactoryRegistrationTest.java | 63 +
.../DefaultObjectWrapperSingletonsTest.java | 675 ++++++++
.../model/impl/DefaultObjectWrapperTest.java | 901 +++++++++++
.../core/model/impl/EnumModelsTest.java | 85 +
.../core/model/impl/ErrorMessagesTest.java | 170 ++
.../impl/FineTuneMethodAppearanceTest.java | 65 +
.../GetlessMethodsAsPropertyGettersRule.java | 67 +
.../core/model/impl/IsApplicableTest.java | 171 ++
.../impl/IsMoreSpecificParameterTypeTest.java | 98 ++
.../Java7MembersOnlyDefaultObjectWrapper.java | 101 ++
.../impl/ManyObjectsOfDifferentClasses.java | 249 +++
.../impl/ManyStaticsOfDifferentClasses.java | 236 +++
.../model/impl/MiscNumericalOperationsTest.java | 111 ++
.../model/impl/ModelAPINewInstanceTest.java | 134 ++
.../core/model/impl/ModelCacheTest.java | 71 +
.../model/impl/OverloadedNumberUtilTest.java | 585 +++++++
.../impl/ParameterListPreferabilityTest.java | 445 ++++++
.../impl/PrallelObjectIntrospectionTest.java | 43 +
.../impl/PrallelStaticIntrospectionTest.java | 47 +
.../core/model/impl/RationalNumber.java | 90 ++
.../core/model/impl/StaticModelsTest.java | 91 ++
.../core/model/impl/TypeFlagsTest.java | 671 ++++++++
.../core/outputformat/_OutputFormatTestAPI.java | 35 +
.../impl/CombinedMarkupOutputFormatTest.java | 194 +++
.../outputformat/impl/HTMLOutputFormatTest.java | 187 +++
.../outputformat/impl/RTFOutputFormatTest.java | 129 ++
.../DefaultTemplateResolverTest.java | 365 +++++
.../FileTemplateLoaderTest.java | 122 ++
.../MultiTemplateLoaderTest.java | 99 ++
.../TemplateConfigurationFactoryTest.java | 203 +++
.../TemplateNameFormatTest.java | 330 ++++
.../TemplateSourceMatcherTest.java | 188 +++
.../AppMetaTemplateDateFormatFactory.java | 129 ++
.../BaseNTemplateNumberFormatFactory.java | 128 ++
.../core/userpkg/CustomHTMLOutputFormat.java | 72 +
.../core/userpkg/CustomTemplateHTMLModel.java | 34 +
.../core/userpkg/DummyOutputFormat.java | 65 +
...EpochMillisDivTemplateDateFormatFactory.java | 102 ++
.../EpochMillisTemplateDateFormatFactory.java | 92 ++
.../HTMLISOTemplateDateFormatFactory.java | 114 ++
.../userpkg/HexTemplateNumberFormatFactory.java | 77 +
...AndTZSensitiveTemplateDateFormatFactory.java | 97 ++
...aleSensitiveTemplateNumberFormatFactory.java | 78 +
.../core/userpkg/PackageVisibleAll.java | 26 +
.../userpkg/PackageVisibleAllWithBuilder.java | 26 +
.../PackageVisibleAllWithBuilderBuilder.java | 28 +
.../PackageVisibleWithPublicConstructor.java | 27 +
.../PrintfGTemplateNumberFormatFactory.java | 138 ++
.../freemarker/core/userpkg/PublicAll.java | 24 +
.../userpkg/PublicWithMixedConstructors.java | 38 +
.../PublicWithPackageVisibleConstructor.java | 26 +
.../core/userpkg/SeldomEscapedOutputFormat.java | 71 +
.../core/userpkg/TemplateDummyOutputModel.java | 34 +
.../TemplateSeldomEscapedOutputModel.java | 34 +
.../freemarker/core/util/DateUtilTest.java | 1085 +++++++++++++
.../freemarker/core/util/FTLUtilTest.java | 117 ++
.../freemarker/core/util/NumberUtilTest.java | 215 +++
.../freemarker/core/util/StringUtilTest.java | 403 +++++
.../core/valueformat/NumberFormatTest.java | 365 +++++
.../impl/ExtendedDecimalFormatTest.java | 343 ++++
.../apache/freemarker/dom/DOMSiblingTest.java | 99 ++
.../freemarker/dom/DOMSimplifiersTest.java | 201 +++
.../java/org/apache/freemarker/dom/DOMTest.java | 159 ++
.../manualtest/AutoEscapingExample.java | 72 +
.../ConfigureOutputFormatExamples.java | 105 ++
.../manualtest/CustomFormatsExample.java | 84 +
.../manualtest/GettingStartedExample.java | 69 +
.../apache/freemarker/manualtest/Product.java | 49 +
.../TemplateConfigurationExamples.java | 191 +++
.../UnitAwareTemplateNumberFormatFactory.java | 80 +
.../UnitAwareTemplateNumberModel.java | 43 +
.../test/templatesuite/TemplateTestCase.java | 515 ++++++
.../test/templatesuite/TemplateTestSuite.java | 298 ++++
.../templatesuite/models/AllTemplateModels.java | 128 ++
.../templatesuite/models/BeanTestClass.java | 93 ++
.../templatesuite/models/BeanTestInterface.java | 25 +
.../models/BeanTestSuperclass.java | 30 +
.../models/BooleanAndScalarModel.java | 40 +
.../models/BooleanAndStringTemplateModel.java | 38 +
.../test/templatesuite/models/BooleanHash1.java | 58 +
.../test/templatesuite/models/BooleanHash2.java | 50 +
.../test/templatesuite/models/BooleanList1.java | 62 +
.../test/templatesuite/models/BooleanList2.java | 53 +
.../models/BooleanVsStringMethods.java | 40 +
.../templatesuite/models/EnumTestClass.java | 34 +
.../templatesuite/models/ExceptionModel.java | 39 +
.../models/HashAndScalarModel.java | 84 +
.../templatesuite/models/JavaObjectInfo.java | 35 +
.../test/templatesuite/models/Listables.java | 185 +++
.../test/templatesuite/models/MultiModel1.java | 116 ++
.../test/templatesuite/models/MultiModel2.java | 63 +
.../test/templatesuite/models/MultiModel3.java | 69 +
.../test/templatesuite/models/MultiModel4.java | 77 +
.../test/templatesuite/models/MultiModel5.java | 81 +
.../test/templatesuite/models/NewTestModel.java | 52 +
.../templatesuite/models/NewTestModel2.java | 52 +
.../models/NumberAndStringModel.java | 47 +
.../models/OverloadedConstructor.java | 46 +
.../templatesuite/models/OverloadedMethods.java | 191 +++
.../models/OverloadedMethods2.java | 1110 +++++++++++++
.../SimpleMapAndCollectionObjectWrapper.java | 60 +
.../templatesuite/models/SimpleTestMethod.java | 49 +
.../models/TransformHashWrapper.java | 79 +
.../models/TransformMethodWrapper1.java | 49 +
.../models/TransformMethodWrapper2.java | 64 +
.../templatesuite/models/TransformModel1.java | 175 ++
.../templatesuite/models/VarArgTestModel.java | 63 +
.../freemarker/test/templatesuite/package.html | 42 +
.../org/apache/freemarker/core/ast-1.ast | 187 +++
.../org/apache/freemarker/core/ast-1.ftl | 29 +
.../apache/freemarker/core/ast-assignments.ast | 172 ++
.../apache/freemarker/core/ast-assignments.ftl | 29 +
.../org/apache/freemarker/core/ast-builtins.ast | 59 +
.../org/apache/freemarker/core/ast-builtins.ftl | 23 +
.../apache/freemarker/core/ast-locations.ast | 155 ++
.../apache/freemarker/core/ast-locations.ftl | 36 +
.../core/ast-mixedcontentsimplifications.ast | 38 +
.../core/ast-mixedcontentsimplifications.ftl | 26 +
.../core/ast-multipleignoredchildren.ast | 30 +
.../core/ast-multipleignoredchildren.ftl | 33 +
.../core/ast-nestedignoredchildren.ast | 20 +
.../core/ast-nestedignoredchildren.ftl | 19 +
.../org/apache/freemarker/core/ast-range.ast | 281 ++++
.../org/apache/freemarker/core/ast-range.ftl | 47 +
.../freemarker/core/ast-strlitinterpolation.ast | 82 +
.../freemarker/core/ast-strlitinterpolation.ftl | 25 +
.../freemarker/core/ast-whitespacestripping.ast | 70 +
.../freemarker/core/ast-whitespacestripping.ftl | 40 +
.../apache/freemarker/core/cano-assignments.ftl | 35 +
.../freemarker/core/cano-assignments.ftl.out | 34 +
.../apache/freemarker/core/cano-builtins.ftl | 23 +
.../freemarker/core/cano-builtins.ftl.out | 23 +
.../core/cano-identifier-escaping.ftl | 76 +
.../core/cano-identifier-escaping.ftl.out | 44 +
.../org/apache/freemarker/core/cano-macros.ftl | 29 +
.../apache/freemarker/core/cano-macros.ftl.out | 28 +
.../core/cano-strlitinterpolation.ftl | 19 +
.../core/cano-strlitinterpolation.ftl.out | 19 +
.../core/encodingOverride-ISO-8859-1.ftl | 20 +
.../freemarker/core/encodingOverride-UTF-8.ftl | 20 +
.../freemarker/core/templateresolver/test.ftl | 19 +
.../org/apache/freemarker/core/toCache1.ftl | 19 +
.../org/apache/freemarker/core/toCache2.ftl | 19 +
.../apache/freemarker/dom/DOMSiblingTest.xml | 31 +
.../manualtest/AutoEscapingExample-capture.ftlh | 21 +
.../AutoEscapingExample-capture.ftlh.out | 20 +
.../manualtest/AutoEscapingExample-convert.ftlh | 27 +
.../AutoEscapingExample-convert.ftlh.out | 25 +
.../manualtest/AutoEscapingExample-convert2.ftl | 25 +
.../AutoEscapingExample-convert2.ftl.out | 21 +
.../manualtest/AutoEscapingExample-infoBox.ftlh | 26 +
.../AutoEscapingExample-infoBox.ftlh.out | 25 +
.../manualtest/AutoEscapingExample-markup.ftlh | 28 +
.../AutoEscapingExample-markup.ftlh.out | 26 +
.../AutoEscapingExample-stringConcat.ftlh | 19 +
.../AutoEscapingExample-stringConcat.ftlh.out | 19 +
.../AutoEscapingExample-stringLiteral.ftlh | 21 +
.../AutoEscapingExample-stringLiteral.ftlh.out | 20 +
.../AutoEscapingExample-stringLiteral2.ftlh | 25 +
.../AutoEscapingExample-stringLiteral2.ftlh.out | 21 +
.../ConfigureOutputFormatExamples1.properties | 21 +
.../ConfigureOutputFormatExamples2.properties | 31 +
.../manualtest/CustomFormatsExample-alias1.ftlh | 22 +
.../CustomFormatsExample-alias1.ftlh.out | 22 +
.../manualtest/CustomFormatsExample-alias2.ftlh | 19 +
.../CustomFormatsExample-alias2.ftlh.out | 19 +
.../CustomFormatsExample-modelAware.ftlh | 20 +
.../CustomFormatsExample-modelAware.ftlh.out | 20 +
.../TemplateConfigurationExamples1.properties | 25 +
.../TemplateConfigurationExamples2.properties | 32 +
.../TemplateConfigurationExamples3.properties | 47 +
.../org/apache/freemarker/manualtest/test.ftlh | 28 +
.../org/apache/freemarker/test/servlet/web.xml | 101 ++
.../test/templatesuite/expected/arithmetic.txt | 46 +
.../expected/boolean-formatting.txt | 31 +
.../test/templatesuite/expected/boolean.txt | 102 ++
.../expected/charset-in-header.txt | 26 +
.../test/templatesuite/expected/comment.txt | 34 +
.../test/templatesuite/expected/comparisons.txt | 93 ++
.../test/templatesuite/expected/compress.txt | 40 +
.../templatesuite/expected/dateformat-java.txt | 55 +
.../expected/default-object-wrapper.txt | 55 +
.../templatesuite/expected/default-xmlns.txt | 25 +
.../test/templatesuite/expected/default.txt | 26 +
.../expected/encoding-builtins.txt | 44 +
.../test/templatesuite/expected/escapes.txt | 49 +
.../test/templatesuite/expected/exception.txt | 43 +
.../test/templatesuite/expected/exception2.txt | 47 +
.../test/templatesuite/expected/exception3.txt | 21 +
.../test/templatesuite/expected/exthash.txt | 76 +
.../test/templatesuite/expected/hashconcat.txt | 138 ++
.../test/templatesuite/expected/hashliteral.txt | 74 +
.../test/templatesuite/expected/helloworld.txt | 31 +
.../expected/identifier-escaping.txt | 57 +
.../expected/identifier-non-ascii.txt | 19 +
.../test/templatesuite/expected/if.txt | 104 ++
.../test/templatesuite/expected/import.txt | 40 +
.../test/templatesuite/expected/include.txt | 67 +
.../test/templatesuite/expected/include2.txt | 28 +
.../test/templatesuite/expected/interpret.txt | 23 +
.../test/templatesuite/expected/iterators.txt | 84 +
.../templatesuite/expected/lastcharacter.txt | 31 +
.../test/templatesuite/expected/list-bis.txt | 51 +
.../test/templatesuite/expected/list.txt | 51 +
.../test/templatesuite/expected/list2.txt | 211 +++
.../test/templatesuite/expected/list3.txt | 57 +
.../test/templatesuite/expected/listhash.txt | 157 ++
.../templatesuite/expected/listhashliteral.txt | 36 +
.../test/templatesuite/expected/listliteral.txt | 75 +
.../templatesuite/expected/localization.txt | 32 +
.../test/templatesuite/expected/logging.txt | 27 +
.../templatesuite/expected/loopvariable.txt | 54 +
.../templatesuite/expected/macros-return.txt | 23 +
.../test/templatesuite/expected/macros.txt | 67 +
.../test/templatesuite/expected/macros2.txt | 22 +
.../test/templatesuite/expected/multimodels.txt | 93 ++
.../test/templatesuite/expected/nested.txt | 25 +
.../expected/new-allowsnothing.txt | 19 +
.../expected/new-defaultresolver.txt | 19 +
.../test/templatesuite/expected/new-optin.txt | 32 +
.../test/templatesuite/expected/newlines1.txt | 29 +
.../test/templatesuite/expected/newlines2.txt | 30 +
.../test/templatesuite/expected/noparse.txt | 54 +
.../templatesuite/expected/number-format.txt | 33 +
.../templatesuite/expected/number-literal.txt | 79 +
.../templatesuite/expected/number-to-date.txt | 31 +
.../templatesuite/expected/numerical-cast.txt | 462 ++++++
.../templatesuite/expected/output-encoding1.txt | 27 +
.../templatesuite/expected/output-encoding2.txt | Bin 0 -> 1972 bytes
.../templatesuite/expected/output-encoding3.txt | 26 +
.../test/templatesuite/expected/precedence.txt | 48 +
.../test/templatesuite/expected/recover.txt | 26 +
.../test/templatesuite/expected/root.txt | 44 +
.../expected/sequence-builtins.txt | 404 +++++
.../test/templatesuite/expected/specialvars.txt | 25 +
.../string-builtins-regexps-matches.txt | 99 ++
.../expected/string-builtins-regexps.txt | 112 ++
.../templatesuite/expected/string-builtins1.txt | 112 ++
.../templatesuite/expected/string-builtins2.txt | 135 ++
.../templatesuite/expected/stringbimethods.txt | 29 +
.../templatesuite/expected/stringliteral.txt | Bin 0 -> 1550 bytes
.../test/templatesuite/expected/switch.txt | 80 +
.../test/templatesuite/expected/transforms.txt | 68 +
.../templatesuite/expected/type-builtins.txt | 33 +
.../test/templatesuite/expected/var-layers.txt | 37 +
.../test/templatesuite/expected/varargs.txt | 44 +
.../test/templatesuite/expected/variables.txt | 62 +
.../templatesuite/expected/whitespace-trim.txt | 60 +
.../templatesuite/expected/wstrip-in-header.txt | 23 +
.../test/templatesuite/expected/wstripping.txt | 39 +
.../templatesuite/expected/xml-fragment.txt | 25 +
.../expected/xml-ns_prefix-scope.txt | 29 +
.../test/templatesuite/expected/xml.txt | 65 +
.../test/templatesuite/expected/xmlns1.txt | 63 +
.../test/templatesuite/expected/xmlns3.txt | 47 +
.../test/templatesuite/expected/xmlns4.txt | 47 +
.../test/templatesuite/expected/xmlns5.txt | 26 +
.../models/BeansTestResources.properties | 19 +
.../test/templatesuite/models/defaultxmlns1.xml | 24 +
.../models/xml-ns_prefix-scope.xml | 26 +
.../test/templatesuite/models/xml.xml | 31 +
.../test/templatesuite/models/xmlfragment.xml | 19 +
.../test/templatesuite/models/xmlns.xml | 32 +
.../test/templatesuite/models/xmlns2.xml | 32 +
.../test/templatesuite/models/xmlns3.xml | 32 +
.../templatesuite/templates/api-builtins.ftl | 40 +
.../test/templatesuite/templates/arithmetic.ftl | 50 +
.../templatesuite/templates/assignments.ftl | 108 ++
.../templates/boolean-formatting.ftl | 82 +
.../test/templatesuite/templates/boolean.ftl | 142 ++
.../templates/charset-in-header.ftl | 27 +
.../templates/charset-in-header_inc1.ftl | 20 +
.../templates/charset-in-header_inc2.ftl | 19 +
.../test/templatesuite/templates/comment.ftl | 50 +
.../templatesuite/templates/comparisons.ftl | 218 +++
.../test/templatesuite/templates/compress.ftl | 59 +
.../templates/date-type-builtins.ftl | 47 +
.../templates/dateformat-iso-bi.ftl | 163 ++
.../templates/dateformat-iso-like.ftl | 155 ++
.../templatesuite/templates/dateformat-java.ftl | 71 +
.../templatesuite/templates/dateparsing.ftl | 84 +
.../templates/default-object-wrapper.ftl | 59 +
.../templatesuite/templates/default-xmlns.ftl | 28 +
.../test/templatesuite/templates/default.ftl | 34 +
.../templates/encoding-builtins.ftl | 52 +
.../test/templatesuite/templates/escapes.ftl | 79 +
.../test/templatesuite/templates/exception.ftl | 31 +
.../test/templatesuite/templates/exception2.ftl | 31 +
.../test/templatesuite/templates/exception3.ftl | 31 +
.../templates/existence-operators.ftl | 141 ++
.../test/templatesuite/templates/hashconcat.ftl | 60 +
.../templatesuite/templates/hashliteral.ftl | 100 ++
.../test/templatesuite/templates/helloworld.ftl | 30 +
.../templates/identifier-escaping.ftl | 81 +
.../templates/identifier-non-ascii.ftl | 21 +
.../test/templatesuite/templates/if.ftl | 109 ++
.../test/templatesuite/templates/import.ftl | 45 +
.../test/templatesuite/templates/import_lib.ftl | 31 +
.../test/templatesuite/templates/include.ftl | 47 +
.../templates/include2-included.ftl | 19 +
.../test/templatesuite/templates/include2.ftl | 32 +
.../test/templatesuite/templates/included.ftl | 30 +
.../test/templatesuite/templates/interpret.ftl | 25 +
.../test/templatesuite/templates/iterators.ftl | 71 +
.../templatesuite/templates/lastcharacter.ftl | 31 +
.../test/templatesuite/templates/list-bis.ftl | 48 +
.../test/templatesuite/templates/list.ftl | 44 +
.../test/templatesuite/templates/list2.ftl | 90 ++
.../test/templatesuite/templates/list3.ftl | 70 +
.../test/templatesuite/templates/listhash.ftl | 70 +
.../templatesuite/templates/listhashliteral.ftl | 35 +
.../templatesuite/templates/listliteral.ftl | 84 +
.../templatesuite/templates/localization.ftl | 32 +
.../templatesuite/templates/localization_en.ftl | 32 +
.../templates/localization_en_AU.ftl | 32 +
.../test/templatesuite/templates/logging.ftl | 42 +
.../templatesuite/templates/loopvariable.ftl | 49 +
.../templatesuite/templates/macros-return.ftl | 34 +
.../test/templatesuite/templates/macros.ftl | 101 ++
.../test/templatesuite/templates/macros2.ftl | 35 +
.../templatesuite/templates/multimodels.ftl | 84 +
.../test/templatesuite/templates/nested.ftl | 29 +
.../templatesuite/templates/nestedinclude.ftl | 21 +
.../templates/new-defaultresolver.ftl | 23 +
.../test/templatesuite/templates/new-optin.ftl | 30 +
.../test/templatesuite/templates/newlines1.ftl | 29 +
.../test/templatesuite/templates/newlines2.ftl | 33 +
.../test/templatesuite/templates/noparse.ftl | 62 +
.../templatesuite/templates/number-format.ftl | 42 +
.../templatesuite/templates/number-literal.ftl | 133 ++
.../templates/number-math-builtins.ftl | 78 +
.../templatesuite/templates/number-to-date.ftl | 35 +
.../templatesuite/templates/numerical-cast.ftl | 82 +
.../templates/output-encoding1.ftl | 30 +
.../templates/output-encoding2.ftl | 28 +
.../templates/output-encoding3.ftl | 28 +
.../templates/overloaded-methods.ftl | 411 +++++
.../test/templatesuite/templates/precedence.ftl | 61 +
.../templatesuite/templates/range-common.ftl | 314 ++++
.../test/templatesuite/templates/range.ftl | 50 +
.../test/templatesuite/templates/recover.ftl | 47 +
.../test/templatesuite/templates/root.ftl | 47 +
.../templates/sequence-builtins.ftl | 360 +++++
.../test/templatesuite/templates/setting.ftl | 53 +
.../templates/simplehash-char-key.ftl | 44 +
.../templatesuite/templates/specialvars.ftl | 38 +
.../templates/string-builtin-coercion.ftl | 34 +
.../string-builtins-regexps-matches.ftl | 118 ++
.../templates/string-builtins-regexps.ftl | 136 ++
.../templates/string-builtins1.ftl | 129 ++
.../templates/string-builtins2.ftl | 135 ++
.../templates/string-builtins3.ftl | 225 +++
.../templatesuite/templates/stringbimethods.ftl | 36 +
.../templatesuite/templates/stringliteral.ftl | 69 +
.../templates/subdir/include-subdir.ftl | 27 +
.../templates/subdir/include-subdir2.ftl | 19 +
.../templates/subdir/new-optin-2.ftl | 24 +
.../templates/subdir/new-optin.ftl | 26 +
.../templates/subdir/subsub/new-optin.ftl | 24 +
.../templatesuite/templates/switch-builtin.ftl | 54 +
.../test/templatesuite/templates/switch.ftl | 139 ++
.../templatesuite/templates/then-builtin.ftl | 53 +
.../test/templatesuite/templates/transforms.ftl | 100 ++
.../templatesuite/templates/type-builtins.ftl | 44 +
.../test/templatesuite/templates/undefined.ftl | 19 +
.../test/templatesuite/templates/url.ftl | 24 +
.../test/templatesuite/templates/var-layers.ftl | 39 +
.../test/templatesuite/templates/varargs.ftl | 45 +
.../test/templatesuite/templates/variables.ftl | 70 +
.../templatesuite/templates/varlayers_lib.ftl | 28 +
.../templatesuite/templates/whitespace-trim.ftl | 102 ++
.../templates/wsstripinheader_inc.ftl | 22 +
.../templates/wstrip-in-header.ftl | 26 +
.../templatesuite/templates/xml-fragment.ftl | 26 +
.../templates/xml-ns_prefix-scope-lib.ftl | 23 +
.../templates/xml-ns_prefix-scope-main.ftl | 36 +
.../test/templatesuite/templates/xml.ftl | 47 +
.../test/templatesuite/templates/xmlns1.ftl | 53 +
.../test/templatesuite/templates/xmlns3.ftl | 70 +
.../test/templatesuite/templates/xmlns4.ftl | 70 +
.../test/templatesuite/templates/xmlns5.ftl | 28 +
.../freemarker/test/templatesuite/testcases.xml | 211 +++
freemarker-core/src/test/README.txt | 7 +
.../core/ASTBasedErrorMessagesTest.java | 74 -
.../org/apache/freemarker/core/ASTPrinter.java | 438 -----
.../org/apache/freemarker/core/ASTTest.java | 103 --
.../core/ActualNamingConvetionTest.java | 66 -
.../freemarker/core/ActualTagSyntaxTest.java | 68 -
.../freemarker/core/BreakPlacementTest.java | 56 -
.../apache/freemarker/core/CamelCaseTest.java | 486 ------
.../freemarker/core/CanonicalFormTest.java | 68 -
.../freemarker/core/CoercionToTextualTest.java | 149 --
.../freemarker/core/ConfigurableTest.java | 176 --
.../freemarker/core/ConfigurationTest.java | 1486 -----------------
.../freemarker/core/CoreLocaleUtilsTest.java | 73 -
.../freemarker/core/CustomAttributeTest.java | 163 --
.../apache/freemarker/core/DateFormatTest.java | 464 ------
.../freemarker/core/DirectiveCallPlaceTest.java | 249 ---
.../freemarker/core/EncodingOverrideTest.java | 62 -
.../EnvironmentGetTemplateVariantsTest.java | 214 ---
.../apache/freemarker/core/ExceptionTest.java | 115 --
.../apache/freemarker/core/GetSourceTest.java | 52 -
.../freemarker/core/HeaderParsingTest.java | 60 -
.../IncludeAndImportConfigurableLayersTest.java | 354 -----
.../freemarker/core/IncludeAndImportTest.java | 270 ----
.../freemarker/core/IncudeFromNamelessTest.java | 58 -
.../core/InterpretAndEvalTemplateNameTest.java | 70 -
.../core/InterpretSettingInheritanceTest.java | 104 --
.../freemarker/core/IteratorIssuesTest.java | 64 -
.../core/JavaCCExceptionAsEOFFixTest.java | 126 --
.../apache/freemarker/core/ListErrorsTest.java | 130 --
.../freemarker/core/MiscErrorMessagesTest.java | 48 -
.../core/MistakenlyPublicImportAPIsTest.java | 104 --
.../core/MistakenlyPublicMacroAPIsTest.java | 88 -
.../core/NewBiObjectWrapperRestrictionTest.java | 50 -
.../core/ObjectBuilderSettingsTest.java | 1499 ------------------
.../core/OptInTemplateClassResolverTest.java | 230 ---
.../freemarker/core/OutputFormatTest.java | 1068 -------------
.../ParseTimeParameterBIErrorMessagesTest.java | 46 -
.../core/ParsingErrorMessagesTest.java | 116 --
.../core/RestrictedObjectWrapperTest.java | 72 -
.../core/RestrictedObjetWrapperTest.java | 112 --
.../apache/freemarker/core/SQLTimeZoneTest.java | 371 -----
.../freemarker/core/SettingDirectiveTest.java | 40 -
.../freemarker/core/SpecialVariableTest.java | 114 --
.../core/StringLiteralInterpolationTest.java | 135 --
.../org/apache/freemarker/core/TabSizeTest.java | 91 --
.../core/TagSyntaxVariationsTest.java | 186 ---
.../core/TemplateConfigurationTest.java | 909 -----------
...gurationWithDefaultTemplateResolverTest.java | 267 ----
.../core/TemplateConstructorsTest.java | 113 --
.../core/TemplateGetEncodingTest.java | 64 -
.../core/TemplateLookupStrategyTest.java | 669 --------
.../core/TemplateNameSpecialVariablesTest.java | 159 --
.../core/TemplateNotFoundMessageTest.java | 207 ---
.../core/TheadInterruptingSupportTest.java | 163 --
.../freemarker/core/TypeErrorMessagesTest.java | 105 --
.../freemarker/core/UnclosedCommentTest.java | 41 -
.../org/apache/freemarker/core/VersionTest.java | 227 ---
.../core/WhitespaceStrippingTest.java | 63 -
.../freemarker/core/XHTMLOutputFormatTest.java | 59 -
.../freemarker/core/XMLOutputFormatTest.java | 59 -
.../impl/AbstractParallelIntrospectionTest.java | 126 --
.../model/impl/AlphabeticalMethodSorter.java | 45 -
.../CommonSupertypeForUnwrappingHintTest.java | 129 --
.../model/impl/DefaultObjectWrapperDesc.java | 31 -
.../model/impl/DefaultObjectWrapperInc.java | 31 -
...jectWrapperModelFactoryRegistrationTest.java | 63 -
.../DefaultObjectWrapperSingletonsTest.java | 675 --------
.../model/impl/DefaultObjectWrapperTest.java | 901 -----------
.../core/model/impl/EnumModelsTest.java | 85 -
.../core/model/impl/ErrorMessagesTest.java | 170 --
.../impl/FineTuneMethodAppearanceTest.java | 65 -
.../GetlessMethodsAsPropertyGettersRule.java | 67 -
.../core/model/impl/IsApplicableTest.java | 171 --
.../impl/IsMoreSpecificParameterTypeTest.java | 98 --
.../Java7MembersOnlyDefaultObjectWrapper.java | 101 --
.../impl/ManyObjectsOfDifferentClasses.java | 249 ---
.../impl/ManyStaticsOfDifferentClasses.java | 236 ---
.../model/impl/MiscNumericalOperationsTest.java | 111 --
.../model/impl/ModelAPINewInstanceTest.java | 134 --
.../core/model/impl/ModelCacheTest.java | 71 -
.../model/impl/OverloadedNumberUtilTest.java | 585 -------
.../impl/ParameterListPreferabilityTest.java | 445 ------
.../impl/PrallelObjectIntrospectionTest.java | 43 -
.../impl/PrallelStaticIntrospectionTest.java | 47 -
.../core/model/impl/RationalNumber.java | 90 --
.../core/model/impl/StaticModelsTest.java | 91 --
.../core/model/impl/TypeFlagsTest.java | 671 --------
.../core/outputformat/_OutputFormatTestAPI.java | 35 -
.../impl/CombinedMarkupOutputFormatTest.java | 194 ---
.../outputformat/impl/HTMLOutputFormatTest.java | 187 ---
.../outputformat/impl/RTFOutputFormatTest.java | 129 --
.../DefaultTemplateResolverTest.java | 365 -----
.../FileTemplateLoaderTest.java | 122 --
.../MultiTemplateLoaderTest.java | 99 --
.../TemplateConfigurationFactoryTest.java | 203 ---
.../TemplateNameFormatTest.java | 330 ----
.../TemplateSourceMatcherTest.java | 188 ---
.../AppMetaTemplateDateFormatFactory.java | 129 --
.../BaseNTemplateNumberFormatFactory.java | 128 --
.../core/userpkg/CustomHTMLOutputFormat.java | 72 -
.../core/userpkg/CustomTemplateHTMLModel.java | 34 -
.../core/userpkg/DummyOutputFormat.java | 65 -
...EpochMillisDivTemplateDateFormatFactory.java | 102 --
.../EpochMillisTemplateDateFormatFactory.java | 92 --
.../HTMLISOTemplateDateFormatFactory.java | 114 --
.../userpkg/HexTemplateNumberFormatFactory.java | 77 -
...AndTZSensitiveTemplateDateFormatFactory.java | 97 --
...aleSensitiveTemplateNumberFormatFactory.java | 78 -
.../core/userpkg/PackageVisibleAll.java | 26 -
.../userpkg/PackageVisibleAllWithBuilder.java | 26 -
.../PackageVisibleAllWithBuilderBuilder.java | 28 -
.../PackageVisibleWithPublicConstructor.java | 27 -
.../PrintfGTemplateNumberFormatFactory.java | 138 --
.../freemarker/core/userpkg/PublicAll.java | 24 -
.../userpkg/PublicWithMixedConstructors.java | 38 -
.../PublicWithPackageVisibleConstructor.java | 26 -
.../core/userpkg/SeldomEscapedOutputFormat.java | 71 -
.../core/userpkg/TemplateDummyOutputModel.java | 34 -
.../TemplateSeldomEscapedOutputModel.java | 34 -
.../freemarker/core/util/DateUtilTest.java | 1085 -------------
.../freemarker/core/util/FTLUtilTest.java | 117 --
.../freemarker/core/util/NumberUtilTest.java | 215 ---
.../freemarker/core/util/StringUtilTest.java | 403 -----
.../core/valueformat/NumberFormatTest.java | 365 -----
.../impl/ExtendedDecimalFormatTest.java | 343 ----
.../apache/freemarker/dom/DOMSiblingTest.java | 99 --
.../freemarker/dom/DOMSimplifiersTest.java | 201 ---
.../java/org/apache/freemarker/dom/DOMTest.java | 159 --
.../manualtest/AutoEscapingExample.java | 72 -
.../ConfigureOutputFormatExamples.java | 105 --
.../manualtest/CustomFormatsExample.java | 84 -
.../manualtest/GettingStartedExample.java | 69 -
.../apache/freemarker/manualtest/Product.java | 49 -
.../TemplateConfigurationExamples.java | 191 ---
.../UnitAwareTemplateNumberFormatFactory.java | 80 -
.../UnitAwareTemplateNumberModel.java | 43 -
.../CopyrightCommentRemoverTemplateLoader.java | 104 --
.../test/MonitoredTemplateLoader.java | 325 ----
.../apache/freemarker/test/TemplateTest.java | 341 ----
.../test/TestConfigurationBuilder.java | 92 --
.../freemarker/test/hamcerst/Matchers.java | 34 -
.../hamcerst/StringContainsIgnoringCase.java | 47 -
.../org/apache/freemarker/test/package.html | 28 -
.../test/templatesuite/TemplateTestCase.java | 515 ------
.../test/templatesuite/TemplateTestSuite.java | 298 ----
.../templatesuite/models/AllTemplateModels.java | 128 --
.../templatesuite/models/BeanTestClass.java | 93 --
.../templatesuite/models/BeanTestInterface.java | 25 -
.../models/BeanTestSuperclass.java | 30 -
.../models/BooleanAndScalarModel.java | 40 -
.../models/BooleanAndStringTemplateModel.java | 38 -
.../test/templatesuite/models/BooleanHash1.java | 58 -
.../test/templatesuite/models/BooleanHash2.java | 50 -
.../test/templatesuite/models/BooleanList1.java | 62 -
.../test/templatesuite/models/BooleanList2.java | 53 -
.../models/BooleanVsStringMethods.java | 40 -
.../templatesuite/models/EnumTestClass.java | 34 -
.../templatesuite/models/ExceptionModel.java | 39 -
.../models/HashAndScalarModel.java | 84 -
.../templatesuite/models/JavaObjectInfo.java | 35 -
.../test/templatesuite/models/Listables.java | 185 ---
.../test/templatesuite/models/MultiModel1.java | 116 --
.../test/templatesuite/models/MultiModel2.java | 63 -
.../test/templatesuite/models/MultiModel3.java | 69 -
.../test/templatesuite/models/MultiModel4.java | 77 -
.../test/templatesuite/models/MultiModel5.java | 81 -
.../test/templatesuite/models/NewTestModel.java | 52 -
.../templatesuite/models/NewTestModel2.java | 52 -
.../models/NumberAndStringModel.java | 47 -
.../models/OverloadedConstructor.java | 46 -
.../templatesuite/models/OverloadedMethods.java | 191 ---
.../models/OverloadedMethods2.java | 1110 -------------
.../templatesuite/models/SimpleTestMethod.java | 49 -
.../models/TransformHashWrapper.java | 79 -
.../models/TransformMethodWrapper1.java | 49 -
.../models/TransformMethodWrapper2.java | 64 -
.../templatesuite/models/TransformModel1.java | 175 --
.../templatesuite/models/VarArgTestModel.java | 63 -
.../freemarker/test/templatesuite/package.html | 42 -
.../freemarker/test/util/AssertDirective.java | 73 -
.../test/util/AssertEqualsDirective.java | 91 --
.../test/util/AssertFailsDirective.java | 152 --
.../AssertationFailedInTemplateException.java | 46 -
.../test/util/BadParameterTypeException.java | 60 -
.../freemarker/test/util/CoreTestUtil.java | 19 -
.../test/util/EntirelyCustomObjectWrapper.java | 91 --
.../freemarker/test/util/FileTestCase.java | 217 ---
.../util/MissingRequiredParameterException.java | 51 -
.../freemarker/test/util/NoOutputDirective.java | 50 -
.../test/util/ParameterException.java | 54 -
.../SimpleMapAndCollectionObjectWrapper.java | 60 -
.../util/UnsupportedParameterException.java | 50 -
.../apache/freemarker/test/util/XMLLoader.java | 138 --
.../org/apache/freemarker/core/ast-1.ast | 187 ---
.../org/apache/freemarker/core/ast-1.ftl | 29 -
.../apache/freemarker/core/ast-assignments.ast | 172 --
.../apache/freemarker/core/ast-assignments.ftl | 29 -
.../org/apache/freemarker/core/ast-builtins.ast | 59 -
.../org/apache/freemarker/core/ast-builtins.ftl | 23 -
.../apache/freemarker/core/ast-locations.ast | 155 --
.../apache/freemarker/core/ast-locations.ftl | 36 -
.../core/ast-mixedcontentsimplifications.ast | 38 -
.../core/ast-mixedcontentsimplifications.ftl | 26 -
.../core/ast-multipleignoredchildren.ast | 30 -
.../core/ast-multipleignoredchildren.ftl | 33 -
.../core/ast-nestedignoredchildren.ast | 20 -
.../core/ast-nestedignoredchildren.ftl | 19 -
.../org/apache/freemarker/core/ast-range.ast | 281 ----
.../org/apache/freemarker/core/ast-range.ftl | 47 -
.../freemarker/core/ast-strlitinterpolation.ast | 82 -
.../freemarker/core/ast-strlitinterpolation.ftl | 25 -
.../freemarker/core/ast-whitespacestripping.ast | 70 -
.../freemarker/core/ast-whitespacestripping.ftl | 40 -
.../apache/freemarker/core/cano-assignments.ftl | 35 -
.../freemarker/core/cano-assignments.ftl.out | 34 -
.../apache/freemarker/core/cano-builtins.ftl | 23 -
.../freemarker/core/cano-builtins.ftl.out | 23 -
.../core/cano-identifier-escaping.ftl | 76 -
.../core/cano-identifier-escaping.ftl.out | 44 -
.../org/apache/freemarker/core/cano-macros.ftl | 29 -
.../apache/freemarker/core/cano-macros.ftl.out | 28 -
.../core/cano-strlitinterpolation.ftl | 19 -
.../core/cano-strlitinterpolation.ftl.out | 19 -
.../core/encodingOverride-ISO-8859-1.ftl | 20 -
.../freemarker/core/encodingOverride-UTF-8.ftl | 20 -
.../freemarker/core/templateresolver/test.ftl | 19 -
.../org/apache/freemarker/core/toCache1.ftl | 19 -
.../org/apache/freemarker/core/toCache2.ftl | 19 -
.../apache/freemarker/dom/DOMSiblingTest.xml | 31 -
.../manualtest/AutoEscapingExample-capture.ftlh | 21 -
.../AutoEscapingExample-capture.ftlh.out | 20 -
.../manualtest/AutoEscapingExample-convert.ftlh | 27 -
.../AutoEscapingExample-convert.ftlh.out | 25 -
.../manualtest/AutoEscapingExample-convert2.ftl | 25 -
.../AutoEscapingExample-convert2.ftl.out | 21 -
.../manualtest/AutoEscapingExample-infoBox.ftlh | 26 -
.../AutoEscapingExample-infoBox.ftlh.out | 25 -
.../manualtest/AutoEscapingExample-markup.ftlh | 28 -
.../AutoEscapingExample-markup.ftlh.out | 26 -
.../AutoEscapingExample-stringConcat.ftlh | 19 -
.../AutoEscapingExample-stringConcat.ftlh.out | 19 -
.../AutoEscapingExample-stringLiteral.ftlh | 21 -
.../AutoEscapingExample-stringLiteral.ftlh.out | 20 -
.../AutoEscapingExample-stringLiteral2.ftlh | 25 -
.../AutoEscapingExample-stringLiteral2.ftlh.out | 21 -
.../ConfigureOutputFormatExamples1.properties | 21 -
.../ConfigureOutputFormatExamples2.properties | 31 -
.../manualtest/CustomFormatsExample-alias1.ftlh | 22 -
.../CustomFormatsExample-alias1.ftlh.out | 22 -
.../manualtest/CustomFormatsExample-alias2.ftlh | 19 -
.../CustomFormatsExample-alias2.ftlh.out | 19 -
.../CustomFormatsExample-modelAware.ftlh | 20 -
.../CustomFormatsExample-modelAware.ftlh.out | 20 -
.../TemplateConfigurationExamples1.properties | 25 -
.../TemplateConfigurationExamples2.properties | 32 -
.../TemplateConfigurationExamples3.properties | 47 -
.../org/apache/freemarker/manualtest/test.ftlh | 28 -
.../org/apache/freemarker/test/servlet/web.xml | 101 --
.../test/templatesuite/expected/arithmetic.txt | 46 -
.../expected/boolean-formatting.txt | 31 -
.../test/templatesuite/expected/boolean.txt | 102 --
.../expected/charset-in-header.txt | 26 -
.../test/templatesuite/expected/comment.txt | 34 -
.../test/templatesuite/expected/comparisons.txt | 93 --
.../test/templatesuite/expected/compress.txt | 40 -
.../templatesuite/expected/dateformat-java.txt | 55 -
.../expected/default-object-wrapper.txt | 55 -
.../templatesuite/expected/default-xmlns.txt | 25 -
.../test/templatesuite/expected/default.txt | 26 -
.../expected/encoding-builtins.txt | 44 -
.../test/templatesuite/expected/escapes.txt | 49 -
.../test/templatesuite/expected/exception.txt | 43 -
.../test/templatesuite/expected/exception2.txt | 47 -
.../test/templatesuite/expected/exception3.txt | 21 -
.../test/templatesuite/expected/exthash.txt | 76 -
.../test/templatesuite/expected/hashconcat.txt | 138 --
.../test/templatesuite/expected/hashliteral.txt | 74 -
.../test/templatesuite/expected/helloworld.txt | 31 -
.../expected/identifier-escaping.txt | 57 -
.../expected/identifier-non-ascii.txt | 19 -
.../test/templatesuite/expected/if.txt | 104 --
.../test/templatesuite/expected/import.txt | 40 -
.../test/templatesuite/expected/include.txt | 67 -
.../test/templatesuite/expected/include2.txt | 28 -
.../test/templatesuite/expected/interpret.txt | 23 -
.../test/templatesuite/expected/iterators.txt | 84 -
.../templatesuite/expected/lastcharacter.txt | 31 -
.../test/templatesuite/expected/list-bis.txt | 51 -
.../test/templatesuite/expected/list.txt | 51 -
.../test/templatesuite/expected/list2.txt | 211 ---
.../test/templatesuite/expected/list3.txt | 57 -
.../test/templatesuite/expected/listhash.txt | 157 --
.../templatesuite/expected/listhashliteral.txt | 36 -
.../test/templatesuite/expected/listliteral.txt | 75 -
.../templatesuite/expected/localization.txt | 32 -
.../test/templatesuite/expected/logging.txt | 27 -
.../templatesuite/expected/loopvariable.txt | 54 -
.../templatesuite/expected/macros-return.txt | 23 -
.../test/templatesuite/expected/macros.txt | 67 -
.../test/templatesuite/expected/macros2.txt | 22 -
.../test/templatesuite/expected/multimodels.txt | 93 --
.../test/templatesuite/expected/nested.txt | 25 -
.../expected/new-allowsnothing.txt | 19 -
.../expected/new-defaultresolver.txt | 19 -
.../test/templatesuite/expected/new-optin.txt | 32 -
.../test/templatesuite/expected/newlines1.txt | 29 -
.../test/templatesuite/expected/newlines2.txt | 30 -
.../test/templatesuite/expected/noparse.txt | 54 -
.../templatesuite/expected/number-format.txt | 33 -
.../templatesuite/expected/number-literal.txt | 79 -
.../templatesuite/expected/number-to-date.txt | 31 -
.../templatesuite/expected/numerical-cast.txt | 462 ------
.../templatesuite/expected/output-encoding1.txt | 27 -
.../templatesuite/expected/output-encoding2.txt | Bin 1972 -> 0 bytes
.../templatesuite/expected/output-encoding3.txt | 26 -
.../test/templatesuite/expected/precedence.txt | 48 -
.../test/templatesuite/expected/recover.txt | 26 -
.../test/templatesuite/expected/root.txt | 44 -
.../expected/sequence-builtins.txt | 404 -----
.../test/templatesuite/expected/specialvars.txt | 25 -
.../string-builtins-regexps-matches.txt | 99 --
.../expected/string-builtins-regexps.txt | 112 --
.../templatesuite/expected/string-builtins1.txt | 112 --
.../templatesuite/expected/string-builtins2.txt | 135 --
.../templatesuite/expected/stringbimethods.txt | 29 -
.../templatesuite/expected/stringliteral.txt | Bin 1550 -> 0 bytes
.../test/templatesuite/expected/switch.txt | 80 -
.../test/templatesuite/expected/transforms.txt | 68 -
.../templatesuite/expected/type-builtins.txt | 33 -
.../test/templatesuite/expected/var-layers.txt | 37 -
.../test/templatesuite/expected/varargs.txt | 44 -
.../test/templatesuite/expected/variables.txt | 62 -
.../templatesuite/expected/whitespace-trim.txt | 60 -
.../templatesuite/expected/wstrip-in-header.txt | 23 -
.../test/templatesuite/expected/wstripping.txt | 39 -
.../templatesuite/expected/xml-fragment.txt | 25 -
.../expected/xml-ns_prefix-scope.txt | 29 -
.../test/templatesuite/expected/xml.txt | 65 -
.../test/templatesuite/expected/xmlns1.txt | 63 -
.../test/templatesuite/expected/xmlns3.txt | 47 -
.../test/templatesuite/expected/xmlns4.txt | 47 -
.../test/templatesuite/expected/xmlns5.txt | 26 -
.../models/BeansTestResources.properties | 19 -
.../test/templatesuite/models/defaultxmlns1.xml | 24 -
.../models/xml-ns_prefix-scope.xml | 26 -
.../test/templatesuite/models/xml.xml | 31 -
.../test/templatesuite/models/xmlfragment.xml | 19 -
.../test/templatesuite/models/xmlns.xml | 32 -
.../test/templatesuite/models/xmlns2.xml | 32 -
.../test/templatesuite/models/xmlns3.xml | 32 -
.../templatesuite/templates/api-builtins.ftl | 40 -
.../test/templatesuite/templates/arithmetic.ftl | 50 -
.../templatesuite/templates/assignments.ftl | 108 --
.../templates/boolean-formatting.ftl | 82 -
.../test/templatesuite/templates/boolean.ftl | 142 --
.../templates/charset-in-header.ftl | 27 -
.../templates/charset-in-header_inc1.ftl | 20 -
.../templates/charset-in-header_inc2.ftl | 19 -
.../test/templatesuite/templates/comment.ftl | 50 -
.../templatesuite/templates/comparisons.ftl | 218 ---
.../test/templatesuite/templates/compress.ftl | 59 -
.../templates/date-type-builtins.ftl | 47 -
.../templates/dateformat-iso-bi.ftl | 163 --
.../templates/dateformat-iso-like.ftl | 155 --
.../templatesuite/templates/dateformat-java.ftl | 71 -
.../templatesuite/templates/dateparsing.ftl | 84 -
.../templates/default-object-wrapper.ftl | 59 -
.../templatesuite/templates/default-xmlns.ftl | 28 -
.../test/templatesuite/templates/default.ftl | 34 -
.../templates/encoding-builtins.ftl | 52 -
.../test/templatesuite/templates/escapes.ftl | 79 -
.../test/templatesuite/templates/exception.ftl | 31 -
.../test/templatesuite/templates/exception2.ftl | 31 -
.../test/templatesuite/templates/exception3.ftl | 31 -
.../templates/existence-operators.ftl | 141 --
.../test/templatesuite/templates/hashconcat.ftl | 60 -
.../templatesuite/templates/hashliteral.ftl | 100 --
.../test/templatesuite/templates/helloworld.ftl | 30 -
.../templates/identifier-escaping.ftl | 81 -
.../templates/identifier-non-ascii.ftl | 21 -
.../test/templatesuite/templates/if.ftl | 109 --
.../test/templatesuite/templates/import.ftl | 45 -
.../test/templatesuite/templates/import_lib.ftl | 31 -
.../test/templatesuite/templates/include.ftl | 47 -
.../templates/include2-included.ftl | 19 -
.../test/templatesuite/templates/include2.ftl | 32 -
.../test/templatesuite/templates/included.ftl | 30 -
.../test/templatesuite/templates/interpret.ftl | 25 -
.../test/templatesuite/templates/iterators.ftl | 71 -
.../templatesuite/templates/lastcharacter.ftl | 31 -
.../test/templatesuite/templates/list-bis.ftl | 48 -
.../test/templatesuite/templates/list.ftl | 44 -
.../test/templatesuite/templates/list2.ftl | 90 --
.../test/templatesuite/templates/list3.ftl | 70 -
.../test/templatesuite/templates/listhash.ftl | 70 -
.../templatesuite/templates/listhashliteral.ftl | 35 -
.../templatesuite/templates/listliteral.ftl | 84 -
.../templatesuite/templates/localization.ftl | 32 -
.../templatesuite/templates/localization_en.ftl | 32 -
.../templates/localization_en_AU.ftl | 32 -
.../test/templatesuite/templates/logging.ftl | 42 -
.../templatesuite/templates/loopvariable.ftl | 49 -
.../templatesuite/templates/macros-return.ftl | 34 -
.../test/templatesuite/templates/macros.ftl | 101 --
.../test/templatesuite/templates/macros2.ftl | 35 -
.../templatesuite/templates/multimodels.ftl | 84 -
.../test/templatesuite/templates/nested.ftl | 29 -
.../templatesuite/templates/nestedinclude.ftl | 21 -
.../templates/new-defaultresolver.ftl | 23 -
.../test/templatesuite/templates/new-optin.ftl | 30 -
.../test/templatesuite/templates/newlines1.ftl | 29 -
.../test/templatesuite/templates/newlines2.ftl | 33 -
.../test/templatesuite/templates/noparse.ftl | 62 -
.../templatesuite/templates/number-format.ftl | 42 -
.../templatesuite/templates/number-literal.ftl | 133 --
.../templates/number-math-builtins.ftl | 78 -
.../templatesuite/templates/number-to-date.ftl | 35 -
.../templatesuite/templates/numerical-cast.ftl | 82 -
.../templates/output-encoding1.ftl | 30 -
.../templates/output-encoding2.ftl | 28 -
.../templates/output-encoding3.ftl | 28 -
.../templates/overloaded-methods.ftl | 411 -----
.../test/templatesuite/templates/precedence.ftl | 61 -
.../templatesuite/templates/range-common.ftl | 314 ----
.../test/templatesuite/templates/range.ftl | 50 -
.../test/templatesuite/templates/recover.ftl | 47 -
.../test/templatesuite/templates/root.ftl | 47 -
.../templates/sequence-builtins.ftl | 360 -----
.../test/templatesuite/templates/setting.ftl | 53 -
.../templates/simplehash-char-key.ftl | 44 -
.../templatesuite/templates/specialvars.ftl | 38 -
.../templates/string-builtin-coercion.ftl | 34 -
.../string-builtins-regexps-matches.ftl | 118 --
.../templates/string-builtins-regexps.ftl | 136 --
.../templates/string-builtins1.ftl | 129 --
.../templates/string-builtins2.ftl | 135 --
.../templates/string-builtins3.ftl | 225 ---
.../templatesuite/templates/stringbimethods.ftl | 36 -
.../templatesuite/templates/stringliteral.ftl | 69 -
.../templates/subdir/include-subdir.ftl | 27 -
.../templates/subdir/include-subdir2.ftl | 19 -
.../templates/subdir/new-optin-2.ftl | 24 -
.../templates/subdir/new-optin.ftl | 26 -
.../templates/subdir/subsub/new-optin.ftl | 24 -
.../templatesuite/templates/switch-builtin.ftl | 54 -
.../test/templatesuite/templates/switch.ftl | 139 --
.../templatesuite/templates/then-builtin.ftl | 53 -
.../test/templatesuite/templates/transforms.ftl | 100 --
.../templatesuite/templates/type-builtins.ftl | 44 -
.../test/templatesuite/templates/undefined.ftl | 19 -
.../test/templatesuite/templates/url.ftl | 24 -
.../test/templatesuite/templates/var-layers.ftl | 39 -
.../test/templatesuite/templates/varargs.ftl | 45 -
.../test/templatesuite/templates/variables.ftl | 70 -
.../templatesuite/templates/varlayers_lib.ftl | 28 -
.../templatesuite/templates/whitespace-trim.ftl | 102 --
.../templates/wsstripinheader_inc.ftl | 22 -
.../templates/wstrip-in-header.ftl | 26 -
.../templatesuite/templates/xml-fragment.ftl | 26 -
.../templates/xml-ns_prefix-scope-lib.ftl | 23 -
.../templates/xml-ns_prefix-scope-main.ftl | 36 -
.../test/templatesuite/templates/xml.ftl | 47 -
.../test/templatesuite/templates/xmlns1.ftl | 53 -
.../test/templatesuite/templates/xmlns3.ftl | 70 -
.../test/templatesuite/templates/xmlns4.ftl | 70 -
.../test/templatesuite/templates/xmlns5.ftl | 28 -
.../freemarker/test/templatesuite/testcases.xml | 211 ---
freemarker-test-utils/build.gradle | 2 +
.../CopyrightCommentRemoverTemplateLoader.java | 105 ++
.../apache/freemarker/test/FileTestCase.java | 216 +++
.../test/MonitoredTemplateLoader.java | 325 ++++
.../freemarker/test/ResourcesExtractor.java | 14 +-
.../apache/freemarker/test/TemplateTest.java | 340 ++++
.../test/TestConfigurationBuilder.java | 92 ++
.../org/apache/freemarker/test/TestUtil.java | 85 +-
.../org/apache/freemarker/test/XMLLoader.java | 138 ++
.../apache/freemarker/test/_TStringUtil.java | 65 -
.../freemarker/test/hamcerst/Matchers.java | 34 +
.../hamcerst/StringContainsIgnoringCase.java | 47 +
.../test/templateutil/AssertDirective.java | 73 +
.../templateutil/AssertEqualsDirective.java | 91 ++
.../test/templateutil/AssertFailsDirective.java | 152 ++
.../AssertationFailedInTemplateException.java | 46 +
.../templateutil/BadParameterTypeException.java | 60 +
.../MissingRequiredParameterException.java | 51 +
.../test/templateutil/NoOutputDirective.java | 50 +
.../test/templateutil/ParameterException.java | 54 +
.../UnsupportedParameterException.java | 50 +
settings.gradle | 3 +-
962 files changed, 48802 insertions(+), 48913 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/build.gradle
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/build.gradle b/freemarker-core-java8-test/build.gradle
deleted file mode 100644
index ad08d33..0000000
--- a/freemarker-core-java8-test/build.gradle
+++ /dev/null
@@ -1,19 +0,0 @@
-// Override inherited default Java version:
-sourceCompatibility = "1.8"
-targetCompatibility = "1.8"
-[compileJava, compileTestJava]*.options*.bootClasspath = bootClasspathJava8
-
-dependencies {
- compile project(":freemarker-core")
-}
-
-// We have nothing to put into the jar, as we have test classes only
-jar.enabled = false
-
-javadoc.enabled = false
-
-// Must not be deployed to a public Maven repository
-uploadArchives.enabled = false
-
-// Doesn't make sense to Maven "install" this, as the artifact won't contain test classes
-install.enabled = false
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/main/resources/META-INF/DISCLAIMER
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/main/resources/META-INF/DISCLAIMER b/freemarker-core-java8-test/src/main/resources/META-INF/DISCLAIMER
deleted file mode 100644
index 569ba05..0000000
--- a/freemarker-core-java8-test/src/main/resources/META-INF/DISCLAIMER
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache FreeMarker is an effort undergoing incubation at The Apache Software
-Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of
-all newly accepted projects until a further review indicates that the
-infrastructure, communications, and decision making process have stabilized in
-a manner consistent with other successful ASF projects. While incubation
-status is not necessarily a reflection of the completeness or stability of the
-code, it does indicate that the project has yet to be fully endorsed by the
-ASF.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/main/resources/META-INF/LICENSE b/freemarker-core-java8-test/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/freemarker-core-java8-test/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java
deleted file mode 100644
index 2c9d4e9..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public class BridgeMethodsBean extends BridgeMethodsBeanBase<String> {
-
- static final String M1_RETURN_VALUE = "m1ReturnValue";
-
- @Override
- public String m1() {
- return M1_RETURN_VALUE;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
deleted file mode 100644
index 4ecec7c..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public abstract class BridgeMethodsBeanBase<T> {
-
- public abstract T m1();
-
- public T m2() {
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
deleted file mode 100644
index c7d27a6..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public class Java8BridgeMethodsWithDefaultMethodBean implements Java8BridgeMethodsWithDefaultMethodBeanBase<String> {
-
- static final String M1_RETURN_VALUE = "m1ReturnValue";
-
- public String m1() {
- return M1_RETURN_VALUE;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
deleted file mode 100644
index 7dfb39a..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public class Java8BridgeMethodsWithDefaultMethodBean2 implements Java8BridgeMethodsWithDefaultMethodBeanBase2 {
- // All inherited
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
deleted file mode 100644
index fdd8821..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public interface Java8BridgeMethodsWithDefaultMethodBeanBase<T> {
-
- default T m1() {
- return null;
- }
-
- default T m2() {
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
deleted file mode 100644
index 6f68dc7..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public interface Java8BridgeMethodsWithDefaultMethodBeanBase2 extends Java8BridgeMethodsWithDefaultMethodBeanBase<String> {
-
- @Override
- default String m1() {
- return Java8BridgeMethodsWithDefaultMethodBean.M1_RETURN_VALUE;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
deleted file mode 100644
index eabc3d0..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public class Java8DefaultMethodsBean implements Java8DefaultMethodsBeanBase {
-
- static final String NORMAL_PROP = "normalProp";
- static final String NORMAL_PROP_VALUE = "normalPropValue";
- static final String PROP_2_OVERRIDE_VALUE = "prop2OverrideValue";
- static final int NOT_AN_INDEXED_PROP_VALUE = 1;
- static final String ARRAY_PROP_2_VALUE_0 = "arrayProp2[0].value";
- private static final int NOT_AN_INDEXED_PROP_3_VALUE = 3;
- private static final String NOT_AN_INDEXED_PROP_2_VALUE = "notAnIndecedProp2Value";
- static final String INDEXED_PROP_4 = "indexedProp4";
- static final String INDEXED_PROP_GETTER_4 = "getIndexedProp4";
- static final String INDEXED_PROP_4_VALUE = "indexedProp4Value[0]";
- static final String NORMAL_ACTION = "normalAction";
- static final String NORMAL_ACTION_RETURN_VALUE = "normalActionReturnValue";
- static final String OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE = "overriddenValue";
-
- public String getNormalProp() {
- return NORMAL_PROP_VALUE;
- }
-
- @Override
- public String getDefaultMethodProp2() {
- return PROP_2_OVERRIDE_VALUE;
- }
-
- public String[] getDefaultMethodIndexedProp2() {
- return new String[] { ARRAY_PROP_2_VALUE_0 };
- }
-
- /**
- * There's a matching non-indexed reader method in the base class, but as this is indexed, it takes over.
- */
- public String getDefaultMethodIndexedProp3(int index) {
- return "";
- }
-
- public int getDefaultMethodNotAnIndexedProp() {
- return NOT_AN_INDEXED_PROP_VALUE;
- }
-
- /** Actually, this will be indexed if the default method support is off. */
- public String getDefaultMethodNotAnIndexedProp2(int index) {
- return NOT_AN_INDEXED_PROP_2_VALUE;
- }
-
- /** Actually, this will be indexed if the default method support is off. */
- public int getDefaultMethodNotAnIndexedProp3(int index) {
- return NOT_AN_INDEXED_PROP_3_VALUE;
- }
-
- public String getIndexedProp4(int index) {
- return INDEXED_PROP_4_VALUE;
- }
-
- public String normalAction() {
- return NORMAL_ACTION_RETURN_VALUE;
- }
-
- @Override
- public String overriddenDefaultMethodAction() {
- return OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE;
- }
-
-}
[04/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ast
deleted file mode 100644
index 831c7dc..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ast
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: null // Null
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: ..< // o.a.f.c.ASTExpRange
- - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: ..< // o.a.f.c.ASTExpRange
- - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: ..< // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: ..< // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: * // o.a.f.c.ArithmeticExpression
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "1" // Integer
- - right-hand operand: * // o.a.f.c.ArithmeticExpression
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "1" // Integer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: ?abs // o.a.f.c.BuiltInsForNumbers$absBI
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: "abs" // String
- - right-hand operand: ?abs // o.a.f.c.BuiltInsForNumbers$absBI
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: "abs" // String
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
- - callee: ?index_of // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: "index_of" // String
- - argument value: "x" // o.a.f.c.ASTExpStringLiteral
- - right-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
- - callee: ?index_of // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: "index_of" // String
- - argument value: "y" // o.a.f.c.ASTExpStringLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: == // o.a.f.c.ASTExpComparison
- - left-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: o // o.a.f.c.ASTExpVariable
- - right-hand operand: p // o.a.f.c.ASTExpVariable
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: == // o.a.f.c.ASTExpComparison
- - left-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - right-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: o // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: p // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: a // o.a.f.c.ASTExpVariable
- - right-hand operand: +... // o.a.f.c.ASTExpNegateOrPlus
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "1" // Integer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: a // o.a.f.c.ASTExpVariable
- - AST-node subtype: "0" // Integer
- - right-hand operand: -... // o.a.f.c.ASTExpNegateOrPlus
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: ..* // o.a.f.c.ASTExpRange
- - left-hand operand: * // o.a.f.c.ArithmeticExpression
- - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: a // o.a.f.c.ASTExpVariable
- - AST-node subtype: "1" // Integer
- - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: || // o.a.f.c.ASTExpOr
- - left-hand operand: && // o.a.f.c.ASTExpAnd
- - left-hand operand: a // o.a.f.c.ASTExpVariable
- - right-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: b // o.a.f.c.ASTExpVariable
- - right-hand operand: c // o.a.f.c.ASTExpVariable
- - right-hand operand: d // o.a.f.c.ASTExpVariable
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "x" // String
- - assignment operator: "=" // String
- - assignment source: || // o.a.f.c.ASTExpOr
- - left-hand operand: && // o.a.f.c.ASTExpAnd
- - left-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: a // o.a.f.c.ASTExpVariable
- - right-hand operand: null // Null
- - right-hand operand: .. // o.a.f.c.ASTExpRange
- - left-hand operand: b // o.a.f.c.ASTExpVariable
- - right-hand operand: null // Null
- - right-hand operand: d // o.a.f.c.ASTExpVariable
- - variable scope: "1" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
- - callee: f // o.a.f.c.ASTExpVariable
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: null // Null
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - right-hand operand: null // Null
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "\n\n" // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: m // o.a.f.c.ASTExpVariable
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: * // o.a.f.c.ArithmeticExpression
- - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: m // o.a.f.c.ASTExpVariable
- - AST-node subtype: "1" // Integer
- - right-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - right-hand operand: - // o.a.f.c.ArithmeticExpression
- - left-hand operand: n // o.a.f.c.ASTExpVariable
- - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
- - AST-node subtype: "0" // Integer
- - argument value: .. // o.a.f.c.ASTExpRange
- - left-hand operand: m // o.a.f.c.ASTExpVariable
- - right-hand operand: null // Null
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ftl
deleted file mode 100644
index cb55c8a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-range.ftl
+++ /dev/null
@@ -1,47 +0,0 @@
-<#--
- 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.
--->
-<#assign x = 0..>
-
-<#assign x = 0..1>
-<#assign x = 0..<1>
-<#assign x = 0..!1>
-
-<#assign x = n + 1 .. m + 2>
-<#assign x = n + 1 ..< m + 2>
-<#assign x = n + 1 ..! m + 2>
-
-<#assign x = n * 1 .. m * 2>
-
-<#assign x = n?abs .. m?abs>
-
-<#assign x = n?index_of('x') .. m?index_of('y')>
-
-<#assign x = n..m == o..p>
-
-<#assign x = n+1+2..m-1-2 == o+1+2..p-1-2>
-
-<#assign x = 1+a..+2>
-<#assign x = 1-a..-2>
-<#assign x = 1*a..*2>
-<#assign x = a && b..c || d>
-<#assign x = a.. && b.. || d>
-
-${f(m.., m-1.., m+1..n-1)}
-
-<@m 1 * m .. m - 1 m + 1 .. n - 1 m .. />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
deleted file mode 100644
index 321721e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ast
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #text // o.a.f.c.ASTStaticText
- - content: "1. " // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: m // o.a.f.c.ASTExpVariable
- - argument name: "x" // String
- - argument value: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: e1 // o.a.f.c.ASTExpVariable
- - argument name: "y" // String
- - argument value: "$\\{e2}" // o.a.f.c.ASTExpStringLiteral
- #text // o.a.f.c.ASTStaticText
- - content: "\n2. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: "a" // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: "b" // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: "c" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n3. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: "b" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n4. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: "a" // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n5. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: #{...} // o.a.f.c.ASTHashInterpolation
- - content: y // o.a.f.c.ASTExpVariable
- - minimum decimals: "0" // Integer
- - maximum decimals: "0" // Integer
- #text // o.a.f.c.ASTStaticText
- - content: "\n6. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: "a b " // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: " c d" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n7. " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- - value part: " a b " // String
- - value part: ${...} // o.a.f.c.ASTDollarInterpolation
- - content: y // o.a.f.c.ASTExpVariable
- - value part: " c$d" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
deleted file mode 100644
index cd86f2f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-strlitinterpolation.ftl
+++ /dev/null
@@ -1,25 +0,0 @@
-<#--
- 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.
--->
-1. <@m x='${e1}' y='$\\{e2}' />
-2. ${'a${x}b${x}c'}
-3. ${'${x}b'}
-4. ${'a${x}'}
-5. ${'${x}#{y}'}
-6. ${'a b ${x} c d'}
-7. ${'${x} a b ${y} c$d'}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
deleted file mode 100644
index 868fc69..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ast
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-#mixed_content // o.a.f.c.ASTImplicitParent
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "xs" // String
- - assignment operator: "=" // String
- - assignment source: [...] // o.a.f.c.ASTExpListLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- #list // o.a.f.c.ASTDirList
- - list source: x // o.a.f.c.ASTExpVariable
- - target loop variable: "xs" // String
- #text // o.a.f.c.ASTStaticText
- - content: " " // String
- ${...} // o.a.f.c.ASTDollarInterpolation
- - content: x // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "a" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #assign // o.a.f.c.ASTDirAssignment
- - assignment target: "b" // String
- - assignment operator: "=" // String
- - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
- - variable scope: "1" // Integer
- - namespace: null // Null
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: b // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: " x\n" // String
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: c // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\n" // String
- @ // o.a.f.c.ASTDirUserDefined
- - callee: d // o.a.f.c.ASTExpVariable
- #text // o.a.f.c.ASTStaticText
- - content: "\na\n" // String
- #--...-- // o.a.f.c.ASTComment
- - content: " comment " // String
- #text // o.a.f.c.ASTStaticText
- - content: "b" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
deleted file mode 100644
index cba7289..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/ast-whitespacestripping.ftl
+++ /dev/null
@@ -1,40 +0,0 @@
-<#--
- 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.
--->
-
-
-<#assign xs = []>
-
-<#list x as xs>
- ${x}
-</#list>
-
-<#assign a = 1>
-<#assign b = 1>
-
-<@b>
- x
-</...@b>
-
-<@c />
-
-<@d...@d>
-
-a
-<#-- comment -->
-b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
deleted file mode 100644
index 24c8984..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl
+++ /dev/null
@@ -1,35 +0,0 @@
-<#ftl stripWhitespace=false>
-<#--
- 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.
--->
-<#assign x = 1>
-<#assign x = 1, y = 2>
-<#assign x = 1 in ns>
-<#assign x = 1, y = 2 in ns>
-<#assign a += b + c>
-<#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
-<#global x = 1>
-<#global x = 1, y = 2>
-<#global x++>
-<#macro m>
- <#local x = 1>
- <#local x = 1, y = 2>
-</#macro>
-<#assign x>
- foo ${bar}
-</#assign>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
deleted file mode 100644
index 3dd2307..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-assignments.ftl.out
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-<#assign x = 1>
-<#assign x = 1, y = 2>
-<#assign x = 1 in ns>
-<#assign x = 1, y = 2 in ns>
-<#assign a += b + c>
-<#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
-<#global x = 1>
-<#global x = 1, y = 2>
-<#global x++>
-<#macro m>
- <#local x = 1>
- <#local x = 1, y = 2>
-</#macro>
-<#assign x>
- foo ${bar}
-</#assign>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
deleted file mode 100644
index 74aee52..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl
+++ /dev/null
@@ -1,23 +0,0 @@
-<#--
- 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.
--->
-${x?trim}
-${x?left_pad(5)}
-${x?left_pad(5, '-')}
-${x?then('y', 'n')}
-${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
deleted file mode 100644
index 3c62974..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-builtins.ftl.out
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-${x?trim}
-${x?left_pad(5)}
-${x?left_pad(5, "-")}
-${x?then("y", "n")}
-${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
deleted file mode 100644
index 75d52f1..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl
+++ /dev/null
@@ -1,76 +0,0 @@
-<#--
- 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.
--->
-<#macro m\-a data\-color>
- <#local \.namespace = 123>
- <a-b>${data\-color}<#nested \.namespace></a-b><#t>
-</#macro>
-<#macro "m-b2"></#macro>
-<#macro "m/b2"></#macro>
-
-<@m\-a data\-color="red"; loop\-var, loopVar2>${loop\-var}</@>
-
-<#function f\-a p\-a>
- <#return p\-a + " works">
-</#function>
-${f\-a("f-a")}
-
-<#assign \-\-\-\.\: = 'dash-dash-dash etc.'>
-${\-\-\-\.\:}
-${.vars['---.:']}
-<#assign hash = { '--moz-prop': 'propVal' }>
-${hash.\-\-moz\-prop}
-${hash['--moz-prop']}
-
-<#assign ls\:a = 1..3>
-List: <#list ls\:a as \:i>${\:i}</#list>
-
-<#assign sw\-a=1>
-Switch: <#switch sw\-a>
- <#case 1>OK<#break>
- <#default>Fails
-</#switch>
-
-<#escape \-x as \-x?upper_case>${'escaped'}</#escape>
-
-<#if false && sw\-a == 1>
- <#visit x\-y2 using x\-y1>
- <#recurse x\-y2 using x\-y1>
- <#import i\-a as i\-b>
- <#include i\-c>
-</#if>
-
-<#assign @as@_a = 'as1'>
-${@as@_a}
-<#assign 'as-c' = 'as2'>
-${.vars['as-c']}
-<#assign "as/b" = 'as3'>
-${.vars["as/b"]}
-<#assign "as'c" = 'as4'>
-${.vars["as'c"]}
-<#assign 'as"d' = 'as5'>
-${.vars['as"d']}
-
-<#global g\-a=1 g\-b=2 "g-c"=3>
-
-<#macro dumpNS>
- <#list .namespace?keys?sort as k>
- ${k} = <#local v = .namespace[k]><#if v?is_string>${v}<#else>...</#if><#lt>
- </#list>
-</#macro>
-<@dumpNS />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
deleted file mode 100644
index 17e2b4e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-identifier-escaping.ftl.out
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-<#macro m\-a data\-color><#local \.namespace = 123><a-b>${data\-color}<#nested \.namespace></a-b></#macro><#macro m\-b2></#macro><#macro "m/b2"></#macro>
-<@m\-a data\-color="red"; loop\-var, loopVar2>${loop\-var}</@m\-a>
-
-<#function f\-a(p\-a)><#return p\-a + " works"/></#function>${f\-a("f-a")}
-
-<#assign \-\-\-\.\: = "dash-dash-dash etc.">${\-\-\-\.\:}
-${.vars["---.:"]}
-<#assign hash = {"--moz-prop": "propVal"}>${hash.\-\-moz\-prop}
-${hash["--moz-prop"]}
-
-<#assign ls\:a = 1..3>List: <#list ls\:a as \:i>${\:i}</#list>
-
-<#assign sw\-a = 1>Switch: <#switch sw\-a><#case 1>OK<#break/>
- <#default>Fails
-</#switch>
-<#escape \-x as \-x?upper_case>${"escaped"}</#escape>
-
-<#if false && sw\-a == 1><#visit x\-y2 using x\-y1/><#recurse x\-y2 using x\-y1/><#import i\-a as i\-b/><#include i\-c/></#if>
-<#assign @as@_a = "as1">${@as@_a}
-<#assign as\-c = "as2">${.vars["as-c"]}
-<#assign "as/b" = "as3">${.vars["as/b"]}
-<#assign "as'c" = "as4">${.vars["as'c"]}
-<#assign 'as"d' = "as5">${.vars['as"d']}
-
-<#global g\-a = 1, g\-b = 2, g\-c = 3><#macro dumpNS><#list .namespace?keys?sort as k>${k} = <#local v = .namespace[k]><#if v?is_string>${v}<#else>...</#if>
-</#list></#macro><@dumpNS/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
deleted file mode 100644
index 9288e63..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl
+++ /dev/null
@@ -1,29 +0,0 @@
-<#ftl stripWhitespace=false>
-<#--
- 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.
--->
-<#macro m></#macro>
-<#macro m a></#macro>
-<#macro m a b></#macro>
-<#macro m a b c...></#macro>
-<#macro m a...></#macro>
-<#function f()></#function>
-<#function f(a)></#function>
-<#function f(a, b)></#function>
-<#function f(a, b, c...)></#function>
-<#function f(a...)></#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
deleted file mode 100644
index ad49cae..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-macros.ftl.out
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-<#macro m></#macro>
-<#macro m a></#macro>
-<#macro m a b></#macro>
-<#macro m a b c...></#macro>
-<#macro m a...></#macro>
-<#function f()></#function>
-<#function f(a)></#function>
-<#function f(a, b)></#function>
-<#function f(a, b, c...)></#function>
-<#function f(a...)></#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
deleted file mode 100644
index 85189a4..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-<@m x='${e1 + "a\'b${x}"}#{x; M2}' y='$\{e2}' />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
deleted file mode 100644
index 754c225..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/cano-strlitinterpolation.ftl.out
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-<@m x="${e1 + \"a'b$\{x}\"}#{x ; m0M2}" y="$\{e2}"/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
deleted file mode 100644
index e0382c7..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-ISO-8859-1.ftl
+++ /dev/null
@@ -1,20 +0,0 @@
-<#ftl encoding="ISO-8859-1">
-<#--
- 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.
--->
-B�ka
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
deleted file mode 100644
index 5948e30..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/encodingOverride-UTF-8.ftl
+++ /dev/null
@@ -1,20 +0,0 @@
-<#ftl encoding="UTF-8">
-<#--
- 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.
--->
-Béka
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
deleted file mode 100644
index fb3f45d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/templateresolver/test.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-dummy
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache1.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache1.ftl
deleted file mode 100644
index 462f1ae..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache1.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-Template 1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache2.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache2.ftl
deleted file mode 100644
index f59424c..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/core/toCache2.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-Template 2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml b/freemarker-core/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
deleted file mode 100644
index d1fe3dc..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0"?>
-<!--
- 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.
--->
-<person>
- <gender>male</gender>
- <name>pradeep</name>
- <dob>12th August</dob><address>Chennai, India</address>
- <!--This is a comment Node -->
- <?xml-stylesheet type="text/css" href="style.css"?>
- <profession>Software Engineer</profession>
- <![CDATA[ ]]>
- <hobby>gardening</hobby>
- <![CDATA[this is a valid cdata]]>
- <phone>12345678</phone>
-</person>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
deleted file mode 100644
index 24bd0ee..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh
+++ /dev/null
@@ -1,21 +0,0 @@
-<#--
- 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.
--->
-<#assign captured><b>Test</b></#assign>
-Just a string: ${"<b>Test</b>"}
-Captured output: ${captured}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
deleted file mode 100644
index cf0da7e..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-capture.ftlh.out
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-Just a string: <b>Test</b>
-Captured output: <b>Test</b>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
deleted file mode 100644
index e0d3348..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh
+++ /dev/null
@@ -1,27 +0,0 @@
-<#--
- 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.
--->
-<#assign mo1 = "Foo's bar {}"?esc>
-HTLM: ${mo1}
-XML: <#outputformat 'XML'>${mo1}</#outputformat>
-RTF: <#outputformat 'RTF'>${mo1}</#outputformat>
-
-<#assign mo2><p>Test</#assign>
-HTML: ${mo2}
-XML: <#attempt><#outputformat 'XML'>${mo2}</#outputformat><#recover>Failed</#attempt>
-RTF: <#attempt><#outputformat 'RTF'>${mo2}</#outputformat><#recover>Failed</#attempt>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
deleted file mode 100644
index 65be2a0..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert.ftlh.out
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-HTLM: Foo's bar {}
-XML: Foo's bar {}
-RTF: Foo's bar \{\}
-
-HTML: <p>Test
-XML: Failed
-RTF: Failed
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
deleted file mode 100644
index 80ae292..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl
+++ /dev/null
@@ -1,25 +0,0 @@
-<#--
- 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.
--->
-<#outputformat "HTML"><#assign htmlMO><p>Test</#assign></#outputformat>
-<#outputformat "XML"><#assign xmlMO><p>Test</p></#assign></#outputformat>
-<#outputformat "RTF"><#assign rtfMO>\par Test</#assign></#outputformat>
-<#-- We assume that we have "undefined" output format here. -->
-HTML: ${htmlMO}
-XML: ${xmlMO}
-RTF: ${rtfMO}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
deleted file mode 100644
index cd84bd2..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-convert2.ftl.out
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-HTML: <p>Test
-XML: <p>Test</p>
-RTF: \par Test
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
deleted file mode 100644
index 9b8dbd9..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh
+++ /dev/null
@@ -1,26 +0,0 @@
-<#--
- 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.
--->
-<@infoBox "Foo & bar" />
-<@infoBox "Foo <b>bar</b>"?no_esc />
-
-<#macro infoBox message>
- <div class="infoBox">
- ${message}
- </div>
-</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
deleted file mode 100644
index 9471ab7..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-infoBox.ftlh.out
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
- <div class="infoBox">
- Foo & bar
- </div>
- <div class="infoBox">
- Foo <b>bar</b>
- </div>
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
deleted file mode 100644
index f9deeae..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh
+++ /dev/null
@@ -1,28 +0,0 @@
-<#--
- 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.
--->
-<#assign markupOutput1="<b>Test</b>"?no_esc>
-<#assign markupOutput2="Foo & bar"?esc>
-
-As expected:
-${markupOutput1}
-${markupOutput2}
-
-Double escaping:
-${markupOutput1?markup_string}
-${markupOutput2?markup_string}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
deleted file mode 100644
index 0420cca..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-markup.ftlh.out
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-As expected:
-<b>Test</b>
-Foo & bar
-
-Double escaping:
-<b>Test</b>
-Foo &amp; bar
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
deleted file mode 100644
index f7884bb..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
deleted file mode 100644
index d016072..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringConcat.ftlh.out
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-<h1>Foo & bar</h1>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
deleted file mode 100644
index 4904f60..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh
+++ /dev/null
@@ -1,21 +0,0 @@
-<#--
- 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.
--->
-<#assign s = "Foo & bar">
-${s}
-${"${s} & baz"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
deleted file mode 100644
index c6bd10d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral.ftlh.out
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-Foo & bar
-Foo & bar & baz
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
deleted file mode 100644
index 52db70b..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh
+++ /dev/null
@@ -1,25 +0,0 @@
-<#--
- 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.
--->
-<#-- Markup output value created by escaping plain text: -->
-<#assign mo1 = "Foo & bar"?esc>
-<#-- Markup output value created outherwise: -->
-<#assign mo2 = "<p>Foo"?no_esc>
-
-${"${mo1} baz"}
-${"${mo2} baz"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
deleted file mode 100644
index f47e521..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/AutoEscapingExample-stringLiteral2.ftlh.out
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-
-Foo & bar baz
-<p>Foo baz
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
deleted file mode 100644
index 0df9e33..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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.
-
-templateConfigurations = \
- ConditionalTemplateConfigurationFactory( \
- PathGlobMatcher("mail/**"), \
- TemplateConfiguration(outputFormat = HTMLOutputFormat()))
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
deleted file mode 100644
index 5d2a738..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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.
-
-templateConfigurations = \
- FirstMatchTemplateConfigurationFactory( \
- ConditionalTemplateConfigurationFactory( \
- FileExtensionMatcher("xml"), \
- TemplateConfiguration(outputFormat = XMLOutputFormat())), \
- ConditionalTemplateConfigurationFactory( \
- OrMatcher( \
- FileExtensionMatcher("html"), \
- FileExtensionMatcher("htm")), \
- TemplateConfiguration(outputFormat = HTMLOutputFormat())), \
- ConditionalTemplateConfigurationFactory( \
- FileExtensionMatcher("rtf"), \
- TemplateConfiguration(outputFormat = RTFOutputFormat())), \
- allowNoMatch = true)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
deleted file mode 100644
index fe9690c..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh
+++ /dev/null
@@ -1,22 +0,0 @@
-<#--
- 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.
--->
-${p?string.@price}
-${w?string.@weight}
-${fd?string.@fileDate}
-${let?datetime?string.@logEventTime}
[25/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range.ftl
new file mode 100644
index 0000000..d2f5450
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range.ftl
@@ -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.
+-->
+<#include 'range-common.ftl'>
+
+<@assertEquals actual=(4..)?size expected=2147483647 />
+<@assertEquals actual=limitedJoin(4.., 3) expected="4, 5, 6, ..." />
+
+<@assertEquals actual=(4..)[0] expected=4 />
+<@assertEquals actual=(4..)[1] expected=5 />
+<@assertEquals actual=(4..)[1000000] expected=1000004 />
+<@assertFails message="out of bounds">
+ <@assertEquals actual=(4..)[-1] expected=5 />
+</@>
+
+<#assign r = 2147483646..>
+<@assertEquals actual=r?size expected=2147483647 />
+<@assertEquals actual=limitedJoin(r, 3) expected="2147483646, 2147483647, 2147483648, ..." />
+<@assertEquals actual=r[100] expected=2147483746 />
+
+<#assign r = -2..>
+<@assertEquals actual=limitedJoin(r, 5) expected="-2, -1, 0, 1, 2, ..." />
+<@assertEquals actual=r[0] expected=-2 />
+<@assertEquals actual=r[1] expected=-1 />
+
+<#function limitedJoin range limit>
+ <#assign joined="">
+ <#list range as i>
+ <#assign joined = joined + i?c>
+ <#if i_has_next><#assign joined = joined + ', '></#if>
+ <#local limit = limit - 1>
+ <#if limit == 0><#assign joined = joined + "..."><#break></#if>
+ </#list>
+ <#return joined>
+</#function>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/recover.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/recover.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/recover.ftl
new file mode 100644
index 0000000..f7dc437
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/recover.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<#attempt>
+ <#assign sequence = ["Hello, World"]>
+ ${sequence[0]}
+<#recover>
+ We should never get here.
+</#recover>
+<#attempt>
+ Let's try to output an undefined variable: ${undefinedVariable}
+<#recover>
+ Well, that did not work.<@assert test=.error?contains('undefinedVariable') />
+ Now we nest another attempt/recover here:
+ <#attempt>
+ ${sequence[1]}
+ <#recover>
+ Oops...<@assert test=.error?contains('sequence[1]') />
+ Remember, freeMarker sequences are zero-based! ${sequence[0]}
+ </#recover>
+ Now we check the current error message.<@assert test=.error?contains('undefinedVariable') />
+</#recover>
+<#attempt>
+ <#include "nonexistent_template">
+<#recover>
+ The template is not currently available
+</#recover>
+<#attempt>
+ <#include "undefined.ftl">
+<#recover>
+ The included template had a problem.<@assert test=.error?contains('undefined_variable') />
+</#attempt>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/root.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/root.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/root.ftl
new file mode 100644
index 0000000..e1bc7f3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/root.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Root Lookup Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Access the same variable via the root variable (dot syntax):</p>
+
+<p>${.data_model.message}</p>
+
+<p>Access the same variable via the root variable (bracket syntax):</p>
+
+<p>${.data_model["message"]}</p>
+
+<p>Ensure that root lookups are unaffected by local variables:</p>
+
+<#macro test message>
+ ${.data_model.message}
+ ${message}
+</#macro>
+
+<@test message + " Part Deux" />
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/sequence-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/sequence-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/sequence-builtins.ftl
new file mode 100644
index 0000000..e21bc2d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/sequence-builtins.ftl
@@ -0,0 +1,360 @@
+<#--
+ 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.
+-->
+<@noOutput>
+<#setting locale="en_US">
+<#setting number_format="0.#########">
+
+<#assign ls = []?sort>
+<#list ls as i>
+- ${i}
+</#list>
+<@assertEquals expected=0 actual=ls?size />
+<@assertEquals expected=3 actual=set?size />
+</...@noOutput>
+Sorting scalars:
+----------------
+
+String order:
+<#assign ls = ["whale", "Barbara", "zeppelin", "aardvark", "beetroot"]?sort>
+<#list ls as i>
+- ${i}
+</#list>
+
+First: ${ls?first}
+Last: ${ls?last}
+Size ${ls?size}
+
+Numerical order:
+<#assign ls = [123?byte, 543, -324, -34?float, 0.11, 0, 111?int, 0.1?double, 1, 5]?sort>
+<#list ls as i>
+- ${i}
+</#list>
+
+First: ${ls?first}
+Last: ${ls?last}
+Size ${ls?size}
+
+Date/time order:
+<#assign x = [
+ '08:05'?time('HH:mm'),
+ '18:00'?time('HH:mm'),
+ '06:05'?time('HH:mm'),
+ '08:15'?time('HH:mm')]>
+<#list x?sort as i>
+- ${i?string('HH:mm')}
+</#list>
+
+Boolean order:
+<#assign x = [
+ true,
+ false,
+ false,
+ true]>
+<#list x?sort as i>
+- ${i?string}
+</#list>
+
+
+Sorting hashes:
+---------------
+
+<#assign ls = [
+ {"name":"whale", "weight":2000?short},
+ {"name":"Barbara", "weight":53},
+ {"name":"zeppelin", "weight":-200?float},
+ {"name":"aardvark", "weight":30?long},
+ {"name":"beetroot", "weight":0.3}
+]>
+Order by name:
+<#assign ls = ls?sort_by("name")>
+<#list ls as i>
+- ${i.name}: ${i.weight}
+</#list>
+
+Order by weight:
+<#assign ls = ls?sort_by("weight")>
+<#list ls as i>
+- ${i.name}: ${i.weight}
+</#list>
+
+Order by a.x.v:
+<#assign x = [
+ {"a": {"x": {"v": "qweqw", "w": "asd"}, "y": '1998-02-20'?date('yyyy-MM-dd')}},
+ {"a": {"x": {"v": "aqweqw", "w": "asd"}, "y": '1999-01-20'?date('yyyy-MM-dd')}},
+ {"a": {"x": {"v": "dfgdf", "w": "asd"}, "y": '1999-04-20'?date('yyyy-MM-dd')}},
+ {"a": {"x": {"v": "utyu", "w": "asd"}, "y": '1999-04-19'?date('yyyy-MM-dd')}}]>
+<#list x?sort_by(['a', 'x', 'v']) as i>
+- ${i.a.x.v}
+</#list>
+
+Order by a.y, which is a date:
+<#list x?sort_by(['a', 'y']) as i>
+- ${i.a.y?string('yyyy-MM-dd')}
+</#list>
+
+Reverse:
+--------
+
+Order by weight desc:
+<#assign ls = ls?reverse>
+<#list ls as i>
+- ${i.name}: ${i.weight}
+</#list>
+
+Order by weight desc desc:
+<#assign ls = ls?reverse>
+<#list ls as i>
+- ${i.name}: ${i.weight}
+</#list>
+
+Order by weight desc desc desc:
+<#assign ls = ls?reverse>
+<#list ls as i>
+- ${i.name}: ${i.weight}
+</#list>
+
+Contains:
+---------
+
+<#macro test></#macro>
+<#assign x = [1, "2", true, [1,2,3], {"a":1}, test, '1992-02-21'?date('yyyy-MM-dd')]>
+True:
+${x?seq_contains(1.0)?string}
+${x?seq_contains("2")?string}
+${x?seq_contains(true)?string}
+${x?seq_contains('1992-02-21'?date('yyyy-MM-dd'))?string}
+${abcSet?seq_contains("a")?string}
+${abcSet?seq_contains("b")?string}
+${abcSet?seq_contains("c")?string}
+
+False:
+${x?seq_contains("1")?string}
+${x?seq_contains(2)?string}
+${x?seq_contains(false)?string}
+${x?seq_contains('1992-02-22'?date('yyyy-MM-dd'))?string}
+${abcSet?seq_contains("A")?string}
+${abcSet?seq_contains(1)?string}
+${abcSet?seq_contains(true)?string}
+
+<#assign x = []>
+False: ${x?seq_contains(1)?string}
+
+Index_of:
+---------
+
+<#assign x = [1, "2", true, [1,2,3], {"a":1}, test, '1992-02-21'?date('yyyy-MM-dd')]>
+0 = ${x?seq_index_of(1.0)}
+1 = ${x?seq_index_of("2")}
+2 = ${x?seq_index_of(true)}
+6 = ${x?seq_index_of('1992-02-21'?date('yyyy-MM-dd'))}
+0 = ${abcSet?seq_index_of("a")}
+1 = ${abcSet?seq_index_of("b")}
+2 = ${abcSet?seq_index_of("c")}
+
+-1 = ${x?seq_index_of("1")}
+-1 = ${x?seq_index_of(2)}
+-1 = ${x?seq_index_of(false)}
+-1 = ${x?seq_index_of('1992-02-22'?date('yyyy-MM-dd'))}
+-1 = ${abcSet?seq_index_of("A")}
+-1 = ${abcSet?seq_index_of(1)}
+-1 = ${abcSet?seq_index_of(true)}
+
+<#assign x = []>
+-1 = ${x?seq_index_of(1)}
+
+Last_index_of:
+--------------
+
+<#assign x = [1, "2", true, [1,2,3], {"a":1}, test, 1, '1992-02-21'?date('yyyy-MM-dd')]>
+6 = ${x?seq_last_index_of(1.0)}
+1 = ${x?seq_last_index_of("2")}
+2 = ${x?seq_last_index_of(true)}
+7 = ${x?seq_last_index_of('1992-02-21'?date('yyyy-MM-dd'))}
+-1 = ${x?seq_last_index_of("1")}
+0 = ${abcSet?seq_last_index_of("a")}
+1 = ${abcSet?seq_last_index_of("b")}
+2 = ${abcSet?seq_last_index_of("c")}
+-1 = ${abcSet?seq_last_index_of("A")}
+
+Index_of and last_index_of with starting indices
+------------------------------------------------
+
+<#assign names = ["Joe", "Fred", "Joe", "Susan"]>
+seq_index_of "Joe":
+0 = ${names?seq_index_of("Joe", -2)}
+0 = ${names?seq_index_of("Joe", -1)}
+0 = ${names?seq_index_of("Joe", 0)}
+2 = ${names?seq_index_of("Joe", 1)}
+2 = ${names?seq_index_of("Joe", 2)}
+-1 = ${names?seq_index_of("Joe", 3)}
+-1 = ${names?seq_index_of("Joe", 4)}
+
+seq_last_index_of "Joe":
+-1 = ${names?seq_last_index_of("Joe", -2)}
+-1 = ${names?seq_last_index_of("Joe", -1)}
+0 = ${names?seq_last_index_of("Joe", 0)}
+0 = ${names?seq_last_index_of("Joe", 1)}
+2 = ${names?seq_last_index_of("Joe", 2)}
+2 = ${names?seq_last_index_of("Joe", 3)}
+2 = ${names?seq_last_index_of("Joe", 4)}
+
+seq_index_of "Susan":
+3 = ${names?seq_index_of("Susan", -2)}
+3 = ${names?seq_index_of("Susan", -1)}
+3 = ${names?seq_index_of("Susan", 0)}
+3 = ${names?seq_index_of("Susan", 1)}
+3 = ${names?seq_index_of("Susan", 2)}
+3 = ${names?seq_index_of("Susan", 3)}
+-1 = ${names?seq_index_of("Susan", 4)}
+
+seq_last_index_of "Susan":
+-1 = ${names?seq_last_index_of("Susan", -2)}
+-1 = ${names?seq_last_index_of("Susan", -1)}
+-1 = ${names?seq_last_index_of("Susan", 0)}
+-1 = ${names?seq_last_index_of("Susan", 1)}
+-1 = ${names?seq_last_index_of("Susan", 2)}
+3 = ${names?seq_last_index_of("Susan", 3)}
+3 = ${names?seq_last_index_of("Susan", 4)}
+
+seq_index_of "a":
+0 = ${abcSet?seq_index_of("a", -2)}
+0 = ${abcSet?seq_index_of("a", -1)}
+0 = ${abcSet?seq_index_of("a", 0)}
+-1 = ${abcSet?seq_index_of("a", 1)}
+-1 = ${abcSet?seq_index_of("a", 2)}
+-1 = ${abcSet?seq_index_of("a", 3)}
+-1 = ${abcSet?seq_index_of("a", 4)}
+
+seq_index_of "b":
+1 = ${abcSet?seq_index_of("b", -2)}
+1 = ${abcSet?seq_index_of("b", -1)}
+1 = ${abcSet?seq_index_of("b", 0)}
+1 = ${abcSet?seq_index_of("b", 1)}
+-1 = ${abcSet?seq_index_of("b", 2)}
+-1 = ${abcSet?seq_index_of("b", 3)}
+
+seq_index_of "c":
+2 = ${abcSet?seq_index_of("c", -2)}
+2 = ${abcSet?seq_index_of("c", -1)}
+2 = ${abcSet?seq_index_of("c", 0)}
+2 = ${abcSet?seq_index_of("c", 1)}
+2 = ${abcSet?seq_index_of("c", 2)}
+-1 = ${abcSet?seq_index_of("c", 3)}
+
+seq_last_index_of "a":
+-1 = ${abcSet?seq_last_index_of("a", -2)}
+-1 = ${abcSet?seq_last_index_of("a", -1)}
+0 = ${abcSet?seq_last_index_of("a", 0)}
+0 = ${abcSet?seq_last_index_of("a", 1)}
+0 = ${abcSet?seq_last_index_of("a", 2)}
+0 = ${abcSet?seq_last_index_of("a", 3)}
+0 = ${abcSet?seq_last_index_of("a", 4)}
+
+seq_last_index_of "b":
+-1 = ${abcSet?seq_last_index_of("b", -2)}
+-1 = ${abcSet?seq_last_index_of("b", -1)}
+-1 = ${abcSet?seq_last_index_of("b", 0)}
+1 = ${abcSet?seq_last_index_of("b", 1)}
+1 = ${abcSet?seq_last_index_of("b", 2)}
+1 = ${abcSet?seq_last_index_of("b", 3)}
+
+seq_last_index_of "c":
+-1 = ${abcSet?seq_last_index_of("c", -2)}
+-1 = ${abcSet?seq_last_index_of("c", -1)}
+-1 = ${abcSet?seq_last_index_of("c", 0)}
+-1 = ${abcSet?seq_last_index_of("c", 1)}
+2 = ${abcSet?seq_last_index_of("c", 2)}
+2 = ${abcSet?seq_last_index_of("c", 3)}
+
+Sequence builtins ignoring nulls
+--------------------------------
+
+true = ${listWithNull?seq_contains('c')?string}
+2 = ${listWithNull?seq_index_of('c')}
+0 = ${listWithNull?seq_last_index_of('a')}
+
+These should throw exception, but for BC they don't:
+false = ${listWithNull?seq_contains(noSuchVar)?string}
+-1 = ${listWithNull?seq_index_of(noSuchVar)}
+-1 = ${listWithNull?seq_last_index_of(noSuchVar)}
+
+Sequence built-ins failing on date-type mismatch
+------------------------------------------------
+
+<#assign x = ['1992-02-21'?date('yyyy-MM-dd'), 'foo']>
+<@assertEquals actual=x?seq_index_of('foo') expected=1 />
+<@assertEquals actual=x?seq_index_of('1992-02-21'?date('yyyy-MM-dd')) expected=0 />
+<@assertFails message="dates of different types">
+ 0 = ${x?seq_index_of('1992-02-21 00:00:00'?datetime('yyyy-MM-dd HH:mm:ss'))}
+</@>
+
+Chunk
+-----
+
+<#assign ls = ['a', 'b', 'c', 'd', 'e', 'f', 'g']>
+<#list ['NULL', '-'] as fill>
+ <#list [1, 2, 3, 4, 5, 10] as columns>
+ <@printTable ls, columns, fill />
+ </#list>
+</#list>
+<@printTable [1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 'NULL' />
+<@printTable [1, 2, 3, 4, 5, 6, 7, 8, 9], 3, '-' />
+<@printTable [1], 3, 'NULL' />
+<@printTable [1], 3, '-' />
+<@printTable [], 3, 'NULL' />
+<@printTable [], 3, '-' />
+
+<#macro printTable ls columns fill>
+ columns = ${columns}, fill = ${fill}:<#lt>
+ <#if fill='NULL'>
+ <#local rows = ls?chunk(columns)>
+ <#else>
+ <#local rows = ls?chunk(columns, fill)>
+ </#if>
+ Rows: ${rows?size}
+ <#list rows as row>
+ <#list row as i>${i} </#list> <-- Columns: ${row?size}
+ </#list>
+
+</#macro>
+
+
+Join
+----
+
+<#assign xs = [1, "two", "three", 4]>
+- ${xs?join(", ")}
+- ${[]?join(", ")}
+- ${xs?join(", ", "(empty)", ".")}
+- ${[]?join(", ", "(empty)", ".")}
+- ${listWithNull?join(", ")}
+- ${listWithNull?join(", ", "(empty)")}
+- ${listWithNull?join(", ", "(empty)", ".")}
+- ${listWithNullsOnly?join(", ")}
+- ${listWithNullsOnly?join(", ", "(empty)")}
+- ${listWithNullsOnly?join(", ", "(empty)", ".")}
+- ${abcSet?join(", ", "(empty)", ".")}
+- ${abcCollection?join(", ", "(empty)", ".")}
+<@assertFails message="index 1">${['a', [], 'c']?join(", ", "(empty)", ".")}</@>
+
+Misc
+----
+
+First of set 1: ${abcSet?first}
+First of set 2: ${abcSetNonSeq?first}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/setting.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/setting.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/setting.ftl
new file mode 100644
index 0000000..89f3e23
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/setting.ftl
@@ -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.
+-->
+<#setting locale='de_DE'>
+<@assertEquals expected='de_DE' actual=.locale />
+<@assertEquals expected='de' actual=.lang />
+<@assertEquals expected='java.util.Locale "de_DE"' actual=javaObjectInfo.info(.locale_object) />
+
+<#setting number_format="'f'#">
+<@assertEquals expected='f1' actual=1?string />
+
+<#setting boolean_format="t,f">
+<@assertEquals expected='t' actual=true?string />
+
+<#setting date_format="'df'">
+<@assertEquals expected='df' actual=.now?date?string />
+
+<#setting time_format="'tf'">
+<@assertEquals expected='tf' actual=.now?time?string />
+
+<#setting datetime_format="'dtf'">
+<@assertEquals expected='dtf' actual=.now?string />
+
+<#setting time_zone='GMT+00'>
+<#assign t1='2000'?datetime('yyyy')>
+<#setting time_zone='GMT+01'>
+<#assign t2='2000'?datetime('yyyy')>
+<@assertEquals expected=1000*60*60 actual=t1?long-t2?long />
+
+<#setting sql_date_and_time_time_zone='GMT+01'>
+
+<#setting url_escaping_charset='ISO-8859-1'>
+<@assertEquals expected='%E1' actual='á'?url />
+<#setting url_escaping_charset='UTF-8'>
+<@assertEquals expected='%C3%A1' actual='á'?url />
+
+<#setting output_encoding="ISO-8859-2">
+<@assertEquals expected="ISO-8859-2" actual=.output_encoding />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/simplehash-char-key.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/simplehash-char-key.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/simplehash-char-key.ftl
new file mode 100644
index 0000000..07a3f1e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/simplehash-char-key.ftl
@@ -0,0 +1,44 @@
+<#--
+ 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.
+-->
+<@assertEquals expected="string" actual=mStringC.c />
+<@assertEquals expected=1 actual=mStringC?keys?size />
+<@assertEquals expected="null" actual=mStringC.d!'null' />
+<@assertEquals expected=1 actual=mStringC?keys?size />
+
+<@assertEquals expected="null" actual=mStringCNull.c!'null' />
+<@assertEquals expected=1 actual=mStringCNull?keys?size />
+<@assertEquals expected="null" actual=mStringCNull.d!'null' />
+<@assertEquals expected=1 actual=mStringCNull?keys?size />
+
+<@assertEquals expected="char" actual=mCharC.c />
+<@assertEquals expected=1 actual=mCharC?keys?size />
+<@assertEquals expected="null" actual=mCharC.d!'null' />
+<@assertEquals expected=1 actual=mCharC?keys?size />
+
+<@assertEquals expected="null" actual=mCharCNull.c!'null' />
+<@assertEquals expected=1 actual=mCharCNull?keys?size />
+<@assertEquals expected="null" actual=mCharCNull.d!'null' />
+<@assertEquals expected=1 actual=mCharCNull?keys?size />
+
+<@assertEquals expected="char" actual=mMixed.c />
+<@assertEquals expected="string" actual=mMixed.s />
+<@assertEquals expected="string2" actual=mMixed.s2 />
+<@assertEquals expected="null" actual=mMixed.s2n!'null' />
+<@assertEquals expected="null" actual=mMixed.wrong!'null' />
+<@assertEquals expected=4 actual=mMixed?keys?size />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/specialvars.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/specialvars.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/specialvars.ftl
new file mode 100644
index 0000000..50416c9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/specialvars.ftl
@@ -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.
+-->
+<#-- Mostly just checks if the expressions doesn't fail -->
+<#assign works = .data_model>
+<#attempt>
+ ${noSuchVariableExists}
+<#recover>
+ <#assign works = .error>
+</#attempt>
+<#assign works = .globals>
+${.lang} == en
+${.locale} == en_US
+<#assign works = .locals!>
+<#assign works = .main>
+<#assign works = .node!>
+${.output_encoding?lower_case} == utf-8
+${.template_name} == specialvars.ftl
+${.url_escaping_charset?lower_case} == iso-8859-1
+<#assign foo = "x">
+${.vars['foo']} == x
+<#assign works = .version>
+${.now?is_datetime?c} == true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtin-coercion.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtin-coercion.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtin-coercion.ftl
new file mode 100644
index 0000000..5d2e094
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtin-coercion.ftl
@@ -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.
+-->
+Was broken 2.3.19:
+<#setting number_format="0.#">
+<@assert test=1232?contains('2') />
+<@assert test=1232?index_of('2') == 1 />
+<@assert test=1232?last_index_of('2') == 3 />
+<@assert test=1232?left_pad(6) == ' 1232' /><@assert test=1232?left_pad(6, '0') == '001232' />
+<@assert test=1232?right_pad(6) == '1232 ' /><@assert test=1232?right_pad(6, '0') == '123200' />
+<@assert test=1232?matches('[1-3]+') />
+<@assert test=1232?replace('2', 'z') == '1z3z' />
+<@assert test=1232?replace('2', 'z', 'r') == '1z3z' />
+<@assert test=1232?split('2')[1] == '3' /><@assert test=1232?split('2')[2] == '' />
+<@assert test=1232?split('2', 'r')[1] == '3' />
+
+Was no broken in 2.3.19:
+<@assert test=1232?starts_with('12') />
+<@assert test=1232?ends_with('32') />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps-matches.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps-matches.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps-matches.ftl
new file mode 100644
index 0000000..201f404
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps-matches.ftl
@@ -0,0 +1,118 @@
+<#--
+ 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.
+-->
+<#assign input>
+L16
+L27
+L38
+L49
+</#assign>
+
+List mode:
+<#assign matches = input?matches(".+") >
+Size: ${matches?size}
+<#list 0..<matches?size as i>[${matches[i]}]</#list>
+<#list matches as m>[${m}]</#list>
+
+Iterator mode:
+<#assign matches = input?matches(".+") >
+<#list matches as m>[${m}]</#list>
+<#list matches as m>[${m}(${matches?join(', ')})]</#list>
+<#list matches as m>[${m}]</#list>
+
+Iterator mode changes to list mode:
+<#assign matches = input?matches(".+") >
+<#list matches as m>[${m}]/${matches?size}</#list>
+<#list matches as m>[${m}]</#list>
+
+Iterator mode changes to list mode 2:
+<#assign matches = input?matches(".+") >
+<#list matches as m>[${m}]</#list>
+<#list matches as m>[${m}]/${matches?size}<#t></#list>
+
+List mode with embedded iteration:
+<#assign matches = input?matches(".+") >
+<#list 0..<matches?size as i>[${matches[i]}(${matches?join(', ')})]</#list>
+
+Entire input match:
+<#assign matches = input?matches(r".*(\d)(\d)") >
+<#assign firstGS = false>
+<#list matches as m>
+- M: ${m}
+ <#if firstGS?is_boolean>
+ <#assign firstGS = m?groups>
+ </#if>
+ <#list m?groups as g>
+ - G: ${g}
+ </#list>
+</#list>
+firstGS was: ${firstGS?join(', ')}
+
+Entire input match 2:
+<#assign match = "x12"?matches(r"x(\d)(\d)") >
+Matches: ${match?c}
+<#list match?groups as g>
+- G: ${g}
+</#list>
+As list:
+<#list match as m>
+- M: ${m}
+ <#list m?groups as g>
+ - G: ${g}
+ </#list>
+</#list>
+Groups again:
+<#list match?groups as g>
+- G: ${g}
+</#list>
+
+Entire input match 3:
+<#assign match = "x12"?matches(r"y(\d)(\d)") >
+Matches: ${match?c}
+<@assertEquals expected=3 actual=match?groups?size />
+<@assertEquals expected=0 actual=match?size />
+
+Entire input match 4:
+<#assign match = "x12"?matches(r"x(\d)(\d)") >
+Matches: ${match?c}
+<#assign gs = match?groups>
+<@assertEquals expected=3 actual=gs?size />
+<@assertEquals expected=1 actual=match?size />
+- G: ${gs[0]}
+- G: ${match?groups[1]}
+- G: ${gs[2]}
+
+Substring match nested into entire input match:
+<#assign match = "x12"?matches(r"x(\d)(\d)") >
+<#list match?groups as g>
+- G: ${g} (<#list match as m>[${m}{${m?groups?join(', ')}}]</#list>)
+</#list>
+
+Different entire input and substring matches:
+<#assign match = "123"?matches(r"(\d+?)") >
+${match?groups?join(", ")}
+<#list match as m>
+- M: ${m} (Gs: ${m?groups?join(", ")})
+</#list>
+
+Different entire input and substring matches 2:
+<#assign match = "123"?matches(r"\d+?") >
+${match?groups?join(", ")}
+<#list match as m>
+- M: ${m} (Gs: ${m?groups?join(", ")})
+</#list>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
new file mode 100644
index 0000000..81c0b8f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
@@ -0,0 +1,136 @@
+<#--
+ 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.
+-->
+${"test"?matches('test')?string} == true
+${"test"?matches('test', '')?string} == true
+
+${"TEST"?matches('test')?string} == false
+${"TEST"?matches('test', 'i')?string} == true
+
+${"test\nfoo"?matches('.*^foo')?string} == false
+${"test\nfoo"?matches(r'.*\n^foo', 'm')?string} == true
+
+${"test\nfoo"?matches('test.foo')?string} == false
+${"test\nfoo"?matches('test.foo', 's')?string} == true
+
+${"test\nFoo"?matches('.*foo', 's')?string} == false
+${"test\nFoo"?matches('.*foo', 'i')?string} == false
+${"test\nFoo"?matches('.*foo', 'im')?string} == false
+${"test\nFoo"?matches('.*foo', 'si')?string} == true
+${"test\nFoo"?matches('.*foo', 'is')?string} == true
+${"test\nFoo"?matches('.*foo', 'mis')?string} == true
+
+${"test\nFoo"?matches('.*\n^foo', 'm')?string} == false
+${"test\nFoo"?matches('.*\n^foo', 'i')?string} == false
+${"test\nFoo"?matches('.*\n^foo', 'im')?string} == true
+${"test\nFoo"?matches('.*\n^foo', 'mi')?string} == true
+${"test\nFoo"?matches('.*^foo', 'ism')?string} == true
+${"test\nFoo"?matches('.*^foo', 'smi')?string} == true
+<#setting boolean_format="True,False">
+<@assert test=false?matches('[eslaF]+') />
+<@assert test='False'?matches('[eslaF]+') />
+
+<#assign s = "Code without test coverage\nis considered to be BROKEN">
+
+Lower 'c'-words:
+<#list s?matches('c[a-z]*') as m>
+- ${m}
+</#list>
+
+Any 'c'-words:
+<#list s?matches('c[a-z]*', 'i') as m>
+- ${m}
+</#list>
+
+Lower line-last words:
+<#list s?matches('[a-z]+$', 'm') as m>
+- ${m}
+</#list>
+
+Any line-last words:
+<#list s?matches('[a-z]+$', 'mi') as m>
+- ${m}
+</#list>
+
+Any last words:
+<#list s?matches('[a-z]+$', 'i') as m>
+- ${m}
+</#list>
+
+c-word with follower:
+<#list s?matches('(c[a-z]*+).([a-z]++)', 'is') as m>
+- "${m?j_string}"
+ Groups: <#list m?groups as g>"${g?j_string}"<#if g_has_next>, </#if></#list>
+</#list>
+
+c-word with follower in the same line:
+<#list s?matches('c[a-z]*+.[a-z]++', 'i') as m>
+- ${m}
+</#list>
+
+Lower c-word with follower in the same line:
+<#list s?matches('c[a-z]*+.[a-z]++', '') as m>
+- ${m}
+</#list>
+
+<#attempt>
+ Ignored but logged in 2.3: ${s?matches('broken', 'I')?string} == False
+<#recover>
+ Fails in 2.4
+</#attempt>
+<#attempt>
+ Ignored but logged in 2.3: ${s?matches('broken', 'f')?string} == False
+<#recover>
+ Fails in 2.4
+</#attempt>
+
+${"foobar"?replace("foo", "FOO")} == FOObar
+${"Foobar"?replace("foo", "FOO", "")} == Foobar
+${"Foobar"?replace("foo", "FOO", "i")} == FOObar
+${"FoobarfOO"?replace("foo", "FOO", "i")} == FOObarFOO
+${"FoobarfOO"?replace("foo", "FOO", "if")} == FOObarfOO
+${"FoobarfOO"?replace("foo", "FOO", "fi")} == FOObarfOO
+${"Foobar"?replace("foo", "FOO", "r")} == Foobar
+${"Foobar"?replace("foo", "FOO", "ri")} == FOObar
+${"FoobarfOO"?replace("foo", "FOO", "ri")} == FOObarFOO
+${"FoobarfOO"?replace("foo", "FOO", "rif")} == FOObarfOO
+${"FoobarfOO"?replace("foo", "FOO", "fri")} == FOObarfOO
+${"foobar"?replace("fo+", "FOO")} == foobar
+${"foobar"?replace("fo+", "FOO", "")} == foobar
+${"foobar"?replace("fo+", "FOO", "r")} == FOObar
+${"foobarfOo"?replace("fo+", "FOO", "ri")} == FOObarFOO
+${"foobarfOo"?replace("fo+", "FOO", "rif")} == FOObarfOo
+${false?replace('a', 'A')} == FAlse
+${false?replace('[abc]', 'A', 'r')} == FAlse
+
+<#attempt>
+ Ignored but logged in 2.3: ${"foobar"?replace("foo", "FOO", "c")}
+<#recover>
+ Fails in 2.4
+</#attempt>
+
+<#macro dumpList xs>[<#list xs as x>${x}<#if x_has_next>, </#if></#list>]</#macro>
+<@dumpList "fooXbarxbaaz"?split("X") /> == [foo, barxbaaz]
+<@dumpList "fooXbarxbaaz"?split("X", "") /> == [foo, barxbaaz]
+<@dumpList "fooXbarxbaaz"?split("X", "i") /> == [foo, bar, baaz]
+<@dumpList "fooXbarxbaaz"?split("X", "r") /> == [foo, barxbaaz]
+<@dumpList "fooXbarxbaaz"?split("X", "ri") /> == [foo, bar, baaz]
+<@dumpList "fooXXbarxxbaaz"?split("X+", "i") /> == [fooXXbarxxbaaz]
+<@dumpList "fooXXbarxxbaaz"?split("X+", "ri") /> == [foo, bar, baaz]
+<@dumpList false?split("[ae]", "r") /> == [F, ls]
+<@dumpList false?split("e") /> == [Fals, ]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins1.ftl
new file mode 100644
index 0000000..0e18520
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins1.ftl
@@ -0,0 +1,129 @@
+<#--
+ 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.
+-->
+FreeMarker: Encoding string built-in tests
+
+<#assign x = r' dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case} '>
+
+cap_first: ${x?cap_first}
+uncap_first:${x?uncap_first}
+uncap_first:${"Blah"?uncap_first}
+capitalize: ${x?capitalize}
+html: ${x?html}
+length: ${x?length}
+lower_case: ${x?lower_case}
+rtf: ${x?rtf}
+trim: ${x?trim}
+trim2: ${"foo bar"?trim}
+trim3: ${" foo bar"?trim}
+trim4: ${"foo bar "?trim}
+upper_case: ${x?upper_case}
+xml: ${x?xml}
+xhtml: ${"\"Blah's is > 1 & < 2\""?xhtml}
+<@assertEquals actual="'"?html expected="'" />
+<@assertEquals actual="'"?xhtml expected="'" />
+<@assertEquals actual="'"?xml expected="'" />
+<#-- ?substring: -->
+<@assertEquals actual="ab"?substring(0) expected="ab" />
+<@assertEquals actual="ab"?substring(1) expected="b" />
+<@assertEquals actual="ab"?substring(2) expected="" />
+<@assertFails message="at least 0">${"ab"?substring(-1)}</@><#t>
+<@assertFails message="greater than the length of the string">${"ab"?substring(3)}</@><#t>
+<@assertEquals actual="ab"?substring(0, 0) expected="" />
+<@assertEquals actual="ab"?substring(0, 1) expected="a" />
+<@assertEquals actual="ab"?substring(0, 2) expected="ab" />
+<@assertFails message="at least 0">${"ab"?substring(0, -1)}</@><#t>
+<@assertFails message="greater than the length of the string">${"ab"?substring(0, 3)}</@><#t>
+<@assertEquals actual="ab"?substring(1, 1) expected="" />
+<@assertEquals actual="ab"?substring(1, 2) expected="b" />
+<@assertFails message="at least 0">${"ab"?substring(1, -1)}</@><#t>
+<@assertFails message="greater than the length of the string">${"ab"?substring(1, 3)}</@><#t>
+<@assertFails message="shouldn't be greater than the end index">${"ab"?substring(1, 0)}</@><#t>
+
+word_list:
+<#global words = x?word_list>
+<#list words as w>- ${w}
+</#list>
+
+<#global canufeelitbabe = x?interpret>
+interpret: <@canufeelitbabe></@>
+<#setting locale="es_ES">number: ${"-123.45"?number + 1.1}
+${"1.5e3"?number?c}
+${"0005"?number?c}
+${"+0"?number?c}
+${"-0"?number?c}
+${"NaN"?number?is_nan?c}
+${("INF"?number?is_infinite && "INF"?number > 0)?c}
+${("-INF"?number?is_infinite && "-INF"?number < 0)?c}
+${("Infinity"?number?is_infinite && "Infinity"?number > 0)?c}
+${("-Infinity"?number?is_infinite && "-Infinity"?number < 0)?c}
+
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new()}
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new(1)}
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("xxx")}
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("xxx", "yyy")}
+
+<#assign x = "In the beginning, God created the Heavens and The Earth.">
+
+${x?replace("the", "The Sacred, Holy", "i")} <#-- case insensitive replacement -->
+${x?replace("the", "the very", "f")} <#-- replace only the first one -->
+${x?replace("", "|")} <#-- replace empry string -->
+${x?replace("", "|", "f")} <#-- replace first empty string -->
+
+${x?replace("the H[a-z]+", "the sky", "r")} <#-- regexp replacement -->
+
+<#if x?matches(".*Heav..s.*")>matches<#else>Really?</#if>
+
+<#list x?matches("(the) ([a-z]+)", "i") as match>
+ ${match}
+ ${match?groups[1]} sacred ${match?groups[2]}
+</#list>
+
+<#assign matches = x?matches("In the ([a-z]+), God created (.*)")>
+${matches?groups[0]}
+${matches?groups[1]}
+${matches?groups[2]}
+
+<#assign x="foo, bar;baz, foobar">
+<#list x?split("[,;] ?", "r") as word>
+ ${word}
+</#list>
+
+
+<#assign a = "foo", b="bar", c="(a+b)?upper_case">
+${c?eval}
+
+[${"a"?j_string}] = [a]
+[${"a\\'x'\nb"?j_string}] = [a\\'x'\nb]
+[${"\x1\x1A\x20"?j_string}] = [\u0001\u001a ]
+
+[${"a"?js_string}] = [a]
+[${"a\\'x'\nb"?js_string}] = [a\\\'x\'\nb]
+[${"\x1\x1A\x20"?js_string}] = [\x01\x1A ]
+[${"<![CDATA["?js_string}] = [\x3C![CDATA[]
+[${"]]>"?js_string}] = []]\>]
+
+[${"a"?json_string}] = [a]
+[${"a\\'x'\nb"?json_string}] = [a\\'x'\nb]
+[${"\x1\x1A\x20"?json_string}] = [\u0001\u001A ]
+[${"\n\r\t\f\b\""?json_string}] = [\n\r\t\f\b\"]
+[${"/"?json_string}] = [\/]
+[${"a/b"?json_string}] = [a/b]
+[${"</script>"?json_string}] = [<\/script>]
+[${"<![CDATA["?json_string}] = [\u003C![CDATA[]
+[${"]]>"?json_string}] = []]\u003E]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins2.ftl
new file mode 100644
index 0000000..c9294fa
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins2.ftl
@@ -0,0 +1,135 @@
+<#--
+ 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.
+-->
+--
+<#assign s = "abbcdbb">
+${s?index_of("bb")} = 1
+${s?index_of("bb", 2)} = 5
+${s?index_of("")} = 0
+--
+${s?last_index_of("bb")} = 5
+${s?last_index_of("bb", 4)} = 1
+${s?last_index_of("")} = ${s?length}
+--
+${s?starts_with("abb")?string} = true
+${s?starts_with("bb")?string} = false
+${s?starts_with("")?string} = true
+--
+${s?ends_with("dbb")?string} = true
+${s?ends_with("cbb")?string} = false
+${s?ends_with("")?string} = true
+--
+${s?contains("abb")?string} = true
+${s?contains("bcd")?string} = true
+${s?contains("dbb")?string} = true
+${s?contains("bbx")?string} = false
+${s?contains("")?string} = true
+--
+[${s?chop_linebreak}] = [abbcdbb]
+[${"qwe\n"?chop_linebreak}] = [qwe]
+[${"qwe\r"?chop_linebreak}] = [qwe]
+[${"qwe\r\n"?chop_linebreak}] = [qwe]
+[${"qwe\r\n\r\n"?chop_linebreak}] = [qwe
+]
+[${"qwe\n\n"?chop_linebreak}] = [qwe
+]
+--
+[${s?replace("A", "-")}] = [abbcdbb]
+[${s?replace("c", "-")}] = [abb-dbb]
+[${s?replace("bb", "-=*")}] = [a-=*cd-=*]
+--
+<#assign ls = s?split("b")>
+<#list ls as i>[${i}]</#list> == [a][][cd][][]
+<#list "--die--maggots--!"?split("--") as i>[${i}]</#list> == [][die][maggots][!]
+<#list "Die maggots!"?split("--") as i>[${i}]</#list> == [Die maggots!]
+--
+[${""?left_pad(5)}]
+[${"a"?left_pad(5)}]
+[${"ab"?left_pad(5)}]
+[${"abc"?left_pad(5)}]
+[${"abcd"?left_pad(5)}]
+[${"abcde"?left_pad(5)}]
+[${"abcdef"?left_pad(5)}]
+[${"abcdefg"?left_pad(5)}]
+[${"abcdefgh"?left_pad(5)}]
+[${""?left_pad(5, "-")}]
+[${"a"?left_pad(5, "-")}]
+[${"ab"?left_pad(5, "-")}]
+[${"abc"?left_pad(5, "-")}]
+[${"abcd"?left_pad(5, "-")}]
+[${"abcde"?left_pad(5, "-")}]
+[${"abcdef"?left_pad(5, "-")}]
+[${"abcdefg"?left_pad(5, "-")}]
+[${"abcdefgh"?left_pad(5, "-")}]
+[${""?left_pad(8, ".oO")}]
+[${"a"?left_pad(8, ".oO")}]
+[${"ab"?left_pad(8, ".oO")}]
+[${"abc"?left_pad(8, ".oO")}]
+[${"abcd"?left_pad(8, ".oO")}]
+[${"abcde"?left_pad(8, ".oO")}]
+[${"abcdef"?left_pad(8, ".oO")}]
+[${"abcdefg"?left_pad(8, ".oO")}]
+[${"abcdefgh"?left_pad(8, ".oO")}]
+[${"abcdefghi"?left_pad(8, ".oO")}]
+[${"abcdefghij"?left_pad(8, ".oO")}]
+[${""?left_pad(0, r"/\_")}]
+[${""?left_pad(1, r"/\_")}]
+[${""?left_pad(2, r"/\_")}]
+[${""?left_pad(3, r"/\_")}]
+[${""?left_pad(4, r"/\_")}]
+[${""?left_pad(5, r"/\_")}]
+[${""?left_pad(6, r"/\_")}]
+[${""?left_pad(7, r"/\_")}]
+--
+[${""?right_pad(5)}]
+[${"a"?right_pad(5)}]
+[${"ab"?right_pad(5)}]
+[${"abc"?right_pad(5)}]
+[${"abcd"?right_pad(5)}]
+[${"abcde"?right_pad(5)}]
+[${"abcdef"?right_pad(5)}]
+[${"abcdefg"?right_pad(5)}]
+[${"abcdefgh"?right_pad(5)}]
+[${""?right_pad(5, "-")}]
+[${"a"?right_pad(5, "-")}]
+[${"ab"?right_pad(5, "-")}]
+[${"abc"?right_pad(5, "-")}]
+[${"abcd"?right_pad(5, "-")}]
+[${"abcde"?right_pad(5, "-")}]
+[${"abcdef"?right_pad(5, "-")}]
+[${"abcdefg"?right_pad(5, "-")}]
+[${"abcdefgh"?right_pad(5, "-")}]
+[${""?right_pad(8, ".oO")}]
+[${"a"?right_pad(8, ".oO")}]
+[${"ab"?right_pad(8, ".oO")}]
+[${"abc"?right_pad(8, ".oO")}]
+[${"abcd"?right_pad(8, ".oO")}]
+[${"abcde"?right_pad(8, ".oO")}]
+[${"abcdef"?right_pad(8, ".oO")}]
+[${"abcdefg"?right_pad(8, ".oO")}]
+[${"abcdefgh"?right_pad(8, ".oO")}]
+[${"abcdefghi"?right_pad(8, ".oO")}]
+[${"abcdefghij"?right_pad(8, ".oO")}]
+[${""?right_pad(0, r"/\_")}]
+[${""?right_pad(1, r"/\_")}]
+[${""?right_pad(2, r"/\_")}]
+[${""?right_pad(3, r"/\_")}]
+[${""?right_pad(4, r"/\_")}]
+[${""?right_pad(5, r"/\_")}]
+[${""?right_pad(6, r"/\_")}]
+[${""?right_pad(7, r"/\_")}]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins3.ftl
new file mode 100644
index 0000000..77389fa
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/string-builtins3.ftl
@@ -0,0 +1,225 @@
+<#--
+ 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.
+-->
+<@assertEquals expected='foo' actual='foo'?keep_before('x') />
+<@assertEquals expected='f' actual='foo'?keep_before('o') />
+<@assertEquals expected='' actual='foo'?keep_before('f') />
+<@assertEquals expected='fo' actual='foobar'?keep_before('ob') />
+<@assertEquals expected='foob' actual='foobar'?keep_before('ar') />
+<@assertEquals expected='' actual='foobar'?keep_before('foobar') />
+<@assertEquals expected='' actual='foobar'?keep_before('') />
+<@assertEquals expected='' actual='foobar'?keep_before('', 'r') />
+<@assertEquals expected='FOO' actual='FOO'?keep_before('o') />
+<@assertEquals expected='F' actual='FOO'?keep_before('o', 'i') />
+<@assertEquals expected='fo' actual='fo.o'?keep_before('.') />
+<@assertEquals expected='' actual='fo.o'?keep_before('.', 'r') />
+<@assertEquals expected='FOOb' actual='FOObaar'?keep_before(r'([a-z])\1', 'r') />
+<@assertEquals expected='F' actual='FOObaar'?keep_before(r'([a-z])\1', 'ri') />
+<@assertEquals expected='foo' actual="foo : bar"?keep_before(r"\s*:\s*", "r") />
+<@assertEquals expected='foo' actual="foo:bar"?keep_before(r"\s*:\s*", "r") />
+<@assertFails message='"m" flag'>
+ ${'x'?keep_before('x', 'm')}
+</...@assertFails>
+<@assertFails message='3'>
+ ${'x'?keep_before('x', 'i', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?keep_before()}
+</...@assertFails>
+
+<@assertEquals expected='' actual=''?keep_before_last('f') />
+<@assertEquals expected='ff' actual='fff'?keep_before_last('f') />
+<@assertEquals expected='' actual='foo'?keep_before_last('f') />
+<@assertEquals expected='' actual='f'?keep_before_last('f') />
+<@assertEquals expected='a.b' actual='a.b.txt'?keep_before_last('.') />
+<@assertEquals expected='ab' actual='ab'?keep_before_last('.') />
+<@assertEquals expected='a' actual='ab'?keep_before_last('.', 'r') />
+<@assertEquals expected='ab' actual='ab'?keep_before_last(r'\.', 'r') />
+<@assertEquals expected='af' actual='afFf'?keep_before_last('F') />
+<@assertEquals expected='afF' actual='afFf'?keep_before_last('F', 'i') />
+<@assertEquals expected='1a2' actual='1a2b3'?keep_before_last('[ab]', 'r') />
+<@assertEquals expected='aa' actual='aaabb'?keep_before_last('[ab]{3}', 'r') />
+<@assertEquals expected='aaabbx' actual='aaabbxbabe'?keep_before_last('[ab]{3}', 'r') />
+<@assertEquals expected='xxxaa' actual='xxxaaayyy'?keep_before_last('a+', 'r') />
+<@assertEquals expected='foobar' actual='foobar'?keep_before_last('') />
+<@assertEquals expected='foobar' actual='foobar'?keep_before_last('', 'r') />
+<@assertFails message='"m" flag'>
+ ${'x'?keep_before_last('x', 'm')}
+</...@assertFails>
+<@assertFails message='3'>
+ ${'x'?keep_before_last('x', 'i', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?keep_before_last()}
+</...@assertFails>
+
+<@assertEquals expected='' actual='foo'?keep_after('x') />
+<@assertEquals expected='o' actual='foo'?keep_after('o') />
+<@assertEquals expected='oo' actual='foo'?keep_after('f') />
+<@assertEquals expected='ar' actual='foobar'?keep_after('ob') />
+<@assertEquals expected='' actual='foobar'?keep_after('ar') />
+<@assertEquals expected='' actual='foobar'?keep_after('foobar') />
+<@assertEquals expected='foobar' actual='foobar'?keep_after('') />
+<@assertEquals expected='foobar' actual='foobar'?keep_after('', 'r') />
+<@assertEquals expected='' actual='FOO'?keep_after('o') />
+<@assertEquals expected='O' actual='FOO'?keep_after('o', 'i') />
+<@assertEquals expected='o' actual='fo.o'?keep_after('.') />
+<@assertEquals expected='o.o' actual='fo.o'?keep_after('.', 'r') />
+<@assertEquals expected='r' actual='FOObaar'?keep_after(r'([a-z])\1', 'r') />
+<@assertEquals expected='baar' actual='FOObaar'?keep_after(r'([a-z])\1', 'ri') />
+<@assertEquals expected='bar' actual="foo : bar"?keep_after(r"\s*:\s*", "r") />
+<@assertEquals expected='bar' actual="foo:bar"?keep_after(r"\s*:\s*", "r") />
+<@assertFails message='"m" flag'>
+ ${'x'?keep_after('x', 'm')}
+</...@assertFails>
+<@assertFails message='3'>
+ ${'x'?keep_after('x', 'i', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?keep_after()}
+</...@assertFails>
+
+<@assertEquals expected='' actual=''?keep_after_last('f') />
+<@assertEquals expected='' actual='fff'?keep_after_last('f') />
+<@assertEquals expected='' actual='oof'?keep_after_last('f') />
+<@assertEquals expected='' actual='f'?keep_after_last('f') />
+<@assertEquals expected='txt' actual='a.b.txt'?keep_after_last('.') />
+<@assertEquals expected='' actual='ab'?keep_after_last('.') />
+<@assertEquals expected='' actual='ab'?keep_after_last('.', 'r') />
+<@assertEquals expected='' actual='ab'?keep_after_last(r'\.', 'r') />
+<@assertEquals expected='fa' actual='fFfa'?keep_after_last('F') />
+<@assertEquals expected='a' actual='fFfa'?keep_after_last('F', 'i') />
+<@assertEquals expected='3' actual='1a2b3'?keep_after_last('[ab]', 'r') />
+<@assertEquals expected='' actual='aaabb'?keep_after_last('[ab]{3}', 'r') />
+<@assertEquals expected='x' actual='aaabbx'?keep_after_last('[ab]{3}', 'r') />
+<@assertEquals expected='e' actual='aaabbxbabe'?keep_after_last('[ab]{3}', 'r') />
+<@assertEquals expected='12345' actual='aaabb12345'?keep_after_last('[ab]{3}', 'r') />
+<@assertEquals expected='yyy' actual='xxxaaayyy'?keep_after_last('a+', 'r') />
+<@assertEquals expected='' actual='foobar'?keep_after_last('') />
+<@assertEquals expected='' actual='foobar'?keep_after_last('', 'r') />
+<@assertFails message='"m" flag'>
+ ${'x'?keep_after_last('x', 'm')}
+</...@assertFails>
+<@assertFails message='3'>
+ ${'x'?keep_after_last('x', 'i', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?keep_after_last()}
+</...@assertFails>
+
+<@assertEquals expected='foo' actual='foo'?remove_beginning('x') />
+<@assertEquals expected='foo' actual='foo'?remove_beginning('o') />
+<@assertEquals expected='foo' actual='foo'?remove_beginning('fooo') />
+<@assertEquals expected='oo' actual='foo'?remove_beginning('f') />
+<@assertEquals expected='o' actual='foo'?remove_beginning('fo') />
+<@assertEquals expected='' actual='foo'?remove_beginning('foo') />
+<@assertEquals expected='foo' actual='foo'?remove_beginning('') />
+<@assertFails message='2'>
+ ${'x'?remove_beginning('x', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?remove_beginning()}
+</...@assertFails>
+
+<@assertEquals expected='bar' actual='bar'?remove_ending('x') />
+<@assertEquals expected='bar' actual='bar'?remove_ending('a') />
+<@assertEquals expected='bar' actual='bar'?remove_ending('barr') />
+<@assertEquals expected='ba' actual='bar'?remove_ending('r') />
+<@assertEquals expected='b' actual='bar'?remove_ending('ar') />
+<@assertEquals expected='' actual='bar'?remove_ending('bar') />
+<@assertEquals expected='bar' actual='bar'?remove_ending('') />
+<@assertFails message='2'>
+ ${'x'?remove_ending('x', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?remove_ending()}
+</...@assertFails>
+
+<@assertEquals expected='xfoo' actual='foo'?ensure_starts_with('x') />
+<@assertEquals expected='foo' actual='foo'?ensure_starts_with('f') />
+<@assertEquals expected='foo' actual='foo'?ensure_starts_with('foo') />
+<@assertEquals expected='fooofoo' actual='foo'?ensure_starts_with('fooo') />
+<@assertEquals expected='foo' actual='foo'?ensure_starts_with('') />
+<@assertEquals expected='x' actual=''?ensure_starts_with('x') />
+<@assertEquals expected='' actual=''?ensure_starts_with('') />
+<@assertEquals expected='bacdef' actual="bacdef"?ensure_starts_with("[ab]{2}", "ab") />
+<@assertEquals expected='bacdef' actual="bacdef"?ensure_starts_with("^[ab]{2}", "ab") />
+<@assertEquals expected='abcacdef' actual="cacdef"?ensure_starts_with("[ab]{2}", "ab") />
+<@assertEquals expected='abcacdef' actual="cacdef"?ensure_starts_with("^[ab]{2}", "ab") />
+<@assertEquals expected='ab!cdef' actual="cdef"?ensure_starts_with("ab", "ab!") />
+<@assertEquals expected='ab!ABcdef' actual="ABcdef"?ensure_starts_with("ab", "ab!") />
+<@assertEquals expected='ABcdef' actual="ABcdef"?ensure_starts_with("ab", "ab!", 'i') />
+<@assertEquals expected='abABcdef' actual="ABcdef"?ensure_starts_with(".b", "ab", 'i') />
+<@assertEquals expected='ABcdef' actual="ABcdef"?ensure_starts_with(".b", "ab", 'ri') />
+<@assertEquals expected='http://example.com' actual="example.com"?ensure_starts_with("[a-z]+://", "http://") />
+<@assertEquals expected='http://example.com' actual="http://example.com"?ensure_starts_with("[a-z]+://", "http://") />
+<@assertEquals expected='https://example.com' actual="https://example.com"?ensure_starts_with("[a-z]+://", "http://") />
+<@assertEquals expected='http://HTTP://example.com' actual="HTTP://example.com"?ensure_starts_with("[a-z]+://", "http://") />
+<@assertEquals expected='HTTP://example.com' actual="HTTP://example.com"?ensure_starts_with("[a-z]+://", "http://", "ir") />
+<@assertFails message='4'>
+ ${'x'?ensure_starts_with('x', 'x', 'x', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?ensure_starts_with()}
+</...@assertFails>
+
+<@assertEquals expected='foox' actual='foo'?ensure_ends_with('x') />
+<@assertEquals expected='foo' actual='foo'?ensure_ends_with('o') />
+<@assertEquals expected='foo' actual='foo'?ensure_ends_with('foo') />
+<@assertEquals expected='foofooo' actual='foo'?ensure_ends_with('fooo') />
+<@assertEquals expected='foo' actual='foo'?ensure_ends_with('') />
+<@assertEquals expected='x' actual=''?ensure_ends_with('x') />
+<@assertEquals expected='' actual=''?ensure_ends_with('') />
+<@assertFails message='2'>
+ ${'x'?ensure_ends_with('x', 'x')}
+</...@assertFails>
+<@assertFails message='none'>
+ ${'x'?ensure_ends_with()}
+</...@assertFails>
+
+<@assertEquals expected='a' actual=1?lower_abc />
+<@assertEquals expected='b' actual=2?lower_abc />
+<@assertEquals expected='z' actual=26?lower_abc />
+<@assertEquals expected='aa' actual=27?lower_abc />
+<@assertEquals expected='ab' actual=28?lower_abc />
+<@assertEquals expected='cv' actual=100?lower_abc />
+<@assertFails messageRegexp='0|at least 1']>
+ ${0?lower_abc}
+</...@assertFails>
+<@assertFails messageRegexp='0|at least 1'>
+ ${-1?lower_abc}
+</...@assertFails>
+<@assertFails messageRegexp='1.00001|integer'>
+ ${1.00001?lower_abc}
+</...@assertFails>
+
+<@assertEquals expected='A' actual=1?upper_abc />
+<@assertEquals expected='B' actual=2?upper_abc />
+<@assertEquals expected='Z' actual=26?upper_abc />
+<@assertEquals expected='AA' actual=27?upper_abc />
+<@assertEquals expected='AB' actual=28?upper_abc />
+<@assertEquals expected='CV' actual=100?upper_abc />
+<@assertFails messageRegexp='0|at least 1']>
+ ${0?upper_abc}
+</...@assertFails>
+<@assertFails messageRegexp='0|at least 1'>
+ ${-1?upper_abc}
+</...@assertFails>
+<@assertFails messageRegexp='1.00001|integer'>
+ ${1.00001?upper_abc}
+</...@assertFails>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringbimethods.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringbimethods.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringbimethods.ftl
new file mode 100644
index 0000000..1d31c44
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringbimethods.ftl
@@ -0,0 +1,36 @@
+<#--
+ 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.
+-->
+<#setting locale="en_US">
+<#assign x = 3>
+${x?string["0.00"]}
+${x?string("0.00")}
+${'01:02:03'?time.iso?string["iso ms nz"]}
+${'01:02:03'?time.iso?string("iso ms nz")}
+---
+${multi}
+<#assign a = true>
+<#assign b = false>
+${a?string} ${b?string}
+${a?string("yes", "no")} ${b?string("yes", "no")}
+<#setting boolean_format="igen,nem"/>
+${a?string} ${b?string}
+<#setting number_format="0.0">
+${a?string(0, 1)} ${b?string(0, 1)}
+<#setting boolean_format="true,false"/>
+${a?string(0, 1)?is_string?string} ${b?string(0, 1)?is_string?string}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringliteral.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringliteral.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringliteral.ftl
new file mode 100644
index 0000000..436c632
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/stringliteral.ftl
@@ -0,0 +1,69 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+ <title>FreeMarker: String literal test</title>
+ <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<#assign x = "Hello", y = "World">
+<#assign message = "${x}, ${y}!">
+
+${message}
+
+<p>
+[${""}] = []<br>
+[${"a"}] = [a]<br>
+[${"abcdef"}] = [abcdef]<br>
+[${"\""}] = ["]<br>
+[${"\"\"\""}] = ["""]<br>
+[${"a\""}] = [a"]<br>
+[${"\"a"}] = ["a]<br>
+[${"a\"b"}] = [a"b]<br>
+[${"a\nb"}] = [a
+b]<br>
+[${"'"}] = [']<br>
+[${"a'a"}] = [a'a]<br>
+[${"\"\'\n\r\f\b\t\l\a\g"}]<br>
+[${"\xA\x0A\x00A\x000A\x0000A"}]<br>
+[${"\x15Bz\x15b"}]<br>
+[${"\x010Cz\x010c"}]<br>
+
+<p>
+[${''}] = []<br>
+[${'a'}] = [a]<br>
+[${'abcdef'}] = [abcdef]<br>
+[${'"'}] = ["]<br>
+[${'"""'}] = ["""]<br>
+[${'a"'}] = [a"]<br>
+[${'"a'}] = ["a]<br>
+[${'a"b'}] = [a"b]<br>
+[${'a\nb'}] = [a
+b]<br>
+[${'\''}] = [']<br>
+[${'a\'a'}] = [a'a]<br>
+[${'\"\'\n\r\f\b\t\l\a\g'}]<br>
+[${'\xA\x0A\x00A\x000A\x0000A'}]<br>
+[${'\x15Bz\x15b'}]<br>
+[${'\x010Cz\x010c'}]<br>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir.ftl
new file mode 100644
index 0000000..cd24873
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir.ftl
@@ -0,0 +1,27 @@
+<#--
+ 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.
+-->
+<p>This is include-subdir.ftl</p>
+<p>Testing including from same directory</p>
+<#include "include-subdir2.ftl">
+<p>Testing including from relative parent</p>
+<#include "../included.ftl">
+<p>Testing including from loader root</p>
+<#include "/included.ftl">
+<p>Testing including through acquisition</p>
+<#include "*/subdir/include-subdir2.ftl">
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir2.ftl
new file mode 100644
index 0000000..356fcb2
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/include-subdir2.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+<p>This is include-subdir2.ftl</p>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin-2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin-2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin-2.ftl
new file mode 100644
index 0000000..687661b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin-2.ftl
@@ -0,0 +1,24 @@
+<#--
+ 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.
+-->
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("works")}
+<#attempt>
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel2"?new("works")}
+<#recover>
+fails
+</#attempt>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin.ftl
new file mode 100644
index 0000000..242d221
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/new-optin.ftl
@@ -0,0 +1,26 @@
+<#--
+ 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.
+-->
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("works")}
+<#attempt>
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel2"?new("works")}
+<#recover>
+fails
+</#attempt>
+
+<#include "new-optin-2.ftl">
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/subsub/new-optin.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/subsub/new-optin.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/subsub/new-optin.ftl
new file mode 100644
index 0000000..687661b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/subdir/subsub/new-optin.ftl
@@ -0,0 +1,24 @@
+<#--
+ 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.
+-->
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("works")}
+<#attempt>
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel2"?new("works")}
+<#recover>
+fails
+</#attempt>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch-builtin.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch-builtin.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch-builtin.ftl
new file mode 100644
index 0000000..7441733
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch-builtin.ftl
@@ -0,0 +1,54 @@
+<#--
+ 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.
+-->
+<@assertEquals expected="A" actual="a"?switch("a", "A") />
+<@assertFails message="didn't match">${"b"?switch("a", "A")}</@>
+<@assertEquals expected="D" actual="b"?switch("a", "A", "D") />
+<@assertEquals expected="B" actual="b"?switch("a", "A", "b", "B") />
+<@assertFails message="didn't match">${"c"?switch("a", "A", "b", "B")}</@>
+<@assertEquals expected="D" actual="c"?switch("a", "A", "b", "B", "D") />
+
+<#assign out = "">
+<#assign fInvocationCnt = 0>
+<#list 0..5 as x>
+ <#assign out += x?switch(1, f("one"), 2, f("two"), 3, f("three"), f("default")) + ";">
+</#list>
+<@assertEquals expected="default;one;two;three;default;default;" actual=out />
+<@assertEquals expected=6 actual=fInvocationCnt />
+
+<#assign out = "">
+<#list 0..5 as x>
+ <#assign out += true?switch(x <= 1, "low", x == 2 || x == 3, "medium", x >= 3, "high") + ";">
+</#list>
+<@assertEquals expected="low;low;medium;medium;high;high;" actual=out />
+
+<#function f x>
+ <#assign fInvocationCnt++>
+ <#return x>
+</#function>
+
+<@assertFails message="noSuchVar1">${1?switch(noSuchVar1, noSuchVar2)}</@>
+<@assertFails message="noSuchVar2">${1?switch(1, noSuchVar2)}</@>
+<@assertFails message="noSuchVar3">${noSuchVar3?switch(1, 1)}</@>
+
+<@assertEquals expected="one" actual=1?switch(1, "one", "2", "two") />
+<@assertFails messageRegexp="Can't compare.+number.+string">${2?switch(1, "one", "2", "two")}</@>
+<@assertFails messageRegexp="Can't compare.+number.+string">${2?switch(1, "one", "2", "two", "default")}</@>
+
+<#assign out><#escape x as x?switch(2 * x, "zero", 1, "one", x, x?string("0.0"))>${0} ${1} ${2}</#escape></#assign>
+<@assertEquals expected="zero one 2.0" actual=out />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch.ftl
new file mode 100644
index 0000000..6bbab3c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/switch.ftl
@@ -0,0 +1,139 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Switch-Case Test</title>
+</head>
+<body>
+
+<p>Here we iterate over a list of animals.</p>
+<#assign animalList = [ "aardvark", "kiwi", "gecko", "cat", "dog", "elephant",
+ "squirrel", "zebra" ]>
+<#assign favoriteAnimal = "kiwi">
+
+<#list animalList as animal>
+<p>Animal is: ${animal}.<br />
+<#switch animal>
+ <#case "zebra">
+ This is the HTML for a large stripey animal.
+ <#case "elephant">
+ <#case "rhinocerous">
+ This is the HTML for large animals.
+ <#break>
+ <#case "squirrel">
+ <#case "gecko">
+ This is the HTML for small animals.
+ <#break>
+ <#case favoriteAnimal>
+ This is the HTML for the user's favorite animal.
+ <#break>
+ <#default>
+ This is the HTML for other animals.
+ <#break>
+</#switch>
+</p>
+</#list>
+
+<#-- Nesting and no-match -->
+<#list [ 1, 2, 3 ] as x>
+ <#switch x>
+ <#case 1>
+ 1
+ <#switch x*2>
+ <#case 1>
+ i1
+ <#break>
+ <#case 2>
+ i2
+ <#break>
+ <#case 3>
+ i3
+ <#break>
+ <#case 4>
+ i4
+ <#break>
+ <#case 6>
+ i6
+ <#break>
+ </#switch>
+ <#break>
+ <#case 2>
+ 2
+ <#switch x*2>
+ <#case 1>
+ i1
+ <#break>
+ <#case 2>
+ i2
+ <#break>
+ <#case 3>
+ i3
+ <#break>
+ <#case 4>
+ i4
+ <#-- falls through -->
+ <#case 5>
+ ft
+ <#-- falls through -->
+ </#switch>
+ ft
+ <#-- falls through -->
+ <#case 3>
+ 3
+ <#switch x*2>
+ <#case 1>
+ i1
+ <#break>
+ <#case 2>
+ i2
+ <#break>
+ <#case 3>
+ i3
+ <#break>
+ <#case 4>
+ i4
+ <#break>
+ <#case 6>
+ i6
+ <#break>
+ </#switch>
+ <#break>
+ </#switch>
+</#list>
+
+<#-- No match -->
+[<#switch 213>
+ <#case 1>sadas
+</#switch>]
+
+<#-- Fall-through -->
+<#list [ 0, 1, 2, 3, 4 ] as x>
+ "<#switch x><#case 1>1<#case 2>2<#case 3>3<#case 4>4</#switch>"
+</#list>
+
+<#-- Legacy parser bug: #default might not be the last, but it doesn't fall through if called directly -->
+<#list [1, 2, 3, 4, 5] as x>
+ "<#switch x><#case 1>1<#case 2>2<#default>default<#case 4>4<#case 5>5</#switch>"
+</#list>
+
+<#-- two #default-s are parsing error -->
+<@assertFails message="can only have one default"><@"<#switch 1><#case 1><#default><#default></#switch>"?interpret /></@>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/then-builtin.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/then-builtin.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/then-builtin.ftl
new file mode 100644
index 0000000..de809e1
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/then-builtin.ftl
@@ -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.
+-->
+<#assign f1InvocationCnt = 0>
+<#assign f2InvocationCnt = 0>
+
+<@assertEquals expected="f1 1" actual=true?then(f1(), f2()) />
+<@assertEquals expected="f2 1" actual=false?then(f1(), f2()) />
+<@assertEquals expected="f1 2" actual=true?then(f1(), f2()) />
+<@assertEquals expected="f2 2" actual=false?then(f1(), f2()) />
+<@assertEquals expected=2 actual=f1InvocationCnt />
+<@assertEquals expected=2 actual=f2InvocationCnt />
+
+<#function f1>
+ <#assign f1InvocationCnt++>
+ <#return "f1 " + f1InvocationCnt>
+</#function>
+
+<#function f2>
+ <#assign f2InvocationCnt++>
+ <#return "f2 " + f2InvocationCnt>
+</#function>
+
+<#assign x = 1>
+<@assertEquals expected='Y' actual=(x < 2 * x)?then(-x < x, false)?then('Y', 'N') />
+
+<@assertEquals expected=1 actual=true?then(x, noSuchVar) />
+<@assertEquals expected=1 actual=false?then(noSuchVar, x) />
+
+<@assertFails message="noSuchVar1">${true?then(noSuchVar1, noSuchVar2)}</@>
+<@assertFails message="noSuchVar2">${false?then(noSuchVar1, noSuchVar2)}</@>
+<@assertFails message="noSuchVar3">${noSuchVar3?then(noSuchVar1, noSuchVar2)}</@>
+
+<#assign out><#escape x as x?then(1, 0)>${false} ${true}</#escape></#assign>
+<@assertEquals expected="0 1" actual=out />
+
+<#assign out><#escape x as (x < 0)?then(-x * 3, x * 2)>${-1} ${1}</#escape></#assign>
+<@assertEquals expected="3 2" actual=out />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/transforms.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/transforms.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/transforms.ftl
new file mode 100644
index 0000000..9e5613a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/transforms.ftl
@@ -0,0 +1,100 @@
+<#--
+ 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.
+-->
+<#assign htmlEscape = "org.apache.freemarker.core.util.HtmlEscape"?new(),
+ utility = "org.apache.freemarker.test.templatesuite.models.TransformHashWrapper"?new()>
+<html>
+<head>
+<title>FreeMarker: Transformation Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<@htmlEscape>
+<p>${message}</p>
+</...@htmlEscape>
+
+<P>Now try the Utility package:</p>
+<p>${utility}</p>
+
+<@utility.htmlEscape>
+<p>${utility}</p>
+</@>
+
+<p>Now some nested transforms:</p>
+<@utility.compress>
+<p >This tests the compress transformation</p >
+</@>
+<@utility.compress>
+<@utility.htmlEscape>
+<p >This tests the compress transformation</p >
+</@>
+</...@utility.compress>
+<#assign html_transform = "org.apache.freemarker.core.util.HtmlEscape"?new() />
+<@html_transform><#--Using the transform via an instantiation -->
+<@utility.compress>
+<p >This tests the compress transformation</p >
+</@>
+</@>
+
+<p>Now try method and transform interactions:</p>
+<@utility.escape("xml")>
+<p>This isn't a valid XML string.</p>
+</@>
+<@utility.escape("html")>
+<p>This isn't a valid HTML string.</p>
+</@>
+
+<p>A more advanced interaction involves getting a TemplateMethodModel
+to initialise a TemplateTransformModel, as follow:</p>
+
+<@utility.special("This is a comment")>
+Comment: *
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+</@>
+
+<@utility.special("This is a second comment", "quote")>
+Comment: *
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+</@>
+<@utility.special("This is a third comment", "ampersand", "quote")>
+Comment: *
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+</@>
+<@utility.special("tag", utility)>
+Comment: *
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+</@>
+
+</body>
+</html>
[07/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
deleted file mode 100644
index 0edae99..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestSuite.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
deleted file mode 100644
index 974b3f9..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/AllTemplateModels.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
deleted file mode 100644
index 7e7fa82..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestClass.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
deleted file mode 100644
index 6737b87..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestInterface.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
deleted file mode 100644
index b462e9a..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BeanTestSuperclass.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
deleted file mode 100644
index 4af030e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndScalarModel.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
deleted file mode 100644
index d87b65c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanAndStringTemplateModel.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
deleted file mode 100644
index 524d003..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash1.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
deleted file mode 100644
index 8bae7ab..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanHash2.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
deleted file mode 100644
index 3e0a69c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList1.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
deleted file mode 100644
index 939fb5f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanList2.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
deleted file mode 100644
index 3e13623..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/BooleanVsStringMethods.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
deleted file mode 100644
index 359e4a4..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/EnumTestClass.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
deleted file mode 100644
index ca0f9be..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/ExceptionModel.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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!" );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
deleted file mode 100644
index 70ea42a..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.TemplateCollectionModel;
-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.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-public class HashAndScalarModel implements TemplateHashModelEx, TemplateScalarModel {
-
- public static final HashAndScalarModel INSTANCE = new HashAndScalarModel();
-
- private final TemplateCollectionModel EMPTY_COLLECTION = new TemplateCollectionModel() {
-
- @Override
- public TemplateModelIterator iterator() throws TemplateModelException {
- return new TemplateModelIterator() {
-
- @Override
- public TemplateModel next() throws TemplateModelException {
- return null;
- }
-
- @Override
- public boolean hasNext() throws TemplateModelException {
- return false;
- }
-
- };
- }
- };
-
- @Override
- public String getAsString() throws TemplateModelException {
- return "scalarValue";
- }
-
- @Override
- public TemplateModel get(String key) throws TemplateModelException {
- return new SimpleScalar("mapValue for " + key);
- }
-
- @Override
- public boolean isEmpty() throws TemplateModelException {
- return true;
- }
-
- @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;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
deleted file mode 100644
index 4673b09..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.util._StringUtil;
-
-public class JavaObjectInfo {
-
- public static final Object INSTANCE = new JavaObjectInfo();
-
- private JavaObjectInfo() { }
-
- public String info(Object o) {
- if (o == null) return "null";
- return o.getClass().getName() + " " + _StringUtil.jQuote(o.toString());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
deleted file mode 100644
index c2d7c90..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateHashModelEx2;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.WrappingTemplateModel;
-import org.apache.freemarker.core.model.impl.DefaultMapAdapter;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleCollection;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class Listables {
-
- private static final List<Integer> LIST;
- static {
- List<Integer> list = new ArrayList<>();
- list.add(11);
- list.add(22);
- list.add(33);
- LIST = list;
- }
-
- private static final List<Integer> LINKED_LIST;
- static {
- List<Integer> list = new LinkedList<>();
- list.add(11);
- list.add(22);
- list.add(33);
- LINKED_LIST = list;
- }
-
- private static final List<Integer> EMPTY_LINKED_LIST = new LinkedList<>();
-
- private static final Set<Integer> SET;
- static {
- Set<Integer> set = new TreeSet<>();
- set.add(11);
- set.add(22);
- set.add(33);
- SET = set;
- }
-
- public List<Integer> getList() {
- return LIST;
- }
-
- public List<Integer> getLinkedList() {
- return LINKED_LIST;
- }
-
- public Set<Integer> getSet() {
- return SET;
- }
-
- public Iterator<Integer> getIterator() {
- return SET.iterator();
- }
-
- public List<Integer> getEmptyList() {
- return Collections.emptyList();
- }
-
- public List<Integer> getEmptyLinkedList() {
- return Collections.emptyList();
- }
-
- public Set<Integer> getEmptySet() {
- return Collections.emptySet();
- }
-
- public Iterator<Integer> getEmptyIterator() {
- return Collections.<Integer>emptySet().iterator();
- }
-
- public List<TemplateHashModelEx2> getHashEx2s() throws TemplateModelException {
- Map<Object, Object> map;
- map = new LinkedHashMap<>();
- map.put("k1", "v1");
- map.put(2, "v2");
- map.put("k3", "v3");
- map.put(null, "v4");
- map.put(true, "v5");
- map.put(false, null);
-
- return getMapsWrappedAsEx2(map);
- }
-
- public List<? extends TemplateHashModelEx> getEmptyHashes() throws TemplateModelException {
- List<TemplateHashModelEx> emptyMaps = new ArrayList<>();
- emptyMaps.addAll(getMapsWrappedAsEx2(Collections.emptyMap()));
- emptyMaps.add((TemplateHashModelEx) new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build()
- .wrap(Collections.emptyMap()));
- return emptyMaps;
- }
-
- /**
- * Returns the map wrapped on various ways.
- */
- private List<TemplateHashModelEx2> getMapsWrappedAsEx2(Map<?, ?> map) throws TemplateModelException {
- List<TemplateHashModelEx2> maps = new ArrayList<>();
-
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- maps.add(new SimpleHash(map, ow));
- maps.add((DefaultMapAdapter) ow.wrap(map));
-
- return maps;
- }
-
- public TemplateHashModelEx getHashNonEx2() {
- return new NonEx2MapAdapter(ImmutableMap.of("k1", 11, "k2", 22),
- new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- }
-
- public static class NonEx2MapAdapter extends WrappingTemplateModel implements TemplateHashModelEx {
-
- private final Map<?, ?> map;
-
- public NonEx2MapAdapter(Map<?, ?> map, ObjectWrapper wrapper) {
- super(wrapper);
- this.map = map;
- }
-
- @Override
- public TemplateModel get(String key) throws TemplateModelException {
- return wrap(map.get(key));
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public TemplateCollectionModel keys() {
- return new SimpleCollection(map.keySet(), getObjectWrapper());
- }
-
- @Override
- public TemplateCollectionModel values() {
- return new SimpleCollection(map.values(), getObjectWrapper());
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
deleted file mode 100644
index 66a0ffe..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.Configuration;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.model.impl.SimpleSequence;
-
-/**
- * Testcase to see how FreeMarker deals with multiple Template models.
- */
-public class MultiModel1 implements TemplateHashModel,
- TemplateSequenceModel, TemplateScalarModel {
-
- private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- private TemplateModel m_cSubModel = new MultiModel2();
- private TemplateModel m_cListHashModel1 = new MultiModel4(ow);
- private TemplateModel m_cListHashModel2 = new MultiModel5(ow);
- private TemplateSequenceModel m_cListModel = new SimpleSequence(ow);
- private TemplateHashModel m_cHashModel = new SimpleHash(ow);
-
- /** Creates new MultiModel1 */
- public MultiModel1() {
- for ( int i = 0; i < 10; i++ ) {
- ((SimpleSequence) m_cListModel).add( "Model1 value: " + Integer.toString( i ));
- }
- ((SimpleSequence) m_cListModel).add( new MultiModel3() );
- ((SimpleHash) m_cHashModel).put( "nested", new MultiModel3() );
- }
-
- /**
- * 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( "model2" )) {
- return m_cSubModel;
- } else if ( key.equals( "modellist" )) {
- return m_cListModel;
- } else if ( key.equals( "selftest" )) {
- return new SimpleScalar( "Selftest of a hash from MultiModel1" );
- } else if ( key.equals( "one" )) {
- return m_cListHashModel1;
- } else if ( key.equals( "two" )) {
- return m_cListHashModel2;
- } else if ( key.equals( "size" )) {
- return new SimpleScalar( "Nasty!" );
- } else if ( key.equals( "nesting1" )) {
- return m_cHashModel;
- } else {
- return null;
- }
- }
-
- /**
- * @return true if this object is empty.
- */
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- /**
- * @return the specified index in the list
- */
- @Override
- public TemplateModel get(int i) throws TemplateModelException {
- return m_cListModel.get( i );
- }
-
- /**
- * Returns the scalar's value as a String.
- *
- * @return the String value of this scalar.
- */
- @Override
- public String getAsString() {
- return "MultiModel1 as a string!";
- }
-
- @Override
- public int size() throws TemplateModelException {
- return m_cListModel.size();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java
deleted file mode 100644
index a7a75b5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * Testcase to see how FreeMarker deals with multiple Template models.
- */
-public class MultiModel2 implements TemplateScalarModel, TemplateMethodModel {
-
- /**
- * Returns the scalar's value as a String.
- *
- * @return the String value of this scalar.
- */
- @Override
- public String getAsString() {
- return "Model2 is alive!";
- }
-
- /**
- * Executes a method call.
- *
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing the values
- * of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
- @Override
- public Object exec(List arguments) {
- StringBuilder aResults = new StringBuilder( "Arguments are:<br />" );
- Iterator iList = arguments.iterator();
-
- while ( iList.hasNext() ) {
- aResults.append( (String) iList.next() );
- aResults.append( "<br />" );
- }
-
- return new SimpleScalar( aResults.toString() );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
deleted file mode 100644
index 4434afc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * Testcase to see how FreeMarker deals with multiple Template models.
- */
-public class MultiModel3 implements TemplateScalarModel, TemplateHashModel {
-
- /**
- * Returns the scalar's value as a String.
- *
- * @return the String value of this scalar.
- */
- @Override
- public String getAsString() {
- return "Model3 is alive!";
- }
-
- /**
- * @return true if this object is empty.
- */
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- /**
- * 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( "selftest" )) {
- return new SimpleScalar( "Selftest from MultiModel3!" );
- } else if ( key.equals( "message" )) {
- return new SimpleScalar( "Hello world from MultiModel3!" );
- } else {
- return null;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
deleted file mode 100644
index bdd11fc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.TemplateHashModel;
-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.SimpleScalar;
-import org.apache.freemarker.core.model.impl.SimpleSequence;
-
-/**
- * Testcase to see how FreeMarker deals with multiple Template models.
- */
-public class MultiModel4 implements TemplateSequenceModel, TemplateHashModel {
-
- private final SimpleSequence m_cList;
-
- public MultiModel4(ObjectWrapper ow) {
- this.m_cList = new SimpleSequence(ow);
- }
-
- /**
- * @return the specified index in the list
- */
- @Override
- public TemplateModel get(int i) throws TemplateModelException {
- return m_cList.get( i );
- }
-
- /**
- * 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( "size" )) {
- return new SimpleScalar( "Key size, not the listSize method." );
- } else {
- return null;
- }
- }
-
-
- @Override
- public int size() {
- return m_cList.size();
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
deleted file mode 100644
index 01f7a3e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.TemplateHashModel;
-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.SimpleScalar;
-import org.apache.freemarker.core.model.impl.SimpleSequence;
-
-/**
- * Testcase to see how FreeMarker deals with multiple Template models.
- */
-public class MultiModel5 implements TemplateSequenceModel, TemplateHashModel {
-
- private final SimpleSequence m_cList;
-
- /** Creates new MultiModel5 */
- public MultiModel5(ObjectWrapper ow) {
- this.m_cList = new SimpleSequence(ow);
- m_cList.add( new SimpleScalar( "Dummy to make list non-empty" ));
- }
-
- /**
- * @return the specified index in the list
- */
- @Override
- public TemplateModel get(int i) throws TemplateModelException {
- return m_cList.get( i );
- }
-
- /**
- * @return true if this object is empty.
- */
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public int size() {
- return m_cList.size();
- }
-
- /**
- * 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( "empty" )) {
- return new SimpleScalar( "Dummy hash value, for test purposes." );
- } else {
- return null;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
deleted file mode 100644
index 9f51458..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.TemplateScalarModel;
-
-/**
- * Testcase to see how FreeMarker's ?new built-in deals with constructors.
- */
-public class NewTestModel
-implements
- TemplateScalarModel {
- private final String string;
-
- public NewTestModel() {
- string = "default constructor";
- }
-
- public NewTestModel(String str) {
- string = str;
- }
-
- public NewTestModel(long i) {
- string = Long.toString(i);
- }
-
- public NewTestModel(Object o1, java.io.Serializable o2) {
- string = o1 + ":" + o2;
- }
-
- @Override
- public String getAsString() {
- return string;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
deleted file mode 100644
index 420b4fa..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.TemplateScalarModel;
-
-/**
- * Testcase to see how FreeMarker's ?new built-in deals with constructors.
- */
-public class NewTestModel2
-implements
- TemplateScalarModel {
- private final String string;
-
- public NewTestModel2() {
- string = "default constructor";
- }
-
- public NewTestModel2(String str) {
- string = str;
- }
-
- public NewTestModel2(long i) {
- string = Long.toString(i);
- }
-
- public NewTestModel2(Object o1, java.io.Serializable o2) {
- string = o1 + ":" + o2;
- }
-
- @Override
- public String getAsString() {
- return string;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
deleted file mode 100644
index 5c8e7db..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-
-public class NumberAndStringModel implements TemplateNumberModel,
- TemplateScalarModel {
-
- private final String s;
-
- public NumberAndStringModel(String s) {
- super();
- this.s = s;
- }
-
- @Override
- public String getAsString() throws TemplateModelException {
- return s;
- }
-
- @Override
- @SuppressWarnings("boxing")
- public Number getAsNumber() throws TemplateModelException {
- return s.length();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
deleted file mode 100644
index 6e09053..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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;
-
-public class OverloadedConstructor implements TemplateScalarModel {
-
- String value;
-
- public OverloadedConstructor(int i) {
- value = "int " + i;
- }
-
- public OverloadedConstructor(String s) {
- value = "String " + s;
- }
-
- public OverloadedConstructor(CharSequence s) {
- value = "CharSequence " + s;
- }
-
- @Override
- public String getAsString() throws TemplateModelException {
- return value;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java
deleted file mode 100644
index ebd505a..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.freemarker.core.util.FTLUtil;
-
-/**
- * For testing overloaded method selection.
- */
-public class OverloadedMethods {
-
- public String oneArg(Object a1) {
- return methodCallToStr("oneArg<Object>", a1);
- }
-
- public String oneArg(String a1) {
- return methodCallToStr("oneArg<String>", a1);
- }
-
- public String oneArg(Boolean a1) {
- return methodCallToStr("oneArg<Boolean>", a1);
- }
-
- public String oneArg(boolean a1) {
- return methodCallToStr("oneArg<boolean>", Boolean.valueOf(a1));
- }
-
- public String oneArg(List a1) {
- return methodCallToStr("oneArg<List>", a1);
- }
-
- public String oneArg(Map a1) {
- return methodCallToStr("oneArg<Map>", a1);
- }
-
- public String oneArg2(Map a1) {
- return methodCallToStr("oneArg2<Map>", a1);
- }
-
- public String oneArg2(List a1) {
- return methodCallToStr("oneArg2<List>", a1);
- }
-
- public String oneArg3(List a1, List a2) {
- return methodCallToStr("oneArg3<List, List>", a1, a2);
- }
-
- public String oneArg3(List a1) {
- return methodCallToStr("oneArg3<List>", a1);
- }
-
- public String oneArg4(Integer a1) {
- return methodCallToStr("oneArg4<Integer>", a1);
- }
-
- public String oneArg4(int a1) {
- return methodCallToStr("oneArg4<int>", Integer.valueOf(a1));
- }
-
- public String notOverloaded(List a1) {
- return methodCallToStr("notOverloaded<List>", a1);
- }
-
- public String varargsIssue1(Map a1, List a2) {
- return methodCallToStr("varargsIssue1<Map, List>", a1, a2);
- }
-
- public String varargsIssue1(Object... a1) {
- return methodCallToStr("varargsIssue1<Object...>", a1);
- }
-
- public String varargsIssue2(String a1, List a2) {
- return methodCallToStr("varargsIssue2<String, List>", a1, a2);
- }
-
- public String varargsIssue2(String a1, Map a2) {
- return methodCallToStr("varargsIssue2<String, Map>", a1, a2);
- }
-
- public String varargsIssue2(Object... a1) {
- return methodCallToStr("varargsIssue2<Object...>", a1);
- }
-
- public String numberIssue1(int a1) {
- return methodCallToStr("numberIssue1<int>", a1);
- }
-
- public String numberIssue1(float a1) {
- return methodCallToStr("numberIssue1<float>", a1);
- }
-
- public String numberIssue2(int a1) {
- return methodCallToStr("numberIssue2<int>", a1);
- }
-
- public String numberIssue2(BigDecimal a1) {
- return methodCallToStr("numberIssue2<BigDecimal>", a1);
- }
-
- public String numberIssue3(int a1) {
- return methodCallToStr("numberIssue3<int>", a1);
- }
-
- public String numberIssue3(double a1) {
- return methodCallToStr("numberIssue3<double>", a1);
- }
-
- private String methodCallToStr(String methodName, Object... args) {
- StringBuilder sb = new StringBuilder();
-
- sb.append(methodName);
- sb.append('(');
- boolean hadItems = false;
- for (Object arg : args) {
- if (hadItems) sb.append(", ");
- sb.append(valueToStr(arg));
- hadItems = true;
- }
- sb.append(')');
-
- return sb.toString();
- }
-
- private String valueToStr(Object value) {
- if (value == null) {
- return "null";
- } else if (value instanceof Character) {
- return "'" + FTLUtil.escapeStringLiteralPart(value.toString()) + "'";
- } else if (value instanceof String) {
- return "\"" + FTLUtil.escapeStringLiteralPart((String) value) + "\"";
- } else if (value instanceof Map) {
- StringBuilder sb = new StringBuilder();
- sb.append("{");
- boolean hadItems = false;
- for (Map.Entry<?, ?> ent : ((Map<?, ?>) value).entrySet()) {
- if (hadItems) sb.append(", ");
- sb.append(valueToStr(ent.getKey()));
- sb.append(": ");
- sb.append(valueToStr(ent.getValue()));
- hadItems = true;
- }
- sb.append("}");
- return sb.toString();
- } else if (value instanceof Collection || value.getClass().isArray()) {
- StringBuilder sb = new StringBuilder();
-
- if (value.getClass().isArray()) {
- value = Arrays.asList(value);
- sb.append("array");
- } else if (value instanceof Set) {
- sb.append("set");
- }
- sb.append("[");
- boolean hadItems = false;
- for (Object i : (Collection) value) {
- if (hadItems) sb.append(", ");
- sb.append(i);
- hadItems = true;
- }
- sb.append("]");
- return sb.toString();
- } else {
- return value.toString();
- }
- }
-
-}
[13/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
deleted file mode 100644
index 37e4726..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings("boxing")
-public class OverloadedNumberUtilTest extends TestCase {
-
- public OverloadedNumberUtilTest(String name) {
- super(name);
- }
-
- public void testIntegerCoercions() {
- cipEqu(Byte.valueOf(Byte.MAX_VALUE));
- cipEqu(Byte.valueOf((byte) 0));
- cipEqu(Byte.valueOf(Byte.MIN_VALUE));
-
- cipEqu(Short.valueOf(Byte.MAX_VALUE),
- new OverloadedNumberUtil.ShortOrByte((short) Byte.MAX_VALUE, Byte.MAX_VALUE));
- cipEqu(Short.valueOf((short) 0),
- new OverloadedNumberUtil.ShortOrByte((short) 0, (byte) 0));
- cipEqu(Short.valueOf(Byte.MIN_VALUE),
- new OverloadedNumberUtil.ShortOrByte((short) Byte.MIN_VALUE, Byte.MIN_VALUE));
-
- cipEqu(Short.valueOf((short) (Byte.MAX_VALUE + 1)));
- cipEqu(Short.valueOf((short) (Byte.MIN_VALUE - 1)));
- cipEqu(Short.valueOf(Short.MAX_VALUE));
- cipEqu(Short.valueOf(Short.MIN_VALUE));
-
- cipEqu(Integer.valueOf(Byte.MAX_VALUE),
- new OverloadedNumberUtil.IntegerOrByte((int) Byte.MAX_VALUE, Byte.MAX_VALUE));
- cipEqu(Integer.valueOf(0),
- new OverloadedNumberUtil.IntegerOrByte(0, (byte) 0));
- cipEqu(Integer.valueOf(Byte.MIN_VALUE),
- new OverloadedNumberUtil.IntegerOrByte((int) Byte.MIN_VALUE, Byte.MIN_VALUE));
-
- cipEqu(Integer.valueOf(Byte.MAX_VALUE + 1),
- new OverloadedNumberUtil.IntegerOrShort(Byte.MAX_VALUE + 1, (short) (Byte.MAX_VALUE + 1)));
- cipEqu(Integer.valueOf(Byte.MIN_VALUE - 1),
- new OverloadedNumberUtil.IntegerOrShort(Byte.MIN_VALUE - 1, (short) (Byte.MIN_VALUE - 1)));
- cipEqu(Integer.valueOf(Short.MAX_VALUE),
- new OverloadedNumberUtil.IntegerOrShort((int) Short.MAX_VALUE, Short.MAX_VALUE));
- cipEqu(Integer.valueOf(Short.MIN_VALUE),
- new OverloadedNumberUtil.IntegerOrShort((int) Short.MIN_VALUE, Short.MIN_VALUE));
-
- cipEqu(Integer.valueOf(Short.MAX_VALUE + 1));
- cipEqu(Integer.valueOf(Short.MIN_VALUE - 1));
- cipEqu(Integer.valueOf(Integer.MAX_VALUE));
- cipEqu(Integer.valueOf(Integer.MIN_VALUE));
-
- cipEqu(Long.valueOf(Byte.MAX_VALUE),
- new OverloadedNumberUtil.LongOrByte((long) Byte.MAX_VALUE, Byte.MAX_VALUE));
- cipEqu(Long.valueOf(0),
- new OverloadedNumberUtil.LongOrByte((long) 0, (byte) 0));
- cipEqu(Long.valueOf(Byte.MIN_VALUE),
- new OverloadedNumberUtil.LongOrByte((long) Byte.MIN_VALUE, Byte.MIN_VALUE));
-
- cipEqu(Long.valueOf(Byte.MAX_VALUE + 1),
- new OverloadedNumberUtil.LongOrShort((long) (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
- cipEqu(Long.valueOf(Byte.MIN_VALUE - 1),
- new OverloadedNumberUtil.LongOrShort((long) (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
- cipEqu(Long.valueOf(Short.MAX_VALUE),
- new OverloadedNumberUtil.LongOrShort((long) Short.MAX_VALUE, Short.MAX_VALUE));
- cipEqu(Long.valueOf(Short.MIN_VALUE),
- new OverloadedNumberUtil.LongOrShort((long) Short.MIN_VALUE, Short.MIN_VALUE));
-
- cipEqu(Long.valueOf(Short.MAX_VALUE + 1),
- new OverloadedNumberUtil.LongOrInteger((long) Short.MAX_VALUE + 1, Short.MAX_VALUE + 1));
- cipEqu(Long.valueOf(Short.MIN_VALUE - 1),
- new OverloadedNumberUtil.LongOrInteger((long) Short.MIN_VALUE - 1, Short.MIN_VALUE - 1));
- cipEqu(Long.valueOf(Integer.MAX_VALUE),
- new OverloadedNumberUtil.LongOrInteger((long) Integer.MAX_VALUE, Integer.MAX_VALUE));
- cipEqu(Long.valueOf(Integer.MIN_VALUE),
- new OverloadedNumberUtil.LongOrInteger((long) Integer.MIN_VALUE, Integer.MIN_VALUE));
-
- cipEqu(Long.valueOf(Integer.MAX_VALUE + 1L));
- cipEqu(Long.valueOf(Integer.MIN_VALUE - 1L));
- cipEqu(Long.valueOf(Long.MAX_VALUE));
- cipEqu(Long.valueOf(Long.MIN_VALUE));
- }
-
- public void testIntegerNoCoercions() {
- cipEqu(Integer.valueOf(Byte.MAX_VALUE), Integer.valueOf(Byte.MAX_VALUE), 0);
- cipEqu(Integer.valueOf(0), Integer.valueOf(0), 0);
- cipEqu(Integer.valueOf(Byte.MIN_VALUE), Integer.valueOf(Byte.MIN_VALUE), 0);
- }
-
- public void testIntegerLimitedCoercions() {
- cipEqu(Integer.valueOf(Byte.MAX_VALUE), Integer.valueOf(Byte.MAX_VALUE), TypeFlags.INTEGER);
- cipEqu(Integer.valueOf(0), Integer.valueOf(0), TypeFlags.INTEGER);
- cipEqu(Integer.valueOf(Byte.MIN_VALUE), Integer.valueOf(Byte.MIN_VALUE), TypeFlags.INTEGER);
-
- cipEqu(Long.valueOf(Integer.MAX_VALUE + 1L), Long.valueOf(Integer.MAX_VALUE + 1L), TypeFlags.INTEGER);
-
- for (int n = -1; n < 2; n++) {
- final Long longN = Long.valueOf(n);
- cipEqu(longN, new OverloadedNumberUtil.LongOrInteger(longN, n), TypeFlags.INTEGER);
- cipEqu(longN, new OverloadedNumberUtil.LongOrShort(longN, (short) n), TypeFlags.SHORT);
- cipEqu(longN, new OverloadedNumberUtil.LongOrByte(longN, (byte) n), TypeFlags.BYTE);
- cipEqu(longN, new OverloadedNumberUtil.LongOrShort(longN, (short) n),
- TypeFlags.SHORT | TypeFlags.INTEGER);
- }
- }
-
- public void testBigDecimalCoercions() {
- cipEqu(new BigDecimal(123), new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal(123)));
- cipEqu(new BigDecimal(123), new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal(123)),
- TypeFlags.DOUBLE | TypeFlags.INTEGER);
- cipEqu(new BigDecimal(123), TypeFlags.INTEGER);
- cipEqu(new BigDecimal(123), TypeFlags.INTEGER | TypeFlags.LONG);
- cipEqu(new BigDecimal(123), TypeFlags.DOUBLE);
- cipEqu(new BigDecimal(123), TypeFlags.DOUBLE | TypeFlags.FLOAT);
-
- cipEqu(new BigDecimal(123.5));
- // Not wasting time with check if it's a whole number if we only have integer-only or non-integer-only targets:
- cipEqu(new BigDecimal(123.5), TypeFlags.INTEGER | TypeFlags.LONG);
- cipEqu(new BigDecimal(123.5), TypeFlags.DOUBLE | TypeFlags.FLOAT);
-
- cipEqu(new BigDecimal("0.01"));
- cipEqu(new BigDecimal("-0.01"));
- cipEqu(BigDecimal.ZERO, new OverloadedNumberUtil.IntegerBigDecimal(BigDecimal.ZERO));
- }
-
- public void testUnknownNumberCoercion() {
- cipEqu(new RationalNumber(2, 3));
- }
-
- @SuppressWarnings("boxing")
- public void testDoubleCoercion() {
- cipEqu(Double.valueOf(1.5), new OverloadedNumberUtil.DoubleOrFloat(1.5));
- cipEqu(Double.valueOf(-0.125), new OverloadedNumberUtil.DoubleOrFloat(-0.125));
- cipEqu(Double.valueOf(Float.MAX_VALUE), new OverloadedNumberUtil.DoubleOrFloat((double) Float.MAX_VALUE));
- cipEqu(Double.valueOf(-Float.MAX_VALUE), new OverloadedNumberUtil.DoubleOrFloat((double) -Float.MAX_VALUE));
- cipEqu(Double.valueOf(Float.MAX_VALUE * 10.0));
- cipEqu(Double.valueOf(-Float.MAX_VALUE * 10.0));
-
- cipEqu(Double.valueOf(0), new OverloadedNumberUtil.DoubleOrByte(0.0, (byte) 0));
- cipEqu(Double.valueOf(Byte.MAX_VALUE), new OverloadedNumberUtil.DoubleOrByte((double) Byte.MAX_VALUE, Byte.MAX_VALUE));
- cipEqu(Double.valueOf(Byte.MIN_VALUE), new OverloadedNumberUtil.DoubleOrByte((double) Byte.MIN_VALUE, Byte.MIN_VALUE));
-
- cipEqu(Double.valueOf(Byte.MAX_VALUE + 1), new OverloadedNumberUtil.DoubleOrShort((double)
- (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
- cipEqu(Double.valueOf(Byte.MIN_VALUE - 1), new OverloadedNumberUtil.DoubleOrShort((double)
- (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
-
- cipEqu(Double.valueOf(Short.MAX_VALUE + 1),
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat((double) Short.MAX_VALUE + 1, Short.MAX_VALUE + 1));
- cipEqu(Double.valueOf(Short.MIN_VALUE - 1),
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat((double) Short.MIN_VALUE - 1, Short.MIN_VALUE - 1));
- cipEqu(Double.valueOf(16777216), new OverloadedNumberUtil.DoubleOrIntegerOrFloat(16777216.0, 16777216));
- cipEqu(Double.valueOf(-16777216), new OverloadedNumberUtil.DoubleOrIntegerOrFloat(-16777216.0, -16777216));
-
- cipEqu(Double.valueOf(Integer.MAX_VALUE),
- new OverloadedNumberUtil.DoubleOrInteger((double) Integer.MAX_VALUE, Integer.MAX_VALUE));
- cipEqu(Double.valueOf(Integer.MIN_VALUE),
- new OverloadedNumberUtil.DoubleOrInteger((double) Integer.MIN_VALUE, Integer.MIN_VALUE));
-
- cipEqu(Double.valueOf(Integer.MAX_VALUE + 1L),
- new OverloadedNumberUtil.DoubleOrLong(Double.valueOf(Integer.MAX_VALUE + 1L), Integer.MAX_VALUE + 1L));
- cipEqu(Double.valueOf(Integer.MIN_VALUE - 1L),
- new OverloadedNumberUtil.DoubleOrLong(Double.valueOf(Integer.MIN_VALUE - 1L), Integer.MIN_VALUE - 1L));
- cipEqu(Double.valueOf(Long.MAX_VALUE),
- new OverloadedNumberUtil.DoubleOrFloat((double) Long.MAX_VALUE));
- cipEqu(Double.valueOf(Long.MIN_VALUE),
- new OverloadedNumberUtil.DoubleOrFloat((double) Long.MIN_VALUE));
-
- // When only certain target types are present:
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrByte(5.0, (byte) 5), TypeFlags.BYTE);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrByte(5.0, (byte) 5), TypeFlags.BYTE | TypeFlags.SHORT);
- cipEqu(Double.valueOf(-129), TypeFlags.BYTE);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrShort(5.0, (short) 5), TypeFlags.SHORT);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrInteger(5.0, 5), TypeFlags.INTEGER);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrLong(5.0, 5), TypeFlags.LONG);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrFloat(5.0), TypeFlags.FLOAT);
- cipEqu(Double.valueOf(5), Double.valueOf(5), TypeFlags.DOUBLE);
- cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrFloat(5.0),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(Double.valueOf(5.9), new OverloadedNumberUtil.DoubleOrFloat(5.9),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(Double.valueOf(5.9),
- TypeFlags.DOUBLE | TypeFlags.INTEGER);
- cipEqu(Double.valueOf(5.9), new OverloadedNumberUtil.DoubleOrFloat(5.9),
- TypeFlags.FLOAT | TypeFlags.INTEGER);
- cipEqu(Double.valueOf(5.9), TypeFlags.INTEGER);
- cipEqu(Double.valueOf(Long.MAX_VALUE),
- new OverloadedNumberUtil.DoubleOrFloat((double) Long.MAX_VALUE),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(Double.valueOf(Long.MAX_VALUE),
- TypeFlags.DOUBLE | TypeFlags.LONG);
- cipEqu(Double.valueOf(Long.MIN_VALUE),
- new OverloadedNumberUtil.DoubleOrFloat((double) Long.MIN_VALUE),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(Double.valueOf(Float.MAX_VALUE * 10),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(Double.valueOf(-Float.MAX_VALUE * 10),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
-
- // Rounded values:
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrByte(0.0000009, (byte) 0));
- cipEqu(Double.valueOf(-0.0000009),
- new OverloadedNumberUtil.DoubleOrByte(-0.0000009, (byte) 0));
- cipEqu(Double.valueOf(0.9999991),
- new OverloadedNumberUtil.DoubleOrByte(0.9999991, (byte) 1));
- cipEqu(Double.valueOf(-0.9999991),
- new OverloadedNumberUtil.DoubleOrByte(-0.9999991, (byte) -1));
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrShort(0.0000009, (short) 0),
- TypeFlags.SHORT | TypeFlags.DOUBLE);
- cipEqu(Double.valueOf(0.0000009), new OverloadedNumberUtil.DoubleOrInteger(0.0000009, 0),
- TypeFlags.INTEGER | TypeFlags.DOUBLE);
- cipEqu(Double.valueOf(0.0000009), new OverloadedNumberUtil.DoubleOrLong(0.0000009, 0),
- TypeFlags.LONG | TypeFlags.DOUBLE);
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrByte(0.0000009, (byte) 0), TypeFlags.BYTE);
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrShort(0.0000009, (short) 0), TypeFlags.SHORT);
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrInteger(0.0000009, 0), TypeFlags.INTEGER);
- cipEqu(Double.valueOf(0.0000009),
- new OverloadedNumberUtil.DoubleOrLong(0.0000009, 0L), TypeFlags.LONG);
- cipEqu(Double.valueOf(0.9999999),
- new OverloadedNumberUtil.DoubleOrInteger(0.9999999, 1), TypeFlags.INTEGER);
- cipEqu(Double.valueOf(Byte.MAX_VALUE + 0.9e-6),
- new OverloadedNumberUtil.DoubleOrByte(Byte.MAX_VALUE + 0.9e-6, Byte.MAX_VALUE));
- cipEqu(Double.valueOf(Byte.MIN_VALUE - 0.9e-6),
- new OverloadedNumberUtil.DoubleOrByte(Byte.MIN_VALUE - 0.9e-6, Byte.MIN_VALUE));
- cipEqu(Double.valueOf(Byte.MAX_VALUE + 1.1e-6),
- new OverloadedNumberUtil.DoubleOrFloat(Byte.MAX_VALUE + 1.1e-6));
- cipEqu(Double.valueOf(Byte.MIN_VALUE - 1.1e-6),
- new OverloadedNumberUtil.DoubleOrFloat(Byte.MIN_VALUE - 1.1e-6));
- cipEqu(Double.valueOf(Byte.MAX_VALUE + 0.9999991),
- new OverloadedNumberUtil.DoubleOrShort(
- Byte.MAX_VALUE + 0.9999991, (short) (Byte.MAX_VALUE + 1)));
- cipEqu(Double.valueOf(Byte.MIN_VALUE - 0.9999991),
- new OverloadedNumberUtil.DoubleOrShort(
- Byte.MIN_VALUE - 0.9999991, (short) (Byte.MIN_VALUE - 1)));
-
- cipEqu(Double.valueOf(Byte.MAX_VALUE + 1), new OverloadedNumberUtil.DoubleOrShort((double)
- (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
- cipEqu(Double.valueOf(Byte.MIN_VALUE - 1), new OverloadedNumberUtil.DoubleOrShort((double)
- (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
-
- cipEqu(Short.MAX_VALUE + 0.9999991,
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat(Short.MAX_VALUE + 0.9999991, Short.MAX_VALUE + 1));
- cipEqu(Short.MIN_VALUE - 0.9999991,
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat(Short.MIN_VALUE - 0.9999991, Short.MIN_VALUE - 1));
- cipEqu(16777216 + 0.9e-6,
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat(16777216 + 0.9e-6, 16777216));
- cipEqu(-16777216 - 0.9e-6,
- new OverloadedNumberUtil.DoubleOrIntegerOrFloat(-16777216 - 0.9e-6, -16777216));
-
- cipEqu(Integer.MAX_VALUE + 0.9e-6,
- new OverloadedNumberUtil.DoubleOrInteger(Integer.MAX_VALUE + 0.9e-6, Integer.MAX_VALUE));
- cipEqu(Integer.MIN_VALUE - 0.9e-6,
- new OverloadedNumberUtil.DoubleOrInteger(Integer.MIN_VALUE - 0.9e-6, Integer.MIN_VALUE));
-
- cipEqu(Integer.MAX_VALUE + 1L + 0.9e-6,
- new OverloadedNumberUtil.DoubleOrFloat(Integer.MAX_VALUE + 1L + 0.9e-6));
- cipEqu(Integer.MIN_VALUE - 1L - 0.9e-6,
- new OverloadedNumberUtil.DoubleOrFloat(Integer.MIN_VALUE - 1L - 0.9e-6));
- cipEqu(Long.MAX_VALUE + 0.9e-6,
- new OverloadedNumberUtil.DoubleOrFloat(Long.MAX_VALUE + 0.9e-6));
- cipEqu(Long.MIN_VALUE - 0.9e-6,
- new OverloadedNumberUtil.DoubleOrFloat(Long.MIN_VALUE - 0.9e-6));
- }
-
- @SuppressWarnings("boxing")
- public void testFloatCoercion() {
- cipEqu(1.00002f);
- cipEqu(-1.00002f);
- cipEqu(1.999989f);
- cipEqu(-1.999989f);
- cipEqu(16777218f);
- cipEqu(-16777218f);
-
- cipEqu(1f, new OverloadedNumberUtil.FloatOrByte(1f, (byte) 1));
- cipEqu(-1f, new OverloadedNumberUtil.FloatOrByte(-1f, (byte) -1));
- cipEqu(1.000009f, new OverloadedNumberUtil.FloatOrByte(1.000009f, (byte) 1));
- cipEqu(-1.000009f, new OverloadedNumberUtil.FloatOrByte(-1.000009f, (byte) -1));
- cipEqu(1.999991f, new OverloadedNumberUtil.FloatOrByte(1.999991f, (byte) 2));
- cipEqu(-1.999991f, new OverloadedNumberUtil.FloatOrByte(-1.999991f, (byte) -2));
-
- cipEqu(1000f, new OverloadedNumberUtil.FloatOrShort(1000f, (short) 1000));
- cipEqu(-1000f, new OverloadedNumberUtil.FloatOrShort(-1000f, (short) -1000));
- cipEqu(1000.00006f);
-
- cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000));
- cipEqu(-60000f, new OverloadedNumberUtil.FloatOrInteger(-60000f, -60000));
- cipEqu(60000.004f);
-
- cipEqu(100f, new OverloadedNumberUtil.FloatOrByte(100f, (byte) 100), TypeFlags.MASK_KNOWN_INTEGERS);
- cipEqu(1000f, new OverloadedNumberUtil.FloatOrShort(1000f, (short) 1000), TypeFlags.MASK_KNOWN_INTEGERS);
- cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000), TypeFlags.MASK_KNOWN_INTEGERS);
- cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000), TypeFlags.LONG);
- cipEqu((float) Integer.MAX_VALUE, (float) Integer.MAX_VALUE, TypeFlags.LONG);
- cipEqu((float) -Integer.MAX_VALUE, (float) -Integer.MAX_VALUE);
-
- cipEqu(0.5f, 0.5f, TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(0.5f, 0.5f, TypeFlags.DOUBLE);
- }
-
- public void testBigIntegerCoercion() {
- BigInteger bi;
-
- cipEqu(BigInteger.ZERO, new OverloadedNumberUtil.BigIntegerOrByte(BigInteger.ZERO));
- bi = new BigInteger(String.valueOf(Byte.MAX_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrByte(bi));
- bi = new BigInteger(String.valueOf(Byte.MIN_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrByte(bi));
-
- bi = new BigInteger(String.valueOf(Byte.MAX_VALUE + 1));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
- bi = new BigInteger(String.valueOf(Byte.MIN_VALUE - 1));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
- bi = new BigInteger(String.valueOf(Short.MAX_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
- bi = new BigInteger(String.valueOf(Short.MIN_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
-
- bi = new BigInteger(String.valueOf(Short.MAX_VALUE + 1));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
- bi = new BigInteger(String.valueOf(Short.MIN_VALUE - 1));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
- bi = new BigInteger(String.valueOf(Integer.MAX_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
- bi = new BigInteger(String.valueOf(Integer.MIN_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
-
- bi = new BigInteger(String.valueOf(Integer.MAX_VALUE + 1L));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
- bi = new BigInteger(String.valueOf(Integer.MIN_VALUE - 1L));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
- bi = new BigInteger(String.valueOf(Long.MAX_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
- bi = new BigInteger(String.valueOf(Long.MIN_VALUE));
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
-
- cipEqu(new BigInteger(String.valueOf(Long.MAX_VALUE)).add(BigInteger.ONE));
- cipEqu(new BigInteger(String.valueOf(Long.MIN_VALUE)).subtract(BigInteger.ONE));
-
- bi = new BigInteger("0");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
- TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
- TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
- TypeFlags.FLOAT);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi),
- TypeFlags.DOUBLE);
-
- bi = new BigInteger("16777215");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- bi = new BigInteger("-16777215");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
-
- bi = new BigInteger("16777216");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- bi = new BigInteger("-16777216");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
-
- bi = new BigInteger("16777217");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, TypeFlags.FLOAT);
- bi = new BigInteger("-16777217");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, TypeFlags.FLOAT);
-
- bi = new BigInteger("9007199254740991");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
- bi = new BigInteger("-9007199254740991");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
-
- bi = new BigInteger("9007199254740992");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
- bi = new BigInteger("-9007199254740992");
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
-
- bi = new BigInteger("9007199254740993");
- cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(bi, TypeFlags.FLOAT);
- cipEqu(bi, TypeFlags.DOUBLE);
- bi = new BigInteger("-9007199254740993");
- cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
- cipEqu(bi, TypeFlags.DOUBLE | TypeFlags.FLOAT);
- cipEqu(bi, TypeFlags.FLOAT);
- cipEqu(bi, TypeFlags.DOUBLE);
-
- bi = new BigInteger("9007199254740994");
- cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
- bi = new BigInteger("-9007199254740994");
- cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
- }
-
- private void cipEqu(Number actualAndExpected) {
- cipEqu(actualAndExpected, actualAndExpected, -1);
- }
-
- private void cipEqu(Number actual, Number expected) {
- cipEqu(actual, expected, -1);
- }
-
- private void cipEqu(Number actualAndExpected, int flags) {
- cipEqu(actualAndExpected, actualAndExpected, flags);
- }
-
- @SuppressWarnings("boxing")
- private void cipEqu(Number actual, Number expected, int flags) {
- Number res = OverloadedNumberUtil.addFallbackType(actual, flags);
- assertEquals(expected.getClass(), res.getClass());
- assertEquals(expected, res);
-
- // Some number types wrap the number with multiple types and equals() only compares one of them. So we try to
- // catch any inconsistency:
- assertEquals(expected.byteValue(), res.byteValue());
- assertEquals(expected.shortValue(), res.shortValue());
- assertEquals(expected.intValue(), res.intValue());
- assertEquals(expected.longValue(), res.longValue());
- assertEquals(expected.floatValue(), res.floatValue());
- assertEquals(expected.doubleValue(), res.doubleValue());
- }
-
- public void testGetArgumentConversionPrice() {
- // Unknown number types:
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- RationalNumber.class, Integer.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, RationalNumber.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- RationalNumber.class, Float.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- Float.class, RationalNumber.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- RationalNumber.class, RationalNumber.class));
-
- // Fully check some rows (not all of them; the code is generated anyways):
-
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Byte.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Short.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Integer.class));
- assertEquals(10004, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Long.class));
- assertEquals(10005, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, BigInteger.class));
- assertEquals(30006, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Float.class));
- assertEquals(20007, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, Double.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, BigDecimal.class));
-
- assertEquals(45001, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Byte.class));
- assertEquals(44002, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Short.class));
- assertEquals(41003, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Integer.class));
- assertEquals(41004, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Long.class));
- assertEquals(40005, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, BigInteger.class));
- assertEquals(33006, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Float.class));
- assertEquals(32007, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, Double.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, BigDecimal.class));
-
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Byte.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Short.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Integer.class));
- assertEquals(21004, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Long.class));
- assertEquals(21005, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, BigInteger.class));
- assertEquals(40006, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Float.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, Double.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, BigDecimal.class));
-
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Byte.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Short.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Integer.class));
- assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Long.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, BigInteger.class));
- assertEquals(40006, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Float.class));
- assertEquals(20007, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, Double.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, BigDecimal.class));
-
- // Check if all fromC is present:
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Byte.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Short.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Integer.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Long.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- BigInteger.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Float.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- Double.class, BigDecimal.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- BigDecimal.class, BigDecimal.class));
- assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.IntegerBigDecimal.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrFloat.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.FloatOrByte.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrShort.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.FloatOrByte.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.FloatOrShort.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.FloatOrInteger.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrByte.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrIntegerOrFloat.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrInteger.class, BigDecimal.class));
- assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.DoubleOrLong.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrByte.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrShort.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrInteger.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrLong.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrFloat.class, BigDecimal.class));
- assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
- OverloadedNumberUtil.BigIntegerOrDouble.class, BigDecimal.class));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
deleted file mode 100644
index 3e6c2ed..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.freemarker.core.util._NumberUtil;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings("boxing")
-public class ParameterListPreferabilityTest extends TestCase {
-
- public ParameterListPreferabilityTest(String name) {
- super(name);
- }
-
- public void testNumberical() {
- // Note: the signature lists consists of the same elements, only their order changes depending on the type
- // of the argument value.
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { byte.class },
- new Class[] { Byte.class },
- new Class[] { short.class },
- new Class[] { Short.class },
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { BigInteger.class },
- new Class[] { float.class },
- new Class[] { Float.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { BigDecimal.class },
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class }
- },
- new Object[] { (byte) 1 });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { BigDecimal.class },
- new Class[] { BigInteger.class },
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { float.class },
- new Class[] { Float.class },
- new Class[] { short.class },
- new Class[] { Short.class },
- new Class[] { byte.class },
- new Class[] { Byte.class },
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class },
- },
- new Object[] { new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal("1")) });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { BigDecimal.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { float.class },
- new Class[] { Float.class },
- new Class[] { BigInteger.class },
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { short.class },
- new Class[] { Short.class },
- new Class[] { byte.class },
- new Class[] { Byte.class },
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class },
- },
- new Object[] { new BigDecimal("1") /* possibly non-integer */ });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { float.class },
- new Class[] { Float.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { BigDecimal.class },
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { short.class },
- new Class[] { Short.class },
- new Class[] { byte.class },
- new Class[] { Byte.class },
- new Class[] { BigInteger.class },
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class },
- },
- new Object[] { new OverloadedNumberUtil.FloatOrByte(1f, (byte) 1) });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { BigInteger.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { BigDecimal.class },
- new Class[] { short.class },
- new Class[] { Short.class },
- new Class[] { float.class },
- new Class[] { Float.class },
-
- // Two incompatibles removed, would be removed in reality:
- new Class[] { byte.class },
- new Class[] { Byte.class },
-
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class }
- },
- new Object[] { new OverloadedNumberUtil.IntegerOrShort(1, (short) 1) });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { long.class },
- new Class[] { Long.class },
- new Class[] { BigInteger.class },
- new Class[] { BigDecimal.class },
- new Class[] { double.class },
- new Class[] { Double.class },
- new Class[] { float.class },
- new Class[] { Float.class },
- // skip byte and short as the would be equal with int (all invalid target types)
- new Class[] { int.class }, // In reality, this and Integer are removed as not-applicable overloads
- new Class[] { Integer.class },
- new Class[] { Number.class },
- new Class[] { Serializable.class },
- new Class[] { Object.class }
- },
- new Object[] { 1L });
-
- // Undecidable comparisons:
-
- testAllCmpPermutationsEqu(
- new Class[][] {
- new Class[] { Byte.class },
- new Class[] { Short.class },
- new Class[] { Integer.class },
- new Class[] { Long.class },
- new Class[] { BigInteger.class },
- new Class[] { Float.class },
- },
- new Object[] { 1.0 });
-
- testAllCmpPermutationsEqu(
- new Class[][] {
- new Class[] { byte.class },
- new Class[] { short.class },
- new Class[] { int.class },
- new Class[] { long.class },
- new Class[] { float.class },
- },
- new Object[] { 1.0 });
- }
-
- public void testPrimitiveIsMoreSpecific() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { boolean.class },
- new Class[] { Boolean.class }
- },
- new Object[] { true });
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { char.class },
- new Class[] { Character.class }
- },
- new Object[] { 'x' });
- }
-
- public void testCharIsMoreSpecificThanString() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { char.class },
- new Class[] { Character.class },
- new Class[] { String.class },
- new Class[] { CharSequence.class }
- },
- new Object[] { "s" });
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { char.class },
- new Class[] { Character.class },
- new Class[] { String.class }
- },
- new Object[] { 'c' });
- }
-
- public void testClassHierarchy() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { LinkedHashMap.class },
- new Class[] { HashMap.class },
- new Class[] { Map.class },
- new Class[] { Object.class }
- },
- new Object[] { new LinkedHashMap() });
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { LinkedHashMap.class },
- new Class[] { Cloneable.class },
- new Class[] { Object.class }
- },
- new Object[] { new LinkedHashMap() });
- }
-
- public void testNumericalWithNonNumerical() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { Comparable.class },
- new Class[] { Object.class },
- },
- new Object[] { 1 });
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { int.class },
- new Class[] { Integer.class },
- new Class[] { char.class },
- new Class[] { Character.class },
- },
- new Object[] { 1 });
- }
-
- public void testUnrelated() {
- testAllCmpPermutationsEqu(
- new Class[][] {
- new Class[] { Serializable.class },
- new Class[] { CharSequence.class },
- new Class[] { Comparable.class }
- },
- new Object[] { "s" });
-
- testAllCmpPermutationsEqu(
- new Class[][] {
- new Class[] { HashMap.class },
- new Class[] { TreeMap.class }
- },
- new Object[] { null });
- }
-
- public void testMultiParameter() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, String.class, String.class },
-
- new Class[] { String.class, String.class, Object.class },
- new Class[] { String.class, Object.class, String.class },
- new Class[] { Object.class, String.class, String.class },
-
- new Class[] { String.class, Object.class, Object.class },
- new Class[] { Object.class, String.class, Object.class },
- new Class[] { Object.class, Object.class, String.class },
-
- new Class[] { Object.class, Object.class, Object.class },
- },
- new Object[] { "a", "b", "c" });
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, String.class },
- new Class[] { String.class, Object.class },
- new Class[] { CharSequence.class, CharSequence.class },
- new Class[] { CharSequence.class, Object.class },
- new Class[] { Object.class, String.class },
- new Class[] { Object.class, CharSequence.class },
- new Class[] { Object.class, Object.class },
- },
- new Object[] { "a", "b" });
-
- // Subclassing is more important than primitive-VS-boxed:
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { boolean.class, boolean.class, boolean.class, String.class },
- new Class[] { Boolean.class, boolean.class, boolean.class, String.class },
- new Class[] { boolean.class, Boolean.class, Boolean.class, String.class },
- new Class[] { Boolean.class, boolean.class, Boolean.class, String.class },
- new Class[] { Boolean.class, Boolean.class, boolean.class, String.class },
- new Class[] { Boolean.class, Boolean.class, Boolean.class, String.class },
- new Class[] { Boolean.class, Boolean.class, Boolean.class, CharSequence.class },
- new Class[] { boolean.class, boolean.class, boolean.class, Object.class },
- new Class[] { Boolean.class, boolean.class, boolean.class, Object.class },
- new Class[] { boolean.class, Boolean.class, Boolean.class, Object.class },
- new Class[] { Boolean.class, boolean.class, Boolean.class, Object.class },
- new Class[] { Boolean.class, Boolean.class, boolean.class, Object.class },
- new Class[] { Boolean.class, Boolean.class, Boolean.class, Object.class },
- },
- new Object[] { true, false, true, "a" });
-
- // Subclassing is more important than primitive-VS-boxed:
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { int.class, int.class, int.class, String.class },
- new Class[] { Integer.class, int.class, int.class, String.class },
- new Class[] { int.class, Integer.class, Integer.class, String.class },
- new Class[] { Integer.class, int.class, Integer.class, String.class },
- new Class[] { Integer.class, Integer.class, int.class, String.class },
- new Class[] { Integer.class, Integer.class, Integer.class, String.class },
- new Class[] { Integer.class, Integer.class, Integer.class, CharSequence.class },
- new Class[] { int.class, int.class, int.class, Object.class },
- new Class[] { Integer.class, int.class, int.class, Object.class },
- new Class[] { int.class, Integer.class, Integer.class, Object.class },
- new Class[] { Integer.class, int.class, Integer.class, Object.class },
- new Class[] { Integer.class, Integer.class, int.class, Object.class },
- new Class[] { Integer.class, Integer.class, Integer.class, Object.class },
- },
- new Object[] { 1, 2, 3, "a" });
- }
-
- public void testVarargs() {
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, String[].class },
- new Class[] { String.class, CharSequence[].class },
- new Class[] { String.class, Object[].class },
- },
- new Object[] { "a", "b", "c" },
- true);
-
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, int[].class },
- new Class[] { String.class, Integer[].class },
- new Class[] { String.class, long[].class },
- new Class[] { String.class, Long[].class },
- new Class[] { String.class, double[].class },
- new Class[] { String.class, Double[].class },
- new Class[] { String.class, Serializable[].class },
- new Class[] { String.class, Object[].class },
- },
- new Object[] { "a", 1, 2, 3 },
- true);
-
- // 0-long varargs list; in case of ambiguity, the varargs component type decides:
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, Object[].class },
- new Class[] { CharSequence.class, int[].class },
- new Class[] { CharSequence.class, Integer[].class },
- new Class[] { CharSequence.class, long[].class },
- new Class[] { CharSequence.class, Long[].class },
- new Class[] { CharSequence.class, double[].class },
- new Class[] { CharSequence.class, Double[].class },
- new Class[] { CharSequence.class, Serializable[].class },
- new Class[] { CharSequence.class, Object[].class },
- new Class[] { Object.class, int[].class },
- },
- new Object[] { "a" },
- true);
-
-
- // Different oms prefix length; in the case of ambiguity, the one with higher oms param count wins.
- testAllCmpPermutationsInc(
- new Class[][] {
- new Class[] { String.class, int.class, int.class, int[].class },
- new Class[] { String.class, int.class, int[].class },
- new Class[] { String.class, int[].class },
- },
- new Object[] { "a", 1, 2, 3 },
- true);
- }
-
- private void testAllCmpPermutationsInc(Class[][] sortedSignatures, Object[] args) {
- testAllCmpPermutationsInc(sortedSignatures, args, false);
- }
-
- /**
- * Compares all items with all other items in the provided descending sorted array of signatures, checking that
- * for all valid indexes i and j, where j > i, it stands that sortedSignatures[i] > sortedSignatures[j].
- * The comparisons are done with both operand orders, also each items is compared to itself too.
- *
- * @param sortedSignatures method signatures sorted by decreasing specificity
- */
- private void testAllCmpPermutationsInc(Class[][] sortedSignatures, Object[] args, boolean varargs) {
- final ArgumentTypes argTs = new ArgumentTypes(args);
- for (int i = 0; i < sortedSignatures.length; i++) {
- for (int j = 0; j < sortedSignatures.length; j++) {
- assertEquals("sortedSignatures[" + i + "] <==> sortedSignatures [" + j + "]",
- _NumberUtil.getSignum(
- Integer.valueOf(j).compareTo(i)),
- _NumberUtil.getSignum(
- argTs.compareParameterListPreferability(
- sortedSignatures[i], sortedSignatures[j], varargs)));
- }
- }
- }
-
- private void testAllCmpPermutationsEqu(Class[][] signatures, Object[] args) {
- final ArgumentTypes argTs = new ArgumentTypes(args);
- for (int i = 0; i < signatures.length; i++) {
- for (int j = 0; j < signatures.length; j++) {
- assertEquals("sortedSignatures[" + i + "] <==> sortedSignatures [" + j + "]",
- 0,
- argTs.compareParameterListPreferability(signatures[i], signatures[j], false));
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java
deleted file mode 100644
index 4f4c0a1..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-public class PrallelObjectIntrospectionTest extends AbstractParallelIntrospectionTest {
-
- public PrallelObjectIntrospectionTest(String name) {
- super(name);
- }
-
- public static void main(String[] args) {
- new PrallelObjectIntrospectionTest("almostForever")
- .testReliability(Integer.MAX_VALUE);
- }
-
- @Override
- protected TemplateHashModel getWrappedEntity(int objIdx)
- throws TemplateModelException {
- return (TemplateHashModel) getObjectWrapper().wrap(
- ManyObjectsOfDifferentClasses.OBJECTS[objIdx]);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
deleted file mode 100644
index 836d559..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-public class PrallelStaticIntrospectionTest extends AbstractParallelIntrospectionTest {
-
- private static final String STATICS_CLASS_CONTAINER_CLASS_NAME
- = ManyStaticsOfDifferentClasses.class.getName();
-
- public PrallelStaticIntrospectionTest(String name) {
- super(name);
- }
-
- public static void main(String[] args) {
- new PrallelStaticIntrospectionTest("almostForever")
- .testReliability(Integer.MAX_VALUE);
- }
-
- @Override
- protected TemplateHashModel getWrappedEntity(int clIdx)
- throws TemplateModelException {
- return (TemplateHashModel) getObjectWrapper().getStaticModels().get(
- STATICS_CLASS_CONTAINER_CLASS_NAME + "$C"
- + clIdx);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
deleted file mode 100644
index 806a186..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public final class RationalNumber extends Number {
-
- final int divident;
- final int divisor;
-
- public RationalNumber(int divident, int divisor) {
- this.divident = divident;
- this.divisor = divisor;
- }
-
- @Override
- public int intValue() {
- return divident / divisor;
- }
-
- @Override
- public long longValue() {
- return divident / (long) divisor;
- }
-
- @Override
- public float floatValue() {
- return (float) (divident / (double) divisor);
- }
-
- @Override
- public double doubleValue() {
- return divident / (double) divisor;
- }
-
- public int getDivident() {
- return divident;
- }
-
- public int getDivisor() {
- return divisor;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + divident;
- result = prime * result + divisor;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- RationalNumber other = (RationalNumber) obj;
- if (divident != other.divident)
- return false;
- if (divisor != other.divisor)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return divident + "/" + divisor;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
deleted file mode 100644
index 609d632..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class StaticModelsTest {
-
- @Test
- public void modelCaching() throws Exception {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
- .build();
- TemplateHashModel statics = ow.getStaticModels();
- TemplateHashModel s = (TemplateHashModel) statics.get(S.class.getName());
- assertNotNull(s);
- assertNotNull(s.get("F"));
- assertNotNull(s.get("m"));
- try {
- s.get("x");
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("No such key"));
- }
-
- try {
- statics.get("no.such.ClassExists");
- fail();
- } catch (TemplateModelException e) {
- assertTrue(e.getCause() instanceof ClassNotFoundException);
- }
-
- TemplateModel f = s.get("F");
- assertTrue(f instanceof TemplateScalarModel);
- assertEquals(((TemplateScalarModel) f).getAsString(), "F OK");
-
- TemplateModel m = s.get("m");
- assertTrue(m instanceof TemplateMethodModelEx);
- assertEquals(((TemplateScalarModel) ((TemplateMethodModelEx) m).exec(new ArrayList())).getAsString(), "m OK");
-
- assertSame(s, statics.get(S.class.getName()));
-
- ow.clearClassIntrospecitonCache();
- TemplateHashModel sAfterClean = (TemplateHashModel) statics.get(S.class.getName());
- assertNotSame(s, sAfterClean);
- assertSame(sAfterClean, statics.get(S.class.getName()));
- assertNotNull(sAfterClean.get("F"));
- assertNotNull(sAfterClean.get("m"));
- }
-
- public static class S {
-
- public static final String F = "F OK";
-
- public static String m() {
- return "m OK";
- }
-
- }
-
-}
[03/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
deleted file mode 100644
index 717431f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias1.ftlh.out
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.
- */
-10,000.00
-10.31
-23/Dec/15 10:09 PM
-2015-12-23T21:09:04.213Z
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
deleted file mode 100644
index 624950f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh
+++ /dev/null
@@ -1,19 +0,0 @@
-<#--
- 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.
--->
-${10?string.@oct}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
deleted file mode 100644
index 08d0fea..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-alias2.ftlh.out
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-12
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
deleted file mode 100644
index 9a34ac0..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh
+++ /dev/null
@@ -1,20 +0,0 @@
-<#--
- 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.
--->
-${10.12356}
-${weight}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
deleted file mode 100644
index 25d6155..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/CustomFormatsExample-modelAware.ftlh.out
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-10.1236
-1.5 kg
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
deleted file mode 100644
index faf8592..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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.
-
-templateConfigurations = \
- ConditionalTemplateConfigurationFactory( \
- FileExtensionMatcher("xml"), \
- TemplateConfiguration( \
- sourceEncoding = Charset("utf-8"), \
- outputFormat = XMLOutputFormat() \
- ) \
- )
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
deleted file mode 100644
index f879e70..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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.
-
-templateConfigurations = \
- ConditionalTemplateConfigurationFactory( \
- PathGlobMatcher("mail/**"), \
- FirstMatchTemplateConfigurationFactory( \
- ConditionalTemplateConfigurationFactory( \
- FileNameGlobMatcher("*.subject.*"), \
- TemplateConfiguration(outputFormat = PlainTextOutputFormat()) \
- ), \
- ConditionalTemplateConfigurationFactory( \
- FileNameGlobMatcher("*.body.*"), \
- TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
- ), \
- noMatchErrorDetails = 'Mail template names must contain ".subject." or ".body."!' \
- ) \
- )
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
deleted file mode 100644
index ce72fef..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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.
-
-templateConfigurations = \
- MergingTemplateConfigurationFactory( \
- ConditionalTemplateConfigurationFactory( \
- FileNameGlobMatcher("*.stats.*"), \
- TemplateConfiguration( \
- dateTimeFormat = "iso", \
- dateFormat = "iso", \
- timeFormat = "iso", \
- timeZone = TimeZone("UTC") \
- ) \
- ), \
- ConditionalTemplateConfigurationFactory( \
- PathGlobMatcher("mail/**"), \
- TemplateConfiguration(sourceEncoding = Charset("utf-8")) \
- ), \
- FirstMatchTemplateConfigurationFactory( \
- ConditionalTemplateConfigurationFactory( \
- FileExtensionMatcher("xml"), \
- TemplateConfiguration(outputFormat = XMLOutputFormat()) \
- ), \
- ConditionalTemplateConfigurationFactory( \
- OrMatcher( \
- FileExtensionMatcher("html"), \
- FileExtensionMatcher("htm") \
- ), \
- TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
- ), \
- allowNoMatch = true \
- ) \
- )
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/test.ftlh b/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
deleted file mode 100644
index 852b82b..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/manualtest/test.ftlh
+++ /dev/null
@@ -1,28 +0,0 @@
-<#--
- 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.
--->
-<html>
-<head>
- <title>Welcome!</title>
-</head>
-<body>
- <h1>Welcome ${user}!</h1>
- <p>Our latest product:
- <a href="${latestProduct.url}">${latestProduct.name}</a>!
-</body>
-</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/servlet/web.xml
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/servlet/web.xml b/freemarker-core/src/test/resources/org/apache/freemarker/test/servlet/web.xml
deleted file mode 100644
index e406b1a..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/servlet/web.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-<!--
- 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.
--->
-
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
- version="2.4">
-
- <servlet>
- <servlet-name>controller</servlet-name>
- <servlet-class>com.example.Model2ControllerServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>controller</servlet-name>
- <url-pattern>*.c</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>controller</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
-
- <servlet>
- <servlet-name>freemarker</servlet-name>
- <servlet-class>org.apache.freemarker.servlet.FreemarkerServlet</servlet-class>
-
- <!-- FreemarkerServlet settings: -->
- <init-param>
- <param-name>TemplatePath</param-name>
- <param-value>/</param-value>
- </init-param>
- <init-param>
- <param-name>NoCache</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>ContentType</param-name>
- <param-value>text/html; charset=UTF-8</param-value> <!-- Forces UTF-8 output encoding! -->
- </init-param>
-
- <!-- FreeMarker settings: -->
- <init-param>
- <param-name>incompatible_improvements</param-name>
- <param-value>3.0.0</param-value>
- </init-param>
- <init-param>
- <param-name>template_exception_handler</param-name>
- <!-- Some may prefer "html_debug" for development. -->
- <param-value>rethrow</param-value>
- </init-param>
- <init-param>
- <param-name>template_update_delay</param-name>
- <param-value>0</param-value> <!-- 0 is for development only! Use higher value otherwise. -->
- </init-param>
- <init-param>
- <param-name>sourceEncoding</param-name>
- <param-value>UTF-8</param-value> <!-- The encoding of the template files. -->
- </init-param>
- <init-param>
- <param-name>number_format</param-name>
- <param-value>0.##########</param-value>
- </init-param>
-
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>freemarker</servlet-name>
- <url-pattern>*.ftl</url-pattern>
- </servlet-mapping>
-
- <!-- Prevent the visiting of MVC Views from outside the servlet container.
- RequestDispatcher.forward/include should and will still work. Removing this
- may open security holes! -->
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>FreeMarker MVC Views</web-resource-name>
- <url-pattern>*.ftl</url-pattern>
- </web-resource-collection>
- <auth-constraint>
- <!-- Nobody is allowed to visit these -->
- </auth-constraint>
- </security-constraint>
-
-</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
deleted file mode 100644
index 33a7186..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Arithmetic Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Perform a number assignment:</p>
-
-
-3.234
-2.00
-0.6172500000000000000000000000000000000000
-1.620089104901
-1.6201
-
-<P>Display a number with at least 3 digits after the decimal point</P>
-
-1234.000
-
-<p>Now use numbers in assignment</p>
-
-
-1257.77
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
deleted file mode 100644
index 0bab0bc..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-Y Y Y
-N N N
-y y y
-n n n
-y y y
-n n n
-str:n str:n
-nein ja
-theStringValue theStringValue
-
-
-
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
deleted file mode 100644
index 8dc1290..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Boolean Values Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-
-<p>Now perform scalar boolean tests:</p>
-
-<p>
- b is true.<br />
-</p>
-
-<p> This makes sense.<br />
-</p>
-
-<p>
- boolean3 succeeded.<br />
-</p>
-
-<p>
- boolean4 succeeded.<br />
-</p>
-
-<p>
- boolean4 || boolean5 succeeded.<br />
-</p>
-
-<p>
- boolean5 || boolean4 || boolean5 succeeded.<br />
-</p>
-
-<p> boolean4 && boolean5 failed.<br />
-</p>
-
-<p>Now test list models:</p>
-
-<p>
- list1 succeeded.<br />
-</p>
-
-<p>
- list2 succeeded.<br />
-</p>
-
-<p>Test hash models:</p>
-
-<p>
- hash1 succeeded: Hello, world.<br />
-</p>
-
-<p>
- hash2 succeeded.<br />
-</p>
-
-<p>Test not operator:</p>
-
-<p>
- Not boolean1 succeeded
-</p>
-
-<p>
- Not boolean1 succeeded
-</p>
-
-<p> Not boolean2 failed
-</p>
-
-<p> Not boolean2 failed
-</p>
-
-<p>
- Message is "Hello, world!"
-</p>
-
-<p> Message is "Hello, world!"
-</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
deleted file mode 100644
index 4532027..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-<head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
-</head>
-<body>
-éáőű
-õÕûÛ
-őŐűŰ
-</body>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
deleted file mode 100644
index d5902e3..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Comment Test</title>
-</head>
-<body>
- <p>Message exists!
- </p>
-
-a b
-a b
-
-6
-7
-8
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
deleted file mode 100644
index 8d9d372..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Numeric Operations Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Start with the increment operator:</p>
-<p>a1 = 0</p>
-<p>a1 = 1</p>
-<p>a1 = 2</p>
-
-<p>Now the decrement operator:</p>
-<p>a2 = 5</p>
-<p>a2 = 4</p>
-<p>a2 = 3</p>
-<p>a2 = 2</p>
-<p>a2 = 1</p>
-<p>a2 = 0</p>
-<p>a2 = -1</p>
-
-<p>Now the add operator:</p>
-<p>op1 = 5, op2 = 3, op3 = 8</p>
-<p>op3 = 11</p>
-
-<p>And the subtract operator:</p>
-<p>op1 = 5, op2 = 3, op3 = 2</p>
-<p>op3 = -1</p>
-
-<p>The comparison operators:</p>
- <p>Item is: 0</p>
- <p>Item is less than five.</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is: 1</p>
- <p>Item is less than five.</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is: 2</p>
- <p>Item is less than five.</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is: 3</p>
- <p>Item is less than five.</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is greater than two.</p>
- <p>Item is: 4</p>
- <p>Item is less than five.</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is greater than two.</p>
- <p>Item is: 5</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is greater than two.</p>
- <p>Item is: 6</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is greater than two.</p>
- <p>Item is: 7</p>
- <p>Item is less than or equals to seven.</p>
- <p>Item is greater than two.</p>
- <p>Item is: 8</p>
- <p>Item is greater than two.</p>
- <p>Item is: 9</p>
- <p>Item is greater than two.</p>
- <p>Item is: 10</p>
- <p>Item is greater than two.</p>
- <p>Item is greater than or equal to ten.</p>
- <p>Item is: 11</p>
- <p>Item is greater than two.</p>
- <p>Item is greater than or equal to ten.</p>
- <p>Item is: 12</p>
- <p>Item is greater than two.</p>
- <p>Item is greater than or equal to ten.</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
deleted file mode 100644
index 43c7eed..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Compress Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>This is the same message, using the "compress" tag:</p>
-<p>Hello, world!</p>
-<p>This is the same message, using the "StandardCompress" transform model:</p>
-<p>Hello, world!</p>
-<p>This multi-line message should be compressed to a single line.</p>
-
-<p>An example where the first character is not whitespace but the second character is:</p>
-<p>x y</p>
-
-<p>The end.</p>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
deleted file mode 100644
index 9180262..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-Nov 15, 2002 2:54:13 PM
-Nov 15, 2002 2:54:13 PM
-Nov 15, 2002 2:54:13 PM
-Nov 15, 2002 2:54:13 PM
-11/15/02 2:54 PM
-Nov 15, 2002 2:54:13 PM
-November 15, 2002 2:54:13 PM GMT
-11/15/02 2:54 PM
-11/15/02 2:54:13 PM
-11/15/02 2:54:13 PM GMT
-Nov 15, 2002 2:54 PM
-Nov 15, 2002 2:54:13 PM
-Nov 15, 2002 2:54:13 PM GMT
-November 15, 2002 2:54 PM
-November 15, 2002 2:54:13 PM
-November 15, 2002 2:54:13 PM GMT
-Nov 15, 2002
-Nov 15, 2002
-11/15/02
-Nov 15, 2002
-November 15, 2002
-2:54:13 PM
-2:54:13 PM
-2:54 PM
-2:54:13 PM
-2:54:13 PM GMT
-2002. november 15. 14:54:13 GMT
-Fri, 15 Nov 02002 14:54:13 GMT
-Fri, 15 Nov 2002 14:54:13 GMT
-Fri, 15 Nov 2002 14:54:13 GMT
-2002
-
-2002
-2002
-
-2002
-11
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
deleted file mode 100644
index e015315..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-array-0
-array-1
-2
-array-0
-array-1
-list-0
-list-1
-list-2
-3
-not empty
-list-0
-value
-objValue
-foo-value
-hasfoo
-nobaz
-bar-value-0
-foo-value
-overloaded-int-1
-overloaded-String-String
-Message
-1974-11-14
-static-method
-static-overloaded-int-1
-static-overloaded-String-String
-static-final-field
-static-field
-ONEx
-TWOx
-THREEx
-true
-false
-false
-42
-1
-m
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
deleted file mode 100644
index 3a52c46..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-No NS = No NS
-x NS = x NS
-y NS = y NS
-x NS = x NS
-
-true
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
deleted file mode 100644
index fd48463..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-foo
-
-luck
-
-
-0
-
- UNDEFINED is undefined.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
deleted file mode 100644
index ccfe5c8..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-FreeMarker: Encoding built-in tests
-
-html: [&<>"'{}\a/]
-xml: [&<>"'{}\a/]
-xhtml: [&<>"'{}\a/]
-rtf: [&<>"'\{\}\\a/]
-html: [a&a<a>a"a'a{a}a\]
-xml: [a&a<a>a"a'a{a}a\]
-xhtml: [a&a<a>a"a'a{a}a\]
-rtf: [a&a<a>a"a'a\{a\}a\\]
-html: [<<<<<]
-xml: [<<<<<]
-xhtml: [<<<<<]
-rtf: [\{\{\{\{\{]
-html: []
-xml: []
-xhtml: []
-rtf: []
-html: [a]
-xml: [a]
-xhtml: [a]
-rtf: [a]
-html: [&]
-xml: [&]
-xhtml: [&]
-rtf: [\{]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
deleted file mode 100644
index c0a5440..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-a
-b
-c
-a
-b
-c
-a
-1
-a
-b
-c
-<&>
-&lt;&amp;&gt;
-<&>
----
-<Mooo> = <Mooo>
- <MOOO> = <MOOO>
- <MOOO> = <MOOO>
- <MOOO> = <MOOO>
- <MOOO> = <MOOO>
- <MOOO> = <MOOO>
- <Mooo> = <Mooo>
- <Mooo> = <Mooo>
- <Mooo> = <Mooo>
- <Mooo> = <Mooo>
- <Mooo> = <Mooo>
- <MOOO> = <MOOO>
- red green blue
----
- <A&B>[a&b](A&B) <A&B2>[a&b2](A&B2)
- <{a&b}A&B>[{a&b}a&b]({a&b}A&B) <{a&b2}A&B2>[{a&b2}a&b2]({a&b2}A&B2)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
deleted file mode 100644
index 0ea4395..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Exception Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world! <br />
-freemarker.template.TemplateModelException: Throwing from ExceptionModel!
- at freemarker.test.templatesuite.models.ExceptionModel.getAsString(ExceptionModel.java:57)
- at freemarker.template.compiler.Expression.getStringValue(Expression.java:65)
- at freemarker.template.compiler.DollarVariable.process(DollarVariable.java:62)
- at freemarker.template.compiler.NestedTemplateElements.process(NestedTemplateElements.java:76)
- at freemarker.template.Template.process(Template.java:266)
- at freemarker.template.Template.process(Template.java:289)
- at freemarker.test.TestException.runTest(TestException.java:91)
- at junit.framework.TestCase.runBare(TestCase.java:140)
- at junit.framework.TestResult$1.protect(TestResult.java:106)
- at junit.framework.TestResult.runProtected(TestResult.java:124)
- at junit.framework.TestResult.run(TestResult.java:109)
- at junit.framework.TestCase.run(TestCase.java:131)
- at junit.framework.TestSuite.runTest(TestSuite.java:173)
- at junit.framework.TestSuite.run(TestSuite.java:168)
- at junit.swingui.TestRunner$17.run(TestRunner.java:644)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
deleted file mode 100644
index bf441d3..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Exception Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world! <br />
-<!-- Template Error: Couldn't get value of variable test: Couldn't read string value of test: freemarker.template.TemplateModelException: Throwing from ExceptionModel!
- at freemarker.test.templatesuite.models.ExceptionModel.getAsString(ExceptionModel.java:42)
- at freemarker.template.expression.Variable.getValue(Variable.java:69)
- at freemarker.template.instruction.VariableInstruction.process(VariableInstruction.java:55)
- at freemarker.template.compiler.TemplateArrayList.process(TemplateArrayList.java:69)
- at freemarker.template.Template.process(Template.java:226)
- at freemarker.test.TestException2.runTest(TestException2.java:83)
- at junit.framework.TestCase.runBare(TestCase.java:140)
- at junit.framework.TestResult$1.protect(TestResult.java:106)
- at junit.framework.TestResult.runProtected(TestResult.java:124)
- at junit.framework.TestResult.run(TestResult.java:109)
- at junit.framework.TestCase.run(TestCase.java:131)
- at junit.framework.TestSuite.runTest(TestSuite.java:173)
- at junit.framework.TestSuite.run(TestSuite.java:168)
- at junit.swingui.TestRunner$17.run(TestRunner.java:644)
- -->
-</p>
-
-</body>
-</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
deleted file mode 100644
index 6089e87..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.
- */
-<html><head></head><body bgcolor="#ffffff">
-Template Compilation Error: Identifier expected at line 10.
-</body></html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
deleted file mode 100644
index acb1f78..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Extended Hash Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>A hash set of 8 animals follows:</p>
-
-<p>
- elephant,
-
- cat,
-
- zebra,
-
- dog,
-
- aardvark,
-
- kiwi,
-
- squirrel,
-
- gecko.
-</p>
-
-<p>The first animal is an elephant, and the last is a
-gecko.</p>
-
-<p>A hash set of 8 digits follows:<p>
-
-<p>
- six,
-
- four,
-
- eight,
-
- five,
-
- one,
-
- two,
-
- seven,
-
- three.
-</p>
-
-<p>The zebra number is eight.</p>
-
-<p>The end.</p>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
deleted file mode 100644
index 9736322..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- */
-
-a:
- a = 1
- b = 2
- c = 3
- X = 4
- ---
- 1
- 2
- 3
- 4
- ---
-
-B:
- d = 10
- e = 20
- f = 30
- X = 40
- ---
- 10
- 20
- 30
- 40
- ---
-
-a + B:
- a = 1
- b = 2
- c = 3
- X = 40
- d = 10
- e = 20
- f = 30
- ---
- 1
- 2
- 3
- 40
- 10
- 20
- 30
- ---
-
-B + a:
- d = 10
- e = 20
- f = 30
- X = 4
- a = 1
- b = 2
- c = 3
- ---
- 10
- 20
- 30
- 4
- 1
- 2
- 3
- ---
-
-a + a:
- a = 1
- b = 2
- c = 3
- X = 4
- ---
- 1
- 2
- 3
- 4
- ---
-
-{} + a:
- a = 1
- b = 2
- c = 3
- X = 4
- ---
- 1
- 2
- 3
- 4
- ---
-
-a + {}:
- a = 1
- b = 2
- c = 3
- X = 4
- ---
- 1
- 2
- 3
- 4
- ---
-
-{} + {}:
- ---
- ---
-
-a + b + {} + b + {} + a:
- a = 1
- b = 2
- c = 3
- X = 4
- d = 10
- e = 20
- f = 30
- ---
- 1
- 2
- 3
- 4
- 10
- 20
- 30
- ---
-
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
deleted file mode 100644
index 3af1052..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Hash Literal Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Now perform a hash assignment:</p>
-
-
-test23
-Hello, world!
-hello all
-1
-
-<p>Now update the assignment and repeat:</p>
-
-
-test23
-Hello, world!
-hello all
-
-1
-
-<p>Now reassign the list and repeat:</p>
-
-
-test23
-Hello, world!
-
-
-1
-Temporary
-Temporary
-Temporary
-
-<p>Pathological case: zero item hash:</p>
-
-
-
-<p>Hash of number literals:</p>
-2
-
-<p>Hash concatenation:</p>
-a => 1
-b => 3
-c => 4
-
-<p>Empty hash concatenation:</p>
-foo, bar
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
deleted file mode 100644
index b1072fd..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Exec Model Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!
-</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
deleted file mode 100644
index 1c62bd5..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-<a-b>red123</a-b>
-
-f-a works
-
-dash-dash-dash etc.
-dash-dash-dash etc.
-propVal
-propVal
-
-List: 123
-
-Switch: OK
-ESCAPED
-
-
-as1
-as2
-as3
-as4
-as5
-
-<catchAll x=1 y=2 a:b.c=5 data-foo=4 z=3 />
-
----.: = dash-dash-dash etc.
-@as@_a = as1
-as/b = as3
-as'c = as4
-as"d = as5
-as-c = as2
-catchAll = ...
-dumpNS = ...
-f-a = ...
-hash = ...
-ls:a = ...
-m/b2 = ...
-m-a = ...
-m-b2 = ...
-sw-a = ...
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
deleted file mode 100644
index 8a8d04f..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-Korean Keyboard
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
deleted file mode 100644
index 7c9d1d8..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.
- */
-
-- good
-- good
-- good
-- good
-
-- good
-- good
-
-- good
-- good
-- good
-- good
-
-- good
-- good
-- good
-- good
-
-- good
-- good
-- good
-- good
-
-- good
-- good
-
-- good
-- good
-- good
-- good
-
-- good
-- good
-- good
-- good
-
-- 1
--
--
-- is 1
-- isn't 2
-- isn't 3
-- Finally, it's: 1
--
-- 2
--
-- isn't 1
-- is 2
-- isn't 3
-- Finally, it's: 2
--
--
-- 3
-- isn't 1
-- isn't 2
-- is 3
-- Finally, it's: 3
--
--
--
-- isn't 1
-- isn't 2
-- isn't 3
-- Finally, it's: 4
-
- 1:
- == 1
- 1:
- <= 2
- 1:
- <= 3
- 2:
- > 1
- 2:
- == 2
- 2:
- <= 3
- 3:
- > 1
- 3:
- > 2
- 3:
- == 3
- End
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
deleted file mode 100644
index b51a4f4..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
---
---
-
-
-jsmith@acme.com
- Test bar.
- Email: jsmith@acme.com
-
-jsmith@acme.com
- Test bar.
- Email: jsmith@acme.com
- Email in the root: jsmith@other1.com
-
-jsmith@other2.com
- Test bar.
- Email: jsmith@other2.com
- Email in the root: jsmith@other1.com
-
-jsmith@other2.com
-jsmith@other3.com
-
-foobarfoobar
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
deleted file mode 100644
index c72d69c..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Include Instruction Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-Hello, world!
-
- <p>Message exists!
-
-<p>Test normal includes:</p>
-<p>A test of included files:</p>
-
- <p>Message exists!:<br />
- Hello, world!</p>
-
- Can you see me?
-
-assigning from included template
-I'm here, mon!
-
-Kilroy
- Can you see me? Kilroy
-
-<p>Test subdir includes:</p>
-<p>This is include-subdir.ftl</p>
-<p>Testing including from same directory</p>
-<p>This is include-subdir2.ftl</p>
-<p>Testing including from relative parent</p>
-<p>A test of included files:</p>
-
- <p>Message exists!:<br />
- Hello, world!</p>
-
- Can you see me?
-<p>Testing including from loader root</p>
-<p>A test of included files:</p>
-
- <p>Message exists!:<br />
- Hello, world!</p>
-
- Can you see me?
-<p>Testing including through acquisition</p>
-<p>This is include-subdir2.ftl</p>
-</body>
-</html>
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
deleted file mode 100644
index b7c43a9..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-A próba
-A próba
-
-A próba
-A próba
-A próba
-A próba
-
-[]
-[]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
deleted file mode 100644
index fe862e6..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-abcdef
-abcdef
-abcdef
-
-M
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
deleted file mode 100644
index fb44def..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: List Iterator Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-<p>Now iterate over a list:</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>Now iterate again:</p>
-
-<p>0. one</p>
-<p>1. two</p>
-<p>2. three</p>
-<p>3. four</p>
-<p>4. five</p>
-
-<p>Iterate over a list in a hash:</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-<p>one</p>
-<p>two</p>
-<p>three</p>
-<p>four</p>
-<p>five</p>
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
deleted file mode 100644
index dbe5fd0..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-<html>
-<head>
-<title>FreeMarker: Last Character Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
- 13
-
- ELLO, WORLD!
-
- message: Hello, Worl
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
deleted file mode 100644
index 3b9b76d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
- 0: a [0:A, 1:B, 2:C]
- 1: b [0:A, 1:B, 2:C]
- 2: c [0:A, 1:B, 2:C]
-
- 0: a 0a/0A, 0a/1B, 0a/2C
- 1: b 1b/0A, 1b/1B, 1b/2C
- 2: c 2c/0A, 2c/1B, 2c/2C
-
-0:a, 1:b, 2:c
-1. a; 2. b; 3. c;
-
-a, b, c
-a, b, c
-
-A, b, c.
-
-true/false false/true true/false
-
- <td class="oddRow">a</td>
- <td class="evenRow">b</td>
- <td class="oddRow">c</td>
-
- <td class="rowOdd">a</td>
- <td class="rowEven">b</td>
- <td class="rowOdd">c</td>
-
- <td class="R">a</td>
- <td class="G">b</td>
- <td class="B">c</td>
- <td class="R">d</td>
- <td class="G">e</td>
- <td class="B">f</td>
- <td class="R">g</td>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
deleted file mode 100644
index 05373bd..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-Size: 4
-Items: @0 aardvark, @1 bear, @2 cat, @3 dog.
-
-Size: 1
-Items: @0 aardvark.
-
-Size: 0
-Items:
-
-Size: 3
-Items: @0 11, @1 22, @2 33.
-
-Size: 3
-Items: @0 11, @1 22, @2 33.
-
-Size: 3
-Items: @0 11, @1 22, @2 33.
-
-Size: failed
-Items: @0 11, @1 22, @2 33.
-
-Size: 0
-Items:
-
-Size: 0
-Items:
-
-Size: 0
-Items:
-
-Size: failed
-Items:
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
deleted file mode 100644
index cb9e6d4..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.
- */
-=== [aardvark, bear, cat, dog] ===
-
--- List+sep:
- aardvark,
- bear,
- cat,
- dog
--- List+else:
- aardvark
- bear
- cat
- dog
--- List+items:
- [
- aardvark
- bear
- cat
- dog
- ]
--- List+items+else:
- [
- aardvark
- bear
- cat
- dog
- ]
--- List+items+sep+else:
- [
- aardvark,
- bear,
- cat,
- dog
- ]
---
-
-=== [aardvark] ===
-
--- List+sep:
- aardvark
--- List+else:
- aardvark
--- List+items:
- [
- aardvark
- ]
--- List+items+else:
- [
- aardvark
- ]
--- List+items+sep+else:
- [
- aardvark
- ]
---
-
-=== [] ===
-
--- List+sep:
--- List+else:
- Empty!
--- List+items:
--- List+items+else:
- Empty!
--- List+items+sep+else:
- Empty!
---
-
-=== [11, 22, 33] ===
-
--- List+sep:
- 11,
- 22,
- 33
--- List+else:
- 11
- 22
- 33
--- List+items:
- [
- 11
- 22
- 33
- ]
--- List+items+else:
- [
- 11
- 22
- 33
- ]
--- List+items+sep+else:
- [
- 11,
- 22,
- 33
- ]
---
-
-=== [11, 22, 33] ===
-
--- List+sep:
- 11,
- 22,
- 33
--- List+else:
- 11
- 22
- 33
--- List+items:
- [
- 11
- 22
- 33
- ]
--- List+items+else:
- [
- 11
- 22
- 33
- ]
--- List+items+sep+else:
- [
- 11,
- 22,
- 33
- ]
---
-
-=== [11, 22, 33] ===
-
--- List+sep:
- 11,
- 22,
- 33
--- List+else:
- 11
- 22
- 33
--- List+items:
- [
- 11
- 22
- 33
- ]
--- List+items+else:
- [
- 11
- 22
- 33
- ]
--- List+items+sep+else:
- [
- 11,
- 22,
- 33
- ]
---
-
-=== [] ===
-
--- List+sep:
--- List+else:
- Empty!
--- List+items:
--- List+items+else:
- Empty!
--- List+items+sep+else:
- Empty!
---
-
-=== [] ===
-
--- List+sep:
--- List+else:
- Empty!
--- List+items:
--- List+items+else:
- Empty!
--- List+items+sep+else:
- Empty!
---
-
-=== [] ===
-
--- List+sep:
--- List+else:
- Empty!
--- List+items:
--- List+items+else:
- Empty!
--- List+items+sep+else:
- Empty!
---
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt b/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
deleted file mode 100644
index 26fc60d..0000000
--- a/freemarker-core/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-[
- [(11@0, 11@0), (11@0, 22@1), (11@0, 33@2)],
- [(22@1, 11@0), (22@1, 22@1), (22@1, 33@2)],
- [(33@2, 11@0), (33@2, 22@1), (33@2, 33@2)]
-]
-
-
- <p>2 hits:
- <div class="hits">
- <div class="hit">a</div>
- <div class="hit">b</div>
- </div>
-
- <p>2 hits:
- <div class="hits">
- <div class="hitOther">a</div>
- <div class="hitOther">b</div>
- </div>
-
- <p>2 hits:
- <div class="hits">
- ...
- </div>
-
- <p>Nothing.
-
-11, 22, ...
-[11, 22, ...]
-
-1, 2, 3
-1 /*first*/, 2, 3
-[1, 2, 3]
-1
-1
-[1]
-Empty
-Empty
-Empty
-
[37/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
new file mode 100644
index 0000000..a7259d8
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.freemarker.core.TemplateConfiguration;
+import org.junit.Test;
+
+public class TemplateConfigurationFactoryTest {
+
+ @Test
+ public void testCondition1() throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration tc = newTemplateConfiguration(1);
+
+ TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc);
+
+ assertNotApplicable(tcf, "x.ftl");
+ assertApplicable(tcf, "x.ftlx", tc);
+ }
+
+ @Test
+ public void testCondition2() throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration tc = newTemplateConfiguration(1);
+
+ TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*.ftlx"),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("x.*"), tc));
+
+ assertNotApplicable(tcf, "x.ftl");
+ assertNotApplicable(tcf, "y.ftlx");
+ assertApplicable(tcf, "x.ftlx", tc);
+ }
+
+ @Test
+ public void testMerging() throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration tc1 = newTemplateConfiguration(1);
+ TemplateConfiguration tc2 = newTemplateConfiguration(2);
+ TemplateConfiguration tc3 = newTemplateConfiguration(3);
+
+ TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3));
+
+ assertNotApplicable(tcf, "x.ftl");
+ assertApplicable(tcf, "x.ftlx", tc1);
+ assertApplicable(tcf, "a.ftl", tc2);
+ assertApplicable(tcf, "b.ftl", tc3);
+ assertApplicable(tcf, "a.ftlx", tc1, tc2);
+ assertApplicable(tcf, "b.ftlx", tc1, tc3);
+ assertApplicable(tcf, "ab.ftl", tc2, tc3);
+ assertApplicable(tcf, "ab.ftlx", tc1, tc2, tc3);
+
+ assertNotApplicable(new MergingTemplateConfigurationFactory(), "x.ftl");
+ }
+
+ @Test
+ public void testFirstMatch() throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration tc1 = newTemplateConfiguration(1);
+ TemplateConfiguration tc2 = newTemplateConfiguration(2);
+ TemplateConfiguration tc3 = newTemplateConfiguration(3);
+
+ FirstMatchTemplateConfigurationFactory tcf = new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3));
+
+ try {
+ assertNotApplicable(tcf, "x.ftl");
+ } catch (TemplateConfigurationFactoryException e) {
+ assertThat(e.getMessage(), containsString("x.ftl"));
+ }
+ tcf.setNoMatchErrorDetails("Test details");
+ try {
+ assertNotApplicable(tcf, "x.ftl");
+ } catch (TemplateConfigurationFactoryException e) {
+ assertThat(e.getMessage(), containsString("Test details"));
+ }
+
+ tcf.setAllowNoMatch(true);
+
+ assertNotApplicable(tcf, "x.ftl");
+ assertApplicable(tcf, "x.ftlx", tc1);
+ assertApplicable(tcf, "a.ftl", tc2);
+ assertApplicable(tcf, "b.ftl", tc3);
+ assertApplicable(tcf, "a.ftlx", tc1);
+ assertApplicable(tcf, "b.ftlx", tc1);
+ assertApplicable(tcf, "ab.ftl", tc2);
+ assertApplicable(tcf, "ab.ftlx", tc1);
+
+ assertNotApplicable(new FirstMatchTemplateConfigurationFactory().allowNoMatch(true), "x.ftl");
+ }
+
+ @Test
+ public void testComplex() throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration tcA = newTemplateConfiguration(1);
+ TemplateConfiguration tcBSpec = newTemplateConfiguration(2);
+ TemplateConfiguration tcBCommon = newTemplateConfiguration(3);
+ TemplateConfiguration tcHH = newTemplateConfiguration(4);
+ TemplateConfiguration tcHtml = newTemplateConfiguration(5);
+ TemplateConfiguration tcXml = newTemplateConfiguration(6);
+ TemplateConfiguration tcNWS = newTemplateConfiguration(7);
+
+ TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory(
+ new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("a/**"), tcA),
+ new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("b/**"),
+ new MergingTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*"), tcBCommon),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.s.*"), tcBSpec))))
+ .allowNoMatch(true),
+ new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.hh"), tcHH),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*h"), tcHtml),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*x"), tcXml))
+ .allowNoMatch(true),
+ new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.nws.*"), tcNWS));
+
+ assertNotApplicable(tcf, "x.ftl");
+ assertApplicable(tcf, "b/x.ftl", tcBCommon);
+ assertApplicable(tcf, "b/x.s.ftl", tcBCommon, tcBSpec);
+ assertApplicable(tcf, "b/x.s.ftlh", tcBCommon, tcBSpec, tcHtml);
+ assertApplicable(tcf, "b/x.s.nws.ftlx", tcBCommon, tcBSpec, tcXml, tcNWS);
+ assertApplicable(tcf, "a/x.s.nws.ftlx", tcA, tcXml, tcNWS);
+ assertApplicable(tcf, "a.hh", tcHH);
+ assertApplicable(tcf, "a.nws.hh", tcHH, tcNWS);
+ }
+
+ @SuppressWarnings("boxing")
+ private TemplateConfiguration newTemplateConfiguration(int id) {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setCustomAttribute("id", id);
+ tcb.setCustomAttribute("contains" + id, true);
+ return tcb.build();
+ }
+
+ private void assertNotApplicable(TemplateConfigurationFactory tcf, String sourceName)
+ throws IOException, TemplateConfigurationFactoryException {
+ assertNull(tcf.get(sourceName, DummyTemplateLoadingSource.INSTANCE));
+ }
+
+ private void assertApplicable(TemplateConfigurationFactory tcf, String sourceName, TemplateConfiguration... expectedTCs)
+ throws IOException, TemplateConfigurationFactoryException {
+ TemplateConfiguration mergedTC = tcf.get(sourceName, DummyTemplateLoadingSource.INSTANCE);
+ List<Object> mergedTCAttNames = new ArrayList<>(mergedTC.getCustomAttributes().keySet());
+
+ for (TemplateConfiguration expectedTC : expectedTCs) {
+ Integer tcId = (Integer) expectedTC.getCustomAttribute("id");
+ if (tcId == null) {
+ fail("TemplateConfiguration-s must be created with newTemplateConfiguration(id) in this test");
+ }
+ if (!mergedTCAttNames.contains("contains" + tcId)) {
+ fail("TemplateConfiguration with ID " + tcId + " is missing from the asserted value");
+ }
+ }
+
+ for (Object attKey: mergedTCAttNames) {
+ if (!containsCustomAttr(attKey, expectedTCs)) {
+ fail("The asserted TemplateConfiguration contains an unexpected custom attribute: " + attKey);
+ }
+ }
+
+ assertEquals(expectedTCs[expectedTCs.length - 1].getCustomAttribute("id"), mergedTC.getCustomAttribute("id"));
+ }
+
+ private boolean containsCustomAttr(Object attKey, TemplateConfiguration... expectedTCs) {
+ for (TemplateConfiguration expectedTC : expectedTCs) {
+ if (expectedTC.getCustomAttribute(attKey) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("serial")
+ private static class DummyTemplateLoadingSource implements TemplateLoadingSource {
+ private static DummyTemplateLoadingSource INSTANCE = new DummyTemplateLoadingSource();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
new file mode 100644
index 0000000..3a24bfc
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
@@ -0,0 +1,330 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateNotFoundException;
+import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormatFM2;
+import org.apache.freemarker.test.MonitoredTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+
+public class TemplateNameFormatTest {
+
+ @Test
+ public void testToRootBasedName() throws MalformedTemplateNameException {
+ // Path that are treated the same both in 2.3 and 2.4 format:
+ for (TemplateNameFormat tnf : new TemplateNameFormat[] {
+ DefaultTemplateNameFormatFM2.INSTANCE, DefaultTemplateNameFormat.INSTANCE }) {
+ // Relative paths:
+ // - No scheme:
+ assertEquals("a/b", tnf.toRootBasedName("a/", "b"));
+ assertEquals("/a/b", tnf.toRootBasedName("/a/", "b"));
+ assertEquals("a/b", tnf.toRootBasedName("a/f", "b"));
+ assertEquals("/a/b", tnf.toRootBasedName("/a/f", "b"));
+ // - Scheme:
+ assertEquals("s://a/b", tnf.toRootBasedName("s://a/", "b"));
+ assertEquals("s:///a/b", tnf.toRootBasedName("s:///a/", "b"));
+ assertEquals("s://a/b", tnf.toRootBasedName("s://a/f", "b"));
+ assertEquals("s:///a/b", tnf.toRootBasedName("s:///a/f", "b"));
+ assertEquals("s://b", tnf.toRootBasedName("s://f", "b"));
+ assertEquals("s:///b", tnf.toRootBasedName("s:///f", "b"));
+
+ // Absolute paths:
+ // - No scheme:
+ assertEquals("b", tnf.toRootBasedName("a/", "/b"));
+ assertEquals("b", tnf.toRootBasedName("/a/", "/b"));
+ assertEquals("b", tnf.toRootBasedName("a/s:/f/", "/b"));
+ // - Scheme:
+ assertEquals("s://b", tnf.toRootBasedName("s://x/", "/b"));
+ assertEquals("s://b", tnf.toRootBasedName("s:///x/", "/b"));
+
+ // Schemed absolute paths:
+ assertEquals("s://b", tnf.toRootBasedName("a/", "s://b"));
+ assertEquals("s://b", tnf.toRootBasedName("i://a/", "s://b"));
+ }
+
+ // Scheme names in 2.4 format only:
+ {
+ final TemplateNameFormat tnf = DefaultTemplateNameFormat.INSTANCE;
+ assertEquals("s:b", tnf.toRootBasedName("s:f", "b"));
+ assertEquals("s:/b", tnf.toRootBasedName("s:/f", "b"));
+ assertEquals("s:b", tnf.toRootBasedName("s:f", "/b"));
+ assertEquals("s:b", tnf.toRootBasedName("s:/f", "/b"));
+ assertEquals("s:f/b", tnf.toRootBasedName("s:f/", "b"));
+ assertEquals("s:/f/b", tnf.toRootBasedName("s:/f/", "b"));
+ assertEquals("s:b", tnf.toRootBasedName("s:f/", "/b"));
+ assertEquals("s:b", tnf.toRootBasedName("s:/f/", "/b"));
+ assertEquals("s:b", tnf.toRootBasedName("s:/f/", "/b"));
+ assertEquals("b", tnf.toRootBasedName("a/s://f/", "/b"));
+ }
+
+ // Scheme names in 2.3 format only:
+ {
+ final TemplateNameFormat tnf = DefaultTemplateNameFormatFM2.INSTANCE;
+ assertEquals("a/s://b", tnf.toRootBasedName("a/s://f/", "/b"));
+ }
+ }
+
+ @Test
+ public void testNormalizeRootBasedName() throws MalformedTemplateNameException {
+ // Normalizations that are the same in legacy and modern format:
+ for (TemplateNameFormat tnf : new TemplateNameFormat[] {
+ DefaultTemplateNameFormatFM2.INSTANCE, DefaultTemplateNameFormat.INSTANCE }) {
+ assertEquals("", tnf.normalizeRootBasedName(""));
+ for (String lead : new String[] { "", "/" }) {
+ assertEquals("foo", tnf.normalizeRootBasedName(lead + "foo"));
+ assertEquals("foo", tnf.normalizeRootBasedName(lead + "./foo"));
+ assertEquals("foo", tnf.normalizeRootBasedName(lead + "./././foo"));
+ assertEquals("foo", tnf.normalizeRootBasedName(lead + "bar/../foo"));
+ assertEquals("a/b/", tnf.normalizeRootBasedName("a/b/"));
+ assertEquals("a/", tnf.normalizeRootBasedName("a/b/../"));
+ assertEquals("a/c../..d/e*/*f", tnf.normalizeRootBasedName("a/c../..d/e*/*f"));
+ assertEquals("", tnf.normalizeRootBasedName(""));
+ assertEquals("foo/bar/*", tnf.normalizeRootBasedName("foo/bar/*"));
+ assertEquals("schema://", tnf.normalizeRootBasedName("schema://"));
+
+ assertThrowsWithBackingOutException(lead + "bar/../../x/foo", tnf);
+ assertThrowsWithBackingOutException(lead + "../x", tnf);
+ assertThrowsWithBackingOutException(lead + "../../../x", tnf);
+ assertThrowsWithBackingOutException(lead + "../../../x", tnf);
+ assertThrowsWithBackingOutException("x://../../../foo", tnf);
+
+ {
+ final String name = lead + "foo\u0000";
+ try {
+ tnf.normalizeRootBasedName(name);
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ assertEquals(name, e.getTemplateName());
+
+ assertThat(e.getMalformednessDescription(), containsStringIgnoringCase("null character"));
+ }
+ }
+ }
+ }
+
+ // ".." and "."
+ assertEqualsOn23AndOn24("bar/foo", "foo", "bar/./../foo");
+
+ // Even number of leading ".."-s bug:
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "../../foo");
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "../../../../foo");
+
+ // ".." and "*"
+ assertEqualsOn23AndOn24("a/b/foo", "a/*/foo", "a/b/*/../foo");
+ //
+ assertEqualsOn23AndOn24("a/foo", "foo", "a/b/*/../../foo");
+ //
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "a/b/*/../../../foo");
+ //
+ assertEqualsOn23AndOn24("a/b/*/foo", "a/*/foo", "a/b/*/*/../foo");
+ //
+ assertEqualsOn23AndOn24("a/b/*/c/foo", "a/b/*/foo", "a/b/*/c/*/../foo");
+ //
+ assertEqualsOn23AndOn24("a/b/*/c/foo", "a/b/*/foo", "a/b/*/c/d/*/../../foo");
+ //
+ assertEqualsOn23AndOn24("a/*//b/*/c/foo", "a/*/b/*/foo", "a/*//b/*/c/d/*/../../foo");
+ //
+ assertEqualsOn23AndOn24("*", "", "a/../*");
+ //
+ assertEqualsOn23AndOn24("*/", "", "a/../*/");
+
+ // ".." and "scheme"
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("x:/foo", "x://../foo");
+ //
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "x://../../foo");
+ //
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("x:../foo", "x:../foo");
+ //
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "x:../../foo");
+
+ // Tricky cases with terminating "/":
+ assertEqualsOn23AndOn24("/", "", "/");
+ // Terminating "/.." (produces terminating "/"):
+ assertEqualsOn23AndOn24("foo/bar/..", "foo/", "foo/bar/..");
+ // Terminating "/." (produces terminating "/"):
+ assertEqualsOn23AndOn24("foo/bar/.", "foo/bar/", "foo/bar/.");
+
+ // Lonely "."
+ assertEqualsOn23AndOn24(".", "", ".");
+ // Lonely ".."
+ assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("..", "..");
+ // Lonely "*"
+
+ // Eliminating redundant "//":
+ assertEqualsOn23AndOn24("foo//bar", "foo/bar", "foo//bar");
+ //
+ assertEqualsOn23AndOn24("///foo//bar///baaz////wombat", "foo/bar/baaz/wombat", "////foo//bar///baaz////wombat");
+ //
+ assertEqualsOn23AndOn24("scheme://foo", "scheme://foo", "scheme://foo");
+ //
+ assertEqualsOn23AndOn24("scheme://foo//x/y", "scheme://foo/x/y", "scheme://foo//x/y");
+ //
+ assertEqualsOn23AndOn24("scheme:///foo", "scheme://foo", "scheme:///foo");
+ //
+ assertEqualsOn23AndOn24("scheme:////foo", "scheme://foo", "scheme:////foo");
+
+ // Eliminating redundant "*"-s:
+ assertEqualsOn23AndOn24("a/*/*/b", "a/*/b", "a/*/*/b");
+ //
+ assertEqualsOn23AndOn24("a/*/*/*/b", "a/*/b", "a/*/*/*/b");
+ //
+ assertEqualsOn23AndOn24("*/*/b", "b", "*/*/b");
+ //
+ assertEqualsOn23AndOn24("*/*/b", "b", "/*/*/b");
+ //
+ assertEqualsOn23AndOn24("b/*/*", "b/*", "b/*/*");
+ //
+ assertEqualsOn23AndOn24("b/*/*/*", "b/*", "b/*/*/*");
+ //
+ assertEqualsOn23AndOn24("*/a/*/b/*/*/c", "a/*/b/*/c", "*/a/*/b/*/*/c");
+
+ // New kind of scheme handling:
+
+ assertEquals("s:a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:a/b"));
+ assertEquals("s:a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:/a/b"));
+ assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s://a/b"));
+ assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:///a/b"));
+ assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:////a/b"));
+
+ // Illegal use a of ":":
+ assertNormRBNameThrowsColonExceptionOn24("a/b:c/d");
+ assertNormRBNameThrowsColonExceptionOn24("a/b:/..");
+ }
+
+ @Test
+ public void assertBackslashNotSpecialWith23() throws IOException {
+ MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
+ tl.putTextTemplate("foo\\bar.ftl", "");
+
+ Configuration cfg = new TestConfigurationBuilder().templateLoader(tl).build();
+
+ {
+ final String name = "foo\\bar.ftl";
+
+ Template t = cfg.getTemplate(name, Locale.US);
+ assertEquals(name, t.getLookupName());
+ assertEquals(name, t.getSourceName());
+ assertEquals(
+ ImmutableList.of(
+ "foo\\bar_en_US.ftl",
+ "foo\\bar_en.ftl",
+ name),
+ tl.getLoadNames());
+ tl.clearEvents();
+ }
+
+ try {
+ cfg.getTemplate("foo\\missing.ftl", Locale.US);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals("foo\\missing.ftl", e.getTemplateName());
+ assertEquals(
+ ImmutableList.of(
+ "foo\\missing_en_US.ftl",
+ "foo\\missing_en.ftl",
+ "foo\\missing.ftl"),
+ tl.getLoadNames());
+ tl.clearEvents();
+ cfg.clearTemplateCache();
+ }
+
+ {
+ final String name = "foo/bar\\..\\bar.ftl";
+ try {
+ cfg.getTemplate(name, Locale.US);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertEquals(name, e.getTemplateName());
+ }
+ }
+
+ }
+
+ @Test
+ public void assertBackslashNotAllowed() throws IOException {
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateLoader(new ByteArrayTemplateLoader())
+ .templateNameFormat(DefaultTemplateNameFormat.INSTANCE)
+ .build();
+ try {
+ cfg.getTemplate("././foo\\bar.ftl", Locale.US);
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("backslash"));
+ }
+
+ }
+
+ private void assertEqualsOn23AndOn24(String expected23, String expected24, String name)
+ throws MalformedTemplateNameException {
+ assertEquals(expected23, DefaultTemplateNameFormatFM2.INSTANCE.normalizeRootBasedName(name));
+ assertEquals(expected24, DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName(name));
+ }
+
+ private void assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24(final String expected23, final String name)
+ throws MalformedTemplateNameException {
+ assertEquals(expected23, DefaultTemplateNameFormatFM2.INSTANCE.normalizeRootBasedName(name));
+ assertThrowsWithBackingOutException(name, DefaultTemplateNameFormat.INSTANCE);
+ }
+
+ private void assertThrowsWithBackingOutException(final String name, final TemplateNameFormat tnf) {
+ try {
+ tnf.normalizeRootBasedName(name);
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ assertEquals(name, e.getTemplateName());
+ assertBackingOutFromRootException(e);
+ }
+ }
+
+ private void assertNormRBNameThrowsColonExceptionOn24(final String name) throws MalformedTemplateNameException {
+ try {
+ DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName(name);
+ fail();
+ } catch (MalformedTemplateNameException e) {
+ assertEquals(name, e.getTemplateName());
+ assertColonException(e);
+ }
+ }
+
+ private void assertBackingOutFromRootException(MalformedTemplateNameException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("backing out"));
+ }
+
+ private void assertColonException(MalformedTemplateNameException e) {
+ assertThat(e.getMessage(), containsString("':'"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
new file mode 100644
index 0000000..51273c0
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.core.templateresolver;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class TemplateSourceMatcherTest {
+
+ @Test
+ public void testPathGlobMatcher() throws IOException {
+ PathGlobMatcher m = new PathGlobMatcher("**/a/?.ftl");
+ assertTrue(m.matches("a/b.ftl", "dummy"));
+ assertTrue(m.matches("x/a/c.ftl", "dummy"));
+ assertFalse(m.matches("a/b.Ftl", "dummy"));
+ assertFalse(m.matches("b.ftl", "dummy"));
+ assertFalse(m.matches("a/bc.ftl", "dummy"));
+
+ m = new PathGlobMatcher("**/a/?.ftl").caseInsensitive(true);
+ assertTrue(m.matches("A/B.FTL", "dummy"));
+ m.setCaseInsensitive(false);
+ assertFalse(m.matches("A/B.FTL", "dummy"));
+
+ try {
+ new PathGlobMatcher("/b.ftl");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testFileNameGlobMatcher() throws IOException {
+ FileNameGlobMatcher m = new FileNameGlobMatcher("a*.ftl");
+ assertTrue(m.matches("ab.ftl", "dummy"));
+ assertTrue(m.matches("dir/ab.ftl", "dummy"));
+ assertTrue(m.matches("/dir/dir/ab.ftl", "dummy"));
+ assertFalse(m.matches("Ab.ftl", "dummy"));
+ assertFalse(m.matches("bb.ftl", "dummy"));
+ assertFalse(m.matches("ab.ftl/x", "dummy"));
+
+ m = new FileNameGlobMatcher("a*.ftl").caseInsensitive(true);
+ assertTrue(m.matches("AB.FTL", "dummy"));
+ m.setCaseInsensitive(false);
+ assertFalse(m.matches("AB.FTL", "dummy"));
+
+ m = new FileNameGlobMatcher("\u00E1*.ftl").caseInsensitive(true);
+ assertTrue(m.matches("\u00C1b.ftl", "dummy"));
+
+ try {
+ new FileNameGlobMatcher("dir/a*.ftl");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testFileExtensionMatcher() throws IOException {
+ FileExtensionMatcher m = new FileExtensionMatcher("ftlx");
+ assertTrue(m.matches("a.ftlx", "dummy"));
+ assertTrue(m.matches(".ftlx", "dummy"));
+ assertTrue(m.matches("b/a.b.ftlx", "dummy"));
+ assertTrue(m.matches("b/a.ftlx", "dummy"));
+ assertTrue(m.matches("c.b/a.ftlx", "dummy"));
+ assertFalse(m.matches("a.ftl", "dummy"));
+ assertFalse(m.matches("ftlx", "dummy"));
+ assertFalse(m.matches("b.ftlx/a.ftl", "dummy"));
+
+ assertTrue(m.isCaseInsensitive());
+ assertTrue(m.matches("a.fTlX", "dummy"));
+ m.setCaseInsensitive(false);
+ assertFalse(m.matches("a.fTlX", "dummy"));
+ assertTrue(m.matches("A.ftlx", "dummy"));
+
+ m = new FileExtensionMatcher("");
+ assertTrue(m.matches("a.", "dummy"));
+ assertTrue(m.matches(".", "dummy"));
+ assertFalse(m.matches("a", "dummy"));
+ assertFalse(m.matches("", "dummy"));
+ assertFalse(m.matches("a.x", "dummy"));
+
+ m = new FileExtensionMatcher("html.t");
+ assertTrue(m.matches("a.html.t", "dummy"));
+ assertFalse(m.matches("a.xhtml.t", "dummy"));
+ assertFalse(m.matches("a.html", "dummy"));
+ assertFalse(m.matches("a.t", "dummy"));
+
+ try {
+ new FileExtensionMatcher("*.ftlx");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ new FileExtensionMatcher("ftl?");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ new FileExtensionMatcher(".ftlx");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ new FileExtensionMatcher("dir/a.ftl");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testPathRegexMatcher() throws IOException {
+ PathRegexMatcher m = new PathRegexMatcher("a/[a-z]+\\.ftl");
+ assertTrue(m.matches("a/b.ftl", "dummy"));
+ assertTrue(m.matches("a/abc.ftl", "dummy"));
+ assertFalse(m.matches("b.ftl", "dummy"));
+ assertFalse(m.matches("b/b.ftl", "dummy"));
+
+ try {
+ new PathRegexMatcher("/b.ftl");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testAndMatcher() throws IOException {
+ AndMatcher m = new AndMatcher(new PathGlobMatcher("a*.*"), new PathGlobMatcher("*.t"));
+ assertTrue(m.matches("ab.t", "dummy"));
+ assertFalse(m.matches("bc.t", "dummy"));
+ assertFalse(m.matches("ab.ftl", "dummy"));
+
+ try {
+ new AndMatcher();
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testOrMatcher() throws IOException {
+ OrMatcher m = new OrMatcher(new PathGlobMatcher("a*.*"), new PathGlobMatcher("*.t"));
+ assertTrue(m.matches("ab.t", "dummy"));
+ assertTrue(m.matches("bc.t", "dummy"));
+ assertTrue(m.matches("ab.ftl", "dummy"));
+ assertFalse(m.matches("bc.ftl", "dummy"));
+
+ try {
+ new OrMatcher();
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testNotMatcher() throws IOException {
+ NotMatcher m = new NotMatcher(new PathGlobMatcher("a*.*"));
+ assertFalse(m.matches("ab.t", "dummy"));
+ assertTrue(m.matches("bc.t", "dummy"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
new file mode 100644
index 0000000..1d69dd8
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
@@ -0,0 +1,129 @@
+/*
+ * 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.core.userpkg;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
+import org.apache.freemarker.core.valueformat.UnparsableValueException;
+
+public class AppMetaTemplateDateFormatFactory extends TemplateDateFormatFactory {
+
+ public static final AppMetaTemplateDateFormatFactory INSTANCE = new AppMetaTemplateDateFormatFactory();
+
+ private AppMetaTemplateDateFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
+ Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return AppMetaTemplateDateFormat.INSTANCE;
+ }
+
+ private static class AppMetaTemplateDateFormat extends TemplateDateFormat {
+
+ private static final AppMetaTemplateDateFormat INSTANCE = new AppMetaTemplateDateFormat();
+
+ private AppMetaTemplateDateFormat() { }
+
+ @Override
+ public String formatToPlainText(TemplateDateModel dateModel)
+ throws UnformattableValueException, TemplateModelException {
+ String result = String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
+ if (dateModel instanceof AppMetaTemplateDateModel) {
+ result += "/" + ((AppMetaTemplateDateModel) dateModel).getAppMeta();
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public boolean isTimeZoneBound() {
+ return false;
+ }
+
+ @Override
+ public Object parse(String s, int dateType) throws UnparsableValueException {
+ int slashIdx = s.indexOf('/');
+ try {
+ if (slashIdx != -1) {
+ return new AppMetaTemplateDateModel(
+ new Date(Long.parseLong(s.substring(0, slashIdx))),
+ dateType,
+ s.substring(slashIdx +1));
+ } else {
+ return new Date(Long.parseLong(s));
+ }
+ } catch (NumberFormatException e) {
+ throw new UnparsableValueException("Malformed long");
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "millis since the epoch";
+ }
+
+ }
+
+ public static class AppMetaTemplateDateModel implements TemplateDateModel {
+
+ private final Date date;
+ private final int dateType;
+ private final String appMeta;
+
+ public AppMetaTemplateDateModel(Date date, int dateType, String appMeta) {
+ this.date = date;
+ this.dateType = dateType;
+ this.appMeta = appMeta;
+ }
+
+ @Override
+ public Date getAsDate() throws TemplateModelException {
+ return date;
+ }
+
+ @Override
+ public int getDateType() {
+ return dateType;
+ }
+
+ public String getAppMeta() {
+ return appMeta;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java
new file mode 100644
index 0000000..e5def77
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.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.core.userpkg;
+
+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.util._NumberUtil;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+
+/**
+ * Shows a number in base N number system. Can only format numbers that fit into an {@code int},
+ * however, optionally you can specify a fallback format. This format has one required parameter,
+ * the numerical system base. That can be optionally followed by "|" and a fallback format.
+ */
+public class BaseNTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
+
+ public static final BaseNTemplateNumberFormatFactory INSTANCE
+ = new BaseNTemplateNumberFormatFactory();
+
+ private BaseNTemplateNumberFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateNumberFormat get(String params, Locale locale, Environment env)
+ throws InvalidFormatParametersException {
+ TemplateNumberFormat fallbackFormat;
+ {
+ int barIdx = params.indexOf('|');
+ if (barIdx != -1) {
+ String fallbackFormatStr = params.substring(barIdx + 1);
+ params = params.substring(0, barIdx);
+ try {
+ fallbackFormat = env.getTemplateNumberFormat(fallbackFormatStr, locale);
+ } catch (TemplateValueFormatException e) {
+ throw new InvalidFormatParametersException(
+ "Couldn't get the fallback number format (specified after the \"|\"), "
+ + _StringUtil.jQuote(fallbackFormatStr) + ". Reason: " + e.getMessage(),
+ e);
+ }
+ } else {
+ fallbackFormat = null;
+ }
+ }
+
+ int base;
+ try {
+ base = Integer.parseInt(params);
+ } catch (NumberFormatException e) {
+ if (params.length() == 0) {
+ throw new InvalidFormatParametersException(
+ "A format parameter is required to specify the numerical system base.");
+ }
+ throw new InvalidFormatParametersException(
+ "The format paramter must be an integer, but was (shown quoted): "
+ + _StringUtil.jQuote(params));
+ }
+ if (base < 2) {
+ throw new InvalidFormatParametersException("A base must be at least 2.");
+ }
+ return new BaseNTemplateNumberFormat(base, fallbackFormat);
+ }
+
+ private static class BaseNTemplateNumberFormat extends TemplateNumberFormat {
+
+ private final int base;
+ private final TemplateNumberFormat fallbackFormat;
+
+ private BaseNTemplateNumberFormat(int base, TemplateNumberFormat fallbackFormat) {
+ this.base = base;
+ this.fallbackFormat = fallbackFormat;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateNumberModel numberModel)
+ throws TemplateModelException, TemplateValueFormatException {
+ Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
+ try {
+ return Integer.toString(_NumberUtil.toIntExact(n), base);
+ } catch (ArithmeticException e) {
+ if (fallbackFormat == null) {
+ throw new UnformattableValueException(
+ n + " doesn't fit into an int, and there was no fallback format "
+ + "specified.");
+ } else {
+ return fallbackFormat.formatToPlainText(numberModel);
+ }
+ }
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "base " + base;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
new file mode 100644
index 0000000..f570a66
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
@@ -0,0 +1,72 @@
+/*
+ * 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.core.userpkg;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
+import org.apache.freemarker.core.util._StringUtil;
+
+/**
+ * Represents the HTML output format.
+ *
+ * @since 2.3.24
+ */
+public final class CustomHTMLOutputFormat extends CommonMarkupOutputFormat<CustomTemplateHTMLModel> {
+
+ public static final CustomHTMLOutputFormat INSTANCE = new CustomHTMLOutputFormat();
+
+ private CustomHTMLOutputFormat() {
+ // Only to decrease visibility
+ }
+
+ @Override
+ public String getName() {
+ return "HTML";
+ }
+
+ @Override
+ public String getMimeType() {
+ return "text/html";
+ }
+
+ @Override
+ public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
+ // This is lazy - don't do it in reality.
+ out.write(escapePlainText(textToEsc));
+ }
+
+ @Override
+ public String escapePlainText(String plainTextContent) {
+ return _StringUtil.XHTMLEnc(plainTextContent.replace('x', 'X'));
+ }
+
+ @Override
+ public boolean isLegacyBuiltInBypassed(String builtInName) {
+ return builtInName.equals("html") || builtInName.equals("xml") || builtInName.equals("xhtml");
+ }
+
+ @Override
+ protected CustomTemplateHTMLModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) {
+ return new CustomTemplateHTMLModel(plainTextContent, markupContent);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java
new file mode 100644
index 0000000..4cc67be
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.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.core.userpkg;
+
+import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
+
+public final class CustomTemplateHTMLModel extends CommonTemplateMarkupOutputModel<CustomTemplateHTMLModel> {
+
+ CustomTemplateHTMLModel(String plainTextContent, String markupContent) {
+ super(plainTextContent, markupContent);
+ }
+
+ @Override
+ public CustomHTMLOutputFormat getOutputFormat() {
+ return CustomHTMLOutputFormat.INSTANCE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
new file mode 100644
index 0000000..f368969
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.userpkg;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
+
+public class DummyOutputFormat extends CommonMarkupOutputFormat<TemplateDummyOutputModel> {
+
+ public static final DummyOutputFormat INSTANCE = new DummyOutputFormat();
+
+ private DummyOutputFormat() {
+ // hide
+ }
+
+ @Override
+ public String getName() {
+ return "dummy";
+ }
+
+ @Override
+ public String getMimeType() {
+ return "text/dummy";
+ }
+
+ @Override
+ public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
+ out.write(escapePlainText(textToEsc));
+ }
+
+ @Override
+ public String escapePlainText(String plainTextContent) {
+ return plainTextContent.replaceAll("(\\.|\\\\)", "\\\\$1");
+ }
+
+ @Override
+ public boolean isLegacyBuiltInBypassed(String builtInName) {
+ return false;
+ }
+
+ @Override
+ protected TemplateDummyOutputModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) {
+ return new TemplateDummyOutputModel(plainTextContent, markupContent);
+ }
+
+}
\ 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/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
new file mode 100644
index 0000000..8799eef
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
@@ -0,0 +1,102 @@
+/*
+ * 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.core.userpkg;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
+import org.apache.freemarker.core.valueformat.UnparsableValueException;
+
+public class EpochMillisDivTemplateDateFormatFactory extends TemplateDateFormatFactory {
+
+ public static final EpochMillisDivTemplateDateFormatFactory INSTANCE = new EpochMillisDivTemplateDateFormatFactory();
+
+ private EpochMillisDivTemplateDateFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
+ Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
+ int divisor;
+ try {
+ divisor = Integer.parseInt(params);
+ } catch (NumberFormatException e) {
+ if (params.length() == 0) {
+ throw new InvalidFormatParametersException(
+ "A format parameter is required, which specifies the divisor.");
+ }
+ throw new InvalidFormatParametersException(
+ "The format paramter must be an integer, but was (shown quoted): " + _StringUtil.jQuote(params));
+ }
+ return new EpochMillisDivTemplateDateFormat(divisor);
+ }
+
+ private static class EpochMillisDivTemplateDateFormat extends TemplateDateFormat {
+
+ private final int divisor;
+
+ private EpochMillisDivTemplateDateFormat(int divisor) {
+ this.divisor = divisor;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateDateModel dateModel)
+ throws UnformattableValueException, TemplateModelException {
+ return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() / divisor);
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public boolean isTimeZoneBound() {
+ return false;
+ }
+
+ @Override
+ public Date parse(String s, int dateType) throws UnparsableValueException {
+ try {
+ return new Date(Long.parseLong(s));
+ } catch (NumberFormatException e) {
+ throw new UnparsableValueException("Malformed long");
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "millis since the epoch";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
new file mode 100644
index 0000000..9f27095
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
@@ -0,0 +1,92 @@
+/*
+ * 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.core.userpkg;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+import org.apache.freemarker.core.valueformat.UnparsableValueException;
+
+public class EpochMillisTemplateDateFormatFactory extends TemplateDateFormatFactory {
+
+ public static final EpochMillisTemplateDateFormatFactory INSTANCE
+ = new EpochMillisTemplateDateFormatFactory();
+
+ private EpochMillisTemplateDateFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateDateFormat get(String params, int dateType,
+ Locale locale, TimeZone timeZone, boolean zonelessInput,
+ Environment env)
+ throws InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return EpochMillisTemplateDateFormat.INSTANCE;
+ }
+
+ private static class EpochMillisTemplateDateFormat extends TemplateDateFormat {
+
+ private static final EpochMillisTemplateDateFormat INSTANCE
+ = new EpochMillisTemplateDateFormat();
+
+ private EpochMillisTemplateDateFormat() { }
+
+ @Override
+ public String formatToPlainText(TemplateDateModel dateModel)
+ throws UnformattableValueException, TemplateModelException {
+ return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public boolean isTimeZoneBound() {
+ return false;
+ }
+
+ @Override
+ public Date parse(String s, int dateType) throws UnparsableValueException {
+ try {
+ return new Date(Long.parseLong(s));
+ } catch (NumberFormatException e) {
+ throw new UnparsableValueException("Malformed long");
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "millis since the epoch";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
new file mode 100644
index 0000000..357034c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
@@ -0,0 +1,114 @@
+/*
+ * 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.core.userpkg;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.util._DateUtil;
+import org.apache.freemarker.core.util._DateUtil.CalendarFieldsToDateConverter;
+import org.apache.freemarker.core.util._DateUtil.DateParseException;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
+import org.apache.freemarker.core.valueformat.UnparsableValueException;
+
+public class HTMLISOTemplateDateFormatFactory extends TemplateDateFormatFactory {
+
+ public static final HTMLISOTemplateDateFormatFactory INSTANCE = new HTMLISOTemplateDateFormatFactory();
+
+ private HTMLISOTemplateDateFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
+ Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return HTMLISOTemplateDateFormat.INSTANCE;
+ }
+
+ private static class HTMLISOTemplateDateFormat extends TemplateDateFormat {
+
+ private static final HTMLISOTemplateDateFormat INSTANCE = new HTMLISOTemplateDateFormat();
+
+ private _DateUtil.TrivialDateToISO8601CalendarFactory calendarFactory;
+
+ private CalendarFieldsToDateConverter calToDateConverter;
+
+ private HTMLISOTemplateDateFormat() { }
+
+ @Override
+ public String formatToPlainText(TemplateDateModel dateModel)
+ throws UnformattableValueException, TemplateModelException {
+ if (calendarFactory == null) {
+ calendarFactory = new _DateUtil.TrivialDateToISO8601CalendarFactory();
+ }
+ return _DateUtil.dateToISO8601String(
+ TemplateFormatUtil.getNonNullDate(dateModel),
+ true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC,
+ calendarFactory);
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public boolean isTimeZoneBound() {
+ return false;
+ }
+
+ @Override
+ public Date parse(String s, int dateType) throws UnparsableValueException {
+ try {
+ if (calToDateConverter == null) {
+ calToDateConverter = new _DateUtil.TrivialCalendarFieldsToDateConverter();
+ }
+ return _DateUtil.parseISO8601DateTime(s, _DateUtil.UTC, calToDateConverter);
+ } catch (DateParseException e) {
+ throw new UnparsableValueException("Malformed ISO date-time", e);
+ }
+ }
+
+ @Override
+ public Object format(TemplateDateModel dateModel) throws TemplateValueFormatException, TemplateModelException {
+ return HTMLOutputFormat.INSTANCE.fromMarkup(
+ formatToPlainText(dateModel).replace("T", "<span class='T'>T</span>"));
+ }
+
+ @Override
+ public String getDescription() {
+ return "ISO UTC HTML";
+ }
+
+ }
+
+}
+
\ 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/core/userpkg/HexTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java
new file mode 100644
index 0000000..6d72c20
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java
@@ -0,0 +1,77 @@
+/*
+ * 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.core.userpkg;
+
+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.util._NumberUtil;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+
+public class HexTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
+
+ public static final HexTemplateNumberFormatFactory INSTANCE = new HexTemplateNumberFormatFactory();
+
+ private HexTemplateNumberFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateNumberFormat get(String params, Locale locale, Environment env)
+ throws InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return HexTemplateNumberFormat.INSTANCE;
+ }
+
+ private static class HexTemplateNumberFormat extends TemplateNumberFormat {
+
+ private static final HexTemplateNumberFormat INSTANCE = new HexTemplateNumberFormat();
+
+ private HexTemplateNumberFormat() { }
+
+ @Override
+ public String formatToPlainText(TemplateNumberModel numberModel)
+ throws UnformattableValueException, TemplateModelException {
+ Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
+ try {
+ return Integer.toHexString(_NumberUtil.toIntExact(n));
+ } catch (ArithmeticException e) {
+ throw new UnformattableValueException(n + " doesn't fit into an int");
+ }
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "hexadecimal int";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
new file mode 100644
index 0000000..42b0401
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.core.userpkg;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
+import org.apache.freemarker.core.valueformat.UnparsableValueException;
+
+public class LocAndTZSensitiveTemplateDateFormatFactory extends TemplateDateFormatFactory {
+
+ public static final LocAndTZSensitiveTemplateDateFormatFactory INSTANCE = new LocAndTZSensitiveTemplateDateFormatFactory();
+
+ private LocAndTZSensitiveTemplateDateFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
+ Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return new LocAndTZSensitiveTemplateDateFormat(locale, timeZone);
+ }
+
+ private static class LocAndTZSensitiveTemplateDateFormat extends TemplateDateFormat {
+
+ private final Locale locale;
+ private final TimeZone timeZone;
+
+ public LocAndTZSensitiveTemplateDateFormat(Locale locale, TimeZone timeZone) {
+ this.locale = locale;
+ this.timeZone = timeZone;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateDateModel dateModel)
+ throws UnformattableValueException, TemplateModelException {
+ return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() + "@" + locale + ":" + timeZone.getID());
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return true;
+ }
+
+ @Override
+ public boolean isTimeZoneBound() {
+ return true;
+ }
+
+ @Override
+ public Date parse(String s, int dateType) throws UnparsableValueException {
+ try {
+ int atIdx = s.indexOf("@");
+ if (atIdx == -1) {
+ throw new UnparsableValueException("Missing @");
+ }
+ return new Date(Long.parseLong(s.substring(0, atIdx)));
+ } catch (NumberFormatException e) {
+ throw new UnparsableValueException("Malformed long");
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "millis since the epoch";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
new file mode 100644
index 0000000..dc3dae0
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
@@ -0,0 +1,78 @@
+/*
+ * 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.core.userpkg;
+
+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.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+
+public class LocaleSensitiveTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
+
+ public static final LocaleSensitiveTemplateNumberFormatFactory INSTANCE = new LocaleSensitiveTemplateNumberFormatFactory();
+
+ private LocaleSensitiveTemplateNumberFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateNumberFormat get(String params, Locale locale, Environment env)
+ throws InvalidFormatParametersException {
+ TemplateFormatUtil.checkHasNoParameters(params);
+ return new LocaleSensitiveTemplateNumberFormat(locale);
+ }
+
+ private static class LocaleSensitiveTemplateNumberFormat extends TemplateNumberFormat {
+
+ private final Locale locale;
+
+ private LocaleSensitiveTemplateNumberFormat(Locale locale) {
+ this.locale = locale;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateNumberModel numberModel)
+ throws UnformattableValueException, TemplateModelException {
+ Number n = numberModel.getAsNumber();
+ try {
+ return n + "_" + locale;
+ } catch (ArithmeticException e) {
+ throw new UnformattableValueException(n + " doesn't fit into an int");
+ }
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return true;
+ }
+
+ @Override
+ public String getDescription() {
+ return "test locale sensitive";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
new file mode 100644
index 0000000..f3ebc72
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.userpkg;
+
+class PackageVisibleAll {
+
+ PackageVisibleAll() {}
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
new file mode 100644
index 0000000..53a89d4
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.userpkg;
+
+class PackageVisibleAllWithBuilder {
+
+ PackageVisibleAllWithBuilder() {}
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
new file mode 100644
index 0000000..510ecc2
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
@@ -0,0 +1,28 @@
+/*
+ * 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.core.userpkg;
+
+public class PackageVisibleAllWithBuilderBuilder {
+
+ public PackageVisibleAllWithBuilder build() {
+ return new PackageVisibleAllWithBuilder();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
new file mode 100644
index 0000000..836e80d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
@@ -0,0 +1,27 @@
+/*
+ * 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.core.userpkg;
+
+class PackageVisibleWithPublicConstructor {
+
+ public PackageVisibleWithPublicConstructor() {
+ }
+
+}
[41/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
new file mode 100644
index 0000000..ef15dae
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.core.model.impl;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+
+import junit.framework.TestCase;
+
+public class CommonSupertypeForUnwrappingHintTest extends TestCase {
+
+ final OverloadedMethodsSubset oms = new DummyOverloadedMethodsSubset();
+
+ public CommonSupertypeForUnwrappingHintTest(String name) {
+ super(name);
+ }
+
+ public void testInterfaces() {
+ assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(String.class, Number.class));
+ assertEquals(C1I1.class, oms.getCommonSupertypeForUnwrappingHint(C2ExtC1I1.class, C3ExtC1I1.class));
+ assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, C4I1I2.class));
+ assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, C5I1.class));
+ assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, I1.class));
+ assertEquals(I2.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, I2.class));
+ assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(I1I2.class, I1.class));
+ assertEquals(I2.class, oms.getCommonSupertypeForUnwrappingHint(I1I2.class, I2.class));
+ assertEquals(CharSequence.class, oms.getCommonSupertypeForUnwrappingHint(String.class, StringBuilder.class));
+ assertEquals(C6.class, oms.getCommonSupertypeForUnwrappingHint(C7ExtC6I1.class, C8ExtC6I1.class));
+ }
+
+ public void testArrayAndOther() {
+ testArrayAndOther(oms);
+ }
+
+ /** These will be the same with oms and buggy: */
+ private void testArrayAndOther(OverloadedMethodsSubset oms) {
+ assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, String.class));
+ assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, String.class));
+
+ assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, List.class));
+ assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, List.class));
+
+ assertEquals(int[].class, oms.getCommonSupertypeForUnwrappingHint(int[].class, int[].class));
+ assertEquals(Object[].class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, Object[].class));
+ }
+
+ public void testArrayAndDifferentArray() {
+ assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, Object[].class));
+ assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, long[].class));
+ }
+
+ public void testPrimitive() {
+ assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(int.class, Integer.class));
+ assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, int.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(int.class, Long.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Long.class, int.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, long.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(long.class, Integer.class));
+ assertEquals(Boolean.class, oms.getCommonSupertypeForUnwrappingHint(boolean.class, Boolean.class));
+ assertEquals(Boolean.class, oms.getCommonSupertypeForUnwrappingHint(Boolean.class, boolean.class));
+ assertEquals(Character.class, oms.getCommonSupertypeForUnwrappingHint(char.class, Character.class));
+ assertEquals(Character.class, oms.getCommonSupertypeForUnwrappingHint(Character.class, char.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(int.class, short.class));
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(short.class, int.class));
+ }
+
+ public void testMisc() {
+ assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Long.class, Integer.class));
+ assertEquals(char.class, oms.getCommonSupertypeForUnwrappingHint(char.class, char.class));
+ assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, Integer.class));
+ assertEquals(String.class, oms.getCommonSupertypeForUnwrappingHint(String.class, String.class));
+ }
+
+ static interface I1 { };
+ static class C1I1 implements I1 { };
+ static class C2ExtC1I1 extends C1I1 { };
+ static class C3ExtC1I1 extends C1I1 { };
+ static interface I2 { };
+ static class C3I1I2 implements I1, I2 { };
+ static class C4I1I2 implements I1, I2 { };
+ static class C5I1 implements I1 { };
+ static interface I1I2 extends I1, I2 { };
+ static class C6 { };
+ static class C7ExtC6I1 extends C6 implements I1 { };
+ static class C8ExtC6I1 extends C6 implements I1 { };
+
+ private static class DummyOverloadedMethodsSubset extends OverloadedMethodsSubset {
+
+ DummyOverloadedMethodsSubset() {
+ super();
+ }
+
+ @Override
+ Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
+ return memberDesc.getParamTypes();
+ }
+
+ @Override
+ void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) {
+ // Do nothing
+ }
+
+ @Override
+ MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, DefaultObjectWrapper w) throws TemplateModelException {
+ throw new RuntimeException("Not implemented in this dummy.");
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
new file mode 100644
index 0000000..0ed6e7c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.model.impl;
+
+import org.apache.freemarker.core.Configuration;
+
+public class DefaultObjectWrapperDesc extends DefaultObjectWrapper {
+
+ public DefaultObjectWrapperDesc() {
+ super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .methodSorter(new AlphabeticalMethodSorter(true)), true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
new file mode 100644
index 0000000..eb2cda0
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.model.impl;
+
+import org.apache.freemarker.core.Configuration;
+
+public class DefaultObjectWrapperInc extends DefaultObjectWrapper {
+
+ public DefaultObjectWrapperInc() {
+ super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .methodSorter(new AlphabeticalMethodSorter(false)), true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
new file mode 100644
index 0000000..5c2f653
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import java.lang.ref.Reference;
+
+import org.apache.freemarker.core.Configuration;
+import org.junit.Test;
+
+public class DefaultObjectWrapperModelFactoryRegistrationTest {
+
+ @Test
+ public void introspectionSettingChanges() {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
+ .build();
+ ClassIntrospector ci1 = ow.getClassIntrospector();
+ checkRegisteredModelFactories(ci1, ow.getStaticModels(), ow.getEnumModels());
+ }
+
+ private void checkRegisteredModelFactories(ClassIntrospector ci, Object... expected) {
+ Object[] actualRefs = ci.getRegisteredModelFactoriesSnapshot();
+
+ scanActuals: for (Object actaulRef : actualRefs) {
+ Object actualItem = ((Reference) actaulRef).get();
+ for (Object expectedItem : expected) {
+ if (actualItem == expectedItem) {
+ continue scanActuals;
+ }
+ }
+ fail("Actual item " + actualItem + " is not among the expected items");
+ }
+
+ scanExpecteds: for (Object expectedItem : expected) {
+ for (Object ref : actualRefs) {
+ Object actualItem = ((Reference) ref).get();
+ if (actualItem == expectedItem) {
+ continue scanExpecteds;
+ }
+ }
+ fail("Expected item " + expectedItem + " is not among the actual items");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
new file mode 100644
index 0000000..d6f8177
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
@@ -0,0 +1,675 @@
+/*
+ * 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.core.model.impl;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.lang.ref.Reference;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Version;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.test.TestUtil;
+
+import junit.framework.TestCase;
+
+public class DefaultObjectWrapperSingletonsTest extends TestCase {
+
+ public DefaultObjectWrapperSingletonsTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ DefaultObjectWrapper.Builder.clearInstanceCache();
+ }
+
+ public void testBuilderEqualsAndHash() throws Exception {
+ assertEquals(Configuration.VERSION_3_0_0, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).getIncompatibleImprovements());
+ try {
+ new DefaultObjectWrapper.Builder(TestUtil.getClosestFutureVersion());
+ fail("Maybe you need to update this test for the new FreeMarker version");
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("upgrade"));
+ }
+
+ DefaultObjectWrapper.Builder builder1;
+ DefaultObjectWrapper.Builder builder2;
+
+ builder1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ assertEquals(builder1, builder2);
+
+ builder1.setExposeFields(true);
+ assertNotEquals(builder1, builder2);
+ assertNotEquals(builder1.hashCode(), builder2.hashCode());
+ builder2.setExposeFields(true);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ builder1.setExposureLevel(0);
+ assertNotEquals(builder1, builder2);
+ assertNotEquals(builder1.hashCode(), builder2.hashCode());
+ builder2.setExposureLevel(0);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ builder1.setExposureLevel(1);
+ assertNotEquals(builder1, builder2);
+ assertNotEquals(builder1.hashCode(), builder2.hashCode());
+ builder2.setExposureLevel(1);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ builder1.setDefaultDateType(TemplateDateModel.DATE);
+ assertNotEquals(builder1, builder2);
+ builder2.setDefaultDateType(TemplateDateModel.DATE);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ builder1.setStrict(true);
+ assertNotEquals(builder1, builder2);
+ assertNotEquals(builder1.hashCode(), builder2.hashCode());
+ builder2.setStrict(true);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ builder1.setUseModelCache(true);
+ assertNotEquals(builder1, builder2);
+ assertNotEquals(builder1.hashCode(), builder2.hashCode());
+ builder2.setUseModelCache(true);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ AlphabeticalMethodSorter ms = new AlphabeticalMethodSorter(true);
+ builder1.setMethodSorter(ms);
+ assertNotEquals(builder1, builder2);
+ builder2.setMethodSorter(ms);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+
+ MethodAppearanceFineTuner maft = new MethodAppearanceFineTuner() {
+ @Override
+ public void process(DecisionInput in, Decision out) { }
+ };
+ builder1.setMethodAppearanceFineTuner(maft);
+ assertNotEquals(builder1, builder2);
+ builder2.setMethodAppearanceFineTuner(maft);
+ assertEquals(builder1, builder2);
+ assertEquals(builder1.hashCode(), builder2.hashCode());
+ }
+
+ public void testDefaultObjectWrapperBuilderProducts() throws Exception {
+ List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
+
+ assertEquals(0, getDefaultObjectWrapperInstanceCacheSize());
+
+ {
+ DefaultObjectWrapper ow = getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, true);
+ assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
+ assertSame(ow.getClass(), DefaultObjectWrapper.class);
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ assertFalse(ow.isStrict());
+ assertTrue(ow.getUseModelCache());
+ assertEquals(TemplateDateModel.UNKNOWN, ow.getDefaultDateType());
+ assertSame(ow, ow.getOuterIdentity());
+ assertTrue(ow.isClassIntrospectionCacheRestricted());
+ assertNull(ow.getMethodAppearanceFineTuner());
+ assertNull(ow.getMethodSorter());
+
+ assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, true));
+ assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
+
+ hardReferences.add(ow);
+ }
+
+ {
+ DefaultObjectWrapper ow = getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, false);
+ assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
+ assertSame(ow.getClass(), DefaultObjectWrapper.class);
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ assertFalse(ow.getUseModelCache());
+
+ assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, false));
+
+ hardReferences.add(ow);
+ }
+
+ {
+ DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ factory.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
+ DefaultObjectWrapper ow1 = factory.build();
+ DefaultObjectWrapper ow2 = factory.build();
+ assertEquals(3, getDefaultObjectWrapperInstanceCacheSize());
+ assertSame(ow1, ow2);
+
+ assertSame(ow1.getClass(), DefaultObjectWrapper.class);
+ assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
+ assertEquals(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY, ow1.getExposureLevel());
+ assertFalse(ow1.isStrict());
+ assertEquals(TemplateDateModel.UNKNOWN, ow1.getDefaultDateType());
+ assertSame(ow1, ow1.getOuterIdentity());
+
+ hardReferences.add(ow1);
+ }
+
+ {
+ DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ factory.setExposeFields(true);
+ DefaultObjectWrapper ow1 = factory.build();
+ DefaultObjectWrapper ow2 = factory.build();
+ assertEquals(4, getDefaultObjectWrapperInstanceCacheSize());
+ assertSame(ow1, ow2);
+
+ assertSame(ow1.getClass(), DefaultObjectWrapper.class);
+ assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
+ assertTrue(ow1.isExposeFields());
+
+ hardReferences.add(ow1);
+ }
+
+ {
+ DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ factory.setStrict(true);
+ factory.setDefaultDateType(TemplateDateModel.DATETIME);
+ factory.setOuterIdentity(new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ DefaultObjectWrapper ow = factory.build();
+ assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
+ assertTrue(ow.isStrict());
+ assertEquals(TemplateDateModel.DATETIME, ow.getDefaultDateType());
+ assertSame(RestrictedObjectWrapper.class, ow.getOuterIdentity().getClass());
+
+ hardReferences.add(ow);
+ }
+
+ // Effect of reference and cache clearings:
+ {
+ DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
+ assertEquals(5, getDefaultObjectWrapperNonClearedInstanceCacheSize());
+
+ clearDefaultObjectWrapperInstanceCacheReferences(false);
+ assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
+ assertEquals(0, getDefaultObjectWrapperNonClearedInstanceCacheSize());
+
+ DefaultObjectWrapper bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertNotSame(bw1, bw2);
+ assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
+ assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
+
+ assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
+
+ clearDefaultObjectWrapperInstanceCacheReferences(true);
+ DefaultObjectWrapper bw3 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertNotSame(bw2, bw3);
+ assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
+ assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
+ }
+
+ {
+ DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ factory.setUseModelCache(true);
+ DefaultObjectWrapper ow = factory.build();
+ assertTrue(ow.getUseModelCache());
+ assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
+
+ hardReferences.add(ow);
+ }
+
+ assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
+ }
+
+ private DefaultObjectWrapper getDefaultObjectWrapperWithSetting(Version ici, boolean useModelCache) {
+ DefaultObjectWrapper.Builder f = new DefaultObjectWrapper.Builder(ici);
+ f.setUseModelCache(useModelCache);
+ return f.build();
+ }
+
+ public void testMultipleTCCLs() {
+ List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
+
+ assertEquals(0, getDefaultObjectWrapperInstanceCacheSize());
+
+ DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
+ hardReferences.add(bw1);
+
+ ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader();
+ // Doesn't mater what, just be different from oldTCCL:
+ ClassLoader newTCCL = oldTCCL == null ? getClass().getClassLoader() : null;
+
+ DefaultObjectWrapper bw2;
+ Thread.currentThread().setContextClassLoader(newTCCL);
+ try {
+ bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
+ hardReferences.add(bw2);
+
+ assertNotSame(bw1, bw2);
+ assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldTCCL);
+ }
+
+ assertSame(bw1, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
+
+ DefaultObjectWrapper bw3;
+ Thread.currentThread().setContextClassLoader(newTCCL);
+ try {
+ assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+
+ DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ bwb.setExposeFields(true);
+ bw3 = bwb.build();
+ assertEquals(3, getDefaultObjectWrapperInstanceCacheSize());
+ hardReferences.add(bw3);
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldTCCL);
+ }
+
+ {
+ DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ bwb.setExposeFields(true);
+ DefaultObjectWrapper bw4 = bwb.build();
+ assertEquals(4, getDefaultObjectWrapperInstanceCacheSize());
+ assertNotSame(bw3, bw4);
+ hardReferences.add(bw4);
+ }
+
+ assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
+ }
+
+ public void testClassInrospectorCache() throws TemplateModelException {
+ assertFalse(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .usePrivateCaches(true).build().isClassIntrospectionCacheRestricted());
+ assertTrue(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .build().isClassIntrospectionCacheRestricted());
+
+ ClassIntrospector.Builder.clearInstanceCache();
+ DefaultObjectWrapper.Builder.clearInstanceCache();
+ checkClassIntrospectorCacheSize(0);
+
+ List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
+ DefaultObjectWrapper.Builder builder;
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+
+ DefaultObjectWrapper bw1 = builder.build();
+ checkClassIntrospectorCacheSize(1);
+
+ builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_SAFE); // this was already set to this
+ builder.setUseModelCache(true); // this shouldn't matter for the introspection cache
+ DefaultObjectWrapper bw2 = builder.build();
+ checkClassIntrospectorCacheSize(1);
+
+ assertSame(bw2.getClassIntrospector(), bw1.getClassIntrospector());
+ assertNotSame(bw1, bw2);
+
+ // Wrapping tests:
+ assertFalse(exposesFields(bw1));
+ assertTrue(exposesProperties(bw1));
+ assertTrue(exposesMethods(bw1));
+ assertFalse(exposesUnsafe(bw1));
+ assertTrue(bw1.isClassIntrospectionCacheRestricted());
+ // Prevent introspection cache GC:
+ hardReferences.add(bw1);
+ hardReferences.add(bw2);
+ }
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder.setExposeFields(true);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(2);
+ // Wrapping tests:
+ assertTrue(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertTrue(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(3);
+ // Wrapping tests:
+ assertTrue(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertTrue(exposesMethods(ow));
+ assertTrue(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder.setExposeFields(false);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(4);
+ // Wrapping tests:
+ assertFalse(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertTrue(exposesMethods(ow));
+ assertTrue(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_NOTHING);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(5);
+ // Wrapping tests:
+ assertFalse(exposesFields(ow));
+ assertFalse(exposesProperties(ow));
+ assertFalse(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder.setExposeFields(true);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(6);
+ // Wrapping tests:
+ assertTrue(exposesFields(ow));
+ assertFalse(exposesProperties(ow));
+ assertFalse(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(7);
+ // Wrapping tests:
+ assertTrue(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertFalse(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder.setUseModelCache(true);
+ builder.setExposeFields(false);
+ builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
+
+ DefaultObjectWrapper bw1 = builder.build();
+ checkClassIntrospectorCacheSize(8);
+ ClassIntrospector ci1 = bw1.getClassIntrospector();
+
+ builder.setUseModelCache(false); // Shouldn't mater for the ClassIntrospector
+ DefaultObjectWrapper bw2 = builder.build();
+ ClassIntrospector ci2 = bw2.getClassIntrospector();
+ checkClassIntrospectorCacheSize(8);
+
+ assertSame(ci1, ci2);
+ assertNotSame(bw1, bw2);
+
+ // Wrapping tests:
+ assertFalse(exposesFields(bw1));
+ assertTrue(exposesProperties(bw1));
+ assertFalse(exposesMethods(bw1));
+ assertFalse(exposesUnsafe(bw1));
+
+ // Prevent introspection cache GC:
+ hardReferences.add(bw1);
+ hardReferences.add(bw2);
+ }
+
+ // The ClassInrospector cache couldn't become cleared in reality otherwise:
+ DefaultObjectWrapper.Builder.clearInstanceCache();
+
+ clearClassIntrospectorInstanceCacheReferences(false);
+ checkClassIntrospectorCacheSize(8);
+ assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
+
+ {
+ builder.setExposeFields(false);
+
+ DefaultObjectWrapper bw1 = builder.build();
+ checkClassIntrospectorCacheSize(8);
+ assertEquals(1, getClassIntrospectorNonClearedInstanceCacheSize());
+ ClassIntrospector ci1 = bw1.getClassIntrospector();
+
+ builder.setUseModelCache(true); // Shouldn't mater
+ DefaultObjectWrapper bw2 = builder.build();
+ ClassIntrospector ci2 = bw2.getClassIntrospector();
+
+ assertSame(ci1, ci2);
+ assertNotSame(bw1, bw2);
+
+ // Wrapping tests:
+ assertFalse(exposesFields(bw1));
+ assertTrue(exposesProperties(bw1));
+ assertFalse(exposesMethods(bw1));
+ assertFalse(exposesUnsafe(bw1));
+
+ // Prevent introspection cache GC:
+ hardReferences.add(bw1);
+ hardReferences.add(bw2);
+ }
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(8);
+ assertEquals(2, getClassIntrospectorNonClearedInstanceCacheSize());
+ // Wrapping tests:
+ assertFalse(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertTrue(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ clearClassIntrospectorInstanceCacheReferences(true);
+ checkClassIntrospectorCacheSize(8);
+ assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder.setExposeFields(true);
+ DefaultObjectWrapper ow = builder.build();
+ checkClassIntrospectorCacheSize(1);
+ // Wrapping tests:
+ assertTrue(exposesFields(ow));
+ assertTrue(exposesProperties(ow));
+ assertTrue(exposesMethods(ow));
+ assertFalse(exposesUnsafe(ow));
+ // Prevent introspection cache GC:
+ hardReferences.add(ow);
+ }
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
+ @Override
+ public void process(DecisionInput in, Decision out) {
+ }
+ }); // spoils ClassIntrospector() sharing
+
+ builder.setUseModelCache(false);
+ DefaultObjectWrapper bw1 = builder.build();
+ assertSame(bw1, builder.build());
+
+ builder.setUseModelCache(true);
+ DefaultObjectWrapper bw2 = builder.build();
+ checkClassIntrospectorCacheSize(1);
+ assertNotSame(bw1, bw2);
+ assertNotSame(bw1.getClassIntrospector(), bw2.getClassIntrospector());
+ assertTrue(bw1.isClassIntrospectionCacheRestricted());
+ assertTrue(bw2.isClassIntrospectionCacheRestricted());
+ }
+
+ {
+ builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ builder.setMethodAppearanceFineTuner(
+ GetlessMethodsAsPropertyGettersRule.INSTANCE); // doesn't spoils sharing
+
+ builder.setUseModelCache(false);
+ DefaultObjectWrapper bw1 = builder.build();
+ assertSame(bw1, builder.build());
+ checkClassIntrospectorCacheSize(2);
+
+ builder.setUseModelCache(true);
+ DefaultObjectWrapper bw2 = builder.build();
+ checkClassIntrospectorCacheSize(2);
+
+ assertNotSame(bw1, bw2);
+ assertSame(bw1.getClassIntrospector(), bw2.getClassIntrospector()); // !
+ assertTrue(bw2.isClassIntrospectionCacheRestricted());
+ }
+
+ assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
+ }
+
+ private void checkClassIntrospectorCacheSize(int expectedSize) {
+ assertEquals(expectedSize, getClassIntrospectorInstanceCacheSize());
+ }
+
+ public class C {
+
+ public String foo = "FOO";
+
+ public String getBar() {
+ return "BAR";
+ }
+
+ }
+
+ private boolean exposesFields(DefaultObjectWrapper ow) throws TemplateModelException {
+ TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
+ TemplateScalarModel r = (TemplateScalarModel) thm.get("foo");
+ if (r == null) return false;
+ assertEquals("FOO", r.getAsString());
+ return true;
+ }
+
+ private boolean exposesProperties(DefaultObjectWrapper ow) throws TemplateModelException {
+ TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
+ TemplateScalarModel r = (TemplateScalarModel) thm.get("bar");
+ if (r == null) return false;
+ assertEquals("BAR", r.getAsString());
+ return true;
+ }
+
+ private boolean exposesMethods(DefaultObjectWrapper ow) throws TemplateModelException {
+ TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
+ return thm.get("getBar") != null;
+ }
+
+ private boolean exposesUnsafe(DefaultObjectWrapper ow) throws TemplateModelException {
+ TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
+ return thm.get("wait") != null;
+ }
+
+ static int getClassIntrospectorInstanceCacheSize() {
+ Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ return instanceCache.size();
+ }
+ }
+
+ static int getClassIntrospectorNonClearedInstanceCacheSize() {
+ Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ int cnt = 0;
+ for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
+ if (((Reference) it.next()).get() != null) cnt++;
+ }
+ return cnt;
+ }
+ }
+
+ static void clearClassIntrospectorInstanceCacheReferences(boolean enqueue) {
+ Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
+ Reference ref = ((Reference) it.next());
+ ref.clear();
+ if (enqueue) {
+ ref.enqueue();
+ }
+ }
+ }
+ }
+
+ static int getDefaultObjectWrapperInstanceCacheSize() {
+ Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ int size = 0;
+ for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
+ size += ((Map) it1.next()).size();
+ }
+ return size;
+ }
+ }
+
+ static int getDefaultObjectWrapperNonClearedInstanceCacheSize() {
+ Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ int cnt = 0;
+ for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
+ Map tcclScope = (Map) it1.next();
+ for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
+ if (((Reference) it2.next()).get() != null) cnt++;
+ }
+ }
+ return cnt;
+ }
+ }
+
+ static void clearDefaultObjectWrapperInstanceCacheReferences(boolean enqueue) {
+ Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
+ synchronized (instanceCache) {
+ for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
+ Map tcclScope = (Map) it1.next();
+ for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
+ Reference ref = ((Reference) it2.next());
+ ref.clear();
+ if (enqueue) {
+ ref.enqueue();
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
new file mode 100644
index 0000000..6e9ae25
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
@@ -0,0 +1,901 @@
+/*
+ * 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.core.model.impl;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+
+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.Template;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.Version;
+import org.apache.freemarker.core._CoreAPI;
+import org.apache.freemarker.core.model.AdapterTemplateModel;
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateCollectionModelEx;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.TemplateModelWithAPISupport;
+import org.apache.freemarker.core.model.TemplateNodeModel;
+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.WrapperTemplateModel;
+import org.apache.freemarker.core.model.WrappingTemplateModel;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class DefaultObjectWrapperTest {
+
+ private final static DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .build();
+
+ // This will make sense if we will have multipe incompatibleImprovement versions.
+ @Test
+ public void testIncompatibleImprovementsVersionBreakPoints() throws Exception {
+ List<Version> expected = new ArrayList<>();
+ expected.add(Configuration.VERSION_3_0_0);
+
+ List<Version> actual = new ArrayList<>();
+ int i = _CoreAPI.VERSION_INT_3_0_0;
+ while (i <= Configuration.getVersion().intValue()) {
+ int major = i / 1000000;
+ int minor = i % 1000000 / 1000;
+ int micro = i % 1000;
+ final Version version = new Version(major, minor, micro);
+
+ final Version normalizedVersion = DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(version);
+ actual.add(normalizedVersion);
+
+ final DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(version);
+ assertEquals(normalizedVersion, builder.getIncompatibleImprovements());
+ assertEquals(normalizedVersion, builder.build().getIncompatibleImprovements());
+
+ i++;
+ }
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testIncompatibleImprovementsVersionOutOfBounds() throws Exception {
+ try {
+ DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(new Version(2, 2, 0));
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ Version curVersion = Configuration.getVersion();
+ final Version futureVersion = new Version(curVersion.getMajor(), curVersion.getMicro(),
+ curVersion.getMicro() + 1);
+ try {
+ DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(futureVersion);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ new DefaultObjectWrapper.Builder(futureVersion);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testBuilder() throws Exception {
+ DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ DefaultObjectWrapper ow = builder.build();
+ assertSame(ow, builder.build());
+ assertSame(ow.getClass(), DefaultObjectWrapper.class);
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ }
+
+ @Test
+ public void testWrappedTypes() throws Exception {
+ DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ DefaultObjectWrapper ow = builder.build();
+
+ assertThat(ow.wrap(new HashMap()), instanceOf(DefaultMapAdapter.class));
+ assertThat(ow.wrap(new ArrayList()), instanceOf(DefaultListAdapter.class));
+ assertThat(ow.wrap(new String[] {}), instanceOf(DefaultArrayAdapter.class));
+ assertThat(ow.wrap(new HashSet()), instanceOf(DefaultNonListCollectionAdapter.class));
+ assertThat(ow.wrap(new PureIterable()), instanceOf(DefaultIterableAdapter.class));
+ assertThat(ow.wrap(new Vector<>().iterator()), instanceOf(DefaultIteratorAdapter.class));
+ assertThat(ow.wrap(new Vector<>().elements()), instanceOf(DefaultEnumerationAdapter.class));
+ }
+
+ @Test
+ public void testConstructors() throws Exception {
+ {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .usePrivateCaches(true).build();
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ }
+
+ try {
+ new DefaultObjectWrapper.Builder(new Version(99, 9, 9)).build();
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("version"));
+ }
+ }
+
+
+ @Test
+ public void testCustomization() throws TemplateModelException {
+ CustomizedDefaultObjectWrapper ow = new CustomizedDefaultObjectWrapper(Configuration.VERSION_3_0_0);
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+
+ TemplateSequenceModel seq = (TemplateSequenceModel) ow.wrap(new Tupple(11, 22));
+ assertEquals(2, seq.size());
+ assertEquals(11, ow.unwrap(seq.get(0)));
+ assertEquals(22, ow.unwrap(seq.get(1)));
+
+ assertTrue(ow.wrap("x") instanceof SimpleScalar);
+ assertTrue(ow.wrap(1.5) instanceof SimpleNumber);
+ assertTrue(ow.wrap(new Date()) instanceof SimpleDate);
+ assertEquals(TemplateBooleanModel.TRUE, ow.wrap(true));
+
+ assertTrue(ow.wrap(Collections.emptyMap()) instanceof DefaultMapAdapter);
+ assertTrue(ow.wrap(Collections.emptyList()) instanceof DefaultListAdapter);
+ assertTrue(ow.wrap(new boolean[] { }) instanceof DefaultArrayAdapter);
+ assertTrue(ow.wrap(new HashSet()) instanceof DefaultNonListCollectionAdapter);
+ assertTrue(ow.wrap('c') instanceof TemplateScalarModel); // BeanAndStringModel right now, but should change later
+
+ TemplateHashModel bean = (TemplateHashModel) ow.wrap(new TestBean());
+ assertEquals(1, ow.unwrap(bean.get("x")));
+ {
+ // Check method calls, and also if the return value is wrapped with the overidden "wrap".
+ final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("m")).exec(Collections.emptyList());
+ assertEquals(
+ Collections.singletonList(1),
+ ow.unwrap(mr));
+ assertTrue(DefaultListAdapter.class.isInstance(mr));
+ }
+ {
+ // Check custom TM usage and round trip:
+ final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("incTupple"))
+ .exec(Collections.singletonList(ow.wrap(new Tupple<>(1, 2))));
+ assertEquals(new Tupple<>(2, 3), ow.unwrap(mr));
+ assertTrue(TuppleAdapter.class.isInstance(mr));
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testCompositeValueWrapping() throws TemplateModelException, ClassNotFoundException {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ final Map hashMap = new HashMap();
+ inintTestMap(hashMap);
+ final Map treeMap = new TreeMap();
+ inintTestMap(treeMap);
+ final Map linkedHashMap = new LinkedHashMap();
+ inintTestMap(linkedHashMap);
+ final Map gMap = ImmutableMap.<String, Object> of("a", 1, "b", 2, "c", 3);
+ final LinkedList linkedList = new LinkedList();
+ linkedList.add("a");
+ linkedList.add("b");
+ linkedList.add("c");
+ final int[] intArray = new int[] { 1, 2, 3 };
+ final String[] stringArray = new String[] { "a", "b", "c" };
+ final PureIterable pureIterable = new PureIterable();
+ final HashSet hashSet = new HashSet();
+
+ assertRoundtrip(ow, linkedHashMap, DefaultMapAdapter.class, LinkedHashMap.class, linkedHashMap.toString());
+ assertRoundtrip(ow, treeMap, DefaultMapAdapter.class, TreeMap.class, treeMap.toString());
+ assertRoundtrip(ow, gMap, DefaultMapAdapter.class, ImmutableMap.class, gMap.toString());
+ assertRoundtrip(ow, linkedList, DefaultListAdapter.class, LinkedList.class, linkedList.toString());
+ assertRoundtrip(ow, intArray, DefaultArrayAdapter.class, int[].class, null);
+ assertRoundtrip(ow, stringArray, DefaultArrayAdapter.class, String[].class, null);
+ assertRoundtrip(ow, pureIterable, DefaultIterableAdapter.class, PureIterable.class, pureIterable.toString());
+ assertRoundtrip(ow, hashSet, DefaultNonListCollectionAdapter.class, HashSet.class, hashSet.toString());
+ }
+
+ @SuppressWarnings("boxing")
+ private void inintTestMap(Map map) {
+ map.put("a", 1);
+ map.put("b", 2);
+ map.put("c", 3);
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testMapAdapter() throws TemplateModelException {
+ HashMap<String, Object> testMap = new LinkedHashMap<>();
+ testMap.put("a", 1);
+ testMap.put("b", null);
+ testMap.put("c", "C");
+ testMap.put("d", Collections.singletonList("x"));
+
+ {
+ TemplateHashModelEx hash = (TemplateHashModelEx) OW.wrap(testMap);
+ assertEquals(4, hash.size());
+ assertFalse(hash.isEmpty());
+ assertNull(hash.get("e"));
+ assertEquals(1, ((TemplateNumberModel) hash.get("a")).getAsNumber());
+ assertNull(hash.get("b"));
+ assertEquals("C", ((TemplateScalarModel) hash.get("c")).getAsString());
+ assertTrue(hash.get("d") instanceof DefaultListAdapter);
+
+ assertCollectionTMEquals(hash.keys(), "a", "b", "c", "d");
+ assertCollectionTMEquals(hash.values(), 1, null, "C", Collections.singletonList("x"));
+
+ assertSizeThroughAPIModel(4, hash);
+ }
+
+ {
+ assertTrue(((TemplateHashModel) OW.wrap(Collections.emptyMap())).isEmpty());
+ }
+ }
+
+ private void assertCollectionTMEquals(TemplateCollectionModel coll, Object... expectedItems)
+ throws TemplateModelException {
+ for (int i = 0; i < 2; i++) { // Run twice to check if we always get a new iterator
+ int idx = 0;
+ TemplateModelIterator it2 = null;
+ for (TemplateModelIterator it = coll.iterator(); it.hasNext(); ) {
+ TemplateModel actualItem = it.next();
+ if (idx >= expectedItems.length) {
+ fail("Number of items is more than the expected " + expectedItems.length);
+ }
+ assertEquals(expectedItems[idx], OW.unwrap(actualItem));
+ if (i == 1) {
+ // In the 2nd round we also test with two iterators in parallel.
+ // This 2nd iterator is also special in that its hasNext() is never called.
+ if (it2 == null) {
+ it2 = coll.iterator();
+ }
+ assertEquals(expectedItems[idx], OW.unwrap(it2.next()));
+ }
+ idx++;
+ }
+ if (expectedItems.length != idx) {
+ fail("Number of items is " + idx + ", which is less than the expected " + expectedItems.length);
+ }
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testListAdapter() throws TemplateModelException {
+ {
+ List testList = new ArrayList<>();
+ testList.add(1);
+ testList.add(null);
+ testList.add("c");
+ testList.add(new String[] { "x" });
+
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testList);
+ assertTrue(seq instanceof DefaultListAdapter);
+ assertFalse(seq instanceof TemplateCollectionModel); // Maybe changes at 2.4.0
+ assertEquals(4, seq.size());
+ assertNull(seq.get(-1));
+ assertEquals(1, ((TemplateNumberModel) seq.get(0)).getAsNumber());
+ assertNull(seq.get(1));
+ assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
+ assertTrue(seq.get(3) instanceof DefaultArrayAdapter);
+ assertNull(seq.get(4));
+
+ assertSizeThroughAPIModel(4, seq);
+ }
+
+ {
+ List testList = new LinkedList<>();
+ testList.add(1);
+ testList.add(null);
+ testList.add("c");
+
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testList);
+ assertTrue(seq instanceof DefaultListAdapter);
+ assertTrue(seq instanceof TemplateCollectionModel); // Maybe changes at 2.4.0
+ assertEquals(3, seq.size());
+ assertNull(seq.get(-1));
+ assertEquals(1, ((TemplateNumberModel) seq.get(0)).getAsNumber());
+ assertNull(seq.get(1));
+ assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
+ assertNull(seq.get(3));
+
+ assertCollectionTMEquals((TemplateCollectionModel) seq, 1, null, "c");
+
+ TemplateModelIterator it = ((TemplateCollectionModel) seq).iterator();
+ it.next();
+ it.next();
+ it.next();
+ try {
+ it.next();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("no more"));
+ }
+ }
+ }
+
+ @Test
+ public void testArrayAdapterTypes() throws TemplateModelException {
+ assertArrayAdapterClass("Object", OW.wrap(new Object[] {}));
+ assertArrayAdapterClass("Object", OW.wrap(new String[] {}));
+ assertArrayAdapterClass("byte", OW.wrap(new byte[] {}));
+ assertArrayAdapterClass("short", OW.wrap(new short[] {}));
+ assertArrayAdapterClass("int", OW.wrap(new int[] {}));
+ assertArrayAdapterClass("long", OW.wrap(new long[] {}));
+ assertArrayAdapterClass("float", OW.wrap(new float[] {}));
+ assertArrayAdapterClass("double", OW.wrap(new double[] {}));
+ assertArrayAdapterClass("boolean", OW.wrap(new boolean[] {}));
+ assertArrayAdapterClass("char", OW.wrap(new char[] {}));
+ }
+
+ private void assertArrayAdapterClass(String adapterCompType, TemplateModel adaptedArray) {
+ assertTrue(adaptedArray instanceof DefaultArrayAdapter);
+ assertThat(adaptedArray.getClass().getName(),
+ containsString("$" + adapterCompType.substring(0, 1).toUpperCase() + adapterCompType.substring(1)));
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testArrayAdapters() throws TemplateModelException {
+ {
+ final String[] testArray = new String[] { "a", null, "c" };
+
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
+ assertEquals(3, seq.size());
+ assertNull(seq.get(-1));
+ assertEquals("a", ((TemplateScalarModel) seq.get(0)).getAsString());
+ assertNull(seq.get(1));
+ assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
+ assertNull(seq.get(3));
+ }
+
+ {
+ final int[] testArray = new int[] { 11, 22 };
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
+ assertEquals(2, seq.size());
+ assertNull(seq.get(-1));
+ assertEqualsAndSameClass(Integer.valueOf(11), ((TemplateNumberModel) seq.get(0)).getAsNumber());
+ assertEqualsAndSameClass(Integer.valueOf(22), ((TemplateNumberModel) seq.get(1)).getAsNumber());
+ assertNull(seq.get(2));
+ }
+
+ {
+ final double[] testArray = new double[] { 11, 22 };
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
+ assertEquals(2, seq.size());
+ assertNull(seq.get(-1));
+ assertEqualsAndSameClass(Double.valueOf(11), ((TemplateNumberModel) seq.get(0)).getAsNumber());
+ assertEqualsAndSameClass(Double.valueOf(22), ((TemplateNumberModel) seq.get(1)).getAsNumber());
+ assertNull(seq.get(2));
+ }
+
+ {
+ final boolean[] testArray = new boolean[] { true, false };
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
+ assertEquals(2, seq.size());
+ assertNull(seq.get(-1));
+ assertEqualsAndSameClass(Boolean.valueOf(true), ((TemplateBooleanModel) seq.get(0)).getAsBoolean());
+ assertEqualsAndSameClass(Boolean.valueOf(false), ((TemplateBooleanModel) seq.get(1)).getAsBoolean());
+ assertNull(seq.get(2));
+ }
+
+ {
+ final char[] testArray = new char[] { 'a', 'b' };
+ TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
+ assertEquals(2, seq.size());
+ assertNull(seq.get(-1));
+ assertEquals("a", ((TemplateScalarModel) seq.get(0)).getAsString());
+ assertEquals("b", ((TemplateScalarModel) seq.get(1)).getAsString());
+ assertNull(seq.get(2));
+ }
+ }
+
+ private void assertEqualsAndSameClass(Object expected, Object actual) {
+ assertEquals(expected, actual);
+ if (expected != null) {
+ assertEquals(expected.getClass(), actual.getClass());
+ }
+ }
+
+ private void assertRoundtrip(DefaultObjectWrapper dow, Object obj, Class expectedTMClass,
+ Class expectedPojoClass,
+ String expectedPojoToString)
+ throws TemplateModelException {
+ final TemplateModel objTM = dow.wrap(obj);
+ assertThat(objTM.getClass(), typeCompatibleWith(expectedTMClass));
+
+ final TemplateHashModel testBeanTM = (TemplateHashModel) dow.wrap(new RoundtripTesterBean());
+
+ {
+ TemplateMethodModelEx getClassM = (TemplateMethodModelEx) testBeanTM.get("getClass");
+ Object r = getClassM.exec(Collections.singletonList(objTM));
+ final Class rClass = (Class) ((WrapperTemplateModel) r).getWrappedObject();
+ assertThat(rClass, typeCompatibleWith(expectedPojoClass));
+ }
+
+ if (expectedPojoToString != null) {
+ TemplateMethodModelEx getToStringM = (TemplateMethodModelEx) testBeanTM.get("toString");
+ Object r = getToStringM.exec(Collections.singletonList(objTM));
+ assertEquals(expectedPojoToString, ((TemplateScalarModel) r).getAsString());
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testCollectionAdapterBasics() throws TemplateModelException {
+ {
+ Set set = new TreeSet();
+ set.add("a");
+ set.add("b");
+ set.add("c");
+ TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
+ assertTrue(coll instanceof DefaultNonListCollectionAdapter);
+ assertEquals(3, coll.size());
+ assertFalse(coll.isEmpty());
+ assertCollectionTMEquals(coll, "a", "b", "c");
+
+ assertRoundtrip(OW, set, DefaultNonListCollectionAdapter.class, TreeSet.class, "[a, b, c]");
+
+ assertSizeThroughAPIModel(3, coll);
+ }
+
+ {
+ Set set = new HashSet();
+ final List<String> list = Collections.singletonList("b");
+ set.add(list);
+ set.add(null);
+ TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
+ TemplateModelIterator it = coll.iterator();
+ final TemplateModel tm1 = it.next();
+ Object obj1 = OW.unwrap(tm1);
+ final TemplateModel tm2 = it.next();
+ Object obj2 = OW.unwrap(tm2);
+ assertTrue(obj1 == null || obj2 == null);
+ assertTrue(obj1 != null && obj1.equals(list) || obj2 != null && obj2.equals(list));
+ assertTrue(tm1 instanceof DefaultListAdapter || tm2 instanceof DefaultListAdapter);
+
+ assertRoundtrip(OW, set, DefaultNonListCollectionAdapter.class, HashSet.class, "[" + obj1 + ", "
+ + obj2 + "]");
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testCollectionAdapterOutOfBounds() throws TemplateModelException {
+ Set set = Collections.singleton(123);
+
+ TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
+ TemplateModelIterator it = coll.iterator();
+
+ for (int i = 0; i < 3; i++) {
+ assertTrue(it.hasNext());
+ }
+
+ assertEquals(123, OW.unwrap(it.next()));
+
+ for (int i = 0; i < 3; i++) {
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
+ }
+ }
+ }
+
+ @Test
+ public void testCollectionAdapterAndNulls() throws TemplateModelException {
+ Set set = new HashSet();
+ set.add(null);
+
+ TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
+ assertEquals(1, coll.size());
+ assertFalse(coll.isEmpty());
+ assertNull(coll.iterator().next());
+ }
+
+ @Test
+ public void testIteratorWrapping() throws TemplateModelException, ClassNotFoundException {
+ final List<String> list = ImmutableList.of("a", "b", "c");
+ Iterator<String> it = list.iterator();
+ TemplateCollectionModel coll = (TemplateCollectionModel) OW.wrap(it);
+
+ assertRoundtrip(OW, coll, DefaultIteratorAdapter.class, Iterator.class, null);
+
+ TemplateModelIterator itIt = coll.iterator();
+ TemplateModelIterator itIt2 = coll.iterator(); // used later
+ assertTrue(itIt.hasNext());
+ assertEquals("a", OW.unwrap(itIt.next()));
+ assertTrue(itIt.hasNext());
+ assertEquals("b", OW.unwrap(itIt.next()));
+ assertTrue(itIt.hasNext());
+ assertEquals("c", OW.unwrap(itIt.next()));
+ assertFalse(itIt.hasNext());
+ try {
+ itIt.next();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
+ }
+
+ try {
+ itIt2.hasNext();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("can be listed only once"));
+ }
+
+ TemplateModelIterator itIt3 = coll.iterator();
+ try {
+ itIt3.hasNext();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("can be listed only once"));
+ }
+ }
+
+ @Test
+ public void testIteratorApiSupport() throws TemplateModelException {
+ TemplateModel wrappedIterator = OW.wrap(Collections.emptyIterator());
+ assertThat(wrappedIterator, instanceOf(DefaultIteratorAdapter.class));
+ DefaultIteratorAdapter iteratorAdapter = (DefaultIteratorAdapter) wrappedIterator;
+
+ TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
+ assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
+ api.get("hasNext")).exec(Collections.emptyList())).getAsBoolean());
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testCharKeyFallback() throws TemplateModelException {
+ Map hashMapS = new HashMap<>();
+ hashMapS.put("a", 1);
+ Map sortedMapS = new TreeMap<>();
+ sortedMapS.put("a", 1);
+ Map hashMapC = new HashMap<>();
+ hashMapC.put('a', 1);
+ Map sortedMapC = new TreeMap<>();
+ sortedMapC.put('a', 1);
+
+ assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(hashMapS)).get("a")));
+ assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(hashMapC)).get("a")));
+ assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(sortedMapS)).get("a")));
+ try {
+ ((TemplateHashModel) OW.wrap(sortedMapC)).get("a");
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("String key"));
+ }
+
+ assertNull(((TemplateHashModel) OW.wrap(hashMapS)).get("b"));
+ assertNull(((TemplateHashModel) OW.wrap(hashMapC)).get("b"));
+ assertNull(((TemplateHashModel) OW.wrap(sortedMapS)).get("b"));
+ try {
+ ((TemplateHashModel) OW.wrap(sortedMapC)).get("b");
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("String key"));
+ }
+ }
+
+ @Test
+ public void testIterableSupport() throws TemplateException, IOException {
+ Iterable<String> iterable = new PureIterable();
+
+ String listingFTL = "<#list value as x>${x}<#sep>, </#list>";
+
+ DefaultObjectWrapper ow = OW;
+ TemplateModel tm = ow.wrap(iterable);
+ assertThat(tm, instanceOf(TemplateCollectionModel.class));
+ TemplateCollectionModel iterableTM = (TemplateCollectionModel) tm;
+
+ for (int i = 0; i < 2; i++) {
+ TemplateModelIterator iteratorTM = iterableTM.iterator();
+ assertTrue(iteratorTM.hasNext());
+ assertEquals("a", ow.unwrap(iteratorTM.next()));
+ assertTrue(iteratorTM.hasNext());
+ assertEquals("b", ow.unwrap(iteratorTM.next()));
+ assertTrue(iteratorTM.hasNext());
+ assertEquals("c", ow.unwrap(iteratorTM.next()));
+ assertFalse(iteratorTM.hasNext());
+ try {
+ iteratorTM.next();
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
+ }
+ }
+
+ assertTemplateOutput(OW, iterable, listingFTL, "a, b, c");
+ }
+
+ @Test
+ public void testEnumerationAdapter() throws TemplateModelException {
+ Vector<String> vector = new Vector<String>();
+ vector.add("a");
+ vector.add("b");
+
+ TemplateModel wrappedEnumeration = OW.wrap(vector.elements());
+ assertThat(wrappedEnumeration, instanceOf(DefaultEnumerationAdapter.class));
+ DefaultEnumerationAdapter enumAdapter = (DefaultEnumerationAdapter) wrappedEnumeration;
+ TemplateModelIterator iterator = enumAdapter.iterator();
+ assertTrue(iterator.hasNext());
+ assertEquals("a", ((TemplateScalarModel) iterator.next()).getAsString());
+ assertTrue(iterator.hasNext());
+ assertEquals("b", ((TemplateScalarModel) iterator.next()).getAsString());
+ assertFalse(iterator.hasNext());
+
+ iterator = enumAdapter.iterator();
+ try {
+ iterator.hasNext();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("only once"));
+ }
+
+ TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
+ assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
+ api.get("hasMoreElements")).exec(Collections.emptyList())).getAsBoolean());
+ }
+
+ @Test
+ public void assertCanWrapDOM() throws SAXException, IOException, ParserConfigurationException,
+ TemplateModelException {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
+ Document doc = db.parse(is);
+ assertTrue(OW.wrap(doc) instanceof TemplateNodeModel);
+ }
+
+ @Test
+ public void testExposureLevel() throws Exception {
+ TestBean bean = new TestBean();
+
+ {
+ TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_SAFE);
+ assertNotNull(tm.get("hashCode"));
+ assertNotNull(tm.get("class"));
+ }
+
+ {
+ TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
+ assertNull(tm.get("hashCode"));
+ assertNotNull(tm.get("class"));
+ }
+
+ {
+ TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_NOTHING);
+ assertNull(tm.get("hashCode"));
+ assertNull(tm.get("class"));
+ }
+
+ {
+ TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_ALL);
+ assertNotNull(tm.get("hashCode"));
+ assertNotNull(tm.get("class"));
+ }
+ }
+
+ private TemplateHashModel wrapWithExposureLevel(Object bean, int exposureLevel) throws TemplateModelException {
+ return (TemplateHashModel) new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .exposureLevel(exposureLevel).build()
+ .wrap(bean);
+ }
+
+ private void assertSizeThroughAPIModel(int expectedSize, TemplateModel normalModel) throws TemplateModelException {
+ if (!(normalModel instanceof TemplateModelWithAPISupport)) {
+ fail();
+ }
+ TemplateHashModel apiModel = (TemplateHashModel) ((TemplateModelWithAPISupport) normalModel).getAPI();
+ TemplateMethodModelEx sizeMethod = (TemplateMethodModelEx) apiModel.get("size");
+ TemplateNumberModel r = (TemplateNumberModel) sizeMethod.exec(Collections.emptyList());
+ assertEquals(expectedSize, r.getAsNumber().intValue());
+ }
+
+ private void assertTemplateOutput(ObjectWrapper objectWrapper, Object value, String ftl, String expectedOutput)
+ throws TemplateException, IOException {
+ assertEquals(expectedOutput, processTemplate(objectWrapper, value, ftl));
+ }
+
+ private void assertTemplateFails(ObjectWrapper objectWrapper, Object value, String ftl, String expectedMessagePart)
+ throws TemplateException, IOException {
+ try {
+ processTemplate(objectWrapper, value, ftl);
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString(expectedMessagePart));
+ }
+ }
+
+ private String processTemplate(ObjectWrapper objectWrapper, Object value, String ftl)
+ throws TemplateException, IOException {
+ Configuration cfg = new TestConfigurationBuilder()
+ .logTemplateExceptions(false)
+ .objectWrapper(objectWrapper)
+ .build();
+ StringWriter out = new StringWriter();
+ new Template(null, ftl, cfg).process(ImmutableMap.of("value", value), out);
+ return out.toString();
+ }
+
+ private static final class PureIterable implements Iterable<String> {
+ @Override
+ public Iterator<String> iterator() {
+ return ImmutableList.of("a", "b", "c").iterator();
+ }
+ }
+
+ public static class RoundtripTesterBean {
+
+ public Class getClass(Object o) {
+ return o.getClass();
+ }
+
+ public String toString(Object o) {
+ return o.toString();
+ }
+
+ }
+
+ private static class Tupple<E1, E2> {
+
+ private final E1 e1;
+ private final E2 e2;
+
+ public Tupple(E1 e1, E2 e2) {
+ if (e1 == null || e2 == null) throw new NullPointerException();
+ this.e1 = e1;
+ this.e2 = e2;
+ }
+
+ public E1 getE1() {
+ return e1;
+ }
+
+ public E2 getE2() {
+ return e2;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((e1 == null) ? 0 : e1.hashCode());
+ result = prime * result + ((e2 == null) ? 0 : e2.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ Tupple other = (Tupple) obj;
+ if (e1 == null) {
+ if (other.e1 != null) return false;
+ } else if (!e1.equals(other.e1)) return false;
+ if (e2 == null) {
+ if (other.e2 != null) return false;
+ } else if (!e2.equals(other.e2)) return false;
+ return true;
+ }
+
+ }
+
+ @SuppressWarnings("boxing")
+ public static class TestBean {
+
+ public int getX() {
+ return 1;
+ }
+
+ public List<Integer> m() {
+ return Collections.singletonList(1);
+ }
+
+ public Tupple incTupple(Tupple<Integer, Integer> tupple) {
+ return new Tupple(tupple.e1 + 1, tupple.e2 + 1);
+ }
+
+ }
+
+ private static class CustomizedDefaultObjectWrapper extends DefaultObjectWrapper {
+
+ private CustomizedDefaultObjectWrapper(Version incompatibleImprovements) {
+ super(new DefaultObjectWrapper.Builder(incompatibleImprovements), true);
+ }
+
+ @Override
+ protected TemplateModel handleNonBasicTypes(final Object obj) throws TemplateModelException {
+ if (obj instanceof Tupple) {
+ return new TuppleAdapter((Tupple<?, ?>) obj, this);
+ }
+
+ return super.handleNonBasicTypes(obj);
+ }
+
+ }
+
+ private static class TuppleAdapter extends WrappingTemplateModel implements TemplateSequenceModel,
+ AdapterTemplateModel {
+
+ private final Tupple<?, ?> tupple;
+
+ public TuppleAdapter(Tupple<?, ?> tupple, ObjectWrapper ow) {
+ super(ow);
+ this.tupple = tupple;
+ }
+
+ @Override
+ public int size() throws TemplateModelException {
+ return 2;
+ }
+
+ @Override
+ public TemplateModel get(int index) throws TemplateModelException {
+ switch (index) {
+ case 0: return wrap(tupple.getE1());
+ case 1: return wrap(tupple.getE2());
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getAdaptedObject(Class hint) {
+ return tupple;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
new file mode 100644
index 0000000..fc19bb7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class EnumModelsTest {
+
+ @Test
+ public void modelCaching() throws Exception {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
+ .build();
+ TemplateHashModel enums = ow.getEnumModels();
+ TemplateHashModel e = (TemplateHashModel) enums.get(E.class.getName());
+ assertNotNull(e);
+ assertNotNull(e.get("A"));
+ assertNotNull(e.get("B"));
+ assertNull(e.get("C"));
+
+ try {
+ enums.get("no.such.ClassExists");
+ fail();
+ } catch (TemplateModelException ex) {
+ assertTrue(ex.getCause() instanceof ClassNotFoundException);
+ }
+
+ TemplateModel a = e.get("A");
+ assertTrue(a instanceof TemplateScalarModel);
+ assertTrue(a instanceof TemplateHashModel);
+ assertEquals(((TemplateScalarModel) a).getAsString(), "ts:A");
+ TemplateMethodModelEx nameMethod = (TemplateMethodModelEx) ((TemplateHashModel) a).get("name");
+ assertEquals(((TemplateScalarModel) nameMethod.exec(new ArrayList())).getAsString(), "A");
+
+ assertSame(e, enums.get(E.class.getName()));
+
+ ow.clearClassIntrospecitonCache();
+ TemplateHashModel eAfterClean = (TemplateHashModel) enums.get(E.class.getName());
+ assertNotSame(e, eAfterClean);
+ assertSame(eAfterClean, enums.get(E.class.getName()));
+ assertNotNull(eAfterClean.get("A"));
+ assertNotNull(eAfterClean.get("B"));
+ assertNull(eAfterClean.get("C"));
+ }
+
+ public enum E {
+ A, B;
+
+ @Override
+ public String toString() {
+ return "ts:" + super.toString();
+ }
+
+ }
+
+}
[44/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
new file mode 100644
index 0000000..eedb4d1
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
@@ -0,0 +1,1068 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.core.ParsingConfiguration.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collections;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.OutputFormat;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.PlainTextOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
+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.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.OrMatcher;
+import org.apache.freemarker.core.templateresolver.impl.NullCacheStorage;
+import org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat;
+import org.apache.freemarker.core.userpkg.DummyOutputFormat;
+import org.apache.freemarker.core.userpkg.SeldomEscapedOutputFormat;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class OutputFormatTest extends TemplateTest {
+
+ @Test
+ public void testOutputFormatSettingLayers() throws Exception {
+ addTemplate("t", "${.outputFormat}");
+ addTemplate("t.xml", "${.outputFormat}");
+ addTemplate("tWithHeader", "<#ftl outputFormat='HTML'>${.outputFormat}");
+
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+ for (OutputFormat cfgOutputFormat
+ : new OutputFormat[] { UndefinedOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE } ) {
+ if (!cfgOutputFormat.equals(UndefinedOutputFormat.INSTANCE)) {
+ cfgB.setOutputFormat(cfgOutputFormat);
+ }
+ setConfiguration(cfgB.build());
+
+ assertEquals(cfgOutputFormat, getConfiguration().getOutputFormat());
+
+ {
+ Template t = getConfiguration().getTemplate("t");
+ assertEquals(cfgOutputFormat, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("t.xml");
+ assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("tWithHeader");
+ assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ getConfiguration().clearTemplateCache();
+ }
+ }
+
+ @Test
+ public void testStandardFileExtensions() throws Exception {
+ String commonContent = "${.outputFormat}";
+ addTemplate("t", commonContent);
+ addTemplate("t.ftl", commonContent);
+ addTemplate("t.ftlh", commonContent);
+ addTemplate("t.FTLH", commonContent);
+ addTemplate("t.fTlH", commonContent);
+ addTemplate("t.ftlx", commonContent);
+ addTemplate("t.FTLX", commonContent);
+ addTemplate("t.fTlX", commonContent);
+ addTemplate("tWithHeader.ftlx", "<#ftl outputFormat='HTML'>" + commonContent);
+
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+ for (int setupNumber = 1; setupNumber <= 3; setupNumber++) {
+ final OutputFormat cfgOutputFormat;
+ final OutputFormat ftlhOutputFormat;
+ final OutputFormat ftlxOutputFormat;
+ switch (setupNumber) {
+ case 1:
+ cfgOutputFormat = UndefinedOutputFormat.INSTANCE;
+ ftlhOutputFormat = HTMLOutputFormat.INSTANCE;
+ ftlxOutputFormat = XMLOutputFormat.INSTANCE;
+ break;
+ case 2:
+ cfgOutputFormat = RTFOutputFormat.INSTANCE;
+ cfgB.setOutputFormat(cfgOutputFormat);
+ ftlhOutputFormat = HTMLOutputFormat.INSTANCE;
+ ftlxOutputFormat = XMLOutputFormat.INSTANCE;
+ break;
+ case 3:
+ cfgOutputFormat = UndefinedOutputFormat.INSTANCE;
+ cfgB.unsetOutputFormat();
+ TemplateConfiguration.Builder tcbXML = new TemplateConfiguration.Builder();
+ tcbXML.setOutputFormat(XMLOutputFormat.INSTANCE);
+ cfgB.setTemplateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new OrMatcher(
+ new FileNameGlobMatcher("*.ftlh"),
+ new FileNameGlobMatcher("*.FTLH"),
+ new FileNameGlobMatcher("*.fTlH")),
+ tcbXML.build()));
+ ftlhOutputFormat = HTMLOutputFormat.INSTANCE; // can't be overidden
+ ftlxOutputFormat = XMLOutputFormat.INSTANCE;
+ break;
+ default:
+ throw new AssertionError();
+ }
+
+ setConfiguration(cfgB.build());
+ assertEquals(cfgOutputFormat, getConfiguration().getOutputFormat());
+
+ {
+ Template t = getConfiguration().getTemplate("t");
+ assertEquals(cfgOutputFormat, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("t.ftl");
+ assertEquals(cfgOutputFormat, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ for (String name : new String[] { "t.ftlh", "t.FTLH", "t.fTlH" }) {
+ Template t = getConfiguration().getTemplate(name);
+ assertEquals(ftlhOutputFormat, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ for (String name : new String[] { "t.ftlx", "t.FTLX", "t.fTlX" }) {
+ Template t = getConfiguration().getTemplate(name);
+ assertEquals(ftlxOutputFormat, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("tWithHeader.ftlx");
+ assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
+ assertOutput(t, t.getOutputFormat().getName());
+ }
+
+ getConfiguration().clearTemplateCache();
+ }
+ }
+
+ @Test
+ public void testStandardFileExtensionsSettingOverriding() throws Exception {
+ addTemplate("t.ftlx",
+ "${\"'\"} ${\"'\"?esc} ${\"'\"?noEsc}");
+ addTemplate("t.ftl",
+ "${'{}'} ${'{}'?esc} ${'{}'?noEsc}");
+
+ ConditionalTemplateConfigurationFactory tcfHTML = new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("t.*"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(HTMLOutputFormat.INSTANCE)
+ .build());
+
+ ConditionalTemplateConfigurationFactory tcfNoAutoEsc = new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("t.*"),
+ new TemplateConfiguration.Builder()
+ .autoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY)
+ .build());
+
+ {
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+
+ setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ }
+
+ {
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+
+ setConfiguration(cfgB.recognizeStandardFileExtensions(false).build());
+ assertErrorContainsForNamed("t.ftlx", UndefinedOutputFormat.INSTANCE.getName());
+ setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build());
+ assertOutputForNamed("t.ftlx", "' ' '");
+ setConfiguration(cfgB.outputFormat(XMLOutputFormat.INSTANCE).build());
+ assertOutputForNamed("t.ftlx", "' ' '");
+ setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
+ assertOutputForNamed("t.ftlx", "' ' '");
+ setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
+ assertOutputForNamed("t.ftlx", "' ' '");
+ }
+
+ {
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+ cfgB.setRecognizeStandardFileExtensions(true);
+
+ setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ }
+
+ {
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+
+ setConfiguration(cfgB.templateConfigurations(tcfHTML).build());
+ assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it
+ setConfiguration(cfgB.recognizeStandardFileExtensions(false).build());
+ assertOutputForNamed("t.ftlx", "' ' '");
+ }
+ }
+
+ @Test
+ public void testStandardFileExtensionsWithConstructor() throws Exception {
+ Configuration cfg = getConfiguration();
+ String commonFTL = "${'\\''}";
+ {
+ Template t = new Template("foo.ftl", commonFTL, cfg);
+ assertSame(UndefinedOutputFormat.INSTANCE, t.getOutputFormat());
+ StringWriter out = new StringWriter();
+ t.process(null, out);
+ assertEquals("'", out.toString());
+ }
+ {
+ Template t = new Template("foo.ftlx", commonFTL, cfg);
+ assertSame(XMLOutputFormat.INSTANCE, t.getOutputFormat());
+ StringWriter out = new StringWriter();
+ t.process(null, out);
+ assertEquals("'", out.toString());
+ }
+ {
+ Template t = new Template("foo.ftlh", commonFTL, cfg);
+ assertSame(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
+ StringWriter out = new StringWriter();
+ t.process(null, out);
+ assertEquals("'", out.toString());
+ }
+ }
+
+ @Test
+ public void testStandardFileExtensionsFormatterImplOverriding() throws Exception {
+ addTemplate("t.ftlh", "${'a&x'}");
+
+ assertOutputForNamed("t.ftlh", "a&x");
+
+ setConfiguration(new TestConfigurationBuilder()
+ .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(CustomHTMLOutputFormat.INSTANCE))
+ .build());
+ assertOutputForNamed("t.ftlh", "a&X");
+
+ setConfiguration(new TestConfigurationBuilder()
+ .registeredCustomOutputFormats(Collections.<OutputFormat>emptyList())
+ .build());
+ assertOutputForNamed("t.ftlh", "a&x");
+ }
+
+ @Test
+ public void testAutoEscapingSettingLayers() throws Exception {
+ addTemplate("t", "${'a&b'}");
+ addTemplate("tWithHeaderFalse", "<#ftl autoEsc=false>${'a&b'}");
+ addTemplate("tWithHeaderTrue", "<#ftl autoEsc=true>${'a&b'}");
+
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder().outputFormat(XMLOutputFormat.INSTANCE);
+ assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ for (boolean cfgAutoEscaping : new boolean[] { true, false }) {
+ if (!cfgAutoEscaping) {
+ cfgB.setAutoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY);
+ }
+ setConfiguration(cfgB.build());
+
+ {
+ Template t = getConfiguration().getTemplate("t");
+ if (cfgAutoEscaping) {
+ assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
+ assertOutput(t, "a&b");
+ } else {
+ assertEquals(DISABLE_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
+ assertOutput(t, "a&b");
+ }
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("tWithHeaderFalse");
+ assertEquals(DISABLE_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
+ assertOutput(t, "a&b");
+ }
+
+ {
+ Template t = getConfiguration().getTemplate("tWithHeaderTrue");
+ assertEquals(ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, t.getAutoEscapingPolicy());
+ assertOutput(t, "a&b");
+ }
+
+ getConfiguration().clearTemplateCache();
+ }
+ }
+
+ @Test
+ public void testNumericalInterpolation() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(DummyOutputFormat.INSTANCE))
+ .build());
+ assertOutput(
+ "<#ftl outputFormat='dummy'>#{1.5}; #{1.5; m3}; ${'a.b'}",
+ "1\\.5; 1\\.500; a\\.b");
+ assertOutput(
+ "<#ftl outputFormat='dummy' autoEsc=false>#{1.5}; #{1.5; m3}; ${'a.b'}; ${'a.b'?esc}",
+ "1.5; 1.500; a.b; a\\.b");
+ assertOutput("<#ftl outputFormat='plainText'>#{1.5}", "1.5");
+ assertOutput("<#ftl outputFormat='HTML'>#{1.5}", "1.5");
+ assertOutput("#{1.5}", "1.5");
+ }
+
+ @Test
+ public void testUndefinedOutputFormat() throws IOException, TemplateException {
+ assertOutput("${'a < b'}; ${htmlPlain}; ${htmlMarkup}", "a < b; a < {h'}; <p>c");
+ assertErrorContains("${'x'?esc}", "undefined", "escaping", "?esc");
+ assertErrorContains("${'x'?noEsc}", "undefined", "escaping", "?noEsc");
+ }
+
+ @Test
+ public void testPlainTextOutputFormat() throws IOException, TemplateException {
+ assertOutput("<#ftl outputFormat='plainText'>${'a < b'}; ${htmlPlain}", "a < b; a < {h'}");
+ assertErrorContains("<#ftl outputFormat='plainText'>${htmlMarkup}", "plainText", "HTML", "conversion");
+ assertErrorContains("<#ftl outputFormat='plainText'>${'x'?esc}", "plainText", "escaping", "?esc");
+ assertErrorContains("<#ftl outputFormat='plainText'>${'x'?noEsc}", "plainText", "escaping", "?noEsc");
+ }
+
+ @Test
+ public void testAutoEscapingOnMOs() throws IOException, TemplateException {
+ for (boolean cfgAutoEscaping : new boolean[] { true, false }) {
+ String commonAutoEscFtl = "<#ftl outputFormat='HTML'>${'&'}";
+ if (cfgAutoEscaping) {
+ // Cfg default is autoEscaping true
+ assertOutput(commonAutoEscFtl, "&");
+ } else {
+ setConfiguration(createDefaultConfigurationBuilder()
+ .autoEscapingPolicy(DISABLE_AUTO_ESCAPING_POLICY)
+ .build());
+ assertOutput(commonAutoEscFtl, "&");
+ }
+
+ assertOutput(
+ "<#ftl outputFormat='RTF'>"
+ + "${rtfPlain} ${rtfMarkup} "
+ + "${htmlPlain} "
+ + "${xmlPlain}",
+ "\\\\par a & b \\par c "
+ + "a < \\{h'\\} "
+ + "a < \\{x'\\}");
+ assertOutput(
+ "<#ftl outputFormat='HTML'>"
+ + "${htmlPlain} ${htmlMarkup} "
+ + "${xmlPlain} "
+ + "${rtfPlain}",
+ "a < {h'} <p>c "
+ + "a < {x'} "
+ + "\\par a & b");
+ assertOutput(
+ "<#ftl outputFormat='XML'>"
+ + "${xmlPlain} ${xmlMarkup} "
+ + "${htmlPlain} "
+ + "${rtfPlain}",
+ "a < {x'} <p>c</p> "
+ + "a < {h'} "
+ + "\\par a & b");
+ assertErrorContains("<#ftl outputFormat='RTF'>${htmlMarkup}", "output format", "RTF", "HTML");
+ assertErrorContains("<#ftl outputFormat='RTF'>${xmlMarkup}", "output format", "RTF", "XML");
+ assertErrorContains("<#ftl outputFormat='HTML'>${rtfMarkup}", "output format", "HTML", "RTF");
+ assertErrorContains("<#ftl outputFormat='HTML'>${xmlMarkup}", "output format", "HTML", "XML");
+ assertErrorContains("<#ftl outputFormat='XML'>${rtfMarkup}", "output format", "XML", "RTF");
+ assertErrorContains("<#ftl outputFormat='XML'>${htmlMarkup}", "output format", "XML", "HTML");
+
+ for (int hasHeader = 0; hasHeader < 2; hasHeader++) {
+ assertOutput(
+ (hasHeader == 1 ? "<#ftl outputFormat='undefined'>" : "")
+ + "${xmlPlain} ${xmlMarkup} "
+ + "${htmlPlain} ${htmlMarkup} "
+ + "${rtfPlain} ${rtfMarkup}",
+ "a < {x'} <p>c</p> "
+ + "a < {h'} <p>c "
+ + "\\\\par a & b \\par c");
+ }
+ }
+ }
+
+ @Test
+ public void testStringLiteralsUseUndefinedOF() throws IOException, TemplateException {
+ String expectedOut = "& (&) &";
+ String ftl = "<#ftl outputFormat='XML'>${'&'} ${\"(${'&'})\"?noEsc} ${'&'}";
+
+ assertOutput(ftl, expectedOut);
+
+ addTemplate("t.xml", ftl);
+ assertOutputForNamed("t.xml", expectedOut);
+ }
+
+ @Test
+ public void testUnparsedTemplate() throws IOException, TemplateException {
+ String content = "<#ftl>a<#foo>b${x}";
+ {
+ Template t = Template.createPlainTextTemplate("x", content, getConfiguration());
+ Writer sw = new StringWriter();
+ t.process(null, sw);
+ assertEquals(content, sw.toString());
+ assertEquals(UndefinedOutputFormat.INSTANCE, t.getOutputFormat());
+ }
+
+ {
+ setConfiguration(new TestConfigurationBuilder().outputFormat(HTMLOutputFormat.INSTANCE).build());
+ Template t = Template.createPlainTextTemplate("x", content, getConfiguration());
+ Writer sw = new StringWriter();
+ t.process(null, sw);
+ assertEquals(content, sw.toString());
+ assertEquals(HTMLOutputFormat.INSTANCE, t.getOutputFormat());
+ }
+ }
+
+ @Test
+ public void testStringLiteralInterpolation() throws IOException, TemplateException {
+ Template t = new Template(null, "<#ftl outputFormat='XML'>${'&'} ${\"(${'&'})\"?noEsc}", getConfiguration());
+ assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
+
+ assertOutput("${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
+ "undefined undefined undefined");
+ assertOutput("<#ftl outputFormat='HTML'>${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
+ "HTML HTML HTML");
+ assertOutput("${.outputFormat} <#outputFormat 'XML'>${'${.outputFormat}'}</#outputFormat> ${.outputFormat}",
+ "undefined XML undefined");
+ assertOutput("${'foo ${xmlPlain}'}", "foo a < {x'}");
+ assertOutput("${'${xmlMarkup}'}", "<p>c</p>");
+ assertErrorContains("${'${\"x\"?esc}'}", "?esc", "undefined");
+ assertOutput("<#ftl outputFormat='XML'>${'${xmlMarkup?esc} ${\"<\"?esc} ${\">\"} ${\"&\"?noEsc}'}",
+ "<p>c</p> < > &");
+ }
+
+ @Test
+ public void testStringBIsFail() {
+ assertErrorContains("<#ftl outputFormat='HTML'>${'<b>foo</b>'?esc?upperCase}", "string", "markup_output");
+ }
+
+ @Test
+ public void testConcatWithMOs() throws IOException, TemplateException {
+ assertOutput(
+ "${'\\'' + htmlMarkup} ${htmlMarkup + '\\''} ${htmlMarkup + htmlMarkup}",
+ "'<p>c <p>c' <p>c<p>c");
+ assertOutput(
+ "${'\\'' + htmlPlain} ${htmlPlain + '\\''} ${htmlPlain + htmlPlain}",
+ "'a < {h'} a < {h'}' a < {h'}a < {h'}");
+ assertErrorContains(
+ "<#ftl outputFormat='XML'>${'\\'' + htmlMarkup}",
+ "HTML", "XML", "conversion");
+ assertErrorContains(
+ "${xmlMarkup + htmlMarkup}",
+ "HTML", "XML", "Conversion", "common");
+ assertOutput(
+ "${xmlMarkup + htmlPlain}",
+ "<p>c</p>a < {h'}");
+ assertOutput(
+ "${xmlPlain + htmlMarkup}",
+ "a < {x'}<p>c");
+ assertOutput(
+ "${xmlPlain + htmlPlain}",
+ "a < {x'}a < {h'}");
+ assertOutput(
+ "${xmlPlain + htmlPlain + '\\''}",
+ "a < {x'}a < {h'}'");
+ assertOutput(
+ "${htmlPlain + xmlPlain + '\\''}",
+ "a < {h'}a < {x'}'");
+ assertOutput(
+ "${xmlPlain + htmlPlain + '\\''}",
+ "a < {x'}a < {h'}'");
+ assertOutput(
+ "<#ftl outputFormat='XML'>${htmlPlain + xmlPlain + '\\''}",
+ "a < {h'}a < {x'}'");
+ assertOutput(
+ "<#ftl outputFormat='RTF'>${htmlPlain + xmlPlain + '\\''}",
+ "a < \\{h'\\}a < \\{x'\\}'");
+ assertOutput(
+ "<#ftl outputFormat='XML'>${'\\'' + htmlPlain}",
+ "'a < {h'}");
+ assertOutput(
+ "<#ftl outputFormat='HTML'>${'\\'' + htmlPlain}",
+ "'a < {h'}");
+ assertOutput(
+ "<#ftl outputFormat='HTML'>${'\\'' + xmlPlain}",
+ "'a < {x'}");
+ assertOutput(
+ "<#ftl outputFormat='RTF'>${'\\'' + xmlPlain}",
+ "'a < \\{x'\\}");
+
+ assertOutput(
+ "<#assign x = '\\''><#assign x += xmlMarkup>${x}",
+ "'<p>c</p>");
+ assertOutput(
+ "<#assign x = xmlMarkup><#assign x += '\\''>${x}",
+ "<p>c</p>'");
+ assertOutput(
+ "<#assign x = xmlMarkup><#assign x += htmlPlain>${x}",
+ "<p>c</p>a < {h'}");
+ assertErrorContains(
+ "<#assign x = xmlMarkup><#assign x += htmlMarkup>${x}",
+ "HTML", "XML", "Conversion", "common");
+ }
+
+ @Test
+ public void testBlockAssignment() throws Exception {
+ for (String d : new String[] { "assign", "global", "local" }) {
+ String commonFTL =
+ "<#macro m>"
+ + "<#" + d + " x><p>${'&'}</#" + d + ">${x?isString?c} ${x} ${'&'} "
+ + "<#" + d + " x></#" + d + ">${x?isString?c}"
+ + "</#macro><@m />";
+ assertOutput(
+ commonFTL,
+ "true <p>& & true");
+ assertOutput(
+ "<#ftl outputFormat='HTML'>" + commonFTL,
+ "false <p>& & false");
+ }
+ }
+
+ @Test
+ public void testSpecialVariables() throws Exception {
+ String commonFTL = "${.outputFormat} ${.autoEsc?c}";
+
+ addTemplate("t.ftlx", commonFTL);
+ assertOutputForNamed("t.ftlx", "XML true");
+
+ addTemplate("t.ftlh", commonFTL);
+ assertOutputForNamed("t.ftlh", "HTML true");
+
+ addTemplate("t.ftl", commonFTL);
+ assertOutputForNamed("t.ftl", "undefined false");
+
+ addTemplate("tX.ftl", "<#ftl outputFormat='XML'>" + commonFTL);
+ addTemplate("tX.ftlx", commonFTL);
+ assertOutputForNamed("t.ftlx", "XML true");
+
+ addTemplate("tN.ftl", "<#ftl outputFormat='RTF' autoEsc=false>" + commonFTL);
+ assertOutputForNamed("tN.ftl", "RTF false");
+
+ assertOutput("${.output_format} ${.auto_esc?c}", "undefined false");
+ }
+
+ @Test
+ public void testEscAndNoEscBIBasics() throws IOException, TemplateException {
+ String commonFTL = "${'<x>'} ${'<x>'?esc} ${'<x>'?noEsc}";
+ addTemplate("t.ftlh", commonFTL);
+ addTemplate("t-noAuto.ftlh", "<#ftl autoEsc=false>" + commonFTL);
+ addTemplate("t.ftl", commonFTL);
+ assertOutputForNamed("t.ftlh", "<x> <x> <x>");
+ assertOutputForNamed("t-noAuto.ftlh", "<x> <x> <x>");
+ assertErrorContainsForNamed("t.ftl", "output format", "undefined");
+ }
+
+ @Test
+ public void testEscAndNoEscBIsOnMOs() throws IOException, TemplateException {
+ String xmlHdr = "<#ftl outputFormat='XML'>";
+
+ assertOutput(
+ xmlHdr + "${'&'?esc?esc} ${'&'?esc?noEsc} ${'&'?noEsc?esc} ${'&'?noEsc?noEsc}",
+ "& & & &");
+
+ for (String bi : new String[] { "esc", "noEsc" } ) {
+ assertOutput(
+ xmlHdr + "${rtfPlain?" + bi + "}",
+ "\\par a & b");
+ assertOutput(
+ xmlHdr + "<#setting numberFormat='0.0'>${1?" + bi + "}",
+ "1.0");
+ assertOutput(
+ xmlHdr + "<#setting booleanFormat='&y,&n'>${true?" + bi + "}",
+ bi.equals("esc") ? "&y" : "&y");
+ assertErrorContains(
+ xmlHdr + "${rtfMarkup?" + bi + "}",
+ "?" + bi, "output format", "RTF", "XML");
+ assertErrorContains(
+ xmlHdr + "${noSuchVar?" + bi + "}",
+ "noSuchVar", "null or missing");
+ assertErrorContains(
+ xmlHdr + "${[]?" + bi + "}",
+ "?" + bi, "xpected", "string", "sequence");
+ }
+ }
+
+ @Test
+ public void testMarkupStringBI() throws Exception {
+ assertOutput(
+ "${htmlPlain?markupString} ${htmlMarkup?markupString}",
+ "a < {h'} <p>c");
+ assertErrorContains(
+ "${noSuchVar?markupString}",
+ "noSuchVar", "null or missing");
+ assertErrorContains(
+ "${'x'?markupString}",
+ "xpected", "markup output", "string");
+ }
+
+ @Test
+ public void testOutputFormatDirective() throws Exception {
+ assertOutput(
+ "${.outputFormat}${'\\''} "
+ + "<#outputFormat 'HTML'>"
+ + "${.outputFormat}${'\\''} "
+ + "<#outputFormat 'XML'>${.outputFormat}${'\\''}</#outputFormat> "
+ + "${.outputFormat}${'\\''} "
+ + "</#outputFormat>"
+ + "${.outputFormat}${'\\''}",
+ "undefined' HTML' XML' HTML' undefined'");
+ assertOutput(
+ "<#ftl output_format='XML'>"
+ + "${.output_format}${'\\''} "
+ + "<#outputformat 'HTML'>${.output_format}${'\\''}</#outputformat> "
+ + "${.output_format}${'\\''}",
+ "XML' HTML' XML'");
+
+ // Custom format:
+ assertErrorContains(
+ "<#outputFormat 'dummy'></#outputFormat>",
+ "dummy", "nregistered");
+ setConfiguration(new TestConfigurationBuilder()
+ .registeredCustomOutputFormats(Collections.<OutputFormat>singleton(DummyOutputFormat.INSTANCE))
+ .build());
+ assertOutput(
+ "<#outputFormat 'dummy'>${.outputFormat}</#outputFormat>",
+ "dummy");
+
+ // Parse-time param expression:
+ assertOutput(
+ "<#outputFormat 'plain' + 'Text'>${.outputFormat}</#outputFormat>",
+ "plainText");
+ assertErrorContains(
+ "<#outputFormat 'plain' + someVar + 'Text'></#outputFormat>",
+ "someVar", "parse-time");
+ assertErrorContains(
+ "<#outputFormat 'plainText'?upperCase></#outputFormat>",
+ "?upperCase", "parse-time");
+ assertErrorContains(
+ "<#outputFormat true></#outputFormat>",
+ "string", "boolean");
+
+ // Naming convention:
+ assertErrorContains(
+ "<#outputFormat 'HTML'></#outputformat>",
+ "convention", "#outputFormat", "#outputformat");
+ assertErrorContains(
+ "<#outputformat 'HTML'></#outputFormat>",
+ "convention", "#outputFormat", "#outputformat");
+
+ // Empty block:
+ assertOutput(
+ "${.output_format} "
+ + "<#outputformat 'HTML'></#outputformat>"
+ + "${.output_format}",
+ "undefined undefined");
+
+ // WS stripping:
+ assertOutput(
+ "${.output_format}\n"
+ + "<#outputformat 'HTML'>\n"
+ + " x\n"
+ + "</#outputformat>\n"
+ + "${.output_format}",
+ "undefined\n x\nundefined");
+ }
+
+ @Test
+ public void testAutoEscAndNoAutoEscDirectives() throws Exception {
+ assertOutput(
+ "<#ftl outputFormat='XML'>"
+ + "${.autoEsc?c}${'&'} "
+ + "<#noAutoEsc>"
+ + "${.autoEsc?c}${'&'} "
+ + "<#autoEsc>${.autoEsc?c}${'&'}</#autoEsc> "
+ + "${.autoEsc?c}${'&'} "
+ + "</#noAutoEsc>"
+ + "${.autoEsc?c}${'&'}",
+ "true& false& true& false& true&");
+ assertOutput(
+ "<#ftl auto_esc=false output_format='XML'>"
+ + "${.auto_esc?c}${'&'} "
+ + "<#autoesc>${.auto_esc?c}${'&'}</#autoesc> "
+ + "${.auto_esc?c}${'&'}",
+ "false& true& false&");
+
+ // Bad came case:
+ assertErrorContains(
+ "<#noAutoesc></#noAutoesc>",
+ "Unknown directive");
+ assertErrorContains(
+ "<#noautoEsc></#noautoEsc>",
+ "Unknown directive");
+
+ setConfiguration(new TestConfigurationBuilder()
+ .outputFormat(XMLOutputFormat.INSTANCE)
+ .build());
+
+ // Empty block:
+ assertOutput(
+ "${.auto_esc?c} "
+ + "<#noautoesc></#noautoesc>"
+ + "${.auto_esc?c}",
+ "true true");
+
+ // WS stripping:
+ assertOutput(
+ "${.auto_esc?c}\n"
+ + "<#noautoesc>\n"
+ + " x\n"
+ + "</#noautoesc>\n"
+ + "${.auto_esc?c}",
+ "true\n x\ntrue");
+
+
+ // Naming convention:
+ assertErrorContains(
+ "<#autoEsc></#autoesc>",
+ "convention", "#autoEsc", "#autoesc");
+ assertErrorContains(
+ "<#autoesc></#autoEsc>",
+ "convention", "#autoEsc", "#autoesc");
+ assertErrorContains(
+ "<#noAutoEsc></#noautoesc>",
+ "convention", "#noAutoEsc", "#noautoesc");
+ assertErrorContains(
+ "<#noautoesc></#noAutoEsc>",
+ "convention", "#noAutoEsc", "#noautoesc");
+ }
+
+ @Test
+ public void testExplicitAutoEscBannedForNonMarkup() throws Exception {
+ // While this restriction is technically unnecessary, we can catch a dangerous and probably common user
+ // misunderstanding.
+ assertErrorContains("<#ftl autoEsc=true>", "can't do escaping", "undefined");
+ assertErrorContains("<#ftl outputFormat='plainText' autoEsc=true>", "can't do escaping", "plainText");
+ assertErrorContains("<#ftl autoEsc=true outputFormat='plainText'>", "can't do escaping", "plainText");
+ assertOutput("<#ftl autoEsc=true outputFormat='HTML'>", "");
+ assertOutput("<#ftl outputFormat='HTML' autoEsc=true>", "");
+ assertOutput("<#ftl autoEsc=false>", "");
+
+ assertErrorContains("<#autoEsc></#autoEsc>", "can't do escaping", "undefined");
+ assertErrorContains("<#ftl outputFormat='plainText'><#autoEsc></#autoEsc>", "can't do escaping", "plainText");
+ assertOutput("<#ftl outputFormat='plainText'><#outputFormat 'XML'><#autoEsc></#autoEsc></#outputFormat>", "");
+ assertOutput("<#ftl outputFormat='HTML'><#autoEsc></#autoEsc>", "");
+ assertOutput("<#noAutoEsc></#noAutoEsc>", "");
+ }
+
+ @Test
+ public void testAutoEscPolicy() throws Exception {
+ TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder();
+ cfgB.setRegisteredCustomOutputFormats(ImmutableList.<OutputFormat>of(
+ SeldomEscapedOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE));
+ assertEquals(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ String commonFTL = "${'.'} ${.autoEsc?c}";
+ String notEsced = ". false";
+ String esced = "\\. true";
+
+ for (int autoEscPolicy : new int[] {
+ ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY,
+ ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY,
+ DISABLE_AUTO_ESCAPING_POLICY }) {
+ cfgB.setAutoEscapingPolicy(autoEscPolicy);
+
+ String sExpted = autoEscPolicy == ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY ? esced : notEsced;
+ cfgB.setOutputFormat(SeldomEscapedOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput(commonFTL, sExpted);
+ cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("<#ftl outputFormat='seldomEscaped'>" + commonFTL, sExpted);
+ assertOutput("<#outputFormat 'seldomEscaped'>" + commonFTL + "</#outputFormat>", sExpted);
+
+ String dExpted = autoEscPolicy == DISABLE_AUTO_ESCAPING_POLICY ? notEsced : esced;
+ cfgB.setOutputFormat(DummyOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput(commonFTL, dExpted);
+ cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("<#ftl outputFormat='dummy'>" + commonFTL, dExpted);
+ assertOutput("<#outputFormat 'dummy'>" + commonFTL + "</#outputFormat>", dExpted);
+
+ cfgB.setOutputFormat(DummyOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput(
+ commonFTL
+ + "<#outputFormat 'seldomEscaped'>"
+ + commonFTL
+ + "<#outputFormat 'dummy'>"
+ + commonFTL
+ + "</#outputFormat>"
+ + commonFTL
+ + "<#outputFormat 'plainText'>"
+ + commonFTL
+ + "</#outputFormat>"
+ + commonFTL
+ + "<#noAutoEsc>"
+ + commonFTL
+ + "</#noAutoEsc>"
+ + commonFTL
+ + "<#autoEsc>"
+ + commonFTL
+ + "</#autoEsc>"
+ + commonFTL
+ + "</#outputFormat>"
+ + commonFTL
+ + "<#noAutoEsc>"
+ + commonFTL
+ + "</#noAutoEsc>"
+ + commonFTL
+ + "<#autoEsc>"
+ + commonFTL
+ + "</#autoEsc>"
+ + commonFTL
+ ,
+ dExpted
+ + sExpted
+ + dExpted
+ + sExpted
+ + notEsced
+ + sExpted
+ + notEsced
+ + sExpted
+ + esced
+ + sExpted
+ + dExpted
+ + notEsced
+ + dExpted
+ + esced
+ + dExpted);
+ }
+ }
+
+ @Test
+ public void testDynamicParsingBIsInherticContextOutputFormat() throws Exception {
+ // Dynamic parser BI-s are supposed to use the ParsingConfiguration of the calling template, and ignore anything
+ // inside the calling template itself. Except, the outputFormat and autoEscapingPolicy has to come from the
+ // calling lexical context.
+
+ String commonFTL
+ = "Eval: ${'.outputFormat'?eval}; "
+ + "Interpret: <#assign ipd = r\"${.outputFormat} ${'{&}'}\"?interpret><@ipd/>";
+ addTemplate("t.ftlh", commonFTL);
+ addTemplate("t2.ftlh", "<#outputFormat 'RTF'>" + commonFTL + "</#outputFormat>");
+
+ assertOutputForNamed(
+ "t.ftlh",
+ "Eval: HTML; Interpret: HTML {&}");
+ assertOutputForNamed(
+ "t2.ftlh",
+ "Eval: RTF; Interpret: RTF \\{&\\}");
+ assertOutput(
+ commonFTL,
+ "Eval: undefined; Interpret: undefined {&}");
+ assertOutput(
+ "<#ftl outputFormat='RTF'>" + commonFTL + "\n"
+ + "<#outputFormat 'XML'>" + commonFTL + "</#outputFormat>",
+ "Eval: RTF; Interpret: RTF \\{&\\}\n"
+ + "Eval: XML; Interpret: XML {&}");
+
+ // parser.autoEscapingPolicy is inherited too:
+ assertOutput(
+ "<#ftl autoEsc=false outputFormat='XML'>"
+ + commonFTL + " ${'.autoEsc'?eval?c}",
+ "Eval: XML; Interpret: XML {&} false");
+ assertOutput(
+ "<#ftl outputFormat='XML'>"
+ + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>",
+ "Eval: XML; Interpret: XML {&} false");
+ assertOutput(
+ "<#ftl autoEsc=false outputFormat='XML'>"
+ + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>",
+ "Eval: XML; Interpret: XML {&} false");
+ assertOutput(
+ "<#ftl autoEsc=false outputFormat='XML'>"
+ + "<#autoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#autoEsc>",
+ "Eval: XML; Interpret: XML {&} true");
+ assertOutput(
+ "${.outputFormat}<#assign ftl='<#ftl outputFormat=\\'RTF\\'>$\\{.outputFormat}'> <@ftl?interpret/>",
+ "undefined RTF");
+ assertOutput(
+ "${.outputFormat}<#outputFormat 'RTF'>"
+ + "<#assign ftl='$\\{.outputFormat}'> <@ftl?interpret/> ${'.outputFormat'?eval}"
+ + "</#outputFormat>",
+ "undefined RTF RTF");
+ }
+
+ @Test
+ public void testBannedBIsWhenAutoEscaping() throws Exception {
+ for (String biName : new String[] { "html", "xhtml", "rtf", "xml" }) {
+ String commonFTL = "${'x'?" + biName + "}";
+ assertOutput(commonFTL, "x");
+ assertErrorContains("<#ftl outputFormat='HTML'>" + commonFTL,
+ "?" + biName, "HTML", "double-escaping");
+ assertErrorContains("<#ftl outputFormat='HTML'>${'${\"x\"?" + biName + "}'}",
+ "?" + biName, "HTML", "double-escaping");
+ assertOutput("<#ftl outputFormat='plainText'>" + commonFTL, "x");
+ assertOutput("<#ftl outputFormat='HTML' autoEsc=false>" + commonFTL, "x");
+ assertOutput("<#ftl outputFormat='HTML'><#noAutoEsc>" + commonFTL + "</#noAutoEsc>", "x");
+ assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>",
+ "x");
+ }
+ }
+
+ @Test
+ public void testLegacyEscaperBIsBypassMOs() throws Exception {
+ assertOutput("${htmlPlain?html} ${htmlMarkup?html}", "a < {h'} <p>c");
+ assertErrorContains("${xmlPlain?html}", "?html", "string", "markup_output", "XML");
+ assertErrorContains("${xmlMarkup?html}", "?html", "string", "markup_output", "XML");
+ assertErrorContains("${rtfPlain?html}", "?html", "string", "markup_output", "RTF");
+ assertErrorContains("${rtfMarkup?html}", "?html", "string", "markup_output", "RTF");
+
+ assertOutput("${htmlPlain?xhtml} ${htmlMarkup?xhtml}", "a < {h'} <p>c");
+ assertErrorContains("${xmlPlain?xhtml}", "?xhtml", "string", "markup_output", "XML");
+ assertErrorContains("${xmlMarkup?xhtml}", "?xhtml", "string", "markup_output", "XML");
+ assertErrorContains("${rtfPlain?xhtml}", "?xhtml", "string", "markup_output", "RTF");
+ assertErrorContains("${rtfMarkup?xhtml}", "?xhtml", "string", "markup_output", "RTF");
+
+ assertOutput("${xmlPlain?xml} ${xmlMarkup?xml}", "a < {x'} <p>c</p>");
+ assertOutput("${htmlPlain?xml} ${htmlMarkup?xml}", "a < {h'} <p>c");
+ assertErrorContains("${rtfPlain?xml}", "?xml", "string", "markup_output", "RTF");
+ assertErrorContains("${rtfMarkup?xml}", "?xml", "string", "markup_output", "RTF");
+
+ assertOutput("${rtfPlain?rtf} ${rtfMarkup?rtf}", "\\\\par a & b \\par c");
+ assertErrorContains("${xmlPlain?rtf}", "?rtf", "string", "markup_output", "XML");
+ assertErrorContains("${xmlMarkup?rtf}", "?rtf", "string", "markup_output", "XML");
+ assertErrorContains("${htmlPlain?rtf}", "?rtf", "string", "markup_output", "HTML");
+ assertErrorContains("${htmlMarkup?rtf}", "?rtf", "string", "markup_output", "HTML");
+ }
+
+ @Test
+ public void testBannedDirectivesWhenAutoEscaping() throws Exception {
+ String commonFTL = "<#escape x as x?html>x</#escape>";
+ assertOutput(commonFTL, "x");
+ assertErrorContains("<#ftl outputFormat='HTML'>" + commonFTL, "escape", "HTML", "double-escaping");
+ assertOutput("<#ftl outputFormat='plainText'>" + commonFTL, "x");
+ assertOutput("<#ftl outputFormat='HTML' autoEsc=false>" + commonFTL, "x");
+ assertOutput("<#ftl outputFormat='HTML'><#noAutoEsc>" + commonFTL + "</#noAutoEsc>", "x");
+ assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>", "x");
+ }
+
+ @Test
+ public void testCombinedOutputFormats() throws Exception {
+ assertOutput(
+ "<#outputFormat 'XML{HTML}'>${'\\''}</#outputFormat>",
+ "&#39;");
+ assertOutput(
+ "<#outputFormat 'HTML{RTF{XML}}'>${'<a=\\'{}\\' />'}</#outputFormat>",
+ "&lt;a=&apos;\\{\\}&apos; /&gt;");
+
+ String commonFtl = "${'\\''} <#outputFormat '{HTML}'>${'\\''}</#outputFormat>";
+ String commonOutput = "' &#39;";
+ assertOutput(
+ "<#outputFormat 'XML'>" + commonFtl + "</#outputFormat>",
+ commonOutput);
+ assertOutput(
+ "<#ftl outputFormat='XML'>" + commonFtl,
+ commonOutput);
+ addTemplate("t.ftlx", commonFtl);
+ assertOutputForNamed(
+ "t.ftlx",
+ commonOutput);
+
+ assertErrorContains(
+ commonFtl,
+ ParseException.class, "{...}", "markup", UndefinedOutputFormat.INSTANCE.getName());
+ assertErrorContains(
+ "<#ftl outputFormat='plainText'>" + commonFtl,
+ ParseException.class, "{...}", "markup", PlainTextOutputFormat.INSTANCE.getName());
+ assertErrorContains(
+ "<#ftl outputFormat='RTF'><#outputFormat '{plainText}'></#outputFormat>",
+ ParseException.class, "{...}", "markup", PlainTextOutputFormat.INSTANCE.getName());
+ assertErrorContains(
+ "<#ftl outputFormat='RTF'><#outputFormat '{noSuchFormat}'></#outputFormat>",
+ ParseException.class, "noSuchFormat", "registered");
+ assertErrorContains(
+ "<#outputFormat 'noSuchFormat{HTML}'></#outputFormat>",
+ ParseException.class, "noSuchFormat", "registered");
+ assertErrorContains(
+ "<#outputFormat 'HTML{noSuchFormat}'></#outputFormat>",
+ ParseException.class, "noSuchFormat", "registered");
+ }
+
+ @Test
+ public void testHasContentBI() throws Exception {
+ assertOutput("${htmlMarkup?hasContent?c} ${htmlPlain?hasContent?c}", "true true");
+ assertOutput("<#ftl outputFormat='HTML'>${''?esc?hasContent?c} ${''?noEsc?hasContent?c}", "false false");
+ }
+
+ @Test
+ public void testMissingVariables() throws Exception {
+ for (String ftl : new String[] {
+ "${noSuchVar}",
+ "<#ftl outputFormat='XML'>${noSuchVar}",
+ "<#ftl outputFormat='XML'>${noSuchVar?esc}",
+ "<#ftl outputFormat='XML'>${'x'?esc + noSuchVar}"
+ }) {
+ assertErrorContains(ftl, InvalidReferenceException.class, "noSuchVar", "null or missing");
+ }
+ }
+
+ @Test
+ public void testIsMarkupOutputBI() throws Exception {
+ addToDataModel("m1", HTMLOutputFormat.INSTANCE.fromPlainTextByEscaping("x"));
+ addToDataModel("m2", HTMLOutputFormat.INSTANCE.fromMarkup("x"));
+ addToDataModel("s", "x");
+ assertOutput("${m1?isMarkupOutput?c} ${m2?isMarkupOutput?c} ${s?isMarkupOutput?c}", "true true false");
+ assertOutput("${m1?is_markup_output?c}", "true");
+ }
+
+ private TestConfigurationBuilder createDefaultConfigurationBuilder() throws TemplateModelException {
+ return new TestConfigurationBuilder()
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*.xml"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(XMLOutputFormat.INSTANCE)
+ .build()))
+ .cacheStorage(NullCacheStorage.INSTANCE); // Prevent caching as we change the cfgB between build().
+ }
+
+ @Before
+ public void addCommonDataModelVariables() throws TemplateModelException {
+ addToDataModel("rtfPlain", RTFOutputFormat.INSTANCE.fromPlainTextByEscaping("\\par a & b"));
+ addToDataModel("rtfMarkup", RTFOutputFormat.INSTANCE.fromMarkup("\\par c"));
+ addToDataModel("htmlPlain", HTMLOutputFormat.INSTANCE.fromPlainTextByEscaping("a < {h'}"));
+ addToDataModel("htmlMarkup", HTMLOutputFormat.INSTANCE.fromMarkup("<p>c"));
+ addToDataModel("xmlPlain", XMLOutputFormat.INSTANCE.fromPlainTextByEscaping("a < {x'}"));
+ addToDataModel("xmlMarkup", XMLOutputFormat.INSTANCE.fromMarkup("<p>c</p>"));
+ }
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws TemplateModelException {
+ return createDefaultConfigurationBuilder().build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
new file mode 100644
index 0000000..77b46de
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParseTimeParameterBIErrorMessagesTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.core;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class ParseTimeParameterBIErrorMessagesTest extends TemplateTest {
+
+ @Test
+ public void testThen() throws Exception {
+ assertErrorContains("${true?then}", "expecting", "\"(\"");
+ assertErrorContains("${true?then + 1}", "expecting", "\"(\"");
+ assertErrorContains("${true?then()}", "?then", "2 parameters");
+ assertErrorContains("${true?then(1)}", "?then", "2 parameters");
+ assertOutput("${true?then(1, 2)}", "1");
+ assertErrorContains("${true?then(1, 2, 3)}", "?then", "2 parameters");
+ }
+
+ @Test
+ public void testSwitch() throws Exception {
+ assertErrorContains("${true?switch}", "expecting", "\"(\"");
+ assertErrorContains("${true?switch + 1}", "expecting", "\"(\"");
+ assertErrorContains("${true?switch()}", "at least 2 parameters");
+ assertErrorContains("${true?switch(true)}", "at least 2 parameters");
+ assertOutput("${true?switch(true, 1)}", "1");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
new file mode 100644
index 0000000..8f20d6c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class ParsingErrorMessagesTest {
+
+ private Configuration cfg = new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
+ .build();
+
+ @Test
+ public void testNeedlessInterpolation() {
+ assertErrorContains("<#if ${x} == 3></#if>", "instead of ${");
+ assertErrorContains("<#if ${x == 3}></#if>", "instead of ${");
+ assertErrorContains("<@foo ${x == 3} />", "instead of ${");
+ }
+
+ @Test
+ public void testWrongDirectiveNames() {
+ assertErrorContains("<#foo />", "nknown directive", "#foo");
+ assertErrorContains("<#set x = 1 />", "nknown directive", "#set", "#assign");
+ assertErrorContains("<#iterator></#iterator>", "nknown directive", "#iterator", "#list");
+ }
+
+ @Test
+ public void testBug402() {
+ assertErrorContains("<#list 1..i as k>${k}<#list>", "existing directive", "malformed", "#list");
+ assertErrorContains("<#assign>", "existing directive", "malformed", "#assign");
+ assertErrorContains("</#if x>", "existing directive", "malformed", "#if");
+ assertErrorContains("<#compress x>", "existing directive", "malformed", "#compress");
+ }
+
+ @Test
+ public void testUnclosedDirectives() {
+ assertErrorContains("<#macro x>", "#macro", "unclosed");
+ assertErrorContains("<#function x>", "#macro", "unclosed");
+ assertErrorContains("<#assign x>", "#assign", "unclosed");
+ assertErrorContains("<#macro m><#local x>", "#local", "unclosed");
+ assertErrorContains("<#global x>", "#global", "unclosed");
+ assertErrorContains("<@foo>", "@...", "unclosed");
+ assertErrorContains("<#list xs as x>", "#list", "unclosed");
+ assertErrorContains("<#list xs as x><#if x>", "#if", "unclosed");
+ assertErrorContains("<#list xs as x><#if x><#if q><#else>", "#if", "unclosed");
+ assertErrorContains("<#list xs as x><#if x><#if q><#else><#macro x>qwe", "#macro", "unclosed");
+ assertErrorContains("${(blah", "\"(\"", "unclosed");
+ assertErrorContains("${blah", "\"{\"", "unclosed");
+ }
+
+ @Test
+ public void testInterpolatingClosingsErrors() {
+ assertErrorContains("${x", "unclosed");
+ assertErrorContains("<#assign x = x}>", "\"}\"", "open");
+ // TODO assertErrorContains("<#assign x = '${x'>", "unclosed");
+ }
+
+ private void assertErrorContains(String ftl, String... expectedSubstrings) {
+ assertErrorContains(false, ftl, expectedSubstrings);
+ assertErrorContains(true, ftl, expectedSubstrings);
+ }
+
+ private void assertErrorContains(boolean squareTags, String ftl, String... expectedSubstrings) {
+ try {
+ if (squareTags) {
+ ftl = ftl.replace('<', '[').replace('>', ']');
+ }
+ new Template("adhoc", ftl, cfg);
+ fail("The template had to fail");
+ } catch (ParseException e) {
+ String msg = e.getMessage();
+ for (String needle: expectedSubstrings) {
+ if (needle.startsWith("\\!")) {
+ String netNeedle = needle.substring(2);
+ if (msg.contains(netNeedle)) {
+ fail("The message shouldn't contain substring " + _StringUtil.jQuote(netNeedle) + ":\n" + msg);
+ }
+ } else if (!msg.contains(needle)) {
+ fail("The message didn't contain substring " + _StringUtil.jQuote(needle) + ":\n" + msg);
+ }
+ }
+ showError(e);
+ } catch (IOException e) {
+ // Won't happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void showError(Throwable e) {
+ //System.out.println(e);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
new file mode 100644
index 0000000..702a254
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjectWrapperTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.DefaultArrayAdapter;
+import org.apache.freemarker.core.model.impl.DefaultListAdapter;
+import org.apache.freemarker.core.model.impl.DefaultMapAdapter;
+import org.apache.freemarker.core.model.impl.DefaultNonListCollectionAdapter;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapperTest.TestBean;
+import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleDate;
+import org.apache.freemarker.core.model.impl.SimpleNumber;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.junit.Test;
+
+public class RestrictedObjectWrapperTest {
+
+ @Test
+ public void testBasics() throws TemplateModelException {
+ PostConstruct.class.toString();
+ RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ testCustomizationCommonPart(ow);
+ assertTrue(ow.wrap(Collections.emptyMap()) instanceof DefaultMapAdapter);
+ assertTrue(ow.wrap(Collections.emptyList()) instanceof DefaultListAdapter);
+ assertTrue(ow.wrap(new boolean[] { }) instanceof DefaultArrayAdapter);
+ assertTrue(ow.wrap(new HashSet()) instanceof DefaultNonListCollectionAdapter);
+ }
+
+ @SuppressWarnings("boxing")
+ private void testCustomizationCommonPart(RestrictedObjectWrapper ow) throws TemplateModelException {
+ assertTrue(ow.wrap("x") instanceof SimpleScalar);
+ assertTrue(ow.wrap(1.5) instanceof SimpleNumber);
+ assertTrue(ow.wrap(new Date()) instanceof SimpleDate);
+ assertEquals(TemplateBooleanModel.TRUE, ow.wrap(true));
+
+ try {
+ ow.wrap(new TestBean());
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("type"));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
new file mode 100644
index 0000000..43ff3bf
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/RestrictedObjetWrapperTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateCollectionModelEx;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx2;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateModelWithAPISupport;
+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.RestrictedObjectWrapper;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class RestrictedObjetWrapperTest {
+
+ @Test
+ public void testDoesNotAllowAPIBuiltin() throws TemplateModelException {
+ RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ TemplateModelWithAPISupport map = (TemplateModelWithAPISupport) sow.wrap(new HashMap());
+ try {
+ map.getAPI();
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString("?api"));
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testCanWrapBasicTypes() throws TemplateModelException {
+ RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertTrue(sow.wrap("s") instanceof TemplateScalarModel);
+ assertTrue(sow.wrap(1) instanceof TemplateNumberModel);
+ assertTrue(sow.wrap(true) instanceof TemplateBooleanModel);
+ assertTrue(sow.wrap(new Date()) instanceof TemplateDateModel);
+ assertTrue(sow.wrap(new ArrayList()) instanceof TemplateSequenceModel);
+ assertTrue(sow.wrap(new String[0]) instanceof TemplateSequenceModel);
+ assertTrue(sow.wrap(new ArrayList().iterator()) instanceof TemplateCollectionModel);
+ assertTrue(sow.wrap(new HashSet()) instanceof TemplateCollectionModelEx);
+ assertTrue(sow.wrap(new HashMap()) instanceof TemplateHashModelEx2);
+ assertNull(sow.wrap(null));
+ }
+
+ @Test
+ public void testWontWrapDOM() throws SAXException, IOException, ParserConfigurationException,
+ TemplateModelException {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ InputSource is = new InputSource();
+ is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
+ Document doc = db.parse(is);
+
+ RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ try {
+ sow.wrap(doc);
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("won't wrap"));
+ }
+ }
+
+ @Test
+ public void testWontWrapGenericObjects() {
+ RestrictedObjectWrapper sow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ try {
+ sow.wrap(new File("/x"));
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("won't wrap"));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
new file mode 100644
index 0000000..cf14b93
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
@@ -0,0 +1,371 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.util._DateUtil;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class SQLTimeZoneTest extends TemplateTest {
+
+ private final static TimeZone GMT_P02 = TimeZone.getTimeZone("GMT+02");
+
+ private TimeZone lastDefaultTimeZone;
+
+ private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
+ {
+ df.setTimeZone(_DateUtil.UTC);
+ }
+
+ // Values that JDBC in GMT+02 would produce
+ private final java.sql.Date sqlDate = new java.sql.Date(utcToLong("2014-07-11T22:00:00")); // 2014-07-12
+ private final Time sqlTime = new Time(utcToLong("1970-01-01T10:30:05")); // 12:30:05
+ private final Timestamp sqlTimestamp = new Timestamp(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05
+ private final Date javaDate = new Date(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05
+ private final Date javaDayErrorDate = new Date(utcToLong("2014-07-11T22:00:00")); // 2014-07-12T12:30:05
+
+ public TimeZone getLastDefaultTimeZone() {
+ return lastDefaultTimeZone;
+ }
+
+ public void setLastDefaultTimeZone(TimeZone lastDefaultTimeZone) {
+ this.lastDefaultTimeZone = lastDefaultTimeZone;
+ }
+
+ public java.sql.Date getSqlDate() {
+ return sqlDate;
+ }
+
+ public Time getSqlTime() {
+ return sqlTime;
+ }
+
+ public Timestamp getSqlTimestamp() {
+ return sqlTimestamp;
+ }
+
+ public Date getJavaDate() {
+ return javaDate;
+ }
+
+ public Date getJavaDayErrorDate() {
+ return javaDayErrorDate;
+ }
+
+ private static final String FTL =
+ "${sqlDate} ${sqlTime} ${sqlTimestamp} ${javaDate?datetime}\n"
+ + "${sqlDate?string.iso_fz} ${sqlTime?string.iso_fz} "
+ + "${sqlTimestamp?string.iso_fz} ${javaDate?datetime?string.iso_fz}\n"
+ + "${sqlDate?string.xs_fz} ${sqlTime?string.xs_fz} "
+ + "${sqlTimestamp?string.xs_fz} ${javaDate?datetime?string.xs_fz}\n"
+ + "${sqlDate?string.xs} ${sqlTime?string.xs} "
+ + "${sqlTimestamp?string.xs} ${javaDate?datetime?string.xs}\n"
+ + "<#setting time_zone='GMT'>\n"
+ + "${sqlDate} ${sqlTime} ${sqlTimestamp} ${javaDate?datetime}\n"
+ + "${sqlDate?string.iso_fz} ${sqlTime?string.iso_fz} "
+ + "${sqlTimestamp?string.iso_fz} ${javaDate?datetime?string.iso_fz}\n"
+ + "${sqlDate?string.xs_fz} ${sqlTime?string.xs_fz} "
+ + "${sqlTimestamp?string.xs_fz} ${javaDate?datetime?string.xs_fz}\n"
+ + "${sqlDate?string.xs} ${sqlTime?string.xs} "
+ + "${sqlTimestamp?string.xs} ${javaDate?datetime?string.xs}\n";
+
+ private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2
+ = "2014-07-12 12:30:05 2014-07-12T12:30:05 2014-07-12T12:30:05\n"
+ + "2014-07-12 12:30:05+02:00 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n"
+ + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n"
+ + "2014-07-12 12:30:05 2014-07-12T12:30:05+02:00 2014-07-12T12:30:05+02:00\n";
+
+ private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_DIFFERENT
+ = "2014-07-12 12:30:05 2014-07-12T11:30:05 2014-07-12T11:30:05\n"
+ + "2014-07-12 12:30:05+02:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
+ + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
+ + "2014-07-12 12:30:05 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n";
+
+ private static final String OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_SAME
+ = "2014-07-11 11:30:05 2014-07-12T11:30:05 2014-07-12T11:30:05\n"
+ + "2014-07-11 11:30:05+01:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
+ + "2014-07-11+01:00 11:30:05+01:00 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n"
+ + "2014-07-11 11:30:05 2014-07-12T11:30:05+01:00 2014-07-12T11:30:05+01:00\n";
+
+ private static final String OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME
+ = "2014-07-11 10:30:05 2014-07-12T10:30:05 2014-07-12T10:30:05\n"
+ + "2014-07-11 10:30:05Z 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
+ + "2014-07-11Z 10:30:05Z 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
+ + "2014-07-11 10:30:05 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n";
+
+ private static final String OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT
+ = "2014-07-12 12:30:05 2014-07-12T10:30:05 2014-07-12T10:30:05\n"
+ + "2014-07-12 12:30:05+02:00 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
+ + "2014-07-12+02:00 12:30:05+02:00 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n"
+ + "2014-07-12 12:30:05 2014-07-12T10:30:05Z 2014-07-12T10:30:05Z\n";
+
+ @Test
+ public void testWithDefaultTZAndNullSQL() throws Exception {
+ TimeZone prevSysDefTz = TimeZone.getDefault();
+ TimeZone.setDefault(GMT_P02);
+ try {
+ Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder();
+ cfgB.unsetTimeZone();
+ setConfiguration(cfgB.build());
+
+ assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
+ assertEquals(TimeZone.getDefault(), getConfiguration().getTimeZone());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
+ } finally {
+ TimeZone.setDefault(prevSysDefTz);
+ }
+ }
+
+ @Test
+ public void testWithDefaultTZAndGMT2SQL() throws Exception {
+ TimeZone prevSysDefTz = TimeZone.getDefault();
+ TimeZone.setDefault(GMT_P02);
+ try {
+ Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder();
+ cfgB.sqlDateAndTimeTimeZone(GMT_P02).unsetTimeZone();
+ setConfiguration(cfgB.build());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
+ } finally {
+ TimeZone.setDefault(prevSysDefTz);
+ }
+ }
+
+ @Test
+ public void testWithGMT1AndNullSQL() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .timeZone(TimeZone.getTimeZone("GMT+01:00"))
+ .build());
+ assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_SAME + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
+ }
+
+ @Test
+ public void testWithGMT1AndGMT2SQL() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .sqlDateAndTimeTimeZone(GMT_P02)
+ .timeZone(TimeZone.getTimeZone("GMT+01:00"))
+ .build());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT1_SQL_DIFFERENT + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
+ }
+
+ @Test
+ public void testWithGMT2AndNullSQL() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .timeZone(TimeZone.getTimeZone("GMT+02"))
+ .build());
+ assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_SAME);
+ }
+
+ @Test
+ public void testWithGMT2AndGMT2SQL() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .sqlDateAndTimeTimeZone(GMT_P02)
+ .timeZone(TimeZone.getTimeZone("GMT+02"))
+ .build());
+
+ assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);
+ }
+
+ @Test
+ public void testCacheFlushings() throws Exception {
+ Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder()
+ .timeZone(_DateUtil.UTC)
+ .dateFormat("yyyy-MM-dd E")
+ .timeFormat("HH:mm:ss E")
+ .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss E");
+
+ setConfiguration(cfgB.build());
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting locale='de'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-11 Fr, 10:30:05 Do, 2014-07-12T10:30:05 Sa, 2014-07-12T10:30:05 Sa, 2014-07-12 Sa, 10:30:05 Sa\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting date_format='yyyy-MM-dd'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-11, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12, 10:30:05 Sat\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting time_format='HH:mm:ss'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-11 Fri, 10:30:05, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting datetime_format='yyyy-MM-dd\\'T\\'HH:mm:ss'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n");
+
+ setConfiguration(cfgB.sqlDateAndTimeTimeZone(GMT_P02).build());
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting locale='de'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-12 Sa, 12:30:05 Do, 2014-07-12T10:30:05 Sa, 2014-07-12T10:30:05 Sa, 2014-07-12 Sa, 10:30:05 Sa\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting date_format='yyyy-MM-dd'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-12, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12, 10:30:05 Sat\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting time_format='HH:mm:ss'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-12 Sat, 12:30:05, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05\n");
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n"
+ + "<#setting datetime_format='yyyy-MM-dd\\'T\\'HH:mm:ss'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n",
+ "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n"
+ + "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n");
+ }
+
+ @Test
+ public void testDateAndTimeBuiltInsHasNoEffect() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .timeZone(_DateUtil.UTC)
+ .sqlDateAndTimeTimeZone(GMT_P02)
+ .build());
+
+ assertOutput(
+ "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
+ + "${sqlDate?date} ${sqlTime?time}\n"
+ + "<#setting time_zone='GMT+02'>\n"
+ + "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
+ + "${sqlDate?date} ${sqlTime?time}\n"
+ + "<#setting time_zone='GMT-11'>\n"
+ + "${javaDayErrorDate?date} ${javaDayErrorDate?time} ${sqlTimestamp?date} ${sqlTimestamp?time} "
+ + "${sqlDate?date} ${sqlTime?time}\n",
+ "2014-07-11 22:00:00 2014-07-12 10:30:05 2014-07-12 12:30:05\n"
+ + "2014-07-12 00:00:00 2014-07-12 12:30:05 2014-07-12 12:30:05\n"
+ + "2014-07-11 11:00:00 2014-07-11 23:30:05 2014-07-12 12:30:05\n");
+ }
+
+ @Test
+ public void testChangeSettingInTemplate() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .timeZone(_DateUtil.UTC)
+ .build());
+
+ assertNull(getConfiguration().getSQLDateAndTimeTimeZone());
+
+ assertOutput(
+ "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting sql_date_and_time_time_zone='GMT+02'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting sql_date_and_time_time_zone='null'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting time_zone='GMT+03'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting sql_date_and_time_time_zone='GMT+02'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting sql_date_and_time_time_zone='GMT-11'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting date_format='xs fz'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting time_format='xs fz'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n"
+ + "<#setting datetime_format='iso m'>\n"
+ + "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}\n",
+ "2014-07-11, 10:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
+ + "2014-07-12, 12:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
+ + "2014-07-11, 10:30:05, 2014-07-12T10:30:05, 2014-07-12T10:30:05\n"
+ + "2014-07-12, 13:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
+ + "2014-07-12, 12:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
+ + "2014-07-11, 23:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
+ + "2014-07-11-11:00, 23:30:05, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
+ + "2014-07-11-11:00, 23:30:05-11:00, 2014-07-12T13:30:05, 2014-07-12T13:30:05\n"
+ + "2014-07-11-11:00, 23:30:05-11:00, 2014-07-12T13:30+03:00, 2014-07-12T13:30+03:00\n");
+ }
+
+ @Test
+ public void testFormatUTCFlagHasNoEffect() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .sqlDateAndTimeTimeZone(GMT_P02)
+ .timeZone(TimeZone.getTimeZone("GMT-01"))
+ .build());
+
+ assertOutput(
+ "<#setting date_format='xs fz'><#setting time_format='xs fz'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
+ + "<#setting date_format='xs fz u'><#setting time_format='xs fz u'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
+ + "<#setting sql_date_and_time_time_zone='GMT+03'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
+ + "<#setting sql_date_and_time_time_zone='null'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
+ + "<#setting date_format='xs fz'><#setting time_format='xs fz'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n"
+ + "<#setting date_format='xs fz fu'><#setting time_format='xs fz fu'>\n"
+ + "${sqlDate}, ${sqlTime}, ${javaDate?time}\n",
+ "2014-07-12+02:00, 12:30:05+02:00, 09:30:05-01:00\n"
+ + "2014-07-12+02:00, 12:30:05+02:00, 10:30:05Z\n"
+ + "2014-07-12+03:00, 13:30:05+03:00, 10:30:05Z\n"
+ + "2014-07-11-01:00, 09:30:05-01:00, 10:30:05Z\n"
+ + "2014-07-11-01:00, 09:30:05-01:00, 09:30:05-01:00\n"
+ + "2014-07-11Z, 10:30:05Z, 10:30:05Z\n");
+ }
+
+ private Configuration.ExtendableBuilder<?> createConfigurationBuilder() {
+ return new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .locale(Locale.US)
+ .dateFormat("yyyy-MM-dd")
+ .timeFormat("HH:mm:ss")
+ .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss");
+ }
+
+ @Override
+ protected Object createDataModel() {
+ return this;
+ }
+
+ private long utcToLong(String isoDateTime) {
+ try {
+ return df.parse(isoDateTime).getTime();
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
[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
Posted by dd...@apache.org.
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!" );
+ }
+}
[29/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
new file mode 100644
index 0000000..1b4e007
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros2.txt
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+1 1
+2 2
+4
+m3 with d="4" Failed!
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
new file mode 100644
index 0000000..54ec68d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/multimodels.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Test of Multiple Model implementations</title>
+</head>
+<body>
+
+<p>Let's begin with a simple model:</p>
+<p>Hello, world!</p>
+
+<p>Cool, now get into the first model. This implements a scalar, list, and
+hash as a single class. Let's try some tests...</p>
+
+<p>MultiModel1 as a string!</p>
+
+<p>Now as a list...</p>
+
+Model1 value: 0<br />
+Model1 value: 1<br />
+Model1 value: 2<br />
+Model1 value: 3<br />
+Model1 value: 4<br />
+Model1 value: 5<br />
+Model1 value: 6<br />
+Model1 value: 7<br />
+Model1 value: 8<br />
+Model1 value: 9<br />
+Model3 is alive!<br />
+
+<p>Index into a list...</p>
+<p>Model1 value: 1</p>
+<p>List size is: Nasty!</p>
+<p>List size is: Nasty!</p>
+
+<p>Now, again, as a hash. First using dot notation, then using [] notation:</p>
+
+<p>Selftest of a hash from MultiModel1</p>
+<p>Selftest of a hash from MultiModel1</p>
+
+<p>Now for the tricky stuff... use a model to index into another model...</p>
+<p>selftest</p>
+<p>Selftest of a hash from MultiModel1</p>
+<p>self</p>
+<p>Selftest of a hash from MultiModel1</p>
+
+<p>Same thing, this time a List index...</p>
+<p>0</p>
+<p>Model1 value: 0</p>
+<p>Model1 value: 1</p>
+
+<p>Now, do the same recursively...</p>
+<p>MultiModel1 as a string!</p>
+<p>Model2 is alive!</p>
+<p>Arguments are:<br />test<br /></p>
+<p>Arguments are:<br />MultiModel1 as a string!<br />Selftest of a hash from MultiModel1<br />Hello, world!<br /></p>
+
+<p>Does this really not work?</p>
+<p>Model3 is alive!</p>
+<p>Selftest from MultiModel3!</p>
+<p>Hello world from MultiModel3!</p>
+
+<p>(Again, with Hashes)</p>
+<p>Model3 is alive!</p>
+<p>Selftest from MultiModel3!</p>
+
+<p>Model3 is alive!</p>
+<p>Selftest from MultiModel3!</p>
+<p>Selftest from MultiModel3!</p>
+
+<p>As I suspected! (Manual on Expressions needs updating.)</p>
+
+<p>Second test on list size</p>
+<p>Key size, not the listSize method.</p>
+<p>Key size, not the listSize method.</p>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
new file mode 100644
index 0000000..bcfb104
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/nested.txt
@@ -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.
+ */
+ test 3/1: undefined undefined undefined
+ test 3/2: undefined undefined undefined
+ test 3/3: undefined undefined undefined
+
+ test 3/1: Y X Count 1
+ test 3/2: Y X Count 2
+ test 3/3: Y X Count 3
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
new file mode 100644
index 0000000..b8384c7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-allowsnothing.txt
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+fails
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
new file mode 100644
index 0000000..35e7a3e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-defaultresolver.txt
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+works
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
new file mode 100644
index 0000000..9d8e883
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/new-optin.txt
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+works
+fails
+
+works
+works
+
+works
+fails
+
+works
+fails
+
+works
+works
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
new file mode 100644
index 0000000..bc58731
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines1.txt
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Newlines Test</title>
+</head>
+<body>
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
new file mode 100644
index 0000000..c131421
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/newlines2.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Newlines the Second Test</title>
+</head>
+<body>
+<p>A simple test follows:</p>
+
+<p>Hello, world!
+</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
new file mode 100644
index 0000000..5e8486c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/noparse.txt
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: NoParse Test</title>
+</head>
+<body>
+
+A simple test follows:
+
+${message}
+
+A more rigorous test, showing that we're not faking it:
+
+${message@#$%&}
+
+ <p>Message exists!
+ ...and even generates output!
+ <#if message>
+ Nested statements are ok, too.
+ </#if>
+ </p>
+
+Here's another edge case, this time, trying to output a <noparse>
+inside another <noparse>
+
+
+This is what the noparse instruction looks like:
+
+<#noparse>This part of the template wont be parsed by the
+FreeMarker parser. Instead, it will be treated as verbatim text information,
+and output as such.</#noparse>
+
+The rest of the template appears here.
+
+Simple.
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
new file mode 100644
index 0000000..a6f8475
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-format.txt
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+1
+1
+1 234 567,89
+1234567.886
+1,00
+1
+1234567,89
+1234567.886
+1
+1
+1.000000000000001
+0.0000000000000001
+-0.0000000000000001
+1
+0.0000000000000001
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
new file mode 100644
index 0000000..b80bc85
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-literal.txt
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Number Literal Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now perform a number assignment:</p>
+
+1,3
+
+
+My number is: 1,8
+My float is: 1.800000
+The int part is: 1
+
+
+1.83
+
+<p>Now use numbers in assignment</p>
+
+6
+
+8
+
+<p>Try numbers in tests</p>
+
+MyMessage is not 152, its: 8.
+
+<if (mymessage > 5)>
+ MyMessage is greater than five.
+</if
+
+ MyMessage is: 8.
+
+<p>Now for numbers in dynamic keys:</p>
+
+
+one
+three
+
+<p>Numbers in hashes:</p>
+
+twelve
+twelve
+twelve
+
+
+<p>Numbers in method calls:</p>
+
+Single argument value is: 1
+Single argument value is: 1
+Single argument value is: 12
+Single argument value is: 3
+Single argument value is: 3
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
new file mode 100644
index 0000000..bc8a10e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/number-to-date.txt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
+2011-05-16 == 2011-05-16
+19:47:55.54Z == 19:47:55.54Z
+
+2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
+2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
+2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
+2011-05-16T19:47:55.54Z == 2011-05-16T19:47:55.54Z
+1970-01-01T00:00:01Z == 1970-01-01T00:00:01Z
+1970-01-01T00:00:01Z == 1970-01-01T00:00:01Z
+1970-01-01T00:00:00Z == 1970-01-01T00:00:00Z
+
+failed
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
new file mode 100644
index 0000000..3bf6cd0
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/numerical-cast.txt
@@ -0,0 +1,462 @@
+/*
+ * 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.
+ */
+
+?int:
+ 0?int=0
+ 1?int=1
+ -1?int=-1
+ 0.5?int=0
+ 1.5?int=1
+ -0.5?int=0
+ -1.5?int=-1
+ 0.25?int=0
+ -0.25?int=0
+ 1.75?int=1
+ -1.75?int=-1
+ 1.01?int=1
+ -1.01?int=-1
+ 0.01?int=0
+ -0.01?int=0
+ 127?int=127
+ 128?int=128
+ -127?int=-127
+ -128?int=-128
+ 32767?int=32767
+ 32768?int=32768
+ -32767?int=-32767
+ -32768?int=-32768
+ 2147483647?int=2147483647
+ 2147483648?int=-2147483648
+ -2147483647?int=-2147483647
+ -2147483648?int=-2147483648
+ 4294967295?int=-1
+ 4294967296?int=0
+ -4294967295?int=1
+ -4294967296?int=0
+ 2147483647.1?int=2147483647
+ 2147483648.1?int=-2147483648
+ -2147483647.1?int=-2147483647
+ -2147483648.1?int=-2147483648
+ 4294967295.1?int=-1
+ 4294967296.1?int=0
+ -4294967295.1?int=1
+ -4294967296.1?int=0
+ 2147483647.5?int=2147483647
+ 2147483648.5?int=-2147483648
+ -2147483647.5?int=-2147483647
+ -2147483648.5?int=-2147483648
+ 4294967295.5?int=-1
+ 4294967296.5?int=0
+ -4294967295.5?int=1
+ -4294967296.5?int=0
+
+?double
+ 0?double=0
+ 1?double=1
+ -1?double=-1
+ 0.5?double=0.5
+ 1.5?double=1.5
+ -0.5?double=-0.5
+ -1.5?double=-1.5
+ 0.25?double=0.25
+ -0.25?double=-0.25
+ 1.75?double=1.75
+ -1.75?double=-1.75
+ 1.01?double=1.01
+ -1.01?double=-1.01
+ 0.01?double=0.01
+ -0.01?double=-0.01
+ 127?double=127
+ 128?double=128
+ -127?double=-127
+ -128?double=-128
+ 32767?double=32767
+ 32768?double=32768
+ -32767?double=-32767
+ -32768?double=-32768
+ 2147483647?double=2147483647
+ 2147483648?double=2147483648
+ -2147483647?double=-2147483647
+ -2147483648?double=-2147483648
+ 4294967295?double=4294967295
+ 4294967296?double=4294967296
+ -4294967295?double=-4294967295
+ -4294967296?double=-4294967296
+ 2147483647.1?double=2147483647.1
+ 2147483648.1?double=2147483648.1
+ -2147483647.1?double=-2147483647.1
+ -2147483648.1?double=-2147483648.1
+ 4294967295.1?double=4294967295.1
+ 4294967296.1?double=4294967296.1
+ -4294967295.1?double=-4294967295.1
+ -4294967296.1?double=-4294967296.1
+ 2147483647.5?double=2147483647.5
+ 2147483648.5?double=2147483648.5
+ -2147483647.5?double=-2147483647.5
+ -2147483648.5?double=-2147483648.5
+ 4294967295.5?double=4294967295.5
+ 4294967296.5?double=4294967296.5
+ -4294967295.5?double=-4294967295.5
+ -4294967296.5?double=-4294967296.5
+
+?long
+ 0?long=0
+ 1?long=1
+ -1?long=-1
+ 0.5?long=0
+ 1.5?long=1
+ -0.5?long=0
+ -1.5?long=-1
+ 0.25?long=0
+ -0.25?long=0
+ 1.75?long=1
+ -1.75?long=-1
+ 1.01?long=1
+ -1.01?long=-1
+ 0.01?long=0
+ -0.01?long=0
+ 127?long=127
+ 128?long=128
+ -127?long=-127
+ -128?long=-128
+ 32767?long=32767
+ 32768?long=32768
+ -32767?long=-32767
+ -32768?long=-32768
+ 2147483647?long=2147483647
+ 2147483648?long=2147483648
+ -2147483647?long=-2147483647
+ -2147483648?long=-2147483648
+ 4294967295?long=4294967295
+ 4294967296?long=4294967296
+ -4294967295?long=-4294967295
+ -4294967296?long=-4294967296
+ 2147483647.1?long=2147483647
+ 2147483648.1?long=2147483648
+ -2147483647.1?long=-2147483647
+ -2147483648.1?long=-2147483648
+ 4294967295.1?long=4294967295
+ 4294967296.1?long=4294967296
+ -4294967295.1?long=-4294967295
+ -4294967296.1?long=-4294967296
+ 2147483647.5?long=2147483647
+ 2147483648.5?long=2147483648
+ -2147483647.5?long=-2147483647
+ -2147483648.5?long=-2147483648
+ 4294967295.5?long=4294967295
+ 4294967296.5?long=4294967296
+ -4294967295.5?long=-4294967295
+ -4294967296.5?long=-4294967296
+
+?long from date
+ 1304877615000 = 1304877615000
+
+?float
+ 0?float=0
+ 1?float=1
+ -1?float=-1
+ 0.5?float=0.5
+ 1.5?float=1.5
+ -0.5?float=-0.5
+ -1.5?float=-1.5
+ 0.25?float=0.25
+ -0.25?float=-0.25
+ 1.75?float=1.75
+ -1.75?float=-1.75
+ 1.01?float=1.00999999
+ -1.01?float=-1.00999999
+ 0.01?float=0.01
+ -0.01?float=-0.01
+ 127?float=127
+ 128?float=128
+ -127?float=-127
+ -128?float=-128
+ 32767?float=32767
+ 32768?float=32768
+ -32767?float=-32767
+ -32768?float=-32768
+ 2147483647?float=2147483648
+ 2147483648?float=2147483648
+ -2147483647?float=-2147483648
+ -2147483648?float=-2147483648
+ 4294967295?float=4294967296
+ 4294967296?float=4294967296
+ -4294967295?float=-4294967296
+ -4294967296?float=-4294967296
+ 2147483647.1?float=2147483648
+ 2147483648.1?float=2147483648
+ -2147483647.1?float=-2147483648
+ -2147483648.1?float=-2147483648
+ 4294967295.1?float=4294967296
+ 4294967296.1?float=4294967296
+ -4294967295.1?float=-4294967296
+ -4294967296.1?float=-4294967296
+ 2147483647.5?float=2147483648
+ 2147483648.5?float=2147483648
+ -2147483647.5?float=-2147483648
+ -2147483648.5?float=-2147483648
+ 4294967295.5?float=4294967296
+ 4294967296.5?float=4294967296
+ -4294967295.5?float=-4294967296
+ -4294967296.5?float=-4294967296
+
+?byte
+ 0?byte=0
+ 1?byte=1
+ -1?byte=-1
+ 0.5?byte=0
+ 1.5?byte=1
+ -0.5?byte=0
+ -1.5?byte=-1
+ 0.25?byte=0
+ -0.25?byte=0
+ 1.75?byte=1
+ -1.75?byte=-1
+ 1.01?byte=1
+ -1.01?byte=-1
+ 0.01?byte=0
+ -0.01?byte=0
+ 127?byte=127
+ 128?byte=-128
+ -127?byte=-127
+ -128?byte=-128
+ 32767?byte=-1
+ 32768?byte=0
+ -32767?byte=1
+ -32768?byte=0
+ 2147483647?byte=-1
+ 2147483648?byte=0
+ -2147483647?byte=1
+ -2147483648?byte=0
+ 4294967295?byte=-1
+ 4294967296?byte=0
+ -4294967295?byte=1
+ -4294967296?byte=0
+ 2147483647.1?byte=-1
+ 2147483648.1?byte=0
+ -2147483647.1?byte=1
+ -2147483648.1?byte=0
+ 4294967295.1?byte=-1
+ 4294967296.1?byte=0
+ -4294967295.1?byte=1
+ -4294967296.1?byte=0
+ 2147483647.5?byte=-1
+ 2147483648.5?byte=0
+ -2147483647.5?byte=1
+ -2147483648.5?byte=0
+ 4294967295.5?byte=-1
+ 4294967296.5?byte=0
+ -4294967295.5?byte=1
+ -4294967296.5?byte=0
+
+?short
+ 0?short=0
+ 1?short=1
+ -1?short=-1
+ 0.5?short=0
+ 1.5?short=1
+ -0.5?short=0
+ -1.5?short=-1
+ 0.25?short=0
+ -0.25?short=0
+ 1.75?short=1
+ -1.75?short=-1
+ 1.01?short=1
+ -1.01?short=-1
+ 0.01?short=0
+ -0.01?short=0
+ 127?short=127
+ 128?short=128
+ -127?short=-127
+ -128?short=-128
+ 32767?short=32767
+ 32768?short=-32768
+ -32767?short=-32767
+ -32768?short=-32768
+ 2147483647?short=-1
+ 2147483648?short=0
+ -2147483647?short=1
+ -2147483648?short=0
+ 4294967295?short=-1
+ 4294967296?short=0
+ -4294967295?short=1
+ -4294967296?short=0
+ 2147483647.1?short=-1
+ 2147483648.1?short=0
+ -2147483647.1?short=1
+ -2147483648.1?short=0
+ 4294967295.1?short=-1
+ 4294967296.1?short=0
+ -4294967295.1?short=1
+ -4294967296.1?short=0
+ 2147483647.5?short=-1
+ 2147483648.5?short=0
+ -2147483647.5?short=1
+ -2147483648.5?short=0
+ 4294967295.5?short=-1
+ 4294967296.5?short=0
+ -4294967295.5?short=1
+ -4294967296.5?short=0
+
+?floor
+ 0?floor=0
+ 1?floor=1
+ -1?floor=-1
+ 0.5?floor=0
+ 1.5?floor=1
+ -0.5?floor=-1
+ -1.5?floor=-2
+ 0.25?floor=0
+ -0.25?floor=-1
+ 1.75?floor=1
+ -1.75?floor=-2
+ 1.01?floor=1
+ -1.01?floor=-2
+ 0.01?floor=0
+ -0.01?floor=-1
+ 127?floor=127
+ 128?floor=128
+ -127?floor=-127
+ -128?floor=-128
+ 32767?floor=32767
+ 32768?floor=32768
+ -32767?floor=-32767
+ -32768?floor=-32768
+ 2147483647?floor=2147483647
+ 2147483648?floor=2147483648
+ -2147483647?floor=-2147483647
+ -2147483648?floor=-2147483648
+ 4294967295?floor=4294967295
+ 4294967296?floor=4294967296
+ -4294967295?floor=-4294967295
+ -4294967296?floor=-4294967296
+ 2147483647.1?floor=2147483647
+ 2147483648.1?floor=2147483648
+ -2147483647.1?floor=-2147483648
+ -2147483648.1?floor=-2147483649
+ 4294967295.1?floor=4294967295
+ 4294967296.1?floor=4294967296
+ -4294967295.1?floor=-4294967296
+ -4294967296.1?floor=-4294967297
+ 2147483647.5?floor=2147483647
+ 2147483648.5?floor=2147483648
+ -2147483647.5?floor=-2147483648
+ -2147483648.5?floor=-2147483649
+ 4294967295.5?floor=4294967295
+ 4294967296.5?floor=4294967296
+ -4294967295.5?floor=-4294967296
+ -4294967296.5?floor=-4294967297
+
+?ceiling
+ 0?ceiling=0
+ 1?ceiling=1
+ -1?ceiling=-1
+ 0.5?ceiling=1
+ 1.5?ceiling=2
+ -0.5?ceiling=0
+ -1.5?ceiling=-1
+ 0.25?ceiling=1
+ -0.25?ceiling=0
+ 1.75?ceiling=2
+ -1.75?ceiling=-1
+ 1.01?ceiling=2
+ -1.01?ceiling=-1
+ 0.01?ceiling=1
+ -0.01?ceiling=0
+ 127?ceiling=127
+ 128?ceiling=128
+ -127?ceiling=-127
+ -128?ceiling=-128
+ 32767?ceiling=32767
+ 32768?ceiling=32768
+ -32767?ceiling=-32767
+ -32768?ceiling=-32768
+ 2147483647?ceiling=2147483647
+ 2147483648?ceiling=2147483648
+ -2147483647?ceiling=-2147483647
+ -2147483648?ceiling=-2147483648
+ 4294967295?ceiling=4294967295
+ 4294967296?ceiling=4294967296
+ -4294967295?ceiling=-4294967295
+ -4294967296?ceiling=-4294967296
+ 2147483647.1?ceiling=2147483648
+ 2147483648.1?ceiling=2147483649
+ -2147483647.1?ceiling=-2147483647
+ -2147483648.1?ceiling=-2147483648
+ 4294967295.1?ceiling=4294967296
+ 4294967296.1?ceiling=4294967297
+ -4294967295.1?ceiling=-4294967295
+ -4294967296.1?ceiling=-4294967296
+ 2147483647.5?ceiling=2147483648
+ 2147483648.5?ceiling=2147483649
+ -2147483647.5?ceiling=-2147483647
+ -2147483648.5?ceiling=-2147483648
+ 4294967295.5?ceiling=4294967296
+ 4294967296.5?ceiling=4294967297
+ -4294967295.5?ceiling=-4294967295
+ -4294967296.5?ceiling=-4294967296
+
+?round
+ 0?round=0
+ 1?round=1
+ -1?round=-1
+ 0.5?round=1
+ 1.5?round=2
+ -0.5?round=0
+ -1.5?round=-1
+ 0.25?round=0
+ -0.25?round=0
+ 1.75?round=2
+ -1.75?round=-2
+ 1.01?round=1
+ -1.01?round=-1
+ 0.01?round=0
+ -0.01?round=0
+ 127?round=127
+ 128?round=128
+ -127?round=-127
+ -128?round=-128
+ 32767?round=32767
+ 32768?round=32768
+ -32767?round=-32767
+ -32768?round=-32768
+ 2147483647?round=2147483647
+ 2147483648?round=2147483648
+ -2147483647?round=-2147483647
+ -2147483648?round=-2147483648
+ 4294967295?round=4294967295
+ 4294967296?round=4294967296
+ -4294967295?round=-4294967295
+ -4294967296?round=-4294967296
+ 2147483647.1?round=2147483647
+ 2147483648.1?round=2147483648
+ -2147483647.1?round=-2147483647
+ -2147483648.1?round=-2147483648
+ 4294967295.1?round=4294967295
+ 4294967296.1?round=4294967296
+ -4294967295.1?round=-4294967295
+ -4294967296.1?round=-4294967296
+ 2147483647.5?round=2147483648
+ 2147483648.5?round=2147483649
+ -2147483647.5?round=-2147483647
+ -2147483648.5?round=-2147483648
+ 4294967295.5?round=4294967296
+ 4294967296.5?round=4294967297
+ -4294967295.5?round=-4294967295
+ -4294967296.5?round=-4294967296
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
new file mode 100644
index 0000000..3b5215a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding1.txt
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+Output charset: UTF-8
+URL escaping charset: undefined
+
+a%FE%FF%00%2F%00%25b
+a%FE%FF%00%2F%00%25b
+a%2F%25b
+a%2F%25b
+a%FE%FF%00%2F%00%25b
+a%2F%25b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt
new file mode 100644
index 0000000..6956b6c
Binary files /dev/null and b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding2.txt differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
new file mode 100644
index 0000000..c0369f6
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/output-encoding3.txt
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+Output charset: ISO-8859-1
+URL escaping charset: UTF-16
+
+UTF-16: a%FE%FF%00%2F%00%25b
+ISO-8859-1: a%2F%25b
+UTF-16: a%FE%FF%00%2F%00%25b
+ISO-8859-1: a%2F%25b
+ISO-8859-1: a%2F%25b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
new file mode 100644
index 0000000..b19cb31
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/precedence.txt
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Operator Precedence Test</title>
+</head>
+<body>
+
+@@@@@@@@@@@
+
+<br />
+<br />
+
+##########
+
+<br />
+<br />
+
+&&&&&&&&&&&
+
+<br />
+<br />
+
+!!!!!!!!!!!
+
+<br />
+<br />
+
+$$$$$$$$$$$
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
new file mode 100644
index 0000000..880cea3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/recover.txt
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+ Hello, World
+ Well, that did not work.
+ Now we nest another attempt/recover here:
+ Oops...
+ Remember, freeMarker sequences are zero-based! Hello, World
+ Now we check the current error message.
+ The template is not currently available
+ The included template had a problem.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
new file mode 100644
index 0000000..041222c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/root.txt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Root Lookup Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Access the same variable via the root variable (dot syntax):</p>
+
+<p>Hello, world!</p>
+
+<p>Access the same variable via the root variable (bracket syntax):</p>
+
+<p>Hello, world!</p>
+
+<p>Ensure that root lookups are unaffected by local variables:</p>
+
+
+ Hello, world!
+ Hello, world! Part Deux
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
new file mode 100644
index 0000000..4f7796a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/sequence-builtins.txt
@@ -0,0 +1,404 @@
+/*
+ * 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.
+ */
+Sorting scalars:
+----------------
+
+String order:
+- aardvark
+- Barbara
+- beetroot
+- whale
+- zeppelin
+
+First: aardvark
+Last: zeppelin
+Size 5
+
+Numerical order:
+- -324
+- -34
+- 0
+- 0.1
+- 0.11
+- 1
+- 5
+- 111
+- 123
+- 543
+
+First: -324
+Last: 543
+Size 10
+
+Date/time order:
+- 06:05
+- 08:05
+- 08:15
+- 18:00
+
+Boolean order:
+- false
+- false
+- true
+- true
+
+
+Sorting hashes:
+---------------
+
+Order by name:
+- aardvark: 30
+- Barbara: 53
+- beetroot: 0.3
+- whale: 2000
+- zeppelin: -200
+
+Order by weight:
+- zeppelin: -200
+- beetroot: 0.3
+- aardvark: 30
+- Barbara: 53
+- whale: 2000
+
+Order by a.x.v:
+- aqweqw
+- dfgdf
+- qweqw
+- utyu
+
+Order by a.y, which is a date:
+- 1998-02-20
+- 1999-01-20
+- 1999-04-19
+- 1999-04-20
+
+Reverse:
+--------
+
+Order by weight desc:
+- whale: 2000
+- Barbara: 53
+- aardvark: 30
+- beetroot: 0.3
+- zeppelin: -200
+
+Order by weight desc desc:
+- zeppelin: -200
+- beetroot: 0.3
+- aardvark: 30
+- Barbara: 53
+- whale: 2000
+
+Order by weight desc desc desc:
+- whale: 2000
+- Barbara: 53
+- aardvark: 30
+- beetroot: 0.3
+- zeppelin: -200
+
+Contains:
+---------
+
+True:
+true
+true
+true
+true
+true
+true
+true
+
+False:
+false
+false
+false
+false
+false
+false
+false
+
+False: false
+
+Index_of:
+---------
+
+0 = 0
+1 = 1
+2 = 2
+6 = 6
+0 = 0
+1 = 1
+2 = 2
+
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+
+-1 = -1
+
+Last_index_of:
+--------------
+
+6 = 6
+1 = 1
+2 = 2
+7 = 7
+-1 = -1
+0 = 0
+1 = 1
+2 = 2
+-1 = -1
+
+Index_of and last_index_of with starting indices
+------------------------------------------------
+
+seq_index_of "Joe":
+0 = 0
+0 = 0
+0 = 0
+2 = 2
+2 = 2
+-1 = -1
+-1 = -1
+
+seq_last_index_of "Joe":
+-1 = -1
+-1 = -1
+0 = 0
+0 = 0
+2 = 2
+2 = 2
+2 = 2
+
+seq_index_of "Susan":
+3 = 3
+3 = 3
+3 = 3
+3 = 3
+3 = 3
+3 = 3
+-1 = -1
+
+seq_last_index_of "Susan":
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+3 = 3
+3 = 3
+
+seq_index_of "a":
+0 = 0
+0 = 0
+0 = 0
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+
+seq_index_of "b":
+1 = 1
+1 = 1
+1 = 1
+1 = 1
+-1 = -1
+-1 = -1
+
+seq_index_of "c":
+2 = 2
+2 = 2
+2 = 2
+2 = 2
+2 = 2
+-1 = -1
+
+seq_last_index_of "a":
+-1 = -1
+-1 = -1
+0 = 0
+0 = 0
+0 = 0
+0 = 0
+0 = 0
+
+seq_last_index_of "b":
+-1 = -1
+-1 = -1
+-1 = -1
+1 = 1
+1 = 1
+1 = 1
+
+seq_last_index_of "c":
+-1 = -1
+-1 = -1
+-1 = -1
+-1 = -1
+2 = 2
+2 = 2
+
+Sequence builtins ignoring nulls
+--------------------------------
+
+true = true
+2 = 2
+0 = 0
+
+These should throw exception, but for BC they don't:
+false = false
+-1 = -1
+-1 = -1
+
+Sequence built-ins failing on date-type mismatch
+------------------------------------------------
+
+
+Chunk
+-----
+
+columns = 1, fill = NULL:
+ Rows: 7
+ a <-- Columns: 1
+ b <-- Columns: 1
+ c <-- Columns: 1
+ d <-- Columns: 1
+ e <-- Columns: 1
+ f <-- Columns: 1
+ g <-- Columns: 1
+
+columns = 2, fill = NULL:
+ Rows: 4
+ a b <-- Columns: 2
+ c d <-- Columns: 2
+ e f <-- Columns: 2
+ g <-- Columns: 1
+
+columns = 3, fill = NULL:
+ Rows: 3
+ a b c <-- Columns: 3
+ d e f <-- Columns: 3
+ g <-- Columns: 1
+
+columns = 4, fill = NULL:
+ Rows: 2
+ a b c d <-- Columns: 4
+ e f g <-- Columns: 3
+
+columns = 5, fill = NULL:
+ Rows: 2
+ a b c d e <-- Columns: 5
+ f g <-- Columns: 2
+
+columns = 10, fill = NULL:
+ Rows: 1
+ a b c d e f g <-- Columns: 7
+
+columns = 1, fill = -:
+ Rows: 7
+ a <-- Columns: 1
+ b <-- Columns: 1
+ c <-- Columns: 1
+ d <-- Columns: 1
+ e <-- Columns: 1
+ f <-- Columns: 1
+ g <-- Columns: 1
+
+columns = 2, fill = -:
+ Rows: 4
+ a b <-- Columns: 2
+ c d <-- Columns: 2
+ e f <-- Columns: 2
+ g - <-- Columns: 2
+
+columns = 3, fill = -:
+ Rows: 3
+ a b c <-- Columns: 3
+ d e f <-- Columns: 3
+ g - - <-- Columns: 3
+
+columns = 4, fill = -:
+ Rows: 2
+ a b c d <-- Columns: 4
+ e f g - <-- Columns: 4
+
+columns = 5, fill = -:
+ Rows: 2
+ a b c d e <-- Columns: 5
+ f g - - - <-- Columns: 5
+
+columns = 10, fill = -:
+ Rows: 1
+ a b c d e f g - - - <-- Columns: 10
+
+columns = 3, fill = NULL:
+ Rows: 3
+ 1 2 3 <-- Columns: 3
+ 4 5 6 <-- Columns: 3
+ 7 8 9 <-- Columns: 3
+
+columns = 3, fill = -:
+ Rows: 3
+ 1 2 3 <-- Columns: 3
+ 4 5 6 <-- Columns: 3
+ 7 8 9 <-- Columns: 3
+
+columns = 3, fill = NULL:
+ Rows: 1
+ 1 <-- Columns: 1
+
+columns = 3, fill = -:
+ Rows: 1
+ 1 - - <-- Columns: 3
+
+columns = 3, fill = NULL:
+ Rows: 0
+
+columns = 3, fill = -:
+ Rows: 0
+
+
+
+
+Join
+----
+
+- 1, two, three, 4
+-
+- 1, two, three, 4.
+- (empty)
+- a, c
+- a, c
+- a, c.
+-
+- (empty)
+- (empty)
+- a, b, c.
+- a, b, c.
+
+
+Misc
+----
+
+First of set 1: a
+First of set 2: a
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
new file mode 100644
index 0000000..e2fa13e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/specialvars.txt
@@ -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.
+ */
+en == en
+en_US == en_US
+utf-8 == utf-8
+specialvars.ftl == specialvars.ftl
+iso-8859-1 == iso-8859-1
+x == x
+true == true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
new file mode 100644
index 0000000..ba14e7f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps-matches.txt
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+List mode:
+Size: 4
+[L16][L27][L38][L49]
+[L16][L27][L38][L49]
+
+Iterator mode:
+[L16][L27][L38][L49]
+[L16(L16, L27, L38, L49)][L27(L16, L27, L38, L49)][L38(L16, L27, L38, L49)][L49(L16, L27, L38, L49)]
+[L16][L27][L38][L49]
+
+Iterator mode changes to list mode:
+[L16]/4[L27]/4[L38]/4[L49]/4
+[L16][L27][L38][L49]
+
+Iterator mode changes to list mode 2:
+[L16][L27][L38][L49]
+[L16]/4[L27]/4[L38]/4[L49]/4
+
+List mode with embedded iteration:
+[L16(L16, L27, L38, L49)][L27(L16, L27, L38, L49)][L38(L16, L27, L38, L49)][L49(L16, L27, L38, L49)]
+
+Entire input match:
+- M: L16
+ - G: L16
+ - G: 1
+ - G: 6
+- M: L27
+ - G: L27
+ - G: 2
+ - G: 7
+- M: L38
+ - G: L38
+ - G: 3
+ - G: 8
+- M: L49
+ - G: L49
+ - G: 4
+ - G: 9
+firstGS was: L16, 1, 6
+
+Entire input match 2:
+Matches: true
+- G: x12
+- G: 1
+- G: 2
+As list:
+- M: x12
+ - G: x12
+ - G: 1
+ - G: 2
+Groups again:
+- G: x12
+- G: 1
+- G: 2
+
+Entire input match 3:
+Matches: false
+
+Entire input match 4:
+Matches: true
+- G: x12
+- G: 1
+- G: 2
+
+Substring match nested into entire input match:
+- G: x12 ([x12{x12, 1, 2}])
+- G: 1 ([x12{x12, 1, 2}])
+- G: 2 ([x12{x12, 1, 2}])
+
+Different entire input and substring matches:
+123, 123
+- M: 1 (Gs: 1, 1)
+- M: 2 (Gs: 2, 2)
+- M: 3 (Gs: 3, 3)
+
+Different entire input and substring matches 2:
+123
+- M: 1 (Gs: 1)
+- M: 2 (Gs: 2)
+- M: 3 (Gs: 3)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
new file mode 100644
index 0000000..c54dc96
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins-regexps.txt
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+true == true
+true == true
+
+false == false
+true == true
+
+false == false
+true == true
+
+false == false
+true == true
+
+false == false
+false == false
+false == false
+true == true
+true == true
+true == true
+
+false == false
+false == false
+true == true
+true == true
+true == true
+true == true
+
+
+Lower 'c'-words:
+- coverage
+- considered
+
+Any 'c'-words:
+- Code
+- coverage
+- considered
+
+Lower line-last words:
+- coverage
+
+Any line-last words:
+- coverage
+- BROKEN
+
+Any last words:
+- BROKEN
+
+c-word with follower:
+- "Code without"
+ Groups: "Code without", "Code", "without"
+- "coverage\nis"
+ Groups: "coverage\nis", "coverage", "is"
+- "considered to"
+ Groups: "considered to", "considered", "to"
+
+c-word with follower in the same line:
+- Code without
+- considered to
+
+Lower c-word with follower in the same line:
+- considered to
+
+ Ignored but logged in 2.3: False == False
+ Ignored but logged in 2.3: False == False
+
+FOObar == FOObar
+Foobar == Foobar
+FOObar == FOObar
+FOObarFOO == FOObarFOO
+FOObarfOO == FOObarfOO
+FOObarfOO == FOObarfOO
+Foobar == Foobar
+FOObar == FOObar
+FOObarFOO == FOObarFOO
+FOObarfOO == FOObarfOO
+FOObarfOO == FOObarfOO
+foobar == foobar
+foobar == foobar
+FOObar == FOObar
+FOObarFOO == FOObarFOO
+FOObarfOo == FOObarfOo
+FAlse == FAlse
+FAlse == FAlse
+
+ Ignored but logged in 2.3: FOObar
+
+[foo, barxbaaz] == [foo, barxbaaz]
+[foo, barxbaaz] == [foo, barxbaaz]
+[foo, bar, baaz] == [foo, bar, baaz]
+[foo, barxbaaz] == [foo, barxbaaz]
+[foo, bar, baaz] == [foo, bar, baaz]
+[fooXXbarxxbaaz] == [fooXXbarxxbaaz]
+[foo, bar, baaz] == [foo, bar, baaz]
+[F, ls] == [F, ls]
+[Fals, ] == [Fals, ]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
new file mode 100644
index 0000000..6e689ac
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins1.txt
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+FreeMarker: Encoding string built-in tests
+
+
+cap_first: DieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+uncap_first: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+uncap_first:blah
+capitalize: Diebugsdie! * Vazzze 123456 --cdc-- --<<--@ X ${"kigyo"?upper_case}
+html: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+length: 71
+lower_case: diebugsdie! * vazzze 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+rtf: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x $\{"kigyo"?upper_case\}
+trim: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+trim2: foo bar
+trim3: foo bar
+trim4: foo bar
+upper_case: DIEBUGSDIE! * VAZZZE 123456 --CDC-- --<<--@ X ${"KIGYO"?UPPER_CASE}
+xml: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x ${"kigyo"?upper_case}
+xhtml: "Blah's is > 1 & < 2"
+
+word_list:
+- dieBugsDie!
+- *
+- vazzZE
+- 123456
+- --cdc--
+- --<<--@
+- x
+- ${"kigyo"?upper_case}
+
+interpret: dieBugsDie! * vazzZE 123456 --cdc-- --<<--@ x KIGYO
+number: -122,35
+1500
+5
+0
+0
+true
+true
+true
+true
+true
+
+default constructor
+1
+xxx
+xxx:yyy
+
+
+In The Sacred, Holy beginning, God created The Sacred, Holy Heavens and The Sacred, Holy Earth.
+In the very beginning, God created the Heavens and The Earth.
+|I|n| |t|h|e| |b|e|g|i|n|n|i|n|g|,| |G|o|d| |c|r|e|a|t|e|d| |t|h|e| |H|e|a|v|e|n|s| |a|n|d| |T|h|e| |E|a|r|t|h|.|
+|In the beginning, God created the Heavens and The Earth.
+
+In the beginning, God created the sky and The Earth.
+
+matches
+
+ the beginning
+ the sacred beginning
+ the Heavens
+ the sacred Heavens
+ The Earth
+ The sacred Earth
+
+In the beginning, God created the Heavens and The Earth.
+beginning
+the Heavens and The Earth.
+
+ foo
+ bar
+ baz
+ foobar
+
+
+FOOBAR
+
+[a] = [a]
+[a\\'x'\nb] = [a\\'x'\nb]
+[\u0001\u001a ] = [\u0001\u001a ]
+
+[a] = [a]
+[a\\\'x\'\nb] = [a\\\'x\'\nb]
+[\x01\x1A ] = [\x01\x1A ]
+[\x3C![CDATA[] = [\x3C![CDATA[]
+[]]\>] = []]\>]
+
+[a] = [a]
+[a\\'x'\nb] = [a\\'x'\nb]
+[\u0001\u001A ] = [\u0001\u001A ]
+[\n\r\t\f\b\"] = [\n\r\t\f\b\"]
+[\/] = [\/]
+[a/b] = [a/b]
+[<\/script>] = [<\/script>]
+[\u003C![CDATA[] = [\u003C![CDATA[]
+[]]\u003E] = []]\u003E]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
new file mode 100644
index 0000000..f5eebd9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/string-builtins2.txt
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+--
+1 = 1
+5 = 5
+0 = 0
+--
+5 = 5
+1 = 1
+7 = 7
+--
+true = true
+false = false
+true = true
+--
+true = true
+false = false
+true = true
+--
+true = true
+true = true
+true = true
+false = false
+true = true
+--
+[abbcdbb] = [abbcdbb]
+[qwe] = [qwe]
+[qwe] = [qwe]
+[qwe] = [qwe]
+[qwe
+] = [qwe
+]
+[qwe
+] = [qwe
+]
+--
+[abbcdbb] = [abbcdbb]
+[abb-dbb] = [abb-dbb]
+[a-=*cd-=*] = [a-=*cd-=*]
+--
+[a][][cd][][] == [a][][cd][][]
+[][die][maggots][!] == [][die][maggots][!]
+[Die maggots!] == [Die maggots!]
+--
+[ ]
+[ a]
+[ ab]
+[ abc]
+[ abcd]
+[abcde]
+[abcdef]
+[abcdefg]
+[abcdefgh]
+[-----]
+[----a]
+[---ab]
+[--abc]
+[-abcd]
+[abcde]
+[abcdef]
+[abcdefg]
+[abcdefgh]
+[.oO.oO.o]
+[.oO.oO.a]
+[.oO.oOab]
+[.oO.oabc]
+[.oO.abcd]
+[.oOabcde]
+[.oabcdef]
+[.abcdefg]
+[abcdefgh]
+[abcdefghi]
+[abcdefghij]
+[]
+[/]
+[/\]
+[/\_]
+[/\_/]
+[/\_/\]
+[/\_/\_]
+[/\_/\_/]
+--
+[ ]
+[a ]
+[ab ]
+[abc ]
+[abcd ]
+[abcde]
+[abcdef]
+[abcdefg]
+[abcdefgh]
+[-----]
+[a----]
+[ab---]
+[abc--]
+[abcd-]
+[abcde]
+[abcdef]
+[abcdefg]
+[abcdefgh]
+[.oO.oO.o]
+[aoO.oO.o]
+[abO.oO.o]
+[abc.oO.o]
+[abcdoO.o]
+[abcdeO.o]
+[abcdef.o]
+[abcdefgo]
+[abcdefgh]
+[abcdefghi]
+[abcdefghij]
+[]
+[/]
+[/\]
+[/\_]
+[/\_/]
+[/\_/\]
+[/\_/\_]
+[/\_/\_/]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
new file mode 100644
index 0000000..8ef415d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringbimethods.txt
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+3.00
+3.00
+01:02:03.000
+01:02:03.000
+---
+de
+true false
+yes no
+igen nem
+0.0 1.0
+true true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt
new file mode 100644
index 0000000..3d9d4c9
Binary files /dev/null and b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/stringliteral.txt differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
new file mode 100644
index 0000000..5d42785
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/switch.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Switch-Case Test</title>
+</head>
+<body>
+
+<p>Here we iterate over a list of animals.</p>
+
+<p>Animal is: aardvark.<br />
+ This is the HTML for other animals.
+</p>
+<p>Animal is: kiwi.<br />
+ This is the HTML for the user's favorite animal.
+</p>
+<p>Animal is: gecko.<br />
+ This is the HTML for small animals.
+</p>
+<p>Animal is: cat.<br />
+ This is the HTML for other animals.
+</p>
+<p>Animal is: dog.<br />
+ This is the HTML for other animals.
+</p>
+<p>Animal is: elephant.<br />
+ This is the HTML for large animals.
+</p>
+<p>Animal is: squirrel.<br />
+ This is the HTML for small animals.
+</p>
+<p>Animal is: zebra.<br />
+ This is the HTML for a large stripey animal.
+ This is the HTML for large animals.
+</p>
+
+ 1
+ i2
+ 2
+ i4
+ ft
+ ft
+ 3
+ i4
+ 3
+ i6
+
+[]
+
+ ""
+ "1234"
+ "234"
+ "34"
+ "4"
+
+ "12default45"
+ "2default45"
+ "default"
+ "45"
+ "5"
+
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
new file mode 100644
index 0000000..6b7f986
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/transforms.txt
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Transformation Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Hello, world!</p>
+
+<P>Now try the Utility package:</p>
+<p>Utility transformations</p>
+
+<p>Utility transformations</p>
+
+<p>Now some nested transforms:</p>
+<p >This tests the compress transformation</p ><p >This tests the compress transformation</p ><p >This tests the compress transformation</p >
+<p>Now try method and transform interactions:</p>
+<p>This isn't a valid XML string.</p>
+<p>This isn't a valid HTML string.</p>
+
+<p>A more advanced interaction involves getting a TemplateMethodModel
+to initialise a TemplateTransformModel, as follow:</p>
+
+Comment: This is a comment
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+
+Comment: This is a second comment
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+Comment: This is a third comment
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish &amp; Chips.</p>
+Comment: Utility transformations
+
+A test string containing quotes: "This isn't a test".
+A test string containing amps: Fish & Chips.
+A test string containing tags: <p>Fish & Chips.</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/type-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/type-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/type-builtins.txt
new file mode 100644
index 0000000..0b4e23a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/type-builtins.txt
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+StNuBoMeTaMaHaHxSeCoCxEnInDiNo
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
+0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
+0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 1 0 0 1 1 0 0
+0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
+1 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/var-layers.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/var-layers.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/var-layers.txt
new file mode 100644
index 0000000..5fd6e2e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/var-layers.txt
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+ 1 = 1
+ 2 = 2
+ 3 = 3
+4 = 4 = 4
+5 = 5 = 5
+6 but 4 = 4
+7 = 7 = 7
+Invisiblity test 1.: passed
+Invisiblity test 2.: passed
+Invisiblity test 3.: passed
+--
+ 1 = 1
+ 2 = 2
+ 3 = 3
+ 4 = 4 = 4 = 4
+ 5
+ 6 == 6
+ 7 == 7 == 7
+--
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/varargs.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/varargs.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/varargs.txt
new file mode 100644
index 0000000..a310855
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/varargs.txt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+0 == 0
+0 == 0
+11 == 11
+11 == 11
+1122 == 1122
+1122 == 1122
+112233 == 112233
+112233 == 112233
+
+-22334411 == -22334411
+-223311 == -223311
+-2211 == -2211
+-11 == -11
+
+0 == 0
+-11 == -11
+1122 == 1122
+-112233 == -112233
+-11223344 == -11223344
+-1122334455 == -1122334455
+
+1122 == 1122
+-1122 == -1122
+
+string, true, 123, 1000000 == string, true, 123, 1000000
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/variables.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/variables.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/variables.txt
new file mode 100644
index 0000000..5365b07
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/variables.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Variable Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now get into variable nesting:</p>
+
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+<p>My message.</p>
+
+<p>More deep nesting...</p>
+
+<p>My message.</p>
+<p>one</p>
+<p>one</p>
+
+
+<p>Nesting inside nesting...</p>
+
+<p>two</p>
+<p>two</p>
+<p>two</p>
+<p>two</p>
+
+<p>Test underscores...</p>
+
+<p>out</p>
+<p>out</p>
+
+SAVE
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/whitespace-trim.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/whitespace-trim.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/whitespace-trim.txt
new file mode 100644
index 0000000..e74163a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/whitespace-trim.txt
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+LB
+LB
+LB
+LB
+ IB
+ IC1 IC2C1C2 ICS CS1 CS2 C3C1C2
+B
+B
+C1CB
+C1
+C2 ICB
+ IC ICB
+ ICCB
+--
+LB
+LB
+LB
+LB
+ IB
+ IC1 IC2C1C2 ICS CS1 CS2 C3C1C2
+B
+B
+C1CB
+C1
+C2 ICB
+ IC ICB
+ ICCB
+--
+ IB
+ IC1C2 IB
+12
+---
+1 23
+ 4
+ 5 6
+---
+a
+bc
+---
+foo
+---
+foo
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstrip-in-header.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstrip-in-header.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstrip-in-header.txt
new file mode 100644
index 0000000..2cb2913
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstrip-in-header.txt
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+a
+
+b
+a
+b
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstripping.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstripping.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstripping.txt
new file mode 100644
index 0000000..2aae297
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/wstripping.txt
@@ -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.
+ */
+a
+b
+c
+d
+e2
+f
+g
+x
+ x
+ x
+ y
+y
+x
+y
+x
+y
+a
+ x
+b
+ x
+c
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-fragment.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-fragment.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-fragment.txt
new file mode 100644
index 0000000..cb0da5f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-fragment.txt
@@ -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.
+ */
+b = b
+@document = @document
+@document = @document
+
+C<>&"']]> = C<>&"']]>
+
+<root xmlns:n="http://x"><a><b><n:c>C<>&"']]></n:c></b></a></root>
\ No newline at end of file
[48/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
new file mode 100644
index 0000000..dcefa3f
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
@@ -0,0 +1,1486 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
+import org.apache.freemarker.core.outputformat.OutputFormat;
+import org.apache.freemarker.core.outputformat.UnregisteredOutputFormatException;
+import org.apache.freemarker.core.outputformat.impl.CombinedMarkupOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat;
+import org.apache.freemarker.core.templateresolver.CacheStorageWithGetSize;
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
+import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
+import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
+import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormatFM2;
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
+import org.apache.freemarker.core.templateresolver.impl.NullCacheStorage;
+import org.apache.freemarker.core.templateresolver.impl.SoftCacheStorage;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
+import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat;
+import org.apache.freemarker.core.userpkg.DummyOutputFormat;
+import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
+import org.apache.freemarker.core.util._DateUtil;
+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.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import junit.framework.TestCase;
+
+public class ConfigurationTest extends TestCase {
+
+ private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
+
+ public ConfigurationTest(String name) {
+ super(name);
+ }
+
+ public void testUnsetAndIsSet() throws Exception {
+ Configuration.ExtendableBuilder<?> cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertFalse(cfgB.isLogTemplateExceptionsSet());
+ assertFalse(cfgB.getLogTemplateExceptions());
+ //
+ cfgB.setLogTemplateExceptions(true);
+ {
+ Configuration cfg = cfgB.build();
+ assertTrue(cfgB.isLogTemplateExceptionsSet());
+ assertTrue(cfg.isLogTemplateExceptionsSet());
+ assertTrue(cfgB.getLogTemplateExceptions());
+ assertTrue(cfg.getLogTemplateExceptions());
+ }
+ //
+ for (int i = 0; i < 2; i++) {
+ cfgB.unsetLogTemplateExceptions();
+ Configuration cfg = cfgB.build();
+ assertFalse(cfgB.isLogTemplateExceptionsSet());
+ assertTrue(cfg.isLogTemplateExceptionsSet());
+ assertFalse(cfgB.getLogTemplateExceptions());
+ assertFalse(cfg.getLogTemplateExceptions());
+ }
+
+ DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertFalse(cfgB.isObjectWrapperSet());
+ assertSame(dow, cfgB.getObjectWrapper());
+ //
+ RestrictedObjectWrapper ow = new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ cfgB.setObjectWrapper(ow);
+ assertTrue(cfgB.isObjectWrapperSet());
+ assertSame(ow, cfgB.getObjectWrapper());
+ //
+ for (int i = 0; i < 2; i++) {
+ cfgB.unsetObjectWrapper();
+ assertFalse(cfgB.isObjectWrapperSet());
+ assertSame(dow, cfgB.getObjectWrapper());
+ }
+
+ assertFalse(cfgB.isTemplateExceptionHandlerSet());
+ assertSame(TemplateExceptionHandler.DEBUG_HANDLER, cfgB.getTemplateExceptionHandler());
+ //
+ cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ assertTrue(cfgB.isTemplateExceptionHandlerSet());
+ assertSame(TemplateExceptionHandler.RETHROW_HANDLER, cfgB.getTemplateExceptionHandler());
+ //
+ for (int i = 0; i < 2; i++) {
+ cfgB.unsetTemplateExceptionHandler();
+ assertFalse(cfgB.isTemplateExceptionHandlerSet());
+ assertSame(TemplateExceptionHandler.DEBUG_HANDLER, cfgB.getTemplateExceptionHandler());
+ }
+
+ assertFalse(cfgB.isTemplateLoaderSet());
+ assertNull(cfgB.getTemplateLoader());
+ //
+ cfgB.setTemplateLoader(null);
+ assertTrue(cfgB.isTemplateLoaderSet());
+ assertNull(cfgB.getTemplateLoader());
+ //
+ for (int i = 0; i < 3; i++) {
+ if (i == 2) {
+ cfgB.setTemplateLoader(new StringTemplateLoader());
+ }
+ cfgB.unsetTemplateLoader();
+ assertFalse(cfgB.isTemplateLoaderSet());
+ assertNull(cfgB.getTemplateLoader());
+ }
+
+ assertFalse(cfgB.isTemplateLookupStrategySet());
+ assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
+ //
+ cfgB.setTemplateLookupStrategy(DefaultTemplateLookupStrategy.INSTANCE);
+ assertTrue(cfgB.isTemplateLookupStrategySet());
+ //
+ for (int i = 0; i < 2; i++) {
+ cfgB.unsetTemplateLookupStrategy();
+ assertFalse(cfgB.isTemplateLookupStrategySet());
+ }
+
+ assertFalse(cfgB.isTemplateNameFormatSet());
+ assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
+ //
+ cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE);
+ assertTrue(cfgB.isTemplateNameFormatSet());
+ assertSame(DefaultTemplateNameFormat.INSTANCE, cfgB.getTemplateNameFormat());
+ //
+ for (int i = 0; i < 2; i++) {
+ cfgB.unsetTemplateNameFormat();
+ assertFalse(cfgB.isTemplateNameFormatSet());
+ assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
+ }
+
+ assertFalse(cfgB.isCacheStorageSet());
+ assertTrue(cfgB.getCacheStorage() instanceof SoftCacheStorage);
+ //
+ cfgB.setCacheStorage(NullCacheStorage.INSTANCE);
+ assertTrue(cfgB.isCacheStorageSet());
+ assertSame(NullCacheStorage.INSTANCE, cfgB.getCacheStorage());
+ //
+ for (int i = 0; i < 3; i++) {
+ if (i == 2) {
+ cfgB.setCacheStorage(cfgB.getCacheStorage());
+ }
+ cfgB.unsetCacheStorage();
+ assertFalse(cfgB.isCacheStorageSet());
+ assertTrue(cfgB.getCacheStorage() instanceof SoftCacheStorage);
+ }
+ }
+
+ public void testTemplateLoadingErrors() throws Exception {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(new ClassTemplateLoader(getClass(), "nosuchpackage"))
+ .build();
+ try {
+ cfg.getTemplate("missing.ftl");
+ fail();
+ } catch (TemplateNotFoundException e) {
+ assertThat(e.getMessage(), not(containsString("wasn't set")));
+ }
+ }
+
+ public void testVersion() {
+ Version v = Configuration.getVersion();
+ assertTrue(v.intValue() >= _CoreAPI.VERSION_INT_3_0_0);
+
+ try {
+ new Configuration.Builder(new Version(999, 1, 2));
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("upgrade"));
+ }
+
+ try {
+ new Configuration.Builder(new Version(2, 3, 0));
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("3.0.0"));
+ }
+ }
+
+ public void testShowErrorTips() throws Exception {
+ try {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+ new Template(null, "${x}", cfg).process(null, _NullWriter.INSTANCE);
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString("Tip:"));
+ }
+
+ try {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).showErrorTips(false).build();
+ new Template(null, "${x}", cfg).process(null, _NullWriter.INSTANCE);
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), not(containsString("Tip:")));
+ }
+ }
+
+ @Test
+ @SuppressWarnings("boxing")
+ public void testGetTemplateOverloads() throws Exception {
+ final Locale hu = new Locale("hu", "HU");
+ final String tFtl = "t.ftl";
+ final String tHuFtl = "t_hu.ftl";
+ final String tEnFtl = "t_en.ftl";
+ final String tUtf8Ftl = "utf8.ftl";
+ final Serializable custLookupCond = 12345;
+
+ ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
+ tl.putTemplate(tFtl, "${1}".getBytes(StandardCharsets.UTF_8));
+ tl.putTemplate(tEnFtl, "${1}".getBytes(StandardCharsets.UTF_8));
+ tl.putTemplate(tHuFtl, "${1}".getBytes(StandardCharsets.UTF_8));
+ tl.putTemplate(tUtf8Ftl, "<#ftl encoding='utf-8'>".getBytes(StandardCharsets.UTF_8));
+
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .locale(Locale.GERMAN)
+ .sourceEncoding(StandardCharsets.ISO_8859_1)
+ .templateLoader(tl)
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*_hu.*"),
+ new TemplateConfiguration.Builder().sourceEncoding(ISO_8859_2).build()))
+ .build();
+
+ // 1 args:
+ {
+ Template t = cfg.getTemplate(tFtl);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tFtl, t.getSourceName());
+ assertEquals(Locale.GERMAN, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tUtf8Ftl);
+ assertEquals(tUtf8Ftl, t.getLookupName());
+ assertEquals(tUtf8Ftl, t.getSourceName());
+ assertEquals(Locale.GERMAN, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ }
+
+ // 2 args:
+ {
+ Template t = cfg.getTemplate(tFtl, Locale.GERMAN);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tFtl, t.getSourceName());
+ assertEquals(Locale.GERMAN, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tFtl, (Locale) null);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tFtl, t.getSourceName());
+ assertEquals(Locale.GERMAN, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tFtl, Locale.US);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tEnFtl, t.getSourceName());
+ assertEquals(Locale.US, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tUtf8Ftl, Locale.US);
+ assertEquals(tUtf8Ftl, t.getLookupName());
+ assertEquals(tUtf8Ftl, t.getSourceName());
+ assertEquals(Locale.US, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tFtl, hu);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tHuFtl, t.getSourceName());
+ assertEquals(hu, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(ISO_8859_2, t.getActualSourceEncoding());
+ }
+ {
+ Template t = cfg.getTemplate(tUtf8Ftl, hu);
+ assertEquals(tUtf8Ftl, t.getLookupName());
+ assertEquals(tUtf8Ftl, t.getSourceName());
+ assertEquals(hu, t.getLocale());
+ assertNull(t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ }
+
+ // 4 args:
+ try {
+ cfg.getTemplate("missing.ftl", hu, custLookupCond, false);
+ fail();
+ } catch (TemplateNotFoundException e) {
+ // Expected
+ }
+ assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, true));
+ {
+ Template t = cfg.getTemplate(tFtl, hu, custLookupCond, false);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tHuFtl, t.getSourceName());
+ assertEquals(hu, t.getLocale());
+ assertEquals(custLookupCond, t.getCustomLookupCondition());
+ assertEquals(ISO_8859_2, t.getActualSourceEncoding());
+ assertOutputEquals("1", t);
+ }
+ {
+ Template t = cfg.getTemplate(tFtl, null, custLookupCond, false);
+ assertEquals(tFtl, t.getLookupName());
+ assertEquals(tFtl, t.getSourceName());
+ assertEquals(Locale.GERMAN, t.getLocale());
+ assertEquals(custLookupCond, t.getCustomLookupCondition());
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ assertOutputEquals("1", t);
+ }
+ }
+
+ private void assertOutputEquals(final String expectedContent, final Template t) throws ConfigurationException,
+ IOException, TemplateException {
+ StringWriter sw = new StringWriter();
+ t.process(null, sw);
+ assertEquals(expectedContent, sw.toString());
+ }
+
+ public void testTemplateResolverCache() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ CacheStorageWithGetSize cache = (CacheStorageWithGetSize) cfgB.getCacheStorage();
+ assertEquals(0, cache.getSize());
+ cfgB.setCacheStorage(new StrongCacheStorage());
+ cache = (CacheStorageWithGetSize) cfgB.getCacheStorage();
+ assertEquals(0, cache.getSize());
+ cfgB.setTemplateLoader(new ClassTemplateLoader(ConfigurationTest.class, ""));
+ Configuration cfg = cfgB.build();
+ assertEquals(0, cache.getSize());
+ cfg.getTemplate("toCache1.ftl");
+ assertEquals(1, cache.getSize());
+ cfg.getTemplate("toCache2.ftl");
+ assertEquals(2, cache.getSize());
+ cfg.clearTemplateCache();
+ assertEquals(0, cache.getSize());
+ cfg.getTemplate("toCache1.ftl");
+ assertEquals(1, cache.getSize());
+ cfgB.setTemplateLoader(cfgB.getTemplateLoader());
+ assertEquals(1, cache.getSize());
+ }
+
+ public void testTemplateNameFormat() throws Exception {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("a/b.ftl", "In a/b.ftl");
+ tl.putTemplate("b.ftl", "In b.ftl");
+
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(tl);
+
+ {
+ cfgB.setTemplateNameFormat(DefaultTemplateNameFormatFM2.INSTANCE);
+ final Template template = cfgB.build().getTemplate("a/./../b.ftl");
+ assertEquals("a/b.ftl", template.getLookupName());
+ assertEquals("a/b.ftl", template.getSourceName());
+ assertEquals("In a/b.ftl", template.toString());
+ }
+
+ {
+ cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE);
+ final Template template = cfgB.build().getTemplate("a/./../b.ftl");
+ assertEquals("b.ftl", template.getLookupName());
+ assertEquals("b.ftl", template.getSourceName());
+ assertEquals("In b.ftl", template.toString());
+ }
+ }
+
+ public void testTemplateNameFormatSetSetting() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defAult_2_4_0");
+ assertSame(DefaultTemplateNameFormat.INSTANCE, cfgB.getTemplateNameFormat());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defaUlt_2_3_0");
+ assertSame(DefaultTemplateNameFormatFM2.INSTANCE, cfgB.getTemplateNameFormat());
+ assertTrue(cfgB.isTemplateNameFormatSet());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_NAME_FORMAT_KEY, "defauLt");
+ assertFalse(cfgB.isTemplateNameFormatSet());
+ }
+
+ public void testObjectWrapperSetSetting() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ {
+ cfgB.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "defAult");
+ DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertSame(dow, cfgB.getObjectWrapper());
+ assertEquals(Configuration.VERSION_3_0_0, dow.getIncompatibleImprovements());
+ }
+
+ {
+ cfgB.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "restricted");
+ assertThat(cfgB.getObjectWrapper(), instanceOf(RestrictedObjectWrapper.class));
+ }
+ }
+
+ public void testTemplateLookupStrategyDefaultAndSet() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
+ assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.build().getTemplateLookupStrategy());
+
+ cfgB.setTemplateLoader(new ClassTemplateLoader(ConfigurationTest.class, ""));
+ assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy());
+ Configuration cfg = cfgB.build();
+ assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfg.getTemplateLookupStrategy());
+ cfg.getTemplate("toCache1.ftl");
+
+ final TemplateLookupStrategy myStrategy = new TemplateLookupStrategy() {
+ @Override
+ public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
+ return ctx.lookupWithAcquisitionStrategy("toCache2.ftl");
+ }
+ };
+ cfgB.setTemplateLookupStrategy(myStrategy);
+ assertSame(myStrategy, cfgB.getTemplateLookupStrategy());
+ cfg = cfgB.build();
+ cfg.clearTemplateCache();
+ assertSame(myStrategy, cfg.getTemplateLookupStrategy());
+ Template template = cfg.getTemplate("toCache1.ftl");
+ assertEquals("toCache2.ftl", template.getSourceName());
+ }
+
+ public void testSetTemplateConfigurations() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertNull(cfgB.getTemplateConfigurations());
+
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("t.de.ftlh", "");
+ tl.putTemplate("t.fr.ftlx", "");
+ tl.putTemplate("t.ftlx", "");
+ tl.putTemplate("Stat/t.de.ftlx", "");
+ cfgB.setTemplateLoader(tl);
+
+ cfgB.setTimeZone(TimeZone.getTimeZone("GMT+09"));
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_CONFIGURATIONS_KEY,
+ "MergingTemplateConfigurationFactory("
+ + "FirstMatchTemplateConfigurationFactory("
+ + "ConditionalTemplateConfigurationFactory("
+ + "FileNameGlobMatcher('*.de.*'), TemplateConfiguration(timeZone=TimeZone('GMT+01'))), "
+ + "ConditionalTemplateConfigurationFactory("
+ + "FileNameGlobMatcher('*.fr.*'), TemplateConfiguration(timeZone=TimeZone('GMT'))), "
+ + "allowNoMatch=true"
+ + "), "
+ + "FirstMatchTemplateConfigurationFactory("
+ + "ConditionalTemplateConfigurationFactory("
+ + "FileExtensionMatcher('ftlh'), TemplateConfiguration(booleanFormat='TODO,HTML')), "
+ + "ConditionalTemplateConfigurationFactory("
+ + "FileExtensionMatcher('ftlx'), TemplateConfiguration(booleanFormat='TODO,XML')), "
+ + "noMatchErrorDetails='Unrecognized template file extension'"
+ + "), "
+ + "ConditionalTemplateConfigurationFactory("
+ + "PathGlobMatcher('stat/**', caseInsensitive=true), "
+ + "TemplateConfiguration(timeZone=TimeZone('UTC'))"
+ + ")"
+ + ")");
+
+ Configuration cfg = cfgB.build();
+ {
+ Template t = cfg.getTemplate("t.de.ftlh");
+ assertEquals("TODO,HTML", t.getBooleanFormat());
+ assertEquals(TimeZone.getTimeZone("GMT+01"), t.getTimeZone());
+ }
+ {
+ Template t = cfg.getTemplate("t.fr.ftlx");
+ assertEquals("TODO,XML", t.getBooleanFormat());
+ assertEquals(TimeZone.getTimeZone("GMT"), t.getTimeZone());
+ }
+ {
+ Template t = cfg.getTemplate("t.ftlx");
+ assertEquals("TODO,XML", t.getBooleanFormat());
+ assertEquals(TimeZone.getTimeZone("GMT+09"), t.getTimeZone());
+ }
+ {
+ Template t = cfg.getTemplate("Stat/t.de.ftlx");
+ assertEquals("TODO,XML", t.getBooleanFormat());
+ assertEquals(_DateUtil.UTC, t.getTimeZone());
+ }
+
+ assertNotNull(cfgB.getTemplateConfigurations());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_CONFIGURATIONS_KEY, "null");
+ assertNull(cfgB.getTemplateConfigurations());
+ }
+
+ public void testSetAutoEscaping() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY);
+ assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY);
+ assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
+ assertEquals(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enableIfSupported");
+ assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enable_if_supported");
+ assertEquals(ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enableIfDefault");
+ assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "enable_if_default");
+ assertEquals(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE, "disable");
+ assertEquals(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY, cfgB.getAutoEscapingPolicy());
+
+ try {
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void testSetOutputFormat() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(UndefinedOutputFormat.INSTANCE, cfgB.getOutputFormat());
+ assertFalse(cfgB.isOutputFormatSet());
+
+ try {
+ cfgB.setOutputFormat(null);
+ fail();
+ } catch (_NullArgumentException e) {
+ // Expected
+ }
+
+ assertFalse(cfgB.isOutputFormatSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE, XMLOutputFormat.class.getSimpleName());
+ assertEquals(XMLOutputFormat.INSTANCE, cfgB.getOutputFormat());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_SNAKE_CASE, HTMLOutputFormat.class.getSimpleName());
+ assertEquals(HTMLOutputFormat.INSTANCE, cfgB.getOutputFormat());
+
+ cfgB.unsetOutputFormat();
+ assertEquals(UndefinedOutputFormat.INSTANCE, cfgB.getOutputFormat());
+ assertFalse(cfgB.isOutputFormatSet());
+
+ cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
+ assertTrue(cfgB.isOutputFormatSet());
+ cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE, "default");
+ assertFalse(cfgB.isOutputFormatSet());
+
+ try {
+ cfgB.setSetting(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY, "null");
+ } catch (ConfigurationSettingValueException e) {
+ assertThat(e.getCause().getMessage(), containsString(UndefinedOutputFormat.class.getSimpleName()));
+ }
+ }
+
+ @Test
+ public void testGetOutputFormatByName() throws Exception {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+
+ assertSame(HTMLOutputFormat.INSTANCE, cfg.getOutputFormat(HTMLOutputFormat.INSTANCE.getName()));
+
+ try {
+ cfg.getOutputFormat("noSuchFormat");
+ fail();
+ } catch (UnregisteredOutputFormatException e) {
+ assertThat(e.getMessage(), containsString("noSuchFormat"));
+ }
+
+ try {
+ cfg.getOutputFormat("HTML}");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("'{'"));
+ }
+
+ {
+ OutputFormat of = cfg.getOutputFormat("HTML{RTF}");
+ assertThat(of, instanceOf(CombinedMarkupOutputFormat.class));
+ CombinedMarkupOutputFormat combinedOF = (CombinedMarkupOutputFormat) of;
+ assertSame(HTMLOutputFormat.INSTANCE, combinedOF.getOuterOutputFormat());
+ assertSame(RTFOutputFormat.INSTANCE, combinedOF.getInnerOutputFormat());
+ }
+
+ {
+ OutputFormat of = cfg.getOutputFormat("XML{HTML{RTF}}");
+ assertThat(of, instanceOf(CombinedMarkupOutputFormat.class));
+ CombinedMarkupOutputFormat combinedOF = (CombinedMarkupOutputFormat) of;
+ assertSame(XMLOutputFormat.INSTANCE, combinedOF.getOuterOutputFormat());
+ MarkupOutputFormat innerOF = combinedOF.getInnerOutputFormat();
+ assertThat(innerOF, instanceOf(CombinedMarkupOutputFormat.class));
+ CombinedMarkupOutputFormat innerCombinedOF = (CombinedMarkupOutputFormat) innerOF;
+ assertSame(HTMLOutputFormat.INSTANCE, innerCombinedOF.getOuterOutputFormat());
+ assertSame(RTFOutputFormat.INSTANCE, innerCombinedOF.getInnerOutputFormat());
+ }
+
+ try {
+ cfg.getOutputFormat("plainText{HTML}");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), allOf(containsString("plainText"), containsString("markup")));
+ }
+ try {
+ cfg.getOutputFormat("HTML{plainText}");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), allOf(containsString("plainText"), containsString("markup")));
+ }
+ }
+
+ public void testSetRegisteredCustomOutputFormats() throws Exception {
+ Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertTrue(cfg.getRegisteredCustomOutputFormats().isEmpty());
+
+ cfg.setSetting(Configuration.ExtendableBuilder.REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE,
+ "[org.apache.freemarker.core.userpkg.CustomHTMLOutputFormat(), "
+ + "org.apache.freemarker.core.userpkg.DummyOutputFormat()]");
+ assertEquals(
+ ImmutableList.of(CustomHTMLOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE),
+ new ArrayList(cfg.getRegisteredCustomOutputFormats()));
+
+ try {
+ cfg.setSetting(Configuration.ExtendableBuilder.REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE, "[TemplateConfiguration()]");
+ fail();
+ } catch (ConfigurationSettingValueException e) {
+ assertThat(e.getMessage(), containsString(OutputFormat.class.getSimpleName()));
+ }
+ }
+
+ public void testSetRecognizeStandardFileExtensions() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertTrue(cfgB.getRecognizeStandardFileExtensions());
+ assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
+
+ cfgB.setRecognizeStandardFileExtensions(false);
+ assertFalse(cfgB.getRecognizeStandardFileExtensions());
+ assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
+
+ cfgB.unsetRecognizeStandardFileExtensions();
+ assertTrue(cfgB.getRecognizeStandardFileExtensions());
+ assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
+
+ cfgB.setRecognizeStandardFileExtensions(true);
+ assertTrue(cfgB.getRecognizeStandardFileExtensions());
+ assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE, "false");
+ assertFalse(cfgB.getRecognizeStandardFileExtensions());
+ assertTrue(cfgB.isRecognizeStandardFileExtensionsSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE, "default");
+ assertTrue(cfgB.getRecognizeStandardFileExtensions());
+ assertFalse(cfgB.isRecognizeStandardFileExtensionsSet());
+ }
+
+ public void testSetTimeZone() throws ConfigurationException {
+ TimeZone origSysDefTZ = TimeZone.getDefault();
+ try {
+ TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01");
+ TimeZone.setDefault(sysDefTZ);
+
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertEquals(sysDefTZ, cfgB.getTimeZone());
+ cfgB.setSetting(MutableProcessingConfiguration.TIME_ZONE_KEY, "JVM default");
+ assertEquals(sysDefTZ, cfgB.getTimeZone());
+
+ TimeZone newSysDefTZ = TimeZone.getTimeZone("GMT+09");
+ TimeZone.setDefault(newSysDefTZ);
+ assertEquals(sysDefTZ, cfgB.getTimeZone());
+ cfgB.setSetting(MutableProcessingConfiguration.TIME_ZONE_KEY, "JVM default");
+ assertEquals(newSysDefTZ, cfgB.getTimeZone());
+ } finally {
+ TimeZone.setDefault(origSysDefTZ);
+ }
+ }
+
+ public void testSetSQLDateAndTimeTimeZone() throws ConfigurationException {
+ TimeZone origSysDefTZ = TimeZone.getDefault();
+ try {
+ TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01");
+ TimeZone.setDefault(sysDefTZ);
+
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertNull(cfgB.getSQLDateAndTimeTimeZone());
+
+ cfgB.setSQLDateAndTimeTimeZone(null);
+ assertNull(cfgB.getSQLDateAndTimeTimeZone());
+
+ cfgB.setSetting(MutableProcessingConfiguration.SQL_DATE_AND_TIME_TIME_ZONE_KEY, "JVM default");
+ assertEquals(sysDefTZ, cfgB.getSQLDateAndTimeTimeZone());
+
+ cfgB.setSetting(MutableProcessingConfiguration.SQL_DATE_AND_TIME_TIME_ZONE_KEY, "null");
+ assertNull(cfgB.getSQLDateAndTimeTimeZone());
+ } finally {
+ TimeZone.setDefault(origSysDefTZ);
+ }
+ }
+
+ public void testTimeZoneLayers() throws Exception {
+ TimeZone localTZ = TimeZone.getTimeZone("Europe/Brussels");
+
+ {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+ Template t = new Template(null, "", cfg);
+ Environment env1 = t.createProcessingEnvironment(null, new StringWriter());
+ Environment env2 = t.createProcessingEnvironment(null, new StringWriter());
+
+ // cfg:
+ assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+ assertNull(cfg.getSQLDateAndTimeTimeZone());
+ // env:
+ assertEquals(TimeZone.getDefault(), env1.getTimeZone());
+ assertNull(env1.getSQLDateAndTimeTimeZone());
+ // env 2:
+ assertEquals(TimeZone.getDefault(), env2.getTimeZone());
+ assertNull(env2.getSQLDateAndTimeTimeZone());
+
+ env1.setSQLDateAndTimeTimeZone(_DateUtil.UTC);
+ // cfg:
+ assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+ assertNull(cfg.getSQLDateAndTimeTimeZone());
+ // env:
+ assertEquals(TimeZone.getDefault(), env1.getTimeZone());
+ assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
+
+ env1.setTimeZone(localTZ);
+ // cfg:
+ assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+ assertNull(cfg.getSQLDateAndTimeTimeZone());
+ // env:
+ assertEquals(localTZ, env1.getTimeZone());
+ assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
+ // env 2:
+ assertEquals(TimeZone.getDefault(), env2.getTimeZone());
+ assertNull(env2.getSQLDateAndTimeTimeZone());
+ }
+
+ {
+ TimeZone otherTZ1 = TimeZone.getTimeZone("GMT+05");
+ TimeZone otherTZ2 = TimeZone.getTimeZone("GMT+06");
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .timeZone(otherTZ1)
+ .sqlDateAndTimeTimeZone(otherTZ2)
+ .build();
+
+ Template t = new Template(null, "", cfg);
+ Environment env1 = t.createProcessingEnvironment(null, new StringWriter());
+ Environment env2 = t.createProcessingEnvironment(null, new StringWriter());
+
+ env1.setTimeZone(localTZ);
+ env1.setSQLDateAndTimeTimeZone(_DateUtil.UTC);
+
+ // cfg:
+ assertEquals(otherTZ1, cfg.getTimeZone());
+ assertEquals(otherTZ2, cfg.getSQLDateAndTimeTimeZone());
+ // env:
+ assertEquals(localTZ, env1.getTimeZone());
+ assertEquals(_DateUtil.UTC, env1.getSQLDateAndTimeTimeZone());
+ // env 2:
+ assertEquals(otherTZ1, env2.getTimeZone());
+ assertEquals(otherTZ2, env2.getSQLDateAndTimeTimeZone());
+
+ try {
+ setTimeZoneToNull(env2);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ env2.setSQLDateAndTimeTimeZone(null);
+ assertEquals(otherTZ1, env2.getTimeZone());
+ assertNull(env2.getSQLDateAndTimeTimeZone());
+ }
+ }
+
+ @SuppressFBWarnings(value="NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS", justification="Expected to fail")
+ private void setTimeZoneToNull(Environment env2) {
+ env2.setTimeZone(null);
+ }
+
+ public void testSetICIViaSetSettingAPI() throws ConfigurationException {
+ Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertEquals(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS, cfg.getIncompatibleImprovements());
+ // This is the only valid value ATM:
+ cfg.setSetting(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY, "3.0.0");
+ assertEquals(Configuration.VERSION_3_0_0, cfg.getIncompatibleImprovements());
+ }
+
+ public void testSetLogTemplateExceptionsViaSetSettingAPI() throws ConfigurationException {
+ Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertFalse(cfg.getLogTemplateExceptions());
+ cfg.setSetting(MutableProcessingConfiguration.LOG_TEMPLATE_EXCEPTIONS_KEY, "true");
+ assertTrue(cfg.getLogTemplateExceptions());
+ }
+
+ public void testSharedVariables() throws TemplateException, IOException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ Map<String, Object> vars = new HashMap<>();
+ vars.put("a", "aa");
+ vars.put("b", "bb");
+ vars.put("c", new MyScalarModel());
+ cfgB.setSharedVariables(vars);
+
+ assertNull(cfgB.getSharedVariable("erased"));
+
+ {
+ Configuration cfg = cfgB.build();
+
+ TemplateScalarModel aVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("a");
+ assertEquals("aa", aVal.getAsString());
+ assertEquals(SimpleScalar.class, aVal.getClass());
+
+ TemplateScalarModel bVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("b");
+ assertEquals("bb", bVal.getAsString());
+ assertEquals(SimpleScalar.class, bVal.getClass());
+
+ TemplateScalarModel cVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("c");
+ assertEquals("my", cVal.getAsString());
+ assertEquals(MyScalarModel.class, cfg.getWrappedSharedVariable("c").getClass());
+
+ // See if it actually works in templates:
+ StringWriter sw = new StringWriter();
+ new Template(null, "${a} ${b}", cfg)
+ .process(ImmutableMap.of("a", "aaDM"), sw);
+ assertEquals("aaDM bb", sw.toString());
+ }
+
+ cfgB.setSharedVariable("b", "bbLegacy");
+
+ {
+ Configuration cfg = cfgB.build();
+
+ TemplateScalarModel aVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("a");
+ assertEquals("aa", aVal.getAsString());
+ assertEquals(SimpleScalar.class, aVal.getClass());
+
+ TemplateScalarModel bVal = (TemplateScalarModel) cfg.getWrappedSharedVariable("b");
+ assertEquals("bbLegacy", bVal.getAsString());
+ assertEquals(SimpleScalar.class, bVal.getClass());
+ }
+ }
+
+ @Test
+ public void testApiBuiltinEnabled() throws Exception {
+ try {
+ new Template(
+ null, "${1?api}",
+ new Configuration.Builder(Configuration.VERSION_3_0_0).build())
+ .process(null, _NullWriter.INSTANCE);
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString(MutableProcessingConfiguration.API_BUILTIN_ENABLED_KEY));
+ }
+
+ new Template(
+ null, "${m?api.hashCode()}",
+ new Configuration.Builder(Configuration.VERSION_3_0_0).apiBuiltinEnabled(true).build())
+ .process(Collections.singletonMap("m", new HashMap()), _NullWriter.INSTANCE);
+ }
+
+ @Test
+ public void testTemplateUpdateDelay() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(DefaultTemplateResolver.DEFAULT_TEMPLATE_UPDATE_DELAY_MILLIS, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ cfgB.setTemplateUpdateDelayMilliseconds(4000);
+ assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ cfgB.setTemplateUpdateDelayMilliseconds(100);
+ assertEquals(100L, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ try {
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5");
+ assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds());
+ } catch (ConfigurationSettingValueException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("unit must be specified"));
+ }
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "0");
+ assertEquals(0L, cfgB.getTemplateUpdateDelayMilliseconds());
+ try {
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5 foo");
+ assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds());
+ } catch (ConfigurationSettingValueException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("\"foo\""));
+ }
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 ms");
+ assertEquals(3L, cfgB.getTemplateUpdateDelayMilliseconds());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4ms");
+ assertEquals(4L, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 s");
+ assertEquals(3000L, cfgB.getTemplateUpdateDelayMilliseconds());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4s");
+ assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 m");
+ assertEquals(1000L * 60 * 3, cfgB.getTemplateUpdateDelayMilliseconds());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4m");
+ assertEquals(1000L * 60 * 4, cfgB.getTemplateUpdateDelayMilliseconds());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "1 h");
+ assertEquals(1000L * 60 * 60, cfgB.getTemplateUpdateDelayMilliseconds());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "2h");
+ assertEquals(1000L * 60 * 60 * 2, cfgB.getTemplateUpdateDelayMilliseconds());
+ }
+
+ @Test
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS ", justification = "Testing wrong args")
+ public void testSetCustomNumberFormat() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ try {
+ cfgB.setCustomNumberFormats(null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("null"));
+ }
+
+ try {
+ cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
+ "", HexTemplateNumberFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("0 length"));
+ }
+
+ try {
+ cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
+ "a_b", HexTemplateNumberFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("a_b"));
+ }
+
+ try {
+ cfgB.setCustomNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
+ "a b", HexTemplateNumberFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("a b"));
+ }
+
+ try {
+ cfgB.setCustomNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
+ "a", HexTemplateNumberFormatFactory.INSTANCE,
+ "@wrong", HexTemplateNumberFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("@wrong"));
+ }
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE,
+ "{ 'base': " + BaseNTemplateNumberFormatFactory.class.getName() + "() }");
+ assertEquals(
+ Collections.singletonMap("base", BaseNTemplateNumberFormatFactory.INSTANCE),
+ cfgB.getCustomNumberFormats());
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_SNAKE_CASE,
+ "{ "
+ + "'base': " + BaseNTemplateNumberFormatFactory.class.getName() + "(), "
+ + "'hex': " + HexTemplateNumberFormatFactory.class.getName() + "()"
+ + " }");
+ assertEquals(
+ ImmutableMap.of(
+ "base", BaseNTemplateNumberFormatFactory.INSTANCE,
+ "hex", HexTemplateNumberFormatFactory.INSTANCE),
+ cfgB.getCustomNumberFormats());
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY, "{}");
+ assertEquals(Collections.emptyMap(), cfgB.getCustomNumberFormats());
+
+ try {
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE,
+ "{ 'x': " + EpochMillisTemplateDateFormatFactory.class.getName() + "() }");
+ fail();
+ } catch (ConfigurationException e) {
+ assertThat(e.getCause().getMessage(), allOf(
+ containsString(EpochMillisTemplateDateFormatFactory.class.getName()),
+ containsString(TemplateNumberFormatFactory.class.getName())));
+ }
+ }
+
+ @Test
+ public void testSetTabSize() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ String ftl = "${\t}";
+
+ try {
+ new Template(null, ftl, cfgB.build());
+ fail();
+ } catch (ParseException e) {
+ assertEquals(9, e.getColumnNumber());
+ }
+
+ cfgB.setTabSize(1);
+ try {
+ new Template(null, ftl, cfgB.build());
+ fail();
+ } catch (ParseException e) {
+ assertEquals(4, e.getColumnNumber());
+ }
+
+ try {
+ cfgB.setTabSize(0);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ cfgB.setTabSize(257);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testTabSizeSetting() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ assertEquals(8, cfgB.getTabSize());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_CAMEL_CASE, "4");
+ assertEquals(4, cfgB.getTabSize());
+ cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_SNAKE_CASE, "1");
+ assertEquals(1, cfgB.getTabSize());
+
+ try {
+ cfgB.setSetting(Configuration.ExtendableBuilder.TAB_SIZE_KEY_SNAKE_CASE, "x");
+ fail();
+ } catch (ConfigurationException e) {
+ assertThat(e.getCause(), instanceOf(NumberFormatException.class));
+ }
+ }
+
+ @SuppressFBWarnings(value="NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS", justification="We test failures")
+ @Test
+ public void testSetCustomDateFormat() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ try {
+ cfgB.setCustomDateFormats(null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("null"));
+ }
+
+ try {
+ cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
+ "", EpochMillisTemplateDateFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("0 length"));
+ }
+
+ try {
+ cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
+ "a_b", EpochMillisTemplateDateFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("a_b"));
+ }
+
+ try {
+ cfgB.setCustomDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
+ "a b", EpochMillisTemplateDateFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("a b"));
+ }
+
+ try {
+ cfgB.setCustomDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
+ "a", EpochMillisTemplateDateFormatFactory.INSTANCE,
+ "@wrong", EpochMillisTemplateDateFormatFactory.INSTANCE));
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), containsString("@wrong"));
+ }
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE,
+ "{ 'epoch': " + EpochMillisTemplateDateFormatFactory.class.getName() + "() }");
+ assertEquals(
+ Collections.singletonMap("epoch", EpochMillisTemplateDateFormatFactory.INSTANCE),
+ cfgB.getCustomDateFormats());
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_SNAKE_CASE,
+ "{ "
+ + "'epoch': " + EpochMillisTemplateDateFormatFactory.class.getName() + "(), "
+ + "'epochDiv': " + EpochMillisDivTemplateDateFormatFactory.class.getName() + "()"
+ + " }");
+ assertEquals(
+ ImmutableMap.of(
+ "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
+ "epochDiv", EpochMillisDivTemplateDateFormatFactory.INSTANCE),
+ cfgB.getCustomDateFormats());
+
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY, "{}");
+ assertEquals(Collections.emptyMap(), cfgB.getCustomDateFormats());
+
+ try {
+ cfgB.setSetting(MutableProcessingConfiguration.CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE,
+ "{ 'x': " + HexTemplateNumberFormatFactory.class.getName() + "() }");
+ fail();
+ } catch (ConfigurationException e) {
+ assertThat(e.getCause().getMessage(), allOf(
+ containsString(HexTemplateNumberFormatFactory.class.getName()),
+ containsString(TemplateDateFormatFactory.class.getName())));
+ }
+ }
+
+ public void testNamingConventionSetSetting() throws ConfigurationException {
+ Configuration.Builder cfg = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention());
+
+ cfg.setSetting("naming_convention", "legacy");
+ assertEquals(ParsingConfiguration.LEGACY_NAMING_CONVENTION, cfg.getNamingConvention());
+
+ cfg.setSetting("naming_convention", "camel_case");
+ assertEquals(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION, cfg.getNamingConvention());
+
+ cfg.setSetting("naming_convention", "auto_detect");
+ assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention());
+ }
+
+ public void testLazyImportsSetSetting() throws ConfigurationException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertFalse(cfgB.getLazyImports());
+ assertFalse(cfgB.isLazyImportsSet());
+ cfgB.setSetting("lazy_imports", "true");
+ assertTrue(cfgB.getLazyImports());
+ cfgB.setSetting("lazyImports", "false");
+ assertFalse(cfgB.getLazyImports());
+ assertTrue(cfgB.isLazyImportsSet());
+ }
+
+ public void testLazyAutoImportsSetSetting() throws ConfigurationException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertNull(cfgB.getLazyAutoImports());
+ assertFalse(cfgB.isLazyAutoImportsSet());
+ cfgB.setSetting("lazy_auto_imports", "true");
+ assertEquals(Boolean.TRUE, cfgB.getLazyAutoImports());
+ assertTrue(cfgB.isLazyAutoImportsSet());
+ cfgB.setSetting("lazyAutoImports", "false");
+ assertEquals(Boolean.FALSE, cfgB.getLazyAutoImports());
+ cfgB.setSetting("lazyAutoImports", "null");
+ assertNull(cfgB.getLazyAutoImports());
+ assertTrue(cfgB.isLazyAutoImportsSet());
+ cfgB.unsetLazyAutoImports();
+ assertNull(cfgB.getLazyAutoImports());
+ assertFalse(cfgB.isLazyAutoImportsSet());
+ }
+
+ public void testLocaleSetting() throws TemplateException, ConfigurationException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(Locale.getDefault(), cfgB.getLocale());
+ assertFalse(cfgB.isLocaleSet());
+
+ Locale nonDefault = Locale.getDefault().equals(Locale.GERMANY) ? Locale.FRANCE : Locale.GERMANY;
+ cfgB.setLocale(nonDefault);
+ assertTrue(cfgB.isLocaleSet());
+ assertEquals(nonDefault, cfgB.getLocale());
+
+ cfgB.unsetLocale();
+ assertEquals(Locale.getDefault(), cfgB.getLocale());
+ assertFalse(cfgB.isLocaleSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.LOCALE_KEY, "JVM default");
+ assertEquals(Locale.getDefault(), cfgB.getLocale());
+ assertTrue(cfgB.isLocaleSet());
+ }
+
+ public void testDefaultEncodingSetting() throws TemplateException, ConfigurationException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
+ assertFalse(cfgB.isSourceEncodingSet());
+
+ Charset nonDefault = Charset.defaultCharset().equals(StandardCharsets.UTF_8) ? StandardCharsets.ISO_8859_1
+ : StandardCharsets.UTF_8;
+ cfgB.setSourceEncoding(nonDefault);
+ assertTrue(cfgB.isSourceEncodingSet());
+ assertEquals(nonDefault, cfgB.getSourceEncoding());
+
+ cfgB.unsetSourceEncoding();
+ assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
+ assertFalse(cfgB.isSourceEncodingSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY, "JVM default");
+ assertEquals(Charset.defaultCharset(), cfgB.getSourceEncoding());
+ assertTrue(cfgB.isSourceEncodingSet());
+ }
+
+ public void testTimeZoneSetting() throws TemplateException, ConfigurationException {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
+ assertFalse(cfgB.isTimeZoneSet());
+
+ TimeZone nonDefault = TimeZone.getDefault().equals(_DateUtil.UTC) ? TimeZone.getTimeZone("PST") : _DateUtil.UTC;
+ cfgB.setTimeZone(nonDefault);
+ assertTrue(cfgB.isTimeZoneSet());
+ assertEquals(nonDefault, cfgB.getTimeZone());
+
+ cfgB.unsetTimeZone();
+ assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
+ assertFalse(cfgB.isTimeZoneSet());
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.TIME_ZONE_KEY, "JVM default");
+ assertEquals(TimeZone.getDefault(), cfgB.getTimeZone());
+ assertTrue(cfgB.isTimeZoneSet());
+ }
+
+ @Test
+ public void testGetSettingNamesAreSorted() throws Exception {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+ for (boolean camelCase : new boolean[] { false, true }) {
+ List<String> names = new ArrayList<>(Configuration.Builder.getSettingNames(camelCase));
+ List<String> procCfgNames = new ArrayList<>(new Template(null, "", cfg)
+ .createProcessingEnvironment(null, _NullWriter.INSTANCE)
+ .getSettingNames(camelCase));
+ assertStartsWith(names, procCfgNames);
+
+ String prevName = null;
+ for (int i = procCfgNames.size(); i < names.size(); i++) {
+ String name = names.get(i);
+ if (prevName != null) {
+ assertThat(name, greaterThan(prevName));
+ }
+ prevName = name;
+ }
+ }
+ }
+
+ @Test
+ @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
+ public void testGetSettingNamesNameConventionsContainTheSame() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ ConfigurableTest.testGetSettingNamesNameConventionsContainTheSame(
+ new ArrayList<>(cfgB.getSettingNames(false)),
+ new ArrayList<>(cfgB.getSettingNames(true)));
+ }
+
+ @Test
+ @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
+ public void testStaticFieldKeysCoverAllGetSettingNames() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ List<String> names = new ArrayList<>(cfgB.getSettingNames(false));
+ List<String> cfgableNames = new ArrayList<>(cfgB.getSettingNames(false));
+ assertStartsWith(names, cfgableNames);
+
+ for (int i = cfgableNames.size(); i < names.size(); i++) {
+ String name = names.get(i);
+ assertTrue("No field was found for " + name, keyFieldExists(name));
+ }
+ }
+
+ @Test
+ public void testGetSettingNamesCoversAllStaticKeyFields() throws Exception {
+ Collection<String> names = new Configuration.Builder(Configuration.VERSION_3_0_0).getSettingNames(false);
+
+ for (Class<? extends MutableProcessingConfiguration> cfgableClass : new Class[] { Configuration.class, MutableProcessingConfiguration.class }) {
+ for (Field f : cfgableClass.getFields()) {
+ if (f.getName().endsWith("_KEY")) {
+ final Object name = f.get(null);
+ assertTrue("Missing setting name: " + name, names.contains(name));
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testKeyStaticFieldsHasAllVariationsAndCorrectFormat() throws IllegalArgumentException, IllegalAccessException {
+ ConfigurableTest.testKeyStaticFieldsHasAllVariationsAndCorrectFormat(Configuration.ExtendableBuilder.class);
+ }
+
+ @Test
+ public void testGetSettingNamesCoversAllSettingNames() throws Exception {
+ Collection<String> names = new Configuration.Builder(Configuration.VERSION_3_0_0).getSettingNames(false);
+
+ for (Field f : MutableProcessingConfiguration.class.getFields()) {
+ if (f.getName().endsWith("_KEY")) {
+ final Object name = f.get(null);
+ assertTrue("Missing setting name: " + name, names.contains(name));
+ }
+ }
+ }
+
+ @Test
+ public void testSetSettingSupportsBothNamingConventions() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_CAMEL_CASE, StandardCharsets.UTF_16LE.name());
+ assertEquals(StandardCharsets.UTF_16LE, cfgB.getSourceEncoding());
+ cfgB.setSetting(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_SNAKE_CASE, StandardCharsets.UTF_8.name());
+ assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
+
+ for (String nameCC : cfgB.getSettingNames(true)) {
+ for (String value : new String[] { "1", "default", "true" }) {
+ Exception resultCC = null;
+ try {
+ cfgB.setSetting(nameCC, value);
+ } catch (Exception e) {
+ assertThat(e, not(instanceOf(UnknownConfigurationSettingException.class)));
+ resultCC = e;
+ }
+
+ String nameSC = _StringUtil.camelCaseToUnderscored(nameCC);
+ Exception resultSC = null;
+ try {
+ cfgB.setSetting(nameSC, value);
+ } catch (Exception e) {
+ assertThat(e, not(instanceOf(UnknownConfigurationSettingException.class)));
+ resultSC = e;
+ }
+
+ if (resultCC == null) {
+ assertNull(resultSC);
+ } else {
+ assertNotNull(resultSC);
+ assertEquals(resultCC.getClass(), resultSC.getClass());
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testGetSupportedBuiltInDirectiveNames() {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+
+ Set<String> allNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
+ Set<String> lNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ Set<String> cNames = cfg.getSupportedBuiltInDirectiveNames(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+
+ checkNamingConventionNameSets(allNames, lNames, cNames);
+
+ for (String name : cNames) {
+ assertThat(name.toLowerCase(), isIn(lNames));
+ }
+ }
+
+ @Test
+ public void testGetSupportedBuiltInNames() {
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build();
+
+ Set<String> allNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
+ Set<String> lNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ Set<String> cNames = cfg.getSupportedBuiltInNames(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+
+ checkNamingConventionNameSets(allNames, lNames, cNames);
+ }
+
+ private void checkNamingConventionNameSets(Set<String> allNames, Set<String> lNames, Set<String> cNames) {
+ for (String name : lNames) {
+ assertThat(allNames, hasItem(name));
+ assertTrue("Should be all-lowercase: " + name, name.equals(name.toLowerCase()));
+ }
+ for (String name : cNames) {
+ assertThat(allNames, hasItem(name));
+ }
+ for (String name : allNames) {
+ assertThat(name, anyOf(isIn(lNames), isIn(cNames)));
+ }
+ assertEquals(lNames.size(), cNames.size());
+ }
+
+ @Test
+ public void testRemovedSettings() {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+ try {
+ cfgB.setSetting("classic_compatible", "true");
+ fail();
+ } catch (ConfigurationException e) {
+ assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0")));
+ }
+ try {
+ cfgB.setSetting("strict_syntax", "true");
+ fail();
+ } catch (ConfigurationException e) {
+ assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0")));
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ private void assertStartsWith(List<String> list, List<String> headList) {
+ int index = 0;
+ for (String name : headList) {
+ assertThat(index, lessThan(list.size()));
+ assertEquals(name, list.get(index));
+ index++;
+ }
+ }
+
+ private boolean keyFieldExists(String name) throws Exception {
+ Field field;
+ try {
+ field = Configuration.class.getField(name.toUpperCase() + "_KEY");
+ } catch (NoSuchFieldException e) {
+ return false;
+ }
+ assertEquals(name, field.get(null));
+ return true;
+ }
+
+ private static class MyScalarModel implements TemplateScalarModel {
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return "my";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
new file mode 100644
index 0000000..6714fc3
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoreLocaleUtilsTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.util.Locale;
+
+import org.apache.freemarker.core.util._LocaleUtil;
+import org.junit.Test;
+
+public class CoreLocaleUtilsTest {
+
+ @Test
+ public void testGetLessSpecificLocale() {
+ Locale locale;
+
+ locale = new Locale("ru", "RU", "Linux");
+ assertEquals("ru_RU_Linux", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertEquals("ru_RU", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertEquals("ru", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+
+ locale = new Locale("ch", "CH");
+ assertEquals("ch_CH", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertEquals("ch", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+
+ locale = new Locale("ja");
+ assertEquals("ja", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+
+ locale = new Locale("ja", "", "");
+ assertEquals("ja", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+
+ locale = new Locale("");
+ assertEquals("", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+
+ locale = new Locale("hu", "", "Linux");
+ assertEquals("hu__Linux", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertEquals("hu", locale.toString());
+ locale = _LocaleUtil.getLessSpecificLocale(locale);
+ assertNull(locale);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
new file mode 100644
index 0000000..726a20c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomAttributeTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+@SuppressWarnings("boxing")
+public class CustomAttributeTest {
+
+ private static final String KEY_1 = "key1";
+ private static final String KEY_2 = "key2";
+ private static final String KEY_3 = "key3";
+ private static final Integer KEY_4 = 4;
+
+ private static final Integer VALUE_1 = 1; // Serializable
+ private static final Object VALUE_2 = new Object();
+ private static final Object VALUE_3 = new Object();
+ private static final Object VALUE_4 = new Object();
+ private static final Object VALUE_LIST = ImmutableList.<Object>of(
+ "s", BigDecimal.valueOf(2), Boolean.TRUE, ImmutableMap.of("a", "A"));
+ private static final Object VALUE_BIGDECIMAL = BigDecimal.valueOf(22);
+
+ private static final Object CUST_ATT_KEY = new Object();
+
+ @Test
+ public void testStringKey() throws Exception {
+ // Need some MutableProcessingConfiguration:
+ TemplateConfiguration.Builder mpc = new TemplateConfiguration.Builder();
+
+ assertEquals(0, mpc.getCustomAttributeNames().length);
+ assertNull(mpc.getCustomAttribute(KEY_1));
+
+ mpc.setCustomAttribute(KEY_1, VALUE_1);
+ assertArrayEquals(new String[] { KEY_1 }, mpc.getCustomAttributeNames());
+ assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
+
+ mpc.setCustomAttribute(KEY_2, VALUE_2);
+ assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
+ assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
+ assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
+
+ mpc.setCustomAttribute(KEY_1, VALUE_2);
+ assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
+ assertSame(VALUE_2, mpc.getCustomAttribute(KEY_1));
+ assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
+
+ mpc.setCustomAttribute(KEY_1, null);
+ assertArrayEquals(new String[] { KEY_1, KEY_2 }, sort(mpc.getCustomAttributeNames()));
+ assertNull(mpc.getCustomAttribute(KEY_1));
+ assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
+
+ mpc.removeCustomAttribute(KEY_1);
+ assertArrayEquals(new String[] { KEY_2 }, mpc.getCustomAttributeNames());
+ assertNull(mpc.getCustomAttribute(KEY_1));
+ assertSame(VALUE_2, mpc.getCustomAttribute(KEY_2));
+ }
+
+ @Test
+ public void testRemoveFromEmptySet() throws Exception {
+ // Need some MutableProcessingConfiguration:
+ TemplateConfiguration.Builder mpc = new TemplateConfiguration.Builder();
+
+ mpc.removeCustomAttribute(KEY_1);
+ assertEquals(0, mpc.getCustomAttributeNames().length);
+ assertNull(mpc.getCustomAttribute(KEY_1));
+
+ mpc.setCustomAttribute(KEY_1, VALUE_1);
+ assertArrayEquals(new String[] { KEY_1 }, mpc.getCustomAttributeNames());
+ assertSame(VALUE_1, mpc.getCustomAttribute(KEY_1));
+ }
+
+ @Test
+ public void testAttrsFromFtlHeaderOnly() throws Exception {
+ Template t = new Template(null, "<#ftl attributes={"
+ + "'" + KEY_1 + "': [ 's', 2, true, { 'a': 'A' } ], "
+ + "'" + KEY_2 + "': " + VALUE_BIGDECIMAL + " "
+ + "}>",
+ new Configuration.Builder(Configuration.VERSION_3_0_0).build());
+
+ assertEquals(ImmutableSet.of(KEY_1, KEY_2), t.getCustomAttributes().keySet());
+ assertEquals(VALUE_LIST, t.getCustomAttribute(KEY_1));
+ assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
+
+ t.setCustomAttribute(KEY_1, VALUE_1);
+ assertEquals(VALUE_1, t.getCustomAttribute(KEY_1));
+ assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
+
+ t.setCustomAttribute(KEY_1, null);
+ assertEquals(ImmutableSet.of(KEY_1, KEY_2), t.getCustomAttributes().keySet());
+ assertNull(t.getCustomAttribute(KEY_1));
+ }
+
+ @Test
+ public void testAttrsFromFtlHeaderAndFromTemplateConfiguration() throws Exception {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setCustomAttribute(KEY_3, VALUE_3);
+ tcb.setCustomAttribute(KEY_4, VALUE_4);
+ Template t = new Template(null, "<#ftl attributes={"
+ + "'" + KEY_1 + "': 'a', "
+ + "'" + KEY_2 + "': 'b', "
+ + "'" + KEY_3 + "': 'c' "
+ + "}>",
+ new Configuration.Builder(Configuration.VERSION_3_0_0).build(),
+ tcb.build());
+
+ assertEquals(ImmutableSet.of(KEY_1, KEY_2, KEY_3, KEY_4), t.getCustomAttributes().keySet());
+ assertEquals("a", t.getCustomAttribute(KEY_1));
+ assertEquals("b", t.getCustomAttribute(KEY_2));
+ assertEquals("c", t.getCustomAttribute(KEY_3)); // Has overridden TC attribute
+ assertEquals(VALUE_4, t.getCustomAttribute(KEY_4)); // Inherited TC attribute
+
+ t.setCustomAttribute(KEY_3, null);
+ assertEquals(ImmutableSet.of(KEY_1, KEY_2, KEY_3, KEY_4), t.getCustomAttributes().keySet());
+ assertNull("null value shouldn't cause fallback to TC attribute", t.getCustomAttribute(KEY_3));
+ }
+
+
+ @Test
+ public void testAttrsFromTemplateConfigurationOnly() throws Exception {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setCustomAttribute(KEY_3, VALUE_3);
+ tcb.setCustomAttribute(KEY_4, VALUE_4);
+ Template t = new Template(null, "",
+ new Configuration.Builder(Configuration.VERSION_3_0_0).build(),
+ tcb.build());
+
+ assertEquals(ImmutableSet.of(KEY_3, KEY_4), t.getCustomAttributes().keySet());
+ assertEquals(VALUE_3, t.getCustomAttribute(KEY_3));
+ assertEquals(VALUE_4, t.getCustomAttribute(KEY_4));
+ }
+
+ private Object[] sort(String[] customAttributeNames) {
+ Arrays.sort(customAttributeNames);
+ return customAttributeNames;
+ }
+
+}
[17/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java
deleted file mode 100644
index 3b59e78..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-public class SettingDirectiveTest {
-
- @Test
- public void testGetSettingNamesSorted() throws Exception {
- String prevName = null;
- for (String name : ASTDirSetting.SETTING_NAMES) {
- if (prevName != null) {
- assertThat(name, greaterThan(prevName));
- }
- prevName = name;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
deleted file mode 100644
index 7e17fc7..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-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.test.TemplateTest;
-import org.junit.Test;
-
-public class SpecialVariableTest extends TemplateTest {
-
- @Test
- public void testNamesSorted() throws Exception {
- String prevName = null;
- for (String name : ASTExpBuiltInVariable.SPEC_VAR_NAMES) {
- if (prevName != null) {
- assertThat(name, greaterThan(prevName));
- }
- prevName = name;
- }
- }
-
- @Test
- public void testVersion() throws Exception {
- String versionStr = Configuration.getVersion().toString();
- assertOutput("${.version}", versionStr);
- }
-
- @Test
- public void testIncompationImprovements() throws Exception {
- setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0).build());
- assertOutput(
- "${.incompatibleImprovements}",
- getConfiguration().getIncompatibleImprovements().toString());
-
- setConfiguration(new Configuration.Builder(Configuration.getVersion()).build());
- assertOutput(
- "${.incompatible_improvements}",
- getConfiguration().getIncompatibleImprovements().toString());
- }
-
- @Test
- public void testAutoEsc() throws Exception {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
-
- for (int autoEscaping : new int[] {
- ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY }) {
- cfgB.setAutoEscapingPolicy(autoEscaping);
- cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "true");
- assertOutput("<#ftl autoEsc=false>${.autoEsc?c}", "false");
-
- cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "false");
-
- cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "false");
- }
-
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
- cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "false");
- assertOutput("<#ftl autoEsc=true>${.autoEsc?c}", "true");
-
- cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "false");
-
- cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
- setConfiguration(cfgB.build());
- assertOutput("${.autoEsc?c}", "false");
-
- cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY);
- setConfiguration(cfgB.build());
- assertOutput(
- "${.autoEsc?c} "
- + "<#outputFormat 'HTML'>${.autoEsc?c}</#outputFormat> "
- + "<#outputFormat 'undefined'>${.autoEsc?c}</#outputFormat> "
- + "<#outputFormat 'HTML'>"
- + "${.autoEsc?c} <#noAutoEsc>${.autoEsc?c} "
- + "<#autoEsc>${.autoEsc?c}</#autoEsc> ${.autoEsc?c}</#noAutoEsc> ${.autoEsc?c}"
- + "</#outputFormat>",
- "false true false "
- + "true false true false true");
-
- assertErrorContains("${.autoEscaping}", "You may meant: \"autoEsc\"");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
deleted file mode 100644
index ae72dac..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.util.Collections;
-
-import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
-import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class StringLiteralInterpolationTest extends TemplateTest {
-
- @Test
- public void basics() throws IOException, TemplateException {
- addToDataModel("x", 1);
- assertOutput("${'${x}'}", "1");
- assertOutput("${'#{x}'}", "1");
- assertOutput("${'a${x}b${x*2}c'}", "a1b2c");
- assertOutput("${'a#{x}b#{x*2}c'}", "a1b2c");
- assertOutput("${'a#{x; m2}'}", "a1.00");
- assertOutput("${'${x} ${x}'}", "1 1");
- assertOutput("${'$\\{x}'}", "${x}");
- assertOutput("${'$\\{x} $\\{x}'}", "${x} ${x}");
- assertOutput("${'<#-- not a comment -->${x}'}", "<#-- not a comment -->1");
- assertOutput("${'<#-- not a comment -->$\\{x}'}", "<#-- not a comment -->${x}");
- assertOutput("${'<#assign x = 2> ${x} <#assign x = 2>'}", "<#assign x = 2> 1 <#assign x = 2>");
- assertOutput("${'<#assign x = 2> $\\{x} <#assign x = 2>'}", "<#assign x = 2> ${x} <#assign x = 2>");
- assertOutput("${'<@x/>${x}<@x/>'}", "<@x/>1<@x/>");
- assertOutput("${'<@x/>$\\{x}<@x/>'}", "<@x/>${x}<@x/>");
- assertOutput("${'<@ ${x}<@'}", "<@ 1<@");
- assertOutput("${'<@ $\\{x}<@'}", "<@ ${x}<@");
- assertOutput("${'</...@x>${x}'}", "</...@x>1");
- assertOutput("${'</...@x>$\\{x}'}", "</...@x>${x}");
- assertOutput("${'</@ ${x}</@'}", "</@ 1</@");
- assertOutput("${'</@ $\\{x}</@'}", "</@ ${x}</@");
- assertOutput("${'[@ ${x}'}", "[@ 1");
- assertOutput("${'[@ $\\{x}'}", "[@ ${x}");
- }
-
- /**
- * Broken behavior for backward compatibility.
- */
- @Test
- public void legacyEscapingBugStillPresent() throws IOException, TemplateException {
- addToDataModel("x", 1);
- assertOutput("${'$\\{x} ${x}'}", "1 1");
- assertOutput("${'${x} $\\{x}'}", "1 1");
- }
-
- @Test
- public void legacyLengthGlitch() throws IOException, TemplateException {
- assertOutput("${'${'}", "${");
- assertOutput("${'${1'}", "${1");
- assertOutput("${'${}'}", "${}");
- assertOutput("${'${1}'}", "1");
- assertErrorContains("${'${ '}", "");
- }
-
- @Test
- public void testErrors() {
- addToDataModel("x", 1);
- assertErrorContains("${'${noSuchVar}'}", InvalidReferenceException.class, "missing", "noSuchVar");
- assertErrorContains("${'${x/0}'}", ArithmeticException.class, "zero");
- }
-
- @Test
- public void escaping() throws IOException, TemplateException {
- assertOutput("<#escape x as x?html><#assign x = '&'>${x} ${'${x}'}</#escape> ${x}", "& & &");
- }
-
- // We couldn't test this on 3.0.0, as nothing was fixed there with IcI yet
- /*-
- @Test
- public void iciInheritanceBugFixed() throws Exception {
- // Broken behavior emulated:
- getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_23);
- assertOutput("${'&\\''?html} ${\"${'&\\\\\\''?html}\"}", "&' &'");
-
- // Fix enabled:
- getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_24);
- assertOutput("${'&\\''?html} ${\"${'&\\\\\\''?html}\"}", "&' &'");
- }
- */
-
- @Test
- public void markup() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .customNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
- "G", PrintfGTemplateNumberFormatFactory.INSTANCE))
- .numberFormat("@G 3")
- .build());
-
- assertOutput("${\"${1000}\"}", "1.00*10<sup>3</sup>");
- assertOutput("${\"&_${1000}\"}", "&_1.00*10<sup>3</sup>");
- assertOutput("${\"${1000}_&\"}", "1.00*10<sup>3</sup>_&");
- assertOutput("${\"${1000}, ${2000}\"}", "1.00*10<sup>3</sup>, 2.00*10<sup>3</sup>");
- assertOutput("${\"& ${'x'}, ${2000}\"}", "& x, 2.00*10<sup>3</sup>");
- assertOutput("${\"& ${'x'}, #{2000}\"}", "& x, 2000");
-
- assertOutput("${\"${2000}\"?isMarkupOutput?c}", "true");
- assertOutput("${\"x ${2000}\"?isMarkupOutput?c}", "true");
- assertOutput("${\"${2000} x\"?isMarkupOutput?c}", "true");
- assertOutput("${\"#{2000}\"?isMarkupOutput?c}", "false");
- assertOutput("${\"${'x'}\"?isMarkupOutput?c}", "false");
- assertOutput("${\"x ${'x'}\"?isMarkupOutput?c}", "false");
- assertOutput("${\"${'x'} x\"?isMarkupOutput?c}", "false");
-
- addToDataModel("rtf", RTFOutputFormat.INSTANCE.fromMarkup("\\p"));
- assertOutput("${\"${rtf}\"?isMarkupOutput?c}", "true");
- assertErrorContains("${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
- assertErrorContains("x${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TabSizeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TabSizeTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TabSizeTest.java
deleted file mode 100644
index 7945b5e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TabSizeTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class TabSizeTest extends TemplateTest {
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return super.createDefaultConfiguration();
- }
-
- @Test
- public void testBasics() throws Exception {
- assertErrorColumnNumber(3, "${*}");
- assertErrorColumnNumber(8 + 3, "\t${*}");
- assertErrorColumnNumber(16 + 3, "\t\t${*}");
- assertErrorColumnNumber(16 + 3, " \t \t${*}");
-
- setConfiguration(new TestConfigurationBuilder().tabSize(1).build());
- assertErrorColumnNumber(3, "${*}");
- assertErrorColumnNumber(1 + 3, "\t${*}");
- assertErrorColumnNumber(2 + 3, "\t\t${*}");
- assertErrorColumnNumber(6 + 3, " \t \t${*}");
- }
-
- @Test
- public void testEvalBI() throws Exception {
- assertErrorContains("${r'\t~'?eval}", "column 9");
- setConfiguration(new TestConfigurationBuilder().tabSize(4).build());
- assertErrorContains("${r'\t~'?eval}", "column 5");
- }
-
- @Test
- public void testInterpretBI() throws Exception {
- assertErrorContains("<@'\\t$\\{*}'?interpret />", "column 11");
- setConfiguration(new TestConfigurationBuilder().tabSize(4).build());
- assertErrorContains("<@'\\t$\\{*}'?interpret />", "column 7");
- }
-
- @Test
- public void testStringLiteralInterpolation() throws Exception {
- assertErrorColumnNumber(6, "${'${*}'}");
- assertErrorColumnNumber(9, "${'${\t*}'}");
- setConfiguration(new TestConfigurationBuilder().tabSize(16).build());
- assertErrorColumnNumber(17, "${'${\t*}'}");
- }
-
- protected void assertErrorColumnNumber(int expectedColumn, String templateSource)
- throws IOException {
- addTemplate("t", templateSource);
- try {
- getConfiguration().getTemplate("t");
- fail();
- } catch (ParseException e) {
- assertEquals(expectedColumn, e.getColumnNumber());
- }
- getConfiguration().clearTemplateCache();
-
- try {
- new Template(null, templateSource, getConfiguration());
- fail();
- } catch (ParseException e) {
- assertEquals(expectedColumn, e.getColumnNumber());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
deleted file mode 100644
index fa21c76..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-
-import junit.framework.TestCase;
-
-/**
- * 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 {
- // 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++) {
- Configuration cfg = new TestConfigurationBuilder()
- .tagSyntax(angOrSqu == 0
- ? ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX
- : ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
- .build();
-
- 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(cfg,
- 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;
-
- test(cfg,
- wrongx_xxx + dir_xxx,
- null);
-
- test(cfg,
- dir_xxx + wrongx_xxx,
- null);
-
- test(cfg,
- hdr_xxx + wrongx_xxx,
- null);
-
- test(cfg,
- cust_xxx + wrongx_xxx + dir_xxx,
- null);
- } // for wrongc
- } // for squ
-
- {
- Configuration cfg = new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
- .build();
- 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;
-
- test(cfg,
- wrong_xxx + dir_xxx,
- null);
- } // for perm
- }
-
- {
- Configuration cfg = new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
- .build();
- // 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(cfg,
- cust_xxx + wrong_yyy + dir_xxx,
- CUST_OUT + wrong_yyy + dir_out);
-
- test(cfg,
- hdr_xxx + wrong_yyy + dir_xxx,
- wrong_yyy + dir_out);
-
- test(cfg,
- cust_xxx + wrong_yyy + dir_yyy,
- CUST_OUT + wrong_yyy + dir_yyy);
-
- test(cfg,
- hdr_xxx + wrong_yyy + dir_yyy,
- wrong_yyy + dir_yyy);
-
- test(cfg,
- 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 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 invoke 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());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
deleted file mode 100644
index 5b1cda9..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-
-import org.apache.commons.collections.ListUtils;
-import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
-import org.apache.freemarker.core.arithmetic.impl.ConservativeArithmeticEngine;
-import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-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.impl.StringTemplateLoader;
-import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.LocAndTZSensitiveTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.LocaleSensitiveTemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.test.MonitoredTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class TemplateConfigurationTest {
-
- private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
-
- private final class DummyArithmeticEngine extends ArithmeticEngine {
-
- @Override
- public int compareNumbers(Number first, Number second) throws TemplateException {
- return 0;
- }
-
- @Override
- public Number add(Number first, Number second) throws TemplateException {
- return 22;
- }
-
- @Override
- public Number subtract(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number multiply(Number first, Number second) throws TemplateException {
- return 33;
- }
-
- @Override
- public Number divide(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number modulus(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number toNumber(String s) {
- return 11;
- }
- }
-
- private static final Configuration DEFAULT_CFG;
- static {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
- StringTemplateLoader stl = new StringTemplateLoader();
- stl.putTemplate("t1.ftl", "<#global loaded = (loaded!) + 't1;'>In t1;");
- stl.putTemplate("t2.ftl", "<#global loaded = (loaded!) + 't2;'>In t2;");
- stl.putTemplate("t3.ftl", "<#global loaded = (loaded!) + 't3;'>In t3;");
- try {
- DEFAULT_CFG = cfgB.templateLoader(stl).build();
- } catch (ConfigurationException e) {
- throw new IllegalStateException("Faild to create default configuration", e);
- }
- }
-
- private static final TimeZone NON_DEFAULT_TZ;
- static {
- TimeZone defaultTZ = DEFAULT_CFG.getTimeZone();
- TimeZone tz = TimeZone.getTimeZone("UTC");
- if (tz.equals(defaultTZ)) {
- tz = TimeZone.getTimeZone("GMT+01");
- if (tz.equals(defaultTZ)) {
- throw new AssertionError("Couldn't chose a non-default time zone");
- }
- }
- NON_DEFAULT_TZ = tz;
- }
-
- private static final Locale NON_DEFAULT_LOCALE =
- DEFAULT_CFG.getLocale().equals(Locale.US) ? Locale.GERMAN : Locale.US;
-
- private static final Charset NON_DEFAULT_ENCODING =
- DEFAULT_CFG.getSourceEncoding().equals(StandardCharsets.UTF_8) ? StandardCharsets.UTF_16LE
- : StandardCharsets.UTF_8;
-
- private static final Map<String, Object> SETTING_ASSIGNMENTS;
-
- static {
- SETTING_ASSIGNMENTS = new HashMap<>();
-
- // "MutableProcessingConfiguration" settings:
- SETTING_ASSIGNMENTS.put("APIBuiltinEnabled", true);
- SETTING_ASSIGNMENTS.put("SQLDateAndTimeTimeZone", NON_DEFAULT_TZ);
- SETTING_ASSIGNMENTS.put("URLEscapingCharset", StandardCharsets.UTF_16);
- SETTING_ASSIGNMENTS.put("autoFlush", false);
- SETTING_ASSIGNMENTS.put("booleanFormat", "J,N");
- SETTING_ASSIGNMENTS.put("dateFormat", "yyyy-#DDD");
- SETTING_ASSIGNMENTS.put("dateTimeFormat", "yyyy-#DDD-@HH:mm");
- SETTING_ASSIGNMENTS.put("locale", NON_DEFAULT_LOCALE);
- SETTING_ASSIGNMENTS.put("logTemplateExceptions", true);
- SETTING_ASSIGNMENTS.put("newBuiltinClassResolver", TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
- SETTING_ASSIGNMENTS.put("numberFormat", "0.0000");
- SETTING_ASSIGNMENTS.put("objectWrapper",
- new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- SETTING_ASSIGNMENTS.put("outputEncoding", StandardCharsets.UTF_16);
- SETTING_ASSIGNMENTS.put("showErrorTips", false);
- SETTING_ASSIGNMENTS.put("templateExceptionHandler", TemplateExceptionHandler.IGNORE_HANDLER);
- SETTING_ASSIGNMENTS.put("timeFormat", "@HH:mm");
- SETTING_ASSIGNMENTS.put("timeZone", NON_DEFAULT_TZ);
- SETTING_ASSIGNMENTS.put("arithmeticEngine", ConservativeArithmeticEngine.INSTANCE);
- SETTING_ASSIGNMENTS.put("customNumberFormats",
- ImmutableMap.of("dummy", HexTemplateNumberFormatFactory.INSTANCE));
- SETTING_ASSIGNMENTS.put("customDateFormats",
- ImmutableMap.of("dummy", EpochMillisTemplateDateFormatFactory.INSTANCE));
- SETTING_ASSIGNMENTS.put("customAttributes", ImmutableMap.of("dummy", 123));
-
- // Parser-only settings:
- SETTING_ASSIGNMENTS.put("templateLanguage", TemplateLanguage.STATIC_TEXT);
- SETTING_ASSIGNMENTS.put("tagSyntax", ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX);
- SETTING_ASSIGNMENTS.put("namingConvention", ParsingConfiguration.LEGACY_NAMING_CONVENTION);
- SETTING_ASSIGNMENTS.put("whitespaceStripping", false);
- SETTING_ASSIGNMENTS.put("strictSyntaxMode", false);
- SETTING_ASSIGNMENTS.put("autoEscapingPolicy", ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
- SETTING_ASSIGNMENTS.put("outputFormat", HTMLOutputFormat.INSTANCE);
- SETTING_ASSIGNMENTS.put("recognizeStandardFileExtensions", false);
- SETTING_ASSIGNMENTS.put("tabSize", 1);
- SETTING_ASSIGNMENTS.put("lazyImports", Boolean.TRUE);
- SETTING_ASSIGNMENTS.put("lazyAutoImports", Boolean.FALSE);
- SETTING_ASSIGNMENTS.put("autoImports", ImmutableMap.of("a", "/lib/a.ftl"));
- SETTING_ASSIGNMENTS.put("autoIncludes", ImmutableList.of("/lib/b.ftl"));
-
- // Special settings:
- SETTING_ASSIGNMENTS.put("sourceEncoding", NON_DEFAULT_ENCODING);
- }
-
- public static String getIsSetMethodName(String readMethodName) {
- return (readMethodName.startsWith("get") ? "is" + readMethodName.substring(3)
- : readMethodName)
- + "Set";
- }
-
- public static List<PropertyDescriptor> getTemplateConfigurationSettingPropDescs(
- Class<? extends ProcessingConfiguration> confClass, boolean includeCompilerSettings)
- throws IntrospectionException {
- List<PropertyDescriptor> settingPropDescs = new ArrayList<>();
-
- BeanInfo beanInfo = Introspector.getBeanInfo(confClass);
- for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
- String name = pd.getName();
- if (pd.getWriteMethod() != null && !IGNORED_PROP_NAMES.contains(name)
- && (includeCompilerSettings
- || (CONFIGURABLE_PROP_NAMES.contains(name) || !PARSER_PROP_NAMES.contains(name)))) {
- if (pd.getReadMethod() == null) {
- throw new AssertionError("Property has no read method: " + pd);
- }
- settingPropDescs.add(pd);
- }
- }
-
- Collections.sort(settingPropDescs, new Comparator<PropertyDescriptor>() {
- @Override
- public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
- return o1.getName().compareToIgnoreCase(o2.getName());
- }
- });
-
- return settingPropDescs;
- }
-
- private static final Set<String> IGNORED_PROP_NAMES;
-
- static {
- IGNORED_PROP_NAMES = new HashSet();
- IGNORED_PROP_NAMES.add("class");
- IGNORED_PROP_NAMES.add("strictBeanModels");
- IGNORED_PROP_NAMES.add("parentConfiguration");
- IGNORED_PROP_NAMES.add("settings");
- }
-
- private static final Set<String> CONFIGURABLE_PROP_NAMES;
- static {
- CONFIGURABLE_PROP_NAMES = new HashSet<>();
- try {
- for (PropertyDescriptor propDesc : Introspector.getBeanInfo(MutableProcessingConfiguration.class).getPropertyDescriptors()) {
- String propName = propDesc.getName();
- if (!IGNORED_PROP_NAMES.contains(propName)) {
- CONFIGURABLE_PROP_NAMES.add(propName);
- }
- }
- } catch (IntrospectionException e) {
- throw new IllegalStateException("Failed to init static field", e);
- }
- }
-
- private static final Set<String> PARSER_PROP_NAMES;
- static {
- PARSER_PROP_NAMES = new HashSet<>();
- // It's an interface; can't use standard Inrospector
- for (Method m : ParsingConfiguration.class.getMethods()) {
- String propertyName;
- String name = m.getName();
- if (name.startsWith("get")) {
- propertyName = name.substring(3);
- } else if (name.startsWith("is") && !name.endsWith("Set")) {
- propertyName = name.substring(2);
- } else {
- propertyName = null;
- }
- if (propertyName != null) {
- if (!Character.isUpperCase(propertyName.charAt(1))) {
- propertyName = Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
- }
- PARSER_PROP_NAMES.add(propertyName);
- }
- }
- }
-
- private static final Object CA1 = new Object();
- private static final String CA2 = "ca2";
- private static final String CA3 = "ca3";
- private static final String CA4 = "ca4";
-
- @Test
- public void testMergeBasicFunctionality() throws Exception {
- for (PropertyDescriptor propDesc1 : getTemplateConfigurationSettingPropDescs(
- TemplateConfiguration.Builder.class, true)) {
- for (PropertyDescriptor propDesc2 : getTemplateConfigurationSettingPropDescs(
- TemplateConfiguration.Builder.class, true)) {
- TemplateConfiguration.Builder tcb1 = new TemplateConfiguration.Builder();
- TemplateConfiguration.Builder tcb2 = new TemplateConfiguration.Builder();
-
- Object value1 = SETTING_ASSIGNMENTS.get(propDesc1.getName());
- propDesc1.getWriteMethod().invoke(tcb1, value1);
- Object value2 = SETTING_ASSIGNMENTS.get(propDesc2.getName());
- propDesc2.getWriteMethod().invoke(tcb2, value2);
-
- tcb1.merge(tcb2);
- if (propDesc1.getName().equals(propDesc2.getName()) && value1 instanceof List
- && !propDesc1.getName().equals("autoIncludes")) {
- assertEquals("For " + propDesc1.getName(),
- ListUtils.union((List) value1, (List) value1), propDesc1.getReadMethod().invoke(tcb1));
- } else { // Values of the same setting merged
- assertEquals("For " + propDesc1.getName(), value1, propDesc1.getReadMethod().invoke(tcb1));
- assertEquals("For " + propDesc2.getName(), value2, propDesc2.getReadMethod().invoke(tcb1));
- }
- }
- }
- }
-
- @Test
- public void testMergeMapSettings() throws Exception {
- TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
- tc1.setCustomDateFormats(ImmutableMap.of(
- "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
- "x", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE));
- tc1.setCustomNumberFormats(ImmutableMap.of(
- "hex", HexTemplateNumberFormatFactory.INSTANCE,
- "x", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE));
- tc1.setAutoImports(ImmutableMap.of("a", "a1.ftl", "b", "b1.ftl"));
-
- TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
- tc2.setCustomDateFormats(ImmutableMap.of(
- "loc", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE,
- "x", EpochMillisDivTemplateDateFormatFactory.INSTANCE));
- tc2.setCustomNumberFormats(ImmutableMap.of(
- "loc", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE,
- "x", BaseNTemplateNumberFormatFactory.INSTANCE));
- tc2.setAutoImports(ImmutableMap.of("b", "b2.ftl", "c", "c2.ftl"));
-
- tc1.merge(tc2);
-
- Map<String, ? extends TemplateDateFormatFactory> mergedCustomDateFormats = tc1.getCustomDateFormats();
- assertEquals(EpochMillisTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("epoch"));
- assertEquals(LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("loc"));
- assertEquals(EpochMillisDivTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("x"));
-
- Map<String, ? extends TemplateNumberFormatFactory> mergedCustomNumberFormats = tc1.getCustomNumberFormats();
- assertEquals(HexTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("hex"));
- assertEquals(LocaleSensitiveTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("loc"));
- assertEquals(BaseNTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("x"));
-
- Map<String, String> mergedAutoImports = tc1.getAutoImports();
- assertEquals("a1.ftl", mergedAutoImports.get("a"));
- assertEquals("b2.ftl", mergedAutoImports.get("b"));
- assertEquals("c2.ftl", mergedAutoImports.get("c"));
-
- // Empty map merging optimization:
- tc1.merge(new TemplateConfiguration.Builder());
- assertSame(mergedCustomDateFormats, tc1.getCustomDateFormats());
- assertSame(mergedCustomNumberFormats, tc1.getCustomNumberFormats());
-
- // Empty map merging optimization:
- TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
- tc3.merge(tc1);
- assertSame(mergedCustomDateFormats, tc3.getCustomDateFormats());
- assertSame(mergedCustomNumberFormats, tc3.getCustomNumberFormats());
- }
-
- @Test
- public void testMergeListSettings() throws Exception {
- TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
- tc1.setAutoIncludes(ImmutableList.of("a.ftl", "x.ftl", "b.ftl"));
-
- TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
- tc2.setAutoIncludes(ImmutableList.of("c.ftl", "x.ftl", "d.ftl"));
-
- tc1.merge(tc2);
-
- assertEquals(ImmutableList.of("a.ftl", "b.ftl", "c.ftl", "x.ftl", "d.ftl"), tc1.getAutoIncludes());
- }
-
- @Test
- public void testMergePriority() throws Exception {
- TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
- tc1.setDateFormat("1");
- tc1.setTimeFormat("1");
- tc1.setDateTimeFormat("1");
-
- TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
- tc2.setDateFormat("2");
- tc2.setTimeFormat("2");
-
- TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
- tc3.setDateFormat("3");
-
- tc1.merge(tc2);
- tc1.merge(tc3);
-
- assertEquals("3", tc1.getDateFormat());
- assertEquals("2", tc1.getTimeFormat());
- assertEquals("1", tc1.getDateTimeFormat());
- }
-
- @Test
- public void testMergeCustomAttributes() throws Exception {
- TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
- tc1.setCustomAttribute("k1", "v1");
- tc1.setCustomAttribute("k2", "v1");
- tc1.setCustomAttribute("k3", "v1");
- tc1.setCustomAttribute(CA1, "V1");
- tc1.setCustomAttribute(CA2, "V1");
- tc1.setCustomAttribute(CA3, "V1");
-
- TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
- tc2.setCustomAttribute("k1", "v2");
- tc2.setCustomAttribute("k2", "v2");
- tc2.setCustomAttribute(CA1, "V2");
- tc2.setCustomAttribute(CA2, "V2");
-
- TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
- tc3.setCustomAttribute("k1", "v3");
- tc3.setCustomAttribute(CA1, "V3");
-
- tc1.merge(tc2);
- tc1.merge(tc3);
-
- assertEquals("v3", tc1.getCustomAttribute("k1"));
- assertEquals("v2", tc1.getCustomAttribute("k2"));
- assertEquals("v1", tc1.getCustomAttribute("k3"));
- assertEquals("V3", tc1.getCustomAttribute(CA1));
- assertEquals("V2", tc1.getCustomAttribute(CA2));
- assertEquals("V1", tc1.getCustomAttribute(CA3));
- }
-
- @Test
- public void testMergeNullCustomAttributes() throws Exception {
- TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
- tc1.setCustomAttribute("k1", "v1");
- tc1.setCustomAttribute("k2", "v1");
- tc1.setCustomAttribute(CA1, "V1");
- tc1.setCustomAttribute(CA2,"V1");
-
- assertEquals("v1", tc1.getCustomAttribute("k1"));
- assertEquals("v1", tc1.getCustomAttribute("k2"));
- assertNull("v1", tc1.getCustomAttribute("k3"));
- assertEquals("V1", tc1.getCustomAttribute(CA1));
- assertEquals("V1", tc1.getCustomAttribute(CA2));
- assertNull(tc1.getCustomAttribute(CA3));
-
- TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
- tc2.setCustomAttribute("k1", "v2");
- tc2.setCustomAttribute("k2", null);
- tc2.setCustomAttribute(CA1, "V2");
- tc2.setCustomAttribute(CA2, null);
-
- TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
- tc3.setCustomAttribute("k1", null);
- tc2.setCustomAttribute(CA1, null);
-
- tc1.merge(tc2);
- tc1.merge(tc3);
-
- assertNull(tc1.getCustomAttribute("k1"));
- assertNull(tc1.getCustomAttribute("k2"));
- assertNull(tc1.getCustomAttribute("k3"));
- assertNull(tc1.getCustomAttribute(CA1));
- assertNull(tc1.getCustomAttribute(CA2));
- assertNull(tc1.getCustomAttribute(CA3));
-
- TemplateConfiguration.Builder tc4 = new TemplateConfiguration.Builder();
- tc4.setCustomAttribute("k1", "v4");
- tc4.setCustomAttribute(CA1, "V4");
-
- tc1.merge(tc4);
-
- assertEquals("v4", tc1.getCustomAttribute("k1"));
- assertNull(tc1.getCustomAttribute("k2"));
- assertNull(tc1.getCustomAttribute("k3"));
- assertEquals("V4", tc1.getCustomAttribute(CA1));
- assertNull(tc1.getCustomAttribute(CA2));
- assertNull(tc1.getCustomAttribute(CA3));
- }
-
- @Test
- public void testConfigureNonParserConfig() throws Exception {
- for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
- TemplateConfiguration.Builder.class, false)) {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
-
- Object newValue = SETTING_ASSIGNMENTS.get(pd.getName());
- pd.getWriteMethod().invoke(tcb, newValue);
-
- TemplateConfiguration tc = tcb.build();
-
- Method tReaderMethod = Template.class.getMethod(pd.getReadMethod().getName());
-
- // Without TC
- assertNotEquals("For \"" + pd.getName() + "\"",
- tReaderMethod.invoke(new Template(null, "", DEFAULT_CFG)));
- // With TC
- assertEquals("For \"" + pd.getName() + "\"", newValue,
- tReaderMethod.invoke(new Template(null, "", DEFAULT_CFG, tc)));
- }
- }
-
- @Test
- public void testConfigureCustomAttributes() throws Exception {
- Configuration cfg = new TestConfigurationBuilder()
- .customAttribute("k1", "c")
- .customAttribute("k2", "c")
- .customAttribute("k3", "c")
- .build();
-
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setCustomAttribute("k2", "tc");
- tcb.setCustomAttribute("k3", null);
- tcb.setCustomAttribute("k4", "tc");
- tcb.setCustomAttribute("k5", "tc");
- tcb.setCustomAttribute("k6", "tc");
- tcb.setCustomAttribute(CA1, "tc");
- tcb.setCustomAttribute(CA2,"tc");
- tcb.setCustomAttribute(CA3,"tc");
-
- TemplateConfiguration tc = tcb.build();
- Template t = new Template(null, "", cfg, tc);
- t.setCustomAttribute("k5", "t");
- t.setCustomAttribute("k6", null);
- t.setCustomAttribute("k7", "t");
- t.setCustomAttribute(CA2, "t");
- t.setCustomAttribute(CA3, null);
- t.setCustomAttribute(CA4, "t");
-
- assertEquals("c", t.getCustomAttribute("k1"));
- assertEquals("tc", t.getCustomAttribute("k2"));
- assertNull(t.getCustomAttribute("k3"));
- assertEquals("tc", t.getCustomAttribute("k4"));
- assertEquals("t", t.getCustomAttribute("k5"));
- assertNull(t.getCustomAttribute("k6"));
- assertEquals("t", t.getCustomAttribute("k7"));
- assertEquals("tc", t.getCustomAttribute(CA1));
- assertEquals("t", t.getCustomAttribute(CA2));
- assertNull(t.getCustomAttribute(CA3));
- assertEquals("t", t.getCustomAttribute(CA4));
- }
-
- @Test
- public void testConfigureParser() throws Exception {
- Set<String> testedProps = new HashSet<>();
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setTagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "[#if true]y[/#if]", "[#if true]y[/#if]", "y");
- testedProps.add(Configuration.ExtendableBuilder.TAG_SYNTAX_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setNamingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "<#if true>y<#elseif false>n</#if>", "y", null);
- testedProps.add(Configuration.ExtendableBuilder.NAMING_CONVENTION_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setWhitespaceStripping(false);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "<#if true>\nx\n</#if>\n", "x\n", "\nx\n\n");
- testedProps.add(Configuration.ExtendableBuilder.WHITESPACE_STRIPPING_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setArithmeticEngine(new DummyArithmeticEngine());
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "${1} ${1+1}", "1 2", "11 22");
- testedProps.add(Configuration.ExtendableBuilder.ARITHMETIC_ENGINE_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setOutputFormat(XMLOutputFormat.INSTANCE);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "${.outputFormat} ${\"a'b\"}",
- UndefinedOutputFormat.INSTANCE.getName() + " a'b",
- XMLOutputFormat.INSTANCE.getName() + " a'b");
- testedProps.add(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setOutputFormat(XMLOutputFormat.INSTANCE);
- tcb.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "${'a&b'}", "a&b", "a&b");
- testedProps.add(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- /* Can't test this now, as the only valid value is 3.0.0. [FM3.0.1]
- TemplateConfiguration tc = tcb.build();
- tc.setParentConfiguration(new Configuration(new Version(2, 3, 0)));
- assertOutputWithoutAndWithTC(tc, "<#foo>", null, "<#foo>");
- */
- testedProps.add(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setRecognizeStandardFileExtensions(false);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "adhoc.ftlh", "${.outputFormat}",
- HTMLOutputFormat.INSTANCE.getName(), UndefinedOutputFormat.INSTANCE.getName());
- testedProps.add(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE);
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setLogTemplateExceptions(false);
- tcb.setTabSize(3);
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc,
- "<#attempt><@'\\t$\\{1+}'?interpret/><#recover>"
- + "${.error?replace('(?s).*?column ([0-9]+).*', '$1', 'r')}"
- + "</#attempt>",
- "13", "8");
- testedProps.add(Configuration.ExtendableBuilder.TAB_SIZE_KEY_CAMEL_CASE);
- }
-
- {
- // As the TemplateLanguage-based parser selection happens in the TemplateResolver, we can't use
- // assertOutput here, as that hard-coded to create an FTL Template.
-
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setTemplateLanguage(TemplateLanguage.STATIC_TEXT);
-
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
- cfgB.setTemplateConfigurations(
- new ConditionalTemplateConfigurationFactory(new FileExtensionMatcher("txt"), tcb.build()));
-
- StringTemplateLoader templateLoader = new StringTemplateLoader();
- templateLoader.putTemplate("adhoc.ftl", "${1+1}");
- templateLoader.putTemplate("adhoc.txt", "${1+1}");
- cfgB.setTemplateLoader(templateLoader);
-
- Configuration cfg = cfgB.build();
-
- {
- StringWriter out = new StringWriter();
- cfg.getTemplate("adhoc.ftl").process(null, out);
- assertEquals("2", out.toString());
- }
- {
- StringWriter out = new StringWriter();
- cfg.getTemplate("adhoc.txt").process(null, out);
- assertEquals("${1+1}", out.toString());
- }
-
- testedProps.add(Configuration.ExtendableBuilder.TEMPLATE_LANGUAGE_KEY_CAMEL_CASE);
- }
-
- {
- // As the TemplateLanguage-based parser selection happens in the TemplateResolver, we can't use
- // assertOutput here, as that hard-coded to create an FTL Template.
-
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setSourceEncoding(StandardCharsets.ISO_8859_1);
-
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
- cfgB.setSourceEncoding(StandardCharsets.UTF_8);
- cfgB.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("latin1.ftl"), tcb.build()));
-
- MonitoredTemplateLoader templateLoader = new MonitoredTemplateLoader();
- templateLoader.putBinaryTemplate("utf8.ftl", "próba", StandardCharsets.UTF_8, 1);
- templateLoader.putBinaryTemplate("latin1.ftl", "próba", StandardCharsets.ISO_8859_1, 1);
- cfgB.setTemplateLoader(templateLoader);
-
- Configuration cfg = cfgB.build();
-
- {
- StringWriter out = new StringWriter();
- cfg.getTemplate("utf8.ftl").process(null, out);
- assertEquals("próba", out.toString());
- }
- {
- StringWriter out = new StringWriter();
- cfg.getTemplate("latin1.ftl").process(null, out);
- assertEquals("próba", out.toString());
- }
-
- testedProps.add(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_CAMEL_CASE);
- }
-
- if (!PARSER_PROP_NAMES.equals(testedProps)) {
- Set<String> diff = new HashSet<>(PARSER_PROP_NAMES);
- diff.removeAll(testedProps);
- fail("Some settings weren't checked: " + diff);
- }
- }
-
- @Test
- public void testArithmeticEngine() throws TemplateException, IOException {
- TemplateConfiguration tc = new TemplateConfiguration.Builder()
- .arithmeticEngine(new DummyArithmeticEngine())
- .build();
- assertOutputWithoutAndWithTC(tc,
- "<#setting locale='en_US'>${1} ${1+1} ${1*3} <#assign x = 1>${x + x} ${x * 3}",
- "1 2 3 2 3", "11 22 33 22 33");
-
- // Does affect template.arithmeticEngine (unlike in FM2)
- Template t = new Template(null, null, new StringReader(""), DEFAULT_CFG, tc, null);
- assertEquals(tc.getArithmeticEngine(), t.getArithmeticEngine());
- }
-
- @Test
- public void testAutoImport() throws TemplateException, IOException {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setAutoImports(ImmutableMap.of("t1", "t1.ftl", "t2", "t2.ftl"));
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "<#import 't3.ftl' as t3>${loaded}", "t3;", "t1;t2;t3;");
- }
-
- @Test
- public void testAutoIncludes() throws TemplateException, IOException {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setAutoIncludes(ImmutableList.of("t1.ftl", "t2.ftl"));
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc, "<#include 't3.ftl'>", "In t3;", "In t1;In t2;In t3;");
- }
-
- @Test
- public void testStringInterpolate() throws TemplateException, IOException {
- TemplateConfiguration tc = new TemplateConfiguration.Builder()
- .arithmeticEngine(new DummyArithmeticEngine())
- .build();
- assertOutputWithoutAndWithTC(tc,
- "<#setting locale='en_US'>${'${1} ${1+1} ${1*3}'} <#assign x = 1>${'${x + x} ${x * 3}'}",
- "1 2 3 2 3", "11 22 33 22 33");
-
- // Does affect template.arithmeticEngine (unlike in FM2):
- Template t = new Template(null, null, new StringReader(""), DEFAULT_CFG, tc, null);
- assertEquals(tc.getArithmeticEngine(), t.getArithmeticEngine());
- }
-
- @Test
- public void testInterpret() throws TemplateException, IOException {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setArithmeticEngine(new DummyArithmeticEngine());
- {
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc,
- "<#setting locale='en_US'><#assign src = r'${1} <#assign x = 1>${x + x}'><@src?interpret />",
- "1 2", "11 22");
- }
- tcb.setWhitespaceStripping(false);
- {
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc,
- "<#if true>\nX</#if><#assign src = r'<#if true>\nY</#if>'><@src?interpret />",
- "XY", "\nX\nY");
- }
- }
-
- @Test
- public void testEval() throws TemplateException, IOException {
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setArithmeticEngine(new DummyArithmeticEngine());
- TemplateConfiguration tc = tcb.build();
- assertOutputWithoutAndWithTC(tc,
- "<#assign x = 1>${r'1 + x'?eval?c}",
- "2", "22");
- assertOutputWithoutAndWithTC(tc,
- "${r'1?c'?eval}",
- "1", "11");
- }
-
- {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- Charset outputEncoding = ISO_8859_2;
- tcb.setOutputEncoding(outputEncoding);
-
- String legacyNCFtl = "${r'.output_encoding!\"null\"'?eval}";
- String camelCaseNCFtl = "${r'.outputEncoding!\"null\"'?eval}";
-
- {
- TemplateConfiguration tc = tcb.build();
-
- // Default is re-auto-detecting in ?eval:
- assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", outputEncoding.name());
- assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", outputEncoding.name());
- }
-
- {
- // Force camelCase:
- tcb.setNamingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
-
- TemplateConfiguration tc = tcb.build();
-
- assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", null);
- assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", outputEncoding.name());
- }
-
- {
- // Force legacy:
- tcb.setNamingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
-
- TemplateConfiguration tc = tcb.build();
-
- assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", outputEncoding.name());
- assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", null);
- }
- }
- }
-
- private void assertOutputWithoutAndWithTC(
- TemplateConfiguration tc, String ftl, String expectedDefaultOutput,
- String expectedConfiguredOutput) throws TemplateException, IOException {
- assertOutputWithoutAndWithTC(tc, null, ftl, expectedDefaultOutput, expectedConfiguredOutput);
- }
-
- private void assertOutputWithoutAndWithTC(
- TemplateConfiguration tc, String templateName, String ftl, String expectedDefaultOutput,
- String expectedConfiguredOutput) throws TemplateException, IOException {
- if (templateName == null) {
- templateName = "adhoc.ftl";
- }
- assertOutput(null, templateName, ftl, expectedDefaultOutput);
- assertOutput(tc, templateName, ftl, expectedConfiguredOutput);
- }
-
- private void assertOutput(TemplateConfiguration tc, String templateName, String ftl, String
- expectedConfiguredOutput)
- throws TemplateException, IOException {
- StringWriter sw = new StringWriter();
- try {
- Template t = new Template(templateName, null, new StringReader(ftl), DEFAULT_CFG, tc, null);
- t.process(null, sw);
- if (expectedConfiguredOutput == null) {
- fail("Template should have fail.");
- }
- } catch (TemplateException|ParseException e) {
- if (expectedConfiguredOutput != null) {
- throw e;
- }
- }
- if (expectedConfiguredOutput != null) {
- assertEquals(expectedConfiguredOutput, sw.toString());
- }
- }
-
- @Test
- public void testIsSet() throws Exception {
- for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
- TemplateConfiguration.Builder.class, true)) {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- checkAllIsSetFalseExcept(tcb.build(), null);
- pd.getWriteMethod().invoke(tcb, SETTING_ASSIGNMENTS.get(pd.getName()));
- checkAllIsSetFalseExcept(tcb.build(), pd.getName());
- }
- }
-
- private void checkAllIsSetFalseExcept(TemplateConfiguration tc, String setSetting)
- throws SecurityException, IntrospectionException,
- IllegalArgumentException, IllegalAccessException, InvocationTargetException {
- for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(TemplateConfiguration.class, true)) {
- String isSetMethodName = getIsSetMethodName(pd.getReadMethod().getName());
- Method isSetMethod;
- try {
- isSetMethod = tc.getClass().getMethod(isSetMethodName);
- } catch (NoSuchMethodException e) {
- fail("Missing " + isSetMethodName + " method for \"" + pd.getName() + "\".");
- return;
- }
- if (pd.getName().equals(setSetting)) {
- assertTrue(isSetMethod + " should return true", (Boolean) (isSetMethod.invoke(tc)));
- } else {
- assertFalse(isSetMethod + " should return false", (Boolean) (isSetMethod.invoke(tc)));
- }
- }
- }
-
- /**
- * Test case self-check.
- */
- @Test
- public void checkTestAssignments() throws Exception {
- for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
- TemplateConfiguration.Builder.class, true)) {
- String propName = pd.getName();
- if (!SETTING_ASSIGNMENTS.containsKey(propName)) {
- fail("Test case doesn't cover all settings in SETTING_ASSIGNMENTS. Missing: " + propName);
- }
- Method readMethod = pd.getReadMethod();
- String cfgMethodName = readMethod.getName();
- Method cfgMethod = DEFAULT_CFG.getClass().getMethod(cfgMethodName, readMethod.getParameterTypes());
- Object defaultSettingValue = cfgMethod.invoke(DEFAULT_CFG);
- Object assignedValue = SETTING_ASSIGNMENTS.get(propName);
- assertNotEquals("SETTING_ASSIGNMENTS must contain a non-default value for " + propName,
- assignedValue, defaultSettingValue);
-
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- try {
- pd.getWriteMethod().invoke(tcb, assignedValue);
- } catch (Exception e) {
- throw new IllegalStateException("For setting \"" + propName + "\" and assigned value of type "
- + (assignedValue != null ? assignedValue.getClass().getName() : "Null"),
- e);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
deleted file mode 100644
index 4cd50eb..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-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.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class TemplateConfigurationWithDefaultTemplateResolverTest {
-
- private static final String TEXT_WITH_ACCENTS = "pr\u00F3ba";
-
- private static final Object CUST_ATT_1 = new Object();
- private static final Object CUST_ATT_2 = new Object();
-
- private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
-
- @Test
- public void testEncoding() throws Exception {
- Configuration cfg = createCommonEncodingTesterConfig();
-
- {
- Template t = cfg.getTemplate("utf8.ftl");
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("utf16.ftl");
- assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
- assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("default.ftl");
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("utf8-latin2.ftl");
- assertEquals(ISO_8859_2, t.getActualSourceEncoding());
- assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("default-latin2.ftl");
- assertEquals(ISO_8859_2, t.getActualSourceEncoding());
- assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
- }
- }
-
- @Test
- public void testIncludeAndEncoding() throws Exception {
- Configuration cfg = createCommonEncodingTesterConfig();
- ByteArrayTemplateLoader tl = (ByteArrayTemplateLoader) cfg.getTemplateLoader();
- tl.putTemplate("main.ftl", (
- "<#include 'utf8.ftl'>"
- + "<#include 'utf16.ftl'>"
- + "<#include 'default.ftl'>"
- + "<#include 'utf8-latin2.ftl'>"
- ).getBytes(StandardCharsets.ISO_8859_1));
- assertEquals(
- TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS,
- getTemplateOutput(cfg.getTemplate("main.ftl")));
- }
-
- @Test
- public void testLocale() throws Exception {
- StringTemplateLoader loader = new StringTemplateLoader();
- loader.putTemplate("(de).ftl", "${.locale}");
- loader.putTemplate("default.ftl", "${.locale}");
- loader.putTemplate("(de)-fr.ftl",
- ("<#ftl locale='fr_FR'>${.locale}"));
- loader.putTemplate("default-fr.ftl",
- ("<#ftl locale='fr_FR'>${.locale}"));
-
- Configuration cfg = new TestConfigurationBuilder()
- .templateLoader(loader)
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(de)*"),
- new TemplateConfiguration.Builder()
- .locale(Locale.GERMANY)
- .build()))
- .build();
-
- {
- Template t = cfg.getTemplate("(de).ftl");
- assertEquals(Locale.GERMANY, t.getLocale());
- assertEquals("de_DE", getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("(de).ftl", Locale.ITALY);
- assertEquals(Locale.GERMANY, t.getLocale());
- assertEquals("de_DE", getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("default.ftl");
- assertEquals(Locale.US, t.getLocale());
- assertEquals("en_US", getTemplateOutput(t));
- }
- {
- Template t = cfg.getTemplate("default.ftl", Locale.ITALY);
- assertEquals(Locale.ITALY, t.getLocale());
- assertEquals("it_IT", getTemplateOutput(t));
- }
- }
-
- @Test
- public void testConfigurableSettings() throws Exception {
- String commonFTL = "${.locale} ${true?string} ${1.2}";
- StringTemplateLoader loader = new StringTemplateLoader();
- loader.putTemplate("default", commonFTL);
- loader.putTemplate("(fr)", commonFTL);
- loader.putTemplate("(yn)(00)", commonFTL);
- loader.putTemplate("(00)(fr)", commonFTL);
-
- Configuration cfg = new TestConfigurationBuilder()
- .templateConfigurations(
- new MergingTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(fr)*"),
- new TemplateConfiguration.Builder().locale(Locale.FRANCE).build()),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(yn)*"),
- new TemplateConfiguration.Builder().booleanFormat("Y,N").build()),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(00)*"),
- new TemplateConfiguration.Builder().numberFormat("0.00").build())))
- .templateLoader(loader)
- .build();
-
- assertEquals("en_US true 1.2", getTemplateOutput(cfg.getTemplate("default")));
- assertEquals("fr_FR true 1,2", getTemplateOutput(cfg.getTemplate("(fr)")));
- assertEquals("en_US Y 1.20", getTemplateOutput(cfg.getTemplate("(yn)(00)")));
- assertEquals("fr_FR true 1,20", getTemplateOutput(cfg.getTemplate("(00)(fr)")));
- }
-
- @Test
- public void testCustomAttributes() throws Exception {
- String commonFTL = "<#ftl attributes={ 'a3': 'a3temp' }>";
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("(tc1)", commonFTL);
- tl.putTemplate("(tc1)noHeader", "");
- tl.putTemplate("(tc2)", commonFTL);
- tl.putTemplate("(tc1)(tc2)", commonFTL);
-
- Configuration cfg = new TestConfigurationBuilder()
- .templateConfigurations(
- new MergingTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(tc1)*"),
- new TemplateConfiguration.Builder()
- .customAttribute("a1", "a1tc1")
- .customAttribute("a2", "a2tc1")
- .customAttribute("a3", "a3tc1")
- .customAttribute(CUST_ATT_1, "ca1tc1")
- .customAttribute(CUST_ATT_2, "ca2tc1")
- .build()),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*(tc2)*"),
- new TemplateConfiguration.Builder()
- .customAttribute("a1", "a1tc2")
- .customAttribute(CUST_ATT_1, "ca1tc2")
- .build())))
- .templateLoader(tl)
- .build();
-
- {
- Template t = cfg.getTemplate("(tc1)");
- assertEquals("a1tc1", t.getCustomAttribute("a1"));
- assertEquals("a2tc1", t.getCustomAttribute("a2"));
- assertEquals("a3temp", t.getCustomAttribute("a3"));
- assertEquals("ca1tc1", t.getCustomAttribute(CUST_ATT_1));
- assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
- }
- {
- Template t = cfg.getTemplate("(tc1)noHeader");
- assertEquals("a1tc1", t.getCustomAttribute("a1"));
- assertEquals("a2tc1", t.getCustomAttribute("a2"));
- assertEquals("a3tc1", t.getCustomAttribute("a3"));
- assertEquals("ca1tc1", t.getCustomAttribute(CUST_ATT_1));
- assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
- }
- {
- Template t = cfg.getTemplate("(tc2)");
- assertEquals("a1tc2", t.getCustomAttribute("a1"));
- assertNull(t.getCustomAttribute("a2"));
- assertEquals("a3temp", t.getCustomAttribute("a3"));
- assertEquals("ca1tc2", t.getCustomAttribute(CUST_ATT_1));
- assertNull(t.getCustomAttribute(CUST_ATT_2));
- }
- {
- Template t = cfg.getTemplate("(tc1)(tc2)");
- assertEquals("a1tc2", t.getCustomAttribute("a1"));
- assertEquals("a2tc1", t.getCustomAttribute("a2"));
- assertEquals("a3temp", t.getCustomAttribute("a3"));
- assertEquals("ca1tc2", t.getCustomAttribute(CUST_ATT_1));
- assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
- }
- }
-
- private String getTemplateOutput(Template t) throws TemplateException, IOException {
- StringWriter sw = new StringWriter();
- t.process(null, sw);
- return sw.toString();
- }
-
- private Configuration createCommonEncodingTesterConfig() throws UnsupportedEncodingException {
- ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
- tl.putTemplate("utf8.ftl", TEXT_WITH_ACCENTS.getBytes(StandardCharsets.UTF_8));
- tl.putTemplate("utf16.ftl", TEXT_WITH_ACCENTS.getBytes(StandardCharsets.UTF_16LE));
- tl.putTemplate("default.ftl", TEXT_WITH_ACCENTS.getBytes(ISO_8859_2));
- tl.putTemplate("utf8-latin2.ftl",
- ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes(ISO_8859_2));
- tl.putTemplate("default-latin2.ftl",
- ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes(ISO_8859_2));
-
- return new TestConfigurationBuilder()
- .sourceEncoding(StandardCharsets.ISO_8859_1)
- .locale(Locale.US)
- .templateLoader(tl)
- .templateConfigurations(
- new FirstMatchTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*utf8*"),
- new TemplateConfiguration.Builder()
- .sourceEncoding(StandardCharsets.UTF_8)
- .build()),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*utf16*"),
- new TemplateConfiguration.Builder()
- .sourceEncoding(StandardCharsets.UTF_16LE)
- .build())
- )
- .allowNoMatch(true))
- .build();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
deleted file mode 100644
index 97c43ad..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-public class TemplateConstructorsTest {
-
- private static final String CONTENT = "From a reader...";
- private static final String CONTENT_FORCE_UTF8 = "<#ftl encoding='utf-8'>From a reader...";
-
- @Test
- public void test() throws IOException {
- final Configuration cfg = new TestConfigurationBuilder().sourceEncoding(StandardCharsets.ISO_8859_1).build();
-
- final String name = "foo/bar.ftl";
- final String sourceName = "foo/bar_de.ftl";
- final Charset sourceEncoding = StandardCharsets.UTF_16LE;
- {
- Template t = new Template(name, createReader(), cfg);
- assertEquals(name, t.getLookupName());
- assertNull(t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertNull(t.getActualSourceEncoding());
- }
- {
- Template t = new Template(name, CONTENT, cfg);
- assertEquals(name, t.getLookupName());
- assertNull(t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertNull(t.getActualSourceEncoding());
- }
- {
- Template t = new Template(name, CONTENT_FORCE_UTF8, cfg);
- assertEquals(name, t.getLookupName());
- assertNull(t.getSourceName());
- // assertEquals(CONTENT_FORCE_UTF8, t.toString()); // FIXME the #ftl header is missing from the dump, why?
- assertNull(t.getActualSourceEncoding()); // Because it was created from a String
- }
- {
- Template t = new Template(name, createReader(), cfg, sourceEncoding);
- assertEquals(name, t.getLookupName());
- assertNull(t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
- }
- {
- Template t = new Template(name, sourceName, createReader(), cfg);
- assertEquals(name, t.getLookupName());
- assertEquals(sourceName, t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertNull(t.getActualSourceEncoding());
- }
- {
- Template t = new Template(name, sourceName, createReader(), cfg, sourceEncoding);
- assertEquals(name, t.getLookupName());
- assertEquals(sourceName, t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
- }
- {
- Template t = Template.createPlainTextTemplate(name, CONTENT, cfg);
- assertEquals(name, t.getLookupName());
- assertNull(t.getSourceName());
- assertEquals(CONTENT, t.toString());
- assertNull(t.getActualSourceEncoding());
- }
- {
- try {
- new Template(name, sourceName, createReaderForceUTF8(), cfg, sourceEncoding);
- fail();
- } catch (WrongTemplateCharsetException e) {
- assertThat(e.getMessage(), containsString(StandardCharsets.UTF_8.name()));
- assertThat(e.getMessage(), containsString(sourceEncoding.name()));
- }
- }
- }
-
- private Reader createReader() {
- return new StringReader(CONTENT);
- }
-
- private Reader createReaderForceUTF8() {
- return new StringReader(CONTENT_FORCE_UTF8);
- }
-
-}
[20/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
deleted file mode 100644
index ff5897f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-/**
- * Test template names returned by special variables and relative path resolution in {@code ?interpret}-ed and
- * {@code ?eval}-ed parts.
- */
-public class InterpretAndEvalTemplateNameTest extends TemplateTest {
-
- @Test
- public void testInterpret() throws IOException, TemplateException {
- for (String getTemplateNames : new String[] {
- "c=${.current_template_name}, m=${.main_template_name}",
- "c=${\".current_template_name\"?eval}, m=${\".main_template_name\"?eval}"
- }) {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate(
- "main.ftl",
- getTemplateNames + " "
- + "{<#include 'sub/t.ftl'>}");
- tl.putTemplate(
- "sub/t.ftl",
- getTemplateNames + " "
- + "i{<@r'" + getTemplateNames + " {<#include \"a.ftl\">'?interpret />}} "
- + "i{<@[r'" + getTemplateNames + " {<#include \"a.ftl\">','named_interpreted']?interpret />}}");
- tl.putTemplate("sub/a.ftl", "In sub/a.ftl, " + getTemplateNames);
- tl.putTemplate("a.ftl", "In a.ftl");
-
- setConfiguration(new TestConfigurationBuilder().templateLoader(tl).build());
-
- assertOutputForNamed("main.ftl",
- "c=main.ftl, m=main.ftl "
- + "{"
- + "c=sub/t.ftl, m=main.ftl "
- + "i{c=sub/t.ftl->anonymous_interpreted, m=main.ftl {In sub/a.ftl, c=sub/a.ftl, m=main.ftl}} "
- + "i{c=sub/t.ftl->named_interpreted, m=main.ftl {In sub/a.ftl, c=sub/a.ftl, m=main.ftl}}"
- + "}");
-
- assertOutputForNamed("sub/t.ftl",
- "c=sub/t.ftl, m=sub/t.ftl "
- + "i{c=sub/t.ftl->anonymous_interpreted, m=sub/t.ftl {In sub/a.ftl, c=sub/a.ftl, m=sub/t.ftl}} "
- + "i{c=sub/t.ftl->named_interpreted, m=sub/t.ftl {In sub/a.ftl, c=sub/a.ftl, m=sub/t.ftl}}");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
deleted file mode 100644
index 2d061d7..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-/**
- * The {@code interpret} built-in must not consider the settings or established auto-detected syntax of the surrounding
- * template. It can only depend on the {@link Configuration}.
- */
-public class InterpretSettingInheritanceTest extends TemplateTest {
-
- private static final String FTL_A_S_A = "<#ftl><@'[#if true]s[/#if]<#if true>a</#if>'?interpret />";
- private static final String FTL_A_A_S = "<#ftl><@'<#if true>a</#if>[#if true]s[/#if]'?interpret />";
- private static final String FTL_S_S_A = "[#ftl][@'[#if true]s[/#if]<#if true>a</#if>'?interpret /]";
- private static final String FTL_S_A_S = "[#ftl][@'<#if true>a</#if>[#if true]s[/#if]'?interpret /]";
- private static final String OUT_S_A_WHEN_SYNTAX_IS_S = "s<#if true>a</#if>";
- private static final String OUT_S_A_WHEN_SYNTAX_IS_A = "[#if true]s[/#if]a";
- private static final String OUT_A_S_WHEN_SYNTAX_IS_A = "a[#if true]s[/#if]";
- private static final String OUT_A_S_WHEN_SYNTAX_IS_S = "<#if true>a</#if>s";
-
- @Test
- public void tagSyntaxTest() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX)
- .build());
- assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
- assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_A);
- assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
- assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_A);
-
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
- .build());
- assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_S);
- assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
- assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_S);
- assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
-
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
- .build());
- assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
- assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
- assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
- assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
- assertOutput("<@'[#ftl]x'?interpret />[#if true]y[/#if]", "x[#if true]y[/#if]");
- }
-
- @Test
- public void whitespaceStrippingTest() throws IOException, TemplateException {
- Configuration cfg = getConfiguration();
-
- setConfiguration(new TestConfigurationBuilder()
- .whitespaceStripping(true)
- .build());
- assertOutput("<#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "XY");
- assertOutput("<#ftl stripWhitespace=false><#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "\nXY");
- assertOutput("<#assign x = 1>\nX<@'<#ftl stripWhitespace=false><#assign x = 1>\\nY'?interpret />", "X\nY");
-
- setConfiguration(new TestConfigurationBuilder()
- .whitespaceStripping(false)
- .build());
- assertOutput("<#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "\nX\nY");
- assertOutput("<#ftl stripWhitespace=true><#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "X\nY");
- assertOutput("<#assign x = 1>\nX<@'<#ftl stripWhitespace=true><#assign x = 1>\\nY'?interpret />", "\nXY");
- }
-
- @Test
- public void evalTest() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX)
- .build());
- assertOutput("<@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval />", OUT_S_A_WHEN_SYNTAX_IS_A);
- assertOutput("[#ftl][@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval /]", OUT_S_A_WHEN_SYNTAX_IS_A);
-
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
- .build());
- assertOutput("[@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval /]", OUT_S_A_WHEN_SYNTAX_IS_S);
- assertOutput("<#ftl><@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval />", OUT_S_A_WHEN_SYNTAX_IS_S);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
deleted file mode 100644
index 08fcee2..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class IteratorIssuesTest extends TemplateTest {
-
- private static final DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- private static final String FTL_HAS_CONTENT_AND_LIST
- = "<#if it?hasContent><#list it as i>${i}</#list><#else>empty</#if>";
- private static final String OUT_HAS_CONTENT_AND_LIST_ABC = "abc";
- private static final String OUT_HAS_CONTENT_AND_LIST_EMPTY = "empty";
-
- private static final String FTL_LIST_AND_HAS_CONTENT
- = "<#list it as i>${i}${it?hasContent?then('+', '-')}</#list>";
- private static final String OUT_LIST_AND_HAS_CONTENT_BW_GOOD = "a+b+c-";
-
- @Test
- public void testHasContentAndList() throws Exception {
- addToDataModel("it", OW.wrap(getAbcIt()));
- assertOutput(FTL_HAS_CONTENT_AND_LIST, OUT_HAS_CONTENT_AND_LIST_ABC);
-
- addToDataModel("it", OW.wrap(getEmptyIt()));
- assertOutput(FTL_HAS_CONTENT_AND_LIST, OUT_HAS_CONTENT_AND_LIST_EMPTY);
- }
-
- @Test
- public void testListAndHasContent() throws Exception {
- addToDataModel("it", OW.wrap(getAbcIt()));
- assertErrorContains(FTL_LIST_AND_HAS_CONTENT, "can be listed only once");
- }
-
- private Iterator getAbcIt() {
- return Arrays.asList(new String[] { "a", "b", "c" }).iterator();
- }
-
- private Iterator getEmptyIt() {
- return Arrays.asList(new String[] { }).iterator();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
deleted file mode 100644
index 0fa3f79..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Reader;
-
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * JavaCC suppresses exceptions thrown by the Reader, silently treating them as EOF. To be precise, JavaCC 3.2 only does
- * that with {@link IOException}-s, while JavaCC 6 does that for all {@link Exception}-s. This tests FreeMarker's
- * workaround for this problem.
- */
-public class JavaCCExceptionAsEOFFixTest {
-
- public static class FailingReader extends Reader {
-
- private static final String CONTENT = "abc";
-
- private final Throwable exceptionToThrow;
- private int readSoFar;
-
- protected FailingReader(Throwable exceptionToThrow) {
- this.exceptionToThrow = exceptionToThrow;
- }
-
- @Override
- public int read() throws IOException {
- if (readSoFar == CONTENT.length()) {
- if (exceptionToThrow != null) {
- throwException();
- } else {
- return -1;
- }
- }
- return CONTENT.charAt(readSoFar++);
- }
-
- private void throwException() throws IOException {
- if (exceptionToThrow instanceof IOException) {
- throw (IOException) exceptionToThrow;
- }
- if (exceptionToThrow instanceof RuntimeException) {
- throw (RuntimeException) exceptionToThrow;
- }
- if (exceptionToThrow instanceof Error) {
- throw (Error) exceptionToThrow;
- }
- Assert.fail();
- }
-
- @Override
- public void close() throws IOException {
- // nop
- }
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- for (int i = 0; i < len; i++) {
- int c = read();
- if (c == -1) return i == 0 ? -1 : i;
- cbuf[off + i] = (char) c;
- }
- return len;
- }
-
- }
-
- @Test
- public void testIOException() throws IOException {
- try {
- new Template(null, new FailingReader(new IOException("test")), new TestConfigurationBuilder().build());
- fail();
- } catch (IOException e) {
- assertEquals("test", e.getMessage());
- }
- }
-
- @Test
- public void testRuntimeException() throws IOException {
- try {
- new Template(null, new FailingReader(new NullPointerException("test")), new TestConfigurationBuilder().build());
- fail();
- } catch (NullPointerException e) {
- assertEquals("test", e.getMessage());
- }
- }
-
- @Test
- public void testError() throws IOException {
- try {
- new Template(null, new FailingReader(new OutOfMemoryError("test")), new TestConfigurationBuilder().build());
- fail();
- } catch (OutOfMemoryError e) {
- assertEquals("test", e.getMessage());
- }
- }
-
- @Test
- public void testNoException() throws IOException {
- Template t = new Template(null, new FailingReader(null), new TestConfigurationBuilder().build());
- assertEquals("abc", t.toString());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ListErrorsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
deleted file mode 100644
index 05bac4f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.templatesuite.models.Listables;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-public class ListErrorsTest extends TemplateTest {
-
- @Test
- public void testValid() throws IOException, TemplateException {
- assertOutput("<#list 1..2 as x><#list 3..4>${x}:<#items as x>${x}</#items></#list>;</#list>", "1:34;2:34;");
- assertOutput("<#list [] as x>${x}<#else><#list 1..2 as x>${x}<#sep>, </#list></#list>", "1, 2");
- assertOutput("<#macro m>[<#nested 3>]</#macro>"
- + "<#list 1..2 as x>"
- + "${x}@${x?index}"
- + "<@m ; x>"
- + "${x},"
- + "<#list 4..4 as x>${x}@${x?index}</#list>"
- + "</@>"
- + "${x}@${x?index}; "
- + "</#list>",
- "1@0[3,4@0]1@0; 2@1[3,4@0]2@1; ");
- }
-
- @Test
- public void testInvalidItemsParseTime() throws IOException, TemplateException {
- assertErrorContains("<#items as x>${x}</#items>",
- "#items", "must be inside", "#list");
- assertErrorContains("<#list xs><#macro m><#items as x></#items></#macro></#list>",
- "#items", "must be inside", "#list");
- assertErrorContains("<#list xs as x><#items as x>${x}</#items></#list>",
- "#list", "must not have", "#items", "as loopVar");
- assertErrorContains("<#list xs><#list xs as x><#items as x>${x}</#items></#list></#list>",
- "#list", "must not have", "#items", "as loopVar");
- assertErrorContains("<#list xs></#list>",
- "#list", "must have", "#items", "as loopVar");
- }
-
- @Test
- public void testInvalidSepParseTime() throws IOException, TemplateException {
- assertErrorContains("<#sep>, </#sep>",
- "#sep", "must be inside", "#list");
- assertErrorContains("<#sep>, ",
- "#sep", "must be inside", "#list");
- assertErrorContains("<#list xs as x><#else><#sep>, </#list>",
- "#sep", "must be inside", "#list");
- assertErrorContains("<#list xs as x><#macro m><#sep>, </#macro></#list>",
- "#sep", "must be inside", "#list");
- }
-
- @Test
- public void testInvalidItemsRuntime() throws IOException, TemplateException {
- assertErrorContains("<#list 1..1><#items as x></#items><#items as x></#items></#list>",
- "#items", "already entered earlier");
- assertErrorContains("<#list 1..1><#items as x><#items as y>${x}/${y}</#items></#items></#list>",
- "#items", "Can't nest #items into each other");
- }
-
- @Test
- public void testInvalidLoopVarBuiltinLHO() {
- assertErrorContains("<#list foos>${foo?index}</#list>",
- "?index", "foo", "no loop variable");
- assertErrorContains("<#list foos as foo></#list>${foo?index}",
- "?index", "foo" , "no loop variable");
- assertErrorContains("<#list foos as foo><#macro m>${foo?index}</#macro></#list>",
- "?index", "foo" , "no loop variable");
- assertErrorContains("<#list foos as foo><#function f>${foo?index}</#function></#list>",
- "?index", "foo" , "no loop variable");
- assertErrorContains("<#list xs as x>${foo?index}</#list>",
- "?index", "foo" , "no loop variable");
- assertErrorContains("<#list foos as foo><@m; foo>${foo?index}</@></#list>",
- "?index", "foo" , "user defined directive");
- assertErrorContains(
- "<#list foos as foo><@m; foo><@m; foo>${foo?index}</@></@></#list>",
- "?index", "foo" , "user defined directive");
- assertErrorContains(
- "<#list foos as foo><@m; foo>"
- + "<#list foos as foo><@m; foo>${foo?index}</@></#list>"
- + "</@></#list>",
- "?index", "foo" , "user defined directive");
- }
-
- @Test
- public void testKeyValueSameName() {
- assertErrorContains("<#list {} as foo, foo></#list>",
- "key", "value", "both" , "foo");
- }
-
- @Test
- public void testCollectionVersusHash() {
- assertErrorContains("<#list {} as i></#list>",
- "as k, v");
- assertErrorContains("<#list [] as k, v></#list>",
- "only one loop variable");
- }
-
- @Test
- public void testNonEx2NonStringKey() throws IOException, TemplateException {
- addToDataModel("m", new Listables.NonEx2MapAdapter(ImmutableMap.of("k1", "v1", 2, "v2"),
- new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build()));
- assertOutput("<#list m?keys as k>${k};</#list>", "k1;2;");
- assertErrorContains("<#list m as k, v></#list>",
- "string", "number", ".TemplateHashModelEx2");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
deleted file mode 100644
index 1903e05..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.core;
-
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class MiscErrorMessagesTest extends TemplateTest {
-
- @Test
- public void stringIndexOutOfBounds() {
- assertErrorContains("${'foo'[10]}", "length", "3", "10", "String index out of");
- }
-
- @Test
- public void wrongTemplateNameFormat() {
- setConfiguration(new TestConfigurationBuilder().templateNameFormat(DefaultTemplateNameFormat.INSTANCE).build());
-
- assertErrorContains("<#include 'foo:/bar:baaz'>", "Malformed template name", "':'");
- assertErrorContains("<#include '../baaz'>", "Malformed template name", "root");
- assertErrorContains("<#include '\u0000'>", "Malformed template name", "\\u0000");
- }
-
- @Test
- public void numericalKeyHint() {
- assertErrorContains("${{}[10]}", "[]", "?api");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
deleted file mode 100644
index 5fcee97..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.List;
-
-import org.apache.freemarker.core.Environment.Namespace;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.core.util._NullWriter;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-/**
- * These are things that users shouldn't do, but we shouldn't break backward compatibility without knowing about it.
- */
-public class MistakenlyPublicImportAPIsTest {
-
- @Test
- public void testImportCopying() throws IOException, TemplateException {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("imp1", "<#macro m>1</#macro>");
- tl.putTemplate("imp2", "<#assign x = 2><#macro m>${x}</#macro>");
-
- Configuration cfg = new TestConfigurationBuilder().templateLoader(tl).build();
-
- Template t1 = new Template(null, "<#import 'imp1' as i1><#import 'imp2' as i2>", cfg);
- List<ASTDirImport> imports = t1.getImports();
- assertEquals(2, imports.size());
-
- {
- Template t2 = new Template(null, "<@i1.m/><@i2.m/>", cfg);
- for (ASTDirImport libLoad : imports) {
- t2.addImport(libLoad);
- }
-
- try {
- t2.process(null, _NullWriter.INSTANCE);
- fail();
- } catch (InvalidReferenceException e) {
- // Apparenly, it has never worked like this...
- assertEquals("i1", e.getBlamedExpressionString());
- }
- }
-
- // It works this way, though it has nothing to do with the problematic API-s:
- Environment env = t1.createProcessingEnvironment(null, _NullWriter.INSTANCE);
- env.process();
- TemplateModel i1 = env.getVariable("i1");
- assertThat(i1, instanceOf(Namespace.class));
- TemplateModel i2 = env.getVariable("i2");
- assertThat(i2, instanceOf(Namespace.class));
-
- {
- Template t2 = new Template(null, "<@i1.m/>", cfg);
-
- StringWriter sw = new StringWriter();
- env = t2.createProcessingEnvironment(null, sw);
- env.setVariable("i1", i1);
-
- env.process();
- assertEquals("1", sw.toString());
- }
-
- {
- Template t2 = new Template(null, "<@i2.m/>", cfg);
-
- StringWriter sw = new StringWriter();
- env = t2.createProcessingEnvironment(null, sw);
- env.setVariable("i2", i2);
-
- try {
- env.process();
- assertEquals("2", sw.toString());
- } catch (NullPointerException e) {
- // Expected on 2.3.x, because it won't find the namespace for the macro
- // [2.4] Fix this "bug"
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
deleted file mode 100644
index 9c87e61..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util._NullWriter;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-/**
- * These are things that users shouldn't do, but we shouldn't break backward compatibility without knowing about it.
- */
-public class MistakenlyPublicMacroAPIsTest {
-
- private final Configuration cfg = new TestConfigurationBuilder().build();
-
- /**
- * Getting the macros from one template, and adding them to another.
- */
- @Test
- public void testMacroCopyingExploit() throws IOException, TemplateException {
- Template tMacros = new Template(null, "<#macro m1>1</#macro><#macro m2>2</#macro>", cfg);
- Map<String, ASTDirMacro> macros = tMacros.getMacros();
-
- Template t = new Template(null,
- "<@m1/><@m2/><@m3/>"
- + "<#macro m1>1b</#macro><#macro m3>3b</#macro> "
- + "<@m1/><@m2/><@m3/>", cfg);
- t.addMacro(macros.get("m1"));
- t.addMacro(macros.get("m2"));
-
- assertEquals("123b 1b23b", getTemplateOutput(t));
- }
-
- @Test
- public void testMacroCopyingExploitAndNamespaces() throws IOException, TemplateException {
- Template tMacros = new Template(null, "<#assign x = 0><#macro m1>${x}</#macro>", cfg);
- Template t = new Template(null, "<#assign x = 1><@m1/>", cfg);
- t.addMacro((ASTDirMacro) tMacros.getMacros().get("m1"));
-
- assertEquals("1", getTemplateOutput(t));
- }
-
- @Test
- public void testMacroCopyingFromFTLVariable() throws IOException, TemplateException {
- Template tMacros = new Template(null, "<#assign x = 0><#macro m1>${x}</#macro>", cfg);
- Environment env = tMacros.createProcessingEnvironment(null, _NullWriter.INSTANCE);
- env.process();
- TemplateModel m1 = env.getVariable("m1");
- assertThat(m1, instanceOf(ASTDirMacro.class));
-
- Template t = new Template(null, "<#assign x = 1><@m1/>", cfg);
- t.addMacro((ASTDirMacro) m1);
-
- assertEquals("1", getTemplateOutput(t));
- }
-
- private String getTemplateOutput(Template t) throws TemplateException, IOException {
- StringWriter sw = new StringWriter();
- t.process(null, sw);
- return sw.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
deleted file mode 100644
index d865deb..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.apache.freemarker.test.util.EntirelyCustomObjectWrapper;
-import org.junit.Test;
-
-public class NewBiObjectWrapperRestrictionTest extends TemplateTest {
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return new TestConfigurationBuilder().objectWrapper(new EntirelyCustomObjectWrapper()).build();
- }
-
- @Test
- public void testPositive() throws IOException, TemplateException {
- assertOutput(
- "${'org.apache.freemarker.test.templatesuite.models.NewTestModel'?new()}",
- "default constructor");
- }
-
- @Test
- public void testNegative() {
- assertErrorContains(
- "${'org.apache.freemarker.test.templatesuite.models.NewTestModel'?new('s')}",
- "only supports 0 argument");
- }
-
-}
[11/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
deleted file mode 100644
index a7259d8..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateConfigurationFactoryTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.freemarker.core.TemplateConfiguration;
-import org.junit.Test;
-
-public class TemplateConfigurationFactoryTest {
-
- @Test
- public void testCondition1() throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration tc = newTemplateConfiguration(1);
-
- TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc);
-
- assertNotApplicable(tcf, "x.ftl");
- assertApplicable(tcf, "x.ftlx", tc);
- }
-
- @Test
- public void testCondition2() throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration tc = newTemplateConfiguration(1);
-
- TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*.ftlx"),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("x.*"), tc));
-
- assertNotApplicable(tcf, "x.ftl");
- assertNotApplicable(tcf, "y.ftlx");
- assertApplicable(tcf, "x.ftlx", tc);
- }
-
- @Test
- public void testMerging() throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration tc1 = newTemplateConfiguration(1);
- TemplateConfiguration tc2 = newTemplateConfiguration(2);
- TemplateConfiguration tc3 = newTemplateConfiguration(3);
-
- TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3));
-
- assertNotApplicable(tcf, "x.ftl");
- assertApplicable(tcf, "x.ftlx", tc1);
- assertApplicable(tcf, "a.ftl", tc2);
- assertApplicable(tcf, "b.ftl", tc3);
- assertApplicable(tcf, "a.ftlx", tc1, tc2);
- assertApplicable(tcf, "b.ftlx", tc1, tc3);
- assertApplicable(tcf, "ab.ftl", tc2, tc3);
- assertApplicable(tcf, "ab.ftlx", tc1, tc2, tc3);
-
- assertNotApplicable(new MergingTemplateConfigurationFactory(), "x.ftl");
- }
-
- @Test
- public void testFirstMatch() throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration tc1 = newTemplateConfiguration(1);
- TemplateConfiguration tc2 = newTemplateConfiguration(2);
- TemplateConfiguration tc3 = newTemplateConfiguration(3);
-
- FirstMatchTemplateConfigurationFactory tcf = new FirstMatchTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3));
-
- try {
- assertNotApplicable(tcf, "x.ftl");
- } catch (TemplateConfigurationFactoryException e) {
- assertThat(e.getMessage(), containsString("x.ftl"));
- }
- tcf.setNoMatchErrorDetails("Test details");
- try {
- assertNotApplicable(tcf, "x.ftl");
- } catch (TemplateConfigurationFactoryException e) {
- assertThat(e.getMessage(), containsString("Test details"));
- }
-
- tcf.setAllowNoMatch(true);
-
- assertNotApplicable(tcf, "x.ftl");
- assertApplicable(tcf, "x.ftlx", tc1);
- assertApplicable(tcf, "a.ftl", tc2);
- assertApplicable(tcf, "b.ftl", tc3);
- assertApplicable(tcf, "a.ftlx", tc1);
- assertApplicable(tcf, "b.ftlx", tc1);
- assertApplicable(tcf, "ab.ftl", tc2);
- assertApplicable(tcf, "ab.ftlx", tc1);
-
- assertNotApplicable(new FirstMatchTemplateConfigurationFactory().allowNoMatch(true), "x.ftl");
- }
-
- @Test
- public void testComplex() throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration tcA = newTemplateConfiguration(1);
- TemplateConfiguration tcBSpec = newTemplateConfiguration(2);
- TemplateConfiguration tcBCommon = newTemplateConfiguration(3);
- TemplateConfiguration tcHH = newTemplateConfiguration(4);
- TemplateConfiguration tcHtml = newTemplateConfiguration(5);
- TemplateConfiguration tcXml = newTemplateConfiguration(6);
- TemplateConfiguration tcNWS = newTemplateConfiguration(7);
-
- TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory(
- new FirstMatchTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("a/**"), tcA),
- new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("b/**"),
- new MergingTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*"), tcBCommon),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.s.*"), tcBSpec))))
- .allowNoMatch(true),
- new FirstMatchTemplateConfigurationFactory(
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.hh"), tcHH),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*h"), tcHtml),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*x"), tcXml))
- .allowNoMatch(true),
- new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.nws.*"), tcNWS));
-
- assertNotApplicable(tcf, "x.ftl");
- assertApplicable(tcf, "b/x.ftl", tcBCommon);
- assertApplicable(tcf, "b/x.s.ftl", tcBCommon, tcBSpec);
- assertApplicable(tcf, "b/x.s.ftlh", tcBCommon, tcBSpec, tcHtml);
- assertApplicable(tcf, "b/x.s.nws.ftlx", tcBCommon, tcBSpec, tcXml, tcNWS);
- assertApplicable(tcf, "a/x.s.nws.ftlx", tcA, tcXml, tcNWS);
- assertApplicable(tcf, "a.hh", tcHH);
- assertApplicable(tcf, "a.nws.hh", tcHH, tcNWS);
- }
-
- @SuppressWarnings("boxing")
- private TemplateConfiguration newTemplateConfiguration(int id) {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- tcb.setCustomAttribute("id", id);
- tcb.setCustomAttribute("contains" + id, true);
- return tcb.build();
- }
-
- private void assertNotApplicable(TemplateConfigurationFactory tcf, String sourceName)
- throws IOException, TemplateConfigurationFactoryException {
- assertNull(tcf.get(sourceName, DummyTemplateLoadingSource.INSTANCE));
- }
-
- private void assertApplicable(TemplateConfigurationFactory tcf, String sourceName, TemplateConfiguration... expectedTCs)
- throws IOException, TemplateConfigurationFactoryException {
- TemplateConfiguration mergedTC = tcf.get(sourceName, DummyTemplateLoadingSource.INSTANCE);
- List<Object> mergedTCAttNames = new ArrayList<>(mergedTC.getCustomAttributes().keySet());
-
- for (TemplateConfiguration expectedTC : expectedTCs) {
- Integer tcId = (Integer) expectedTC.getCustomAttribute("id");
- if (tcId == null) {
- fail("TemplateConfiguration-s must be created with newTemplateConfiguration(id) in this test");
- }
- if (!mergedTCAttNames.contains("contains" + tcId)) {
- fail("TemplateConfiguration with ID " + tcId + " is missing from the asserted value");
- }
- }
-
- for (Object attKey: mergedTCAttNames) {
- if (!containsCustomAttr(attKey, expectedTCs)) {
- fail("The asserted TemplateConfiguration contains an unexpected custom attribute: " + attKey);
- }
- }
-
- assertEquals(expectedTCs[expectedTCs.length - 1].getCustomAttribute("id"), mergedTC.getCustomAttribute("id"));
- }
-
- private boolean containsCustomAttr(Object attKey, TemplateConfiguration... expectedTCs) {
- for (TemplateConfiguration expectedTC : expectedTCs) {
- if (expectedTC.getCustomAttribute(attKey) != null) {
- return true;
- }
- }
- return false;
- }
-
- @SuppressWarnings("serial")
- private static class DummyTemplateLoadingSource implements TemplateLoadingSource {
- private static DummyTemplateLoadingSource INSTANCE = new DummyTemplateLoadingSource();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
deleted file mode 100644
index 3a24bfc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.Locale;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateNotFoundException;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormatFM2;
-import org.apache.freemarker.test.MonitoredTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-
-
-public class TemplateNameFormatTest {
-
- @Test
- public void testToRootBasedName() throws MalformedTemplateNameException {
- // Path that are treated the same both in 2.3 and 2.4 format:
- for (TemplateNameFormat tnf : new TemplateNameFormat[] {
- DefaultTemplateNameFormatFM2.INSTANCE, DefaultTemplateNameFormat.INSTANCE }) {
- // Relative paths:
- // - No scheme:
- assertEquals("a/b", tnf.toRootBasedName("a/", "b"));
- assertEquals("/a/b", tnf.toRootBasedName("/a/", "b"));
- assertEquals("a/b", tnf.toRootBasedName("a/f", "b"));
- assertEquals("/a/b", tnf.toRootBasedName("/a/f", "b"));
- // - Scheme:
- assertEquals("s://a/b", tnf.toRootBasedName("s://a/", "b"));
- assertEquals("s:///a/b", tnf.toRootBasedName("s:///a/", "b"));
- assertEquals("s://a/b", tnf.toRootBasedName("s://a/f", "b"));
- assertEquals("s:///a/b", tnf.toRootBasedName("s:///a/f", "b"));
- assertEquals("s://b", tnf.toRootBasedName("s://f", "b"));
- assertEquals("s:///b", tnf.toRootBasedName("s:///f", "b"));
-
- // Absolute paths:
- // - No scheme:
- assertEquals("b", tnf.toRootBasedName("a/", "/b"));
- assertEquals("b", tnf.toRootBasedName("/a/", "/b"));
- assertEquals("b", tnf.toRootBasedName("a/s:/f/", "/b"));
- // - Scheme:
- assertEquals("s://b", tnf.toRootBasedName("s://x/", "/b"));
- assertEquals("s://b", tnf.toRootBasedName("s:///x/", "/b"));
-
- // Schemed absolute paths:
- assertEquals("s://b", tnf.toRootBasedName("a/", "s://b"));
- assertEquals("s://b", tnf.toRootBasedName("i://a/", "s://b"));
- }
-
- // Scheme names in 2.4 format only:
- {
- final TemplateNameFormat tnf = DefaultTemplateNameFormat.INSTANCE;
- assertEquals("s:b", tnf.toRootBasedName("s:f", "b"));
- assertEquals("s:/b", tnf.toRootBasedName("s:/f", "b"));
- assertEquals("s:b", tnf.toRootBasedName("s:f", "/b"));
- assertEquals("s:b", tnf.toRootBasedName("s:/f", "/b"));
- assertEquals("s:f/b", tnf.toRootBasedName("s:f/", "b"));
- assertEquals("s:/f/b", tnf.toRootBasedName("s:/f/", "b"));
- assertEquals("s:b", tnf.toRootBasedName("s:f/", "/b"));
- assertEquals("s:b", tnf.toRootBasedName("s:/f/", "/b"));
- assertEquals("s:b", tnf.toRootBasedName("s:/f/", "/b"));
- assertEquals("b", tnf.toRootBasedName("a/s://f/", "/b"));
- }
-
- // Scheme names in 2.3 format only:
- {
- final TemplateNameFormat tnf = DefaultTemplateNameFormatFM2.INSTANCE;
- assertEquals("a/s://b", tnf.toRootBasedName("a/s://f/", "/b"));
- }
- }
-
- @Test
- public void testNormalizeRootBasedName() throws MalformedTemplateNameException {
- // Normalizations that are the same in legacy and modern format:
- for (TemplateNameFormat tnf : new TemplateNameFormat[] {
- DefaultTemplateNameFormatFM2.INSTANCE, DefaultTemplateNameFormat.INSTANCE }) {
- assertEquals("", tnf.normalizeRootBasedName(""));
- for (String lead : new String[] { "", "/" }) {
- assertEquals("foo", tnf.normalizeRootBasedName(lead + "foo"));
- assertEquals("foo", tnf.normalizeRootBasedName(lead + "./foo"));
- assertEquals("foo", tnf.normalizeRootBasedName(lead + "./././foo"));
- assertEquals("foo", tnf.normalizeRootBasedName(lead + "bar/../foo"));
- assertEquals("a/b/", tnf.normalizeRootBasedName("a/b/"));
- assertEquals("a/", tnf.normalizeRootBasedName("a/b/../"));
- assertEquals("a/c../..d/e*/*f", tnf.normalizeRootBasedName("a/c../..d/e*/*f"));
- assertEquals("", tnf.normalizeRootBasedName(""));
- assertEquals("foo/bar/*", tnf.normalizeRootBasedName("foo/bar/*"));
- assertEquals("schema://", tnf.normalizeRootBasedName("schema://"));
-
- assertThrowsWithBackingOutException(lead + "bar/../../x/foo", tnf);
- assertThrowsWithBackingOutException(lead + "../x", tnf);
- assertThrowsWithBackingOutException(lead + "../../../x", tnf);
- assertThrowsWithBackingOutException(lead + "../../../x", tnf);
- assertThrowsWithBackingOutException("x://../../../foo", tnf);
-
- {
- final String name = lead + "foo\u0000";
- try {
- tnf.normalizeRootBasedName(name);
- fail();
- } catch (MalformedTemplateNameException e) {
- assertEquals(name, e.getTemplateName());
-
- assertThat(e.getMalformednessDescription(), containsStringIgnoringCase("null character"));
- }
- }
- }
- }
-
- // ".." and "."
- assertEqualsOn23AndOn24("bar/foo", "foo", "bar/./../foo");
-
- // Even number of leading ".."-s bug:
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "../../foo");
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "../../../../foo");
-
- // ".." and "*"
- assertEqualsOn23AndOn24("a/b/foo", "a/*/foo", "a/b/*/../foo");
- //
- assertEqualsOn23AndOn24("a/foo", "foo", "a/b/*/../../foo");
- //
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "a/b/*/../../../foo");
- //
- assertEqualsOn23AndOn24("a/b/*/foo", "a/*/foo", "a/b/*/*/../foo");
- //
- assertEqualsOn23AndOn24("a/b/*/c/foo", "a/b/*/foo", "a/b/*/c/*/../foo");
- //
- assertEqualsOn23AndOn24("a/b/*/c/foo", "a/b/*/foo", "a/b/*/c/d/*/../../foo");
- //
- assertEqualsOn23AndOn24("a/*//b/*/c/foo", "a/*/b/*/foo", "a/*//b/*/c/d/*/../../foo");
- //
- assertEqualsOn23AndOn24("*", "", "a/../*");
- //
- assertEqualsOn23AndOn24("*/", "", "a/../*/");
-
- // ".." and "scheme"
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("x:/foo", "x://../foo");
- //
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "x://../../foo");
- //
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("x:../foo", "x:../foo");
- //
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("foo", "x:../../foo");
-
- // Tricky cases with terminating "/":
- assertEqualsOn23AndOn24("/", "", "/");
- // Terminating "/.." (produces terminating "/"):
- assertEqualsOn23AndOn24("foo/bar/..", "foo/", "foo/bar/..");
- // Terminating "/." (produces terminating "/"):
- assertEqualsOn23AndOn24("foo/bar/.", "foo/bar/", "foo/bar/.");
-
- // Lonely "."
- assertEqualsOn23AndOn24(".", "", ".");
- // Lonely ".."
- assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24("..", "..");
- // Lonely "*"
-
- // Eliminating redundant "//":
- assertEqualsOn23AndOn24("foo//bar", "foo/bar", "foo//bar");
- //
- assertEqualsOn23AndOn24("///foo//bar///baaz////wombat", "foo/bar/baaz/wombat", "////foo//bar///baaz////wombat");
- //
- assertEqualsOn23AndOn24("scheme://foo", "scheme://foo", "scheme://foo");
- //
- assertEqualsOn23AndOn24("scheme://foo//x/y", "scheme://foo/x/y", "scheme://foo//x/y");
- //
- assertEqualsOn23AndOn24("scheme:///foo", "scheme://foo", "scheme:///foo");
- //
- assertEqualsOn23AndOn24("scheme:////foo", "scheme://foo", "scheme:////foo");
-
- // Eliminating redundant "*"-s:
- assertEqualsOn23AndOn24("a/*/*/b", "a/*/b", "a/*/*/b");
- //
- assertEqualsOn23AndOn24("a/*/*/*/b", "a/*/b", "a/*/*/*/b");
- //
- assertEqualsOn23AndOn24("*/*/b", "b", "*/*/b");
- //
- assertEqualsOn23AndOn24("*/*/b", "b", "/*/*/b");
- //
- assertEqualsOn23AndOn24("b/*/*", "b/*", "b/*/*");
- //
- assertEqualsOn23AndOn24("b/*/*/*", "b/*", "b/*/*/*");
- //
- assertEqualsOn23AndOn24("*/a/*/b/*/*/c", "a/*/b/*/c", "*/a/*/b/*/*/c");
-
- // New kind of scheme handling:
-
- assertEquals("s:a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:a/b"));
- assertEquals("s:a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:/a/b"));
- assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s://a/b"));
- assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:///a/b"));
- assertEquals("s://a/b", DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName("s:////a/b"));
-
- // Illegal use a of ":":
- assertNormRBNameThrowsColonExceptionOn24("a/b:c/d");
- assertNormRBNameThrowsColonExceptionOn24("a/b:/..");
- }
-
- @Test
- public void assertBackslashNotSpecialWith23() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("foo\\bar.ftl", "");
-
- Configuration cfg = new TestConfigurationBuilder().templateLoader(tl).build();
-
- {
- final String name = "foo\\bar.ftl";
-
- Template t = cfg.getTemplate(name, Locale.US);
- assertEquals(name, t.getLookupName());
- assertEquals(name, t.getSourceName());
- assertEquals(
- ImmutableList.of(
- "foo\\bar_en_US.ftl",
- "foo\\bar_en.ftl",
- name),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- try {
- cfg.getTemplate("foo\\missing.ftl", Locale.US);
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("foo\\missing.ftl", e.getTemplateName());
- assertEquals(
- ImmutableList.of(
- "foo\\missing_en_US.ftl",
- "foo\\missing_en.ftl",
- "foo\\missing.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final String name = "foo/bar\\..\\bar.ftl";
- try {
- cfg.getTemplate(name, Locale.US);
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals(name, e.getTemplateName());
- }
- }
-
- }
-
- @Test
- public void assertBackslashNotAllowed() throws IOException {
- Configuration cfg = new TestConfigurationBuilder()
- .templateLoader(new ByteArrayTemplateLoader())
- .templateNameFormat(DefaultTemplateNameFormat.INSTANCE)
- .build();
- try {
- cfg.getTemplate("././foo\\bar.ftl", Locale.US);
- fail();
- } catch (MalformedTemplateNameException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("backslash"));
- }
-
- }
-
- private void assertEqualsOn23AndOn24(String expected23, String expected24, String name)
- throws MalformedTemplateNameException {
- assertEquals(expected23, DefaultTemplateNameFormatFM2.INSTANCE.normalizeRootBasedName(name));
- assertEquals(expected24, DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName(name));
- }
-
- private void assertNormRBNameEqualsOn23ButThrowsBackOutExcOn24(final String expected23, final String name)
- throws MalformedTemplateNameException {
- assertEquals(expected23, DefaultTemplateNameFormatFM2.INSTANCE.normalizeRootBasedName(name));
- assertThrowsWithBackingOutException(name, DefaultTemplateNameFormat.INSTANCE);
- }
-
- private void assertThrowsWithBackingOutException(final String name, final TemplateNameFormat tnf) {
- try {
- tnf.normalizeRootBasedName(name);
- fail();
- } catch (MalformedTemplateNameException e) {
- assertEquals(name, e.getTemplateName());
- assertBackingOutFromRootException(e);
- }
- }
-
- private void assertNormRBNameThrowsColonExceptionOn24(final String name) throws MalformedTemplateNameException {
- try {
- DefaultTemplateNameFormat.INSTANCE.normalizeRootBasedName(name);
- fail();
- } catch (MalformedTemplateNameException e) {
- assertEquals(name, e.getTemplateName());
- assertColonException(e);
- }
- }
-
- private void assertBackingOutFromRootException(MalformedTemplateNameException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("backing out"));
- }
-
- private void assertColonException(MalformedTemplateNameException e) {
- assertThat(e.getMessage(), containsString("':'"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
deleted file mode 100644
index 51273c0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/TemplateSourceMatcherTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import org.junit.Test;
-
-public class TemplateSourceMatcherTest {
-
- @Test
- public void testPathGlobMatcher() throws IOException {
- PathGlobMatcher m = new PathGlobMatcher("**/a/?.ftl");
- assertTrue(m.matches("a/b.ftl", "dummy"));
- assertTrue(m.matches("x/a/c.ftl", "dummy"));
- assertFalse(m.matches("a/b.Ftl", "dummy"));
- assertFalse(m.matches("b.ftl", "dummy"));
- assertFalse(m.matches("a/bc.ftl", "dummy"));
-
- m = new PathGlobMatcher("**/a/?.ftl").caseInsensitive(true);
- assertTrue(m.matches("A/B.FTL", "dummy"));
- m.setCaseInsensitive(false);
- assertFalse(m.matches("A/B.FTL", "dummy"));
-
- try {
- new PathGlobMatcher("/b.ftl");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testFileNameGlobMatcher() throws IOException {
- FileNameGlobMatcher m = new FileNameGlobMatcher("a*.ftl");
- assertTrue(m.matches("ab.ftl", "dummy"));
- assertTrue(m.matches("dir/ab.ftl", "dummy"));
- assertTrue(m.matches("/dir/dir/ab.ftl", "dummy"));
- assertFalse(m.matches("Ab.ftl", "dummy"));
- assertFalse(m.matches("bb.ftl", "dummy"));
- assertFalse(m.matches("ab.ftl/x", "dummy"));
-
- m = new FileNameGlobMatcher("a*.ftl").caseInsensitive(true);
- assertTrue(m.matches("AB.FTL", "dummy"));
- m.setCaseInsensitive(false);
- assertFalse(m.matches("AB.FTL", "dummy"));
-
- m = new FileNameGlobMatcher("\u00E1*.ftl").caseInsensitive(true);
- assertTrue(m.matches("\u00C1b.ftl", "dummy"));
-
- try {
- new FileNameGlobMatcher("dir/a*.ftl");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testFileExtensionMatcher() throws IOException {
- FileExtensionMatcher m = new FileExtensionMatcher("ftlx");
- assertTrue(m.matches("a.ftlx", "dummy"));
- assertTrue(m.matches(".ftlx", "dummy"));
- assertTrue(m.matches("b/a.b.ftlx", "dummy"));
- assertTrue(m.matches("b/a.ftlx", "dummy"));
- assertTrue(m.matches("c.b/a.ftlx", "dummy"));
- assertFalse(m.matches("a.ftl", "dummy"));
- assertFalse(m.matches("ftlx", "dummy"));
- assertFalse(m.matches("b.ftlx/a.ftl", "dummy"));
-
- assertTrue(m.isCaseInsensitive());
- assertTrue(m.matches("a.fTlX", "dummy"));
- m.setCaseInsensitive(false);
- assertFalse(m.matches("a.fTlX", "dummy"));
- assertTrue(m.matches("A.ftlx", "dummy"));
-
- m = new FileExtensionMatcher("");
- assertTrue(m.matches("a.", "dummy"));
- assertTrue(m.matches(".", "dummy"));
- assertFalse(m.matches("a", "dummy"));
- assertFalse(m.matches("", "dummy"));
- assertFalse(m.matches("a.x", "dummy"));
-
- m = new FileExtensionMatcher("html.t");
- assertTrue(m.matches("a.html.t", "dummy"));
- assertFalse(m.matches("a.xhtml.t", "dummy"));
- assertFalse(m.matches("a.html", "dummy"));
- assertFalse(m.matches("a.t", "dummy"));
-
- try {
- new FileExtensionMatcher("*.ftlx");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- new FileExtensionMatcher("ftl?");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- new FileExtensionMatcher(".ftlx");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- new FileExtensionMatcher("dir/a.ftl");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testPathRegexMatcher() throws IOException {
- PathRegexMatcher m = new PathRegexMatcher("a/[a-z]+\\.ftl");
- assertTrue(m.matches("a/b.ftl", "dummy"));
- assertTrue(m.matches("a/abc.ftl", "dummy"));
- assertFalse(m.matches("b.ftl", "dummy"));
- assertFalse(m.matches("b/b.ftl", "dummy"));
-
- try {
- new PathRegexMatcher("/b.ftl");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testAndMatcher() throws IOException {
- AndMatcher m = new AndMatcher(new PathGlobMatcher("a*.*"), new PathGlobMatcher("*.t"));
- assertTrue(m.matches("ab.t", "dummy"));
- assertFalse(m.matches("bc.t", "dummy"));
- assertFalse(m.matches("ab.ftl", "dummy"));
-
- try {
- new AndMatcher();
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testOrMatcher() throws IOException {
- OrMatcher m = new OrMatcher(new PathGlobMatcher("a*.*"), new PathGlobMatcher("*.t"));
- assertTrue(m.matches("ab.t", "dummy"));
- assertTrue(m.matches("bc.t", "dummy"));
- assertTrue(m.matches("ab.ftl", "dummy"));
- assertFalse(m.matches("bc.ftl", "dummy"));
-
- try {
- new OrMatcher();
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testNotMatcher() throws IOException {
- NotMatcher m = new NotMatcher(new PathGlobMatcher("a*.*"));
- assertFalse(m.matches("ab.t", "dummy"));
- assertTrue(m.matches("bc.t", "dummy"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
deleted file mode 100644
index 1d69dd8..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/AppMetaTemplateDateFormatFactory.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
-import org.apache.freemarker.core.valueformat.UnparsableValueException;
-
-public class AppMetaTemplateDateFormatFactory extends TemplateDateFormatFactory {
-
- public static final AppMetaTemplateDateFormatFactory INSTANCE = new AppMetaTemplateDateFormatFactory();
-
- private AppMetaTemplateDateFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
- Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return AppMetaTemplateDateFormat.INSTANCE;
- }
-
- private static class AppMetaTemplateDateFormat extends TemplateDateFormat {
-
- private static final AppMetaTemplateDateFormat INSTANCE = new AppMetaTemplateDateFormat();
-
- private AppMetaTemplateDateFormat() { }
-
- @Override
- public String formatToPlainText(TemplateDateModel dateModel)
- throws UnformattableValueException, TemplateModelException {
- String result = String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
- if (dateModel instanceof AppMetaTemplateDateModel) {
- result += "/" + ((AppMetaTemplateDateModel) dateModel).getAppMeta();
- }
- return result;
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public boolean isTimeZoneBound() {
- return false;
- }
-
- @Override
- public Object parse(String s, int dateType) throws UnparsableValueException {
- int slashIdx = s.indexOf('/');
- try {
- if (slashIdx != -1) {
- return new AppMetaTemplateDateModel(
- new Date(Long.parseLong(s.substring(0, slashIdx))),
- dateType,
- s.substring(slashIdx +1));
- } else {
- return new Date(Long.parseLong(s));
- }
- } catch (NumberFormatException e) {
- throw new UnparsableValueException("Malformed long");
- }
- }
-
- @Override
- public String getDescription() {
- return "millis since the epoch";
- }
-
- }
-
- public static class AppMetaTemplateDateModel implements TemplateDateModel {
-
- private final Date date;
- private final int dateType;
- private final String appMeta;
-
- public AppMetaTemplateDateModel(Date date, int dateType, String appMeta) {
- this.date = date;
- this.dateType = dateType;
- this.appMeta = appMeta;
- }
-
- @Override
- public Date getAsDate() throws TemplateModelException {
- return date;
- }
-
- @Override
- public int getDateType() {
- return dateType;
- }
-
- public String getAppMeta() {
- return appMeta;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java
deleted file mode 100644
index e5def77..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/BaseNTemplateNumberFormatFactory.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.core.userpkg;
-
-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.util._NumberUtil;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-
-/**
- * Shows a number in base N number system. Can only format numbers that fit into an {@code int},
- * however, optionally you can specify a fallback format. This format has one required parameter,
- * the numerical system base. That can be optionally followed by "|" and a fallback format.
- */
-public class BaseNTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
-
- public static final BaseNTemplateNumberFormatFactory INSTANCE
- = new BaseNTemplateNumberFormatFactory();
-
- private BaseNTemplateNumberFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateNumberFormat get(String params, Locale locale, Environment env)
- throws InvalidFormatParametersException {
- TemplateNumberFormat fallbackFormat;
- {
- int barIdx = params.indexOf('|');
- if (barIdx != -1) {
- String fallbackFormatStr = params.substring(barIdx + 1);
- params = params.substring(0, barIdx);
- try {
- fallbackFormat = env.getTemplateNumberFormat(fallbackFormatStr, locale);
- } catch (TemplateValueFormatException e) {
- throw new InvalidFormatParametersException(
- "Couldn't get the fallback number format (specified after the \"|\"), "
- + _StringUtil.jQuote(fallbackFormatStr) + ". Reason: " + e.getMessage(),
- e);
- }
- } else {
- fallbackFormat = null;
- }
- }
-
- int base;
- try {
- base = Integer.parseInt(params);
- } catch (NumberFormatException e) {
- if (params.length() == 0) {
- throw new InvalidFormatParametersException(
- "A format parameter is required to specify the numerical system base.");
- }
- throw new InvalidFormatParametersException(
- "The format paramter must be an integer, but was (shown quoted): "
- + _StringUtil.jQuote(params));
- }
- if (base < 2) {
- throw new InvalidFormatParametersException("A base must be at least 2.");
- }
- return new BaseNTemplateNumberFormat(base, fallbackFormat);
- }
-
- private static class BaseNTemplateNumberFormat extends TemplateNumberFormat {
-
- private final int base;
- private final TemplateNumberFormat fallbackFormat;
-
- private BaseNTemplateNumberFormat(int base, TemplateNumberFormat fallbackFormat) {
- this.base = base;
- this.fallbackFormat = fallbackFormat;
- }
-
- @Override
- public String formatToPlainText(TemplateNumberModel numberModel)
- throws TemplateModelException, TemplateValueFormatException {
- Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
- try {
- return Integer.toString(_NumberUtil.toIntExact(n), base);
- } catch (ArithmeticException e) {
- if (fallbackFormat == null) {
- throw new UnformattableValueException(
- n + " doesn't fit into an int, and there was no fallback format "
- + "specified.");
- } else {
- return fallbackFormat.formatToPlainText(numberModel);
- }
- }
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public String getDescription() {
- return "base " + base;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
deleted file mode 100644
index f570a66..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomHTMLOutputFormat.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * Represents the HTML output format.
- *
- * @since 2.3.24
- */
-public final class CustomHTMLOutputFormat extends CommonMarkupOutputFormat<CustomTemplateHTMLModel> {
-
- public static final CustomHTMLOutputFormat INSTANCE = new CustomHTMLOutputFormat();
-
- private CustomHTMLOutputFormat() {
- // Only to decrease visibility
- }
-
- @Override
- public String getName() {
- return "HTML";
- }
-
- @Override
- public String getMimeType() {
- return "text/html";
- }
-
- @Override
- public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
- // This is lazy - don't do it in reality.
- out.write(escapePlainText(textToEsc));
- }
-
- @Override
- public String escapePlainText(String plainTextContent) {
- return _StringUtil.XHTMLEnc(plainTextContent.replace('x', 'X'));
- }
-
- @Override
- public boolean isLegacyBuiltInBypassed(String builtInName) {
- return builtInName.equals("html") || builtInName.equals("xml") || builtInName.equals("xhtml");
- }
-
- @Override
- protected CustomTemplateHTMLModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) {
- return new CustomTemplateHTMLModel(plainTextContent, markupContent);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java
deleted file mode 100644
index 4cc67be..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/CustomTemplateHTMLModel.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
-
-public final class CustomTemplateHTMLModel extends CommonTemplateMarkupOutputModel<CustomTemplateHTMLModel> {
-
- CustomTemplateHTMLModel(String plainTextContent, String markupContent) {
- super(plainTextContent, markupContent);
- }
-
- @Override
- public CustomHTMLOutputFormat getOutputFormat() {
- return CustomHTMLOutputFormat.INSTANCE;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
deleted file mode 100644
index f368969..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
-
-public class DummyOutputFormat extends CommonMarkupOutputFormat<TemplateDummyOutputModel> {
-
- public static final DummyOutputFormat INSTANCE = new DummyOutputFormat();
-
- private DummyOutputFormat() {
- // hide
- }
-
- @Override
- public String getName() {
- return "dummy";
- }
-
- @Override
- public String getMimeType() {
- return "text/dummy";
- }
-
- @Override
- public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
- out.write(escapePlainText(textToEsc));
- }
-
- @Override
- public String escapePlainText(String plainTextContent) {
- return plainTextContent.replaceAll("(\\.|\\\\)", "\\\\$1");
- }
-
- @Override
- public boolean isLegacyBuiltInBypassed(String builtInName) {
- return false;
- }
-
- @Override
- protected TemplateDummyOutputModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) {
- return new TemplateDummyOutputModel(plainTextContent, markupContent);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
deleted file mode 100644
index 8799eef..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisDivTemplateDateFormatFactory.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
-import org.apache.freemarker.core.valueformat.UnparsableValueException;
-
-public class EpochMillisDivTemplateDateFormatFactory extends TemplateDateFormatFactory {
-
- public static final EpochMillisDivTemplateDateFormatFactory INSTANCE = new EpochMillisDivTemplateDateFormatFactory();
-
- private EpochMillisDivTemplateDateFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
- Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
- int divisor;
- try {
- divisor = Integer.parseInt(params);
- } catch (NumberFormatException e) {
- if (params.length() == 0) {
- throw new InvalidFormatParametersException(
- "A format parameter is required, which specifies the divisor.");
- }
- throw new InvalidFormatParametersException(
- "The format paramter must be an integer, but was (shown quoted): " + _StringUtil.jQuote(params));
- }
- return new EpochMillisDivTemplateDateFormat(divisor);
- }
-
- private static class EpochMillisDivTemplateDateFormat extends TemplateDateFormat {
-
- private final int divisor;
-
- private EpochMillisDivTemplateDateFormat(int divisor) {
- this.divisor = divisor;
- }
-
- @Override
- public String formatToPlainText(TemplateDateModel dateModel)
- throws UnformattableValueException, TemplateModelException {
- return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() / divisor);
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public boolean isTimeZoneBound() {
- return false;
- }
-
- @Override
- public Date parse(String s, int dateType) throws UnparsableValueException {
- try {
- return new Date(Long.parseLong(s));
- } catch (NumberFormatException e) {
- throw new UnparsableValueException("Malformed long");
- }
- }
-
- @Override
- public String getDescription() {
- return "millis since the epoch";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
deleted file mode 100644
index 9f27095..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/EpochMillisTemplateDateFormatFactory.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-import org.apache.freemarker.core.valueformat.UnparsableValueException;
-
-public class EpochMillisTemplateDateFormatFactory extends TemplateDateFormatFactory {
-
- public static final EpochMillisTemplateDateFormatFactory INSTANCE
- = new EpochMillisTemplateDateFormatFactory();
-
- private EpochMillisTemplateDateFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateDateFormat get(String params, int dateType,
- Locale locale, TimeZone timeZone, boolean zonelessInput,
- Environment env)
- throws InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return EpochMillisTemplateDateFormat.INSTANCE;
- }
-
- private static class EpochMillisTemplateDateFormat extends TemplateDateFormat {
-
- private static final EpochMillisTemplateDateFormat INSTANCE
- = new EpochMillisTemplateDateFormat();
-
- private EpochMillisTemplateDateFormat() { }
-
- @Override
- public String formatToPlainText(TemplateDateModel dateModel)
- throws UnformattableValueException, TemplateModelException {
- return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public boolean isTimeZoneBound() {
- return false;
- }
-
- @Override
- public Date parse(String s, int dateType) throws UnparsableValueException {
- try {
- return new Date(Long.parseLong(s));
- } catch (NumberFormatException e) {
- throw new UnparsableValueException("Malformed long");
- }
- }
-
- @Override
- public String getDescription() {
- return "millis since the epoch";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
deleted file mode 100644
index 357034c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HTMLISOTemplateDateFormatFactory.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.util._DateUtil;
-import org.apache.freemarker.core.util._DateUtil.CalendarFieldsToDateConverter;
-import org.apache.freemarker.core.util._DateUtil.DateParseException;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
-import org.apache.freemarker.core.valueformat.UnparsableValueException;
-
-public class HTMLISOTemplateDateFormatFactory extends TemplateDateFormatFactory {
-
- public static final HTMLISOTemplateDateFormatFactory INSTANCE = new HTMLISOTemplateDateFormatFactory();
-
- private HTMLISOTemplateDateFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
- Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return HTMLISOTemplateDateFormat.INSTANCE;
- }
-
- private static class HTMLISOTemplateDateFormat extends TemplateDateFormat {
-
- private static final HTMLISOTemplateDateFormat INSTANCE = new HTMLISOTemplateDateFormat();
-
- private _DateUtil.TrivialDateToISO8601CalendarFactory calendarFactory;
-
- private CalendarFieldsToDateConverter calToDateConverter;
-
- private HTMLISOTemplateDateFormat() { }
-
- @Override
- public String formatToPlainText(TemplateDateModel dateModel)
- throws UnformattableValueException, TemplateModelException {
- if (calendarFactory == null) {
- calendarFactory = new _DateUtil.TrivialDateToISO8601CalendarFactory();
- }
- return _DateUtil.dateToISO8601String(
- TemplateFormatUtil.getNonNullDate(dateModel),
- true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC,
- calendarFactory);
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public boolean isTimeZoneBound() {
- return false;
- }
-
- @Override
- public Date parse(String s, int dateType) throws UnparsableValueException {
- try {
- if (calToDateConverter == null) {
- calToDateConverter = new _DateUtil.TrivialCalendarFieldsToDateConverter();
- }
- return _DateUtil.parseISO8601DateTime(s, _DateUtil.UTC, calToDateConverter);
- } catch (DateParseException e) {
- throw new UnparsableValueException("Malformed ISO date-time", e);
- }
- }
-
- @Override
- public Object format(TemplateDateModel dateModel) throws TemplateValueFormatException, TemplateModelException {
- return HTMLOutputFormat.INSTANCE.fromMarkup(
- formatToPlainText(dateModel).replace("T", "<span class='T'>T</span>"));
- }
-
- @Override
- public String getDescription() {
- return "ISO UTC HTML";
- }
-
- }
-
-}
-
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java
deleted file mode 100644
index 6d72c20..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/HexTemplateNumberFormatFactory.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.core.userpkg;
-
-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.util._NumberUtil;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-
-public class HexTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
-
- public static final HexTemplateNumberFormatFactory INSTANCE = new HexTemplateNumberFormatFactory();
-
- private HexTemplateNumberFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateNumberFormat get(String params, Locale locale, Environment env)
- throws InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return HexTemplateNumberFormat.INSTANCE;
- }
-
- private static class HexTemplateNumberFormat extends TemplateNumberFormat {
-
- private static final HexTemplateNumberFormat INSTANCE = new HexTemplateNumberFormat();
-
- private HexTemplateNumberFormat() { }
-
- @Override
- public String formatToPlainText(TemplateNumberModel numberModel)
- throws UnformattableValueException, TemplateModelException {
- Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
- try {
- return Integer.toHexString(_NumberUtil.toIntExact(n));
- } catch (ArithmeticException e) {
- throw new UnformattableValueException(n + " doesn't fit into an int");
- }
- }
-
- @Override
- public boolean isLocaleBound() {
- return false;
- }
-
- @Override
- public String getDescription() {
- return "hexadecimal int";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
deleted file mode 100644
index 42b0401..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocAndTZSensitiveTemplateDateFormatFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-import org.apache.freemarker.core.valueformat.UnknownDateTypeFormattingUnsupportedException;
-import org.apache.freemarker.core.valueformat.UnparsableValueException;
-
-public class LocAndTZSensitiveTemplateDateFormatFactory extends TemplateDateFormatFactory {
-
- public static final LocAndTZSensitiveTemplateDateFormatFactory INSTANCE = new LocAndTZSensitiveTemplateDateFormatFactory();
-
- private LocAndTZSensitiveTemplateDateFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput,
- Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return new LocAndTZSensitiveTemplateDateFormat(locale, timeZone);
- }
-
- private static class LocAndTZSensitiveTemplateDateFormat extends TemplateDateFormat {
-
- private final Locale locale;
- private final TimeZone timeZone;
-
- public LocAndTZSensitiveTemplateDateFormat(Locale locale, TimeZone timeZone) {
- this.locale = locale;
- this.timeZone = timeZone;
- }
-
- @Override
- public String formatToPlainText(TemplateDateModel dateModel)
- throws UnformattableValueException, TemplateModelException {
- return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() + "@" + locale + ":" + timeZone.getID());
- }
-
- @Override
- public boolean isLocaleBound() {
- return true;
- }
-
- @Override
- public boolean isTimeZoneBound() {
- return true;
- }
-
- @Override
- public Date parse(String s, int dateType) throws UnparsableValueException {
- try {
- int atIdx = s.indexOf("@");
- if (atIdx == -1) {
- throw new UnparsableValueException("Missing @");
- }
- return new Date(Long.parseLong(s.substring(0, atIdx)));
- } catch (NumberFormatException e) {
- throw new UnparsableValueException("Malformed long");
- }
- }
-
- @Override
- public String getDescription() {
- return "millis since the epoch";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
deleted file mode 100644
index dc3dae0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/LocaleSensitiveTemplateNumberFormatFactory.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.core.userpkg;
-
-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.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-
-public class LocaleSensitiveTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
-
- public static final LocaleSensitiveTemplateNumberFormatFactory INSTANCE = new LocaleSensitiveTemplateNumberFormatFactory();
-
- private LocaleSensitiveTemplateNumberFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateNumberFormat get(String params, Locale locale, Environment env)
- throws InvalidFormatParametersException {
- TemplateFormatUtil.checkHasNoParameters(params);
- return new LocaleSensitiveTemplateNumberFormat(locale);
- }
-
- private static class LocaleSensitiveTemplateNumberFormat extends TemplateNumberFormat {
-
- private final Locale locale;
-
- private LocaleSensitiveTemplateNumberFormat(Locale locale) {
- this.locale = locale;
- }
-
- @Override
- public String formatToPlainText(TemplateNumberModel numberModel)
- throws UnformattableValueException, TemplateModelException {
- Number n = numberModel.getAsNumber();
- try {
- return n + "_" + locale;
- } catch (ArithmeticException e) {
- throw new UnformattableValueException(n + " doesn't fit into an int");
- }
- }
-
- @Override
- public boolean isLocaleBound() {
- return true;
- }
-
- @Override
- public String getDescription() {
- return "test locale sensitive";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
deleted file mode 100644
index f3ebc72..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAll.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core.userpkg;
-
-class PackageVisibleAll {
-
- PackageVisibleAll() {}
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
deleted file mode 100644
index 53a89d4..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core.userpkg;
-
-class PackageVisibleAllWithBuilder {
-
- PackageVisibleAllWithBuilder() {}
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
deleted file mode 100644
index 510ecc2..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleAllWithBuilderBuilder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.core.userpkg;
-
-public class PackageVisibleAllWithBuilderBuilder {
-
- public PackageVisibleAllWithBuilder build() {
- return new PackageVisibleAllWithBuilder();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
deleted file mode 100644
index 836e80d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PackageVisibleWithPublicConstructor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core.userpkg;
-
-class PackageVisibleWithPublicConstructor {
-
- public PackageVisibleWithPublicConstructor() {
- }
-
-}
[46/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
new file mode 100644
index 0000000..ff5897f
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretAndEvalTemplateNameTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+/**
+ * Test template names returned by special variables and relative path resolution in {@code ?interpret}-ed and
+ * {@code ?eval}-ed parts.
+ */
+public class InterpretAndEvalTemplateNameTest extends TemplateTest {
+
+ @Test
+ public void testInterpret() throws IOException, TemplateException {
+ for (String getTemplateNames : new String[] {
+ "c=${.current_template_name}, m=${.main_template_name}",
+ "c=${\".current_template_name\"?eval}, m=${\".main_template_name\"?eval}"
+ }) {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate(
+ "main.ftl",
+ getTemplateNames + " "
+ + "{<#include 'sub/t.ftl'>}");
+ tl.putTemplate(
+ "sub/t.ftl",
+ getTemplateNames + " "
+ + "i{<@r'" + getTemplateNames + " {<#include \"a.ftl\">'?interpret />}} "
+ + "i{<@[r'" + getTemplateNames + " {<#include \"a.ftl\">','named_interpreted']?interpret />}}");
+ tl.putTemplate("sub/a.ftl", "In sub/a.ftl, " + getTemplateNames);
+ tl.putTemplate("a.ftl", "In a.ftl");
+
+ setConfiguration(new TestConfigurationBuilder().templateLoader(tl).build());
+
+ assertOutputForNamed("main.ftl",
+ "c=main.ftl, m=main.ftl "
+ + "{"
+ + "c=sub/t.ftl, m=main.ftl "
+ + "i{c=sub/t.ftl->anonymous_interpreted, m=main.ftl {In sub/a.ftl, c=sub/a.ftl, m=main.ftl}} "
+ + "i{c=sub/t.ftl->named_interpreted, m=main.ftl {In sub/a.ftl, c=sub/a.ftl, m=main.ftl}}"
+ + "}");
+
+ assertOutputForNamed("sub/t.ftl",
+ "c=sub/t.ftl, m=sub/t.ftl "
+ + "i{c=sub/t.ftl->anonymous_interpreted, m=sub/t.ftl {In sub/a.ftl, c=sub/a.ftl, m=sub/t.ftl}} "
+ + "i{c=sub/t.ftl->named_interpreted, m=sub/t.ftl {In sub/a.ftl, c=sub/a.ftl, m=sub/t.ftl}}");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
new file mode 100644
index 0000000..2d061d7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpretSettingInheritanceTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+/**
+ * The {@code interpret} built-in must not consider the settings or established auto-detected syntax of the surrounding
+ * template. It can only depend on the {@link Configuration}.
+ */
+public class InterpretSettingInheritanceTest extends TemplateTest {
+
+ private static final String FTL_A_S_A = "<#ftl><@'[#if true]s[/#if]<#if true>a</#if>'?interpret />";
+ private static final String FTL_A_A_S = "<#ftl><@'<#if true>a</#if>[#if true]s[/#if]'?interpret />";
+ private static final String FTL_S_S_A = "[#ftl][@'[#if true]s[/#if]<#if true>a</#if>'?interpret /]";
+ private static final String FTL_S_A_S = "[#ftl][@'<#if true>a</#if>[#if true]s[/#if]'?interpret /]";
+ private static final String OUT_S_A_WHEN_SYNTAX_IS_S = "s<#if true>a</#if>";
+ private static final String OUT_S_A_WHEN_SYNTAX_IS_A = "[#if true]s[/#if]a";
+ private static final String OUT_A_S_WHEN_SYNTAX_IS_A = "a[#if true]s[/#if]";
+ private static final String OUT_A_S_WHEN_SYNTAX_IS_S = "<#if true>a</#if>s";
+
+ @Test
+ public void tagSyntaxTest() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX)
+ .build());
+ assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
+ assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_A);
+ assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
+ assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_A);
+
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
+ .build());
+ assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_S);
+ assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
+ assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_S);
+ assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
+
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
+ .build());
+ assertOutput(FTL_S_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
+ assertOutput(FTL_S_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
+ assertOutput(FTL_A_A_S, OUT_A_S_WHEN_SYNTAX_IS_A);
+ assertOutput(FTL_A_S_A, OUT_S_A_WHEN_SYNTAX_IS_S);
+ assertOutput("<@'[#ftl]x'?interpret />[#if true]y[/#if]", "x[#if true]y[/#if]");
+ }
+
+ @Test
+ public void whitespaceStrippingTest() throws IOException, TemplateException {
+ Configuration cfg = getConfiguration();
+
+ setConfiguration(new TestConfigurationBuilder()
+ .whitespaceStripping(true)
+ .build());
+ assertOutput("<#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "XY");
+ assertOutput("<#ftl stripWhitespace=false><#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "\nXY");
+ assertOutput("<#assign x = 1>\nX<@'<#ftl stripWhitespace=false><#assign x = 1>\\nY'?interpret />", "X\nY");
+
+ setConfiguration(new TestConfigurationBuilder()
+ .whitespaceStripping(false)
+ .build());
+ assertOutput("<#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "\nX\nY");
+ assertOutput("<#ftl stripWhitespace=true><#assign x = 1>\nX<@'<#assign x = 1>\\nY'?interpret />", "X\nY");
+ assertOutput("<#assign x = 1>\nX<@'<#ftl stripWhitespace=true><#assign x = 1>\\nY'?interpret />", "\nXY");
+ }
+
+ @Test
+ public void evalTest() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX)
+ .build());
+ assertOutput("<@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval />", OUT_S_A_WHEN_SYNTAX_IS_A);
+ assertOutput("[#ftl][@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval /]", OUT_S_A_WHEN_SYNTAX_IS_A);
+
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
+ .build());
+ assertOutput("[@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval /]", OUT_S_A_WHEN_SYNTAX_IS_S);
+ assertOutput("<#ftl><@'\"[#if true]s[/#if]<#if true>a</#if>\"?interpret'?eval />", OUT_S_A_WHEN_SYNTAX_IS_S);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
new file mode 100644
index 0000000..08fcee2
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IteratorIssuesTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.core;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class IteratorIssuesTest extends TemplateTest {
+
+ private static final DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ private static final String FTL_HAS_CONTENT_AND_LIST
+ = "<#if it?hasContent><#list it as i>${i}</#list><#else>empty</#if>";
+ private static final String OUT_HAS_CONTENT_AND_LIST_ABC = "abc";
+ private static final String OUT_HAS_CONTENT_AND_LIST_EMPTY = "empty";
+
+ private static final String FTL_LIST_AND_HAS_CONTENT
+ = "<#list it as i>${i}${it?hasContent?then('+', '-')}</#list>";
+ private static final String OUT_LIST_AND_HAS_CONTENT_BW_GOOD = "a+b+c-";
+
+ @Test
+ public void testHasContentAndList() throws Exception {
+ addToDataModel("it", OW.wrap(getAbcIt()));
+ assertOutput(FTL_HAS_CONTENT_AND_LIST, OUT_HAS_CONTENT_AND_LIST_ABC);
+
+ addToDataModel("it", OW.wrap(getEmptyIt()));
+ assertOutput(FTL_HAS_CONTENT_AND_LIST, OUT_HAS_CONTENT_AND_LIST_EMPTY);
+ }
+
+ @Test
+ public void testListAndHasContent() throws Exception {
+ addToDataModel("it", OW.wrap(getAbcIt()));
+ assertErrorContains(FTL_LIST_AND_HAS_CONTENT, "can be listed only once");
+ }
+
+ private Iterator getAbcIt() {
+ return Arrays.asList(new String[] { "a", "b", "c" }).iterator();
+ }
+
+ private Iterator getEmptyIt() {
+ return Arrays.asList(new String[] { }).iterator();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
new file mode 100644
index 0000000..0fa3f79
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/JavaCCExceptionAsEOFFixTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * JavaCC suppresses exceptions thrown by the Reader, silently treating them as EOF. To be precise, JavaCC 3.2 only does
+ * that with {@link IOException}-s, while JavaCC 6 does that for all {@link Exception}-s. This tests FreeMarker's
+ * workaround for this problem.
+ */
+public class JavaCCExceptionAsEOFFixTest {
+
+ public static class FailingReader extends Reader {
+
+ private static final String CONTENT = "abc";
+
+ private final Throwable exceptionToThrow;
+ private int readSoFar;
+
+ protected FailingReader(Throwable exceptionToThrow) {
+ this.exceptionToThrow = exceptionToThrow;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (readSoFar == CONTENT.length()) {
+ if (exceptionToThrow != null) {
+ throwException();
+ } else {
+ return -1;
+ }
+ }
+ return CONTENT.charAt(readSoFar++);
+ }
+
+ private void throwException() throws IOException {
+ if (exceptionToThrow instanceof IOException) {
+ throw (IOException) exceptionToThrow;
+ }
+ if (exceptionToThrow instanceof RuntimeException) {
+ throw (RuntimeException) exceptionToThrow;
+ }
+ if (exceptionToThrow instanceof Error) {
+ throw (Error) exceptionToThrow;
+ }
+ Assert.fail();
+ }
+
+ @Override
+ public void close() throws IOException {
+ // nop
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ int c = read();
+ if (c == -1) return i == 0 ? -1 : i;
+ cbuf[off + i] = (char) c;
+ }
+ return len;
+ }
+
+ }
+
+ @Test
+ public void testIOException() throws IOException {
+ try {
+ new Template(null, new FailingReader(new IOException("test")), new TestConfigurationBuilder().build());
+ fail();
+ } catch (IOException e) {
+ assertEquals("test", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRuntimeException() throws IOException {
+ try {
+ new Template(null, new FailingReader(new NullPointerException("test")), new TestConfigurationBuilder().build());
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("test", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testError() throws IOException {
+ try {
+ new Template(null, new FailingReader(new OutOfMemoryError("test")), new TestConfigurationBuilder().build());
+ fail();
+ } catch (OutOfMemoryError e) {
+ assertEquals("test", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoException() throws IOException {
+ Template t = new Template(null, new FailingReader(null), new TestConfigurationBuilder().build());
+ assertEquals("abc", t.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ListErrorsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
new file mode 100644
index 0000000..05bac4f
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ListErrorsTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.templatesuite.models.Listables;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class ListErrorsTest extends TemplateTest {
+
+ @Test
+ public void testValid() throws IOException, TemplateException {
+ assertOutput("<#list 1..2 as x><#list 3..4>${x}:<#items as x>${x}</#items></#list>;</#list>", "1:34;2:34;");
+ assertOutput("<#list [] as x>${x}<#else><#list 1..2 as x>${x}<#sep>, </#list></#list>", "1, 2");
+ assertOutput("<#macro m>[<#nested 3>]</#macro>"
+ + "<#list 1..2 as x>"
+ + "${x}@${x?index}"
+ + "<@m ; x>"
+ + "${x},"
+ + "<#list 4..4 as x>${x}@${x?index}</#list>"
+ + "</@>"
+ + "${x}@${x?index}; "
+ + "</#list>",
+ "1@0[3,4@0]1@0; 2@1[3,4@0]2@1; ");
+ }
+
+ @Test
+ public void testInvalidItemsParseTime() throws IOException, TemplateException {
+ assertErrorContains("<#items as x>${x}</#items>",
+ "#items", "must be inside", "#list");
+ assertErrorContains("<#list xs><#macro m><#items as x></#items></#macro></#list>",
+ "#items", "must be inside", "#list");
+ assertErrorContains("<#list xs as x><#items as x>${x}</#items></#list>",
+ "#list", "must not have", "#items", "as loopVar");
+ assertErrorContains("<#list xs><#list xs as x><#items as x>${x}</#items></#list></#list>",
+ "#list", "must not have", "#items", "as loopVar");
+ assertErrorContains("<#list xs></#list>",
+ "#list", "must have", "#items", "as loopVar");
+ }
+
+ @Test
+ public void testInvalidSepParseTime() throws IOException, TemplateException {
+ assertErrorContains("<#sep>, </#sep>",
+ "#sep", "must be inside", "#list");
+ assertErrorContains("<#sep>, ",
+ "#sep", "must be inside", "#list");
+ assertErrorContains("<#list xs as x><#else><#sep>, </#list>",
+ "#sep", "must be inside", "#list");
+ assertErrorContains("<#list xs as x><#macro m><#sep>, </#macro></#list>",
+ "#sep", "must be inside", "#list");
+ }
+
+ @Test
+ public void testInvalidItemsRuntime() throws IOException, TemplateException {
+ assertErrorContains("<#list 1..1><#items as x></#items><#items as x></#items></#list>",
+ "#items", "already entered earlier");
+ assertErrorContains("<#list 1..1><#items as x><#items as y>${x}/${y}</#items></#items></#list>",
+ "#items", "Can't nest #items into each other");
+ }
+
+ @Test
+ public void testInvalidLoopVarBuiltinLHO() {
+ assertErrorContains("<#list foos>${foo?index}</#list>",
+ "?index", "foo", "no loop variable");
+ assertErrorContains("<#list foos as foo></#list>${foo?index}",
+ "?index", "foo" , "no loop variable");
+ assertErrorContains("<#list foos as foo><#macro m>${foo?index}</#macro></#list>",
+ "?index", "foo" , "no loop variable");
+ assertErrorContains("<#list foos as foo><#function f>${foo?index}</#function></#list>",
+ "?index", "foo" , "no loop variable");
+ assertErrorContains("<#list xs as x>${foo?index}</#list>",
+ "?index", "foo" , "no loop variable");
+ assertErrorContains("<#list foos as foo><@m; foo>${foo?index}</@></#list>",
+ "?index", "foo" , "user defined directive");
+ assertErrorContains(
+ "<#list foos as foo><@m; foo><@m; foo>${foo?index}</@></@></#list>",
+ "?index", "foo" , "user defined directive");
+ assertErrorContains(
+ "<#list foos as foo><@m; foo>"
+ + "<#list foos as foo><@m; foo>${foo?index}</@></#list>"
+ + "</@></#list>",
+ "?index", "foo" , "user defined directive");
+ }
+
+ @Test
+ public void testKeyValueSameName() {
+ assertErrorContains("<#list {} as foo, foo></#list>",
+ "key", "value", "both" , "foo");
+ }
+
+ @Test
+ public void testCollectionVersusHash() {
+ assertErrorContains("<#list {} as i></#list>",
+ "as k, v");
+ assertErrorContains("<#list [] as k, v></#list>",
+ "only one loop variable");
+ }
+
+ @Test
+ public void testNonEx2NonStringKey() throws IOException, TemplateException {
+ addToDataModel("m", new Listables.NonEx2MapAdapter(ImmutableMap.of("k1", "v1", 2, "v2"),
+ new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build()));
+ assertOutput("<#list m?keys as k>${k};</#list>", "k1;2;");
+ assertErrorContains("<#list m as k, v></#list>",
+ "string", "number", ".TemplateHashModelEx2");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
new file mode 100644
index 0000000..1903e05
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MiscErrorMessagesTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.core;
+
+import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class MiscErrorMessagesTest extends TemplateTest {
+
+ @Test
+ public void stringIndexOutOfBounds() {
+ assertErrorContains("${'foo'[10]}", "length", "3", "10", "String index out of");
+ }
+
+ @Test
+ public void wrongTemplateNameFormat() {
+ setConfiguration(new TestConfigurationBuilder().templateNameFormat(DefaultTemplateNameFormat.INSTANCE).build());
+
+ assertErrorContains("<#include 'foo:/bar:baaz'>", "Malformed template name", "':'");
+ assertErrorContains("<#include '../baaz'>", "Malformed template name", "root");
+ assertErrorContains("<#include '\u0000'>", "Malformed template name", "\\u0000");
+ }
+
+ @Test
+ public void numericalKeyHint() {
+ assertErrorContains("${{}[10]}", "[]", "?api");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
new file mode 100644
index 0000000..5fcee97
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicImportAPIsTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+
+import org.apache.freemarker.core.Environment.Namespace;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.core.util._NullWriter;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+/**
+ * These are things that users shouldn't do, but we shouldn't break backward compatibility without knowing about it.
+ */
+public class MistakenlyPublicImportAPIsTest {
+
+ @Test
+ public void testImportCopying() throws IOException, TemplateException {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("imp1", "<#macro m>1</#macro>");
+ tl.putTemplate("imp2", "<#assign x = 2><#macro m>${x}</#macro>");
+
+ Configuration cfg = new TestConfigurationBuilder().templateLoader(tl).build();
+
+ Template t1 = new Template(null, "<#import 'imp1' as i1><#import 'imp2' as i2>", cfg);
+ List<ASTDirImport> imports = t1.getImports();
+ assertEquals(2, imports.size());
+
+ {
+ Template t2 = new Template(null, "<@i1.m/><@i2.m/>", cfg);
+ for (ASTDirImport libLoad : imports) {
+ t2.addImport(libLoad);
+ }
+
+ try {
+ t2.process(null, _NullWriter.INSTANCE);
+ fail();
+ } catch (InvalidReferenceException e) {
+ // Apparenly, it has never worked like this...
+ assertEquals("i1", e.getBlamedExpressionString());
+ }
+ }
+
+ // It works this way, though it has nothing to do with the problematic API-s:
+ Environment env = t1.createProcessingEnvironment(null, _NullWriter.INSTANCE);
+ env.process();
+ TemplateModel i1 = env.getVariable("i1");
+ assertThat(i1, instanceOf(Namespace.class));
+ TemplateModel i2 = env.getVariable("i2");
+ assertThat(i2, instanceOf(Namespace.class));
+
+ {
+ Template t2 = new Template(null, "<@i1.m/>", cfg);
+
+ StringWriter sw = new StringWriter();
+ env = t2.createProcessingEnvironment(null, sw);
+ env.setVariable("i1", i1);
+
+ env.process();
+ assertEquals("1", sw.toString());
+ }
+
+ {
+ Template t2 = new Template(null, "<@i2.m/>", cfg);
+
+ StringWriter sw = new StringWriter();
+ env = t2.createProcessingEnvironment(null, sw);
+ env.setVariable("i2", i2);
+
+ try {
+ env.process();
+ assertEquals("2", sw.toString());
+ } catch (NullPointerException e) {
+ // Expected on 2.3.x, because it won't find the namespace for the macro
+ // [2.4] Fix this "bug"
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
new file mode 100644
index 0000000..9c87e61
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/MistakenlyPublicMacroAPIsTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util._NullWriter;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+/**
+ * These are things that users shouldn't do, but we shouldn't break backward compatibility without knowing about it.
+ */
+public class MistakenlyPublicMacroAPIsTest {
+
+ private final Configuration cfg = new TestConfigurationBuilder().build();
+
+ /**
+ * Getting the macros from one template, and adding them to another.
+ */
+ @Test
+ public void testMacroCopyingExploit() throws IOException, TemplateException {
+ Template tMacros = new Template(null, "<#macro m1>1</#macro><#macro m2>2</#macro>", cfg);
+ Map<String, ASTDirMacro> macros = tMacros.getMacros();
+
+ Template t = new Template(null,
+ "<@m1/><@m2/><@m3/>"
+ + "<#macro m1>1b</#macro><#macro m3>3b</#macro> "
+ + "<@m1/><@m2/><@m3/>", cfg);
+ t.addMacro(macros.get("m1"));
+ t.addMacro(macros.get("m2"));
+
+ assertEquals("123b 1b23b", getTemplateOutput(t));
+ }
+
+ @Test
+ public void testMacroCopyingExploitAndNamespaces() throws IOException, TemplateException {
+ Template tMacros = new Template(null, "<#assign x = 0><#macro m1>${x}</#macro>", cfg);
+ Template t = new Template(null, "<#assign x = 1><@m1/>", cfg);
+ t.addMacro((ASTDirMacro) tMacros.getMacros().get("m1"));
+
+ assertEquals("1", getTemplateOutput(t));
+ }
+
+ @Test
+ public void testMacroCopyingFromFTLVariable() throws IOException, TemplateException {
+ Template tMacros = new Template(null, "<#assign x = 0><#macro m1>${x}</#macro>", cfg);
+ Environment env = tMacros.createProcessingEnvironment(null, _NullWriter.INSTANCE);
+ env.process();
+ TemplateModel m1 = env.getVariable("m1");
+ assertThat(m1, instanceOf(ASTDirMacro.class));
+
+ Template t = new Template(null, "<#assign x = 1><@m1/>", cfg);
+ t.addMacro((ASTDirMacro) m1);
+
+ assertEquals("1", getTemplateOutput(t));
+ }
+
+ private String getTemplateOutput(Template t) throws TemplateException, IOException {
+ StringWriter sw = new StringWriter();
+ t.process(null, sw);
+ return sw.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
new file mode 100644
index 0000000..506101d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/NewBiObjectWrapperRestrictionTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelAdapter;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleDate;
+import org.apache.freemarker.core.model.impl.SimpleHash;
+import org.apache.freemarker.core.model.impl.SimpleNumber;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class NewBiObjectWrapperRestrictionTest extends TemplateTest {
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return new TestConfigurationBuilder().objectWrapper(new EntirelyCustomObjectWrapper()).build();
+ }
+
+ @Test
+ public void testPositive() throws IOException, TemplateException {
+ assertOutput(
+ "${'org.apache.freemarker.test.templatesuite.models.NewTestModel'?new()}",
+ "default constructor");
+ }
+
+ @Test
+ public void testNegative() {
+ assertErrorContains(
+ "${'org.apache.freemarker.test.templatesuite.models.NewTestModel'?new('s')}",
+ "only supports 0 argument");
+ }
+
+ /**
+ * An object wrapper that doesn't extend {@link DefaultObjectWrapper}.
+ */
+ public static class EntirelyCustomObjectWrapper implements ObjectWrapper {
+
+ @Override
+ public TemplateModel wrap(Object obj) throws TemplateModelException {
+ if (obj == null) {
+ return null;
+ }
+
+ if (obj instanceof TemplateModel) {
+ return (TemplateModel) obj;
+ }
+ if (obj instanceof TemplateModelAdapter) {
+ return ((TemplateModelAdapter) obj).getTemplateModel();
+ }
+
+ if (obj instanceof String) {
+ return new SimpleScalar((String) obj);
+ }
+ if (obj instanceof Number) {
+ return new SimpleNumber((Number) obj);
+ }
+ if (obj instanceof Boolean) {
+ return obj.equals(Boolean.TRUE) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
+ }
+ if (obj instanceof java.util.Date) {
+ if (obj instanceof java.sql.Date) {
+ return new SimpleDate((java.sql.Date) obj);
+ }
+ if (obj instanceof java.sql.Time) {
+ return new SimpleDate((java.sql.Time) obj);
+ }
+ if (obj instanceof java.sql.Timestamp) {
+ return new SimpleDate((java.sql.Timestamp) obj);
+ }
+ return new SimpleDate((java.util.Date) obj, TemplateDateModel.UNKNOWN);
+ }
+
+ if (obj.getClass().isArray()) {
+ obj = Arrays.asList((Object[]) obj);
+ }
+ if (obj instanceof Collection) {
+ return new SimpleSequence((Collection<?>) obj, this);
+ }
+ if (obj instanceof Map) {
+ return new SimpleHash((Map<?, ?>) obj, this);
+ }
+
+ return null;
+ }
+ }
+}
[09/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
deleted file mode 100644
index 2a0ae9d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * 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.core.util;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.regex.Pattern;
-
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-public class StringUtilTest {
-
- @Test
- public void testV2319() {
- assertEquals("\\n\\r\\f\\b\\t\\x00\\x19", _StringUtil.javaScriptStringEnc("\n\r\f\b\t\u0000\u0019"));
- }
-
- @Test
- public void testControlChars() {
- assertEsc(
- "\n\r\f\b\t \u0000\u0019\u001F \u007F\u0080\u009F \u2028\u2029",
- "\\n\\r\\f\\b\\t \\x00\\x19\\x1F \\x7F\\x80\\x9F \\u2028\\u2029",
- "\\n\\r\\f\\b\\t \\u0000\\u0019\\u001F \\u007F\\u0080\\u009F \\u2028\\u2029");
- }
-
- @Test
- public void testHtmlChars() {
- assertEsc(
- "<safe>/>->]> </foo> <!-- --> <![CDATA[ ]]> <?php?>",
- "<safe>/>->]> <\\/foo> \\x3C!-- --\\> \\x3C![CDATA[ ]]\\> \\x3C?php?>",
- "<safe>/>->]> <\\/foo> \\u003C!-- --\\u003E \\u003C![CDATA[ ]]\\u003E \\u003C?php?>");
- assertEsc("<!c", "\\x3C!c", "\\u003C!c");
- assertEsc("c<!", "c\\x3C!", "c\\u003C!");
- assertEsc("c<", "c\\x3C", "c\\u003C");
- assertEsc("c<c", "c<c", "c<c");
- assertEsc("<c", "<c", "<c");
- assertEsc(">", "\\>", "\\u003E");
- assertEsc("->", "-\\>", "-\\u003E");
- assertEsc("-->", "--\\>", "--\\u003E");
- assertEsc("c-->", "c--\\>", "c--\\u003E");
- assertEsc("-->c", "--\\>c", "--\\u003Ec");
- assertEsc("]>", "]\\>", "]\\u003E");
- assertEsc("]]>", "]]\\>", "]]\\u003E");
- assertEsc("c]]>", "c]]\\>", "c]]\\u003E");
- assertEsc("]]>c", "]]\\>c", "]]\\u003Ec");
- assertEsc("c->", "c->", "c->");
- assertEsc("c>", "c>", "c>");
- assertEsc("-->", "--\\>", "--\\u003E");
- assertEsc("/", "\\/", "\\/");
- assertEsc("/c", "\\/c", "\\/c");
- assertEsc("</", "<\\/", "<\\/");
- assertEsc("</c", "<\\/c", "<\\/c");
- assertEsc("c/", "c/", "c/");
- }
-
- @Test
- public void testJSChars() {
- assertEsc("\"", "\\\"", "\\\"");
- assertEsc("'", "\\'", "'");
- assertEsc("\\", "\\\\", "\\\\");
- }
-
- @Test
- public void testSameStringsReturned() {
- String s = "==> I/m <safe>!";
- assertTrue(s == _StringUtil.jsStringEnc(s, false)); // "==" because is must return the same object
- assertTrue(s == _StringUtil.jsStringEnc(s, true));
-
- s = "";
- assertTrue(s == _StringUtil.jsStringEnc(s, false));
- assertTrue(s == _StringUtil.jsStringEnc(s, true));
-
- s = "\u00E1rv\u00EDzt\u0171r\u0151 \u3020";
- assertEquals(s, _StringUtil.jsStringEnc(s, false));
- assertTrue(s == _StringUtil.jsStringEnc(s, false));
- assertTrue(s == _StringUtil.jsStringEnc(s, true));
- }
-
- @Test
- public void testOneOffs() {
- assertEsc("c\"c\"cc\"\"c", "c\\\"c\\\"cc\\\"\\\"c", "c\\\"c\\\"cc\\\"\\\"c");
- assertEsc("\"c\"cc\"", "\\\"c\\\"cc\\\"", "\\\"c\\\"cc\\\"");
- assertEsc("c/c/cc//c", "c/c/cc//c", "c/c/cc//c");
- assertEsc("c<c<cc<<c", "c<c<cc<<c", "c<c<cc<<c");
- assertEsc("/<", "\\/\\x3C", "\\/\\u003C");
- assertEsc(">", "\\>", "\\u003E");
- assertEsc("]>", "]\\>", "]\\u003E");
- assertEsc("->", "-\\>", "-\\u003E");
- }
-
- private void assertEsc(String s, String javaScript, String json) {
- assertEquals(javaScript, _StringUtil.jsStringEnc(s, false));
- assertEquals(json, _StringUtil.jsStringEnc(s, true));
- }
-
- @Test
- public void testTrim() {
- assertSame(_CollectionUtil.EMPTY_CHAR_ARRAY, _StringUtil.trim(_CollectionUtil.EMPTY_CHAR_ARRAY));
- assertSame(_CollectionUtil.EMPTY_CHAR_ARRAY, _StringUtil.trim(" \t\u0001 ".toCharArray()));
- {
- char[] cs = "foo".toCharArray();
- assertSame(cs, cs);
- }
- assertArrayEquals("foo".toCharArray(), _StringUtil.trim("foo ".toCharArray()));
- assertArrayEquals("foo".toCharArray(), _StringUtil.trim(" foo".toCharArray()));
- assertArrayEquals("foo".toCharArray(), _StringUtil.trim(" foo ".toCharArray()));
- assertArrayEquals("foo".toCharArray(), _StringUtil.trim("\t\tfoo \r\n".toCharArray()));
- assertArrayEquals("x".toCharArray(), _StringUtil.trim(" x ".toCharArray()));
- assertArrayEquals("x y z".toCharArray(), _StringUtil.trim(" x y z ".toCharArray()));
- }
-
- @Test
- public void testIsTrimmedToEmpty() {
- assertTrue(_StringUtil.isTrimmableToEmpty("".toCharArray()));
- assertTrue(_StringUtil.isTrimmableToEmpty("\r\r\n\u0001".toCharArray()));
- assertFalse(_StringUtil.isTrimmableToEmpty("x".toCharArray()));
- assertFalse(_StringUtil.isTrimmableToEmpty(" x ".toCharArray()));
- }
-
- @Test
- public void testJQuote() {
- assertEquals("null", _StringUtil.jQuote(null));
- assertEquals("\"foo\"", _StringUtil.jQuote("foo"));
- assertEquals("\"123\"", _StringUtil.jQuote(Integer.valueOf(123)));
- assertEquals("\"foo's \\\"bar\\\"\"",
- _StringUtil.jQuote("foo's \"bar\""));
- assertEquals("\"\\n\\r\\t\\u0001\"",
- _StringUtil.jQuote("\n\r\t\u0001"));
- assertEquals("\"<\\nb\\rc\\td\\u0001>\"",
- _StringUtil.jQuote("<\nb\rc\td\u0001>"));
- }
-
- @Test
- public void testJQuoteNoXSS() {
- assertEquals("null", _StringUtil.jQuoteNoXSS(null));
- assertEquals("\"foo\"", _StringUtil.jQuoteNoXSS("foo"));
- assertEquals("\"123\"", _StringUtil.jQuoteNoXSS(Integer.valueOf(123)));
- assertEquals("\"foo's \\\"bar\\\"\"",
- _StringUtil.jQuoteNoXSS("foo's \"bar\""));
- assertEquals("\"\\n\\r\\t\\u0001\"",
- _StringUtil.jQuoteNoXSS("\n\r\t\u0001"));
- assertEquals("\"\\u003C\\nb\\rc\\td\\u0001>\"",
- _StringUtil.jQuoteNoXSS("<\nb\rc\td\u0001>"));
- assertEquals("\"\\u003C\\nb\\rc\\td\\u0001>\"",
- _StringUtil.jQuoteNoXSS((Object) "<\nb\rc\td\u0001>"));
- }
-
- @Test
- public void testGlobToRegularExpression() {
- assertGlobMatches("a/b/c.ftl", "a/b/c.ftl");
- assertGlobDoesNotMatch("/a/b/cxftl", "/a/b/c.ftl", "a/b/C.ftl");
-
- assertGlobMatches("a/b/*.ftl", "a/b/.ftl", "a/b/x.ftl", "a/b/xx.ftl");
- assertGlobDoesNotMatch("a/b/*.ftl", "a/c/x.ftl", "a/b/c/x.ftl", "/a/b/x.ftl", "a/b/xxftl");
-
- assertGlobMatches("a/b/?.ftl", "a/b/x.ftl");
- assertGlobDoesNotMatch("a/b/?.ftl", "a/c/x.ftl", "a/b/.ftl", "a/b/xx.ftl", "a/b/xxftl");
-
- assertGlobMatches("a/**/c.ftl", "a/b/c.ftl", "a/c.ftl", "a/b/b2/b3/c.ftl", "a//c.ftl");
- assertGlobDoesNotMatch("a/**/c.ftl", "x/b/c.ftl", "a/b/x.ftl");
-
- assertGlobMatches("**/c.ftl", "a/b/c.ftl", "c.ftl", "/c.ftl", "///c.ftl");
- assertGlobDoesNotMatch("**/c.ftl", "a/b/x.ftl");
-
- assertGlobMatches("a/b/**", "a/b/c.ftl", "a/b/c2/c.ftl", "a/b/", "a/b/c/");
- assertGlobDoesNotMatch("a/b.ftl");
-
- assertGlobMatches("**", "a/b/c.ftl", "");
-
- assertGlobMatches("\\[\\{\\*\\?\\}\\]\\\\", "[{*?}]\\");
- assertGlobDoesNotMatch("\\[\\{\\*\\?\\}\\]\\\\", "[{xx}]\\");
-
- assertGlobMatches("a/b/\\?.ftl", "a/b/?.ftl");
- assertGlobDoesNotMatch("a/b/\\?.ftl", "a/b/x.ftl");
-
- assertGlobMatches("\\?\\?.ftl", "??.ftl");
- assertGlobMatches("\\\\\\\\", "\\\\");
- assertGlobMatches("\\\\\\\\?", "\\\\x");
- assertGlobMatches("x\\", "x");
-
- assertGlobMatches("???*", "123", "1234", "12345");
- assertGlobDoesNotMatch("???*", "12", "1", "");
-
- assertGlobMatches("**/a??/b*.ftl", "a11/b1.ftl", "x/a11/b123.ftl", "x/y/a11/b.ftl");
- assertGlobDoesNotMatch("**/a??/b*.ftl", "a1/b1.ftl", "x/a11/c123.ftl");
-
- assertFalse(_StringUtil.globToRegularExpression("ab*").matcher("aBc").matches());
- assertTrue(_StringUtil.globToRegularExpression("ab*", true).matcher("aBc").matches());
- assertTrue(_StringUtil.globToRegularExpression("ab", true).matcher("aB").matches());
- assertTrue(_StringUtil.globToRegularExpression("\u00E1b*", true).matcher("\u00C1bc").matches());
-
- try {
- _StringUtil.globToRegularExpression("x**/y");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), Matchers.containsString("**"));
- }
-
- try {
- _StringUtil.globToRegularExpression("**y");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), Matchers.containsString("**"));
- }
-
- try {
- _StringUtil.globToRegularExpression("[ab]c");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), Matchers.containsString("unsupported"));
- }
-
- try {
- _StringUtil.globToRegularExpression("{aa,bb}c");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), Matchers.containsString("unsupported"));
- }
- }
-
- private void assertGlobMatches(String glob, String... ss) {
- Pattern pattern = _StringUtil.globToRegularExpression(glob);
- for (String s : ss) {
- if (!pattern.matcher(s).matches()) {
- fail("Glob " + glob + " (regexp: " + pattern + ") doesn't match " + s);
- }
- }
- }
-
- private void assertGlobDoesNotMatch(String glob, String... ss) {
- Pattern pattern = _StringUtil.globToRegularExpression(glob);
- for (String s : ss) {
- if (pattern.matcher(s).matches()) {
- fail("Glob " + glob + " (regexp: " + pattern + ") matches " + s);
- }
- }
- }
-
- @Test
- public void testHTMLEnc() {
- String s = "";
- assertSame(s, _StringUtil.XMLEncNA(s));
-
- s = "asd";
- assertSame(s, _StringUtil.XMLEncNA(s));
-
- assertEquals("a&b<c>d"e'f", _StringUtil.XMLEncNA("a&b<c>d\"e'f"));
- assertEquals("<", _StringUtil.XMLEncNA("<"));
- assertEquals("<a", _StringUtil.XMLEncNA("<a"));
- assertEquals("<a>", _StringUtil.XMLEncNA("<a>"));
- assertEquals("a>", _StringUtil.XMLEncNA("a>"));
- assertEquals("<>", _StringUtil.XMLEncNA("<>"));
- assertEquals("a<>b", _StringUtil.XMLEncNA("a<>b"));
- }
-
- @Test
- public void testXHTMLEnc() throws IOException {
- String s = "";
- assertSame(s, _StringUtil.XHTMLEnc(s));
-
- s = "asd";
- assertSame(s, _StringUtil.XHTMLEnc(s));
-
- testXHTMLEnc("a&b<c>d"e'f", "a&b<c>d\"e'f");
- testXHTMLEnc("<", "<");
- testXHTMLEnc("<a", "<a");
- testXHTMLEnc("<a>", "<a>");
- testXHTMLEnc("a>", "a>");
- testXHTMLEnc("<>", "<>");
- testXHTMLEnc("a<>b", "a<>b");
- }
-
- private void testXHTMLEnc(String expected, String in) throws IOException {
- assertEquals(expected, _StringUtil.XHTMLEnc(in));
-
- StringWriter sw = new StringWriter();
- _StringUtil.XHTMLEnc(in, sw);
- assertEquals(expected, sw.toString());
- }
-
- @Test
- public void testXMLEnc() throws IOException {
- String s = "";
- assertSame(s, _StringUtil.XMLEnc(s));
-
- s = "asd";
- assertSame(s, _StringUtil.XMLEnc(s));
-
- testXMLEnc("a&b<c>d"e'f", "a&b<c>d\"e'f");
- testXMLEnc("<", "<");
- testXMLEnc("<a", "<a");
- testXMLEnc("<a>", "<a>");
- testXMLEnc("a>", "a>");
- testXMLEnc("<>", "<>");
- testXMLEnc("a<>b", "a<>b");
- }
-
- private void testXMLEnc(String expected, String in) throws IOException {
- assertEquals(expected, _StringUtil.XMLEnc(in));
-
- StringWriter sw = new StringWriter();
- _StringUtil.XMLEnc(in, sw);
- assertEquals(expected, sw.toString());
- }
-
- @Test
- public void testXMLEncQAttr() throws IOException {
- String s = "";
- assertSame(s, _StringUtil.XMLEncQAttr(s));
-
- s = "asd";
- assertSame(s, _StringUtil.XMLEncQAttr(s));
-
- assertEquals("a&b<c>d"e'f", _StringUtil.XMLEncQAttr("a&b<c>d\"e'f"));
- assertEquals("<", _StringUtil.XMLEncQAttr("<"));
- assertEquals("<a", _StringUtil.XMLEncQAttr("<a"));
- assertEquals("<a>", _StringUtil.XMLEncQAttr("<a>"));
- assertEquals("a>", _StringUtil.XMLEncQAttr("a>"));
- assertEquals("<>", _StringUtil.XMLEncQAttr("<>"));
- assertEquals("a<>b", _StringUtil.XMLEncQAttr("a<>b"));
- }
-
- @Test
- public void testXMLEncNQG() throws IOException {
- String s = "";
- assertSame(s, _StringUtil.XMLEncNQG(s));
-
- s = "asd";
- assertSame(s, _StringUtil.XMLEncNQG(s));
-
- assertEquals("a&b<c>d\"e'f", _StringUtil.XMLEncNQG("a&b<c>d\"e'f"));
- assertEquals("<", _StringUtil.XMLEncNQG("<"));
- assertEquals("<a", _StringUtil.XMLEncNQG("<a"));
- assertEquals("<a>", _StringUtil.XMLEncNQG("<a>"));
- assertEquals("a>", _StringUtil.XMLEncNQG("a>"));
- assertEquals("<>", _StringUtil.XMLEncNQG("<>"));
- assertEquals("a<>b", _StringUtil.XMLEncNQG("a<>b"));
-
- assertEquals(">", _StringUtil.XMLEncNQG(">"));
- assertEquals("]>", _StringUtil.XMLEncNQG("]>"));
- assertEquals("]]>", _StringUtil.XMLEncNQG("]]>"));
- assertEquals("x]]>", _StringUtil.XMLEncNQG("x]]>"));
- assertEquals("x]>", _StringUtil.XMLEncNQG("x]>"));
- assertEquals("]x>", _StringUtil.XMLEncNQG("]x>"));
- }
-
- @Test
- public void testRTFEnc() throws IOException {
- String s = "";
- assertSame(s, _StringUtil.RTFEnc(s));
-
- s = "asd";
- assertSame(s, _StringUtil.RTFEnc(s));
-
- testRTFEnc("a\\{b\\}c\\\\d", "a{b}c\\d");
- testRTFEnc("\\{", "{");
- testRTFEnc("\\{a", "{a");
- testRTFEnc("\\{a\\}", "{a}");
- testRTFEnc("a\\}", "a}");
- testRTFEnc("\\{\\}", "{}");
- testRTFEnc("a\\{\\}b", "a{}b");
- }
-
- private void testRTFEnc(String expected, String in) throws IOException {
- assertEquals(expected, _StringUtil.RTFEnc(in));
-
- StringWriter sw = new StringWriter();
- _StringUtil.RTFEnc(in, sw);
- assertEquals(expected, sw.toString());
- }
-
- @Test
- public void testNormalizeEOLs() {
- assertNull(_StringUtil.normalizeEOLs(null));
- assertEquals("", _StringUtil.normalizeEOLs(""));
- assertEquals("x", _StringUtil.normalizeEOLs("x"));
- assertEquals("x\ny", _StringUtil.normalizeEOLs("x\ny"));
- assertEquals("x\ny", _StringUtil.normalizeEOLs("x\r\ny"));
- assertEquals("x\ny", _StringUtil.normalizeEOLs("x\ry"));
- assertEquals("\n\n\n\n\n\n", _StringUtil.normalizeEOLs("\n\r\r\r\n\r\n\r"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
deleted file mode 100644
index 8900d2b..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * 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.core.valueformat;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateConfiguration;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.impl.SimpleNumber;
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.TemplateConfigurationFactory;
-import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.LocaleSensitiveTemplateNumberFormatFactory;
-import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.impl.AliasTemplateNumberFormatFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class NumberFormatTest extends TemplateTest {
-
- @Test
- public void testUnknownCustomFormat() throws Exception {
- {
- setConfigurationWithNumberFormat("@noSuchFormat");
- Throwable exc = assertErrorContains("${1}", "\"@noSuchFormat\"", "\"noSuchFormat\"");
- assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
- }
-
- {
- setConfigurationWithNumberFormat("number");
- Throwable exc = assertErrorContains("${1?string('@noSuchFormat2')}",
- "\"@noSuchFormat2\"", "\"noSuchFormat2\"");
- assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
- }
- }
-
- @Test
- public void testStringBI() throws Exception {
- setConfigurationWithNumberFormat(null);
- assertOutput("${11} ${11?string.@hex} ${12} ${12?string.@hex}", "11 b 12 c");
- }
-
- @Test
- public void testSetting() throws Exception {
- setConfigurationWithNumberFormat("@hex");
- assertOutput("${11?string.number} ${11} ${12?string.number} ${12}", "11 b 12 c");
- }
-
- @Test
- public void testSetting2() throws Exception {
- setConfigurationWithNumberFormat(null);
- assertOutput(
- "<#setting numberFormat='@hex'>${11?string.number} ${11} ${12?string.number} ${12} ${13?string}"
- + "<#setting numberFormat='@loc'>${11?string.number} ${11} ${12?string.number} ${12} ${13?string}",
- "11 b 12 c d"
- + "11 11_en_US 12 12_en_US 13_en_US");
- }
-
- @Test
- public void testUnformattableNumber() throws Exception {
- setConfigurationWithNumberFormat("@hex");
- assertErrorContains("${1.1}", "hexadecimal int", "doesn't fit into an int");
- }
-
- @Test
- public void testLocaleSensitive() throws Exception {
- setConfigurationWithNumberFormat("@loc");
- assertOutput("${1.1}", "1.1_en_US");
- setConfigurationWithNumberFormat("@loc", null, null, Locale.GERMANY);
- assertOutput("${1.1}", "1.1_de_DE");
- }
-
- @Test
- public void testLocaleSensitive2() throws Exception {
- setConfigurationWithNumberFormat("@loc");
- assertOutput("${1.1} <#setting locale='de_DE'>${1.1}", "1.1_en_US 1.1_de_DE");
- }
-
- @Test
- public void testCustomParameterized() throws Exception {
- setConfigurationWithNumberFormat("@base 2");
- assertOutput("${11}", "1011");
- assertOutput("${11?string}", "1011");
- assertOutput("${11?string.@base_3}", "102");
-
- assertErrorContains("${11?string.@base_xyz}", "\"@base_xyz\"", "\"xyz\"");
- setConfigurationWithNumberFormat("@base");
- assertErrorContains("${11}", "\"@base\"", "format parameter is required");
- }
-
- @Test
- public void testCustomWithFallback() throws Exception {
- Configuration cfg = getConfiguration();
- setConfigurationWithNumberFormat("@base 2|0.0#");
- assertOutput("${11}", "1011");
- assertOutput("${11.34}", "11.34");
- assertOutput("${11?string('@base 3|0.00')}", "102");
- assertOutput("${11.2?string('@base 3|0.00')}", "11.20");
- }
-
- @Test
- public void testEnvironmentGetters() throws Exception {
- setConfigurationWithNumberFormat(null);
-
- Template t = new Template(null, "", getConfiguration());
- Environment env = t.createProcessingEnvironment(null, null);
-
- TemplateNumberFormat defF = env.getTemplateNumberFormat();
- //
- TemplateNumberFormat explF = env.getTemplateNumberFormat("0.00");
- assertEquals("1.25", explF.formatToPlainText(new SimpleNumber(1.25)));
- //
- TemplateNumberFormat expl2F = env.getTemplateNumberFormat("@loc");
- assertEquals("1.25_en_US", expl2F.formatToPlainText(new SimpleNumber(1.25)));
-
- TemplateNumberFormat explFFr = env.getTemplateNumberFormat("0.00", Locale.FRANCE);
- assertNotSame(explF, explFFr);
- assertEquals("1,25", explFFr.formatToPlainText(new SimpleNumber(1.25)));
- //
- TemplateNumberFormat expl2FFr = env.getTemplateNumberFormat("@loc", Locale.FRANCE);
- assertEquals("1.25_fr_FR", expl2FFr.formatToPlainText(new SimpleNumber(1.25)));
-
- assertSame(env.getTemplateNumberFormat(), defF);
- //
- assertSame(env.getTemplateNumberFormat("0.00"), explF);
- //
- assertSame(env.getTemplateNumberFormat("@loc"), expl2F);
- }
-
- /**
- * ?string formats lazily (at least in 2.3.x), so it must make a snapshot of the format inputs when it's called.
- */
- @Test
- @Ignore // [FM3] We want to rework BI-s so that lazy evaluation won't be needed. Then this will go away too.
- public void testStringBIDoesSnapshot() throws Exception {
- // TemplateNumberModel-s shouldn't change, but we have to keep BC when that still happens.
- final MutableTemplateNumberModel nm = new MutableTemplateNumberModel();
- nm.setNumber(123);
- addToDataModel("n", nm);
- addToDataModel("incN", new TemplateDirectiveModel() {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- nm.setNumber(nm.getAsNumber().intValue() + 1);
- }
- });
- assertOutput(
- "<#assign s1 = n?string>"
- + "<#setting numberFormat='@loc'>"
- + "<#assign s2 = n?string>"
- + "<#setting numberFormat='@hex'>"
- + "<#assign s3 = n?string>"
- + "${s1} ${s2} ${s3}",
- "123 123_en_US 7b");
- assertOutput(
- "<#assign s1 = n?string>"
- + "<@incN />"
- + "<#assign s2 = n?string>"
- + "${s1} ${s2}",
- "123 124");
- }
-
- @Test
- public void testNullInModel() throws Exception {
- addToDataModel("n", new MutableTemplateNumberModel());
- assertErrorContains("${n}", "nothing inside it");
- assertErrorContains("${n?string}", "nothing inside it");
- }
-
- @Test
- public void testAtPrefix() throws Exception {
- Configuration cfg = getConfiguration();
-
- setConfigurationWithNumberFormat("@hex");
- assertOutput("${10}", "a");
- setConfigurationWithNumberFormat("'@'0");
- assertOutput("${10}", "@10");
- setConfigurationWithNumberFormat("@@0");
- assertOutput("${10}", "@@10");
-
- setConfigurationWithNumberFormat(
- "@hex", Collections.<String, TemplateNumberFormatFactory>emptyMap());
- assertErrorContains("${10}", "custom", "\"hex\"");
-
- setConfigurationWithNumberFormat(
- "'@'0", Collections.<String, TemplateNumberFormatFactory>emptyMap());
- assertOutput("${10}", "@10");
-
- setConfigurationWithNumberFormat(
- "@@0", Collections.<String, TemplateNumberFormatFactory>emptyMap());
- assertOutput("${10}", "@@10");
- }
-
- @Test
- public void testAlieses() throws Exception {
- setConfigurationWithNumberFormat(
- "'@'0",
- ImmutableMap.of(
- "f", new AliasTemplateNumberFormatFactory("0.#'f'"),
- "d", new AliasTemplateNumberFormatFactory("0.0#"),
- "hex", HexTemplateNumberFormatFactory.INSTANCE),
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*2*"),
- new TemplateConfiguration.Builder()
- .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
- "d", new AliasTemplateNumberFormatFactory("0.#'d'"),
- "i", new AliasTemplateNumberFormatFactory("@hex")))
- .build()));
-
- String commonFtl = "${1?string.@f} ${1?string.@d} "
- + "<#setting locale='fr_FR'>${1.5?string.@d} "
- + "<#attempt>${10?string.@i}<#recover>E</#attempt>";
- addTemplate("t1.ftl", commonFtl);
- addTemplate("t2.ftl", commonFtl);
-
- assertOutputForNamed("t1.ftl", "1f 1.0 1,5 E");
- assertOutputForNamed("t2.ftl", "1f 1d 1,5d a");
- }
-
- @Test
- public void testAlieses2() throws Exception {
- setConfigurationWithNumberFormat(
- "@n",
- ImmutableMap.<String, TemplateNumberFormatFactory>of(
- "n", new AliasTemplateNumberFormatFactory("0.0",
- ImmutableMap.of(
- new Locale("en"), "0.0'_en'",
- Locale.UK, "0.0'_en_GB'",
- Locale.FRANCE, "0.0'_fr_FR'"))));
- assertOutput(
- "<#setting locale='en_US'>${1} "
- + "<#setting locale='en_GB'>${1} "
- + "<#setting locale='en_GB_Win'>${1} "
- + "<#setting locale='fr_FR'>${1} "
- + "<#setting locale='hu_HU'>${1}",
- "1.0_en 1.0_en_GB 1.0_en_GB 1,0_fr_FR 1,0");
- }
-
- @Test
- public void testMarkupFormat() throws IOException, TemplateException {
- setConfigurationWithNumberFormat("@printfG_3");
-
- String commonFTL = "${1234567} ${'cat:' + 1234567} ${0.0000123}";
- String commonOutput = "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>";
- assertOutput(commonFTL, commonOutput);
- assertOutput("<#ftl outputFormat='HTML'>" + commonFTL, commonOutput);
- assertOutput("<#escape x as x?html>" + commonFTL + "</#escape>", commonOutput);
- assertOutput("<#escape x as x?xhtml>" + commonFTL + "</#escape>", commonOutput);
- assertOutput("<#escape x as x?xml>" + commonFTL + "</#escape>", commonOutput);
- assertOutput("${\"" + commonFTL + "\"}", "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>");
- assertErrorContains("<#ftl outputFormat='plainText'>" + commonFTL, "HTML", "plainText", "conversion");
- }
-
- @Test
- public void testPrintG() throws IOException, TemplateException {
- setConfigurationWithNumberFormat(null);
- for (Number n : new Number[] {
- 1234567, 1234567L, 1234567d, 1234567f, BigInteger.valueOf(1234567), BigDecimal.valueOf(1234567) }) {
- addToDataModel("n", n);
-
- assertOutput("${n?string.@printfG}", "1.23457E+06");
- assertOutput("${n?string.@printfG_3}", "1.23E+06");
- assertOutput("${n?string.@printfG_7}", "1234567");
- assertOutput("${0.0000123?string.@printfG}", "1.23000E-05");
- }
- }
-
- private void setConfigurationWithNumberFormat(
- String numberFormat,
- Map<String, TemplateNumberFormatFactory> customNumberFormats,
- TemplateConfigurationFactory templateConfigurationFactory,
- Locale locale) {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder(Configuration.VERSION_3_0_0);
-
- if (numberFormat != null) {
- cfgB.setNumberFormat(numberFormat);
- }
- cfgB.setCustomNumberFormats(
- customNumberFormats != null ? customNumberFormats
- : ImmutableMap.of(
- "hex", HexTemplateNumberFormatFactory.INSTANCE,
- "loc", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE,
- "base", BaseNTemplateNumberFormatFactory.INSTANCE,
- "printfG", PrintfGTemplateNumberFormatFactory.INSTANCE));
- if (locale != null) {
- cfgB.setLocale(locale);
- }
- if (templateConfigurationFactory != null) {
- cfgB.setTemplateConfigurations(templateConfigurationFactory);
- }
-
- setConfiguration(cfgB.build());
- }
-
- private void setConfigurationWithNumberFormat(String numberFormat) {
- setConfigurationWithNumberFormat(numberFormat, null, null, null);
- }
-
- private void setConfigurationWithNumberFormat(
- String numberFormat, Map<String, TemplateNumberFormatFactory> customNumberFormats) {
- setConfigurationWithNumberFormat(numberFormat, customNumberFormats, null, null);
- }
-
- private void setConfigurationWithNumberFormat(
- String numberFormat, Map<String, TemplateNumberFormatFactory> customNumberFormats,
- TemplateConfigurationFactory templateConfigurationFactory) {
- setConfigurationWithNumberFormat(numberFormat, customNumberFormats, templateConfigurationFactory, null);
- }
-
- private static class MutableTemplateNumberModel implements TemplateNumberModel {
-
- private Number number;
-
- public void setNumber(Number number) {
- this.number = number;
- }
-
- @Override
- public Number getAsNumber() throws TemplateModelException {
- return number;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
deleted file mode 100644
index 76c0bfc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * 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.core.valueformat.impl;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.util.Locale;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class ExtendedDecimalFormatTest extends TemplateTest {
-
- private static final Locale LOC = Locale.US;
- private static final DecimalFormatSymbols SYMS = DecimalFormatSymbols.getInstance(LOC);
-
- @Test
- public void testNonExtended() throws ParseException {
- for (String fStr : new String[] { "0.00", "0.###", "#,#0.###", "#0.####", "0.0;m", "0.0;",
- "0'x'", "0'x';'m'", "0';'", "0';';m", "0';';'#'m';'", "0';;'", "" }) {
- assertFormatsEquivalent(new DecimalFormat(fStr, SYMS), ExtendedDecimalFormatParser.parse(fStr, LOC));
- }
-
- try {
- new DecimalFormat(";");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- ExtendedDecimalFormatParser.parse(";", LOC);
- } catch (ParseException e) {
- // Expected
- }
- }
-
- @Test
- public void testNonExtended2() throws ParseException {
- assertFormatsEquivalent(new DecimalFormat("0.0", SYMS), ExtendedDecimalFormatParser.parse("0.0;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0.0", SYMS), ExtendedDecimalFormatParser.parse("0.0;;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0.0;m", SYMS), ExtendedDecimalFormatParser.parse("0.0;m;", LOC));
- assertFormatsEquivalent(new DecimalFormat("", SYMS), ExtendedDecimalFormatParser.parse(";;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0'x'", SYMS), ExtendedDecimalFormatParser.parse("0'x';;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0'x';'m'", SYMS),
- ExtendedDecimalFormatParser.parse("0'x';'m';", LOC));
- assertFormatsEquivalent(new DecimalFormat("0';'", SYMS), ExtendedDecimalFormatParser.parse("0';';;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0';';m", SYMS), ExtendedDecimalFormatParser.parse("0';';m;", LOC));
- assertFormatsEquivalent(new DecimalFormat("0';';'#'m';'", SYMS),
- ExtendedDecimalFormatParser.parse("0';';'#'m';';", LOC));
- assertFormatsEquivalent(new DecimalFormat("0';;'", SYMS),
- ExtendedDecimalFormatParser.parse("0';;';;", LOC));
-
- try {
- new DecimalFormat(";m");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- new DecimalFormat("; ;");
- fail();
- } catch (IllegalArgumentException e) {
- // Expected
- }
- try {
- ExtendedDecimalFormatParser.parse("; ;", LOC);
- fail();
- } catch (ParseException e) {
- // Expected
- }
- try {
- ExtendedDecimalFormatParser.parse(";m", LOC);
- fail();
- } catch (ParseException e) {
- // Expected
- }
- try {
- ExtendedDecimalFormatParser.parse(";m;", LOC);
- fail();
- } catch (ParseException e) {
- // Expected
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testExtendedParamsParsing() throws ParseException {
- for (String fs : new String[] {
- "00.##;; decimalSeparator='D'",
- "00.##;;decimalSeparator=D",
- "00.##;; decimalSeparator = D ", "00.##;; decimalSeparator = 'D' " }) {
- assertFormatted(fs, 1.125, "01D12");
- }
- for (String fs : new String[] {
- ",#0.0;; decimalSeparator=D, groupingSeparator=_",
- ",#0.0;;decimalSeparator=D,groupingSeparator=_",
- ",#0.0;; decimalSeparator = D , groupingSeparator = _ ",
- ",#0.0;; decimalSeparator='D', groupingSeparator='_'"
- }) {
- assertFormatted(fs, 12345, "1_23_45D0");
- }
-
- assertFormatted("0.0;;infinity=infinity", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;infinity='infinity'", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;infinity=\"infinity\"", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;infinity=''", Double.POSITIVE_INFINITY, "");
- assertFormatted("0.0;;infinity=\"\"", Double.POSITIVE_INFINITY, "");
- assertFormatted("0.0;;infinity='x''y'", Double.POSITIVE_INFINITY, "x'y");
- assertFormatted("0.0;;infinity=\"x'y\"", Double.POSITIVE_INFINITY, "x'y");
- assertFormatted("0.0;;infinity='x\"\"y'", Double.POSITIVE_INFINITY, "x\"\"y");
- assertFormatted("0.0;;infinity=\"x''y\"", Double.POSITIVE_INFINITY, "x''y");
- assertFormatted("0.0;;decimalSeparator=''''", 1, "1'0");
- assertFormatted("0.0;;decimalSeparator=\"'\"", 1, "1'0");
- assertFormatted("0.0;;decimalSeparator='\"'", 1, "1\"0");
- assertFormatted("0.0;;decimalSeparator=\"\"\"\"", 1, "1\"0");
-
- try {
- ExtendedDecimalFormatParser.parse(";;decimalSeparator=D,", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(),
- allOf(containsStringIgnoringCase("expected a(n) name"), containsString(" end of ")));
- }
- try {
- ExtendedDecimalFormatParser.parse(";;foo=D,", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(),
- allOf(containsString("\"foo\""), containsString("name")));
- }
- try {
- ExtendedDecimalFormatParser.parse(";;decimalSeparator='D", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(),
- allOf(containsString("quotation"), containsString("closed")));
- }
- try {
- ExtendedDecimalFormatParser.parse(";;decimalSeparator=\"D", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(),
- allOf(containsString("quotation"), containsString("closed")));
- }
- try {
- ExtendedDecimalFormatParser.parse(";;decimalSeparator='D'groupingSeparator=G", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(), allOf(
- containsString("separator"), containsString("whitespace"), containsString("comma")));
- }
- try {
- ExtendedDecimalFormatParser.parse(";;decimalSeparator=., groupingSeparator=G", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(), allOf(
- containsStringIgnoringCase("expected a(n) value"), containsString("., gr[...]")));
- }
- try {
- ExtendedDecimalFormatParser.parse("0.0;;decimalSeparator=''", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(), allOf(
- containsStringIgnoringCase("\"decimalSeparator\""), containsString("exactly 1 char")));
- }
- try {
- ExtendedDecimalFormatParser.parse("0.0;;multipier=ten", LOC);
- fail();
- } catch (java.text.ParseException e) {
- assertThat(e.getMessage(), allOf(
- containsString("\"multipier\""), containsString("\"ten\""), containsString("integer")));
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testExtendedParamsEffect() throws ParseException {
- assertFormatted("0",
- 1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; roundingMode=halfEven",
- 1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; roundingMode=halfUp",
- 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-3", -1.6, "-2");
- assertFormatted("0;; roundingMode=halfDown",
- 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; roundingMode=floor",
- 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
- assertFormatted("0;; roundingMode=ceiling",
- 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
- assertFormatted("0;; roundingMode=up",
- 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
- assertFormatted("0;; roundingMode=down",
- 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
- assertFormatted("0;; roundingMode=unnecessary", 2, "2");
- try {
- assertFormatted("0;; roundingMode=unnecessary", 2.5, "2");
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
-
- assertFormatted("0.##;; multipier=100", 12.345, "1234.5");
- assertFormatted("0.##;; multipier=1000", 12.345, "12345");
-
- assertFormatted(",##0.##;; groupingSeparator=_ decimalSeparator=D", 12345.1, "12_345D1", 1, "1");
-
- assertFormatted("0.##E0;; exponentSeparator='*10^'", 12345.1, "1.23*10^4");
-
- assertFormatted("0.##;; minusSign=m", -1, "m1", 1, "1");
-
- assertFormatted("0.##;; infinity=foo", Double.POSITIVE_INFINITY, "foo", Double.NEGATIVE_INFINITY, "-foo");
-
- assertFormatted("0.##;; nan=foo", Double.NaN, "foo");
-
- assertFormatted("0%;; percent='c'", 0.75, "75c");
-
- assertFormatted("0\u2030;; perMill='m'", 0.75, "750m");
-
- assertFormatted("0.00;; zeroDigit='@'", 10.5, "A@.E@");
-
- assertFormatted("0;; currencyCode=USD", 10, "10");
- assertFormatted("0 \u00A4;; currencyCode=USD", 10, "10 $");
- assertFormatted("0 \u00A4\u00A4;; currencyCode=USD", 10, "10 USD");
- assertFormatted(Locale.GERMANY, "0 \u00A4;; currencyCode=EUR", 10, "10 \u20AC");
- assertFormatted(Locale.GERMANY, "0 \u00A4\u00A4;; currencyCode=EUR", 10, "10 EUR");
- try {
- assertFormatted("0;; currencyCode=USDX", 10, "10");
- } catch (ParseException e) {
- assertThat(e.getMessage(), containsString("ISO 4217"));
- }
- assertFormatted("0 \u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 bucks");
- // Order doesn't mater:
- assertFormatted("0 \u00A4;; currencySymbol=bucks currencyCode=USD", 10, "10 bucks");
- // International symbol isn't affected:
- assertFormatted("0 \u00A4\u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 USD");
-
- assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m", 10.5, "10m5 $");
- assertFormatted("0.0 kg;; monetaryDecimalSeparator=m", 10.5, "10.5 kg");
- assertFormatted("0.0 \u00A4;; decimalSeparator=d", 10.5, "10.5 $");
- assertFormatted("0.0 kg;; decimalSeparator=d", 10.5, "10d5 kg");
- assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10m5 $");
- assertFormatted("0.0 kg;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10d5 kg");
- }
-
- @Test
- public void testLocale() throws ParseException {
- assertEquals("1000.0", ExtendedDecimalFormatParser.parse("0.0", Locale.US).format(1000));
- assertEquals("1000,0", ExtendedDecimalFormatParser.parse("0.0", Locale.FRANCE).format(1000));
- assertEquals("1_000.0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.US).format(1000));
- assertEquals("1_000,0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.FRANCE).format(1000));
- }
-
- @Test
- public void testTemplates() throws IOException, TemplateException {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
-
- setConfiguration(cfgB.numberFormat(",000.#").build());
- assertOutput("${1000.15} ${1000.25}", "1,000.2 1,000.2");
- setConfiguration(cfgB.numberFormat(",000.#;; roundingMode=halfUp groupingSeparator=_").build());;
- assertOutput("${1000.15} ${1000.25}", "1_000.2 1_000.3");
- setConfiguration(cfgB.locale(Locale.GERMANY).build());;
- assertOutput("${1000.15} ${1000.25}", "1_000,2 1_000,3");
- setConfiguration(cfgB.locale(Locale.US).build());;
- assertOutput(
- "${1000.15}; "
- + "${1000.15?string(',##.#;;groupingSeparator=\" \"')}; "
- + "<#setting locale='de_DE'>${1000.15}; "
- + "<#setting numberFormat='0.0;;roundingMode=down'>${1000.15}",
- "1_000.2; 10 00.2; 1_000,2; 1000,1");
- assertErrorContains("${1?string('#E')}",
- TemplateException.class, "\"#E\"", "format string", "exponential");
- assertErrorContains("<#setting numberFormat='#E'>${1}",
- TemplateException.class, "\"#E\"", "format string", "exponential");
- assertErrorContains("<#setting numberFormat=';;foo=bar'>${1}",
- TemplateException.class, "\"foo\"", "supported");
- assertErrorContains("<#setting numberFormat='0;;roundingMode=unnecessary'>${1.5}",
- TemplateException.class, "can't format", "1.5", "UNNECESSARY");
- }
-
- private void assertFormatted(String formatString, Object... numberAndExpectedOutput) throws ParseException {
- assertFormatted(LOC, formatString, numberAndExpectedOutput);
- }
-
- private void assertFormatted(Locale loc, String formatString, Object... numberAndExpectedOutput) throws ParseException {
- if (numberAndExpectedOutput.length % 2 != 0) {
- throw new IllegalArgumentException();
- }
-
- DecimalFormat df = ExtendedDecimalFormatParser.parse(formatString, loc);
- Number num = null;
- for (int i = 0; i < numberAndExpectedOutput.length; i++) {
- if (i % 2 == 0) {
- num = (Number) numberAndExpectedOutput[i];
- } else {
- assertEquals(numberAndExpectedOutput[i], df.format(num));
- }
- }
- }
-
- private void assertFormatsEquivalent(DecimalFormat dfExpected, DecimalFormat dfActual) {
- for (int signum : new int[] { 1, -1 }) {
- assertFormatsEquivalent(dfExpected, dfActual, 0);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 0.5);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 0.25);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 0.125);
- assertFormatsEquivalent(dfExpected, dfActual, signum);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 10);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 100);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 1000);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 10000);
- assertFormatsEquivalent(dfExpected, dfActual, signum * 100000);
- }
- }
-
- private void assertFormatsEquivalent(DecimalFormat dfExpected, DecimalFormat dfActual, double n) {
- assertEquals(dfExpected.format(n), dfActual.format(n));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java b/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
deleted file mode 100644
index 1707756..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.dom;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.util.XMLLoader;
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public class DOMSiblingTest extends TemplateTest {
-
- @Before
- public void setUp() throws SAXException, IOException, ParserConfigurationException {
- InputSource is = new InputSource(getClass().getResourceAsStream("DOMSiblingTest.xml"));
- addToDataModel("doc", XMLLoader.toModel(is));
- }
-
- @Test
- public void testBlankPreviousSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.name?previousSibling}", "\n ");
- assertOutput("${doc.person.name?previous_sibling}", "\n ");
- }
-
- @Test
- public void testNonBlankPreviousSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.address?previousSibling}", "12th August");
- }
-
- @Test
- public void testBlankNextSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.name?nextSibling}", "\n ");
- assertOutput("${doc.person.name?next_sibling}", "\n ");
- }
-
- @Test
- public void testNonBlankNextSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.dob?nextSibling}", "Chennai, India");
- }
-
- @Test
- public void testNullPreviousSibling() throws IOException, TemplateException {
- assertOutput("${doc.person?previousSibling?? ?c}", "false");
- }
-
- @Test
- public void testSignificantPreviousSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.name.@@previous_sibling_element}", "male");
- }
-
- @Test
- public void testSignificantNextSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.name.@@next_sibling_element}", "12th August");
- }
-
- @Test
- public void testNullSignificantPreviousSibling() throws IOException, TemplateException {
- assertOutput("${doc.person.phone.@@next_sibling_element?size}", "0");
- }
-
- @Test
- public void testSkippingCommentNode() throws IOException, TemplateException {
- assertOutput("${doc.person.profession.@@previous_sibling_element}", "Chennai, India");
- }
-
- @Test
- public void testSkippingEmptyCDataNode() throws IOException, TemplateException {
- assertOutput("${doc.person.hobby.@@previous_sibling_element}", "Software Engineer");
- }
-
- @Test
- public void testValidCDataNode() throws IOException, TemplateException {
- assertOutput("${doc.person.phone.@@previous_sibling_element?size}", "0");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java b/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
deleted file mode 100644
index fec62fd..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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.dom;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.test.util.XMLLoader;
-import org.junit.Test;
-import org.w3c.dom.CDATASection;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.ProcessingInstruction;
-import org.w3c.dom.Text;
-import org.xml.sax.SAXException;
-
-public class DOMSimplifiersTest {
-
- private static final String COMMON_TEST_XML
- = "<!DOCTYPE a []><?p?><a>x<![CDATA[y]]><!--c--><?p?>z<?p?><b><!--c--></b><c></c>"
- + "<d>a<e>c</e>b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
- + "<f><![CDATA[1]]>2</f></a><!--c-->";
-
- private static final String TEXT_MERGE_CONTENT =
- "<a>"
- + "a<!--c--><s/>"
- + "<!--c-->a<s/>"
- + "a<!--c-->b<s/>"
- + "<!--c-->a<!--c-->b<!--c--><s/>"
- + "a<b>b</b>c<s/>"
- + "a<b>b</b><!--c-->c<s/>"
- + "a<!--c-->1<b>b<!--c--></b>c<!--c-->1<s/>"
- + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
- + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
- + "a<!--c-->1<b>b<!--c-->1<e>c<!--c-->1</e>d<!--c-->1</b>e<!--c-->1<s/>"
- + "</a>";
- private static final String TEXT_MERGE_EXPECTED =
- "<a>"
- + "%a<s/>"
- + "%a<s/>"
- + "%ab<s/>"
- + "%ab<s/>"
- + "%a<b>%b</b>%c<s/>"
- + "%a<b>%b</b>%c<s/>"
- + "%a1<b>%b</b>%c1<s/>"
- + "%a1<b>%bc</b>%d1<s/>"
- + "%a1<b>%bc</b>%d1<s/>"
- + "%a1<b>%b1<e>%c1</e>%d1</b>%e1<s/>"
- + "</a>";
-
- @Test
- public void testTest() throws Exception {
- String expected = "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
- + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
- + "<f><![CDATA[1]]>%2</f></a><!--c-->";
- assertEquals(expected, toString(XMLLoader.toDOM(COMMON_TEST_XML)));
- }
-
- @Test
- public void testMergeAdjacentText() throws Exception {
- Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
- NodeModel.mergeAdjacentText(dom);
- assertEquals(
- "<!DOCTYPE ...><?p?><a>%xy<!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
- + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
- + "<f><![CDATA[12]]></f></a><!--c-->",
- toString(dom));
- }
-
- @Test
- public void testRemoveComments() throws Exception {
- Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
- NodeModel.removeComments(dom);
- assertEquals(
- "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><?p?>%z<?p?><b/><c/>"
- + "<d>%a<e>%c</e>%b<?p?><?p?><?p?></d>"
- + "<f><![CDATA[1]]>%2</f></a>",
- toString(dom));
- }
-
- @Test
- public void testRemovePIs() throws Exception {
- Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
- NodeModel.removePIs(dom);
- assertEquals(
- "<!DOCTYPE ...><a>%x<![CDATA[y]]><!--c-->%z<b><!--c--></b><c/>"
- + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--></d>"
- + "<f><![CDATA[1]]>%2</f></a><!--c-->",
- toString(dom));
- }
-
- @Test
- public void testSimplify() throws Exception {
- testSimplify(
- "<!DOCTYPE ...><a>%xyz<b/><c/>"
- + "<d>%a<e>%c</e>%b</d><f><![CDATA[12]]></f></a>",
- COMMON_TEST_XML);
- }
-
- @Test
- public void testSimplify2() throws Exception {
- testSimplify(TEXT_MERGE_EXPECTED, TEXT_MERGE_CONTENT);
- }
-
- @Test
- public void testSimplify3() throws Exception {
- testSimplify("<a/>", "<a/>");
- }
-
- private void testSimplify(String expected, String content)
- throws SAXException, IOException, ParserConfigurationException {
- {
- Document dom = XMLLoader.toDOM(content);
- NodeModel.simplify(dom);
- assertEquals(expected, toString(dom));
- }
-
- // Must be equivalent:
- {
- Document dom = XMLLoader.toDOM(content);
- NodeModel.removeComments(dom);
- NodeModel.removePIs(dom);
- NodeModel.mergeAdjacentText(dom);
- assertEquals(expected, toString(dom));
- }
-
- // Must be equivalent:
- {
- Document dom = XMLLoader.toDOM(content);
- NodeModel.removeComments(dom);
- NodeModel.removePIs(dom);
- NodeModel.simplify(dom);
- assertEquals(expected, toString(dom));
- }
- }
-
- private String toString(Document doc) {
- StringBuilder sb = new StringBuilder();
- toString(doc, sb);
- return sb.toString();
- }
-
- private void toString(Node node, StringBuilder sb) {
- if (node instanceof Document) {
- childrenToString(node, sb);
- } else if (node instanceof Element) {
- if (node.hasChildNodes()) {
- sb.append("<").append(node.getNodeName()).append(">");
- childrenToString(node, sb);
- sb.append("</").append(node.getNodeName()).append(">");
- } else {
- sb.append("<").append(node.getNodeName()).append("/>");
- }
- } else if (node instanceof Text) {
- if (node instanceof CDATASection) {
- sb.append("<![CDATA[").append(node.getNodeValue()).append("]]>");
- } else {
- sb.append("%").append(node.getNodeValue());
- }
- } else if (node instanceof Comment) {
- sb.append("<!--").append(node.getNodeValue()).append("-->");
- } else if (node instanceof ProcessingInstruction) {
- sb.append("<?").append(node.getNodeName()).append("?>");
- } else if (node instanceof DocumentType) {
- sb.append("<!DOCTYPE ...>");
- } else {
- throw new IllegalStateException("Unhandled node type: " + node.getClass().getName());
- }
- }
-
- private void childrenToString(Node node, StringBuilder sb) {
- Node child = node.getFirstChild();
- while (child != null) {
- toString(child, sb);
- child = child.getNextSibling();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMTest.java b/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMTest.java
deleted file mode 100644
index e9ecf87..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/dom/DOMTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.dom;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.util.XMLLoader;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public class DOMTest extends TemplateTest {
-
- @Test
- public void xpathDetectionBugfix() throws Exception {
- addDocToDataModel("<root><a>A</a><b>B</b><c>C</c></root>");
- assertOutput("${doc.root.b['following-sibling::c']}", "C");
- assertOutput("${doc.root.b['following-sibling::*']}", "C");
- }
-
- @Test
- public void xmlnsPrefixes() throws Exception {
- addDocToDataModel("<root xmlns='http://example.com/ns1' xmlns:ns2='http://example.com/ns2'>"
- + "<a>A</a><ns2:b>B</ns2:b><c a1='1' ns2:a2='2'/></root>");
-
- String ftlHeader = "<#ftl ns_prefixes={'D':'http://example.com/ns1', 'n2':'http://example.com/ns2'}>";
-
- // @@markup:
- assertOutput("${doc.@@markup}",
- "<a:root xmlns:a=\"http://example.com/ns1\" xmlns:b=\"http://example.com/ns2\">"
- + "<a:a>A</a:a><b:b>B</b:b><a:c a1=\"1\" b:a2=\"2\" />"
- + "</a:root>");
- assertOutput(ftlHeader
- + "${doc.@@markup}",
- "<root xmlns=\"http://example.com/ns1\" xmlns:n2=\"http://example.com/ns2\">"
- + "<a>A</a><n2:b>B</n2:b><c a1=\"1\" n2:a2=\"2\" /></root>");
- assertOutput("<#ftl ns_prefixes={'D':'http://example.com/ns1'}>"
- + "${doc.@@markup}",
- "<root xmlns=\"http://example.com/ns1\" xmlns:a=\"http://example.com/ns2\">"
- + "<a>A</a><a:b>B</a:b><c a1=\"1\" a:a2=\"2\" /></root>");
-
- // When there's no matching prefix declared via the #ftl header, return null for qname:
- assertOutput("${doc?children[0].@@qname!'null'}", "null");
- assertOutput("${doc?children[0]?children[1].@@qname!'null'}", "null");
- assertOutput("${doc?children[0]?children[2]['@*'][1].@@qname!'null'}", "null");
-
- // When we have prefix declared in the #ftl header:
- assertOutput(ftlHeader + "${doc?children[0].@@qname}", "root");
- assertOutput(ftlHeader + "${doc?children[0]?children[1].@@qname}", "n2:b");
- assertOutput(ftlHeader + "${doc?children[0]?children[2].@@qname}", "c");
- assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][0].@@qname}", "a1");
- assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][1].@@qname}", "n2:a2");
- // Unfortunately these include the xmlns attributes, but that would be non-BC to fix now:
- assertThat(getOutput(ftlHeader + "${doc?children[0].@@start_tag}"), startsWith("<root"));
- assertThat(getOutput(ftlHeader + "${doc?children[0]?children[1].@@start_tag}"), startsWith("<n2:b"));
- }
-
- @Test
- public void namespaceUnaware() throws Exception {
- addNSUnawareDocToDataModel("<root><x:a>A</x:a><:>B</:><xyz::c>C</xyz::c></root>");
- assertOutput("${doc.root['x:a']}", "A");
- assertOutput("${doc.root[':']}", "B");
- try {
- assertOutput("${doc.root['xyz::c']}", "C");
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsString("xyz"));
- }
- }
-
- private void addDocToDataModel(String xml) throws SAXException, IOException, ParserConfigurationException {
- addToDataModel("doc", XMLLoader.toModel(new InputSource(new StringReader(xml))));
- }
-
- private void addDocToDataModelNoSimplification(String xml) throws SAXException, IOException, ParserConfigurationException {
- addToDataModel("doc", XMLLoader.toModel(new InputSource(new StringReader(xml)), false));
- }
-
- private void addNSUnawareDocToDataModel(String xml) throws ParserConfigurationException, SAXException, IOException {
- DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
- newFactory.setNamespaceAware(false);
- DocumentBuilder builder = newFactory.newDocumentBuilder();
- Document doc = builder.parse(new InputSource(new StringReader(xml)));
- addToDataModel("doc", doc);
- }
-
- @Test
- public void testInvalidAtAtKeyErrors() throws Exception {
- addDocToDataModel("<r><multipleMatches /><multipleMatches /></r>");
- assertErrorContains("${doc.r.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
- assertErrorContains("${doc.@@start_tag}", "@@start_tag", "not supported", "document");
- assertErrorContains("${doc.@@}", "\"@@\"", "not supported", "document");
- assertErrorContains("${doc.r.noMatch.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
- assertErrorContains("${doc.r.multipleMatches.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
- assertErrorContains("${doc.r.noMatch.@@attributes_markup}", "single XML node", "@@attributes_markup");
- assertErrorContains("${doc.r.multipleMatches.@@attributes_markup}", "single XML node", "@@attributes_markup");
- }
-
- @Test
- public void testAtAtSiblingElement() throws Exception {
- addDocToDataModel("<r><a/><b/></r>");
- assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.@@next_sibling_element?size}", "0");
- assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
- assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
- assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
-
- addDocToDataModel("<r>\r\n\t <a/>\r\n\t <b/>\r\n\t </r>");
- assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.@@next_sibling_element?size}", "0");
- assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
- assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
- assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
-
- addDocToDataModel("<r>t<a/>t<b/>t</r>");
- assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
- assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
- assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
-
- addDocToDataModelNoSimplification("<r><a/> <!-- --><?pi?> <b/></r>");
- assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
- assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
-
- addDocToDataModelNoSimplification("<r><a/> <!-- -->t<!-- --> <b/></r>");
- assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
- assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
deleted file mode 100644
index 036bace..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.Configuration;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class AutoEscapingExample extends TemplateTest {
-
- @Test
- public void testInfoBox() throws Exception {
- assertOutputForNamed("AutoEscapingExample-infoBox.ftlh");
- }
-
- @Test
- public void testCapture() throws Exception {
- assertOutputForNamed("AutoEscapingExample-capture.ftlh");
- }
-
- @Test
- public void testMarkup() throws Exception {
- assertOutputForNamed("AutoEscapingExample-markup.ftlh");
- }
-
- @Test
- public void testConvert() throws Exception {
- assertOutputForNamed("AutoEscapingExample-convert.ftlh");
- }
-
- @Test
- public void testConvert2() throws Exception {
- assertOutputForNamed("AutoEscapingExample-convert2.ftl");
- }
-
- @Test
- public void testStringLiteral() throws Exception {
- assertOutputForNamed("AutoEscapingExample-stringLiteral.ftlh");
- }
-
- @Test
- public void testStringLiteral2() throws Exception {
- assertOutputForNamed("AutoEscapingExample-stringLiteral2.ftlh");
- }
-
- @Test
- public void testStringConcat() throws Exception {
- assertOutputForNamed("AutoEscapingExample-stringConcat.ftlh");
- }
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return new TestConfigurationBuilder(AutoEscapingExample.class).build();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
deleted file mode 100644
index 40c1297..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.io.IOException;
-
-import org.apache.freemarker.core.TemplateConfiguration;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
-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.FirstMatchTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.OrMatcher;
-import org.apache.freemarker.core.templateresolver.PathGlobMatcher;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class ConfigureOutputFormatExamples extends TemplateTest {
-
- @Test
- public void test() throws Exception {
- addTemplate("mail/t.ftl", "");
- addTemplate("t.html", "");
- addTemplate("t.htm", "");
- addTemplate("t.xml", "");
- addTemplate("t.rtf", "");
-
- example2(true);
- example2(false);
- example3(true);
- example3(false);
- }
-
- private void example2(boolean javaCfg) throws IOException {
- setConfiguration(
- javaCfg
- ? new TestConfigurationBuilder()
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new PathGlobMatcher("mail/**"),
- new TemplateConfiguration.Builder()
- .outputFormat(HTMLOutputFormat.INSTANCE)
- .build()))
- .build()
- : new TestConfigurationBuilder()
- .settings(loadPropertiesFile("ConfigureOutputFormatExamples1.properties"))
- .build());
- assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("mail/t.ftl").getOutputFormat());
- }
-
- private void example3(boolean javaCfg) throws IOException {
- setConfiguration(
- javaCfg
- ? new TestConfigurationBuilder()
- .templateConfigurations(
- 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()),
- new ConditionalTemplateConfigurationFactory(
- new FileExtensionMatcher("rtf"),
- new TemplateConfiguration.Builder()
- .outputFormat(RTFOutputFormat.INSTANCE)
- .build()))
- .allowNoMatch(true))
- .build()
- : new TestConfigurationBuilder()
- .settings(loadPropertiesFile("ConfigureOutputFormatExamples2.properties"))
- .build());
- assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.html").getOutputFormat());
- assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.htm").getOutputFormat());
- assertEquals(XMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.xml").getOutputFormat());
- assertEquals(RTFOutputFormat.INSTANCE, getConfiguration().getTemplate("t.rtf").getOutputFormat());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
deleted file mode 100644
index f38bb14..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.io.IOException;
-import java.math.BigDecimal;
-import java.util.Date;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.impl.AliasTemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.impl.AliasTemplateNumberFormatFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class CustomFormatsExample extends TemplateTest {
-
- @Test
- public void aliases1() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder(this.getClass())
- .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
- "price", new AliasTemplateNumberFormatFactory(",000.00"),
- "weight", new AliasTemplateNumberFormatFactory("0.##;; roundingMode=halfUp")))
- .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
- "fileDate", new AliasTemplateDateFormatFactory("dd/MMM/yy hh:mm a"),
- "logEventTime", new AliasTemplateDateFormatFactory("iso ms u")
- ))
- .build());
-
- addToDataModel("p", 10000);
- addToDataModel("w", new BigDecimal("10.305"));
- addToDataModel("fd", new Date(1450904944213L));
- addToDataModel("let", new Date(1450904944213L));
-
- assertOutputForNamed("CustomFormatsExample-alias1.ftlh");
- }
-
- @Test
- public void aliases2() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder(this.getClass())
- .customNumberFormats(ImmutableMap.of(
- "base", BaseNTemplateNumberFormatFactory.INSTANCE,
- "oct", new AliasTemplateNumberFormatFactory("@base 8")))
- .build());
-
- assertOutputForNamed("CustomFormatsExample-alias2.ftlh");
- }
-
- @Test
- public void modelAware() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder(this.getClass())
- .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
- "ua", UnitAwareTemplateNumberFormatFactory.INSTANCE))
- .numberFormat("@ua 0.####;; roundingMode=halfUp")
- .build());
-
- addToDataModel("weight", new UnitAwareTemplateNumberModel(1.5, "kg"));
-
- assertOutputForNamed("CustomFormatsExample-modelAware.ftlh");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
deleted file mode 100644
index a676bc4..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateExceptionHandler;
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.junit.Test;
-
-public class GettingStartedExample {
-
- @Test
- public void main() throws Exception {
- /* ------------------------------------------------------------------------ */
- /* You should do this ONLY ONCE in the whole application life-cycle: */
-
- /* Create the configuration singleton (using builder pattern) */
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(new ClassTemplateLoader(GettingStartedExample.class, ""))
- .sourceEncoding(StandardCharsets.UTF_8)
- .templateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
- .logTemplateExceptions(false)
- .build();
-
- /* ------------------------------------------------------------------------ */
- /* You usually do these for MULTIPLE TIMES in the application life-cycle: */
-
- /* Create a data-model */
- Map<String, Object> root = new HashMap();
- root.put("user", "Big Joe");
- Product latest = new Product();
- latest.setUrl("products/greenmouse.html");
- latest.setName("green mouse");
- root.put("latestProduct", latest);
-
- /* Get the template (uses cache internally) */
- Template temp = cfg.getTemplate("test.ftlh");
-
- /* Merge data-model with template */
- Writer out = new OutputStreamWriter(System.out);
- temp.process(root, out);
- // Note: Depending on what `out` is, you may need to call `out.close()`.
- // This is usually the case for file output, but not for servlet output.
- }
-
-}
[21/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/DateFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/DateFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/DateFormatTest.java
deleted file mode 100644
index 4ad5937..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/DateFormatTest.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.SimpleDate;
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.userpkg.AppMetaTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.HTMLISOTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.LocAndTZSensitiveTemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateDateFormat;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.UndefinedCustomFormatException;
-import org.apache.freemarker.core.valueformat.impl.AliasTemplateDateFormatFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-public class DateFormatTest extends TemplateTest {
-
- /** 2015-09-06T12:00:00Z */
- private static long T = 1441540800000L;
- private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
-
- private TestConfigurationBuilder createConfigurationBuilder() {
- return new TestConfigurationBuilder()
- .locale(Locale.US)
- .timeZone(TimeZone.getTimeZone("GMT+01:00"))
- .sqlDateAndTimeTimeZone(TimeZone.getTimeZone("UTC"))
- .customDateFormats(ImmutableMap.of(
- "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
- "loc", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE,
- "div", EpochMillisDivTemplateDateFormatFactory.INSTANCE,
- "appMeta", AppMetaTemplateDateFormatFactory.INSTANCE,
- "htmlIso", HTMLISOTemplateDateFormatFactory.INSTANCE));
- }
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return createConfigurationBuilder().build();
- }
-
- @Test
- public void testCustomFormat() throws Exception {
- addToDataModel("d", new Date(123456789));
- assertOutput(
- "${d?string.@epoch} ${d?string.@epoch} <#setting locale='de_DE'>${d?string.@epoch}",
- "123456789 123456789 123456789");
-
- setConfigurationWithDateTimeFormat("@epoch");
- assertOutput(
- "<#assign d = d?datetime>"
- + "${d} ${d?string} <#setting locale='de_DE'>${d}",
- "123456789 123456789 123456789");
-
- setConfigurationWithDateTimeFormat("@htmlIso");
- assertOutput(
- "<#assign d = d?datetime>"
- + "${d} ${d?string} <#setting locale='de_DE'>${d}",
- "1970-01-02<span class='T'>T</span>10:17:36Z "
- + "1970-01-02T10:17:36Z "
- + "1970-01-02<span class='T'>T</span>10:17:36Z");
- }
-
- @Test
- public void testLocaleChange() throws Exception {
- addToDataModel("d", new Date(123456789));
- assertOutput(
- "${d?string.@loc} ${d?string.@loc} "
- + "<#setting locale='de_DE'>"
- + "${d?string.@loc} ${d?string.@loc} "
- + "<#setting locale='en_US'>"
- + "${d?string.@loc} ${d?string.@loc}",
- "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
- + "123456789@de_DE:GMT+01:00 123456789@de_DE:GMT+01:00 "
- + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
-
- setConfigurationWithDateTimeFormat("@loc");
- assertOutput(
- "<#assign d = d?datetime>"
- + "${d} ${d?string} "
- + "<#setting locale='de_DE'>"
- + "${d} ${d?string} "
- + "<#setting locale='en_US'>"
- + "${d} ${d?string}",
- "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
- + "123456789@de_DE:GMT+01:00 123456789@de_DE:GMT+01:00 "
- + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
- }
-
- @Test
- public void testTimeZoneChange() throws Exception {
- addToDataModel("d", new Date(123456789));
- setConfigurationWithDateTimeFormat("iso");
- assertOutput(
- "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal} "
- + "<#setting timeZone='GMT+02:00'>"
- + "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal} "
- + "<#setting timeZone='GMT+01:00'>"
- + "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal}",
- "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 1970-01-02T11:17:36+01:00 "
- + "123456789@en_US:GMT+02:00 123456789@en_US:GMT+02:00 1970-01-02T12:17:36+02:00 "
- + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 1970-01-02T11:17:36+01:00");
-
- setConfigurationWithDateTimeFormat("@loc");
- assertOutput(
- "<#assign d = d?datetime>"
- + "${d} ${d?string} "
- + "<#setting timeZone='GMT+02:00'>"
- + "${d} ${d?string} "
- + "<#setting timeZone='GMT+01:00'>"
- + "${d} ${d?string}",
- "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
- + "123456789@en_US:GMT+02:00 123456789@en_US:GMT+02:00 "
- + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
- }
-
- @Test
- public void testWrongFormatStrings() throws Exception {
- setConfigurationWithDateTimeFormat("x1");
- assertErrorContains("${.now}", "\"x1\"", "'x'");
- assertErrorContains("${.now?string}", "\"x1\"", "'x'");
- setConfigurationWithDateTimeFormat("short");
- assertErrorContains("${.now?string('x2')}", "\"x2\"", "'x'");
- assertErrorContains("${.now?string('[wrong]')}", "format string", "[wrong]");
-
- setConfiguration(createConfigurationBuilder()
- .dateFormat("[wrong d]")
- .dateTimeFormat("[wrong dt]")
- .timeFormat("[wrong t]")
- .build());
- assertErrorContains("${.now?date}", "\"date_format\"", "[wrong d]");
- assertErrorContains("${.now?datetime}", "\"datetime_format\"", "[wrong dt]");
- assertErrorContains("${.now?time}", "\"time_format\"", "[wrong t]");
- }
-
- @Test
- public void testCustomParameterized() throws Exception {
- Configuration cfg = getConfiguration();
- addToDataModel("d", new SimpleDate(new Date(12345678L), TemplateDateModel.DATETIME));
- setConfigurationWithDateTimeFormat("@div 1000");
- assertOutput("${d}", "12345");
- assertOutput("${d?string}", "12345");
- assertOutput("${d?string.@div_100}", "123456");
-
- assertErrorContains("${d?string.@div_xyz}", "\"@div_xyz\"", "\"xyz\"");
- setConfigurationWithDateTimeFormat("@div");
- assertErrorContains("${d}", "\"datetime_format\"", "\"@div\"", "format parameter is required");
- }
-
- @Test
- public void testUnknownCustomFormat() throws Exception {
- {
- setConfigurationWithDateTimeFormat("@noSuchFormat");
- Throwable exc = assertErrorContains(
- "${.now}",
- "\"@noSuchFormat\"", "\"noSuchFormat\"", "\"datetime_format\"");
- assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
-
- }
- {
- setConfiguration(createConfigurationBuilder().dateFormat("@noSuchFormatD").build());
- assertErrorContains(
- "${.now?date}",
- "\"@noSuchFormatD\"", "\"noSuchFormatD\"", "\"date_format\"");
- }
- {
- setConfiguration(createConfigurationBuilder().timeFormat("@noSuchFormatT").build());
- assertErrorContains(
- "${.now?time}",
- "\"@noSuchFormatT\"", "\"noSuchFormatT\"", "\"time_format\"");
- }
-
- {
- setConfigurationWithDateTimeFormat("");
- Throwable exc = assertErrorContains("${.now?string('@noSuchFormat2')}",
- "\"@noSuchFormat2\"", "\"noSuchFormat2\"");
- assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
- }
- }
-
- private void setConfigurationWithDateTimeFormat(String formatString) {
- setConfiguration(createConfigurationBuilder().dateTimeFormat(formatString).build());
- }
-
- @Test
- public void testNullInModel() throws Exception {
- addToDataModel("d", new MutableTemplateDateModel());
- assertErrorContains("${d}", "nothing inside it");
- assertErrorContains("${d?string}", "nothing inside it");
- }
-
- @Test
- public void testIcIAndEscaping() throws Exception {
- addToDataModel("d", new SimpleDate(new Date(12345678L), TemplateDateModel.DATETIME));
-
- setConfigurationWithDateTimeFormat("@epoch");
- assertOutput("${d}", "12345678");
- setConfigurationWithDateTimeFormat("'@'yyyy");
- assertOutput("${d}", "@1970");
- setConfigurationWithDateTimeFormat("@@yyyy");
- assertOutput("${d}", "@@1970");
-
- setConfiguration(createConfigurationBuilder()
- .customDateFormats(Collections.<String, TemplateDateFormatFactory>emptyMap())
- .dateTimeFormat("@epoch")
- .build());
- assertErrorContains("${d}", "custom", "\"epoch\"");
- }
-
- @Test
- public void testEnvironmentGetters() throws Exception {
- String dateFormatStr = "yyyy.MM.dd. (Z)";
- String timeFormatStr = "HH:mm";
- String dateTimeFormatStr = "yyyy.MM.dd. HH:mm";
-
- setConfiguration(createConfigurationBuilder()
- .dateFormat(dateFormatStr)
- .timeFormat(timeFormatStr)
- .dateTimeFormat(dateTimeFormatStr)
- .build());
-
- Configuration cfg = getConfiguration();
-
- Template t = new Template(null, "", cfg);
- Environment env = t.createProcessingEnvironment(null, null);
-
- // Test that values are coming from the cache if possible
- for (Class dateClass : new Class[] { Date.class, Timestamp.class, java.sql.Date.class, Time.class } ) {
- for (int dateType
- : new int[] { TemplateDateModel.DATE, TemplateDateModel.TIME, TemplateDateModel.DATETIME }) {
- String formatString =
- dateType == TemplateDateModel.DATE ? cfg.getDateFormat() :
- (dateType == TemplateDateModel.TIME ? cfg.getTimeFormat()
- : cfg.getDateTimeFormat());
- TemplateDateFormat expectedF = env.getTemplateDateFormat(formatString, dateType, dateClass);
- assertSame(expectedF, env.getTemplateDateFormat(dateType, dateClass)); // Note: Only reads the cache
- assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass));
- assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass, cfg.getLocale()));
- assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass, cfg.getLocale(),
- cfg.getTimeZone(), cfg.getSQLDateAndTimeTimeZone()));
- }
- }
-
- String dateFormatStr2 = dateFormatStr + "'!'";
- String timeFormatStr2 = timeFormatStr + "'!'";
- String dateTimeFormatStr2 = dateTimeFormatStr + "'!'";
-
- assertEquals("2015.09.06. 13:00",
- env.getTemplateDateFormat(TemplateDateModel.DATETIME, Date.class).formatToPlainText(TM));
- assertEquals("2015.09.06. 13:00!",
- env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Date.class).formatToPlainText(TM));
-
- assertEquals("2015.09.06. (+0100)",
- env.getTemplateDateFormat(TemplateDateModel.DATE, Date.class).formatToPlainText(TM));
- assertEquals("2015.09.06. (+0100)!",
- env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, Date.class).formatToPlainText(TM));
-
- assertEquals("13:00",
- env.getTemplateDateFormat(TemplateDateModel.TIME, Date.class).formatToPlainText(TM));
- assertEquals("13:00!",
- env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Date.class).formatToPlainText(TM));
-
- assertEquals("2015.09.06. 13:00",
- env.getTemplateDateFormat(TemplateDateModel.DATETIME, Timestamp.class).formatToPlainText(TM));
- assertEquals("2015.09.06. 13:00!",
- env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Timestamp.class).formatToPlainText(TM));
-
- assertEquals("2015.09.06. (+0000)",
- env.getTemplateDateFormat(TemplateDateModel.DATE, java.sql.Date.class).formatToPlainText(TM));
- assertEquals("2015.09.06. (+0000)!",
- env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, java.sql.Date.class).formatToPlainText(TM));
-
- assertEquals("12:00",
- env.getTemplateDateFormat(TemplateDateModel.TIME, Time.class).formatToPlainText(TM));
- assertEquals("12:00!",
- env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Time.class).formatToPlainText(TM));
-
- {
- String dateTimeFormatStrLoc = dateTimeFormatStr + " EEEE";
- // Gets into cache:
- TemplateDateFormat format1
- = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
- assertEquals("2015.09.06. 13:00 Sunday", format1.formatToPlainText(TM));
- // Different locale (not cached):
- assertEquals("2015.09.06. 13:00 Sonntag",
- env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
- Locale.GERMANY).formatToPlainText(TM));
- // Different locale and zone (not cached):
- assertEquals("2015.09.06. 14:00 Sonntag",
- env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
- Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToPlainText(TM));
- // Different locale and zone (not cached):
- assertEquals("2015.09.06. 15:00 Sonntag",
- env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, java.sql.Date.class,
- Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToPlainText(TM));
- // Check for corrupted cache:
- TemplateDateFormat format2
- = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
- assertEquals("2015.09.06. 13:00 Sunday", format2.formatToPlainText(TM));
- assertSame(format1, format2);
- }
- }
-
- @Test
- public void testAliases() throws Exception {
- setConfiguration(createConfigurationBuilder()
- .customDateFormats(ImmutableMap.of(
- "d", new AliasTemplateDateFormatFactory("yyyy-MMM-dd"),
- "m", new AliasTemplateDateFormatFactory("yyyy-MMM"),
- "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE))
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*2*"),
- new TemplateConfiguration.Builder()
- .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
- "m", new AliasTemplateDateFormatFactory("yyyy-MMMM"),
- "i", new AliasTemplateDateFormatFactory("@epoch")))
- .build()))
- .build());
-
- addToDataModel("d", TM);
- String commonFtl = "${d?string.@d} ${d?string.@m} "
- + "<#setting locale='fr_FR'>${d?string.@m} "
- + "<#attempt>${d?string.@i}<#recover>E</#attempt>";
- addTemplate("t1.ftl", commonFtl);
- addTemplate("t2.ftl", commonFtl);
-
- // 2015-09-06T12:00:00Z
- assertOutputForNamed("t1.ftl", "2015-Sep-06 2015-Sep 2015-sept. E");
- assertOutputForNamed("t2.ftl", "2015-Sep-06 2015-September 2015-septembre " + T);
- }
-
- @Test
- public void testAliases2() throws Exception {
- setConfiguration(
- createConfigurationBuilder()
- .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
- "d", new AliasTemplateDateFormatFactory("yyyy-MMM",
- ImmutableMap.of(
- new Locale("en"), "yyyy-MMM'_en'",
- Locale.UK, "yyyy-MMM'_en_GB'",
- Locale.FRANCE, "yyyy-MMM'_fr_FR'"))))
- .dateTimeFormat("@d")
- .build());
- addToDataModel("d", TM);
- assertOutput(
- "<#setting locale='en_US'>${d} "
- + "<#setting locale='en_GB'>${d} "
- + "<#setting locale='en_GB_Win'>${d} "
- + "<#setting locale='fr_FR'>${d} "
- + "<#setting locale='hu_HU'>${d}",
- "2015-Sep_en 2015-Sep_en_GB 2015-Sep_en_GB 2015-sept._fr_FR 2015-szept.");
- }
-
- /**
- * ?date() and such are new in 2.3.24.
- */
- @Test
- public void testZeroArgDateBI() throws IOException, TemplateException {
- setConfiguration(
- createConfigurationBuilder()
- .dateFormat("@epoch")
- .dateTimeFormat("@epoch")
- .timeFormat("@epoch")
- .build());
-
- addToDataModel("t", String.valueOf(T));
-
- assertOutput(
- "${t?date?string.xs_u} ${t?date()?string.xs_u}",
- "2015-09-06Z 2015-09-06Z");
- assertOutput(
- "${t?time?string.xs_u} ${t?time()?string.xs_u}",
- "12:00:00Z 12:00:00Z");
- assertOutput(
- "${t?datetime?string.xs_u} ${t?datetime()?string.xs_u}",
- "2015-09-06T12:00:00Z 2015-09-06T12:00:00Z");
- }
-
- @Test
- public void testAppMetaRoundtrip() throws IOException, TemplateException {
- setConfiguration(
- createConfigurationBuilder()
- .dateFormat("@appMeta")
- .dateTimeFormat("@appMeta")
- .timeFormat("@appMeta")
- .build());
-
- addToDataModel("t", String.valueOf(T) + "/foo");
-
- assertOutput(
- "${t?date} ${t?date()}",
- T + " " + T + "/foo");
- assertOutput(
- "${t?time} ${t?time()}",
- T + " " + T + "/foo");
- assertOutput(
- "${t?datetime} ${t?datetime()}",
- T + " " + T + "/foo");
- }
-
- @Test
- public void testUnknownDateType() throws IOException, TemplateException {
- addToDataModel("u", new Date(T));
- assertErrorContains("${u?string}", "isn't known");
- assertOutput("${u?string('yyyy')}", "2015");
- assertOutput("<#assign s = u?string>${s('yyyy')}", "2015");
- }
-
- private static class MutableTemplateDateModel implements TemplateDateModel {
-
- private Date date;
-
- public void setDate(Date date) {
- this.date = date;
- }
-
- @Override
- public Date getAsDate() throws TemplateModelException {
- return date;
- }
-
- @Override
- public int getDateType() {
- return DATETIME;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
deleted file mode 100644
index 29220c4..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.util.ObjectFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class DirectiveCallPlaceTest extends TemplateTest {
-
- @Test
- public void testCustomDataBasics() throws IOException, TemplateException {
- addTemplate(
- "customDataBasics.ftl",
- "<@u...@uc> <@u...@uc> <@uc>Ab<#-- -->c</...@uc> <@l...@lc> <@l...@lc>");
-
- CachingTextConverterDirective.resetCacheRecreationCount();
- for (int i = 0; i < 3; i++) {
- assertOutputForNamed(
- "customDataBasics.ftl",
- "ABC[cached 1] X=123 ABC[cached 2] abc[cached 3]");
- }
- }
-
- @Test
- public void testCustomDataProviderMismatch() throws IOException, TemplateException {
- addTemplate(
- "customDataProviderMismatch.ftl",
- "<#list [uc, lc, uc] as d><#list 1..2 as _><@d...@d></#list></#list>");
-
- CachingTextConverterDirective.resetCacheRecreationCount();
- assertOutputForNamed(
- "customDataProviderMismatch.ftl",
- "ABC[cached 1]ABC[cached 1]abc[cached 2]abc[cached 2]ABC[cached 3]ABC[cached 3]");
- assertOutputForNamed(
- "customDataProviderMismatch.ftl",
- "ABC[cached 3]ABC[cached 3]abc[cached 4]abc[cached 4]ABC[cached 5]ABC[cached 5]");
- }
-
- @Test
- public void testPositions() throws IOException, TemplateException {
- addTemplate(
- "positions.ftl",
- "<@pa />\n"
- + "..<@pa\n"
- + "/><@pa>xxx</@>\n"
- + "<@pa>{<@pa/> <@pa/>}</@>\n"
- + "${curDirLine}<@argP p=curDirLine?string>${curDirLine}</...@argP>${curDirLine}\n"
- + "<#macro m p>(p=${p}){<#nested>}</#macro>\n"
- + "${curDirLine}<@m p=curDirLine?string>${curDirLine}</...@m>${curDirLine}");
-
- assertOutputForNamed(
- "positions.ftl",
- "[positions.ftl:1:1-1:7]"
- + "..[positions.ftl:2:3-3:2]"
- + "[positions.ftl:3:3-3:14]xxx\n"
- + "[positions.ftl:4:1-4:24]{[positions.ftl:4:7-4:12] [positions.ftl:4:14-4:19]}\n"
- + "-(p=5){-}-\n"
- + "-(p=7){-}-"
- );
- }
-
- @SuppressWarnings("boxing")
- @Override
- protected Object createDataModel() {
- Map<String, Object> dm = new HashMap<>();
- dm.put("uc", new CachingUpperCaseDirective());
- dm.put("lc", new CachingLowerCaseDirective());
- dm.put("pa", new PositionAwareDirective());
- dm.put("argP", new ArgPrinterDirective());
- dm.put("curDirLine", new CurDirLineScalar());
- dm.put("x", 123);
- return dm;
- }
-
- private abstract static class CachingTextConverterDirective implements TemplateDirectiveModel {
-
- /** Only needed for testing. */
- private static AtomicInteger cacheRecreationCount = new AtomicInteger();
-
- /** Only needed for testing. */
- static void resetCacheRecreationCount() {
- cacheRecreationCount.set(0);
- }
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, final TemplateDirectiveBody body)
- throws TemplateException, IOException {
- if (body == null) {
- return;
- }
-
- final String convertedText;
-
- final DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
- if (callPlace.isNestedOutputCacheable()) {
- try {
- convertedText = (String) callPlace.getOrCreateCustomData(
- getTextConversionIdentity(), new ObjectFactory<String>() {
-
- @Override
- public String createObject() throws TemplateException, IOException {
- return convertBodyText(body)
- + "[cached " + cacheRecreationCount.incrementAndGet() + "]";
- }
-
- });
- } catch (CallPlaceCustomDataInitializationException e) {
- throw new TemplateModelException("Failed to pre-render nested content", e);
- }
- } else {
- convertedText = convertBodyText(body);
- }
-
- env.getOut().write(convertedText);
- }
-
- protected abstract Class getTextConversionIdentity();
-
- private String convertBodyText(TemplateDirectiveBody body) throws TemplateException,
- IOException {
- StringWriter sw = new StringWriter();
- body.render(sw);
- return convertText(sw.toString());
- }
-
- protected abstract String convertText(String s);
-
- }
-
- private static class CachingUpperCaseDirective extends CachingTextConverterDirective {
-
- @Override
- protected String convertText(String s) {
- return s.toUpperCase();
- }
-
- @Override
- protected Class getTextConversionIdentity() {
- return CachingUpperCaseDirective.class;
- }
-
- }
-
- private static class CachingLowerCaseDirective extends CachingTextConverterDirective {
-
- @Override
- protected String convertText(String s) {
- return s.toLowerCase();
- }
-
- @Override
- protected Class getTextConversionIdentity() {
- return CachingLowerCaseDirective.class;
- }
-
- }
-
- private static class PositionAwareDirective implements TemplateDirectiveModel {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- Writer out = env.getOut();
- DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
- out.write("[");
- out.write(getTemplateSourceName(callPlace));
- out.write(":");
- out.write(Integer.toString(callPlace.getBeginLine()));
- out.write(":");
- out.write(Integer.toString(callPlace.getBeginColumn()));
- out.write("-");
- out.write(Integer.toString(callPlace.getEndLine()));
- out.write(":");
- out.write(Integer.toString(callPlace.getEndColumn()));
- out.write("]");
- if (body != null) {
- body.render(out);
- }
- }
-
- private String getTemplateSourceName(DirectiveCallPlace callPlace) {
- return ((ASTDirUserDefined) callPlace).getTemplate().getSourceName();
- }
-
- }
-
- private static class ArgPrinterDirective implements TemplateDirectiveModel {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- final Writer out = env.getOut();
- if (params.size() > 0) {
- out.write("(p=");
- out.write(((TemplateScalarModel) params.get("p")).getAsString());
- out.write(")");
- }
- if (body != null) {
- out.write("{");
- body.render(out);
- out.write("}");
- }
- }
-
- }
-
- private static class CurDirLineScalar implements TemplateScalarModel {
-
- @Override
- public String getAsString() throws TemplateModelException {
- DirectiveCallPlace callPlace = Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace();
- return callPlace != null
- ? String.valueOf(Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace().getBeginLine())
- : "-";
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java
deleted file mode 100644
index b1acead..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.junit.Test;
-
-public class EncodingOverrideTest {
-
- @Test
- public void testMarchingCharset() throws Exception {
- Template t = createConfig(StandardCharsets.UTF_8).getTemplate("encodingOverride-UTF-8.ftl");
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- checkTemplateOutput(t);
- }
-
- @Test
- public void testDifferentCharset() throws Exception {
- Template t = createConfig(StandardCharsets.UTF_8).getTemplate("encodingOverride-ISO-8859-1.ftl");
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- checkTemplateOutput(t);
- }
-
- private void checkTemplateOutput(Template t) throws TemplateException, IOException {
- StringWriter out = new StringWriter();
- t.process(Collections.emptyMap(), out);
- assertEquals("Béka", out.toString());
- }
-
- private Configuration createConfig(Charset charset) {
- return new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(new ClassTemplateLoader(EncodingOverrideTest.class, ""))
- .sourceEncoding(charset)
- .build();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
deleted file mode 100644
index b79559c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class EnvironmentGetTemplateVariantsTest extends TemplateTest {
-
- private static final StringTemplateLoader TEMPLATES = new StringTemplateLoader();
- static {
- TEMPLATES.putTemplate("main",
- "<@tNames />\n"
- + "---1---\n"
- + "[imp: <#import 'imp' as i>${i.impIni}]\n"
- + "---2---\n"
- + "<@i.impM>"
- + "<@tNames />"
- + "</@>\n"
- + "---3---\n"
- + "[inc: <#include 'inc'>]\n"
- + "---4---\n"
- + "<@incM>"
- + "<@tNames />"
- + "</@>\n"
- + "---5---\n"
- + "[inc2: <#include 'inc2'>]\n"
- + "---6---\n"
- + "<#import 'imp2' as i2>"
- + "<@i.impM2><@tNames /></@>\n"
- + "---7---\n"
- + "<#macro mainM>"
- + "[mainM: <@tNames /> {<#nested>} <@tNames />]"
- + "</#macro>"
- + "[inc3: <#include 'inc3'>]\n"
- + "<@mainM><@tNames /> <#include 'inc4'> <@tNames /></@>\n"
- + "<@tNames />\n"
- + "---8---\n"
- + "<#function mainF>"
- + "<@tNames />"
- + "<#return lastTNamesResult>"
- + "</#function>"
- + "mainF: ${mainF()}, impF: ${i.impF()}, incF: ${incF()}\n"
- );
- TEMPLATES.putTemplate("inc",
- "<@tNames />\n"
- + "<#macro incM>"
- + "[incM: <@tNames /> {<#nested>}]"
- + "</#macro>"
- + "<#function incF>"
- + "<@tNames />"
- + "<#return lastTNamesResult>"
- + "</#function>"
- + "<@incM><@tNames /></@>\n"
- + "<#if !included!false>[incInc: <#assign included=true><#include 'inc'>]\n</#if>"
- );
- TEMPLATES.putTemplate("imp",
- "<#assign impIni><@tNames /></#assign>\n"
- + "<#macro impM>"
- + "[impM: <@tNames />\n"
- + "{<#nested>}\n"
- + "[inc: <#include 'inc'>]\n"
- + "<@incM><@tNames /></@>\n"
- + "]"
- + "</#macro>"
- + "<#macro impM2>"
- + "[impM2: <@tNames />\n"
- + "{<#nested>}\n"
- + "<@i2.imp2M><@tNames /></@>\n"
- + "]"
- + "</#macro>"
- + "<#function impF>"
- + "<@tNames />"
- + "<#return lastTNamesResult>"
- + "</#function>"
- );
- TEMPLATES.putTemplate("inc2",
- "<@tNames />\n"
- + "<@i.impM><@tNames /></@>\n"
- );
- TEMPLATES.putTemplate("imp2",
- "<#macro imp2M>"
- + "[imp2M: <@tNames /> {<#nested>}]"
- + "</#macro>");
- TEMPLATES.putTemplate("inc3",
- "<@tNames />\n"
- + "<@mainM><@tNames /></@>\n"
- );
- TEMPLATES.putTemplate("inc4",
- "<@tNames />"
- );
- }
-
- @Test
- public void test() throws IOException, TemplateException {
- setConfiguration(createConfiguration(Configuration.VERSION_3_0_0));
- assertOutputForNamed(
- "main",
- "<ct=main mt=main>\n"
- + "---1---\n"
- + "[imp: <ct=imp mt=main>]\n"
- + "---2---\n"
- + "[impM: <ct=imp mt=main>\n"
- + "{<ct=main mt=main>}\n"
- + "[inc: <ct=inc mt=main>\n"
- + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
- + "[incInc: <ct=inc mt=main>\n"
- + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
- + "]\n"
- + "]\n"
- + "[incM: <ct=inc mt=main> {<ct=imp mt=main>}]\n"
- + "]\n"
- + "---3---\n"
- + "[inc: <ct=inc mt=main>\n"
- + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
- + "[incInc: <ct=inc mt=main>\n"
- + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
- + "]\n"
- + "]\n"
- + "---4---\n"
- + "[incM: <ct=inc mt=main> {<ct=main mt=main>}]\n"
- + "---5---\n"
- + "[inc2: <ct=inc2 mt=main>\n"
- + "[impM: <ct=imp mt=main>\n"
- + "{<ct=inc2 mt=main>}\n"
- + "[inc: <ct=inc mt=main>\n"
- + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
- + "]\n"
- + "[incM: <ct=inc mt=main> {<ct=imp mt=main>}]\n"
- + "]\n"
- + "]\n"
- + "---6---\n"
- + "[impM2: <ct=imp mt=main>\n"
- + "{<ct=main mt=main>}\n"
- + "[imp2M: <ct=imp2 mt=main> {<ct=imp mt=main>}]\n"
- + "]\n"
- + "---7---\n"
- + "[inc3: <ct=inc3 mt=main>\n"
- + "[mainM: <ct=main mt=main> {<ct=inc3 mt=main>} <ct=main mt=main>]\n"
- + "]\n"
- + "[mainM: "
- + "<ct=main mt=main> "
- + "{<ct=main mt=main> <ct=inc4 mt=main> <ct=main mt=main>} "
- + "<ct=main mt=main>"
- + "]\n"
- + "<ct=main mt=main>\n"
- + "---8---\n"
- + "mainF: <ct=main mt=main>, impF: <ct=imp mt=main>, incF: <ct=inc mt=main>\n"
- .replaceAll("<t=\\w+", "<t=main"));
- }
-
- @Test
- public void testNotStarted() throws IOException, TemplateException {
- Template t = new Template("foo", "", createConfiguration(Configuration.VERSION_3_0_0));
- final Environment env = t.createProcessingEnvironment(null, null);
- assertSame(t, env.getMainTemplate());
- assertSame(t, env.getCurrentTemplate());
- }
-
- private Configuration createConfiguration(Version iciVersion) {
- return new TestConfigurationBuilder(iciVersion)
- .templateLoader(TEMPLATES)
- .whitespaceStripping(false)
- .build();
- }
-
- @Override
- protected Object createDataModel() {
- return Collections.singletonMap("tNames", new TemplateDirectiveModel() {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- Writer out = env.getOut();
- final String r = "<ct=" + env.getCurrentTemplate().getLookupName() + " mt="
- + env.getMainTemplate().getLookupName() + ">";
- out.write(r);
- env.setGlobalVariable("lastTNamesResult", new SimpleScalar(r));
- }
-
- });
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ExceptionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ExceptionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ExceptionTest.java
deleted file mode 100644
index 19c3b6e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ExceptionTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Collections;
-import java.util.Locale;
-
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.core.util._NullWriter;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-
-import junit.framework.TestCase;
-public class ExceptionTest extends TestCase {
-
- public ExceptionTest(String name) {
- super(name);
- }
-
- public void testParseExceptionSerializable() throws IOException, ClassNotFoundException {
- try {
- new Template(null, new StringReader("<@>"), new TestConfigurationBuilder().build());
- fail();
- } catch (ParseException e) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- new ObjectOutputStream(out).writeObject(e);
- new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
- }
- }
-
- public void testTemplateErrorSerializable() throws IOException, ClassNotFoundException {
- Template tmp = new Template(null, new StringReader("${noSuchVar}"),
- new TestConfigurationBuilder().build());
- try {
- tmp.process(Collections.EMPTY_MAP, new StringWriter());
- fail();
- } catch (TemplateException e) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- new ObjectOutputStream(out).writeObject(e);
- new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
- }
- }
-
- @SuppressWarnings("boxing")
- public void testTemplateExceptionLocationInformation() throws IOException {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("foo_en.ftl", "\n\nxxx${noSuchVariable}");
-
- Template t = new TestConfigurationBuilder().templateLoader(tl).build()
- .getTemplate("foo.ftl", Locale.US);
- try {
- t.process(null, _NullWriter.INSTANCE);
- fail();
- } catch (TemplateException e) {
- assertEquals("foo.ftl", t.getLookupName());
- assertEquals("foo.ftl", e.getTemplateLookupName());
- assertEquals("foo_en.ftl", e.getTemplateSourceName());
- assertEquals(3, (int) e.getLineNumber());
- assertEquals(6, (int) e.getColumnNumber());
- assertEquals(3, (int) e.getEndLineNumber());
- assertEquals(19, (int) e.getEndColumnNumber());
- assertThat(e.getMessage(), containsString("foo_en.ftl"));
- assertThat(e.getMessage(), containsString("noSuchVariable"));
- }
- }
-
- @SuppressWarnings("cast")
- public void testParseExceptionLocationInformation() throws IOException {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("foo_en.ftl", "\n\nxxx<#noSuchDirective>");
-
- try {
- new TestConfigurationBuilder().templateLoader(tl).build()
- .getTemplate("foo.ftl", Locale.US);
- fail();
- } catch (ParseException e) {
- System.out.println(e.getMessage());
- assertEquals("foo_en.ftl", e.getTemplateSourceName());
- assertEquals("foo.ftl", e.getTemplateLookupName());
- assertEquals(3, e.getLineNumber());
- assertEquals(5, e.getColumnNumber());
- assertEquals(3, e.getEndLineNumber());
- assertEquals(20, e.getEndColumnNumber());
- assertThat(e.getMessage(), containsString("foo_en.ftl"));
- assertThat(e.getMessage(), containsString("noSuchDirective"));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/GetSourceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/GetSourceTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/GetSourceTest.java
deleted file mode 100644
index 1462bfc..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/GetSourceTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class GetSourceTest {
-
- @Test
- public void testGetSource() throws Exception {
- {
- // Note: Default tab size is 8.
- Template t = new Template(null, "a\n\tb\nc",
- new TestConfigurationBuilder().build());
- // A historical quirk we keep for B.C.: it repaces tabs with spaces.
- assertEquals("a\n b\nc", t.getSource(1, 1, 1, 3));
- }
-
- {
- Template t = new Template(null, "a\n\tb\nc",
- new TestConfigurationBuilder().tabSize(4).build());
- assertEquals("a\n b\nc", t.getSource(1, 1, 1, 3));
- }
-
- {
- Template t = new Template(null, "a\n\tb\nc",
- new TestConfigurationBuilder().tabSize(1).build());
- // If tab size is 1, it behaves as it always should have: it keeps the tab.
- assertEquals("a\n\tb\nc", t.getSource(1, 1, 1, 3));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
deleted file mode 100644
index 6f8851d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class HeaderParsingTest extends TemplateTest {
-
- private final Configuration cfgStripWS = new TestConfigurationBuilder().build();
- private final Configuration cfgNoStripWS = new TestConfigurationBuilder().whitespaceStripping(false).build();
-
- @Test
- public void test() throws IOException, TemplateException {
- assertOutput("<#ftl>text", "text", "text");
- assertOutput(" <#ftl> text", " text", " text");
- assertOutput("\n<#ftl>\ntext", "text", "text");
- assertOutput("\n \n\n<#ftl> \ntext", "text", "text");
- assertOutput("\n \n\n<#ftl>\n\ntext", "\ntext", "\ntext");
- }
-
- private void assertOutput(final String ftl, String expectedOutStripped, String expectedOutNonStripped)
- throws IOException, TemplateException {
- for (int i = 0; i < 4; i++) {
- String ftlPermutation = ftl;
- if ((i & 1) == 1) {
- ftlPermutation = ftlPermutation.replace("<#ftl>", "<#ftl encoding='utf-8'>");
- }
- if ((i & 2) == 2) {
- ftlPermutation = ftlPermutation.replace('<', '[').replace('>', ']');
- }
-
- setConfiguration(cfgStripWS);
- assertOutput(ftlPermutation, expectedOutStripped);
- setConfiguration(cfgNoStripWS);
- assertOutput(ftlPermutation, expectedOutNonStripped);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
deleted file mode 100644
index 738b4de..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class IncludeAndImportConfigurableLayersTest {
-
- @Test
- public void test3LayerImportNoClashes() throws Exception {
- TestConfigurationBuilder cfgB = createConfigurationBuilder()
- .autoImports(ImmutableMap.of("t1", "t1.ftl"))
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("main.ftl"),
- new TemplateConfiguration.Builder()
- .autoImports(ImmutableMap.of("t2", "t2.ftl"))
- .build()));
- Configuration cfg = cfgB.build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoImport("t3", "t3.ftl");
-
- env.process();
- assertEquals("In main: t1;t2;t3;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
-
- env.process();
- assertEquals("In main: t1;t2;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main2.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoImport("t3", "t3.ftl");
-
- env.process();
- assertEquals("In main2: t1;t3;", sw.toString());
- }
-
- cfgB.removeAutoImport("t1");
- cfg = cfgB.build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoImport("t3", "t3.ftl");
-
- env.process();
- assertEquals("In main: t2;t3;", sw.toString());
- }
- }
-
- @Test
- public void test3LayerImportClashes() throws Exception {
- Configuration cfg = createConfigurationBuilder()
- .autoImports(ImmutableMap.of(
- "t1", "t1.ftl",
- "t2", "t2.ftl",
- "t3", "t3.ftl"))
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("main.ftl"),
- new TemplateConfiguration.Builder()
- .autoImports(ImmutableMap.of("t2", "t2b.ftl"))
- .build()))
- .build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoImport("t3", "t3b.ftl");
-
- env.process();
- assertEquals("In main: t1;t2b;t3b;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main2.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoImport("t3", "t3b.ftl");
-
- env.process();
- assertEquals("In main2: t1;t2;t3b;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
-
- env.process();
- assertEquals("In main: t1;t3;t2b;", sw.toString());
- }
- }
-
- @Test
- public void test3LayerIncludesNoClashes() throws Exception {
- TestConfigurationBuilder cfgB = createConfigurationBuilder()
- .autoIncludes(ImmutableList.of("t1.ftl"))
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("main.ftl"),
- new TemplateConfiguration.Builder()
- .autoIncludes(ImmutableList.of("t2.ftl"))
- .build()));
-
- Configuration cfg = cfgB.build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
-
- env.process();
- assertEquals("T1;T2;T3;In main: t1;t2;t3;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
-
- env.process();
- assertEquals("T1;T2;In main: t1;t2;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main2.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
-
- env.process();
- assertEquals("T1;T3;In main2: t1;t3;", sw.toString());
- }
-
- cfgB.removeAutoInclude("t1.ftl");
- cfg = cfgB.build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
-
- env.process();
- assertEquals("T2;T3;In main: t2;t3;", sw.toString());
- }
- }
-
- @Test
- public void test3LayerIncludeClashes() throws Exception {
- Configuration cfg = createConfigurationBuilder()
- .autoIncludes(ImmutableList.of(
- "t1.ftl",
- "t2.ftl",
- "t3.ftl"))
- .templateConfigurations(new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("main.ftl"),
- new TemplateConfiguration.Builder()
- .autoIncludes(ImmutableList.of("t2.ftl"))
- .build()))
- .build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
-
- env.process();
- assertEquals("T1;T2;T3;In main: t1;t2;t3;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main2.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
-
- env.process();
- assertEquals("T1;T2;T3;In main2: t1;t2;t3;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
-
- env.process();
- assertEquals("T1;T3;T2;In main: t1;t3;t2;", sw.toString());
- }
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t1.ftl");
-
- env.process();
- assertEquals("T3;T2;T1;In main: t3;t2;t1;", sw.toString());
- }
- }
-
- @Test
- public void test3LayerIncludesClashes2() throws Exception {
- Configuration cfg = createConfigurationBuilder()
- .autoIncludes(ImmutableList.of("t1.ftl", "t1.ftl"))
- .templateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("main.ftl"),
- new TemplateConfiguration.Builder()
- .autoIncludes(ImmutableList.of("t2.ftl", "t2.ftl"))
- .build()))
- .build();
-
- {
- Template t = cfg.getTemplate("main.ftl");
- StringWriter sw = new StringWriter();
- Environment env = t.createProcessingEnvironment(null, sw);
- env.addAutoInclude("t3.ftl");
- env.addAutoInclude("t3.ftl");
- env.addAutoInclude("t1.ftl");
- env.addAutoInclude("t1.ftl");
-
- env.process();
- assertEquals("T2;T3;T1;In main: t2;t3;t1;", sw.toString());
- }
- }
-
- @Test
- public void test3LayerLaziness() throws Exception {
- for (Class<?> layer : new Class<?>[] { Configuration.class, Template.class, Environment.class }) {
- test3LayerLaziness(layer, null, null, false, "t1;t2;");
- test3LayerLaziness(layer, null, null, true, "t1;t2;");
- test3LayerLaziness(layer, null, false, true, "t1;t2;");
- test3LayerLaziness(layer, null, true, true, "t2;");
-
- test3LayerLaziness(layer, false, null, false, "t1;t2;");
- test3LayerLaziness(layer, false, null, true, "t1;t2;");
- test3LayerLaziness(layer, false, false, true, "t1;t2;");
- test3LayerLaziness(layer, false, true, true, "t2;");
-
- test3LayerLaziness(layer, true, null, false, "");
- test3LayerLaziness(layer, true, null, true, "");
- test3LayerLaziness(layer, true, false, true, "t1;");
- test3LayerLaziness(layer, true, true, true, "");
- }
- }
-
- private void test3LayerLaziness(
- Class<?> layer,
- Boolean lazyImports,
- Boolean lazyAutoImports, boolean setLazyAutoImports,
- String expectedOutput)
- throws Exception {
- Configuration cfg;
- {
- TestConfigurationBuilder cfgB = createConfigurationBuilder()
- .autoImports(ImmutableMap.of("t1", "t1.ftl"));
- if (layer == Configuration.class) {
- setLazinessOfConfigurable(cfgB, lazyImports, lazyAutoImports, setLazyAutoImports);
- }
- cfg = cfgB.build();
- }
-
- TemplateConfiguration tc;
- if (layer == Template.class) {
- TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
- setLazinessOfConfigurable(tcb, lazyImports, lazyAutoImports, setLazyAutoImports);
- tc = tcb.build();
- } else {
- tc = null;
- }
-
- Template t = new Template(null, "<#import 't2.ftl' as t2>${loaded!}", cfg, tc);
- StringWriter sw = new StringWriter();
-
- Environment env = t.createProcessingEnvironment(null, sw);
- if (layer == Environment.class) {
- setLazinessOfConfigurable(env, lazyImports, lazyAutoImports, setLazyAutoImports);
- }
-
- env.process();
- assertEquals(expectedOutput, sw.toString());
- }
-
- private void setLazinessOfConfigurable(
- MutableProcessingConfiguration<?> cfg,
- Boolean lazyImports, Boolean lazyAutoImports, boolean setLazyAutoImports) {
- if (lazyImports != null) {
- cfg.setLazyImports(lazyImports);
- }
- if (setLazyAutoImports) {
- cfg.setLazyAutoImports(lazyAutoImports);
- }
- }
-
- private TestConfigurationBuilder createConfigurationBuilder() {
- StringTemplateLoader loader = new StringTemplateLoader();
- loader.putTemplate("main.ftl", "In main: ${loaded}");
- loader.putTemplate("main2.ftl", "In main2: ${loaded}");
- loader.putTemplate("t1.ftl", "<#global loaded = (loaded!) + 't1;'>T1;");
- loader.putTemplate("t2.ftl", "<#global loaded = (loaded!) + 't2;'>T2;");
- loader.putTemplate("t3.ftl", "<#global loaded = (loaded!) + 't3;'>T3;");
- loader.putTemplate("t1b.ftl", "<#global loaded = (loaded!) + 't1b;'>T1b;");
- loader.putTemplate("t2b.ftl", "<#global loaded = (loaded!) + 't2b;'>T2b;");
- loader.putTemplate("t3b.ftl", "<#global loaded = (loaded!) + 't3b;'>T3b;");
-
- return new TestConfigurationBuilder().templateLoader(loader);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
deleted file mode 100644
index fa767ff..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.apache.freemarker.core.Environment.LazilyInitializedNamespace;
-import org.apache.freemarker.core.Environment.Namespace;
-import org.apache.freemarker.core.model.WrappingTemplateModel;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class IncludeAndImportTest extends TemplateTest {
-
- @Override
- protected void addCommonTemplates() {
- addTemplate("inc1.ftl", "[inc1]<#global inc1Cnt = (inc1Cnt!0) + 1><#global history = (history!) + 'I'>");
- addTemplate("inc2.ftl", "[inc2]");
- addTemplate("inc3.ftl", "[inc3]");
- addTemplate("lib1.ftl", "<#global lib1Cnt = (lib1Cnt!0) + 1><#global history = (history!) + 'L1'>"
- + "<#macro m>In lib1</#macro>");
- addTemplate("lib2.ftl", "<#global history = (history!) + 'L2'>"
- + "<#macro m>In lib2</#macro>");
- addTemplate("lib3.ftl", "<#global history = (history!) + 'L3'>"
- + "<#macro m>In lib3</#macro>");
-
- addTemplate("lib2CallsLib1.ftl", "<#global history = (history!) + 'L2'>"
- + "<#macro m>In lib2 (<@lib1.m/>)</#macro>");
- addTemplate("lib3ImportsLib1.ftl", "<#import 'lib1.ftl' as lib1><#global history = (history!) + 'L3'>"
- + "<#macro m>In lib3 (<@lib1.m/>)</#macro>");
-
- addTemplate("lib_de.ftl", "<#global history = (history!) + 'LDe'><#assign initLocale=.locale>"
- + "<#macro m>de</#macro>");
- addTemplate("lib_en.ftl", "<#global history = (history!) + 'LEn'><#assign initLocale=.locale>"
- + "<#macro m>en</#macro>");
- }
-
- @Test
- public void includeSameTwice() throws IOException, TemplateException {
- assertOutput("<#include 'inc1.ftl'>${inc1Cnt}<#include 'inc1.ftl'>${inc1Cnt}", "[inc1]1[inc1]2");
- }
-
- @Test
- public void importSameTwice() throws IOException, TemplateException {
- assertOutput("<#import 'lib1.ftl' as i1>${lib1Cnt} <#import 'lib1.ftl' as i2>${lib1Cnt}", "1 1");
- }
-
- @Test
- public void importInMainCreatesGlobal() throws IOException, TemplateException {
- String ftl = "${.main.lib1???c} ${.globals.lib1???c}"
- + "<#import 'lib1.ftl' as lib1> ${.main.lib1???c} ${.globals.lib1???c}";
- String expectedOut = "false false true true";
- assertOutput(ftl, expectedOut);
- }
-
- @Test
- public void importInMainCreatesGlobalBugfix() throws IOException, TemplateException {
- // An import in the main namespace should invoke a global variable, even if the imported library was already
- // initialized elsewhere.
- String ftl = "<#import 'lib3ImportsLib1.ftl' as lib3>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}, "
- + "<#import 'lib1.ftl' as lib1>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}";
- assertOutput(ftl, "1 false false, 1 true true");
- }
-
- /**
- * Tests the order of auto-includes and auto-imports, also that they only effect the main template directly.
- */
- @Test
- public void autoIncludeAndAutoImport() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .autoImports(ImmutableMap.of(
- "lib1", "lib1.ftl",
- "lib2", "lib2CallsLib1.ftl"
- ))
- .autoIncludes(ImmutableList.of(
- "inc1.ftl",
- "inc2.ftl"))
- .build());
- assertOutput(
- "<#include 'inc3.ftl'>[main] ${inc1Cnt}, ${history}, <@lib1.m/>, <@lib2.m/>",
- "[inc1][inc2][inc3][main] 1, L1L2I, In lib1, In lib2 (In lib1)");
- }
-
- /**
- * Demonstrates design issue in FreeMarker 2.3.x where the lookupStrategy is not factored in when identifying
- * already existing namespaces.
- */
- @Test
- public void lookupSrategiesAreNotConsideredProperly() throws IOException, TemplateException {
- // As only the name of the template is used for the finding the already existing namespace, the settings that
- // influence the lookup are erroneously ignored.
- assertOutput(
- "<#setting locale='en_US'><#import 'lib.ftl' as ns1>"
- + "<#setting locale='de_DE'><#import 'lib.ftl' as ns2>"
- + "<@ns1.m/> <@ns2.m/> ${history}",
- "en en LEn");
-
- // The opposite of the prevous, where differn names refer to the same template after a lookup:
- assertOutput(
- "<#setting locale='en_US'>"
- + "<#import '*/lib.ftl' as ns1>"
- + "<#import 'lib.ftl' as ns2>"
- + "<@ns1.m/> <@ns2.m/> ${history}",
- "en en LEnLEn");
- }
-
- @Test
- public void lazyImportBasics() throws IOException, TemplateException {
- String ftlImports = "<#import 'lib1.ftl' as l1><#import 'lib2.ftl' as l2><#import 'lib3ImportsLib1.ftl' as l3>";
- String ftlCalls = "<@l2.m/>, <@l1.m/>; ${history}";
- String ftl = ftlImports + ftlCalls;
-
- assertOutput(ftl, "In lib2, In lib1; L1L2L3");
-
- setConfiguration(new TestConfigurationBuilder().lazyImports(true).build());
- assertOutput(ftl, "In lib2, In lib1; L2L1");
-
- assertOutput(ftlImports + "<@l3.m/>, " + ftlCalls, "In lib3 (In lib1), In lib2, In lib1; L3L1L2");
- }
-
- @Test
- public void lazyImportAndLocale() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder().lazyImports(true).build());
- assertOutput("<#setting locale = 'de_DE'><#import 'lib.ftl' as lib>"
- + "[${history!}] "
- + "<#setting locale = 'en'>"
- + "<@lib.m/> ${lib.initLocale} [${history}]",
- "[] de de_DE [LDe]");
- }
-
- @Test
- public void lazyAutoImportSettings() throws IOException, TemplateException {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
- .autoImports(ImmutableMap.of(
- "l1", "lib1.ftl",
- "l2", "lib2.ftl",
- "l3", "lib3.ftl"
- ));
-
- String ftl = "<@l2.m/>, <@l1.m/>; ${history}";
- String expectedEagerOutput = "In lib2, In lib1; L1L2L3";
- String expecedLazyOutput = "In lib2, In lib1; L2L1";
-
- setConfiguration(cfgB.build());
- assertOutput(ftl, expectedEagerOutput);
- cfgB.setLazyImports(true);
- setConfiguration(cfgB.build());
- assertOutput(ftl, expecedLazyOutput);
- cfgB.setLazyImports(false);
- setConfiguration(cfgB.build());
- assertOutput(ftl, expectedEagerOutput);
- cfgB.setLazyAutoImports(true);
- setConfiguration(cfgB.build());
- assertOutput(ftl, expecedLazyOutput);
- cfgB.setLazyAutoImports(null);
- setConfiguration(cfgB.build());
- assertOutput(ftl, expectedEagerOutput);
- cfgB.setLazyImports(true);
- cfgB.setLazyAutoImports(false);
- setConfiguration(cfgB.build());
- assertOutput(ftl, expectedEagerOutput);
- }
-
- @Test
- public void lazyAutoImportMixedWithManualImport() throws IOException, TemplateException {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
- .autoImports(ImmutableMap.of(
- "l1", "lib1.ftl",
- "l2", "/./lib2.ftl",
- "l3", "lib3.ftl"))
- .lazyAutoImports(true);
-
- String ftl = "<@l2.m/>, <@l1.m/>; ${history}";
- String expectOutputWithoutHistory = "In lib2, In lib1; ";
- String expecedOutput = expectOutputWithoutHistory + "L2L1";
-
- setConfiguration(cfgB.build());
- assertOutput(ftl, expecedOutput);
- assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2");
- assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2");
- assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput);
- assertOutput("<#import 'lib3.ftl' as l3>" + ftl, expectOutputWithoutHistory + "L3L2L1");
-
- cfgB.setLazyImports(true);
- setConfiguration(cfgB.build());
- assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expecedOutput);
- assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expecedOutput);
- assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput);
- assertOutput("<#import 'lib3.ftl' as l3>" + ftl, expecedOutput);
- }
-
- @Test
- public void lazyImportErrors() throws IOException, TemplateException {
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
- cfgB.setLazyImports(true);
-
- setConfiguration(cfgB.build());
- assertOutput("<#import 'noSuchTemplate.ftl' as wrong>x", "x");
-
- cfgB.addAutoImport("wrong", "noSuchTemplate.ftl");
- setConfiguration(cfgB.build());
- assertOutput("x", "x");
-
- try {
- assertOutput("${wrong.x}", "");
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(),
- allOf(containsString("Lazy initialization"), containsString("noSuchTemplate.ftl")));
- assertThat(e.getCause(), instanceOf(TemplateNotFoundException.class));
- }
-
- addTemplate("containsError.ftl", "${noSuchVar}");
- try {
- assertOutput("<#import 'containsError.ftl' as lib>${lib.x}", "");
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(),
- allOf(containsString("Lazy initialization"), containsString("containsError.ftl")));
- assertThat(e.getCause(), instanceOf(InvalidReferenceException.class));
- assertThat(e.getCause().getMessage(), containsString("noSuchVar"));
- }
- }
-
- /**
- * Ensures that all methods are overridden so that they will do the lazy initialization.
- */
- @Test
- public void lazilyInitializingNamespaceOverridesAll() throws SecurityException, NoSuchMethodException {
- for (Method m : Namespace.class.getMethods()) {
- Class<?> declClass = m.getDeclaringClass();
- if (declClass == Object.class || declClass == WrappingTemplateModel.class
- || (m.getModifiers() & Modifier.STATIC) != 0
- || m.getName().equals("synchronizedWrapper")) {
- continue;
- }
- Method lazyM = LazilyInitializedNamespace.class.getMethod(m.getName(), m.getParameterTypes());
- if (lazyM.getDeclaringClass() != LazilyInitializedNamespace.class) {
- fail("The " + lazyM + " method wasn't overidden in " + LazilyInitializedNamespace.class.getName());
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java
deleted file mode 100644
index f4908b8..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-
-import junit.framework.TestCase;
-
-public class IncudeFromNamelessTest extends TestCase {
-
- public IncudeFromNamelessTest(String name) {
- super(name);
- }
-
- public void test() throws IOException, TemplateException {
- StringTemplateLoader loader = new StringTemplateLoader();
- loader.putTemplate("i.ftl", "[i]");
- loader.putTemplate("sub/i.ftl", "[sub/i]");
- loader.putTemplate("import.ftl", "<#assign x = 1>");
-
- Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
-
- Template t = new Template(null, new StringReader(
- "<#include 'i.ftl'>\n"
- + "<#include '/i.ftl'>\n"
- + "<#include 'sub/i.ftl'>\n"
- + "<#include '/sub/i.ftl'>"
- + "<#import 'import.ftl' as i>${i.x}"
- ),
- cfg);
- StringWriter out = new StringWriter();
- t.process(null, out);
- assertEquals("[i][i][sub/i][sub/i]1", out.toString());
- }
-
-}
[30/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/servlet/web.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/servlet/web.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/servlet/web.xml
new file mode 100644
index 0000000..e406b1a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/servlet/web.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+ 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.
+-->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <servlet>
+ <servlet-name>controller</servlet-name>
+ <servlet-class>com.example.Model2ControllerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>controller</servlet-name>
+ <url-pattern>*.c</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>controller</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+ <servlet>
+ <servlet-name>freemarker</servlet-name>
+ <servlet-class>org.apache.freemarker.servlet.FreemarkerServlet</servlet-class>
+
+ <!-- FreemarkerServlet settings: -->
+ <init-param>
+ <param-name>TemplatePath</param-name>
+ <param-value>/</param-value>
+ </init-param>
+ <init-param>
+ <param-name>NoCache</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <init-param>
+ <param-name>ContentType</param-name>
+ <param-value>text/html; charset=UTF-8</param-value> <!-- Forces UTF-8 output encoding! -->
+ </init-param>
+
+ <!-- FreeMarker settings: -->
+ <init-param>
+ <param-name>incompatible_improvements</param-name>
+ <param-value>3.0.0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>template_exception_handler</param-name>
+ <!-- Some may prefer "html_debug" for development. -->
+ <param-value>rethrow</param-value>
+ </init-param>
+ <init-param>
+ <param-name>template_update_delay</param-name>
+ <param-value>0</param-value> <!-- 0 is for development only! Use higher value otherwise. -->
+ </init-param>
+ <init-param>
+ <param-name>sourceEncoding</param-name>
+ <param-value>UTF-8</param-value> <!-- The encoding of the template files. -->
+ </init-param>
+ <init-param>
+ <param-name>number_format</param-name>
+ <param-value>0.##########</param-value>
+ </init-param>
+
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>freemarker</servlet-name>
+ <url-pattern>*.ftl</url-pattern>
+ </servlet-mapping>
+
+ <!-- Prevent the visiting of MVC Views from outside the servlet container.
+ RequestDispatcher.forward/include should and will still work. Removing this
+ may open security holes! -->
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>FreeMarker MVC Views</web-resource-name>
+ <url-pattern>*.ftl</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <!-- Nobody is allowed to visit these -->
+ </auth-constraint>
+ </security-constraint>
+
+</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
new file mode 100644
index 0000000..33a7186
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/arithmetic.txt
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Arithmetic Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Perform a number assignment:</p>
+
+
+3.234
+2.00
+0.6172500000000000000000000000000000000000
+1.620089104901
+1.6201
+
+<P>Display a number with at least 3 digits after the decimal point</P>
+
+1234.000
+
+<p>Now use numbers in assignment</p>
+
+
+1257.77
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
new file mode 100644
index 0000000..0bab0bc
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean-formatting.txt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+Y Y Y
+N N N
+y y y
+n n n
+y y y
+n n n
+str:n str:n
+nein ja
+theStringValue theStringValue
+
+
+
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
new file mode 100644
index 0000000..8dc1290
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/boolean.txt
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Boolean Values Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+
+<p>Now perform scalar boolean tests:</p>
+
+<p>
+ b is true.<br />
+</p>
+
+<p> This makes sense.<br />
+</p>
+
+<p>
+ boolean3 succeeded.<br />
+</p>
+
+<p>
+ boolean4 succeeded.<br />
+</p>
+
+<p>
+ boolean4 || boolean5 succeeded.<br />
+</p>
+
+<p>
+ boolean5 || boolean4 || boolean5 succeeded.<br />
+</p>
+
+<p> boolean4 && boolean5 failed.<br />
+</p>
+
+<p>Now test list models:</p>
+
+<p>
+ list1 succeeded.<br />
+</p>
+
+<p>
+ list2 succeeded.<br />
+</p>
+
+<p>Test hash models:</p>
+
+<p>
+ hash1 succeeded: Hello, world.<br />
+</p>
+
+<p>
+ hash2 succeeded.<br />
+</p>
+
+<p>Test not operator:</p>
+
+<p>
+ Not boolean1 succeeded
+</p>
+
+<p>
+ Not boolean1 succeeded
+</p>
+
+<p> Not boolean2 failed
+</p>
+
+<p> Not boolean2 failed
+</p>
+
+<p>
+ Message is "Hello, world!"
+</p>
+
+<p> Message is "Hello, world!"
+</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
new file mode 100644
index 0000000..4532027
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/charset-in-header.txt
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+<head>
+ <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
+</head>
+<body>
+éáőű
+õÕûÛ
+őŐűŰ
+</body>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
new file mode 100644
index 0000000..d5902e3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comment.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Comment Test</title>
+</head>
+<body>
+ <p>Message exists!
+ </p>
+
+a b
+a b
+
+6
+7
+8
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
new file mode 100644
index 0000000..8d9d372
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/comparisons.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Numeric Operations Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Start with the increment operator:</p>
+<p>a1 = 0</p>
+<p>a1 = 1</p>
+<p>a1 = 2</p>
+
+<p>Now the decrement operator:</p>
+<p>a2 = 5</p>
+<p>a2 = 4</p>
+<p>a2 = 3</p>
+<p>a2 = 2</p>
+<p>a2 = 1</p>
+<p>a2 = 0</p>
+<p>a2 = -1</p>
+
+<p>Now the add operator:</p>
+<p>op1 = 5, op2 = 3, op3 = 8</p>
+<p>op3 = 11</p>
+
+<p>And the subtract operator:</p>
+<p>op1 = 5, op2 = 3, op3 = 2</p>
+<p>op3 = -1</p>
+
+<p>The comparison operators:</p>
+ <p>Item is: 0</p>
+ <p>Item is less than five.</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is: 1</p>
+ <p>Item is less than five.</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is: 2</p>
+ <p>Item is less than five.</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is: 3</p>
+ <p>Item is less than five.</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 4</p>
+ <p>Item is less than five.</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 5</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 6</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 7</p>
+ <p>Item is less than or equals to seven.</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 8</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 9</p>
+ <p>Item is greater than two.</p>
+ <p>Item is: 10</p>
+ <p>Item is greater than two.</p>
+ <p>Item is greater than or equal to ten.</p>
+ <p>Item is: 11</p>
+ <p>Item is greater than two.</p>
+ <p>Item is greater than or equal to ten.</p>
+ <p>Item is: 12</p>
+ <p>Item is greater than two.</p>
+ <p>Item is greater than or equal to ten.</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
new file mode 100644
index 0000000..43c7eed
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/compress.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Compress Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>This is the same message, using the "compress" tag:</p>
+<p>Hello, world!</p>
+<p>This is the same message, using the "StandardCompress" transform model:</p>
+<p>Hello, world!</p>
+<p>This multi-line message should be compressed to a single line.</p>
+
+<p>An example where the first character is not whitespace but the second character is:</p>
+<p>x y</p>
+
+<p>The end.</p>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
new file mode 100644
index 0000000..9180262
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/dateformat-java.txt
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+Nov 15, 2002 2:54:13 PM
+Nov 15, 2002 2:54:13 PM
+Nov 15, 2002 2:54:13 PM
+Nov 15, 2002 2:54:13 PM
+11/15/02 2:54 PM
+Nov 15, 2002 2:54:13 PM
+November 15, 2002 2:54:13 PM GMT
+11/15/02 2:54 PM
+11/15/02 2:54:13 PM
+11/15/02 2:54:13 PM GMT
+Nov 15, 2002 2:54 PM
+Nov 15, 2002 2:54:13 PM
+Nov 15, 2002 2:54:13 PM GMT
+November 15, 2002 2:54 PM
+November 15, 2002 2:54:13 PM
+November 15, 2002 2:54:13 PM GMT
+Nov 15, 2002
+Nov 15, 2002
+11/15/02
+Nov 15, 2002
+November 15, 2002
+2:54:13 PM
+2:54:13 PM
+2:54 PM
+2:54:13 PM
+2:54:13 PM GMT
+2002. november 15. 14:54:13 GMT
+Fri, 15 Nov 02002 14:54:13 GMT
+Fri, 15 Nov 2002 14:54:13 GMT
+Fri, 15 Nov 2002 14:54:13 GMT
+2002
+
+2002
+2002
+
+2002
+11
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
new file mode 100644
index 0000000..e015315
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-object-wrapper.txt
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+array-0
+array-1
+2
+array-0
+array-1
+list-0
+list-1
+list-2
+3
+not empty
+list-0
+value
+objValue
+foo-value
+hasfoo
+nobaz
+bar-value-0
+foo-value
+overloaded-int-1
+overloaded-String-String
+Message
+1974-11-14
+static-method
+static-overloaded-int-1
+static-overloaded-String-String
+static-final-field
+static-field
+ONEx
+TWOx
+THREEx
+true
+false
+false
+42
+1
+m
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
new file mode 100644
index 0000000..3a52c46
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default-xmlns.txt
@@ -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.
+ */
+No NS = No NS
+x NS = x NS
+y NS = y NS
+x NS = x NS
+
+true
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
new file mode 100644
index 0000000..fd48463
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/default.txt
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+foo
+
+luck
+
+
+0
+
+ UNDEFINED is undefined.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
new file mode 100644
index 0000000..ccfe5c8
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/encoding-builtins.txt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+FreeMarker: Encoding built-in tests
+
+html: [&<>"'{}\a/]
+xml: [&<>"'{}\a/]
+xhtml: [&<>"'{}\a/]
+rtf: [&<>"'\{\}\\a/]
+html: [a&a<a>a"a'a{a}a\]
+xml: [a&a<a>a"a'a{a}a\]
+xhtml: [a&a<a>a"a'a{a}a\]
+rtf: [a&a<a>a"a'a\{a\}a\\]
+html: [<<<<<]
+xml: [<<<<<]
+xhtml: [<<<<<]
+rtf: [\{\{\{\{\{]
+html: []
+xml: []
+xhtml: []
+rtf: []
+html: [a]
+xml: [a]
+xhtml: [a]
+rtf: [a]
+html: [&]
+xml: [&]
+xhtml: [&]
+rtf: [\{]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
new file mode 100644
index 0000000..c0a5440
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/escapes.txt
@@ -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.
+ */
+a
+b
+c
+a
+b
+c
+a
+1
+a
+b
+c
+<&>
+&lt;&amp;&gt;
+<&>
+---
+<Mooo> = <Mooo>
+ <MOOO> = <MOOO>
+ <MOOO> = <MOOO>
+ <MOOO> = <MOOO>
+ <MOOO> = <MOOO>
+ <MOOO> = <MOOO>
+ <Mooo> = <Mooo>
+ <Mooo> = <Mooo>
+ <Mooo> = <Mooo>
+ <Mooo> = <Mooo>
+ <Mooo> = <Mooo>
+ <MOOO> = <MOOO>
+ red green blue
+---
+ <A&B>[a&b](A&B) <A&B2>[a&b2](A&B2)
+ <{a&b}A&B>[{a&b}a&b]({a&b}A&B) <{a&b2}A&B2>[{a&b2}a&b2]({a&b2}A&B2)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
new file mode 100644
index 0000000..0ea4395
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception.txt
@@ -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.
+ */
+<html>
+<head>
+<title>FreeMarker: Exception Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world! <br />
+freemarker.template.TemplateModelException: Throwing from ExceptionModel!
+ at freemarker.test.templatesuite.models.ExceptionModel.getAsString(ExceptionModel.java:57)
+ at freemarker.template.compiler.Expression.getStringValue(Expression.java:65)
+ at freemarker.template.compiler.DollarVariable.process(DollarVariable.java:62)
+ at freemarker.template.compiler.NestedTemplateElements.process(NestedTemplateElements.java:76)
+ at freemarker.template.Template.process(Template.java:266)
+ at freemarker.template.Template.process(Template.java:289)
+ at freemarker.test.TestException.runTest(TestException.java:91)
+ at junit.framework.TestCase.runBare(TestCase.java:140)
+ at junit.framework.TestResult$1.protect(TestResult.java:106)
+ at junit.framework.TestResult.runProtected(TestResult.java:124)
+ at junit.framework.TestResult.run(TestResult.java:109)
+ at junit.framework.TestCase.run(TestCase.java:131)
+ at junit.framework.TestSuite.runTest(TestSuite.java:173)
+ at junit.framework.TestSuite.run(TestSuite.java:168)
+ at junit.swingui.TestRunner$17.run(TestRunner.java:644)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
new file mode 100644
index 0000000..bf441d3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception2.txt
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Exception Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world! <br />
+<!-- Template Error: Couldn't get value of variable test: Couldn't read string value of test: freemarker.template.TemplateModelException: Throwing from ExceptionModel!
+ at freemarker.test.templatesuite.models.ExceptionModel.getAsString(ExceptionModel.java:42)
+ at freemarker.template.expression.Variable.getValue(Variable.java:69)
+ at freemarker.template.instruction.VariableInstruction.process(VariableInstruction.java:55)
+ at freemarker.template.compiler.TemplateArrayList.process(TemplateArrayList.java:69)
+ at freemarker.template.Template.process(Template.java:226)
+ at freemarker.test.TestException2.runTest(TestException2.java:83)
+ at junit.framework.TestCase.runBare(TestCase.java:140)
+ at junit.framework.TestResult$1.protect(TestResult.java:106)
+ at junit.framework.TestResult.runProtected(TestResult.java:124)
+ at junit.framework.TestResult.run(TestResult.java:109)
+ at junit.framework.TestCase.run(TestCase.java:131)
+ at junit.framework.TestSuite.runTest(TestSuite.java:173)
+ at junit.framework.TestSuite.run(TestSuite.java:168)
+ at junit.swingui.TestRunner$17.run(TestRunner.java:644)
+ -->
+</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
new file mode 100644
index 0000000..6089e87
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exception3.txt
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+<html><head></head><body bgcolor="#ffffff">
+Template Compilation Error: Identifier expected at line 10.
+</body></html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
new file mode 100644
index 0000000..acb1f78
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/exthash.txt
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Extended Hash Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>A hash set of 8 animals follows:</p>
+
+<p>
+ elephant,
+
+ cat,
+
+ zebra,
+
+ dog,
+
+ aardvark,
+
+ kiwi,
+
+ squirrel,
+
+ gecko.
+</p>
+
+<p>The first animal is an elephant, and the last is a
+gecko.</p>
+
+<p>A hash set of 8 digits follows:<p>
+
+<p>
+ six,
+
+ four,
+
+ eight,
+
+ five,
+
+ one,
+
+ two,
+
+ seven,
+
+ three.
+</p>
+
+<p>The zebra number is eight.</p>
+
+<p>The end.</p>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
new file mode 100644
index 0000000..9736322
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashconcat.txt
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+a:
+ a = 1
+ b = 2
+ c = 3
+ X = 4
+ ---
+ 1
+ 2
+ 3
+ 4
+ ---
+
+B:
+ d = 10
+ e = 20
+ f = 30
+ X = 40
+ ---
+ 10
+ 20
+ 30
+ 40
+ ---
+
+a + B:
+ a = 1
+ b = 2
+ c = 3
+ X = 40
+ d = 10
+ e = 20
+ f = 30
+ ---
+ 1
+ 2
+ 3
+ 40
+ 10
+ 20
+ 30
+ ---
+
+B + a:
+ d = 10
+ e = 20
+ f = 30
+ X = 4
+ a = 1
+ b = 2
+ c = 3
+ ---
+ 10
+ 20
+ 30
+ 4
+ 1
+ 2
+ 3
+ ---
+
+a + a:
+ a = 1
+ b = 2
+ c = 3
+ X = 4
+ ---
+ 1
+ 2
+ 3
+ 4
+ ---
+
+{} + a:
+ a = 1
+ b = 2
+ c = 3
+ X = 4
+ ---
+ 1
+ 2
+ 3
+ 4
+ ---
+
+a + {}:
+ a = 1
+ b = 2
+ c = 3
+ X = 4
+ ---
+ 1
+ 2
+ 3
+ 4
+ ---
+
+{} + {}:
+ ---
+ ---
+
+a + b + {} + b + {} + a:
+ a = 1
+ b = 2
+ c = 3
+ X = 4
+ d = 10
+ e = 20
+ f = 30
+ ---
+ 1
+ 2
+ 3
+ 4
+ 10
+ 20
+ 30
+ ---
+
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
new file mode 100644
index 0000000..3af1052
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/hashliteral.txt
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Hash Literal Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now perform a hash assignment:</p>
+
+
+test23
+Hello, world!
+hello all
+1
+
+<p>Now update the assignment and repeat:</p>
+
+
+test23
+Hello, world!
+hello all
+
+1
+
+<p>Now reassign the list and repeat:</p>
+
+
+test23
+Hello, world!
+
+
+1
+Temporary
+Temporary
+Temporary
+
+<p>Pathological case: zero item hash:</p>
+
+
+
+<p>Hash of number literals:</p>
+2
+
+<p>Hash concatenation:</p>
+a => 1
+b => 3
+c => 4
+
+<p>Empty hash concatenation:</p>
+foo, bar
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
new file mode 100644
index 0000000..b1072fd
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/helloworld.txt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Exec Model Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!
+</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
new file mode 100644
index 0000000..1c62bd5
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-escaping.txt
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+<a-b>red123</a-b>
+
+f-a works
+
+dash-dash-dash etc.
+dash-dash-dash etc.
+propVal
+propVal
+
+List: 123
+
+Switch: OK
+ESCAPED
+
+
+as1
+as2
+as3
+as4
+as5
+
+<catchAll x=1 y=2 a:b.c=5 data-foo=4 z=3 />
+
+---.: = dash-dash-dash etc.
+@as@_a = as1
+as/b = as3
+as'c = as4
+as"d = as5
+as-c = as2
+catchAll = ...
+dumpNS = ...
+f-a = ...
+hash = ...
+ls:a = ...
+m/b2 = ...
+m-a = ...
+m-b2 = ...
+sw-a = ...
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
new file mode 100644
index 0000000..8a8d04f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/identifier-non-ascii.txt
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+Korean Keyboard
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
new file mode 100644
index 0000000..7c9d1d8
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/if.txt
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+- good
+- good
+- good
+- good
+
+- good
+- good
+
+- good
+- good
+- good
+- good
+
+- good
+- good
+- good
+- good
+
+- good
+- good
+- good
+- good
+
+- good
+- good
+
+- good
+- good
+- good
+- good
+
+- good
+- good
+- good
+- good
+
+- 1
+-
+-
+- is 1
+- isn't 2
+- isn't 3
+- Finally, it's: 1
+-
+- 2
+-
+- isn't 1
+- is 2
+- isn't 3
+- Finally, it's: 2
+-
+-
+- 3
+- isn't 1
+- isn't 2
+- is 3
+- Finally, it's: 3
+-
+-
+-
+- isn't 1
+- isn't 2
+- isn't 3
+- Finally, it's: 4
+
+ 1:
+ == 1
+ 1:
+ <= 2
+ 1:
+ <= 3
+ 2:
+ > 1
+ 2:
+ == 2
+ 2:
+ <= 3
+ 3:
+ > 1
+ 3:
+ > 2
+ 3:
+ == 3
+ End
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
new file mode 100644
index 0000000..b51a4f4
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/import.txt
@@ -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.
+ */
+--
+--
+
+
+jsmith@acme.com
+ Test bar.
+ Email: jsmith@acme.com
+
+jsmith@acme.com
+ Test bar.
+ Email: jsmith@acme.com
+ Email in the root: jsmith@other1.com
+
+jsmith@other2.com
+ Test bar.
+ Email: jsmith@other2.com
+ Email in the root: jsmith@other1.com
+
+jsmith@other2.com
+jsmith@other3.com
+
+foobarfoobar
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
new file mode 100644
index 0000000..c72d69c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include.txt
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Include Instruction Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+Hello, world!
+
+ <p>Message exists!
+
+<p>Test normal includes:</p>
+<p>A test of included files:</p>
+
+ <p>Message exists!:<br />
+ Hello, world!</p>
+
+ Can you see me?
+
+assigning from included template
+I'm here, mon!
+
+Kilroy
+ Can you see me? Kilroy
+
+<p>Test subdir includes:</p>
+<p>This is include-subdir.ftl</p>
+<p>Testing including from same directory</p>
+<p>This is include-subdir2.ftl</p>
+<p>Testing including from relative parent</p>
+<p>A test of included files:</p>
+
+ <p>Message exists!:<br />
+ Hello, world!</p>
+
+ Can you see me?
+<p>Testing including from loader root</p>
+<p>A test of included files:</p>
+
+ <p>Message exists!:<br />
+ Hello, world!</p>
+
+ Can you see me?
+<p>Testing including through acquisition</p>
+<p>This is include-subdir2.ftl</p>
+</body>
+</html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
new file mode 100644
index 0000000..b7c43a9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/include2.txt
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+A próba
+A próba
+
+A próba
+A próba
+A próba
+A próba
+
+[]
+[]
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
new file mode 100644
index 0000000..fe862e6
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/interpret.txt
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+abcdef
+abcdef
+abcdef
+
+M
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
new file mode 100644
index 0000000..fb44def
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/iterators.txt
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: List Iterator Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now iterate over a list:</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>Now iterate again:</p>
+
+<p>0. one</p>
+<p>1. two</p>
+<p>2. three</p>
+<p>3. four</p>
+<p>4. five</p>
+
+<p>Iterate over a list in a hash:</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+<p>one</p>
+<p>two</p>
+<p>three</p>
+<p>four</p>
+<p>five</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
new file mode 100644
index 0000000..dbe5fd0
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/lastcharacter.txt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Last Character Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+ 13
+
+ ELLO, WORLD!
+
+ message: Hello, Worl
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
new file mode 100644
index 0000000..3b9b76d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list-bis.txt
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+ 0: a [0:A, 1:B, 2:C]
+ 1: b [0:A, 1:B, 2:C]
+ 2: c [0:A, 1:B, 2:C]
+
+ 0: a 0a/0A, 0a/1B, 0a/2C
+ 1: b 1b/0A, 1b/1B, 1b/2C
+ 2: c 2c/0A, 2c/1B, 2c/2C
+
+0:a, 1:b, 2:c
+1. a; 2. b; 3. c;
+
+a, b, c
+a, b, c
+
+A, b, c.
+
+true/false false/true true/false
+
+ <td class="oddRow">a</td>
+ <td class="evenRow">b</td>
+ <td class="oddRow">c</td>
+
+ <td class="rowOdd">a</td>
+ <td class="rowEven">b</td>
+ <td class="rowOdd">c</td>
+
+ <td class="R">a</td>
+ <td class="G">b</td>
+ <td class="B">c</td>
+ <td class="R">d</td>
+ <td class="G">e</td>
+ <td class="B">f</td>
+ <td class="R">g</td>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
new file mode 100644
index 0000000..05373bd
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list.txt
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+Size: 4
+Items: @0 aardvark, @1 bear, @2 cat, @3 dog.
+
+Size: 1
+Items: @0 aardvark.
+
+Size: 0
+Items:
+
+Size: 3
+Items: @0 11, @1 22, @2 33.
+
+Size: 3
+Items: @0 11, @1 22, @2 33.
+
+Size: 3
+Items: @0 11, @1 22, @2 33.
+
+Size: failed
+Items: @0 11, @1 22, @2 33.
+
+Size: 0
+Items:
+
+Size: 0
+Items:
+
+Size: 0
+Items:
+
+Size: failed
+Items:
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
new file mode 100644
index 0000000..cb9e6d4
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list2.txt
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+=== [aardvark, bear, cat, dog] ===
+
+-- List+sep:
+ aardvark,
+ bear,
+ cat,
+ dog
+-- List+else:
+ aardvark
+ bear
+ cat
+ dog
+-- List+items:
+ [
+ aardvark
+ bear
+ cat
+ dog
+ ]
+-- List+items+else:
+ [
+ aardvark
+ bear
+ cat
+ dog
+ ]
+-- List+items+sep+else:
+ [
+ aardvark,
+ bear,
+ cat,
+ dog
+ ]
+--
+
+=== [aardvark] ===
+
+-- List+sep:
+ aardvark
+-- List+else:
+ aardvark
+-- List+items:
+ [
+ aardvark
+ ]
+-- List+items+else:
+ [
+ aardvark
+ ]
+-- List+items+sep+else:
+ [
+ aardvark
+ ]
+--
+
+=== [] ===
+
+-- List+sep:
+-- List+else:
+ Empty!
+-- List+items:
+-- List+items+else:
+ Empty!
+-- List+items+sep+else:
+ Empty!
+--
+
+=== [11, 22, 33] ===
+
+-- List+sep:
+ 11,
+ 22,
+ 33
+-- List+else:
+ 11
+ 22
+ 33
+-- List+items:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+else:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+sep+else:
+ [
+ 11,
+ 22,
+ 33
+ ]
+--
+
+=== [11, 22, 33] ===
+
+-- List+sep:
+ 11,
+ 22,
+ 33
+-- List+else:
+ 11
+ 22
+ 33
+-- List+items:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+else:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+sep+else:
+ [
+ 11,
+ 22,
+ 33
+ ]
+--
+
+=== [11, 22, 33] ===
+
+-- List+sep:
+ 11,
+ 22,
+ 33
+-- List+else:
+ 11
+ 22
+ 33
+-- List+items:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+else:
+ [
+ 11
+ 22
+ 33
+ ]
+-- List+items+sep+else:
+ [
+ 11,
+ 22,
+ 33
+ ]
+--
+
+=== [] ===
+
+-- List+sep:
+-- List+else:
+ Empty!
+-- List+items:
+-- List+items+else:
+ Empty!
+-- List+items+sep+else:
+ Empty!
+--
+
+=== [] ===
+
+-- List+sep:
+-- List+else:
+ Empty!
+-- List+items:
+-- List+items+else:
+ Empty!
+-- List+items+sep+else:
+ Empty!
+--
+
+=== [] ===
+
+-- List+sep:
+-- List+else:
+ Empty!
+-- List+items:
+-- List+items+else:
+ Empty!
+-- List+items+sep+else:
+ Empty!
+--
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
new file mode 100644
index 0000000..26fc60d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/list3.txt
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+[
+ [(11@0, 11@0), (11@0, 22@1), (11@0, 33@2)],
+ [(22@1, 11@0), (22@1, 22@1), (22@1, 33@2)],
+ [(33@2, 11@0), (33@2, 22@1), (33@2, 33@2)]
+]
+
+
+ <p>2 hits:
+ <div class="hits">
+ <div class="hit">a</div>
+ <div class="hit">b</div>
+ </div>
+
+ <p>2 hits:
+ <div class="hits">
+ <div class="hitOther">a</div>
+ <div class="hitOther">b</div>
+ </div>
+
+ <p>2 hits:
+ <div class="hits">
+ ...
+ </div>
+
+ <p>Nothing.
+
+11, 22, ...
+[11, 22, ...]
+
+1, 2, 3
+1 /*first*/, 2, 3
+[1, 2, 3]
+1
+1
+[1]
+Empty
+Empty
+Empty
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
new file mode 100644
index 0000000..e251238
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhash.txt
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+Non-empty maps:
+
+ Map:
+
+ [
+ k1 = v1
+ 2 = v2
+ k3 = v3
+ null = v4
+ Y = v5
+ N = null
+ ]
+
+ [
+ k1 = v1; // @0=@0; odd=odd; Y=Y
+ 2 = v2; // @1=@1; even=even; Y=Y
+ k3 = v3; // @2=@2; odd=odd; Y=Y
+ null = v4; // @3=@3; even=even; Y=Y
+ Y = v5; // @4=@4; odd=odd; Y=Y
+ N = null // @5=@5; even=even; N=N
+ ]
+
+ {
+ [
+ k1 = v1; // @0=@0; odd=odd; Y=Y
+ 2 = v2; // @1=@1; even=even; Y=Y
+ k3 = v3; // @2=@2; odd=odd; Y=Y
+ null = v4; // @3=@3; even=even; Y=Y
+ Y = v5; // @4=@4; odd=odd; Y=Y
+ N = null // @5=@5; even=even; N=N
+ ]
+ }
+
+ Map:
+
+ [
+ k1 = v1
+ 2 = v2
+ k3 = v3
+ null = v4
+ Y = v5
+ N = null
+ ]
+
+ [
+ k1 = v1; // @0=@0; odd=odd; Y=Y
+ 2 = v2; // @1=@1; even=even; Y=Y
+ k3 = v3; // @2=@2; odd=odd; Y=Y
+ null = v4; // @3=@3; even=even; Y=Y
+ Y = v5; // @4=@4; odd=odd; Y=Y
+ N = null // @5=@5; even=even; N=N
+ ]
+
+ {
+ [
+ k1 = v1; // @0=@0; odd=odd; Y=Y
+ 2 = v2; // @1=@1; even=even; Y=Y
+ k3 = v3; // @2=@2; odd=odd; Y=Y
+ null = v4; // @3=@3; even=even; Y=Y
+ Y = v5; // @4=@4; odd=odd; Y=Y
+ N = null // @5=@5; even=even; N=N
+ ]
+ }
+
+ Map:
+
+ [
+ k1 = 11
+ k2 = 22
+ ]
+
+ [
+ k1 = 11; // @0=@0; odd=odd; Y=Y
+ k2 = 22 // @1=@1; even=even; N=N
+ ]
+
+ {
+ [
+ k1 = 11; // @0=@0; odd=odd; Y=Y
+ k2 = 22 // @1=@1; even=even; N=N
+ ]
+ }
+
+
+Empty maps:
+
+ Map:
+
+ [
+ ]
+
+ [
+ Empty
+ ]
+
+ {
+ Empty
+ }
+
+ Map:
+
+ [
+ ]
+
+ [
+ Empty
+ ]
+
+ {
+ Empty
+ }
+
+ Map:
+
+ [
+ ]
+
+ [
+ Empty
+ ]
+
+ {
+ Empty
+ }
+
+
+ a @ 0, 1
+ aa = 11 @ 0 // inside a @ 0, 1
+ a @ 0, 1
+ --
+ b @ 1, 2
+ ba = 21 @ 0 // inside b @ 1, 2
+ bb = 22 @ 1 // inside b @ 1, 2
+ b @ 1, 2
+ --
+ c @ 2, 0
+ c @ 2, 0
+ --
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
new file mode 100644
index 0000000..937f0ea
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listhashliteral.txt
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+ KVPs:
+ a = 3
+ b = 2
+
+ Keys:
+ a
+ b
+
+ Values:
+ 3
+ 2
+
+ KVPs:
+
+ Keys:
+
+ Values:
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
new file mode 100644
index 0000000..2048ac5
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/listliteral.txt
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: List Literal Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now perform a list assignment:</p>
+
+
+The list contains 5 items.
+
+<p>test1</p>
+<p>test23</p>
+<p>test45</p>
+<p>Hello, world!</p>
+<p>hello</p>
+
+<p>Now update the assignment and repeat:</p>
+
+
+<p>test1</p>
+<p>test23</p>
+<p>test45</p>
+<p>Hello, world!</p>
+<p>hello</p>
+
+<p>Now reassign the list and repeat:</p>
+
+
+<p>bar</p>
+<p>Temporary</p>
+<p>test1</p>
+<p>test23</p>
+
+<p>Silly, but necessary tests, for one and zero element lists:</p>
+
+
+<p>Hello, world</p>
+
+<p>Zero item test:</p>
+
+
+
+<p>Dumb test for number literals -- these weren't working as expected:</p>
+
+
+<p>1</p>
+<p>2</p>
+<p>3</p>
+<p>5</p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
new file mode 100644
index 0000000..bd3c87d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/localization.txt
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Localization Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>G'day, mate!</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
new file mode 100644
index 0000000..4fa6b2a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/logging.txt
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Logging Test</title>
+</head>
+<body>
+
+A simple test follows:
+
+ERROR [org.apache.freemarker.core.Template]: message is not a TemplateHashModel, it's a freemarker.template.SimpleScalar.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
new file mode 100644
index 0000000..25c20ac
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/loopvariable.txt
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+---
+ 2
+ - L1 1
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+ - L1 2
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+ - L1 3
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+*
+ 1
+ - L1 1
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+ - L1 2
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+ - L1 3
+ - L2 1: 1; 2; 3;
+ - L2 2: 1; 2; 3;
+*
+*
+---
+ 1 0.5
+ 2 1
+ 3 1.5
+ 4 2 Last!
+123.4
+---
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
new file mode 100644
index 0000000..5aa47ff
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros-return.txt
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+m{
+m{
+m{
+b{
+m:b{
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
new file mode 100644
index 0000000..680a08e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/macros.txt
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+<html>
+<head>
+<title>FreeMarker: Function Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>Hello, world!</p>
+
+<p>Now perform function tests:</p>
+
+
+<p>Function is defined, now let's call it:</p>
+
+ <a href="/home.html">
+ <img src="/images/home.png" border="0" alt="Home">
+ </a>
+ Kilroy was here.
+
+<p>Again, but with different parameters:</p>
+
+ <a href="/about.html">
+ <img src="/image/about-us.jpeg" border="0" alt="About Us">
+ </a>
+ Kilroy was here.
+
+ Good.
+
+<p>A recursive function call:</p>
+
+
+ 0
+ 1
+ 2
+ 3
+
+<p>Test "catch-all" macro parameter:</p>
+
+
+foo=a baz=[]
+foo=a baz=[bar=b]
+foo=a baz=[bar=b, baz=c]
+
+
+Hello World! Today is Monday.
+
+</body>
+</html>
[08/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/manualtest/Product.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/Product.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/Product.java
deleted file mode 100644
index fcb34e8..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/Product.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
deleted file mode 100644
index 8c515bd..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/TemplateConfigurationExamples.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
deleted file mode 100644
index 89f20fa..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberFormatFactory.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java b/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
deleted file mode 100644
index 1e54254..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/manualtest/UnitAwareTemplateNumberModel.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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/src/test/java/org/apache/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/CopyrightCommentRemoverTemplateLoader.java b/freemarker-core/src/test/java/org/apache/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
deleted file mode 100644
index 3b1f1ee..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.input.ReaderInputStream;
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.TemplateLoaderSession;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingResult;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingResultStatus;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingSource;
-
-/**
- * Removes the Apache copyright boiler plate from the beginning of the template, so that they don't mess up the expected
- * template output. This can interfere with tests that try to test I/O errors and such low level things, so use with
- * care.
- */
-public class CopyrightCommentRemoverTemplateLoader implements TemplateLoader {
-
- private final TemplateLoader innerTemplateLoader;
-
- public CopyrightCommentRemoverTemplateLoader(TemplateLoader innerTemplateLoader) {
- this.innerTemplateLoader = innerTemplateLoader;
- }
-
- @Override
- public TemplateLoaderSession createSession() {
- return null;
- }
-
- @Override
- public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom,
- Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException {
- TemplateLoadingResult result = innerTemplateLoader.load(name, ifSourceDiffersFrom, ifVersionDiffersFrom, session);
- if (result.getStatus() != TemplateLoadingResultStatus.OPENED) {
- return result;
- }
- if (result.getInputStream() != null) {
- return new TemplateLoadingResult(
- result.getSource(), result.getVersion(), getWithoutCopyrightHeader(result.getInputStream()),
- result.getTemplateConfiguration());
- } else {
- return new TemplateLoadingResult(
- result.getSource(), result.getVersion(), getWithoutCopyrightHeader(result.getReader()),
- result.getTemplateConfiguration());
- }
- }
-
- @Override
- public void resetState() {
- // Do nothing
- }
-
- private Reader getWithoutCopyrightHeader(Reader reader) throws IOException {
- if (reader == null) {
- return null;
- }
- try {
- String content = IOUtils.toString(reader);
- return new StringReader(TestUtil.removeFTLCopyrightComment(content));
- } finally {
- reader.close();
- }
- }
-
- private InputStream getWithoutCopyrightHeader(InputStream in) throws IOException {
- if (in == null) {
- return null;
- }
- try {
- // Encoding then decosing in ISO-8859-1 is binary loseless
- String content = IOUtils.toString(in, StandardCharsets.ISO_8859_1.name());
- return new ReaderInputStream(
- new StringReader(TestUtil.removeFTLCopyrightComment(content)),
- StandardCharsets.ISO_8859_1);
- } finally {
- in.close();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/MonitoredTemplateLoader.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/MonitoredTemplateLoader.java b/freemarker-core/src/test/java/org/apache/freemarker/test/MonitoredTemplateLoader.java
deleted file mode 100644
index 0ab2922..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/MonitoredTemplateLoader.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.TemplateLoaderSession;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingResult;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingResultStatus;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingSource;
-
-import com.google.common.base.Objects;
-
-public class MonitoredTemplateLoader implements TemplateLoader {
-
- private final List<AbstractTemplateLoader2Event> events
- = Collections.synchronizedList(new ArrayList<AbstractTemplateLoader2Event>());
-
- private Map<String, StoredTemplate> templates
- = new ConcurrentHashMap<>();
-
- @Override
- public TemplateLoaderSession createSession() {
- events.add(CreateSessionEvent.INSTANCE);
- return new MonitoredTemplateLoader2Session();
- }
-
- @Override
- public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom, Serializable ifVersionDiffersFrom,
- TemplateLoaderSession session)
- throws IOException {
- TemplateLoadingResult result = loadInner(name, ifSourceDiffersFrom, ifVersionDiffersFrom, session);
- events.add(new LoadEvent(name, result.getStatus()));
- return result;
- }
-
- private TemplateLoadingResult loadInner(String name, TemplateLoadingSource ifSourceDiffersFrom,
- Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws UnsupportedEncodingException {
- if (session.isClosed()) {
- throw new IllegalArgumentException("Template loader session is already closed.");
- }
-
- StoredTemplate storedTemplate = templates.get(name);
- if (storedTemplate == null) {
- return TemplateLoadingResult.NOT_FOUND;
- }
-
- TemplateLoadingSource source = storedTemplate.getSource();
- Serializable version = storedTemplate.getVersion();
- if (ifSourceDiffersFrom != null
- && ifSourceDiffersFrom.equals(source)
- && Objects.equal(ifVersionDiffersFrom, version)) {
- return TemplateLoadingResult.NOT_MODIFIED;
- }
-
- String content = storedTemplate.getContent();
- return storedTemplate.inputStreamEncoding == null
- ? new TemplateLoadingResult(source, version, new StringReader(content), null)
- : new TemplateLoadingResult(source, version,
- new ByteArrayInputStream(content.getBytes(storedTemplate.inputStreamEncoding)), null);
- }
-
- @Override
- public void resetState() {
- events.add(ResetStateEvent.INSTANCE);
- }
-
- public StoredTemplate putTextTemplate(String name, String content) {
- return putTextTemplate(name, "v1", content);
- }
-
- public StoredTemplate putTextTemplate(String name, Serializable version, String content) {
- StoredTemplate storedTemplate = new StoredTemplate(name, version, content, null);
- templates.put(name, storedTemplate);
- return storedTemplate;
- }
-
- public StoredTemplate putBinaryTemplate(String name, String content) {
- return putBinaryTemplate(name, content, "v1");
- }
-
- public StoredTemplate putBinaryTemplate(String name, String content, Serializable version) {
- return putBinaryTemplate(name, content, null, version);
- }
-
- public StoredTemplate putBinaryTemplate(String name, String content,
- Charset inputStreamEncoding, Serializable version) {
- StoredTemplate storedTemplate = new StoredTemplate(name, version, content,
- inputStreamEncoding != null ? inputStreamEncoding : StandardCharsets.UTF_8);
- templates.put(name, storedTemplate);
- return storedTemplate;
- }
-
- public List<AbstractTemplateLoader2Event> getEvents() {
- return events;
- }
-
- /**
- * Gets a filtered event list.
- */
- @SuppressWarnings("unchecked")
- public <E extends AbstractTemplateLoader2Event> List<E> getEvents(Class<E> eventClass) {
- List<E> result = new ArrayList<>();
- for (AbstractTemplateLoader2Event event : events) {
- if (eventClass.isInstance(event)) {
- result.add((E) event);
- }
- }
- return result;
- }
-
- /**
- * Extract from the {@link #getEvents()} the template names for which {@link TemplateLoader#load} was called.
- */
- public List<String> getLoadNames() {
- List<String> result = new ArrayList<>();
- for (AbstractTemplateLoader2Event event : events) {
- if (event instanceof LoadEvent) {
- result.add(((LoadEvent) event).name);
- }
- }
- return result;
- }
-
- public void clearEvents() {
- events.clear();
- }
-
- @SuppressWarnings("serial")
- public static class StoredTemplate implements TemplateLoadingSource {
- private String name;
- private Serializable version;
- private String content;
- private Charset inputStreamEncoding;
-
- private StoredTemplate(String name, Serializable version, String content, Charset inputStreamEncoding) {
- this.name = name;
- this.version = version;
- this.content = content;
- this.inputStreamEncoding = inputStreamEncoding;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public TemplateLoadingSource getSource() {
- return this;
- }
-
- public Serializable getVersion() {
- return version;
- }
-
- public void setVersion(Serializable version) {
- this.version = version;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
- public Charset getInputStreamEncoding() {
- return inputStreamEncoding;
- }
-
- public void setInputStreamEncoding(Charset inputStreamEncoding) {
- this.inputStreamEncoding = inputStreamEncoding;
- }
-
- }
-
- public abstract static class AbstractTemplateLoader2Event {
- // empty
- }
-
- public static class LoadEvent extends AbstractTemplateLoader2Event {
- private final String name;
- private final TemplateLoadingResultStatus resultStatus;
-
- public LoadEvent(String name, TemplateLoadingResultStatus resultStatus) {
- this.name = name;
- this.resultStatus = resultStatus;
- }
-
- public String getName() {
- return name;
- }
-
- public TemplateLoadingResultStatus getResultStatus() {
- return resultStatus;
- }
-
- @Override
- public String toString() {
- return "LoadEvent [name=" + name + ", resultStatus=" + resultStatus + "]";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((resultStatus == null) ? 0 : resultStatus.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- LoadEvent other = (LoadEvent) obj;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- return resultStatus == other.resultStatus;
- }
-
- }
-
- public static class ResetStateEvent extends AbstractTemplateLoader2Event {
-
- public static ResetStateEvent INSTANCE = new ResetStateEvent();
-
- private ResetStateEvent() {
- //
- }
-
- @Override
- public String toString() {
- return "ResetStateEvent []";
- }
-
- }
-
- public static class CreateSessionEvent extends AbstractTemplateLoader2Event {
-
- public static CreateSessionEvent INSTANCE = new CreateSessionEvent();
-
- private CreateSessionEvent() {
- //
- }
-
- @Override
- public String toString() {
- return "CreateSessionEvent []";
- }
-
- }
-
- public static class CloseSessionEvent extends AbstractTemplateLoader2Event {
-
- public static CloseSessionEvent INSTANCE = new CloseSessionEvent();
-
- private CloseSessionEvent() {
- //
- }
-
- @Override
- public String toString() {
- return "CloseSessionEvent []";
- }
-
- }
-
- public class MonitoredTemplateLoader2Session implements TemplateLoaderSession {
-
- private boolean closed;
-
- @Override
- public void close() {
- closed = true;
- events.add(CloseSessionEvent.INSTANCE);
- }
-
- @Override
- public boolean isClosed() {
- return closed;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/TemplateTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/TemplateTest.java b/freemarker-core/src/test/java/org/apache/freemarker/test/TemplateTest.java
deleted file mode 100644
index 566cc90..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/TemplateTest.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.ParseException;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
-import org.apache.freemarker.core.util._NullArgumentException;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.templatesuite.TemplateTestSuite;
-import org.junit.Ignore;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * Superclass of JUnit tests that process templates but aren't practical to implement via {@link TemplateTestSuite}.
- */
-@Ignore
-public abstract class TemplateTest {
-
- private Configuration configuration;
- private boolean dataModelCreated;
- private Object dataModel;
- private Map<String, String> addedTemplates = new HashMap<>();
-
- /**
- * Gets the {@link Configuration} used, automaticlly creating and setting if it wasn't yet.
- */
- protected final Configuration getConfiguration() {
- if (configuration == null) {
- try {
- setConfiguration(createDefaultConfiguration());
- } catch (Exception e) {
- throw new RuntimeException("Failed to create configuration", e);
- }
- }
- return configuration;
- }
-
- /**
- * @param configuration Usually should be built using {@link TestConfigurationBuilder}; not {@code null}.
- */
- protected final void setConfiguration(Configuration configuration) {
- _NullArgumentException.check("configuration", configuration);
- if (this.configuration == configuration) {
- return;
- }
-
- this.configuration = configuration;
- afterConfigurationSet();
- }
-
- protected void assertOutput(String ftl, String expectedOut) throws IOException, TemplateException {
- assertOutput(createTemplate(ftl), expectedOut, false);
- }
-
- private Template createTemplate(String ftl) throws IOException {
- return new Template(null, ftl, getConfiguration());
- }
-
- protected void assertOutputForNamed(String name, String expectedOut) throws IOException, TemplateException {
- assertOutput(getConfiguration().getTemplate(name), expectedOut, false);
- }
-
- @SuppressFBWarnings(value="UI_INHERITANCE_UNSAFE_GETRESOURCE", justification="By design relative to subclass")
- protected void assertOutputForNamed(String name) throws IOException, TemplateException {
- String expectedOut;
- {
- String resName = name + ".out";
- InputStream in = getClass().getResourceAsStream(resName);
- if (in == null) {
- throw new IOException("Reference output resource not found: " + getClass() + ", " + resName);
- }
- try {
- expectedOut = TestUtil.removeTxtCopyrightComment(IOUtils.toString(in, StandardCharsets.UTF_8.name()));
- } finally {
- in.close();
- }
- }
- assertOutput(getConfiguration().getTemplate(name), expectedOut, true);
- }
-
- protected void assertOutput(Template t, String expectedOut) throws TemplateException, IOException {
- assertOutput(t, expectedOut, false);
- }
-
- protected void assertOutput(Template t, String expectedOut, boolean normalizeNewlines)
- throws TemplateException, IOException {
- String actualOut = getOutput(t);
-
- if (normalizeNewlines) {
- expectedOut = normalizeNewLines(expectedOut);
- actualOut = normalizeNewLines(actualOut);
- }
- assertEquals(expectedOut, actualOut);
- }
-
- protected String getOutput(String ftl) throws IOException, TemplateException {
- return getOutput(createTemplate(ftl));
- }
-
- protected String getOutput(Template t) throws TemplateException, IOException {
- StringWriter out = new StringWriter();
- t.process(getDataModel(), out);
- return out.toString();
- }
-
- protected Configuration createDefaultConfiguration() throws Exception {
- return new TestConfigurationBuilder().build();
- }
-
- private void afterConfigurationSet() {
- ensureAddedTemplatesPresent();
- addCommonTemplates();
- }
-
- private void ensureAddedTemplatesPresent() {
- for (Map.Entry<String, String> ent : addedTemplates.entrySet()) {
- addTemplate(ent.getKey(), ent.getValue());
- }
- }
-
- protected void addCommonTemplates() {
- //
- }
-
- protected Object getDataModel() {
- if (!dataModelCreated) {
- dataModel = createDataModel();
- dataModelCreated = true;
- }
- return dataModel;
- }
-
- protected Object createDataModel() {
- return null;
- }
-
- @SuppressWarnings("boxing")
- protected Map<String, Object> createCommonTestValuesDataModel() {
- Map<String, Object> dataModel = new HashMap<>();
- dataModel.put("map", Collections.singletonMap("key", "value"));
- dataModel.put("list", Collections.singletonList("item"));
- dataModel.put("s", "text");
- dataModel.put("n", 1);
- dataModel.put("b", true);
- dataModel.put("bean", new TestBean());
- return dataModel;
- }
-
- protected void addTemplate(String name, String content) {
- Configuration cfg = getConfiguration();
- TemplateLoader tl = cfg.getTemplateLoader();
- ByteArrayTemplateLoader btl;
- btl = extractByteArrayTemplateLoader(tl);
- btl.putTemplate(name, content.getBytes(StandardCharsets.UTF_8));
- addedTemplates.put(name, content);
- }
-
- private ByteArrayTemplateLoader extractByteArrayTemplateLoader(TemplateLoader tl) {
- if (tl instanceof MultiTemplateLoader) {
- MultiTemplateLoader mtl = (MultiTemplateLoader) tl;
- for (int i = 0; i < mtl.getTemplateLoaderCount(); i++) {
- TemplateLoader tli = mtl.getTemplateLoader(i);
- if (tli instanceof ByteArrayTemplateLoader) {
- return (ByteArrayTemplateLoader) tli;
- }
- }
- throw new IllegalStateException(
- "The template loader was a MultiTemplateLoader that didn't contain ByteArrayTemplateLoader: "
- + tl);
- } else if (tl instanceof ByteArrayTemplateLoader) {
- return (ByteArrayTemplateLoader) tl;
- } else if (tl == null) {
- throw new IllegalStateException("The templateLoader was null in the configuration");
- } else {
- throw new IllegalStateException(
- "The template loader was already set to a non-ByteArrayTemplateLoader non-MultiTemplateLoader: "
- + tl);
- }
- }
-
- protected void addToDataModel(String name, Object value) {
- Object dm = getDataModel();
- if (dm == null) {
- dm = new HashMap<String, Object>();
- dataModel = dm;
- }
- if (dm instanceof Map) {
- ((Map) dm).put(name, value);
- } else {
- throw new IllegalStateException("Can't add to non-Map data-model: " + dm);
- }
- }
-
- protected Properties loadPropertiesFile(String name) throws IOException {
- Properties props = new Properties();
- InputStream in = getClass().getResourceAsStream(name);
- try {
- props.load(in);
- } finally {
- in.close();
- }
- return props;
- }
-
- protected Throwable assertErrorContains(String ftl, String... expectedSubstrings) {
- return assertErrorContains(null, ftl, null, expectedSubstrings);
- }
-
- protected Throwable assertErrorContains(String ftl, Class<? extends Throwable> exceptionClass,
- String... expectedSubstrings) {
- return assertErrorContains(null, ftl, exceptionClass, expectedSubstrings);
- }
-
- protected void assertErrorContainsForNamed(String name, String... expectedSubstrings) {
- assertErrorContains(name, null, null, expectedSubstrings);
- }
-
- protected void assertErrorContainsForNamed(String name, Class<? extends Throwable> exceptionClass,
- String... expectedSubstrings) {
- assertErrorContains(name, null, exceptionClass, expectedSubstrings);
- }
-
- private Throwable assertErrorContains(String name, String ftl, Class<? extends Throwable> exceptionClass,
- String... expectedSubstrings) {
- try {
- Template t;
- if (ftl == null) {
- t = getConfiguration().getTemplate(name);
- } else {
- t = new Template("adhoc", ftl, getConfiguration());
- }
- t.process(getDataModel(), new StringWriter());
- fail("The tempalte had to fail");
- return null;
- } catch (TemplateException e) {
- if (exceptionClass != null) {
- assertThat(e, instanceOf(exceptionClass));
- }
- assertContainsAll(e.getMessageWithoutStackTop(), expectedSubstrings);
- return e;
- } catch (ParseException e) {
- if (exceptionClass != null) {
- assertThat(e, instanceOf(exceptionClass));
- }
- assertContainsAll(e.getEditorMessage(), expectedSubstrings);
- return e;
- } catch (Exception e) {
- if (exceptionClass != null) {
- assertThat(e, instanceOf(exceptionClass));
- return e;
- } else {
- throw new RuntimeException("Unexpected exception class: " + e.getClass().getName(), e);
- }
- }
- }
-
- private void assertContainsAll(String msg, String... expectedSubstrings) {
- for (String needle: expectedSubstrings) {
- if (needle.startsWith("\\!")) {
- String netNeedle = needle.substring(2);
- if (msg.contains(netNeedle)) {
- fail("The message shouldn't contain substring " + _StringUtil.jQuote(netNeedle) + ":\n" + msg);
- }
- } else if (!msg.contains(needle)) {
- fail("The message didn't contain substring " + _StringUtil.jQuote(needle) + ":\n" + msg);
- }
- }
- }
-
- private String normalizeNewLines(String s) {
- return _StringUtil.replace(s, "\r\n", "\n").replace('\r', '\n');
- }
-
- public static class TestBean {
- private int x;
- private boolean b;
-
- public int getX() {
- return x;
- }
- public void setX(int x) {
- this.x = x;
- }
- public boolean isB() {
- return b;
- }
- public void setB(boolean b) {
- this.b = b;
- }
-
- public int intM() {
- return 1;
- }
-
- public int intMP(int x) {
- return x;
- }
-
- public void voidM() {
-
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/TestConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/TestConfigurationBuilder.java b/freemarker-core/src/test/java/org/apache/freemarker/test/TestConfigurationBuilder.java
deleted file mode 100644
index 7f869db..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/TestConfigurationBuilder.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Configuration.Builder;
-import org.apache.freemarker.core.Version;
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
-
-/**
- * Configuration builder you should use instead of {@link Builder} in unit tests.
- * It tries to make the behavior of the tests independent of the environment where we run them. For convenience, it
- * has a {@link ByteArrayTemplateLoader} as the default template loader.
- */
-public class TestConfigurationBuilder extends Configuration.ExtendableBuilder<TestConfigurationBuilder> {
-
- private static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT+1");
- private final Class<?> classTemplateLoaderBase;
- private TemplateLoader defaultTemplateLoader;
-
- public TestConfigurationBuilder() {
- this((Version) null);
- }
-
- public TestConfigurationBuilder(Class<?> classTemplateLoaderBase) {
- this(null, classTemplateLoaderBase);
- }
-
- public TestConfigurationBuilder(Version incompatibleImprovements) {
- this(incompatibleImprovements, null);
- }
-
- public TestConfigurationBuilder(Version incompatibleImprovements, Class<?> classTemplateLoaderBase) {
- super(incompatibleImprovements != null ? incompatibleImprovements : Configuration.VERSION_3_0_0);
- this.classTemplateLoaderBase = classTemplateLoaderBase;
- }
-
- @Override
- protected Locale getDefaultLocale() {
- return Locale.US;
- }
-
- @Override
- protected Charset getDefaultSourceEncoding() {
- return StandardCharsets.UTF_8;
- }
-
- @Override
- protected TimeZone getDefaultTimeZone() {
- return DEFAULT_TIME_ZONE;
- }
-
- @Override
- protected TemplateLoader getDefaultTemplateLoader() {
- if (defaultTemplateLoader == null) {
- if (classTemplateLoaderBase == null) {
- defaultTemplateLoader = new ByteArrayTemplateLoader();
- } else {
- defaultTemplateLoader = new MultiTemplateLoader(
- new ByteArrayTemplateLoader(),
- new ClassTemplateLoader(classTemplateLoaderBase, ""));
- }
- }
- return defaultTemplateLoader;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/Matchers.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/Matchers.java b/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/Matchers.java
deleted file mode 100644
index 7552a8d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/Matchers.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.hamcerst;
-
-import org.hamcrest.Matcher;
-
-public final class Matchers {
-
- private Matchers() {
- // Not meant to be instantiated
- }
-
- public static Matcher<String> containsStringIgnoringCase(String substring) {
- return StringContainsIgnoringCase.containsStringIgnoringCase(substring);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/StringContainsIgnoringCase.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/StringContainsIgnoringCase.java b/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/StringContainsIgnoringCase.java
deleted file mode 100644
index 914bbd1..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/hamcerst/StringContainsIgnoringCase.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.hamcerst;
-
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
-import org.hamcrest.core.SubstringMatcher;
-
-public class StringContainsIgnoringCase extends SubstringMatcher {
-
- public StringContainsIgnoringCase(String substring) {
- super(substring);
- }
-
- @Override
- protected boolean evalSubstringOf(String s) {
- return s.toLowerCase().contains(substring.toLowerCase());
- }
-
- @Override
- protected String relationship() {
- return "containing ignoring case";
- }
-
- @Factory
- public static Matcher<String> containsStringIgnoringCase(String substring) {
- return new StringContainsIgnoringCase(substring);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/package.html
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/package.html b/freemarker-core/src/test/java/org/apache/freemarker/test/package.html
deleted file mode 100644
index 3dbb3fb..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- 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.
--->
-<html>
-<head>
-</head>
-<body>
-<p>Testing-related classes that don't fit into the normal packages.
-Normally you put the test classes into the same package where the
-tested classes are, but under <tt>src/test/java/<tt> instead of
-under <tt>src/main/java/<tt>.</p>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java b/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
deleted file mode 100644
index 07bf0ca..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * 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.util.AssertDirective;
-import org.apache.freemarker.test.util.AssertEqualsDirective;
-import org.apache.freemarker.test.util.AssertFailsDirective;
-import org.apache.freemarker.test.util.FileTestCase;
-import org.apache.freemarker.test.util.NoOutputDirective;
-import org.apache.freemarker.test.util.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();
- }
-
- }
-
-}
[26/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/multimodels.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/multimodels.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/multimodels.ftl
new file mode 100644
index 0000000..f356386
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/multimodels.ftl
@@ -0,0 +1,84 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Test of Multiple Model implementations</title>
+</head>
+<body>
+
+<p>Let's begin with a simple model:</p>
+<p>${message}</p>
+
+<p>Cool, now get into the first model. This implements a scalar, list, and
+hash as a single class. Let's try some tests...</p>
+
+<p>${data}</p>
+
+<p>Now as a list...</p>
+
+<#list data as item>${item}<br />
+</#list>
+
+<p>Index into a list...</p>
+<p>${data[ 1 ]}</p>
+<p>List size is: ${data.size}</p>
+<p>List size is: ${data["size"]}</p>
+
+<p>Now, again, as a hash. First using dot notation, then using [] notation:</p>
+
+<p>${data.selftest}</p>
+<p>${data["selftest"]}</p>
+
+<p>Now for the tricky stuff... use a model to index into another model...</p>
+<p>${test}</p>
+<p>${data[ test ]}</p>
+<p>${self}</p>
+<p>${data[ self + "test" ]}</p>
+
+<p>Same thing, this time a List index...</p>
+<p>${zero}</p>
+<p>${data[ zero ]}</p>
+<p>${data[ zero + 1 ]}</p>
+
+<p>Now, do the same recursively...</p>
+<p>${data}</p>
+<p>${data.model2}</p>
+<p>${data.model2( "test" )}</p>
+<p>${data.model2( data, data.selftest, message )}</p>
+
+<p>Does this really not work?</p>
+<p>${data[ 10 ]}</p>
+<p>${data[ 10 ].selftest}</p>
+<p>${data[ 10 ].message}</p>
+
+<p>(Again, with Hashes)</p>
+<p>${data.nesting1.nested}</p>
+<p>${data.nesting1.nested.selftest}</p>
+
+<p>${data["nesting1"].nested}</p>
+<p>${data["nesting1"].nested["selftest"]}</p>
+<p>${data["nesting1"]["nested"]["selftest"]}</p>
+
+<p>As I suspected! (Manual on Expressions needs updating.)</p>
+
+<p>Second test on list size</p>
+<p>${data.one.size}</p>
+<p>${data.one["size"]}</p>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nested.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nested.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nested.ftl
new file mode 100644
index 0000000..46f4492
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nested.ftl
@@ -0,0 +1,29 @@
+<#--
+ 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.
+-->
+<#macro repeat count>
+ <#local y = "test">
+ <#list 1..count as x>
+ ${y} ${count}/${x}: <#nested x, "asdf"> <#-- the second body parameter is not used below -->
+ </#list>
+</#macro>
+<@repeat count=3>${y?default("undefined")} ${x?default("undefined")} ${count?default("undefined")}</...@repeat>
+<#global x = "X">
+<#global y = "Y">
+<#global count = "Count">
+<@repeat count=3 ; param1>${y?default("undefined")} ${x?default("undefined")} ${count?default("undefined")} ${param1}</...@repeat>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nestedinclude.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nestedinclude.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nestedinclude.ftl
new file mode 100644
index 0000000..c6e7b11
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/nestedinclude.ftl
@@ -0,0 +1,21 @@
+<#--
+ 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.
+-->
+<#assign nestedMessage = "I'm here, mon!">
+${.main.bar}
+<#-- ${.root.message} -->
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-defaultresolver.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-defaultresolver.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-defaultresolver.ftl
new file mode 100644
index 0000000..9efcd88
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-defaultresolver.ftl
@@ -0,0 +1,23 @@
+<#--
+ 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.
+-->
+<#attempt>
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("works")}
+<#recover>
+fails
+</#attempt>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-optin.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-optin.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-optin.ftl
new file mode 100644
index 0000000..7545b58
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/new-optin.ftl
@@ -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.
+-->
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel"?new("works")}
+<#attempt>
+${"org.apache.freemarker.test.templatesuite.models.NewTestModel2"?new("works")}
+<#recover>
+fails
+</#attempt>
+
+<#include "subdir/new-optin.ftl">
+
+<#include "subdir/new-optin-2.ftl">
+
+<#include "subdir/subsub/new-optin.ftl">
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines1.ftl
new file mode 100644
index 0000000..18f4b32
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines1.ftl
@@ -0,0 +1,29 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Newlines Test</title>
+</head>
+<body>
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines2.ftl
new file mode 100644
index 0000000..ac8337c
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/newlines2.ftl
@@ -0,0 +1,33 @@
+<#--
+ 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.
+-->
+<#assign message="Hello, world!\n">
+<#assign normalizeNewlines = "org.apache.freemarker.core.util.NormalizeNewlines"?new()>
+<@normalizeNewlines>
+<html>
+<head>
+<title>FreeMarker: Newlines the Second Test</title>
+</head>
+<body>
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+</body>
+</html>
+</...@normalizeNewlines>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/noparse.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/noparse.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/noparse.ftl
new file mode 100644
index 0000000..f7f1be3
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/noparse.ftl
@@ -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.
+-->
+<html>
+<head>
+<title>FreeMarker: NoParse Test</title>
+</head>
+<body>
+<#noparse>
+
+A simple test follows:
+
+${message}
+
+A more rigorous test, showing that we're not faking it:
+
+${message@#$%&}
+
+</#noparse>
+<#if message?exists>
+ <p>Message exists!
+ <#noparse>
+ ...and even generates output!
+ <#if message>
+ Nested statements are ok, too.
+ </#if>
+ </#noparse>
+ </p>
+</#if>
+
+Here's another edge case, this time, trying to output a <noparse>
+inside another <noparse>
+
+<#noparse>
+
+This is what the noparse instruction looks like:
+
+<#nop</#noparse><#noparse>arse>This part of the template wont be parsed by the
+FreeMarker parser. Instead, it will be treated as verbatim text information,
+and output as such.</#nop</#noparse><#noparse>arse>
+
+The rest of the template appears here.
+</#noparse>
+
+Simple.
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-format.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-format.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-format.ftl
new file mode 100644
index 0000000..d060a44
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-format.ftl
@@ -0,0 +1,42 @@
+<#--
+ 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.
+-->
+<#setting number_format = ",##0.##">
+<#setting locale = "fr_FR">
+${1}
+${1?c}
+${1234567.886}
+${1234567.886?c}
+<#setting number_format = "0.00">
+${1}
+${1?c}
+${1234567.886}
+${1234567.886?c}
+${int?c}
+${double?c}
+${double2?c}
+${double3?c}
+${double4?c}
+${bigDecimal?c}
+${bigDecimal2?c}
+<@assertEquals expected="INF" actual="INF"?number?c />
+<@assertEquals expected="INF" actual="INF"?number?c />
+<@assertEquals expected="-INF" actual="-INF"?number?c />
+<@assertEquals expected="-INF" actual="-INF"?number?float?c />
+<@assertEquals expected="NaN" actual="NaN"?number?float?c />
+<@assertEquals expected="NaN" actual="NaN"?number?float?c />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-literal.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-literal.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-literal.ftl
new file mode 100644
index 0000000..6342afe
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-literal.ftl
@@ -0,0 +1,133 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Number Literal Test</title>
+</head>
+<body>
+<#assign hash = {"1" : "one",
+ "12" : "twelve",
+ "2one" : "two-one",
+ "one2" : "one-two"}
+ list = ["zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "ten",
+ "eleven",
+ "twelve"],
+ foo = "bar",
+ one = "one",
+ "1" = "one",
+ "12" = "twelve",
+ "2one" = "two-one",
+ "one2" = "one-two",
+ call = "org.apache.freemarker.test.templatesuite.models.SimpleTestMethod"?new()
+>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Now perform a number assignment:</p>
+
+#{1.300000?double}
+
+<#assign mynumber = 1.8, USA="en_US" />
+<#assign myfloat = mynumber?float />
+
+My number is: ${mynumber}
+<#setting locale="en_US">
+My float is: #{myfloat ; m6}
+The int part is: ${myfloat?int}
+
+<#assign mymessage = mynumber?string>
+
+${mymessage + 3}
+
+<p>Now use numbers in assignment</p>
+
+<#assign mymessage = 1 + 5>
+${mymessage}
+
+<#assign mymessage = mymessage + 2>
+#{mymessage}
+
+<p>Try numbers in tests</p>
+
+<#if (mymessage == 152)>
+MyMessage is 152
+<#else>
+MyMessage is not 152, its: ${mymessage}.
+</#if >
+
+<if (mymessage > 5)>
+ MyMessage is greater than five.
+</if
+
+<#switch mymessage>
+ <#case 1>
+ MyMessage is one
+ <#break>
+
+ <#case 15>
+ MyMessage is fifteen
+ <#break>
+
+ <#case 152>
+ MyMessage is one-five-two
+ <#break>
+
+ <#default>
+ MyMessage is: ${mymessage}.
+ <#break>
+
+</#switch>
+
+<p>Now for numbers in dynamic keys:</p>
+
+<#assign one = 1>
+<#assign two = 2>
+
+${list[ 1 ]}
+${list[ 1 + 2 ]}
+
+<p>Numbers in hashes:</p>
+
+${hash[ 1 + "2" ]}
+${hash[ "1" + 2 ]}
+${hash[ "1" + two ]}
+
+
+<p>Numbers in method calls:</p>
+
+${call( 1 )}
+${call( one )}
+${call( one + "2" )}
+${call( one + 2 )}
+${call( 1 + 2 )}
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-math-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-math-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-math-builtins.ftl
new file mode 100644
index 0000000..6dab082
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-math-builtins.ftl
@@ -0,0 +1,78 @@
+<#--
+ 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.
+-->
+<@assertEquals actual=0?abs expected=0 />
+<@assertEquals actual=3?abs expected=3 />
+<@assertEquals actual=(-3)?abs expected=3 />
+<@assertEquals actual=3.5?abs expected=3.5 />
+<@assertEquals actual=(-3.5)?abs expected=3.5 />
+
+<@assert test=fNan?abs?is_nan />
+<@assert test=dNan?abs?is_nan />
+<@assert test=fNinf?abs?is_infinite />
+<@assert test=dPinf?abs?is_infinite />
+<@assert test=fNinf lt 0 />
+<@assert test=dPinf gt 0 />
+<@assert test=fNinf?abs gt 0 />
+<@assert test=dPinf?abs gt 0 />
+
+<@assertEquals actual=fn?abs expected=0.05 />
+<@assertEquals actual=dn?abs expected=0.05 />
+<@assertEquals actual=ineg?abs expected=5 />
+<@assertEquals actual=ln?abs expected=5 />
+<@assertEquals actual=sn?abs expected=5 />
+<@assertEquals actual=bn?abs expected=5 />
+<@assertEquals actual=bin?abs expected=5 />
+<@assertEquals actual=bdn?abs expected=0.05 />
+
+<@assertEquals actual=fp?abs expected=0.05 />
+<@assertEquals actual=dp?abs expected=0.05 />
+<@assertEquals actual=ip?abs expected=5 />
+<@assertEquals actual=lp?abs expected=5 />
+<@assertEquals actual=sp?abs expected=5 />
+<@assertEquals actual=bp?abs expected=5 />
+<@assertEquals actual=bip?abs expected=5 />
+<@assertEquals actual=bdp?abs expected=0.05 />
+
+<@assert test=!0?is_infinite />
+<@assert test=!fn?is_infinite />
+<@assert test=!dn?is_infinite />
+<@assert test=!ineg?is_infinite />
+<@assert test=!ln?is_infinite />
+<@assert test=!sn?is_infinite />
+<@assert test=!bn?is_infinite />
+<@assert test=!bin?is_infinite />
+<@assert test=!bdn?is_infinite />
+<@assert test=!fNan?is_infinite />
+<@assert test=!dNan?is_infinite />
+<@assert test=fNinf?is_infinite />
+<@assert test=dPinf?is_infinite />
+
+<@assert test=!0?is_nan />
+<@assert test=!fn?is_nan />
+<@assert test=!dn?is_nan />
+<@assert test=!ineg?is_nan />
+<@assert test=!ln?is_nan />
+<@assert test=!sn?is_nan />
+<@assert test=!bn?is_nan />
+<@assert test=!bin?is_nan />
+<@assert test=!bdn?is_nan />
+<@assert test=fNan?is_nan />
+<@assert test=dNan?is_nan />
+<@assert test=!fNinf?is_nan />
+<@assert test=!dPinf?is_nan />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-to-date.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-to-date.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-to-date.ftl
new file mode 100644
index 0000000..403e033
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/number-to-date.ftl
@@ -0,0 +1,35 @@
+<#--
+ 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.
+-->
+${1305575275540?number_to_datetime?iso_utc_ms} == 2011-05-16T19:47:55.54Z
+${1305575275540?number_to_date?iso_utc} == 2011-05-16
+${1305575275540?number_to_time?iso_utc_ms} == 19:47:55.54Z
+
+${1305575275540?long?number_to_datetime?iso_utc_ms} == 2011-05-16T19:47:55.54Z
+${1305575275540?double?number_to_datetime?iso_utc_ms} == 2011-05-16T19:47:55.54Z
+${bigInteger?number_to_datetime?iso_utc_ms} == 2011-05-16T19:47:55.54Z
+${bigDecimal?number_to_datetime?iso_utc_ms} == 2011-05-16T19:47:55.54Z
+${1000?float?number_to_datetime?iso_utc} == 1970-01-01T00:00:01Z
+${1000?int?number_to_datetime?iso_utc} == 1970-01-01T00:00:01Z
+${0?byte?number_to_datetime?iso_utc} == 1970-01-01T00:00:00Z
+
+<#attempt>
+${9999991305575275540?number_to_datetime?iso_utc} <#-- doesn't fit into long -->
+<#recover>
+failed
+</#attempt>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/numerical-cast.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/numerical-cast.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/numerical-cast.ftl
new file mode 100644
index 0000000..221b61b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/numerical-cast.ftl
@@ -0,0 +1,82 @@
+<#ftl>
+<#--
+ 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.
+-->
+<#setting locale="en_US">
+<#setting number_format="0.#########">
+
+<#assign testlist= [ 0, 1, -1, 0.5, 1.5, -0.5,
+ -1.5, 0.25, -0.25, 1.75, -1.75,
+ 1.01, -1.01, 0.01, -0.01,
+ 127, 128, -127, -128,
+ 32767, 32768, -32767, -32768,
+ 2147483647, 2147483648, -2147483647, -2147483648,
+ 4294967295, 4294967296, -4294967295, -4294967296,
+ 2147483647.1, 2147483648.1, -2147483647.1, -2147483648.1,
+ 4294967295.1, 4294967296.1, -4294967295.1, -4294967296.1
+ 2147483647.5, 2147483648.5, -2147483647.5, -2147483648.5,
+ 4294967295.5, 4294967296.5, -4294967295.5, -4294967296.5
+ ] />
+
+?int:
+<#list testlist as result>
+ ${result}?int=${result?int}
+</#list>
+
+?double
+<#list testlist as result>
+ ${result}?double=${result?double}
+</#list>
+
+?long
+<#list testlist as result>
+ ${result}?long=${result?long}
+</#list>
+
+?long from date
+ ${"2011-05-08 18:00:15 GMT"?date("yyyy-MM-dd HH:mm:ss z")?long} = 1304877615000
+
+?float
+<#list testlist as result>
+ ${result}?float=${result?float}
+</#list>
+
+?byte
+<#list testlist as result>
+ ${result}?byte=${result?byte}
+</#list>
+
+?short
+<#list testlist as result>
+ ${result}?short=${result?short}
+</#list>
+
+?floor
+<#list testlist as result>
+ ${result}?floor=${result?floor}
+</#list>
+
+?ceiling
+<#list testlist as result>
+ ${result}?ceiling=${result?ceiling}
+</#list>
+
+?round
+<#list testlist as result>
+ ${result}?round=${result?round}
+</#list>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding1.ftl
new file mode 100644
index 0000000..da1128f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding1.ftl
@@ -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.
+-->
+Output charset: ${.output_encoding?default("undefined")}
+URL escaping charset: ${.url_escaping_charset?default("undefined")}
+
+<#assign s="a/%b">
+<#setting url_escaping_charset="UTF-16">
+${s?url}
+${s?url}
+<#setting url_escaping_charset="ISO-8859-1">
+${s?url}
+${s?url}
+${s?url('UTF-16')}
+${s?url}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding2.ftl
new file mode 100644
index 0000000..3a4f24d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding2.ftl
@@ -0,0 +1,28 @@
+<#--
+ 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.
+-->
+Output charset: ${.output_encoding?default("undefined")}
+URL escaping charset: ${.url_escaping_charset?default("undefined")}
+
+<#assign s="a/%b">
+UTF-16: ${s?url}
+ISO-8859-1: ${s?url('ISO-8859-1')}
+UTF-16: ${s?url}
+<#setting url_escaping_charset="ISO-8859-1">
+ISO-8859-1: ${s?url}
+ISO-8859-1: ${s?url}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding3.ftl
new file mode 100644
index 0000000..3a4f24d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/output-encoding3.ftl
@@ -0,0 +1,28 @@
+<#--
+ 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.
+-->
+Output charset: ${.output_encoding?default("undefined")}
+URL escaping charset: ${.url_escaping_charset?default("undefined")}
+
+<#assign s="a/%b">
+UTF-16: ${s?url}
+ISO-8859-1: ${s?url('ISO-8859-1')}
+UTF-16: ${s?url}
+<#setting url_escaping_charset="ISO-8859-1">
+ISO-8859-1: ${s?url}
+ISO-8859-1: ${s?url}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/overloaded-methods.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/overloaded-methods.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/overloaded-methods.ftl
new file mode 100644
index 0000000..329d041
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/overloaded-methods.ftl
@@ -0,0 +1,411 @@
+<#--
+ 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.
+-->
+
+<@assertEquals actual=obj.mStringArrayVsListPreference(obj.javaStringList) expected="mStringArrayVsListPreference(List [a, b])" />
+<@assertEquals actual=obj.mStringArrayVsListPreference(obj.javaStringArray) expected="mStringArrayVsListPreference(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVsListPreference(obj.javaObjectArray) expected="mStringArrayVsListPreference(List [a, b])" />
+
+<#-- Check if non-overloaded calls still work; they share some code with overloaded methods: -->
+<@assertEquals actual=obj.mIntArrayNonOverloaded([1, 2, 3]) expected="mIntArrayNonOverloaded(int[] [1, 2, 3])" />
+<@assertEquals actual=obj.mIntegerArrayNonOverloaded([1, 2, 3]) expected="mIntegerArrayNonOverloaded(Integer[] [1, 2, 3])" />
+<@assertEquals actual=obj.mIntegerListNonOverloaded([1, 2, 3]) expected="mIntegerListNonOverloaded(List<Integer> [1, 2, 3])" />
+<@assertEquals actual=obj.mStringListNonOverloaded(['a', 'b', 'c']) expected="mStringListNonOverloaded(List<String> [a, b, c])" />
+<@assertEquals actual=obj.mStringListNonOverloaded(obj.javaStringList) expected="mStringListNonOverloaded(List<String> [a, b])" />
+<@assertEquals actual=obj.mStringListNonOverloaded(obj.javaStringArray) expected="mStringListNonOverloaded(List<String> [a, b])" />
+<@assertEquals actual=obj.mStringArrayNonOverloaded(['a', 'b', 'c']) expected="mStringArrayNonOverloaded(String[] [a, b, c])" />
+<@assertEquals actual=obj.mStringArrayNonOverloaded(obj.javaStringList) expected="mStringArrayNonOverloaded(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayNonOverloaded(obj.javaStringArray) expected="mStringArrayNonOverloaded(String[] [a, b])" />
+<@assertEquals actual=obj.mObjectListNonOverloaded(['a', 'b', 3]) expected="mObjectListNonOverloaded(List<Object> [a, b, 3])" />
+<@assertEquals actual=obj.mObjectListNonOverloaded(obj.javaStringList) expected="mObjectListNonOverloaded(List<Object> [a, b])" />
+<@assertEquals actual=obj.mObjectListNonOverloaded(obj.javaStringArray) expected="mObjectListNonOverloaded(List<Object> [a, b])" />
+<@assertEquals actual=obj.mObjectArrayNonOverloaded(['a', 'b', 3]) expected="mObjectArrayNonOverloaded(Object[] [a, b, 3])" />
+<@assertEquals actual=obj.mObjectArrayNonOverloaded(obj.javaStringList) expected="mObjectArrayNonOverloaded(Object[] [a, b])" />
+<@assertEquals actual=obj.mObjectArrayNonOverloaded(obj.javaStringArray) expected="mObjectArrayNonOverloaded(Object[] [a, b])" />
+
+<@assertEquals actual=obj.mStringArrayVsListPreference(obj.javaStringArray) expected="mStringArrayVsListPreference(String[] [a, b])" />
+
+<@assertEquals actual=obj.mStringArrayVarargsNonOverloaded('a', 'b') expected="mStringArrayVarargsNonOverloaded(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsNonOverloaded(['a', 'b']) expected="mStringArrayVarargsNonOverloaded(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsNonOverloaded(obj.javaStringList) expected="mStringArrayVarargsNonOverloaded(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsNonOverloaded(obj.javaStringArray) expected="mStringArrayVarargsNonOverloaded(String[] [a, b])" />
+
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded1('a', 'b') expected="mStringArrayVarargsOverloaded1(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded1(['a', 'b']) expected="mStringArrayVarargsOverloaded1(List [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded1(obj.javaStringList) expected="mStringArrayVarargsOverloaded1(List [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded1(obj.javaStringArray) expected="mStringArrayVarargsOverloaded1(String[] [a, b])" />
+
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2('a', 'b') expected="mStringArrayVarargsOverloaded2(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2('a') expected="mStringArrayVarargsOverloaded2(String a)" />
+
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3(['a']) expected="mStringArrayVarargsOverloaded3(String[] [a])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3(['a', 'b']) expected="mStringArrayVarargsOverloaded3(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3(['a', 'b', 'c']) expected="mStringArrayVarargsOverloaded3(String[] [a, b, c])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3('a') expected="mStringArrayVarargsOverloaded3(String[] [a])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3('a', 'b') expected="mStringArrayVarargsOverloaded3(String a, String b)" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded3('a', 'b', 'c') expected="mStringArrayVarargsOverloaded3(String[] [a, b, c])" />
+
+<@assertEquals actual=obj.mListOrString(['a', 'b']) expected="mListOrString(List [a, b])" />
+<@assertEquals actual=obj.mListOrString('a') expected="mListOrString(String a)" />
+<@assertEquals actual=obj.mListListOrString([['a'], 'b', 3]) expected="mListListOrString(List [[a], b, 3])" />
+<@assertEquals actual=obj.mListListOrString('s') expected="mListListOrString(String s)" />
+
+<#-- Because the fixed arg interpretations are ambiguous, it only considers the vararg interpretations: -->
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(['a', 'b', 'c']) expected="mStringArrayVarargsOverloaded4(List[] [[a, b, c]])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4('a', 'b', 'c') expected="mStringArrayVarargsOverloaded4(String[] [a, b, c])" />
+
+<#-- Fixed arg solutions have priority: -->
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringList) expected="mStringArrayVarargsOverloaded4(List[] [[a, b]])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringArray) expected="mStringArrayVarargsOverloaded4(String[] [a, b])" />
+
+<#-- Choses between the vararg solutions: -->
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringList, obj.javaStringList) expected="mStringArrayVarargsOverloaded4(List[] [[a, b], [a, b]])" />
+
+<#-- Until there's no overloading String->Character conversion work: -->
+<@assertEquals actual=obj.mCharNonOverloaded('c') expected="mCharNonOverloaded(char c)" />
+<@assertEquals actual=obj.mCharNonOverloaded(obj.javaString) expected="mCharNonOverloaded(char s)" />
+<@assertEquals actual=obj.mCharacterNonOverloaded('c') expected="mCharacterNonOverloaded(Character c)" />
+<@assertEquals actual=obj.mCharacterNonOverloaded(obj.javaString) expected="mCharacterNonOverloaded(Character s)" />
+
+<@assertEquals actual=obj.mCharOrStringOverloaded('s', 1) expected="mCharOrStringOverloaded(String s, int 1)" />
+<@assertEquals actual=obj.mCharacterOrStringOverloaded('s', 1) expected="mCharacterOrStringOverloaded(String s, int 1)" />
+<@assertEquals actual=obj.mCharOrStringOverloaded2('ss') expected="mCharOrStringOverloaded2(String ss)" />
+<@assertEquals actual=obj.mCharacterOrStringOverloaded2('ss') expected="mCharacterOrStringOverloaded2(String ss)" />
+
+<@assertEquals actual=obj.mVarargs('a', obj.getNnS('b'), obj.getNnS('c')) expected='mVarargs(String... a1 = abc)' />
+
+<@assertEquals actual=obj.mNull1(null) expected="mNull1(String a1 = null)" />
+<@assertEquals actual=obj.mNull1(123) expected="mNull1(int a1 = 123)" />
+<@assertEquals actual=obj.mNull2(null) expected="mNull2(String a1 = null)" />
+<@assertEquals actual=obj.mVarargs('a', null) expected="mVarargs(String... a1 = anull)" />
+<@assertEquals actual=obj.mVarargs(null, 'a') expected="mVarargs(File a1, String... a2)" />
+<@assertEquals actual=obj.mSpecificity('a', 'b') expected="mSpecificity(String a1, Object a2)" />
+
+<@assertEquals actual=obj.mChar('a') expected='mChar(char a1 = a)' />
+<@assertEquals actual=obj.mBoolean(true) expected="mBoolean(boolean a1 = true)" />
+<@assertEquals actual=obj.mBoolean(null) expected="mBoolean(Boolean a1 = null)" />
+
+<@assertEquals actual=obj.mIntNonOverloaded(123?long) expected=123 />
+<@assertEquals actual=obj.mIntNonOverloaded(123) expected=123 />
+<@assertEquals actual=obj.mIntNonOverloaded(123.5) expected=123 />
+<@assertEquals actual=obj.mIntNonOverloaded(2147483648) expected=-2147483648 /> <#-- overflow -->
+<@assertEquals actual=obj.mNumBoxedVSBoxed(123.5) expected='mNumBoxedVSBoxed(Long a1 = 123)' />
+<@assertEquals actual=obj.mNumBoxedVSBoxed(123?int) expected='mNumBoxedVSBoxed(Long a1 = 123)' />
+<@assertEquals actual=obj.mNumBoxedVSBoxed(123?long) expected="mNumBoxedVSBoxed(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedVSBoxed(123?short) expected="mNumBoxedVSBoxed(Short a1 = 123)" />
+<@assertEquals
+ actual=obj.mNumUnambigous(2147483648) expected="mNumUnambigous(Integer a1 = -2147483648)" /> <#-- overflow -->
+
+<@assertEquals actual=obj.mIntPrimVSBoxed(123?int) expected="mIntPrimVSBoxed(int a1 = 123)" />
+<@assertEquals actual=obj.mIntPrimVSBoxed(123?short) expected="mIntPrimVSBoxed(int a1 = 123)" />
+<@assertEquals actual=obj.mIntPrimVSBoxed(123) expected="mIntPrimVSBoxed(int a1 = 123)" />
+<#-- This doesn't fail as 123L can be converted to int without loss: -->
+<@assertEquals actual=obj.mIntPrimVSBoxed(123?long) expected="mIntPrimVSBoxed(int a1 = 123)" />
+
+<@assertEquals actual=obj.mNumPrimVSPrim(123?short) expected="mNumPrimVSPrim(short a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimVSPrim(123?int) expected="mNumPrimVSPrim(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimVSPrim(123?long) expected="mNumPrimVSPrim(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimVSPrim(123?double) expected="mNumPrimVSPrim(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimVSPrim(123456) expected="mNumPrimVSPrim(long a1 = 123456)" />
+
+<@assertEquals actual=obj.mNumPrimAll(123?byte) expected="mNumPrimAll(byte a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll(123?short) expected="mNumPrimAll(short a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll(123?int) expected="mNumPrimAll(int a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll(123?long) expected="mNumPrimAll(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll(123?float) expected="mNumPrimAll(float a1 = 123.0)" />
+<@assertEquals actual=obj.mNumPrimAll(123?double) expected="mNumPrimAll(double a1 = 123.0)" />
+<@assertEquals actual=obj.mNumPrimAll(123) expected="mNumPrimAll(BigDecimal a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll(obj.bigInteger(123)) expected="mNumPrimAll(BigInteger a1 = 123)" />
+
+<@assertEquals actual=obj.mNumBoxedAll(123?byte) expected="mNumBoxedAll(Byte a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll(123?short) expected="mNumBoxedAll(Short a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll(123?int) expected="mNumBoxedAll(Integer a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll(123?long) expected="mNumBoxedAll(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll(123?float) expected="mNumBoxedAll(Float a1 = 123.0)" />
+<@assertEquals actual=obj.mNumBoxedAll(123?double) expected="mNumBoxedAll(Double a1 = 123.0)" />
+<@assertEquals actual=obj.mNumBoxedAll(123) expected="mNumBoxedAll(BigDecimal a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll(obj.bigInteger(123)) expected="mNumBoxedAll(BigInteger a1 = 123)" />
+
+<@assertEquals actual=obj.mNumPrimAll2nd(123?byte) expected="mNumPrimAll2nd(short a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll2nd(123?short) expected="mNumPrimAll2nd(short a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll2nd(123?int) expected="mNumPrimAll2nd(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll2nd(123?long) expected="mNumPrimAll2nd(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimAll2nd(123?float) expected="mNumPrimAll2nd(double a1 = 123.0)" />
+<@assertEquals actual=obj.mNumPrimAll2nd(123?double) expected="mNumPrimAll2nd(double a1 = 123.0)" />
+
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?byte) expected="mNumBoxedAll2nd(Short a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?short) expected="mNumBoxedAll2nd(Short a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?int) expected="mNumBoxedAll2nd(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?long) expected="mNumBoxedAll2nd(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?float) expected="mNumBoxedAll2nd(Double a1 = 123.0)" />
+<@assertEquals actual=obj.mNumBoxedAll2nd(123?double) expected="mNumBoxedAll2nd(Double a1 = 123.0)" />
+
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(123?int) expected="mNumPrimFallbackToNumber(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(123?long) expected="mNumPrimFallbackToNumber(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(123?double) expected="mNumPrimFallbackToNumber(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(123.5?double) expected="mNumPrimFallbackToNumber(Number a1 = 123.5)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(123) expected="mNumPrimFallbackToNumber(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(obj.bigInteger(123)) expected="mNumPrimFallbackToNumber(long a1 = 123)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(obj.bigInteger(9223372036854775808))
+ expected="mNumPrimFallbackToNumber(Number a1 = 9223372036854775808)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber(obj.rational(246, 2)) expected="mNumPrimFallbackToNumber(Number a1 = 246/2)" />
+<@assertEquals actual=obj.mNumPrimFallbackToNumber('x') expected="mNumPrimFallbackToNumber(Object a1 = x)" />
+
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(123?int) expected="mNumBoxedFallbackToNumber(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(123?long) expected="mNumBoxedFallbackToNumber(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(123?double) expected="mNumBoxedFallbackToNumber(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(123.5?double) expected="mNumBoxedFallbackToNumber(Number a1 = 123.5)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(123) expected="mNumBoxedFallbackToNumber(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(obj.bigInteger(123)) expected="mNumBoxedFallbackToNumber(Long a1 = 123)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(obj.bigInteger(9223372036854775808))
+ expected="mNumBoxedFallbackToNumber(Number a1 = 9223372036854775808)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber(obj.rational(246, 2)) expected="mNumBoxedFallbackToNumber(Number a1 = 246/2)" />
+<@assertEquals actual=obj.mNumBoxedFallbackToNumber('x') expected="mNumBoxedFallbackToNumber(Object a1 = x)" />
+
+<@assertEquals actual=obj.mDecimalLoss(1.5) expected="mDecimalLoss(double a1 = 1.5)" />
+<@assertEquals actual=obj.mDecimalLoss(1.5?double) expected="mDecimalLoss(double a1 = 1.5)" />
+
+<@assertEquals actual=obj.mNumConversionLoses1(1?double, '', '') expected="Number 1.0 java.lang.Double" />
+<@assertEquals actual=obj.mNumConversionLoses1(1?short, '', '') expected="Number 1 java.lang.Short" />
+<@assertEquals actual=obj.mNumConversionLoses1(1?long, '', '') expected="Number 1 java.lang.Long" />
+<@assertEquals actual=obj.mNumConversionLoses2(1?double, '', '') expected="Number 1.0 java.lang.Double" />
+<@assertEquals actual=obj.mNumConversionLoses2(1?short, '', '') expected="Number 1 java.lang.Short" />
+<@assertEquals actual=obj.mNumConversionLoses2(1?long, '', '') expected="Number 1 java.lang.Long" />
+<@assertEquals actual=obj.mNumConversionLoses3(1?double, '', '') expected="Serializable 1.0 java.lang.Double" />
+<@assertEquals actual=obj.mNumConversionLoses3(1?int, '', '') expected="Serializable 1 java.lang.Integer" />
+<@assertEquals actual=obj.mNumConversionLoses3(1?short, '', '') expected="Serializable 1 java.lang.Short" />
+<@assertEquals actual=obj.mNumConversionLoses3(1?long, '', '') expected="Serializable 1 java.lang.Long" />
+
+<#-- BigDecimal-to-int is preferred over to-long for BC and user expectations: -->
+<@assertEquals actual=obj.nIntAndLong(1) expected="nIntAndLong(int 1)" />
+<@assertEquals actual=obj.nIntAndLong(1?long) expected="nIntAndLong(long 1)" />
+<#-- BigDecimal-to-short is, however unfavored due to the higher chance of overflow: -->
+<@assertEquals actual=obj.nIntAndShort(1) expected="nIntAndShort(int 1)" />
+<@assertEquals actual=obj.nIntAndShort(1?short) expected="nIntAndShort(short 1)" />
+<@assertEquals actual=obj.nLongAndShort(1) expected="nLongAndShort(long 1)" />
+<@assertEquals actual=obj.nLongAndShort(1?short) expected="nLongAndShort(short 1)" />
+
+<@assertEquals actual=obj.varargs1(null, 1, 2, 3.5) expected='varargs1(String s = null, double... xs = [1.0, 2.0, 3.5])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2.5, 3) expected='varargs1(String s = null, double... xs = [1.0, 2.5, 3.0])' />
+<@assertEquals actual=obj.varargs1(null, 1.5, 2, 3) expected='varargs1(String s = null, double... xs = [1.5, 2.0, 3.0])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2, 'c') expected='varargs1(String s = null, Object... xs = [1, 2, c])' />
+<@assertEquals actual=obj.varargs1(null, 1, 'b', 3) expected='varargs1(String s = null, Object... xs = [1, b, 3])' />
+<@assertEquals actual=obj.varargs1(null, 'a', 2, 3) expected='varargs1(String s = null, Object... xs = [a, 2, 3])' />
+<@assertEquals actual=obj.varargs1('s', 1, 2, 3) expected='varargs1(String s = "s", int... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs1('s', 1.1, 2.1, 3.1) expected='varargs1(String s = "s", double... xs = [1.1, 2.1, 3.1])' />
+<@assertEquals actual=obj.varargs1('s', 'a', 'b', 'c') expected='varargs1(String s = "s", Object... xs = [a, b, c])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2, 3) expected='varargs1(String s = null, int... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs1(null, 1.1, 2.1, 3.1) expected='varargs1(String s = null, double... xs = [1.1, 2.1, 3.1])' />
+<@assertEquals actual=obj.varargs1(null, 'a', 'b', 'c') expected='varargs1(String s = null, Object... xs = [a, b, c])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2, 3?double) expected='varargs1(String s = null, int... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2?double, 3?double) expected='varargs1(String s = null, double... xs = [1.0, 2.0, 3.0])' />
+<@assertEquals actual=obj.varargs1(null, 1, 2?float, 3?float) expected='varargs1(String s = null, double... xs = [1.0, 2.0, 3.0])' />
+<@assertEquals actual=obj.varargs1(null, 1?double, 2?byte, 3?byte) expected='varargs1(String s = null, int... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs1(0, 1, 2, 3) expected='varargs1(Object s = 0, Object... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs1('s') expected='varargs1(String s = "s", int... xs = [])' />
+
+<@assertEquals actual=obj.varargs2(1, 2.5, 3) expected='varargs2(double... xs = [1.0, 2.5, 3.0])' />
+<@assertEquals actual=obj.varargs2(1, 2.5?double, 3) expected='varargs2(double... xs = [1.0, 2.5, 3.0])' />
+<@assertEquals actual=obj.varargs2(1?int, 2.5?double, 3) expected='varargs2(double... xs = [1.0, 2.5, 3.0])' />
+<@assertEquals actual=obj.varargs2(1?long, 2.5?double, 3) expected='varargs2(double... xs = [1.0, 2.5, 3.0])' />
+<@assertEquals actual=obj.varargs2(1?long, 2?double, 3) expected='varargs2(int... xs = [1, 2, 3])' />
+
+<@assertEquals actual=obj.varargs3(1, 2, 3) expected='varargs3(Comparable... xs = [1, 2, 3])' />
+<@assertEquals actual=obj.varargs3('a', 'b', 'c') expected='varargs3(String... xs = [a, b, c])' />
+<@assertEquals actual=obj.varargs3(1, 'b', 'c') expected='varargs3(Comparable... xs = [1, b, c])' />
+<@assertEquals actual=obj.varargs3('a', 'b', 3) expected='varargs3(Comparable... xs = [a, b, 3])' />
+<@assertEquals actual=obj.varargs3('a', [], 3) expected='varargs3(Object... xs = [a, [], 3])' />
+<@assertEquals actual=obj.varargs3(null, 'b', null) expected='varargs3(String... xs = [null, b, null])' />
+<@assertEquals actual=obj.varargs3(null, 2, null) expected='varargs3(Comparable... xs = [null, 2, null])' />
+<@assertEquals actual=obj.varargs3(null, [], null) expected='varargs3(Object... xs = [null, [], null])' />
+<@assertEquals actual=obj.varargs3(null, null, null) expected='varargs3(String... xs = [null, null, null])' />
+<@assertEquals actual=obj.varargs3() expected='varargs3(String... xs = [])' />
+
+<@assertEquals actual=obj.varargs4(null) expected='varargs4(Integer... xs = [null])' />
+<@assertEquals actual=obj.varargs4(null, null, null) expected='varargs4(Integer... xs = [null, null, null])' />
+<@assertEquals actual=obj.varargs4(1, null, 2) expected='varargs4(Integer... xs = [1, null, 2])' />
+<@assertEquals actual=obj.varargs4(1) expected='varargs4(int... xs = [1])' />
+<@assertEquals actual=obj.varargs4(1, 2, 3) expected='varargs4(int... xs = [1, 2, 3])' />
+
+<@assertEquals actual=obj.varargs5(1, 2, 3, 4, 5) expected='varargs5(int a1 = 1, int a2 = 2, int a3 = 3, int... xs = [4, 5])' />
+<@assertEquals actual=obj.varargs5(1, 2, 3, 4) expected='varargs5(int a1 = 1, int a2 = 2, int a3 = 3, int... xs = [4])' />
+<@assertEquals actual=obj.varargs5(1, 2, 3) expected='varargs5(int a1 = 1, int a2 = 2, int a3 = 3, int... xs = [])' />
+<@assertEquals actual=obj.varargs5(1, 2) expected='varargs5(int a1 = 1, int a2 = 2, int... xs = [])' />
+<@assertEquals actual=obj.varargs5(1) expected='varargs5(int a1 = 1, int... xs = [])' />
+<@assertEquals actual=obj.varargs5() expected='varargs5(int... xs = [])' />
+
+<@assertEquals actual=obj.varargs6('s', 2) expected='varargs6(String a1 = s, int... xs = [2])' />
+<@assertEquals actual=obj.varargs6('s') expected='varargs6(String a1 = s, int... xs = [])' />
+<@assertEquals actual=obj.varargs6(1, 2) expected='varargs6(Object a1 = 1, int a2 = 2, int... xs = [])' />
+<@assertFails message="no compatible overloaded">${obj.varargs6(1)}</@>
+
+<@assertEquals actual=obj.varargs7(1?int, 2?int) expected='varargs7(int... xs = [1, 2])' />
+<@assertEquals actual=obj.varargs7(1?short, 2?int) expected='varargs7(short a1 = 1, int... xs = [2])' />
+
+<#-- Tests that a pre-2.3.21 bug is fixed now: -->
+<@assertEquals actual=obj.mVarargsIgnoredTail(1, 2, 3) expected='mVarargsIgnoredTail(int... is = [1, 2, 3])' />
+<@assertEquals actual=obj.mVarargsIgnoredTail(1, 2, 3.5) expected='mVarargsIgnoredTail(int i = 1, double... ds = [2.0, 3.5])' />
+
+<@assertEquals actual=obj.mNullAmbiguous('a') expected='mNullAmbiguous(String s = a)' />
+<@assertEquals actual=obj.mNullAmbiguous(123) expected='mNullAmbiguous(int i = 123)' />
+<@assertEquals actual=obj.mNullAmbiguous(1.9) expected='mNullAmbiguous(int i = 1)' />
+<@assertEquals actual=obj.mNullAmbiguous(1?double) expected='mNullAmbiguous(int i = 1)' />
+<@assertFails message="no compatible overloaded">${obj.mNullAmbiguous(1.9?double)}</@>
+<@assertFails message="multiple compatible overloaded">${obj.mNullAmbiguous(null)}</@>
+
+<@assertFails message="multiple compatible overloaded">${obj.mNullAmbiguous2(null)}</@>
+
+<@assertEquals actual=obj.mNullNonAmbiguous(null) expected='mNullNonAmbiguous(String s = null)' />
+
+<#-- The primitive int-s will win twice, but then String wins over Object, which is stronger: -->
+<@assertEquals actual=obj.mLowRankWins(1, 2, 'a') expected='mLowRankWins(Integer x = 1, Integer y = 2, String s = a)' />
+
+<@assertEquals actual=obj.mRareWrappings(obj.file, obj.adaptedNumber, obj.adaptedNumber, obj.adaptedNumber, obj.stringWrappedAsBoolean)
+ expected='mRareWrappings(File f = file, double d1 = 123.0002, Double d2 = 123.0002, double d3 = 123.0002, b = true)' />
+<@assertEquals actual=obj.mRareWrappings(obj.stringWrappedAsBoolean, obj.adaptedNumber, obj.adaptedNumber, obj.adaptedNumber, obj.stringAdaptedToBoolean)
+ expected='mRareWrappings(String s = yes, double d1 = 123.0002, Double d2 = 123.0002, double d3 = 123.0002, b = true)' />
+<@assertEquals actual=obj.mRareWrappings(obj.stringAdaptedToBoolean2, obj.wrapperNumber, obj.wrapperNumber, obj.wrapperNumber, obj.stringAdaptedToBoolean2)
+ expected='mRareWrappings(String s = yes, double d1 = 123.0001, Double d2 = 123.0001, double d3 = 123.0001, b = true)' />
+<@assertEquals actual=obj.mRareWrappings(obj.booleanWrappedAsAnotherBoolean, 0, 0, 0, obj.booleanWrappedAsAnotherBoolean)
+ expected='mRareWrappings(Object o = true, double d1 = 0.0, Double d2 = 0.0, double d3 = 0.0, b = true)' />
+<@assertEquals actual=obj.mRareWrappings(obj.adaptedNumber, 0, 0, 0, !obj.booleanWrappedAsAnotherBoolean)
+ expected='mRareWrappings(Object o = 124, double d1 = 0.0, Double d2 = 0.0, double d3 = 0.0, b = true)' />
+<@assertEquals actual=obj.mRareWrappings(obj.booleanWrappedAsAnotherBoolean, 0, 0, 0, !obj.stringAdaptedToBoolean)
+ expected='mRareWrappings(Object o = true, double d1 = 0.0, Double d2 = 0.0, double d3 = 0.0, b = true)' />
+
+<@assertEquals actual=obj.mRareWrappings2(obj.adaptedNumber) expected='mRareWrappings2(byte b = 124)' />
+
+<#-- Test for List VS array problems due to too vague hinting: -->
+
+<@assertEquals actual=obj.mSeqToArrayNonOverloaded(['a', 'b'], 'c') expected='mSeqToArrayNonOverloaded(String[] [a, b], String c)' />
+
+<@assertEquals actual=obj.mSeqToArrayGoodHint(['a', 'b'], 'c') expected='mSeqToArrayGoodHint(String[] [a, b], String c)' />
+<@assertEquals actual=obj.mSeqToArrayGoodHint(['a', 'b'], 3) expected='mSeqToArrayGoodHint(String[] [a, b], int 3)' />
+
+<@assertEquals actual=obj.mSeqToArrayGoodHint2(['a', 'b'], 'c') expected='mSeqToArrayGoodHint2(String[] [a, b], String c)' />
+<@assertEquals actual=obj.mSeqToArrayGoodHint2('a') expected='mSeqToArrayGoodHint2(String a)' />
+
+<@assertEquals actual=obj.mSeqToArrayPoorHint(['a', 'b'], 'c') expected='mSeqToArrayPoorHint(String[] [a, b], String c)' />
+<@assertEquals actual=obj.mSeqToArrayPoorHint('a', 2) expected='mSeqToArrayPoorHint(String a, int 2)' />
+
+<@assertEquals actual=obj.mSeqToArrayPoorHint2(['a', 'b']) expected='mSeqToArrayPoorHint2(String[] [a, b])' />
+<@assertEquals actual=obj.mSeqToArrayPoorHint2('a') expected='mSeqToArrayPoorHint2(String a)' />
+
+<@assertFails message="multiple compatible overloaded"><@assertEquals actual=obj.mSeqToArrayPoorHint3(['a', 'b']) expected='mSeqToArrayPoorHint3(String[] [a, b])' /></@>
+<@assertFails message="multiple compatible overloaded"><@assertEquals actual=obj.mSeqToArrayPoorHint3([1, 2]) expected='mSeqToArrayPoorHint3(int[] [a, b])' /></@>
+
+<@assertEquals actual=obj.mStringArrayVsListPreference(['a', 'b']) expected="mStringArrayVsListPreference(List [a, b])" />
+<@assertEquals actual=obj.mStringArrayVsListPreference(obj.javaObjectArray) expected="mStringArrayVsListPreference(List [a, b])" />
+<@assertEquals actual=obj.mStringArrayVsObjectArrayPreference(['a', 'b']) expected="mStringArrayVsObjectArrayPreference(Object[] [a, b])" />
+<@assertEquals actual=obj.mIntArrayVsIntegerArrayPreference([1, 2]) expected="mIntArrayVsIntegerArrayPreference(Integer[] [1, 2])" />
+
+<@assertEquals actual=obj.mStringArrayVsObjectArrayPreference(obj.javaStringArray) expected="mStringArrayVsObjectArrayPreference(String[] [a, b])" />
+<@assertFails message="no compatible overloaded">${obj.mStringArrayVsObjectArrayPreference(obj.javaIntArray)}</@>
+<@assertEquals actual=obj.mStringArrayVsObjectArrayPreference(obj.javaIntegerArray) expected="mStringArrayVsObjectArrayPreference(Object[] [11, 22])" />
+
+<@assertEquals actual=obj.mIntegerArrayOverloaded([1, 2], 3) expected="mIntegerArrayOverloaded(Integer[] [1, 2], int 3)" />
+<@assertEquals actual=obj.mIntegerArrayOverloaded([1?byte, 2?byte], 3) expected="mIntegerArrayOverloaded(Integer[] [1, 2], int 3)" />
+<@assertEquals actual=obj.mIntegerArrayOverloaded(obj.javaIntegerList, 3) expected="mIntegerArrayOverloaded(Integer[] [1, 2], int 3)" />
+<@assertEquals actual=obj.mIntegerArrayOverloaded(obj.javaByteList, 3) expected="mIntegerArrayOverloaded(Integer[] [1, 2], int 3)" />
+
+<@assertEquals actual=obj.mStringArrayOverloaded(['a', 'b'], 3) expected="mStringArrayOverloaded(String[] [a, b], int 3)" />
+<@assertEquals actual=obj.mStringArrayOverloaded(obj.javaStringList, 3) expected="mStringArrayOverloaded(String[] [a, b], int 3)" />
+<@assertEquals actual=obj.mStringArrayOverloaded(obj.javaCharacterList, 3) expected="mStringArrayOverloaded(String[] [c, C], int 3)" />
+<@assertFails message="Failed to convert sequence">${obj.mStringArrayOverloaded([1, 2], 3)}</@>
+<@assertFails message="Failed to convert">${obj.mStringArrayOverloaded(obj.javaIntegerList, 3)}</@>
+
+<@assertEquals actual=obj.mCharArrayOverloaded(['a', 'b'], 3) expected="mCharArrayOverloaded(char[] [a, b], int 3)" />
+<@assertEquals actual=obj.mCharArrayOverloaded(obj.javaCharacterList, 3) expected="mCharArrayOverloaded(char[] [c, C], int 3)" />
+<@assertEquals actual=obj.mCharArrayOverloaded(obj.javaStringList, 3) expected="mCharArrayOverloaded(char[] [a, b], int 3)" />
+<@assertFails message="Failed to convert sequence">${obj.mCharArrayOverloaded(['aa', 'bb'], 3)}</@>
+<@assertFails message="Failed to convert">${obj.mCharArrayOverloaded(obj.javaString2List, 3)}</@>
+<@assertEquals actual=obj.mCharArrayOverloaded(['a', 'b'], 's') expected="mCharArrayOverloaded(Character[] [a, b], String s)" />
+<@assertEquals actual=obj.mCharArrayOverloaded(obj.javaCharacterList, 's') expected="mCharArrayOverloaded(Character[] [c, C], String s)" />
+<@assertEquals actual=obj.mCharArrayOverloaded(obj.javaStringList, 's') expected="mCharArrayOverloaded(Character[] [a, b], String s)" />
+<@assertFails message="Failed to convert sequence">${obj.mCharArrayOverloaded(['aa', 'bb'], 's')}</@>
+<@assertFails message="Failed to convert">${obj.mCharArrayOverloaded(obj.javaString2List, 's')}</@>
+
+<@assertEquals actual=obj.mStringArrayArrayOverloaded([['a', 'b'], ['c']], 3) expected="mStringArrayArrayOverloaded(String[][] [[a, b], [c]], int 3)" />
+<@assertEquals actual=obj.mStringArrayArrayOverloaded(obj.javaStringListList, 3) expected="mStringArrayArrayOverloaded(String[][] [[a, b], [c]], int 3)" />
+<@assertEquals actual=obj.mStringArrayArrayOverloaded(obj.javaStringSequenceList, 3) expected="mStringArrayArrayOverloaded(String[][] [[a, b], [c]], int 3)" />
+<@assertFails message="Failed to convert">${obj.mStringArrayArrayOverloaded(obj.javaStringList, 3)}</@>
+<@assertFails message="Failed to convert">${obj.mStringArrayArrayOverloaded(obj.javaIntegerListList, 3)}</@>
+<@assertEquals actual=obj.mIntArrayArrayOverloaded(obj.javaListOfIntArrays) expected="mIntArrayArrayOverloaded([[1, 2, 3], [], [4]])" />
+<@assertEquals actual=obj.mArrayOfListsOverloaded(obj.javaListOfIntArrays) expected="mArrayOfListsOverloaded([[1, 2, 3], [], [4]])" />
+<@assertEquals actual=obj.mIntArrayArrayNonOverloaded(obj.javaListOfIntArrays) expected="mIntArrayArrayNonOverloaded([[1, 2, 3], [], [4]])" />
+<@assertEquals actual=obj.mArrayOfListsNonOverloaded(obj.javaListOfIntArrays) expected="mArrayOfListsNonOverloaded([[1, 2, 3], [], [4]])" />
+
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2(['a', 'b']) expected="mStringArrayVarargsOverloaded2(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2(obj.javaStringList) expected="mStringArrayVarargsOverloaded2(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2(obj.javaStringArray) expected="mStringArrayVarargsOverloaded2(String[] [a, b])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded2(['a']) expected="mStringArrayVarargsOverloaded2(String[] [a])" />
+
+<#-- Situations that lead to array-to-List conversion: -->
+<@assertEquals actual=obj.mListOrString(obj.javaStringArray) expected="mListOrString(List [a, b])" />
+<@assertEquals actual=obj.mListOrString(obj.javaEmptyStringArray) expected="mListOrString(List [])" />
+<@assertEquals actual=obj.mListOrString(obj.javaIntArray) expected="mListOrString(List [11, 22])" />
+<@assertEquals actual=obj.mListListOrString(obj.javaStringArrayArray) expected="mListListOrString(List [[a, b], [], [c]])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringArray, obj.javaStringArray) expected="mStringArrayVarargsOverloaded4(List[] [[a, b], [a, b]])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringList, obj.javaStringArray) expected="mStringArrayVarargsOverloaded4(List[] [[a, b], [a, b]])" />
+<@assertEquals actual=obj.mStringArrayVarargsOverloaded4(obj.javaStringArray, obj.javaStringList) expected="mStringArrayVarargsOverloaded4(List[] [[a, b], [a, b]])" />
+
+<@assertEquals actual=obj.mMapOrBoolean(obj.hashAndScalarModel) expected="mMapOrBoolean(Map {})" />
+<@assertEquals actual=obj.mMapOrBoolean(obj.booleanAndScalarModel) expected="mMapOrBoolean(boolean true)" />
+<@assertEquals actual=obj.mMapOrBoolean(obj.allModels) expected="mMapOrBoolean(boolean true)" />
+
+<@assertEquals actual=obj.mMapOrBooleanVarargs(obj.hashAndScalarModel) expected="mMapOrBooleanVarargs(Map... [{}])" />
+<@assertEquals actual=obj.mMapOrBooleanVarargs(obj.hashAndScalarModel, obj.hashAndScalarModel) expected="mMapOrBooleanVarargs(Map... [{}, {}])" />
+<@assertEquals actual=obj.mMapOrBooleanVarargs(obj.allModels) expected="mMapOrBooleanVarargs(boolean... [true])" />
+<@assertEquals actual=obj.mMapOrBooleanVarargs(obj.allModels, obj.allModels) expected="mMapOrBooleanVarargs(boolean... [true, true])" />
+
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.hashAndScalarModel) expected="mMapOrBooleanFixedAndVarargs(Map {})" />
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.hashAndScalarModel, obj.hashAndScalarModel) expected="mMapOrBooleanFixedAndVarargs(Map... [{}, {}])" />
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.hashAndScalarModel, obj.hashAndScalarModel, obj.hashAndScalarModel) expected="mMapOrBooleanFixedAndVarargs(Map... [{}, {}, {}])" />
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.allModels) expected="mMapOrBooleanFixedAndVarargs(boolean true)" />
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.allModels, obj.allModels) expected="mMapOrBooleanFixedAndVarargs(boolean... [true, true])" />
+<@assertEquals actual=obj.mMapOrBooleanFixedAndVarargs(obj.allModels, obj.allModels, obj.allModels) expected="mMapOrBooleanFixedAndVarargs(boolean... [true, true, true])" />
+
+<@assertEquals actual=obj.mNumberOrArray(obj.allModels) expected="mNumberOrArray(Number 1)" />
+<@assertEquals actual=obj.mNumberOrArray([obj.allModels]) expected="mNumberOrArray(Object[] [1])" />
+<@assertEquals actual=obj.mIntOrArray(obj.allModels) expected="mIntOrArray(int 1)" />
+<@assertEquals actual=obj.mDateOrArray(obj.allModels) expected="mDateOrArray(Date 0)" />
+<@assertEquals actual=obj.mStringOrArray(obj.allModels) expected="mStringOrArray(String s)" />
+<@assertEquals actual=obj.mBooleanOrArray(obj.allModels) expected="mBooleanOrArray(boolean true)" />
+<@assertEquals actual=obj.mMapOrArray(obj.allModels) expected="mMapOrArray(Map {})" />
+<@assertEquals actual=obj.mListOrArray(obj.allModels) expected="mListOrArray(List [])" />
+<@assertEquals actual=obj.mSetOrArray(obj.allModels) expected="mSetOrArray(Set [])" />
+
+<@assertEquals actual=obj.mCharOrCharacterOverloaded('c') expected="mCharOrCharacterOverloaded(char c)" />
+<@assertEquals actual=obj.mCharOrCharacterOverloaded(obj.javaString) expected="mCharOrCharacterOverloaded(char s)" />
+<@assertEquals actual=obj.mCharOrCharacterOverloaded(null) expected="mCharOrCharacterOverloaded(Character null)" />
+
+<@assertEquals actual=obj.mCharOrBooleanOverloaded('c') expected="mCharOrBooleanOverloaded(char c)" />
+<@assertEquals actual=obj.mCharOrBooleanOverloaded(true) expected="mCharOrBooleanOverloaded(boolean true)" />
+
+<@assertEquals actual=obj.mCharOrStringOverloaded('c', true) expected="mCharOrStringOverloaded(char c, boolean true)" />
+<@assertEquals actual=obj.mCharacterOrStringOverloaded('c', true) expected="mCharacterOrStringOverloaded(Character c, boolean true)" />
+
+<@assertEquals actual=obj.mCharOrStringOverloaded2('c') expected="mCharOrStringOverloaded2(char c)" />
+<@assertEquals actual=obj.mCharacterOrStringOverloaded2('c') expected="mCharacterOrStringOverloaded2(Character c)" />
+<@assertEquals actual=obj.mCharOrStringOverloaded2('ss') expected="mCharOrStringOverloaded2(String ss)" />
+<@assertEquals actual=obj.mCharacterOrStringOverloaded2('ss') expected="mCharacterOrStringOverloaded2(String ss)" />
+
+<#-- The exmple given in bug report 363 -->
+<#assign theMap = {'name':'Billy', 'lastName', 'Pilgrim'} />
+<@assertEquals actual=obj.bugReport363(theMap, []) expected="Executed: testMethod(Map fields, List listField) on input: fields={name=Billy, lastName=Pilgrim} and listField=[]" />
+<@assertEquals actual=obj.bugReport363(theMap, null) expected="Executed: testMethod(Map fields, List listField) on input: fields={name=Billy, lastName=Pilgrim} and listField=null" />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/precedence.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/precedence.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/precedence.ftl
new file mode 100644
index 0000000..472b076
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/precedence.ftl
@@ -0,0 +1,61 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Operator Precedence Test</title>
+</head>
+<body>
+<#assign patate1 = "test">
+<#assign patate2 = "test">
+<#assign patate3 = "test">
+
+<#if patate1 == patate2 && patate2 == patate3>
+@@@@@@@@@@@
+</#if>
+
+<br />
+<br />
+
+<#if patate1?exists && patate2 == patate3>
+##########
+</#if>
+
+<br />
+<br />
+
+<#if patate2 == patate2 && (patate2==patate2)>
+&&&&&&&&&&&
+</#if>
+
+<br />
+<br />
+
+<#if (patate2 == patate2) && (patate2==patate2)>
+!!!!!!!!!!!
+</#if>
+
+<br />
+<br />
+
+<#if (patate2 == patate2) && patate2==patate2>
+$$$$$$$$$$$
+</#if>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range-common.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range-common.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range-common.ftl
new file mode 100644
index 0000000..142435b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/range-common.ftl
@@ -0,0 +1,314 @@
+<#--
+ 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.
+-->
+<#-- A version of "?join" that fails at null-s in the sequence: -->
+<#function join seq sep=''>
+ <#local r = "">
+ <#list seq as i>
+ <#local r = r + i>
+ <#if i_has_next>
+ <#local r = r + sep>
+ </#if>
+ </#list>
+ <#return r>
+</#function>
+
+<#----------------------->
+<#-- Range expressions -->
+
+<@assertEquals actual=join(1..2, ' ') expected="1 2" />
+<@assertEquals actual=join(1..1, ' ') expected="1" />
+<@assertEquals actual=join(1..0, ' ') expected="1 0" />
+<@assertEquals actual=join(1..-1, ' ') expected="1 0 -1" />
+<@assertEquals actual=join(-1..-1, ' ') expected="-1" />
+<@assertEquals actual=join(-1..1, ' ') expected="-1 0 1" />
+
+<@assertEquals actual=join(1..<3, ' ') expected="1 2" />
+<@assertEquals actual=join(1..<2, ' ') expected="1" />
+<@assertEquals actual=join(1..<1, ' ') expected="" />
+<@assertEquals actual=join(1..<0, ' ') expected="1" />
+<@assertEquals actual=join(1..<-1, ' ') expected="1 0" />
+<@assertEquals actual=join(1..<-2, ' ') expected="1 0 -1" />
+<@assertEquals actual=join(-1..<0, ' ') expected="-1" />
+<@assertEquals actual=join(-1..<2, ' ') expected="-1 0 1" />
+
+<@assertEquals actual=join(1..!3, ' ') expected="1 2" />
+<@assertEquals actual=join(1..!2, ' ') expected="1" />
+<@assertEquals actual=join(1..!1, ' ') expected="" />
+<@assertEquals actual=join(1..!0, ' ') expected="1" />
+<@assertEquals actual=join(1..!-1, ' ') expected="1 0" />
+<@assertEquals actual=join(1..!-2, ' ') expected="1 0 -1" />
+<@assertEquals actual=join(-1..!0, ' ') expected="-1" />
+<@assertEquals actual=join(-1..!2, ' ') expected="-1 0 1" />
+
+<@assertEquals actual=join(1..*2, ' ') expected="1 2" />
+<@assertEquals actual=join(1..*1, ' ') expected="1" />
+<@assertEquals actual=join(1..*0, ' ') expected="" />
+<@assertEquals actual=join(1..*-1, ' ') expected="1" />
+<@assertEquals actual=join(1..*-2, ' ') expected="1 0" />
+<@assertEquals actual=join(1..*-3, ' ') expected="1 0 -1" />
+<@assertEquals actual=join(-1..*1, ' ') expected="-1" />
+<@assertEquals actual=join(-1..*3, ' ') expected="-1 0 1" />
+
+<@assertEquals actual=1 expected=(0..0)?size />
+<@assertEquals actual=1 expected=(1..1)?size />
+<@assertEquals actual=1 expected=(2..2)?size />
+<@assertEquals actual=2 expected=(0..1)?size />
+<@assertEquals actual=2 expected=(1..2)?size />
+<@assertEquals actual=2 expected=(2..3)?size />
+<@assertEquals actual=3 expected=(2..4)?size />
+<@assertEquals actual=2 expected=(1..0)?size />
+<@assertEquals actual=2 expected=(2..1)?size />
+<@assertEquals actual=2 expected=(3..2)?size />
+<@assertEquals actual=3 expected=(4..2)?size />
+
+<@assertEquals actual=0 expected=(0..<0)?size />
+<@assertEquals actual=0 expected=(1..<1)?size />
+<@assertEquals actual=0 expected=(2..<2)?size />
+<@assertEquals actual=1 expected=(0..<1)?size />
+<@assertEquals actual=1 expected=(1..<2)?size />
+<@assertEquals actual=1 expected=(2..<3)?size />
+<@assertEquals actual=2 expected=(2..<4)?size />
+<@assertEquals actual=1 expected=(1..<0)?size />
+<@assertEquals actual=1 expected=(2..<1)?size />
+<@assertEquals actual=1 expected=(3..<2)?size />
+<@assertEquals actual=2 expected=(4..<2)?size />
+
+<@assertEquals actual=0 expected=(0..*0)?size />
+<@assertEquals actual=0 expected=(1..*0)?size />
+<@assertEquals actual=0 expected=(2..*0)?size />
+<@assertEquals actual=1 expected=(0..*1)?size />
+<@assertEquals actual=1 expected=(1..*1)?size />
+<@assertEquals actual=1 expected=(2..*1)?size />
+<@assertEquals actual=2 expected=(2..*2)?size />
+<@assertEquals actual=1 expected=(0..*-1)?size />
+<@assertEquals actual=1 expected=(1..*-1)?size />
+<@assertEquals actual=1 expected=(2..*-1)?size />
+<@assertEquals actual=2 expected=(0..*-2)?size />
+<@assertEquals actual=2 expected=(1..*-2)?size />
+<@assertEquals actual=2 expected=(2..*-2)?size />
+
+
+<#--------------------->
+<#-- String slicing: -->
+
+<#assign s = 'abcd'>
+
+<@assertEquals actual=s[0..] expected="abcd" />
+<@assertEquals actual=s[1..] expected="bcd" />
+<@assertEquals actual=s[2..] expected="cd" />
+<@assertEquals actual=s[3..] expected="d" />
+<@assertEquals actual=s[4..] expected="" />
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[5..] />
+</...@assertFails>
+<@assertFails message="6 is out of bounds">
+ <#assign _ = s[6..] />
+</...@assertFails>
+
+<@assertEquals actual=s[1..2] expected="bc" />
+<@assertEquals actual=s[1..1] expected="b" />
+<@assertEquals actual=s[0..1] expected="ab" />
+<@assertEquals actual=s[0..0] expected="a" />
+<@assertFails message="4 is out of bounds">
+ <#assign _ = s[1..4] />
+</...@assertFails>
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[1..5] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-1..1] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-2..1] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[0..-1] />
+</...@assertFails>
+
+<@assertEquals actual=s[1..<3] expected="bc" />
+<@assertEquals actual=s[1..!3] expected="bc" />
+<@assertEquals actual=s[1..<2] expected="b" />
+<@assertEquals actual=s[1..<0] expected="b" />
+<@assertEquals actual=s[1..<1] expected="" />
+<@assertEquals actual=s[0..<0] expected="" />
+<@assertEquals actual=s[5..<5] expected="" />
+<@assertEquals actual=s[6..<6] expected="" />
+<@assertEquals actual=s[-5..<-5] expected="" />
+<@assertFails message="negative">
+ <#assign _ = s[-5..<1] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[2..<-4] />
+</...@assertFails>
+<@assertFails message="decreasing">
+ <#assign _ = s[2..<0] />
+</...@assertFails>
+
+<@assertEquals actual=s[1..*-1] expected="b" />
+<@assertEquals actual=s[1..*0] expected="" />
+<@assertEquals actual=s[1..*1] expected="b" />
+<@assertEquals actual=s[1..*2] expected="bc" />
+<@assertEquals actual=s[1..*3] expected="bcd" />
+<@assertEquals actual=s[1..*4] expected="bcd" />
+<@assertEquals actual=s[1..*5] expected="bcd" />
+<@assertEquals actual=s[4..*1] expected="" />
+<@assertEquals actual=s[5..*0] expected="" />
+<@assertEquals actual=s[6..*0] expected="" />
+<@assertEquals actual=s[-5..*0] expected="" />
+<@assertEquals actual=s[0..*0] expected="" />
+<@assertEquals actual=s[0..*-1] expected="a" />
+<@assertEquals actual=s[0..*-2] expected="a" />
+<@assertEquals actual=s[0..*-3] expected="a" />
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[5..*1] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-1..*1] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-2..*1] />
+</...@assertFails>
+<@assertFails message="decreasing">
+ <#assign _ = s[1..*-2] />
+</...@assertFails>
+<@assertFails message="decreasing">
+ <#assign _ = s[1..*-3] />
+</...@assertFails>
+<@assertFails message="4 is out of bounds">
+ <#assign _ = s[4..*-1] />
+</...@assertFails>
+
+<#-- Legacy string backward-range bug kept for compatibility: -->
+<@assertEquals actual=s[1..0] expected="" />
+<@assertEquals actual=s[2..1] expected="" />
+<@assertFails message="negative">
+ <@assertEquals actual=s[0..-1] expected="" />
+</...@assertFails>
+<@assertFails message="decreasing">
+ <@assertEquals actual=s[3..1] expected="" />
+</...@assertFails>
+<#-- But it isn't emulated for operators introduced after 2.3.20: -->
+<@assertFails message="decreasing">
+ <@assertEquals actual=s[3..<1] expected="" />
+</...@assertFails>
+<@assertFails message="decreasing">
+ <@assertEquals actual=s[3..*-2] expected="" />
+</...@assertFails>
+
+<#assign r = 1..2>
+<@assertEquals actual=s[r] expected="bc" />
+<#assign r = 2..1>
+<@assertEquals actual=s[r] expected="" />
+<#assign r = 1..<2>
+<@assertEquals actual=s[r] expected="b" />
+<#assign r = 2..<4>
+<@assertEquals actual=s[r] expected="cd" />
+<#assign r = 2..>
+<@assertEquals actual=s[r] expected="cd" />
+<#assign r = 1..*2>
+<@assertEquals actual=s[r] expected="bc" />
+
+<#----------------------->
+<#-- Sequence slicing: -->
+
+<#assign s = ['a', 'b', 'c', 'd']>
+
+<@assertEquals actual=join(s[0..]) expected="abcd" />
+<@assertEquals actual=join(s[1..]) expected="bcd" />
+<@assertEquals actual=join(s[2..]) expected="cd" />
+<@assertEquals actual=join(s[3..]) expected="d" />
+<@assertEquals actual=join(s[4..]) expected="" />
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[5..] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-1..] />
+</...@assertFails>
+
+<@assertEquals actual=join(s[1..2]) expected="bc" />
+<@assertEquals actual=join(s[1..1]) expected="b" />
+<@assertEquals actual=join(s[0..1]) expected="ab" />
+<@assertEquals actual=join(s[0..0]) expected="a" />
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[1..5] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-1..0] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[0..-1] />
+</...@assertFails>
+
+<@assertEquals actual=join(s[1..<3]) expected="bc" />
+<@assertEquals actual=join(s[1..!3]) expected="bc" />
+<@assertEquals actual=join(s[1..<2]) expected="b" />
+<@assertEquals actual=join(s[1..<0]) expected="b" />
+<@assertEquals actual=join(s[1..<1]) expected="" />
+<@assertEquals actual=join(s[0..<0]) expected="" />
+
+<@assertEquals actual=join(s[1..0]) expected="ba" />
+<@assertEquals actual=join(s[2..1]) expected="cb" />
+<@assertEquals actual=join(s[2..0]) expected="cba" />
+<@assertEquals actual=join(s[2..<0]) expected="cb" />
+<@assertEquals actual=join(s[1..<0]) expected="b" />
+<@assertEquals actual=join(s[0..<0]) expected="" />
+<@assertEquals actual=join(s[3..<1]) expected="dc" />
+<@assertEquals actual=join(s[2..<1]) expected="c" />
+<@assertEquals actual=join(s[1..<1]) expected="" />
+<@assertEquals actual=join(s[0..<1]) expected="a" />
+<@assertEquals actual=join(s[0..<0]) expected="" />
+<@assertEquals actual=join(s[5..<5]) expected="" />
+<@assertEquals actual=join(s[-5..<-5]) expected="" />
+
+<@assertEquals actual=join(s[0..*-4]) expected="a" />
+<@assertEquals actual=join(s[1..*-4]) expected="ba" />
+<@assertEquals actual=join(s[1..*-3]) expected="ba" />
+<@assertEquals actual=join(s[1..*-2]) expected="ba" />
+<@assertEquals actual=join(s[1..*-1]) expected="b" />
+<@assertEquals actual=join(s[1..*0]) expected="" />
+<@assertEquals actual=join(s[1..*1]) expected="b" />
+<@assertEquals actual=join(s[1..*2]) expected="bc" />
+<@assertEquals actual=join(s[1..*3]) expected="bcd" />
+<@assertEquals actual=join(s[1..*4]) expected="bcd" />
+<@assertEquals actual=join(s[1..*5]) expected="bcd" />
+<@assertEquals actual=join(s[0..*3]) expected="abc" />
+<@assertEquals actual=join(s[2..*3]) expected="cd" />
+<@assertEquals actual=join(s[3..*3]) expected="d" />
+<@assertEquals actual=join(s[4..*3]) expected="" />
+<@assertFails message="5 is out of bounds">
+ <#assign _ = s[5..*3] />
+</...@assertFails>
+<@assertFails message="negative">
+ <#assign _ = s[-1..*2] />
+</...@assertFails>
+
+<#assign r = 1..2>
+<@assertEquals actual=join(s[r]) expected="bc" />
+<#assign r = 2..0>
+<@assertEquals actual=join(s[r]) expected="cba" />
+<#assign r = 1..<2>
+<@assertEquals actual=join(s[r]) expected="b" />
+<#assign r = 2..<0>
+<@assertEquals actual=join(s[r]) expected="cb" />
+<#assign r = 2..>
+<@assertEquals actual=join(s[r]) expected="cd" />
+<#assign r = 1..*2>
+<@assertEquals actual=join(s[r]) expected="bc" />
+<#assign r = 1..*-9>
+<@assertEquals actual=join(s[r]) expected="ba" />
[36/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
new file mode 100644
index 0000000..e8d5f2b
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
@@ -0,0 +1,138 @@
+/*
+ * 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.core.userpkg;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+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.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
+import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.UnformattableValueException;
+
+/**
+ * Formats like {@code %G} in {@code printf}, with the specified number of significant digits. Also has special
+ * formatter for HTML output format, where it uses the HTML "sup" element for exponents.
+ */
+public class PrintfGTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
+
+ public static final PrintfGTemplateNumberFormatFactory INSTANCE = new PrintfGTemplateNumberFormatFactory();
+
+ private PrintfGTemplateNumberFormatFactory() {
+ // Defined to decrease visibility
+ }
+
+ @Override
+ public TemplateNumberFormat get(String params, Locale locale, Environment env)
+ throws InvalidFormatParametersException {
+ Integer significantDigits;
+ if (!params.isEmpty()) {
+ try {
+ significantDigits = Integer.valueOf(params);
+ } catch (NumberFormatException e) {
+ throw new InvalidFormatParametersException(
+ "The format parameter must be an integer, but was (shown quoted) "
+ + _StringUtil.jQuote(params) + ".");
+ }
+ } else {
+ // Use the default of %G
+ significantDigits = null;
+ }
+ return new PrintfGTemplateNumberFormat(significantDigits, locale);
+ }
+
+ private static class PrintfGTemplateNumberFormat extends TemplateNumberFormat {
+
+ private final Locale locale;
+ private final String printfFormat;
+
+ private PrintfGTemplateNumberFormat(Integer significantDigits, Locale locale) {
+ printfFormat = "%" + (significantDigits != null ? "." + significantDigits : "") + "G";
+ this.locale = locale;
+ }
+
+ @Override
+ public String formatToPlainText(TemplateNumberModel numberModel)
+ throws UnformattableValueException, TemplateModelException {
+ final Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
+
+ // printf %G only accepts Double, BigDecimal and Float
+ final Number gCompatibleN;
+ if (n instanceof Double || n instanceof BigDecimal || n instanceof Float) {
+ gCompatibleN = n;
+ } else {
+ if (n instanceof BigInteger) {
+ gCompatibleN = new BigDecimal((BigInteger) n);
+ } else if (n instanceof Long) {
+ gCompatibleN = BigDecimal.valueOf(n.longValue());
+ } else {
+ gCompatibleN = Double.valueOf(n.doubleValue());
+ }
+ }
+
+ return String.format(locale, printfFormat, gCompatibleN);
+ }
+
+ @Override
+ public Object format(TemplateNumberModel numberModel)
+ throws UnformattableValueException, TemplateModelException {
+ String strResult = formatToPlainText(numberModel);
+
+ int expIdx = strResult.indexOf('E');
+ if (expIdx == -1) {
+ return strResult;
+ }
+
+ String expStr = strResult.substring(expIdx + 1);
+ int expSignifNumBegin = 0;
+ while (expSignifNumBegin < expStr.length() && isExpSignifNumPrefix(expStr.charAt(expSignifNumBegin))) {
+ expSignifNumBegin++;
+ }
+
+ return HTMLOutputFormat.INSTANCE.fromMarkup(
+ strResult.substring(0, expIdx)
+ + "*10<sup>"
+ + (expStr.charAt(0) == '-' ? "-" : "") + expStr.substring(expSignifNumBegin)
+ + "</sup>");
+ }
+
+ private boolean isExpSignifNumPrefix(char c) {
+ return c == '+' || c == '-' || c == '0';
+ }
+
+ @Override
+ public boolean isLocaleBound() {
+ return true;
+ }
+
+ @Override
+ public String getDescription() {
+ return "printf " + printfFormat;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
new file mode 100644
index 0000000..5767e93
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
@@ -0,0 +1,24 @@
+/*
+ * 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.core.userpkg;
+
+public class PublicAll {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java
new file mode 100644
index 0000000..e521d75
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.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.core.userpkg;
+
+public class PublicWithMixedConstructors {
+
+ private final String s;
+
+ public PublicWithMixedConstructors(Integer x) {
+ s = "Integer";
+ }
+
+ PublicWithMixedConstructors(int x) {
+ s = "int";
+ }
+
+ public String getS() {
+ return s;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
new file mode 100644
index 0000000..9fdec49
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
@@ -0,0 +1,26 @@
+/*
+ * 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.core.userpkg;
+
+public class PublicWithPackageVisibleConstructor {
+
+ PublicWithPackageVisibleConstructor() { }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
new file mode 100644
index 0000000..b8cab13
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
@@ -0,0 +1,71 @@
+/*
+ * 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.core.userpkg;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
+
+public class SeldomEscapedOutputFormat extends CommonMarkupOutputFormat<TemplateSeldomEscapedOutputModel> {
+
+ public static final SeldomEscapedOutputFormat INSTANCE = new SeldomEscapedOutputFormat();
+
+ private SeldomEscapedOutputFormat() {
+ // hide
+ }
+
+ @Override
+ public String getName() {
+ return "seldomEscaped";
+ }
+
+ @Override
+ public String getMimeType() {
+ return "text/seldomEscaped";
+ }
+
+ @Override
+ public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
+ out.write(escapePlainText(textToEsc));
+ }
+
+ @Override
+ public String escapePlainText(String plainTextContent) {
+ return plainTextContent.replaceAll("(\\.|\\\\)", "\\\\$1");
+ }
+
+ @Override
+ public boolean isLegacyBuiltInBypassed(String builtInName) {
+ return false;
+ }
+
+ @Override
+ public boolean isAutoEscapedByDefault() {
+ return false;
+ }
+
+ @Override
+ protected TemplateSeldomEscapedOutputModel newTemplateMarkupOutputModel(
+ String plainTextContent, String markupContent) {
+ return new TemplateSeldomEscapedOutputModel(plainTextContent, markupContent);
+ }
+
+}
\ 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/core/userpkg/TemplateDummyOutputModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java
new file mode 100644
index 0000000..c98df53
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.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.core.userpkg;
+
+import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
+
+public class TemplateDummyOutputModel extends CommonTemplateMarkupOutputModel<TemplateDummyOutputModel> {
+
+ TemplateDummyOutputModel(String plainTextContent, String markupContet) {
+ super(plainTextContent, markupContet);
+ }
+
+ @Override
+ public DummyOutputFormat getOutputFormat() {
+ return DummyOutputFormat.INSTANCE;
+ }
+
+}
\ 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/core/userpkg/TemplateSeldomEscapedOutputModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java
new file mode 100644
index 0000000..b0a21f7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.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.core.userpkg;
+
+import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
+
+public class TemplateSeldomEscapedOutputModel extends CommonTemplateMarkupOutputModel<TemplateSeldomEscapedOutputModel> {
+
+ TemplateSeldomEscapedOutputModel(String plainTextContent, String markupContet) {
+ super(plainTextContent, markupContet);
+ }
+
+ @Override
+ public SeldomEscapedOutputFormat getOutputFormat() {
+ return SeldomEscapedOutputFormat.INSTANCE;
+ }
+
+}
\ 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/core/util/DateUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java
new file mode 100644
index 0000000..0cd8fc0
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java
@@ -0,0 +1,1085 @@
+/*
+ * 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.core.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.apache.freemarker.core.util._DateUtil.CalendarFieldsToDateConverter;
+import org.apache.freemarker.core.util._DateUtil.DateParseException;
+import org.apache.freemarker.core.util._DateUtil.DateToISO8601CalendarFactory;
+import org.apache.freemarker.core.util._DateUtil.TrivialCalendarFieldsToDateConverter;
+
+import junit.framework.TestCase;
+
+public class DateUtilTest extends TestCase {
+
+ private final TimeZone originalDefaultTZ = TimeZone.getDefault();
+
+ @Override
+ protected void setUp() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("Europe/Prague"));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TimeZone.setDefault(originalDefaultTZ);
+ }
+
+ private final DateFormat df
+ = new SimpleDateFormat("G yyyy-MM-dd HH:mm:ss:S Z", Locale.US);
+ {
+ df.setTimeZone(_DateUtil.UTC);
+ }
+
+ private CalendarFieldsToDateConverter cf2dc = new TrivialCalendarFieldsToDateConverter();
+
+ private DateToISO8601CalendarFactory calendarFactory
+ = new _DateUtil.TrivialDateToISO8601CalendarFactory();
+
+ public DateUtilTest(String name) {
+ super(name);
+ }
+
+ public void testDateToUTCString() throws ParseException {
+ assertEquals(
+ "1998-10-30T15:30:00.512Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:512 +0400"), true));
+ assertEquals(
+ "1998-10-30T15:30:00.5Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:500 +0400"), true));
+ assertEquals(
+ "1998-10-30T15:30:00.51Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:510 +0400"), true));
+ assertEquals(
+ "1998-10-30T15:30:00.1Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:100 +0400"), true));
+ assertEquals(
+ "1998-10-30T15:30:00.01Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:10 +0400"), true));
+ assertEquals(
+ "1998-10-30T15:30:00.001Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 1998-10-30 19:30:00:1 +0400"), true));
+ assertEquals(
+ "2000-02-08T06:05:04Z",
+ dateToISO8601UTCDateTimeMSString(
+ df.parse("AD 2000-02-08 09:05:04:0 +0300"), true));
+ assertEquals(
+ "0099-02-28T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse(
+ "AD 0099-03-02 09:15:24:0 +0300"), true));
+ assertEquals(
+ "0010-02-28T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse("AD 0010-03-02 09:15:24:0 +0300"), true));
+ assertEquals(
+ "0001-02-28T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse("AD 0001-03-02 09:15:24:0 +0300"), true));
+ assertEquals(
+ "0000-02-29T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse("BC 0001-03-02 09:15:24:0 +0300"), true));
+ assertEquals(
+ "-1-02-28T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse("BC 2-03-02 09:15:24:0 +0300"), true));
+ assertEquals(
+ "10000-02-28T06:15:24Z",
+ dateToISO8601UTCDateTimeString(
+ df.parse("AD 10000-02-28 09:15:24:0 +0300"), true));
+
+ Date d = df.parse("AD 1998-10-30 19:30:00:512 +0400");
+ assertEquals(
+ "1998-10-30",
+ dateToISO8601UTCDateString(d));
+ assertEquals(
+ "15:30:00.512Z",
+ dateToISO8601UTCTimeMSString(d, true));
+ assertEquals(
+ "15:30:00.512",
+ dateToISO8601UTCTimeMSString(d, false));
+ assertEquals(
+ "1998-10-30",
+ dateToISO8601UTCDateString(
+ new java.sql.Date(d.getTime())));
+ assertEquals(
+ "15:30:00.512Z",
+ dateToISO8601UTCTimeMSString(
+ new java.sql.Time(d.getTime()), true));
+ }
+
+ public void testLocalTime() throws ParseException {
+ Date dsum = df.parse("AD 2010-05-09 20:00:00:0 UTC");
+ Date dwin = df.parse("AD 2010-01-01 20:00:00:0 UTC");
+
+ TimeZone tzRome = TimeZone.getTimeZone("Europe/Rome");
+ if (tzRome.getOffset(0) == 0) {
+ throw new RuntimeException(
+ "Can't get time zone for Europe/Rome!");
+ }
+ assertEquals(
+ "2010-05-09T22:00:00+02:00",
+ dateToISO8601DateTimeString(dsum, tzRome));
+ assertEquals(
+ "2010-01-01T21:00:00+01:00",
+ dateToISO8601DateTimeString(dwin, tzRome));
+ assertEquals(
+ "2010-05-09",
+ dateToISO8601DateString(dsum, tzRome));
+ assertEquals(
+ "2010-01-01",
+ dateToISO8601DateString(dwin, tzRome));
+ assertEquals(
+ "22:00:00+02:00",
+ dateToISO8601TimeString(dsum, tzRome));
+ assertEquals(
+ "21:00:00+01:00",
+ dateToISO8601TimeString(dwin, tzRome));
+
+ TimeZone tzNY = TimeZone.getTimeZone("America/New_York");
+ if (tzNY.getOffset(0) == 0) {
+ throw new RuntimeException(
+ "Can't get time zone for America/New_York!");
+ }
+ assertEquals(
+ "2010-05-09T16:00:00-04:00",
+ dateToISO8601DateTimeString(dsum, tzNY));
+ assertEquals(
+ "2010-01-01T15:00:00-05:00",
+ dateToISO8601DateTimeString(dwin, tzNY));
+ assertEquals(
+ "2010-05-09",
+ dateToISO8601DateString(dsum, tzNY));
+ assertEquals(
+ "2010-01-01",
+ dateToISO8601DateString(dwin, tzNY));
+ assertEquals(
+ "16:00:00-04:00",
+ dateToISO8601TimeString(dsum, tzNY));
+ assertEquals(
+ "15:00:00-05:00",
+ dateToISO8601TimeString(dwin, tzNY));
+
+ TimeZone tzFixed = TimeZone.getTimeZone("GMT+02:30");
+ assertEquals(
+ "2010-05-09T22:30:00+02:30",
+ dateToISO8601DateTimeString(dsum, tzFixed));
+ assertEquals(
+ "2010-01-01T22:30:00+02:30",
+ dateToISO8601DateTimeString(dwin, tzFixed));
+ }
+
+ public void testGetTimeZone() throws Exception {
+ assertTrue(_DateUtil.getTimeZone("GMT") != _DateUtil.UTC);
+ assertTrue(_DateUtil.getTimeZone("UT1") != _DateUtil.UTC);
+ assertEquals(_DateUtil.getTimeZone("UTC"), _DateUtil.UTC);
+
+ assertEquals(_DateUtil.getTimeZone("Europe/Rome"),
+ TimeZone.getTimeZone("Europe/Rome"));
+
+ assertEquals(_DateUtil.getTimeZone("Iceland"), // GMT and no DST
+ TimeZone.getTimeZone("Iceland"));
+
+ try {
+ _DateUtil.getTimeZone("Europe/NoSuch");
+ fail();
+ } catch (UnrecognizedTimeZoneException e) {
+ // good
+ }
+ }
+
+ public void testTimeOnlyDate() throws UnrecognizedTimeZoneException {
+ Date t = new Date(0L);
+ SimpleDateFormat tf = new SimpleDateFormat("HH:mm:ss");
+
+ tf.setTimeZone(_DateUtil.UTC);
+ assertEquals("00:00:00", tf.format(t));
+ assertEquals("00:00:00",
+ dateToISO8601UTCTimeString(t, false));
+
+ TimeZone gmt1 = _DateUtil.getTimeZone("GMT+01");
+ tf.setTimeZone(gmt1);
+ assertEquals("01:00:00", tf.format(t));
+ assertEquals("01:00:00+01:00",
+ dateToISO8601TimeString(t, gmt1));
+ }
+
+ public void testAccuracy() throws ParseException {
+ Date d = df.parse("AD 2000-02-08 09:05:04:250 UTC");
+ assertEquals("2000-02-08T09:05:04Z",
+ dateToISO8601UTCDateTimeString(d, true));
+ assertEquals("2000-02-08T09:05:04.25Z",
+ dateToISO8601String(d, true, true, true,
+ _DateUtil.ACCURACY_MILLISECONDS, null));
+ assertEquals("2000-02-08T09:05:04Z",
+ dateToISO8601String(d, true, true, true,
+ _DateUtil.ACCURACY_SECONDS, null));
+ assertEquals("2000-02-08T09:05Z",
+ dateToISO8601String(d, true, true, true,
+ _DateUtil.ACCURACY_MINUTES, null));
+ assertEquals("2000-02-08T09Z",
+ dateToISO8601String(d, true, true, true,
+ _DateUtil.ACCURACY_HOURS, null));
+
+ d = df.parse("AD 1998-10-30 19:30:00:000 +0400");
+ assertEquals(
+ "15:30:00Z",
+ dateToISO8601UTCTimeMSString(d, true));
+ assertEquals(
+ "15:30:00.000Z",
+ dateToISO8601UTCTimeMSFString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00Z",
+ dateToISO8601UTCDateTimeMSString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.000Z",
+ dateToISO8601UTCDateTimeMSFString(d, true));
+
+ d = df.parse("AD 1998-10-30 19:30:00:100 +0400");
+ assertEquals(
+ "15:30:00.1Z",
+ dateToISO8601UTCTimeMSString(d, true));
+ assertEquals(
+ "15:30:00.100Z",
+ dateToISO8601UTCTimeMSFString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.1Z",
+ dateToISO8601UTCDateTimeMSString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.100Z",
+ dateToISO8601UTCDateTimeMSFString(d, true));
+
+ d = df.parse("AD 1998-10-30 19:30:00:010 +0400");
+ assertEquals(
+ "15:30:00.01Z",
+ dateToISO8601UTCTimeMSString(d, true));
+ assertEquals(
+ "15:30:00.010Z",
+ dateToISO8601UTCTimeMSFString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.01Z",
+ dateToISO8601UTCDateTimeMSString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.010Z",
+ dateToISO8601UTCDateTimeMSFString(d, true));
+
+ d = df.parse("AD 1998-10-30 19:30:00:001 +0400");
+ assertEquals(
+ "15:30:00.001Z",
+ dateToISO8601UTCTimeMSString(d, true));
+ assertEquals(
+ "15:30:00.001Z",
+ dateToISO8601UTCTimeMSFString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.001Z",
+ dateToISO8601UTCDateTimeMSString(d, true));
+ assertEquals(
+ "1998-10-30T15:30:00.001Z",
+ dateToISO8601UTCDateTimeMSFString(d, true));
+ }
+
+ public void testXSFormatISODeviations() throws ParseException, UnrecognizedTimeZoneException {
+ Date dsum = df.parse("AD 2010-05-09 20:00:00:0 UTC");
+ Date dwin = df.parse("AD 2010-01-01 20:00:00:0 UTC");
+
+ TimeZone tzRome = _DateUtil.getTimeZone("Europe/Rome");
+
+ assertEquals(
+ "2010-01-01T21:00:00+01:00",
+ _DateUtil.dateToXSString(dwin, true, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+ assertEquals(
+ "2010-05-09T22:00:00+02:00",
+ _DateUtil.dateToXSString(dsum, true, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+ assertEquals(
+ "2010-01-01+01:00", // ISO doesn't allow date-only with TZ
+ _DateUtil.dateToXSString(dwin, true, false, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+ assertEquals(
+ "2010-05-09+02:00", // ISO doesn't allow date-only with TZ
+ _DateUtil.dateToXSString(dsum, true, false, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+ assertEquals(
+ "21:00:00+01:00",
+ _DateUtil.dateToXSString(dwin, false, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+ assertEquals(
+ "22:00:00+02:00",
+ _DateUtil.dateToXSString(dsum, false, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
+
+ assertEquals(
+ "-1-02-29T06:15:24Z", // ISO uses 0 for BC 1
+ _DateUtil.dateToXSString(
+ df.parse("BC 0001-03-02 09:15:24:0 +0300"),
+ true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC, calendarFactory));
+ assertEquals(
+ "-2-02-28T06:15:24Z", // ISO uses -1 for BC 2
+ _DateUtil.dateToXSString(
+ df.parse("BC 2-03-02 09:15:24:0 +0300"),
+ true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC, calendarFactory));
+ }
+
+ private String dateToISO8601DateTimeString(
+ Date date, TimeZone tz) {
+ return dateToISO8601String(date, true, true, true,
+ _DateUtil.ACCURACY_SECONDS, tz);
+ }
+
+ private String dateToISO8601UTCDateTimeString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, true, true, offsetPart,
+ _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601UTCDateTimeMSString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, true, true, offsetPart,
+ _DateUtil.ACCURACY_MILLISECONDS, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601UTCDateTimeMSFString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, true, true, offsetPart,
+ _DateUtil.ACCURACY_MILLISECONDS_FORCED, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601DateString(Date date, TimeZone tz) {
+ return dateToISO8601String(date, true, false, false,
+ _DateUtil.ACCURACY_SECONDS, tz);
+ }
+
+ private String dateToISO8601UTCDateString(Date date) {
+ return dateToISO8601String(date, true, false, false,
+ _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601TimeString(
+ Date date, TimeZone tz) {
+ return dateToISO8601String(date, false, true, true,
+ _DateUtil.ACCURACY_SECONDS, tz);
+ }
+
+ private String dateToISO8601UTCTimeString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, false, true, offsetPart,
+ _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601UTCTimeMSString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, false, true, offsetPart,
+ _DateUtil.ACCURACY_MILLISECONDS, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601UTCTimeMSFString(
+ Date date, boolean offsetPart) {
+ return dateToISO8601String(date, false, true, offsetPart,
+ _DateUtil.ACCURACY_MILLISECONDS_FORCED, _DateUtil.UTC);
+ }
+
+ private String dateToISO8601String(
+ Date date,
+ boolean datePart, boolean timePart, boolean offsetPart,
+ int accuracy,
+ TimeZone timeZone) {
+ return _DateUtil.dateToISO8601String(
+ date,
+ datePart, timePart, offsetPart,
+ accuracy,
+ timeZone,
+ calendarFactory);
+ }
+
+ public void testParseDate() throws DateParseException {
+ assertDateParsing(
+ "AD 1998-10-29 20:00:00:0 +0000",
+ null,
+ "1998-10-30+04:00", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 1998-10-30 02:00:00:0 +0000",
+ null,
+ "1998-10-30-02:00", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 1998-10-30 02:00:00:0 +0000",
+ "1998-10-30", _DateUtil.parseXSTimeZone("-02:00"));
+ assertDateParsing(
+ null,
+ "AD 1998-10-30 02:00:00:0 +0000",
+ "19981030", _DateUtil.parseXSTimeZone("-02:00"));
+ assertDateParsing(
+ "AD 1998-10-30 00:00:00:0 +0000",
+ null,
+ "1998-10-30Z", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "1998-10-30", _DateUtil.UTC);
+ assertDateParsing(
+ null,
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "19981030", _DateUtil.UTC);
+
+ assertDateParsing(
+ "AD 1998-10-29 20:00:00:0 +0000",
+ null,
+ "1998-10-30+04:00", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 1998-10-30 04:00:00:0 +0000",
+ null,
+ "1998-10-30-04:00", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 1998-10-30 00:00:00:0 +0000",
+ null,
+ "1998-10-30Z", _DateUtil.UTC);
+
+ try {
+ // XS doesn't have year 0
+ assertDateParsing(
+ "BC 0000-02-05 00:00:00:0 +0000",
+ null,
+ "0000-02-03Z", _DateUtil.UTC);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ assertDateParsing(
+ null,
+ "BC 0001-02-05 00:00:00:0 +0000",
+ "0000-02-03", _DateUtil.UTC);
+ assertDateParsing(
+ null,
+ "BC 0001-02-05 00:00:00:0 +0000",
+ "00000203", _DateUtil.UTC);
+
+ assertDateParsing(
+ "BC 0001-02-05 00:00:00:0 +0000", // Julian
+ "BC 0002-02-05 00:00:00:0 +0000", // Julian
+ "-0001-02-03", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateParsing(
+ null,
+ "BC 0002-02-05 00:00:00:0 +0000", // Julian
+ "-00010203", _DateUtil.UTC); // Proleptic Gregorian
+
+ assertDateParsing(
+ "AD 0001-02-05 00:00:00:0 +0000", // Julian
+ null,
+ "0001-02-03Z", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateParsing(
+ "AD 0001-02-05 00:00:00:0 +0000", // Julian
+ "0001-02-03", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateParsing(
+ null,
+ "AD 0001-02-05 00:00:00:0 +0000", // Julian
+ "00010203", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateParsing(
+ "AD 1001-12-07 00:00:00:0 +0000", // Julian
+ null,
+ "1001-12-13Z", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateParsing(
+ "AD 1001-12-07 00:00:00:0 +0000", // Julian
+ "1001-12-13", _DateUtil.UTC); // Proleptic Gregorian
+
+ assertDateParsing(
+ "AD 2006-12-31 00:00:00:0 +0000",
+ null,
+ "2006-12-31Z", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 2006-12-31 00:00:00:0 +0000",
+ "2006-12-31", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 2006-01-01 00:00:00:0 +0000",
+ null,
+ "2006-01-01Z", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 2006-01-01 00:00:00:0 +0000",
+ "2006-01-01", _DateUtil.UTC);
+ assertDateParsing(
+ "AD 12006-01-01 00:00:00:0 +0000",
+ "12006-01-01", _DateUtil.UTC);
+ assertDateParsing(
+ null,
+ "AD 12006-01-01 00:00:00:0 +0000",
+ "120060101", _DateUtil.UTC);
+ }
+
+ public void testParseDateMalformed() {
+ assertDateMalformed("1998-10-30x");
+ assertDateMalformed("+1998-10-30");
+ assertDateMalformed("1998-10-");
+ assertDateMalformed("1998-1-30");
+ assertDateMalformed("1998-10-30+01");
+ assertDateMalformed("1998-00-01");
+ assertDateMalformed("1998-13-01");
+ assertDateMalformed("1998-10-00");
+ assertDateMalformed("1998-10-32");
+ assertDateMalformed("1998-02-31");
+
+ assertISO8601DateMalformed("2100103");
+ assertISO8601DateMalformed("210-01-03");
+ assertISO8601DateMalformed("2012-0301");
+ assertISO8601DateMalformed("201203-01");
+ assertISO8601DateMalformed("2012-01-01+01:00");
+ }
+
+ public void testParseTime() throws DateParseException {
+ assertTimeParsing(
+ "AD 1970-01-01 17:30:05:0 +0000",
+ "17:30:05", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 17:30:05:0 +0000",
+ "173005", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:100 +0000",
+ "07:30:00.1", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:120 +0000",
+ "07:30:00.12", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "07:30:00.123", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "07:30:00.1235", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "07:30:00.12346", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "073000.12346", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "073000,12346", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:120 +0000",
+ "07:30:00.12", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 07:30:00:500 +0000",
+ "07:30:00.5", _DateUtil.UTC);
+
+ assertTimeParsing(
+ "AD 1970-01-01 16:30:05:0 +0000",
+ "17:30:05+01:00", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:30:05:0 +0000",
+ "173005+01", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 19:00:05:0 +0000",
+ "17:30:05-01:30", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 19:00:05:0 +0000",
+ "173005-0130", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-01 16:30:05:500 +0000",
+ "17:30:05.5+01:00", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:30:05:500 +0000",
+ "173005.5+0100", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:30:05:500 +0000",
+ "173005.5+01", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:00:00:0 +0000",
+ "170000+01", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:00:00:0 +0000",
+ "1700+01", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-01 16:00:00:0 +0000",
+ "17+01", _DateUtil.UTC);
+
+ assertTimeParsing(
+ "AD 1970-01-01 00:00:00:0 +0000",
+ "00:00:00", _DateUtil.UTC);
+ assertTimeParsing(
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "24:00:00", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "240000", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "2400", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "24:00", _DateUtil.UTC);
+ assertTimeParsing(
+ null,
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "24", _DateUtil.UTC);
+
+ assertTimeParsing(
+ "AD 1970-01-01 23:59:59:999 +0000",
+ "23:59:59.999", _DateUtil.UTC);
+ }
+
+ public void testParseTimeMalformed() {
+ assertTimeMalformed("00:0000");
+ assertTimeMalformed("00:00:00-01:60");
+ assertTimeMalformed("24:00:01");
+ assertTimeMalformed("00:00:61");
+ assertTimeMalformed("00:60:00");
+ assertTimeMalformed("25:00:00");
+ assertTimeMalformed("2:00:00");
+ assertTimeMalformed("02:0:00");
+ assertTimeMalformed("02:00:0");
+
+ assertISO8601TimeMalformed("1010101");
+ assertISO8601TimeMalformed("10101");
+ assertISO8601TimeMalformed("101");
+ assertISO8601TimeMalformed("1");
+ assertISO8601TimeMalformed("101010-1");
+ assertISO8601TimeMalformed("101010-100");
+ assertISO8601TimeMalformed("101010-10000");
+ assertISO8601TimeMalformed("101010+1");
+ assertISO8601TimeMalformed("101010+100");
+ assertISO8601TimeMalformed("101010+10000");
+ }
+
+ public void testParseDateTime() throws DateParseException {
+ assertDateTimeParsing(
+ "AD 1998-10-30 11:30:00:0 +0000",
+ "1998-10-30T15:30:00+04:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 11:30:00:0 +0000",
+ "19981030T153000+0400", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 11:30:00:500 +0000",
+ "1998-10-30T15:30:00.5+04:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 15:30:00:0 +0000",
+ "1998-10-30T15:30:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 15:30:00:0 +0000",
+ "19981030T1530Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 15:30:00:500 +0000",
+ "1998-10-30T15:30:00.5Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 11:30:00:0 +0000",
+ "1998-10-30T15:30:00+04:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 15:30:00:0 +0000",
+ "1998-10-30T15:30:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 15:30:00:0 +0000",
+ "1998-10-30T15:30:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 15:30:00:0 +0000",
+ "1998-10-30T15:30", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1998-10-29 20:00:00:0 +0000",
+ "1998-10-30T00:00:00+04:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 02:00:00:0 +0000",
+ "1998-10-30T00:00:00-02:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "1998-10-30T00:00:00Z", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1998-10-29 20:00:00:0 +0000",
+ "1998-10-30T00:00:00+04:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "1998-10-30T00:00:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "1998-10-30T00:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "1998-10-30T00:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 1998-10-30 00:00:00:0 +0000",
+ "19981030T00Z", _DateUtil.UTC);
+
+ // BC years
+ try {
+ assertDateTimeParsing(
+ "",
+ null,
+ "0000-02-03T00:00:00Z", _DateUtil.UTC);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ assertDateTimeParsing(
+ null,
+ "BC 0001-02-05 00:00:00:0 +0000",
+ "0000-02-03T00:00:00Z", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "BC 0001-02-05 00:00:00:0 +0000", // Julian
+ "BC 0002-02-05 00:00:00:0 +0000", // Julian
+ "-0001-02-03T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
+
+ assertDateTimeParsing(
+ "AD 0001-02-05 00:00:00:0 +0000", // Julian
+ "0001-02-03T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateTimeParsing(
+ "AD 1001-12-07 00:00:00:0 +0000", // Julian
+ "1001-12-13T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
+ assertDateTimeParsing(
+ "AD 11001-12-13 00:00:00:0 +0000",
+ "11001-12-13T00:00:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ null,
+ "AD 11001-12-13 00:00:00:0 +0000",
+ "110011213T00Z", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 2006-12-31 00:00:00:0 +0000",
+ "2006-12-31T00:00:00Z", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 2006-01-01 00:00:00:0 +0000",
+ "2006-01-01T00:00:00Z", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "1970-01-01T07:30:00.123", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "1970-01-01T07:30:00.1235", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-01 07:30:00:123 +0000",
+ "1970-01-01T07:30:00.12346", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-01 07:30:00:120 +0000",
+ "1970-01-01T07:30:00.12", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-01 07:30:00:500 +0000",
+ "1970-01-01T07:30:00.5", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1970-01-01 16:30:05:0 +0000",
+ "1970-01-01T17:30:05+01:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-01 16:30:05:500 +0000",
+ "1970-01-01T17:30:05.5+01:00", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1970-01-01 00:00:00:0 +0000",
+ "1970-01-01T00:00:00", _DateUtil.UTC);
+ assertDateTimeParsing(
+ "AD 1970-01-02 00:00:00:0 +0000",
+ "1970-01-01T24:00:00", _DateUtil.UTC);
+
+ assertDateTimeParsing(
+ "AD 1970-01-01 23:59:59:999 +0000",
+ "1970-01-01T23:59:59.999", _DateUtil.UTC);
+ }
+
+ public void testParseDateTimeMalformed() throws DateParseException {
+ assertDateTimeMalformed("1998-00-01T00:00:00");
+ assertDateTimeMalformed("1998-13-01T00:00:00");
+ assertDateTimeMalformed("1998-10-00T00:00:00");
+ assertDateTimeMalformed("1998-10-32T00:00:00");
+ assertDateTimeMalformed("1998-02-31T00:00:00");
+ assertDateTimeMalformed("1970-01-02T24:00:01");
+ assertDateTimeMalformed("1970-01-01T00:00:61");
+ assertDateTimeMalformed("1970-01-01T00:60:00");
+ assertDateTimeMalformed("1970-01-01T25:00:00");
+
+ assertISO8601DateTimeMalformed("197-01-01T20:00:00");
+ }
+
+ public void testParseXSTimeZone() throws DateParseException {
+ assertEquals(0,
+ _DateUtil.parseXSTimeZone("Z").getOffset(0));
+ assertEquals(0,
+ _DateUtil.parseXSTimeZone("-00:00").getOffset(0));
+ assertEquals(0,
+ _DateUtil.parseXSTimeZone("+00:00").getOffset(0));
+ assertEquals(90 * 60 * 1000,
+ _DateUtil.parseXSTimeZone("+01:30").getOffset(0));
+ assertEquals(-4 * 60 * 60 * 1000,
+ _DateUtil.parseXSTimeZone("-04:00").getOffset(0));
+ assertEquals(((-23 * 60) - 59) * 60 * 1000,
+ _DateUtil.parseXSTimeZone("-23:59").getOffset(0));
+ assertEquals(((23 * 60) + 59) * 60 * 1000,
+ _DateUtil.parseXSTimeZone("+23:59").getOffset(0));
+ }
+
+ public void testParseXSTimeZoneWrong() {
+ try {
+ _DateUtil.parseXSTimeZone("04:00").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ try {
+ _DateUtil.parseXSTimeZone("-04:00x").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ try {
+ _DateUtil.parseXSTimeZone("-04").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ try {
+ _DateUtil.parseXSTimeZone("+24:00").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ try {
+ _DateUtil.parseXSTimeZone("-24:00").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ try {
+ _DateUtil.parseXSTimeZone("-01:60").getOffset(0);
+ fail();
+ } catch (DateParseException e) {
+ echo(e);
+ }
+ }
+
+ public void testParseXSDateTimeFTLAndJavax() throws DateParseException {
+ // Explicit time zone:
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08Z");
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08+02:00");
+
+ // Default time zone:
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08"); // winter
+ assertJavaxAndFTLXSDateTimesSame("2014-07-01T13:35:08"); // summer
+
+ // Proleptic Gregorian
+ assertJavaxAndFTLXSDateTimesSame("1500-01-01T13:35:08Z");
+ assertJavaxAndFTLXSDateTimesSame("0200-01-01T13:35:08Z");
+ assertJavaxAndFTLXSDateTimesSame("0001-01-01T00:00:00+05:00");
+
+ // BC
+ assertJavaxAndFTLXSDateTimesSame("0001-01-01T13:35:08Z");
+ assertJavaxAndFTLXSDateTimesSame("-0001-01-01T13:35:08Z");
+
+ // Hour 24
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59");
+ if (isAtLeastJava6()) { // Java 5 has broken parser that doesn't allow 24.
+ assertJavaxAndFTLXSDateTimesSame("2014-01-31T24:00:00");
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T24:00:00");
+ }
+ assertJavaxAndFTLXSDateTimesSame("2014-01-02T00:00:00"); // same as the previous
+ assertJavaxAndFTLXSDateTimesSame("2014-02-01T00:00:00"); // same as the previous
+
+ // Under ms
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59.123456789");
+ assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59.1235");
+ }
+
+ private boolean isAtLeastJava6() {
+ try {
+ Class.forName("java.lang.management.LockInfo");
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private final DatatypeFactory datetypeFactory;
+ {
+ try {
+ datetypeFactory = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void assertJavaxAndFTLXSDateTimesSame(String s) throws DateParseException {
+ XMLGregorianCalendar xgc = datetypeFactory.newXMLGregorianCalendar(s);
+ Date javaxDate = xgc.toGregorianCalendar().getTime();
+ Date ftlDate = _DateUtil.parseXSDateTime(s, TimeZone.getDefault(), cf2dc);
+ assertEquals(javaxDate, ftlDate);
+ }
+
+ private void assertDateParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
+ assertDateParsing(expected, expected, parsed, tz);
+ }
+
+ private void assertDateParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
+ throws DateParseException {
+ if (expectedXS != null) {
+ assertEquals(
+ expectedXS,
+ df.format(_DateUtil.parseXSDate(parsed, tz, cf2dc)));
+ }
+ if (expectedISO8601 != null) {
+ assertEquals(
+ expectedISO8601,
+ df.format(_DateUtil.parseISO8601Date(parsed, tz, cf2dc)));
+ }
+ }
+
+ private void assertDateTimeParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
+ assertDateTimeParsing(expected, expected, parsed, tz);
+ }
+
+ private void assertDateTimeParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
+ throws DateParseException {
+ if (expectedXS != null) {
+ assertEquals(
+ expectedXS,
+ df.format(_DateUtil.parseXSDateTime(parsed, tz, cf2dc)));
+ }
+ if (expectedISO8601 != null) {
+ assertEquals(
+ expectedISO8601,
+ df.format(_DateUtil.parseISO8601DateTime(parsed, tz, cf2dc)));
+ }
+ }
+
+ private void assertTimeParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
+ assertTimeParsing(expected, expected, parsed, tz);
+ }
+
+ private void assertTimeParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
+ throws DateParseException {
+ if (expectedXS != null) {
+ assertEquals(
+ expectedXS,
+ df.format(_DateUtil.parseXSTime(parsed, tz, cf2dc)));
+ }
+ if (expectedISO8601 != null) {
+ assertEquals(
+ expectedISO8601,
+ df.format(_DateUtil.parseISO8601Time(parsed, tz, cf2dc)));
+ }
+ }
+
+ private void assertDateMalformed(String parsed) {
+ try {
+ _DateUtil.parseXSDate(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ try {
+ _DateUtil.parseISO8601Date(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void assertTimeMalformed(String parsed) {
+ try {
+ _DateUtil.parseXSTime(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ try {
+ _DateUtil.parseISO8601Time(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void assertDateTimeMalformed(String parsed) {
+ try {
+ _DateUtil.parseXSDateTime(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ try {
+ _DateUtil.parseISO8601DateTime(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void assertISO8601DateMalformed(String parsed) {
+ try {
+ _DateUtil.parseISO8601Date(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void assertISO8601TimeMalformed(String parsed) {
+ try {
+ _DateUtil.parseISO8601Time(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void assertISO8601DateTimeMalformed(String parsed) {
+ try {
+ _DateUtil.parseISO8601DateTime(parsed, _DateUtil.UTC, cf2dc);
+ fail();
+ } catch (DateParseException e) {
+ // Expected
+ echo(e);
+ }
+ }
+
+ private void echo(@SuppressWarnings("unused") DateParseException e) {
+ // System.out.println(e);
+ }
+
+}
\ 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/core/util/FTLUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java
new file mode 100644
index 0000000..f1e44f3
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.core.util;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class FTLUtilTest {
+
+ @Test
+ public void testEscapeStringLiteralPart() {
+ assertEquals("", FTLUtil.escapeStringLiteralPart(""));
+ assertEquals("abc", FTLUtil.escapeStringLiteralPart("abc"));
+ assertEquals("{", FTLUtil.escapeStringLiteralPart("{"));
+ assertEquals("a{b}c", FTLUtil.escapeStringLiteralPart("a{b}c"));
+ assertEquals("a#b", FTLUtil.escapeStringLiteralPart("a#b"));
+ assertEquals("a$b", FTLUtil.escapeStringLiteralPart("a$b"));
+ assertEquals("a#\\{b}c", FTLUtil.escapeStringLiteralPart("a#{b}c"));
+ assertEquals("a$\\{b}c", FTLUtil.escapeStringLiteralPart("a${b}c"));
+ assertEquals("a'c\\\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '"'));
+ assertEquals("a\\'c\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '\''));
+ assertEquals("a\\'c\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '\''));
+ assertEquals("\\n\\r\\t\\f\\x0002\\\\", FTLUtil.escapeStringLiteralPart("\n\r\t\f\u0002\\"));
+ assertEquals("\\l\\g\\a", FTLUtil.escapeStringLiteralPart("<>&"));
+ }
+
+ @Test
+ public void testEscapeStringLiteralAll() {
+ assertFTLEsc("", "", "", "", "\"\"");
+ assertFTLEsc("\'", "\\'", "'", "\\'", "\"'\"");
+ assertFTLEsc("\"", "\\\"", "\\\"", "\"", "'\"'");
+ assertFTLEsc("\"", "\\\"", "\\\"", "\"", "'\"'");
+ assertFTLEsc("foo", "foo", "foo", "foo", "\"foo\"");
+ assertFTLEsc("foo's", "foo\\'s", "foo's", "foo\\'s", "\"foo's\"");
+ assertFTLEsc("foo \"", "foo \\\"", "foo \\\"", "foo \"", "'foo \"'");
+ assertFTLEsc("foo's \"", "foo\\'s \\\"", "foo's \\\"", "foo\\'s \"", "\"foo's \\\"\"");
+ assertFTLEsc("foo\nb\u0000c", "foo\\nb\\x0000c", "foo\\nb\\x0000c", "foo\\nb\\x0000c", "\"foo\\nb\\x0000c\"");
+ }
+
+ private void assertFTLEsc(String s, String partAny, String partQuot, String partApos, String quoted) {
+ assertEquals(partAny, FTLUtil.escapeStringLiteralPart(s));
+ assertEquals(partQuot, FTLUtil.escapeStringLiteralPart(s, '\"'));
+ assertEquals(partApos, FTLUtil.escapeStringLiteralPart(s, '\''));
+ assertEquals(quoted, FTLUtil.toStringLiteral(s));
+ }
+
+ @Test
+ public void testUnescapeStringLiteralPart() throws Exception {
+ assertEquals("", FTLUtil.unescapeStringLiteralPart(""));
+ assertEquals("1", FTLUtil.unescapeStringLiteralPart("1"));
+ assertEquals("123", FTLUtil.unescapeStringLiteralPart("123"));
+ assertEquals("1&2&3", FTLUtil.unescapeStringLiteralPart("1\\a2\\a3"));
+ assertEquals("&", FTLUtil.unescapeStringLiteralPart("\\a"));
+ assertEquals("&&&", FTLUtil.unescapeStringLiteralPart("\\a\\a\\a"));
+ assertEquals(
+ "\u0000\u0000&\u0000\u0000\u0000\u0000",
+ FTLUtil.unescapeStringLiteralPart("\\x0000\\x0000\\a\\x0000\\x000\\x00\\x0"));
+ assertEquals(
+ "'\"\n\b\u0000c><&{\\",
+ FTLUtil.unescapeStringLiteralPart("\\'\\\"\\n\\b\\x0000c\\g\\l\\a\\{\\\\"));
+ }
+
+ @Test
+ public void testEscapeIdentifier() {
+ assertNull(FTLUtil.escapeIdentifier(null));
+ assertEquals("", FTLUtil.escapeIdentifier(""));
+ assertEquals("a", FTLUtil.escapeIdentifier("a"));
+ assertEquals("ab", FTLUtil.escapeIdentifier("ab"));
+ assertEquals("\\.", FTLUtil.escapeIdentifier("."));
+ assertEquals("\\.\\:\\-", FTLUtil.escapeIdentifier(".:-"));
+ assertEquals("a\\.b", FTLUtil.escapeIdentifier("a.b"));
+ assertEquals("a\\.b\\:c\\-d", FTLUtil.escapeIdentifier("a.b:c-d"));
+ }
+
+ @Test
+ public void testIsNonEscapedIdentifierStart() {
+ assertTrue(FTLUtil.isNonEscapedIdentifierPart('a'));
+ assertTrue(FTLUtil.isNonEscapedIdentifierPart('á'));
+ assertTrue(FTLUtil.isNonEscapedIdentifierPart('1'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierPart('-'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierPart(' '));
+ assertFalse(FTLUtil.isNonEscapedIdentifierPart('\u0000'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierPart('\\'));
+ }
+
+ @Test
+ public void testisNonEscapedIdentifierStart() {
+ assertTrue(FTLUtil.isNonEscapedIdentifierStart('a'));
+ assertTrue(FTLUtil.isNonEscapedIdentifierStart('á'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierStart('1'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierStart('-'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierStart(' '));
+ assertFalse(FTLUtil.isNonEscapedIdentifierStart('\u0000'));
+ assertFalse(FTLUtil.isNonEscapedIdentifierStart('\\'));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
new file mode 100644
index 0000000..d5709da
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.core.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.junit.Test;
+
+import junit.framework.TestCase;
+
+public class NumberUtilTest extends TestCase {
+
+ @Test
+ public void testGetSignum() {
+ assertEquals(1, _NumberUtil.getSignum(Double.valueOf(Double.POSITIVE_INFINITY)));
+ assertEquals(1, _NumberUtil.getSignum(Double.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(Double.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(Double.valueOf(-3)));
+ assertEquals(-1, _NumberUtil.getSignum(Double.valueOf(Double.NEGATIVE_INFINITY)));
+ try {
+ _NumberUtil.getSignum(Double.valueOf(Double.NaN));
+ fail();
+ } catch (ArithmeticException e) {
+ // expected
+ }
+
+ assertEquals(1, _NumberUtil.getSignum(Float.valueOf(Float.POSITIVE_INFINITY)));
+ assertEquals(1, _NumberUtil.getSignum(Float.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(Float.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(Float.valueOf(-3)));
+ assertEquals(-1, _NumberUtil.getSignum(Float.valueOf(Float.NEGATIVE_INFINITY)));
+ try {
+ _NumberUtil.getSignum(Float.valueOf(Float.NaN));
+ fail();
+ } catch (ArithmeticException e) {
+ // expected
+ }
+
+ assertEquals(1, _NumberUtil.getSignum(Long.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(Long.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(Long.valueOf(-3)));
+
+ assertEquals(1, _NumberUtil.getSignum(Integer.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(Integer.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(Integer.valueOf(-3)));
+
+ assertEquals(1, _NumberUtil.getSignum(Short.valueOf((short) 3)));
+ assertEquals(0, _NumberUtil.getSignum(Short.valueOf((short) 0)));
+ assertEquals(-1, _NumberUtil.getSignum(Short.valueOf((short) -3)));
+
+ assertEquals(1, _NumberUtil.getSignum(Byte.valueOf((byte) 3)));
+ assertEquals(0, _NumberUtil.getSignum(Byte.valueOf((byte) 0)));
+ assertEquals(-1, _NumberUtil.getSignum(Byte.valueOf((byte) -3)));
+
+ assertEquals(1, _NumberUtil.getSignum(BigDecimal.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(BigDecimal.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(BigDecimal.valueOf(-3)));
+
+ assertEquals(1, _NumberUtil.getSignum(BigInteger.valueOf(3)));
+ assertEquals(0, _NumberUtil.getSignum(BigInteger.valueOf(0)));
+ assertEquals(-1, _NumberUtil.getSignum(BigInteger.valueOf(-3)));
+ }
+
+ @Test
+ public void testIsBigDecimalInteger() {
+ BigDecimal n1 = new BigDecimal("1.125");
+ if (n1.precision() != 4 || n1.scale() != 3) {
+ throw new RuntimeException("Wrong: " + n1);
+ }
+ BigDecimal n2 = new BigDecimal("1.125").subtract(new BigDecimal("0.005"));
+ if (n2.precision() != 4 || n2.scale() != 3) {
+ throw new RuntimeException("Wrong: " + n2);
+ }
+ BigDecimal n3 = new BigDecimal("123");
+ BigDecimal n4 = new BigDecimal("6000");
+ BigDecimal n5 = new BigDecimal("1.12345").subtract(new BigDecimal("0.12345"));
+ if (n5.precision() != 6 || n5.scale() != 5) {
+ throw new RuntimeException("Wrong: " + n5);
+ }
+ BigDecimal n6 = new BigDecimal("0");
+ BigDecimal n7 = new BigDecimal("0.001").subtract(new BigDecimal("0.001"));
+ BigDecimal n8 = new BigDecimal("60000.5").subtract(new BigDecimal("0.5"));
+ BigDecimal n9 = new BigDecimal("6").movePointRight(3).setScale(-3);
+
+ BigDecimal[] ns = new BigDecimal[] {
+ n1, n2, n3, n4, n5, n6, n7, n8, n9,
+ n1.negate(), n2.negate(), n3.negate(), n4.negate(), n5.negate(), n6.negate(), n7.negate(), n8.negate(),
+ n9.negate(),
+ };
+
+ for (BigDecimal n : ns) {
+ assertEquals(n.doubleValue() == n.longValue(), _NumberUtil.isIntegerBigDecimal(n));
+ }
+
+ }
+
+ @Test
+ public void testToIntExcact() {
+ for (int n : new int[] { Integer.MIN_VALUE, Byte.MIN_VALUE, -1, 0, 1, Byte.MAX_VALUE, Integer.MAX_VALUE }) {
+ if (n != Integer.MIN_VALUE && n != Integer.MAX_VALUE) {
+ assertEquals(n, _NumberUtil.toIntExact(Byte.valueOf((byte) n)));
+ assertEquals(n, _NumberUtil.toIntExact(Short.valueOf((short) n)));
+ assertEquals(n, _NumberUtil.toIntExact(Float.valueOf(n)));
+ }
+ assertEquals(n, _NumberUtil.toIntExact(Integer.valueOf(n)));
+ assertEquals(n, _NumberUtil.toIntExact(Long.valueOf(n)));
+ assertEquals(n, _NumberUtil.toIntExact(Double.valueOf(n)));
+ assertEquals(n, _NumberUtil.toIntExact(BigDecimal.valueOf(n)));
+ assertEquals(n, _NumberUtil.toIntExact(BigDecimal.valueOf(n * 10L).divide(BigDecimal.TEN)));
+ assertEquals(n, _NumberUtil.toIntExact(BigInteger.valueOf(n)));
+ }
+
+ try {
+ _NumberUtil.toIntExact(Long.valueOf(Integer.MIN_VALUE - 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(Long.valueOf(Integer.MAX_VALUE + 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+
+ try {
+ _NumberUtil.toIntExact(Float.valueOf(1.00001f));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(Float.valueOf(Integer.MIN_VALUE - 129L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(Float.valueOf(Integer.MAX_VALUE));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+
+ try {
+ _NumberUtil.toIntExact(Double.valueOf(1.00001));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(Double.valueOf(Integer.MIN_VALUE - 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(Double.valueOf(Integer.MAX_VALUE + 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+
+ try {
+ _NumberUtil.toIntExact(new BigDecimal("100.000001"));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(BigDecimal.valueOf(Integer.MIN_VALUE - 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(BigDecimal.valueOf(Integer.MAX_VALUE + 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+
+ try {
+ _NumberUtil.toIntExact(BigInteger.valueOf(Integer.MIN_VALUE - 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ try {
+ _NumberUtil.toIntExact(BigInteger.valueOf(Integer.MAX_VALUE + 1L));
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+ }
+
+}
[19/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
deleted file mode 100644
index 49534fa..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
+++ /dev/null
@@ -1,1499 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TimeZone;
-
-import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
-import org.apache.freemarker.core.arithmetic.impl.BigDecimalArithmeticEngine;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.templateresolver.CacheStorage;
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.TemplateLoaderSession;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingResult;
-import org.apache.freemarker.core.templateresolver.TemplateLoadingSource;
-import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage;
-import org.apache.freemarker.core.userpkg.PublicWithMixedConstructors;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("boxing")
-public class ObjectBuilderSettingsTest {
-
- @Test
- public void newInstanceTest() throws Exception {
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(4f, res.f, 0);
- assertFalse(res.b);
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(4f, res.f, 0);
- assertFalse(res.b);
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1.5, -20, 8589934592, true)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(1.5f, res.f, 0);
- assertEquals(Integer.valueOf(-20), res.i);
- assertEquals(8589934592l, res.l);
- assertTrue(res.b);
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1, true)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(2f, res.f, 0);
- assertEquals(Integer.valueOf(1), res.i);
- assertEquals(2l, res.l);
- assertTrue(res.b);
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(3f, res.f, 0);
- assertEquals(Integer.valueOf(11), res.i);
- assertEquals(22l, res.l);
- assertFalse(res.b);
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(p1 = 1, p2 = 2, p3 = true, p4 = 's')",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(4f, res.f, 0);
- assertFalse(res.b);
- assertEquals(1d, res.getP1(), 0);
- assertEquals(2, res.getP2());
- assertTrue(res.isP3());
- assertEquals("s", res.getP4());
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
- + "null, 2, p1 = 1, p2 = 2, p3 = false, p4 = null)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertNull(res.i);
- assertEquals(2, res.l, 0);
- assertEquals(3f, res.f, 0);
- assertFalse(res.b);
- assertEquals(1d, res.getP1(), 0);
- assertEquals(2, res.getP2());
- assertFalse(res.isP3());
- assertNull(res.getP4());
- }
-
- {
- // Deliberately odd spacings
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "\t\torg.apache.freemarker .core . \n"
- + "\tObjectBuilderSettingsTest$TestBean1(\n\r\tp1=1\n,p2=2,p3=true,p4='s' )",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(4f, res.f, 0);
- assertFalse(res.b);
- assertEquals(1d, res.getP1(), 0);
- assertEquals(2, res.getP2());
- assertTrue(res.isP3());
- assertEquals("s", res.getP4());
- }
-
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1, true, p2 = 2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(2f, res.f, 0);
- assertEquals(Integer.valueOf(1), res.i);
- assertEquals(2l, res.l);
- assertTrue(res.b);
- assertEquals(0d, res.getP1(), 0);
- assertEquals(2, res.getP2());
- assertFalse(res.isP3());
- }
- }
-
- @Test
- public void builderTest() throws Exception {
- {
- // `()`-les syntax:
- TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertTrue(res.built);
- assertEquals(0, res.x);
- }
-
- {
- TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertTrue(res.built);
- assertEquals(0, res.x);
- }
-
- {
- TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertTrue(res.built);
- assertEquals(1, res.x);
- }
-
- {
- TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertTrue(res.built);
- assertEquals(1, res.x);
- }
- }
-
- @Test
- public void staticInstanceTest() throws Exception {
- // ()-les syntax:
- {
- TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(0, res.i);
- assertEquals(0, res.x);
- assertSame(TestBean5.INSTANCE, res); //!
- }
-
- {
- TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(0, res.i);
- assertEquals(0, res.x);
- assertSame(TestBean5.INSTANCE, res); //!
- }
-
- {
- TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5(x = 1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(0, res.i);
- assertEquals(1, res.x);
- assertNotSame(TestBean5.INSTANCE, res);
- }
-
- {
- TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5(1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(1, res.i);
- assertEquals(0, res.x);
- assertNotSame(TestBean5.INSTANCE, res);
- }
- }
-
- @Test
- public void stringLiteralsTest() throws Exception {
- {
- TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"\", '', s3 = r\"\", s4 = r'')",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("", res.getS1());
- assertEquals("", res.getS2());
- assertEquals("", res.getS3());
- assertEquals("", res.getS4());
- }
-
- {
- TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"a\", 'b', s3 = r\"c\", s4 = r'd')",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("a", res.getS1());
- assertEquals("b", res.getS2());
- assertEquals("c", res.getS3());
- assertEquals("d", res.getS4());
- }
-
- {
- TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"a'A\", 'b\"B', s3 = r\"c'C\", s4 = r'd\"D')",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("a'A", res.getS1());
- assertEquals("b\"B", res.getS2());
- assertEquals("c'C", res.getS3());
- assertEquals("d\"D", res.getS4());
- }
-
- {
- TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4("
- + "\"a\\nA\\\"a\\\\A\", 'a\\nA\\'a\\\\A', s3 = r\"a\\n\\A\", s4 = r'a\\n\\A')",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("a\nA\"a\\A", res.getS1());
- assertEquals("a\nA'a\\A", res.getS2());
- assertEquals("a\\n\\A", res.getS3());
- assertEquals("a\\n\\A", res.getS4());
- }
- }
-
- @Test
- public void nestedBuilderTest() throws Exception {
- {
- TestBean6 res = (TestBean6) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
- + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22, p4 = 'foo'),"
- + "1,"
- + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(11),"
- + "y=2,"
- + "b3=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 22)"
- + ")",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(Integer.valueOf(11), res.b1.i);
- assertEquals(22, res.b1.l);
- assertEquals("foo", res.b1.p4);
- assertEquals(1, res.x);
- assertEquals(11, res.b2.x);
- assertEquals(2, res.y);
- assertEquals(22, res.b3.x);
- assertNull(res.b4);
- }
-
- {
- TestBean6 res = (TestBean6) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
- + "null,"
- + "-1,"
- + "null,"
- + "b4=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
- + " org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22, p4 = 'foo'),"
- + " 1,"
- + " org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(11),"
- + " y=2,"
- + " b3=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 22)"
- + "),"
- + "y=2"
- + ")",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertNull(res.b1);
- assertEquals(-1, res.x);
- assertNull(res.b2);
- assertEquals(2, res.y);
- assertEquals(Integer.valueOf(11), res.b4.b1.i);
- assertEquals(22, res.b4.b1.l);
- assertEquals("foo", res.b4.b1.p4);
- assertEquals(1, res.b4.x);
- assertEquals(11, res.b4.b2.x);
- assertEquals(2, res.b4.y);
- assertEquals(22, res.b4.b3.x);
- assertNull(res.b4.b4);
- }
- }
-
- @Test
- public void defaultObjectWrapperTest() throws Exception {
- DefaultObjectWrapper ow = (DefaultObjectWrapper) _ObjectBuilderSettingEvaluator.eval(
- "DefaultObjectWrapper(3.0.0)",
- ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- assertFalse(ow.isExposeFields());
- }
-
- @Test
- public void defaultObjectWrapperTest2() throws Exception {
- DefaultObjectWrapper ow = (DefaultObjectWrapper) _ObjectBuilderSettingEvaluator.eval(
- "DefaultObjectWrapper(3.0.0, exposeFields=true)",
- ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- assertTrue(ow.isExposeFields());
- }
-
- @Test
- public void configurationPropertiesTest() throws Exception {
- final Configuration.Builder cfgB = new Configuration.Builder(Configuration.getVersion());
-
- {
- Properties props = new Properties();
- props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY,
- "org.apache.freemarker.core.model.impl.DefaultObjectWrapper(3.0.0)");
- props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyArithmeticEngine");
- props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateExceptionHandler");
- props.setProperty(Configuration.ExtendableBuilder.CACHE_STORAGE_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyCacheStorage()");
- props.setProperty(MutableProcessingConfiguration.NEW_BUILTIN_CLASS_RESOLVER_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyNewBuiltinClassResolver()");
- props.setProperty(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY, "utf-8");
- props.setProperty(Configuration.ExtendableBuilder.TEMPLATE_LOADER_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateLoader()");
- cfgB.setSettings(props);
- assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
- assertEquals(
- Configuration.VERSION_3_0_0, ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
- assertEquals(DummyArithmeticEngine.class, cfgB.getArithmeticEngine().getClass());
- assertEquals(DummyTemplateExceptionHandler.class, cfgB.getTemplateExceptionHandler().getClass());
- assertEquals(DummyCacheStorage.class, cfgB.getCacheStorage().getClass());
- assertEquals(DummyNewBuiltinClassResolver.class, cfgB.getNewBuiltinClassResolver().getClass());
- assertEquals(DummyTemplateLoader.class, cfgB.getTemplateLoader().getClass());
- assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
- }
-
- {
- Properties props = new Properties();
- props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "defAult");
- props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyArithmeticEngine(x = 1)");
- props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY,
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateExceptionHandler(x = 1)");
- props.setProperty(Configuration.ExtendableBuilder.CACHE_STORAGE_KEY,
- "soft: 500, strong: 100");
- props.setProperty(MutableProcessingConfiguration.NEW_BUILTIN_CLASS_RESOLVER_KEY,
- "allows_nothing");
- cfgB.setSettings(props);
- assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
- assertEquals(1, ((DummyArithmeticEngine) cfgB.getArithmeticEngine()).getX());
- assertEquals(1, ((DummyTemplateExceptionHandler) cfgB.getTemplateExceptionHandler()).getX());
- assertEquals(Configuration.VERSION_3_0_0,
- ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
- assertEquals(500, ((MruCacheStorage) cfgB.getCacheStorage()).getSoftSizeLimit());
- assertEquals(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER, cfgB.getNewBuiltinClassResolver());
- assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
- }
-
- {
- Properties props = new Properties();
- props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "Default");
- props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY, "bigdecimal");
- props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY, "rethrow");
- cfgB.setSettings(props);
- assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
- assertSame(BigDecimalArithmeticEngine.INSTANCE, cfgB.getArithmeticEngine());
- assertSame(TemplateExceptionHandler.RETHROW_HANDLER, cfgB.getTemplateExceptionHandler());
- assertEquals(Configuration.VERSION_3_0_0,
- ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
- }
-
- {
- Properties props = new Properties();
- props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "DefaultObjectWrapper(3.0.0)");
- cfgB.setSettings(props);
- assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
- assertEquals(
- Configuration.VERSION_3_0_0,
- ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
- }
- }
-
- @Test
- public void timeZoneTest() throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException,
- InstantiationException, IllegalAccessException {
- for (String timeZoneId : new String[] { "GMT+01", "GMT", "UTC" }) {
- TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(timeZone=TimeZone('"
- + timeZoneId + "'))",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- assertEquals(TimeZone.getTimeZone(timeZoneId), result.getTimeZone());
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(timeZone=TimeZone('foobar'))",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getCause().getMessage(),
- allOf(containsStringIgnoringCase("unrecognized"), containsString("foobar")));
- }
- }
-
- @Test
- public void charsetTest() throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException,
- InstantiationException, IllegalAccessException {
- for (String timeZoneId : new String[] { "uTf-8", "GMT", "UTC" }) {
- TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(charset=Charset('iso-8859-1'))",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- assertEquals(StandardCharsets.ISO_8859_1, result.getCharset());
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(charset=Charset('noSuchCS'))",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getCause(), instanceOf(UnsupportedCharsetException.class));
- }
- }
-
- @Test
- public void configureBeanTest() throws Exception {
- final TestBean7 bean = new TestBean7();
- final String src = "a/b(s='foo', x=1, b=true), bar";
- int nextPos = _ObjectBuilderSettingEvaluator.configureBean(src, src.indexOf('(') + 1, bean,
- _SettingEvaluationEnvironment.getCurrent());
- assertEquals("foo", bean.getS());
- assertEquals(1, bean.getX());
- assertTrue(bean.isB());
- assertEquals(", bar", src.substring(nextPos));
- }
-
- @Test
- public void parsingErrors() throws Exception {
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1,,2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("\",\""));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x=1,2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("must precede named"));
- }
-
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x=1;2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("\";\""));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1,2))",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("\")\""));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "foo.Bar('s${x}s'))",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("${...}"));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "foo.Bar('s#{x}s'))",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("#{...}"));
- }
- }
-
- @Test
- public void semanticErrors() throws Exception {
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$XTestBean1(1,2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("Failed to get class"));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(true, 2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("constructor"));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x = 1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("no writeable JavaBeans property called \"x\""));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(p1 = 1, p1 = 2)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("twice"));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "java.util.HashMap()",
- ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("is not a(n) " + ObjectWrapper.class.getName()));
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "null",
- ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("can't be null"));
- }
- }
-
- @Test
- public void testLiteralAsObjectBuilder() throws Exception {
- assertNull(_ObjectBuilderSettingEvaluator.eval(
- "null",
- ObjectWrapper.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals("foo", _ObjectBuilderSettingEvaluator.eval(
- "'foo'",
- CharSequence.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Boolean.TRUE, _ObjectBuilderSettingEvaluator.eval(
- " true ",
- Object.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Double.valueOf("1.23"), _ObjectBuilderSettingEvaluator.eval(
- "1.23 ",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(new Version(1, 2, 3), _ObjectBuilderSettingEvaluator.eval(
- " 1.2.3",
- Object.class, true, _SettingEvaluationEnvironment.getCurrent()));
- }
-
- @Test
- public void testNumberLiteralJavaTypes() throws Exception {
- assertEquals(Double.valueOf("1.0"), _ObjectBuilderSettingEvaluator.eval(
- "1.0",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(new BigInteger("-9223372036854775809"), _ObjectBuilderSettingEvaluator.eval(
- "-9223372036854775809",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(new BigInteger("9223372036854775808"), _ObjectBuilderSettingEvaluator.eval(
- "9223372036854775808",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(Long.valueOf(-9223372036854775808L), _ObjectBuilderSettingEvaluator.eval(
- "-9223372036854775808",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Long.valueOf(9223372036854775807L), _ObjectBuilderSettingEvaluator.eval(
- "9223372036854775807",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(Integer.valueOf(-2147483648), _ObjectBuilderSettingEvaluator.eval(
- "-2147483648",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Integer.valueOf(2147483647), _ObjectBuilderSettingEvaluator.eval(
- "2147483647",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(Integer.valueOf(-1), _ObjectBuilderSettingEvaluator.eval(
- "-1",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Integer.valueOf(1), _ObjectBuilderSettingEvaluator.eval(
- "1",
- Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
- }
-
- @Test
- public void testListLiterals() throws Exception {
- {
- ArrayList<Object> expected = new ArrayList();
- expected.add("s");
- expected.add(null);
- expected.add(true);
- expected.add(new TestBean9(1));
- expected.add(ImmutableList.of(11, 22, 33));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- "['s', null, true, org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1), [11, 22, 33]]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- " [ 's' , null , true , org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1) ,"
- + " [ 11 , 22 , 33 ] ] ",
- Collection.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- "['s',null,true,org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1),[11,22,33]]",
- List.class, false, _SettingEvaluationEnvironment.getCurrent()));
- }
-
- assertEquals(Collections.emptyList(), _ObjectBuilderSettingEvaluator.eval(
- "[]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Collections.emptyList(), _ObjectBuilderSettingEvaluator.eval(
- "[ ]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(Collections.singletonList(123), _ObjectBuilderSettingEvaluator.eval(
- "[123]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Collections.singletonList(123), _ObjectBuilderSettingEvaluator.eval(
- "[ 123 ]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(new TestBean9(1, ImmutableList.of("a", "b")), _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1, ['a', 'b'])",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "[1,]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \"]\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "[,1]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \",\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "1]",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \"]\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "[1",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("end of"));
- }
- }
-
- @Test
- public void testMapLiterals() throws Exception {
- {
- HashMap<String, Object> expected = new HashMap();
- expected.put("k1", "s");
- expected.put("k2", null);
- expected.put("k3", true);
- expected.put("k4", new TestBean9(1));
- expected.put("k5", ImmutableList.of(11, 22, 33));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- "{'k1': 's', 'k2': null, 'k3': true, "
- + "'k4': org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1), 'k5': [11, 22, 33]}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- " { 'k1' : 's' , 'k2' : null , 'k3' : true , "
- + "'k4' : org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9 ( 1 ) , 'k5' : [ 11 , 22 , 33 ] } ",
- Map.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- " {'k1':'s','k2':null,'k3':true,"
- + "'k4':org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1),'k5':[11,22,33]}",
- LinkedHashMap.class, false, _SettingEvaluationEnvironment.getCurrent()));
- }
-
- {
- HashMap<Object, String> expected = new HashMap();
- expected.put(true, "T");
- expected.put(1, "O");
- expected.put(new TestBean9(1), "B");
- expected.put(ImmutableList.of(11, 22, 33), "L");
- assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
- "{ true: 'T', 1: 'O', org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1): 'B', "
- + "[11, 22, 33]: 'L' }",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- }
-
- assertEquals(Collections.emptyMap(), _ObjectBuilderSettingEvaluator.eval(
- "{}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Collections.emptyMap(), _ObjectBuilderSettingEvaluator.eval(
- "{ }",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(Collections.singletonMap("k1", 123), _ObjectBuilderSettingEvaluator.eval(
- "{'k1':123}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
- assertEquals(Collections.singletonMap("k1", 123), _ObjectBuilderSettingEvaluator.eval(
- "{ 'k1' : 123 }",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- assertEquals(new TestBean9(1, ImmutableMap.of(11, "a", 22, "b")), _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1, { 11: 'a', 22: 'b' })",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "{1:2,}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \"}\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "{,1:2}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \",\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "1:2}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \":\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "1}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("found character \"}\""));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "{1",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("end of"));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "{1:",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("end of"));
- }
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "{null:1}",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(), containsString("null as key"));
- }
- }
-
- @Test
- public void testMethodParameterNumberTypes() throws Exception {
- {
- TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=1)",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- assertEquals(result.getAnyObject(), 1);
- }
- {
- TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=2147483649)",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- assertEquals(result.getAnyObject(), 2147483649L);
- }
- {
- TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=1.0)",
- TestBean8.class, false, new _SettingEvaluationEnvironment());
- // Like in FTL, non-integer numbers are BigDecimal-s, that are later coerced to the actual parameter type.
- // However, here the type is Object, so it remains BigDecimal.
- assertEquals(new BigDecimal("1.0"), result.getAnyObject());
- }
- }
-
- @Test
- public void testNonMethodParameterNumberTypes() throws Exception {
- assertEqualsEvaled(Integer.valueOf(1), "1");
- assertEqualsEvaled(Double.valueOf(1), "1.0");
- assertEqualsEvaled(Long.valueOf(2147483649l), "2147483649");
-
- assertEqualsEvaled(Double.valueOf(1), "1d");
- assertEqualsEvaled(Double.valueOf(1), "1D");
- assertEqualsEvaled(Float.valueOf(1), "1f");
- assertEqualsEvaled(Float.valueOf(1), "1F");
- assertEqualsEvaled(Long.valueOf(1), "1l");
- assertEqualsEvaled(Long.valueOf(1), "1L");
- assertEqualsEvaled(BigDecimal.valueOf(1), "1bd");
- assertEqualsEvaled(BigDecimal.valueOf(1), "1Bd");
- assertEqualsEvaled(BigDecimal.valueOf(1), "1BD");
- assertEqualsEvaled(BigInteger.valueOf(1), "1bi");
- assertEqualsEvaled(BigInteger.valueOf(1), "1bI");
-
- assertEqualsEvaled(Float.valueOf(1.5f), "1.5f");
- assertEqualsEvaled(Double.valueOf(1.5), "1.5d");
- assertEqualsEvaled(BigDecimal.valueOf(1.5), "1.5bd");
-
- assertEqualsEvaled(
- ImmutableList.of(-1, -0.5, new BigDecimal("-0.1")),
- "[ -1, -0.5, -0.1bd ]");
- assertEqualsEvaled(
- ImmutableMap.of(-1, -11, -0.5, -0.55, new BigDecimal("-0.1"), new BigDecimal("-0.11")),
- "{ -1: -11, -0.5: -0.55, -0.1bd: -0.11bd }");
- }
-
- @Test
- public void testStaticFields() throws Exception {
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
- + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST, true)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(TestStaticFields.CONST, (int) res.i);
- }
- {
- TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
- + "p2 = org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(TestStaticFields.CONST, res.getP2());
- }
- assertEqualsEvaled(123, "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST");
-
- // With shorthand class name:
- assertEqualsEvaled(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX, "Configuration.AUTO_DETECT_TAG_SYNTAX");
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
- + "p2 = org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST())",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(),
- containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST"));
- }
- try {
- assertEqualsEvaled(123, "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST()");
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(),
- containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST"));
- }
- try {
- assertEqualsEvaled(123, "java.lang.String(org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5.INSTANCE)");
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertThat(e.getMessage(),
- containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5()"));
- }
- }
-
- private void assertEqualsEvaled(Object expectedValue, String s)
- throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException, InstantiationException,
- IllegalAccessException {
- Object actualValue = _ObjectBuilderSettingEvaluator.eval(
- s, Object.class, true, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(expectedValue, actualValue);
- }
-
- @Test
- public void visibilityTest() throws Exception {
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PackageVisibleAll()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertEquals(IllegalAccessException.class, e.getCause().getClass());
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PackageVisibleWithPublicConstructor()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertEquals(IllegalAccessException.class, e.getCause().getClass());
- }
-
- try {
- _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PublicWithPackageVisibleConstructor()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- fail();
- } catch (_ObjectBuilderSettingEvaluationException e) {
- assertEquals(IllegalAccessException.class, e.getCause().getClass());
- }
-
- {
- Object o = _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PublicAll()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals(org.apache.freemarker.core.userpkg.PublicAll.class, o.getClass());
- }
-
- {
- Object o = _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PublicWithMixedConstructors(1)",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("Integer", ((PublicWithMixedConstructors) o).getS());
- }
-
-
- {
- Object o = _ObjectBuilderSettingEvaluator.eval(
- "org.apache.freemarker.core.userpkg.PackageVisibleAllWithBuilder()",
- Object.class, false, _SettingEvaluationEnvironment.getCurrent());
- assertEquals("org.apache.freemarker.core.userpkg.PackageVisibleAllWithBuilder", o.getClass().getName());
- }
- }
-
- public static class TestBean1 {
- float f;
- Integer i;
- long l;
- boolean b;
-
- double p1;
- int p2;
- boolean p3;
- String p4;
-
- public TestBean1(float f, Integer i, long l, boolean b) {
- this.f = f;
- this.i = i;
- this.l = l;
- this.b = b;
- }
-
- public TestBean1(Integer i, boolean b) {
- f = 2;
- this.i = i;
- l = 2;
- this.b = b;
- }
-
- public TestBean1(Integer i, long l) {
- f = 3;
- this.i = i;
- this.l = l;
- b = false;
- }
-
- public TestBean1() {
- f = 4;
- }
-
- public double getP1() {
- return p1;
- }
-
- public void setP1(double p1) {
- this.p1 = p1;
- }
-
- public int getP2() {
- return p2;
- }
-
- public void setP2(int p2) {
- this.p2 = p2;
- }
-
- public boolean isP3() {
- return p3;
- }
-
- public void setP3(boolean p3) {
- this.p3 = p3;
- }
-
- public String getP4() {
- return p4;
- }
-
- public void setP4(String p4) {
- this.p4 = p4;
- }
-
- }
-
- public static class TestBean2 {
- final boolean built;
- final int x;
-
- public TestBean2() {
- built = false;
- x = 0;
- }
-
- public TestBean2(int x) {
- built = false;
- this.x = x;
- }
-
- public TestBean2(TestBean2Builder builder) {
- built = true;
- x = builder.x;
- }
-
- }
-
- public static class TestBean2Builder {
- int x;
-
- public TestBean2Builder() { }
-
- public TestBean2Builder(int x) {
- this.x = x;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public TestBean2 build() {
- return new TestBean2(this);
- }
-
- }
-
- public static class TestBean3 {
-
- private int x;
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- }
-
- public static class TestBean4 {
- private final String s1, s2;
- private String s3, s4;
-
- public TestBean4(String s1, String s2) {
- this.s1 = s1;
- this.s2 = s2;
- }
-
- public String getS1() {
- return s1;
- }
-
- public String getS2() {
- return s2;
- }
-
- public String getS3() {
- return s3;
- }
-
- public void setS3(String s3) {
- this.s3 = s3;
- }
-
- public String getS4() {
- return s4;
- }
-
- public void setS4(String s4) {
- this.s4 = s4;
- }
-
- }
-
- public static class TestBean5 {
-
- public final static TestBean5 INSTANCE = new TestBean5();
-
- private final int i;
- private int x;
-
- public TestBean5() {
- i = 0;
- }
-
- public TestBean5(int i) {
- this.i = i;
- }
-
- public int getI() {
- return i;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- }
-
- public static class TestBean6 {
- private final TestBean1 b1;
- private int x;
- private final TestBean2 b2;
- private int y;
- private TestBean2 b3;
- private TestBean6 b4;
-
- public TestBean6(TestBean1 b1, int x, TestBean2 b2) {
- this.b1 = b1;
- this.x = x;
- this.b2 = b2;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public int getY() {
- return y;
- }
-
- public void setY(int y) {
- this.y = y;
- }
-
- public TestBean2 getB3() {
- return b3;
- }
-
- public void setB3(TestBean2 b3) {
- this.b3 = b3;
- }
-
- public TestBean1 getB1() {
- return b1;
- }
-
- public TestBean2 getB2() {
- return b2;
- }
-
- public TestBean6 getB4() {
- return b4;
- }
-
- public void setB4(TestBean6 b4) {
- this.b4 = b4;
- }
-
- }
-
- public class TestBean7 {
-
- private String s;
- private int x;
- private boolean b;
-
- public String getS() {
- return s;
- }
-
- public void setS(String s) {
- this.s = s;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public boolean isB() {
- return b;
- }
-
- public void setB(boolean b) {
- this.b = b;
- }
-
- @Override
- public String toString() {
- return "TestBean [s=" + s + ", x=" + x + ", b=" + b + "]";
- }
-
- }
-
- public static class TestBean8 {
- private TimeZone timeZone;
- private Charset charset;
- private Object anyObject;
- private List<?> list;
-
- public TimeZone getTimeZone() {
- return timeZone;
- }
-
- public void setTimeZone(TimeZone timeZone) {
- this.timeZone = timeZone;
- }
-
- public Charset getCharset() {
- return charset;
- }
-
- public void setCharset(Charset charset) {
- this.charset = charset;
- }
-
- public Object getAnyObject() {
- return anyObject;
- }
-
- public void setAnyObject(Object anyObject) {
- this.anyObject = anyObject;
- }
-
- public List<?> getList() {
- return list;
- }
-
- public void setList(List<?> list) {
- this.list = list;
- }
-
- }
-
- public static class TestBean9 {
-
- private final int n;
- private final List<?> list;
- private final Map<?, ?> map;
-
- public TestBean9(int n) {
- this(n, null, null);
- }
-
- public TestBean9(int n, List<?> list) {
- this(n, list, null);
- }
-
- public TestBean9(int n, Map<?, ?> map) {
- this(n, null, map);
- }
-
- public TestBean9(int n, List<?> list, Map<?, ?> map) {
- this.n = n;
- this.list = list;
- this.map = map;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((list == null) ? 0 : list.hashCode());
- result = prime * result + ((map == null) ? 0 : map.hashCode());
- result = prime * result + n;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- TestBean9 other = (TestBean9) obj;
- if (list == null) {
- if (other.list != null) return false;
- } else if (!list.equals(other.list)) return false;
- if (map == null) {
- if (other.map != null) return false;
- } else if (!map.equals(other.map)) return false;
- return n == other.n;
- }
-
- }
-
- public static class TestStaticFields {
- public static final int CONST = 123;
- }
-
- public static class DummyArithmeticEngine extends ArithmeticEngine {
-
- private int x;
-
- @Override
- public int compareNumbers(Number first, Number second) throws TemplateException {
- return 0;
- }
-
- @Override
- public Number add(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number subtract(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number multiply(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number divide(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number modulus(Number first, Number second) throws TemplateException {
- return null;
- }
-
- @Override
- public Number toNumber(String s) {
- return null;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- }
-
- public static class DummyTemplateExceptionHandler implements TemplateExceptionHandler {
-
- private int x;
-
- @Override
- public void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException {
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- }
-
- public static class DummyCacheStorage implements CacheStorage {
-
- @Override
- public Object get(Object key) {
- return null;
- }
-
- @Override
- public void put(Object key, Object value) {
- }
-
- @Override
- public void remove(Object key) {
- }
-
- @Override
- public void clear() {
- }
-
- }
-
- public static class DummyNewBuiltinClassResolver implements TemplateClassResolver {
-
- @Override
- public Class resolve(String className, Environment env, Template template) throws TemplateException {
- return null;
- }
-
- }
-
- public static class DummyTemplateLoader implements TemplateLoader {
-
- @Override
- public TemplateLoaderSession createSession() {
- return null;
- }
-
- @Override
- public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom,
- Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException {
- return TemplateLoadingResult.NOT_FOUND;
- }
-
- @Override
- public void resetState() {
- // Do nothing
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
deleted file mode 100644
index 06e863c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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.core;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.freemarker.core.util.OptInTemplateClassResolver;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-public class OptInTemplateClassResolverTest extends TestCase {
-
- public OptInTemplateClassResolverTest(String name) {
- super(name);
- }
-
- private static final Set ALLOWED_CLASSES = new HashSet();
- static {
- ALLOWED_CLASSES.add("java.lang.String");
- ALLOWED_CLASSES.add("java.lang.Integer");
- }
-
- private static final List TRUSTED_TEMPLATES = new ArrayList();
- static {
- TRUSTED_TEMPLATES.add("lib/*");
- TRUSTED_TEMPLATES.add("/include/*");
- TRUSTED_TEMPLATES.add("trusted.ftl");
- }
-
- private OptInTemplateClassResolver resolver = new OptInTemplateClassResolver(
- ALLOWED_CLASSES, TRUSTED_TEMPLATES);
-
-
- public void testOptIn() throws TemplateException {
- Template dummyTemp = Template.createPlainTextTemplate("foo.ftl", "",
- new TestConfigurationBuilder().build());
-
- assertEquals(String.class, resolver.resolve("java.lang.String", null, dummyTemp));
- assertEquals(Integer.class, resolver.resolve("java.lang.Integer", null, dummyTemp));
- try {
- resolver.resolve("java.lang.Long", null, dummyTemp);
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- }
-
- public void testTrusted() throws TemplateException {
- Configuration cfg = new TestConfigurationBuilder().build();
-
- assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("lib/foo.ftl", "", cfg)));
- assertEquals(String.class, resolver.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("lib/foo.ftl", "", cfg)));
- assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("/lib/foo.ftl", "", cfg)));
- assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("include/foo.ftl", "", cfg)));
- assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("trusted.ftl", "", cfg)));
- assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("/trusted.ftl", "", cfg)));
- }
-
- public void testCraftedTrusted() throws TemplateException {
- testTrusted_checkFails("lib/../foo.ftl");
- testTrusted_checkFails("lib\\..\\foo.ftl");
- testTrusted_checkFails("lib\\../foo.ftl");
- testTrusted_checkFails("lib/..\\foo.ftl");
- testTrusted_checkFails("lib/..");
- testTrusted_checkFails("lib%2f%2E%2e%5cfoo.ftl");
- testTrusted_checkFails("/lib%5C%.%2e%2Efoo.ftl");
-
- try {
- testTrusted_checkFails("lib/./foo.ftl");
- fail();
- } catch (AssertionFailedError e) {
- // Expected
- }
- try {
- testTrusted_checkFails("lib/foo..ftl");
- fail();
- } catch (AssertionFailedError e) {
- // Expected
- }
- try {
- testTrusted_checkFails("lib/%2e/foo.ftl");
- fail();
- } catch (AssertionFailedError e) {
- // Expected
- }
- }
-
- public void testTrusted_checkFails(String templateName) {
- try {
- resolver.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate(templateName, "",
- new TestConfigurationBuilder().build()));
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- }
-
- public void testSettingParser() throws Exception {
- {
- Configuration cfg = new TestConfigurationBuilder()
- .setting(
- "new_builtin_class_resolver",
- "trusted_templates: foo.ftl, \"lib/*\"")
- .build();
-
- TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
- assertEquals(String.class, res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("foo.ftl", "", cfg)));
- assertEquals(String.class, res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("lib/bar.ftl", "", cfg)));
- try {
- res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("bar.ftl", "", cfg));
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- }
-
- {
- Configuration cfg = new TestConfigurationBuilder()
- .setting(
- "new_builtin_class_resolver",
- "allowed_classes: java.lang.String, java.lang.Integer")
- .build();
-
- TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
- assertEquals(String.class, res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("foo.ftl", "", cfg)));
- assertEquals(Integer.class, res.resolve("java.lang.Integer", null,
- Template.createPlainTextTemplate("foo.ftl", "", cfg)));
- try {
- res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("foo.ftl", "", cfg));
- fail();
- } catch (TemplateException e) {
- // good
- }
- }
-
- {
- Configuration cfg = new TestConfigurationBuilder()
- .setting(
- "new_builtin_class_resolver",
- "trusted_templates: foo.ftl, 'lib/*', allowed_classes: 'java.lang.String',"
- + " java.lang.Integer")
- .build();
- TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
- assertEquals(String.class, res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg)));
- assertEquals(Integer.class, res.resolve("java.lang.Integer", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg)));
- try {
- res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg));
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- assertEquals(Long.class, res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("foo.ftl", "", cfg)));
- assertEquals(Long.class, res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("lib/bar.ftl", "", cfg)));
- try {
- res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg));
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- }
-
- try {
- new TestConfigurationBuilder().setSetting("new_builtin_class_resolver", "wrong: foo");
- fail();
- } catch (ConfigurationException e) {
- // Expected
- }
-
- {
- Configuration cfg = new TestConfigurationBuilder()
- .setting(
- "new_builtin_class_resolver",
- "\"allowed_classes\" : java.lang.String , 'trusted_templates' :\"lib:*\"")
- .build();
- TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
- assertEquals(String.class, res.resolve("java.lang.String", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg)));
- try {
- res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("x.ftl", "", cfg));
- fail();
- } catch (TemplateException e) {
- // Expected
- }
- assertEquals(Long.class, res.resolve("java.lang.Long", null,
- Template.createPlainTextTemplate("lib:bar.ftl", "", cfg)));
- }
- }
-
-}
[43/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.java
new file mode 100644
index 0000000..3b59e78
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SettingDirectiveTest.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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class SettingDirectiveTest {
+
+ @Test
+ public void testGetSettingNamesSorted() throws Exception {
+ String prevName = null;
+ for (String name : ASTDirSetting.SETTING_NAMES) {
+ if (prevName != null) {
+ assertThat(name, greaterThan(prevName));
+ }
+ prevName = name;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
new file mode 100644
index 0000000..7e17fc7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+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.test.TemplateTest;
+import org.junit.Test;
+
+public class SpecialVariableTest extends TemplateTest {
+
+ @Test
+ public void testNamesSorted() throws Exception {
+ String prevName = null;
+ for (String name : ASTExpBuiltInVariable.SPEC_VAR_NAMES) {
+ if (prevName != null) {
+ assertThat(name, greaterThan(prevName));
+ }
+ prevName = name;
+ }
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ String versionStr = Configuration.getVersion().toString();
+ assertOutput("${.version}", versionStr);
+ }
+
+ @Test
+ public void testIncompationImprovements() throws Exception {
+ setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0).build());
+ assertOutput(
+ "${.incompatibleImprovements}",
+ getConfiguration().getIncompatibleImprovements().toString());
+
+ setConfiguration(new Configuration.Builder(Configuration.getVersion()).build());
+ assertOutput(
+ "${.incompatible_improvements}",
+ getConfiguration().getIncompatibleImprovements().toString());
+ }
+
+ @Test
+ public void testAutoEsc() throws Exception {
+ Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
+
+ for (int autoEscaping : new int[] {
+ ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY, ParsingConfiguration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY }) {
+ cfgB.setAutoEscapingPolicy(autoEscaping);
+ cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "true");
+ assertOutput("<#ftl autoEsc=false>${.autoEsc?c}", "false");
+
+ cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "false");
+
+ cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "false");
+ }
+
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
+ cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "false");
+ assertOutput("<#ftl autoEsc=true>${.autoEsc?c}", "true");
+
+ cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "false");
+
+ cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE);
+ setConfiguration(cfgB.build());
+ assertOutput("${.autoEsc?c}", "false");
+
+ cfgB.setAutoEscapingPolicy(ParsingConfiguration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY);
+ setConfiguration(cfgB.build());
+ assertOutput(
+ "${.autoEsc?c} "
+ + "<#outputFormat 'HTML'>${.autoEsc?c}</#outputFormat> "
+ + "<#outputFormat 'undefined'>${.autoEsc?c}</#outputFormat> "
+ + "<#outputFormat 'HTML'>"
+ + "${.autoEsc?c} <#noAutoEsc>${.autoEsc?c} "
+ + "<#autoEsc>${.autoEsc?c}</#autoEsc> ${.autoEsc?c}</#noAutoEsc> ${.autoEsc?c}"
+ + "</#outputFormat>",
+ "false true false "
+ + "true false true false true");
+
+ assertErrorContains("${.autoEscaping}", "You may meant: \"autoEsc\"");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
new file mode 100644
index 0000000..ae72dac
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/StringLiteralInterpolationTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
+import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class StringLiteralInterpolationTest extends TemplateTest {
+
+ @Test
+ public void basics() throws IOException, TemplateException {
+ addToDataModel("x", 1);
+ assertOutput("${'${x}'}", "1");
+ assertOutput("${'#{x}'}", "1");
+ assertOutput("${'a${x}b${x*2}c'}", "a1b2c");
+ assertOutput("${'a#{x}b#{x*2}c'}", "a1b2c");
+ assertOutput("${'a#{x; m2}'}", "a1.00");
+ assertOutput("${'${x} ${x}'}", "1 1");
+ assertOutput("${'$\\{x}'}", "${x}");
+ assertOutput("${'$\\{x} $\\{x}'}", "${x} ${x}");
+ assertOutput("${'<#-- not a comment -->${x}'}", "<#-- not a comment -->1");
+ assertOutput("${'<#-- not a comment -->$\\{x}'}", "<#-- not a comment -->${x}");
+ assertOutput("${'<#assign x = 2> ${x} <#assign x = 2>'}", "<#assign x = 2> 1 <#assign x = 2>");
+ assertOutput("${'<#assign x = 2> $\\{x} <#assign x = 2>'}", "<#assign x = 2> ${x} <#assign x = 2>");
+ assertOutput("${'<@x/>${x}<@x/>'}", "<@x/>1<@x/>");
+ assertOutput("${'<@x/>$\\{x}<@x/>'}", "<@x/>${x}<@x/>");
+ assertOutput("${'<@ ${x}<@'}", "<@ 1<@");
+ assertOutput("${'<@ $\\{x}<@'}", "<@ ${x}<@");
+ assertOutput("${'</...@x>${x}'}", "</...@x>1");
+ assertOutput("${'</...@x>$\\{x}'}", "</...@x>${x}");
+ assertOutput("${'</@ ${x}</@'}", "</@ 1</@");
+ assertOutput("${'</@ $\\{x}</@'}", "</@ ${x}</@");
+ assertOutput("${'[@ ${x}'}", "[@ 1");
+ assertOutput("${'[@ $\\{x}'}", "[@ ${x}");
+ }
+
+ /**
+ * Broken behavior for backward compatibility.
+ */
+ @Test
+ public void legacyEscapingBugStillPresent() throws IOException, TemplateException {
+ addToDataModel("x", 1);
+ assertOutput("${'$\\{x} ${x}'}", "1 1");
+ assertOutput("${'${x} $\\{x}'}", "1 1");
+ }
+
+ @Test
+ public void legacyLengthGlitch() throws IOException, TemplateException {
+ assertOutput("${'${'}", "${");
+ assertOutput("${'${1'}", "${1");
+ assertOutput("${'${}'}", "${}");
+ assertOutput("${'${1}'}", "1");
+ assertErrorContains("${'${ '}", "");
+ }
+
+ @Test
+ public void testErrors() {
+ addToDataModel("x", 1);
+ assertErrorContains("${'${noSuchVar}'}", InvalidReferenceException.class, "missing", "noSuchVar");
+ assertErrorContains("${'${x/0}'}", ArithmeticException.class, "zero");
+ }
+
+ @Test
+ public void escaping() throws IOException, TemplateException {
+ assertOutput("<#escape x as x?html><#assign x = '&'>${x} ${'${x}'}</#escape> ${x}", "& & &");
+ }
+
+ // We couldn't test this on 3.0.0, as nothing was fixed there with IcI yet
+ /*-
+ @Test
+ public void iciInheritanceBugFixed() throws Exception {
+ // Broken behavior emulated:
+ getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_23);
+ assertOutput("${'&\\''?html} ${\"${'&\\\\\\''?html}\"}", "&' &'");
+
+ // Fix enabled:
+ getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_24);
+ assertOutput("${'&\\''?html} ${\"${'&\\\\\\''?html}\"}", "&' &'");
+ }
+ */
+
+ @Test
+ public void markup() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .customNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
+ "G", PrintfGTemplateNumberFormatFactory.INSTANCE))
+ .numberFormat("@G 3")
+ .build());
+
+ assertOutput("${\"${1000}\"}", "1.00*10<sup>3</sup>");
+ assertOutput("${\"&_${1000}\"}", "&_1.00*10<sup>3</sup>");
+ assertOutput("${\"${1000}_&\"}", "1.00*10<sup>3</sup>_&");
+ assertOutput("${\"${1000}, ${2000}\"}", "1.00*10<sup>3</sup>, 2.00*10<sup>3</sup>");
+ assertOutput("${\"& ${'x'}, ${2000}\"}", "& x, 2.00*10<sup>3</sup>");
+ assertOutput("${\"& ${'x'}, #{2000}\"}", "& x, 2000");
+
+ assertOutput("${\"${2000}\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"x ${2000}\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"${2000} x\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"#{2000}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"${'x'}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"x ${'x'}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"${'x'} x\"?isMarkupOutput?c}", "false");
+
+ addToDataModel("rtf", RTFOutputFormat.INSTANCE.fromMarkup("\\p"));
+ assertOutput("${\"${rtf}\"?isMarkupOutput?c}", "true");
+ assertErrorContains("${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
+ assertErrorContains("x${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TabSizeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TabSizeTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TabSizeTest.java
new file mode 100644
index 0000000..7945b5e
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TabSizeTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class TabSizeTest extends TemplateTest {
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return super.createDefaultConfiguration();
+ }
+
+ @Test
+ public void testBasics() throws Exception {
+ assertErrorColumnNumber(3, "${*}");
+ assertErrorColumnNumber(8 + 3, "\t${*}");
+ assertErrorColumnNumber(16 + 3, "\t\t${*}");
+ assertErrorColumnNumber(16 + 3, " \t \t${*}");
+
+ setConfiguration(new TestConfigurationBuilder().tabSize(1).build());
+ assertErrorColumnNumber(3, "${*}");
+ assertErrorColumnNumber(1 + 3, "\t${*}");
+ assertErrorColumnNumber(2 + 3, "\t\t${*}");
+ assertErrorColumnNumber(6 + 3, " \t \t${*}");
+ }
+
+ @Test
+ public void testEvalBI() throws Exception {
+ assertErrorContains("${r'\t~'?eval}", "column 9");
+ setConfiguration(new TestConfigurationBuilder().tabSize(4).build());
+ assertErrorContains("${r'\t~'?eval}", "column 5");
+ }
+
+ @Test
+ public void testInterpretBI() throws Exception {
+ assertErrorContains("<@'\\t$\\{*}'?interpret />", "column 11");
+ setConfiguration(new TestConfigurationBuilder().tabSize(4).build());
+ assertErrorContains("<@'\\t$\\{*}'?interpret />", "column 7");
+ }
+
+ @Test
+ public void testStringLiteralInterpolation() throws Exception {
+ assertErrorColumnNumber(6, "${'${*}'}");
+ assertErrorColumnNumber(9, "${'${\t*}'}");
+ setConfiguration(new TestConfigurationBuilder().tabSize(16).build());
+ assertErrorColumnNumber(17, "${'${\t*}'}");
+ }
+
+ protected void assertErrorColumnNumber(int expectedColumn, String templateSource)
+ throws IOException {
+ addTemplate("t", templateSource);
+ try {
+ getConfiguration().getTemplate("t");
+ fail();
+ } catch (ParseException e) {
+ assertEquals(expectedColumn, e.getColumnNumber());
+ }
+ getConfiguration().clearTemplateCache();
+
+ try {
+ new Template(null, templateSource, getConfiguration());
+ fail();
+ } catch (ParseException e) {
+ assertEquals(expectedColumn, e.getColumnNumber());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
new file mode 100644
index 0000000..fa21c76
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+
+import junit.framework.TestCase;
+
+/**
+ * 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 {
+ // 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++) {
+ Configuration cfg = new TestConfigurationBuilder()
+ .tagSyntax(angOrSqu == 0
+ ? ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX
+ : ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX)
+ .build();
+
+ 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(cfg,
+ 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;
+
+ test(cfg,
+ wrongx_xxx + dir_xxx,
+ null);
+
+ test(cfg,
+ dir_xxx + wrongx_xxx,
+ null);
+
+ test(cfg,
+ hdr_xxx + wrongx_xxx,
+ null);
+
+ test(cfg,
+ cust_xxx + wrongx_xxx + dir_xxx,
+ null);
+ } // for wrongc
+ } // for squ
+
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
+ .build();
+ 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;
+
+ test(cfg,
+ wrong_xxx + dir_xxx,
+ null);
+ } // for perm
+ }
+
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
+ .build();
+ // 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(cfg,
+ cust_xxx + wrong_yyy + dir_xxx,
+ CUST_OUT + wrong_yyy + dir_out);
+
+ test(cfg,
+ hdr_xxx + wrong_yyy + dir_xxx,
+ wrong_yyy + dir_out);
+
+ test(cfg,
+ cust_xxx + wrong_yyy + dir_yyy,
+ CUST_OUT + wrong_yyy + dir_yyy);
+
+ test(cfg,
+ hdr_xxx + wrong_yyy + dir_yyy,
+ wrong_yyy + dir_yyy);
+
+ test(cfg,
+ 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 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 invoke 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());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
new file mode 100644
index 0000000..5b1cda9
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java
@@ -0,0 +1,909 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.apache.commons.collections.ListUtils;
+import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
+import org.apache.freemarker.core.arithmetic.impl.ConservativeArithmeticEngine;
+import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+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.impl.StringTemplateLoader;
+import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.LocAndTZSensitiveTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.LocaleSensitiveTemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.test.MonitoredTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class TemplateConfigurationTest {
+
+ private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
+
+ private final class DummyArithmeticEngine extends ArithmeticEngine {
+
+ @Override
+ public int compareNumbers(Number first, Number second) throws TemplateException {
+ return 0;
+ }
+
+ @Override
+ public Number add(Number first, Number second) throws TemplateException {
+ return 22;
+ }
+
+ @Override
+ public Number subtract(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number multiply(Number first, Number second) throws TemplateException {
+ return 33;
+ }
+
+ @Override
+ public Number divide(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number modulus(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number toNumber(String s) {
+ return 11;
+ }
+ }
+
+ private static final Configuration DEFAULT_CFG;
+ static {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
+ StringTemplateLoader stl = new StringTemplateLoader();
+ stl.putTemplate("t1.ftl", "<#global loaded = (loaded!) + 't1;'>In t1;");
+ stl.putTemplate("t2.ftl", "<#global loaded = (loaded!) + 't2;'>In t2;");
+ stl.putTemplate("t3.ftl", "<#global loaded = (loaded!) + 't3;'>In t3;");
+ try {
+ DEFAULT_CFG = cfgB.templateLoader(stl).build();
+ } catch (ConfigurationException e) {
+ throw new IllegalStateException("Faild to create default configuration", e);
+ }
+ }
+
+ private static final TimeZone NON_DEFAULT_TZ;
+ static {
+ TimeZone defaultTZ = DEFAULT_CFG.getTimeZone();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ if (tz.equals(defaultTZ)) {
+ tz = TimeZone.getTimeZone("GMT+01");
+ if (tz.equals(defaultTZ)) {
+ throw new AssertionError("Couldn't chose a non-default time zone");
+ }
+ }
+ NON_DEFAULT_TZ = tz;
+ }
+
+ private static final Locale NON_DEFAULT_LOCALE =
+ DEFAULT_CFG.getLocale().equals(Locale.US) ? Locale.GERMAN : Locale.US;
+
+ private static final Charset NON_DEFAULT_ENCODING =
+ DEFAULT_CFG.getSourceEncoding().equals(StandardCharsets.UTF_8) ? StandardCharsets.UTF_16LE
+ : StandardCharsets.UTF_8;
+
+ private static final Map<String, Object> SETTING_ASSIGNMENTS;
+
+ static {
+ SETTING_ASSIGNMENTS = new HashMap<>();
+
+ // "MutableProcessingConfiguration" settings:
+ SETTING_ASSIGNMENTS.put("APIBuiltinEnabled", true);
+ SETTING_ASSIGNMENTS.put("SQLDateAndTimeTimeZone", NON_DEFAULT_TZ);
+ SETTING_ASSIGNMENTS.put("URLEscapingCharset", StandardCharsets.UTF_16);
+ SETTING_ASSIGNMENTS.put("autoFlush", false);
+ SETTING_ASSIGNMENTS.put("booleanFormat", "J,N");
+ SETTING_ASSIGNMENTS.put("dateFormat", "yyyy-#DDD");
+ SETTING_ASSIGNMENTS.put("dateTimeFormat", "yyyy-#DDD-@HH:mm");
+ SETTING_ASSIGNMENTS.put("locale", NON_DEFAULT_LOCALE);
+ SETTING_ASSIGNMENTS.put("logTemplateExceptions", true);
+ SETTING_ASSIGNMENTS.put("newBuiltinClassResolver", TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
+ SETTING_ASSIGNMENTS.put("numberFormat", "0.0000");
+ SETTING_ASSIGNMENTS.put("objectWrapper",
+ new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ SETTING_ASSIGNMENTS.put("outputEncoding", StandardCharsets.UTF_16);
+ SETTING_ASSIGNMENTS.put("showErrorTips", false);
+ SETTING_ASSIGNMENTS.put("templateExceptionHandler", TemplateExceptionHandler.IGNORE_HANDLER);
+ SETTING_ASSIGNMENTS.put("timeFormat", "@HH:mm");
+ SETTING_ASSIGNMENTS.put("timeZone", NON_DEFAULT_TZ);
+ SETTING_ASSIGNMENTS.put("arithmeticEngine", ConservativeArithmeticEngine.INSTANCE);
+ SETTING_ASSIGNMENTS.put("customNumberFormats",
+ ImmutableMap.of("dummy", HexTemplateNumberFormatFactory.INSTANCE));
+ SETTING_ASSIGNMENTS.put("customDateFormats",
+ ImmutableMap.of("dummy", EpochMillisTemplateDateFormatFactory.INSTANCE));
+ SETTING_ASSIGNMENTS.put("customAttributes", ImmutableMap.of("dummy", 123));
+
+ // Parser-only settings:
+ SETTING_ASSIGNMENTS.put("templateLanguage", TemplateLanguage.STATIC_TEXT);
+ SETTING_ASSIGNMENTS.put("tagSyntax", ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX);
+ SETTING_ASSIGNMENTS.put("namingConvention", ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ SETTING_ASSIGNMENTS.put("whitespaceStripping", false);
+ SETTING_ASSIGNMENTS.put("strictSyntaxMode", false);
+ SETTING_ASSIGNMENTS.put("autoEscapingPolicy", ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
+ SETTING_ASSIGNMENTS.put("outputFormat", HTMLOutputFormat.INSTANCE);
+ SETTING_ASSIGNMENTS.put("recognizeStandardFileExtensions", false);
+ SETTING_ASSIGNMENTS.put("tabSize", 1);
+ SETTING_ASSIGNMENTS.put("lazyImports", Boolean.TRUE);
+ SETTING_ASSIGNMENTS.put("lazyAutoImports", Boolean.FALSE);
+ SETTING_ASSIGNMENTS.put("autoImports", ImmutableMap.of("a", "/lib/a.ftl"));
+ SETTING_ASSIGNMENTS.put("autoIncludes", ImmutableList.of("/lib/b.ftl"));
+
+ // Special settings:
+ SETTING_ASSIGNMENTS.put("sourceEncoding", NON_DEFAULT_ENCODING);
+ }
+
+ public static String getIsSetMethodName(String readMethodName) {
+ return (readMethodName.startsWith("get") ? "is" + readMethodName.substring(3)
+ : readMethodName)
+ + "Set";
+ }
+
+ public static List<PropertyDescriptor> getTemplateConfigurationSettingPropDescs(
+ Class<? extends ProcessingConfiguration> confClass, boolean includeCompilerSettings)
+ throws IntrospectionException {
+ List<PropertyDescriptor> settingPropDescs = new ArrayList<>();
+
+ BeanInfo beanInfo = Introspector.getBeanInfo(confClass);
+ for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
+ String name = pd.getName();
+ if (pd.getWriteMethod() != null && !IGNORED_PROP_NAMES.contains(name)
+ && (includeCompilerSettings
+ || (CONFIGURABLE_PROP_NAMES.contains(name) || !PARSER_PROP_NAMES.contains(name)))) {
+ if (pd.getReadMethod() == null) {
+ throw new AssertionError("Property has no read method: " + pd);
+ }
+ settingPropDescs.add(pd);
+ }
+ }
+
+ Collections.sort(settingPropDescs, new Comparator<PropertyDescriptor>() {
+ @Override
+ public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+ });
+
+ return settingPropDescs;
+ }
+
+ private static final Set<String> IGNORED_PROP_NAMES;
+
+ static {
+ IGNORED_PROP_NAMES = new HashSet();
+ IGNORED_PROP_NAMES.add("class");
+ IGNORED_PROP_NAMES.add("strictBeanModels");
+ IGNORED_PROP_NAMES.add("parentConfiguration");
+ IGNORED_PROP_NAMES.add("settings");
+ }
+
+ private static final Set<String> CONFIGURABLE_PROP_NAMES;
+ static {
+ CONFIGURABLE_PROP_NAMES = new HashSet<>();
+ try {
+ for (PropertyDescriptor propDesc : Introspector.getBeanInfo(MutableProcessingConfiguration.class).getPropertyDescriptors()) {
+ String propName = propDesc.getName();
+ if (!IGNORED_PROP_NAMES.contains(propName)) {
+ CONFIGURABLE_PROP_NAMES.add(propName);
+ }
+ }
+ } catch (IntrospectionException e) {
+ throw new IllegalStateException("Failed to init static field", e);
+ }
+ }
+
+ private static final Set<String> PARSER_PROP_NAMES;
+ static {
+ PARSER_PROP_NAMES = new HashSet<>();
+ // It's an interface; can't use standard Inrospector
+ for (Method m : ParsingConfiguration.class.getMethods()) {
+ String propertyName;
+ String name = m.getName();
+ if (name.startsWith("get")) {
+ propertyName = name.substring(3);
+ } else if (name.startsWith("is") && !name.endsWith("Set")) {
+ propertyName = name.substring(2);
+ } else {
+ propertyName = null;
+ }
+ if (propertyName != null) {
+ if (!Character.isUpperCase(propertyName.charAt(1))) {
+ propertyName = Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
+ }
+ PARSER_PROP_NAMES.add(propertyName);
+ }
+ }
+ }
+
+ private static final Object CA1 = new Object();
+ private static final String CA2 = "ca2";
+ private static final String CA3 = "ca3";
+ private static final String CA4 = "ca4";
+
+ @Test
+ public void testMergeBasicFunctionality() throws Exception {
+ for (PropertyDescriptor propDesc1 : getTemplateConfigurationSettingPropDescs(
+ TemplateConfiguration.Builder.class, true)) {
+ for (PropertyDescriptor propDesc2 : getTemplateConfigurationSettingPropDescs(
+ TemplateConfiguration.Builder.class, true)) {
+ TemplateConfiguration.Builder tcb1 = new TemplateConfiguration.Builder();
+ TemplateConfiguration.Builder tcb2 = new TemplateConfiguration.Builder();
+
+ Object value1 = SETTING_ASSIGNMENTS.get(propDesc1.getName());
+ propDesc1.getWriteMethod().invoke(tcb1, value1);
+ Object value2 = SETTING_ASSIGNMENTS.get(propDesc2.getName());
+ propDesc2.getWriteMethod().invoke(tcb2, value2);
+
+ tcb1.merge(tcb2);
+ if (propDesc1.getName().equals(propDesc2.getName()) && value1 instanceof List
+ && !propDesc1.getName().equals("autoIncludes")) {
+ assertEquals("For " + propDesc1.getName(),
+ ListUtils.union((List) value1, (List) value1), propDesc1.getReadMethod().invoke(tcb1));
+ } else { // Values of the same setting merged
+ assertEquals("For " + propDesc1.getName(), value1, propDesc1.getReadMethod().invoke(tcb1));
+ assertEquals("For " + propDesc2.getName(), value2, propDesc2.getReadMethod().invoke(tcb1));
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testMergeMapSettings() throws Exception {
+ TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
+ tc1.setCustomDateFormats(ImmutableMap.of(
+ "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
+ "x", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE));
+ tc1.setCustomNumberFormats(ImmutableMap.of(
+ "hex", HexTemplateNumberFormatFactory.INSTANCE,
+ "x", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE));
+ tc1.setAutoImports(ImmutableMap.of("a", "a1.ftl", "b", "b1.ftl"));
+
+ TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
+ tc2.setCustomDateFormats(ImmutableMap.of(
+ "loc", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE,
+ "x", EpochMillisDivTemplateDateFormatFactory.INSTANCE));
+ tc2.setCustomNumberFormats(ImmutableMap.of(
+ "loc", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE,
+ "x", BaseNTemplateNumberFormatFactory.INSTANCE));
+ tc2.setAutoImports(ImmutableMap.of("b", "b2.ftl", "c", "c2.ftl"));
+
+ tc1.merge(tc2);
+
+ Map<String, ? extends TemplateDateFormatFactory> mergedCustomDateFormats = tc1.getCustomDateFormats();
+ assertEquals(EpochMillisTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("epoch"));
+ assertEquals(LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("loc"));
+ assertEquals(EpochMillisDivTemplateDateFormatFactory.INSTANCE, mergedCustomDateFormats.get("x"));
+
+ Map<String, ? extends TemplateNumberFormatFactory> mergedCustomNumberFormats = tc1.getCustomNumberFormats();
+ assertEquals(HexTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("hex"));
+ assertEquals(LocaleSensitiveTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("loc"));
+ assertEquals(BaseNTemplateNumberFormatFactory.INSTANCE, mergedCustomNumberFormats.get("x"));
+
+ Map<String, String> mergedAutoImports = tc1.getAutoImports();
+ assertEquals("a1.ftl", mergedAutoImports.get("a"));
+ assertEquals("b2.ftl", mergedAutoImports.get("b"));
+ assertEquals("c2.ftl", mergedAutoImports.get("c"));
+
+ // Empty map merging optimization:
+ tc1.merge(new TemplateConfiguration.Builder());
+ assertSame(mergedCustomDateFormats, tc1.getCustomDateFormats());
+ assertSame(mergedCustomNumberFormats, tc1.getCustomNumberFormats());
+
+ // Empty map merging optimization:
+ TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
+ tc3.merge(tc1);
+ assertSame(mergedCustomDateFormats, tc3.getCustomDateFormats());
+ assertSame(mergedCustomNumberFormats, tc3.getCustomNumberFormats());
+ }
+
+ @Test
+ public void testMergeListSettings() throws Exception {
+ TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
+ tc1.setAutoIncludes(ImmutableList.of("a.ftl", "x.ftl", "b.ftl"));
+
+ TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
+ tc2.setAutoIncludes(ImmutableList.of("c.ftl", "x.ftl", "d.ftl"));
+
+ tc1.merge(tc2);
+
+ assertEquals(ImmutableList.of("a.ftl", "b.ftl", "c.ftl", "x.ftl", "d.ftl"), tc1.getAutoIncludes());
+ }
+
+ @Test
+ public void testMergePriority() throws Exception {
+ TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
+ tc1.setDateFormat("1");
+ tc1.setTimeFormat("1");
+ tc1.setDateTimeFormat("1");
+
+ TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
+ tc2.setDateFormat("2");
+ tc2.setTimeFormat("2");
+
+ TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
+ tc3.setDateFormat("3");
+
+ tc1.merge(tc2);
+ tc1.merge(tc3);
+
+ assertEquals("3", tc1.getDateFormat());
+ assertEquals("2", tc1.getTimeFormat());
+ assertEquals("1", tc1.getDateTimeFormat());
+ }
+
+ @Test
+ public void testMergeCustomAttributes() throws Exception {
+ TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
+ tc1.setCustomAttribute("k1", "v1");
+ tc1.setCustomAttribute("k2", "v1");
+ tc1.setCustomAttribute("k3", "v1");
+ tc1.setCustomAttribute(CA1, "V1");
+ tc1.setCustomAttribute(CA2, "V1");
+ tc1.setCustomAttribute(CA3, "V1");
+
+ TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
+ tc2.setCustomAttribute("k1", "v2");
+ tc2.setCustomAttribute("k2", "v2");
+ tc2.setCustomAttribute(CA1, "V2");
+ tc2.setCustomAttribute(CA2, "V2");
+
+ TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
+ tc3.setCustomAttribute("k1", "v3");
+ tc3.setCustomAttribute(CA1, "V3");
+
+ tc1.merge(tc2);
+ tc1.merge(tc3);
+
+ assertEquals("v3", tc1.getCustomAttribute("k1"));
+ assertEquals("v2", tc1.getCustomAttribute("k2"));
+ assertEquals("v1", tc1.getCustomAttribute("k3"));
+ assertEquals("V3", tc1.getCustomAttribute(CA1));
+ assertEquals("V2", tc1.getCustomAttribute(CA2));
+ assertEquals("V1", tc1.getCustomAttribute(CA3));
+ }
+
+ @Test
+ public void testMergeNullCustomAttributes() throws Exception {
+ TemplateConfiguration.Builder tc1 = new TemplateConfiguration.Builder();
+ tc1.setCustomAttribute("k1", "v1");
+ tc1.setCustomAttribute("k2", "v1");
+ tc1.setCustomAttribute(CA1, "V1");
+ tc1.setCustomAttribute(CA2,"V1");
+
+ assertEquals("v1", tc1.getCustomAttribute("k1"));
+ assertEquals("v1", tc1.getCustomAttribute("k2"));
+ assertNull("v1", tc1.getCustomAttribute("k3"));
+ assertEquals("V1", tc1.getCustomAttribute(CA1));
+ assertEquals("V1", tc1.getCustomAttribute(CA2));
+ assertNull(tc1.getCustomAttribute(CA3));
+
+ TemplateConfiguration.Builder tc2 = new TemplateConfiguration.Builder();
+ tc2.setCustomAttribute("k1", "v2");
+ tc2.setCustomAttribute("k2", null);
+ tc2.setCustomAttribute(CA1, "V2");
+ tc2.setCustomAttribute(CA2, null);
+
+ TemplateConfiguration.Builder tc3 = new TemplateConfiguration.Builder();
+ tc3.setCustomAttribute("k1", null);
+ tc2.setCustomAttribute(CA1, null);
+
+ tc1.merge(tc2);
+ tc1.merge(tc3);
+
+ assertNull(tc1.getCustomAttribute("k1"));
+ assertNull(tc1.getCustomAttribute("k2"));
+ assertNull(tc1.getCustomAttribute("k3"));
+ assertNull(tc1.getCustomAttribute(CA1));
+ assertNull(tc1.getCustomAttribute(CA2));
+ assertNull(tc1.getCustomAttribute(CA3));
+
+ TemplateConfiguration.Builder tc4 = new TemplateConfiguration.Builder();
+ tc4.setCustomAttribute("k1", "v4");
+ tc4.setCustomAttribute(CA1, "V4");
+
+ tc1.merge(tc4);
+
+ assertEquals("v4", tc1.getCustomAttribute("k1"));
+ assertNull(tc1.getCustomAttribute("k2"));
+ assertNull(tc1.getCustomAttribute("k3"));
+ assertEquals("V4", tc1.getCustomAttribute(CA1));
+ assertNull(tc1.getCustomAttribute(CA2));
+ assertNull(tc1.getCustomAttribute(CA3));
+ }
+
+ @Test
+ public void testConfigureNonParserConfig() throws Exception {
+ for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
+ TemplateConfiguration.Builder.class, false)) {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+
+ Object newValue = SETTING_ASSIGNMENTS.get(pd.getName());
+ pd.getWriteMethod().invoke(tcb, newValue);
+
+ TemplateConfiguration tc = tcb.build();
+
+ Method tReaderMethod = Template.class.getMethod(pd.getReadMethod().getName());
+
+ // Without TC
+ assertNotEquals("For \"" + pd.getName() + "\"",
+ tReaderMethod.invoke(new Template(null, "", DEFAULT_CFG)));
+ // With TC
+ assertEquals("For \"" + pd.getName() + "\"", newValue,
+ tReaderMethod.invoke(new Template(null, "", DEFAULT_CFG, tc)));
+ }
+ }
+
+ @Test
+ public void testConfigureCustomAttributes() throws Exception {
+ Configuration cfg = new TestConfigurationBuilder()
+ .customAttribute("k1", "c")
+ .customAttribute("k2", "c")
+ .customAttribute("k3", "c")
+ .build();
+
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setCustomAttribute("k2", "tc");
+ tcb.setCustomAttribute("k3", null);
+ tcb.setCustomAttribute("k4", "tc");
+ tcb.setCustomAttribute("k5", "tc");
+ tcb.setCustomAttribute("k6", "tc");
+ tcb.setCustomAttribute(CA1, "tc");
+ tcb.setCustomAttribute(CA2,"tc");
+ tcb.setCustomAttribute(CA3,"tc");
+
+ TemplateConfiguration tc = tcb.build();
+ Template t = new Template(null, "", cfg, tc);
+ t.setCustomAttribute("k5", "t");
+ t.setCustomAttribute("k6", null);
+ t.setCustomAttribute("k7", "t");
+ t.setCustomAttribute(CA2, "t");
+ t.setCustomAttribute(CA3, null);
+ t.setCustomAttribute(CA4, "t");
+
+ assertEquals("c", t.getCustomAttribute("k1"));
+ assertEquals("tc", t.getCustomAttribute("k2"));
+ assertNull(t.getCustomAttribute("k3"));
+ assertEquals("tc", t.getCustomAttribute("k4"));
+ assertEquals("t", t.getCustomAttribute("k5"));
+ assertNull(t.getCustomAttribute("k6"));
+ assertEquals("t", t.getCustomAttribute("k7"));
+ assertEquals("tc", t.getCustomAttribute(CA1));
+ assertEquals("t", t.getCustomAttribute(CA2));
+ assertNull(t.getCustomAttribute(CA3));
+ assertEquals("t", t.getCustomAttribute(CA4));
+ }
+
+ @Test
+ public void testConfigureParser() throws Exception {
+ Set<String> testedProps = new HashSet<>();
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setTagSyntax(ParsingConfiguration.SQUARE_BRACKET_TAG_SYNTAX);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "[#if true]y[/#if]", "[#if true]y[/#if]", "y");
+ testedProps.add(Configuration.ExtendableBuilder.TAG_SYNTAX_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setNamingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "<#if true>y<#elseif false>n</#if>", "y", null);
+ testedProps.add(Configuration.ExtendableBuilder.NAMING_CONVENTION_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setWhitespaceStripping(false);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "<#if true>\nx\n</#if>\n", "x\n", "\nx\n\n");
+ testedProps.add(Configuration.ExtendableBuilder.WHITESPACE_STRIPPING_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setArithmeticEngine(new DummyArithmeticEngine());
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "${1} ${1+1}", "1 2", "11 22");
+ testedProps.add(Configuration.ExtendableBuilder.ARITHMETIC_ENGINE_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setOutputFormat(XMLOutputFormat.INSTANCE);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "${.outputFormat} ${\"a'b\"}",
+ UndefinedOutputFormat.INSTANCE.getName() + " a'b",
+ XMLOutputFormat.INSTANCE.getName() + " a'b");
+ testedProps.add(Configuration.ExtendableBuilder.OUTPUT_FORMAT_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setOutputFormat(XMLOutputFormat.INSTANCE);
+ tcb.setAutoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "${'a&b'}", "a&b", "a&b");
+ testedProps.add(Configuration.ExtendableBuilder.AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ /* Can't test this now, as the only valid value is 3.0.0. [FM3.0.1]
+ TemplateConfiguration tc = tcb.build();
+ tc.setParentConfiguration(new Configuration(new Version(2, 3, 0)));
+ assertOutputWithoutAndWithTC(tc, "<#foo>", null, "<#foo>");
+ */
+ testedProps.add(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setRecognizeStandardFileExtensions(false);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "adhoc.ftlh", "${.outputFormat}",
+ HTMLOutputFormat.INSTANCE.getName(), UndefinedOutputFormat.INSTANCE.getName());
+ testedProps.add(Configuration.ExtendableBuilder.RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE);
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setLogTemplateExceptions(false);
+ tcb.setTabSize(3);
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#attempt><@'\\t$\\{1+}'?interpret/><#recover>"
+ + "${.error?replace('(?s).*?column ([0-9]+).*', '$1', 'r')}"
+ + "</#attempt>",
+ "13", "8");
+ testedProps.add(Configuration.ExtendableBuilder.TAB_SIZE_KEY_CAMEL_CASE);
+ }
+
+ {
+ // As the TemplateLanguage-based parser selection happens in the TemplateResolver, we can't use
+ // assertOutput here, as that hard-coded to create an FTL Template.
+
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setTemplateLanguage(TemplateLanguage.STATIC_TEXT);
+
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
+ cfgB.setTemplateConfigurations(
+ new ConditionalTemplateConfigurationFactory(new FileExtensionMatcher("txt"), tcb.build()));
+
+ StringTemplateLoader templateLoader = new StringTemplateLoader();
+ templateLoader.putTemplate("adhoc.ftl", "${1+1}");
+ templateLoader.putTemplate("adhoc.txt", "${1+1}");
+ cfgB.setTemplateLoader(templateLoader);
+
+ Configuration cfg = cfgB.build();
+
+ {
+ StringWriter out = new StringWriter();
+ cfg.getTemplate("adhoc.ftl").process(null, out);
+ assertEquals("2", out.toString());
+ }
+ {
+ StringWriter out = new StringWriter();
+ cfg.getTemplate("adhoc.txt").process(null, out);
+ assertEquals("${1+1}", out.toString());
+ }
+
+ testedProps.add(Configuration.ExtendableBuilder.TEMPLATE_LANGUAGE_KEY_CAMEL_CASE);
+ }
+
+ {
+ // As the TemplateLanguage-based parser selection happens in the TemplateResolver, we can't use
+ // assertOutput here, as that hard-coded to create an FTL Template.
+
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setSourceEncoding(StandardCharsets.ISO_8859_1);
+
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
+ cfgB.setSourceEncoding(StandardCharsets.UTF_8);
+ cfgB.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("latin1.ftl"), tcb.build()));
+
+ MonitoredTemplateLoader templateLoader = new MonitoredTemplateLoader();
+ templateLoader.putBinaryTemplate("utf8.ftl", "próba", StandardCharsets.UTF_8, 1);
+ templateLoader.putBinaryTemplate("latin1.ftl", "próba", StandardCharsets.ISO_8859_1, 1);
+ cfgB.setTemplateLoader(templateLoader);
+
+ Configuration cfg = cfgB.build();
+
+ {
+ StringWriter out = new StringWriter();
+ cfg.getTemplate("utf8.ftl").process(null, out);
+ assertEquals("próba", out.toString());
+ }
+ {
+ StringWriter out = new StringWriter();
+ cfg.getTemplate("latin1.ftl").process(null, out);
+ assertEquals("próba", out.toString());
+ }
+
+ testedProps.add(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY_CAMEL_CASE);
+ }
+
+ if (!PARSER_PROP_NAMES.equals(testedProps)) {
+ Set<String> diff = new HashSet<>(PARSER_PROP_NAMES);
+ diff.removeAll(testedProps);
+ fail("Some settings weren't checked: " + diff);
+ }
+ }
+
+ @Test
+ public void testArithmeticEngine() throws TemplateException, IOException {
+ TemplateConfiguration tc = new TemplateConfiguration.Builder()
+ .arithmeticEngine(new DummyArithmeticEngine())
+ .build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#setting locale='en_US'>${1} ${1+1} ${1*3} <#assign x = 1>${x + x} ${x * 3}",
+ "1 2 3 2 3", "11 22 33 22 33");
+
+ // Does affect template.arithmeticEngine (unlike in FM2)
+ Template t = new Template(null, null, new StringReader(""), DEFAULT_CFG, tc, null);
+ assertEquals(tc.getArithmeticEngine(), t.getArithmeticEngine());
+ }
+
+ @Test
+ public void testAutoImport() throws TemplateException, IOException {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setAutoImports(ImmutableMap.of("t1", "t1.ftl", "t2", "t2.ftl"));
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "<#import 't3.ftl' as t3>${loaded}", "t3;", "t1;t2;t3;");
+ }
+
+ @Test
+ public void testAutoIncludes() throws TemplateException, IOException {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setAutoIncludes(ImmutableList.of("t1.ftl", "t2.ftl"));
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc, "<#include 't3.ftl'>", "In t3;", "In t1;In t2;In t3;");
+ }
+
+ @Test
+ public void testStringInterpolate() throws TemplateException, IOException {
+ TemplateConfiguration tc = new TemplateConfiguration.Builder()
+ .arithmeticEngine(new DummyArithmeticEngine())
+ .build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#setting locale='en_US'>${'${1} ${1+1} ${1*3}'} <#assign x = 1>${'${x + x} ${x * 3}'}",
+ "1 2 3 2 3", "11 22 33 22 33");
+
+ // Does affect template.arithmeticEngine (unlike in FM2):
+ Template t = new Template(null, null, new StringReader(""), DEFAULT_CFG, tc, null);
+ assertEquals(tc.getArithmeticEngine(), t.getArithmeticEngine());
+ }
+
+ @Test
+ public void testInterpret() throws TemplateException, IOException {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setArithmeticEngine(new DummyArithmeticEngine());
+ {
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#setting locale='en_US'><#assign src = r'${1} <#assign x = 1>${x + x}'><@src?interpret />",
+ "1 2", "11 22");
+ }
+ tcb.setWhitespaceStripping(false);
+ {
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#if true>\nX</#if><#assign src = r'<#if true>\nY</#if>'><@src?interpret />",
+ "XY", "\nX\nY");
+ }
+ }
+
+ @Test
+ public void testEval() throws TemplateException, IOException {
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ tcb.setArithmeticEngine(new DummyArithmeticEngine());
+ TemplateConfiguration tc = tcb.build();
+ assertOutputWithoutAndWithTC(tc,
+ "<#assign x = 1>${r'1 + x'?eval?c}",
+ "2", "22");
+ assertOutputWithoutAndWithTC(tc,
+ "${r'1?c'?eval}",
+ "1", "11");
+ }
+
+ {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ Charset outputEncoding = ISO_8859_2;
+ tcb.setOutputEncoding(outputEncoding);
+
+ String legacyNCFtl = "${r'.output_encoding!\"null\"'?eval}";
+ String camelCaseNCFtl = "${r'.outputEncoding!\"null\"'?eval}";
+
+ {
+ TemplateConfiguration tc = tcb.build();
+
+ // Default is re-auto-detecting in ?eval:
+ assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", outputEncoding.name());
+ assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", outputEncoding.name());
+ }
+
+ {
+ // Force camelCase:
+ tcb.setNamingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+
+ TemplateConfiguration tc = tcb.build();
+
+ assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", null);
+ assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", outputEncoding.name());
+ }
+
+ {
+ // Force legacy:
+ tcb.setNamingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+
+ TemplateConfiguration tc = tcb.build();
+
+ assertOutputWithoutAndWithTC(tc, legacyNCFtl, "null", outputEncoding.name());
+ assertOutputWithoutAndWithTC(tc, camelCaseNCFtl, "null", null);
+ }
+ }
+ }
+
+ private void assertOutputWithoutAndWithTC(
+ TemplateConfiguration tc, String ftl, String expectedDefaultOutput,
+ String expectedConfiguredOutput) throws TemplateException, IOException {
+ assertOutputWithoutAndWithTC(tc, null, ftl, expectedDefaultOutput, expectedConfiguredOutput);
+ }
+
+ private void assertOutputWithoutAndWithTC(
+ TemplateConfiguration tc, String templateName, String ftl, String expectedDefaultOutput,
+ String expectedConfiguredOutput) throws TemplateException, IOException {
+ if (templateName == null) {
+ templateName = "adhoc.ftl";
+ }
+ assertOutput(null, templateName, ftl, expectedDefaultOutput);
+ assertOutput(tc, templateName, ftl, expectedConfiguredOutput);
+ }
+
+ private void assertOutput(TemplateConfiguration tc, String templateName, String ftl, String
+ expectedConfiguredOutput)
+ throws TemplateException, IOException {
+ StringWriter sw = new StringWriter();
+ try {
+ Template t = new Template(templateName, null, new StringReader(ftl), DEFAULT_CFG, tc, null);
+ t.process(null, sw);
+ if (expectedConfiguredOutput == null) {
+ fail("Template should have fail.");
+ }
+ } catch (TemplateException|ParseException e) {
+ if (expectedConfiguredOutput != null) {
+ throw e;
+ }
+ }
+ if (expectedConfiguredOutput != null) {
+ assertEquals(expectedConfiguredOutput, sw.toString());
+ }
+ }
+
+ @Test
+ public void testIsSet() throws Exception {
+ for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
+ TemplateConfiguration.Builder.class, true)) {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ checkAllIsSetFalseExcept(tcb.build(), null);
+ pd.getWriteMethod().invoke(tcb, SETTING_ASSIGNMENTS.get(pd.getName()));
+ checkAllIsSetFalseExcept(tcb.build(), pd.getName());
+ }
+ }
+
+ private void checkAllIsSetFalseExcept(TemplateConfiguration tc, String setSetting)
+ throws SecurityException, IntrospectionException,
+ IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(TemplateConfiguration.class, true)) {
+ String isSetMethodName = getIsSetMethodName(pd.getReadMethod().getName());
+ Method isSetMethod;
+ try {
+ isSetMethod = tc.getClass().getMethod(isSetMethodName);
+ } catch (NoSuchMethodException e) {
+ fail("Missing " + isSetMethodName + " method for \"" + pd.getName() + "\".");
+ return;
+ }
+ if (pd.getName().equals(setSetting)) {
+ assertTrue(isSetMethod + " should return true", (Boolean) (isSetMethod.invoke(tc)));
+ } else {
+ assertFalse(isSetMethod + " should return false", (Boolean) (isSetMethod.invoke(tc)));
+ }
+ }
+ }
+
+ /**
+ * Test case self-check.
+ */
+ @Test
+ public void checkTestAssignments() throws Exception {
+ for (PropertyDescriptor pd : getTemplateConfigurationSettingPropDescs(
+ TemplateConfiguration.Builder.class, true)) {
+ String propName = pd.getName();
+ if (!SETTING_ASSIGNMENTS.containsKey(propName)) {
+ fail("Test case doesn't cover all settings in SETTING_ASSIGNMENTS. Missing: " + propName);
+ }
+ Method readMethod = pd.getReadMethod();
+ String cfgMethodName = readMethod.getName();
+ Method cfgMethod = DEFAULT_CFG.getClass().getMethod(cfgMethodName, readMethod.getParameterTypes());
+ Object defaultSettingValue = cfgMethod.invoke(DEFAULT_CFG);
+ Object assignedValue = SETTING_ASSIGNMENTS.get(propName);
+ assertNotEquals("SETTING_ASSIGNMENTS must contain a non-default value for " + propName,
+ assignedValue, defaultSettingValue);
+
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ try {
+ pd.getWriteMethod().invoke(tcb, assignedValue);
+ } catch (Exception e) {
+ throw new IllegalStateException("For setting \"" + propName + "\" and assigned value of type "
+ + (assignedValue != null ? assignedValue.getClass().getName() : "Null"),
+ e);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
new file mode 100644
index 0000000..4cd50eb
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConfigurationWithDefaultTemplateResolverTest.java
@@ -0,0 +1,267 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+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.impl.ByteArrayTemplateLoader;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class TemplateConfigurationWithDefaultTemplateResolverTest {
+
+ private static final String TEXT_WITH_ACCENTS = "pr\u00F3ba";
+
+ private static final Object CUST_ATT_1 = new Object();
+ private static final Object CUST_ATT_2 = new Object();
+
+ private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
+
+ @Test
+ public void testEncoding() throws Exception {
+ Configuration cfg = createCommonEncodingTesterConfig();
+
+ {
+ Template t = cfg.getTemplate("utf8.ftl");
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("utf16.ftl");
+ assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
+ assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("default.ftl");
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("utf8-latin2.ftl");
+ assertEquals(ISO_8859_2, t.getActualSourceEncoding());
+ assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("default-latin2.ftl");
+ assertEquals(ISO_8859_2, t.getActualSourceEncoding());
+ assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
+ }
+ }
+
+ @Test
+ public void testIncludeAndEncoding() throws Exception {
+ Configuration cfg = createCommonEncodingTesterConfig();
+ ByteArrayTemplateLoader tl = (ByteArrayTemplateLoader) cfg.getTemplateLoader();
+ tl.putTemplate("main.ftl", (
+ "<#include 'utf8.ftl'>"
+ + "<#include 'utf16.ftl'>"
+ + "<#include 'default.ftl'>"
+ + "<#include 'utf8-latin2.ftl'>"
+ ).getBytes(StandardCharsets.ISO_8859_1));
+ assertEquals(
+ TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS,
+ getTemplateOutput(cfg.getTemplate("main.ftl")));
+ }
+
+ @Test
+ public void testLocale() throws Exception {
+ StringTemplateLoader loader = new StringTemplateLoader();
+ loader.putTemplate("(de).ftl", "${.locale}");
+ loader.putTemplate("default.ftl", "${.locale}");
+ loader.putTemplate("(de)-fr.ftl",
+ ("<#ftl locale='fr_FR'>${.locale}"));
+ loader.putTemplate("default-fr.ftl",
+ ("<#ftl locale='fr_FR'>${.locale}"));
+
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateLoader(loader)
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(de)*"),
+ new TemplateConfiguration.Builder()
+ .locale(Locale.GERMANY)
+ .build()))
+ .build();
+
+ {
+ Template t = cfg.getTemplate("(de).ftl");
+ assertEquals(Locale.GERMANY, t.getLocale());
+ assertEquals("de_DE", getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("(de).ftl", Locale.ITALY);
+ assertEquals(Locale.GERMANY, t.getLocale());
+ assertEquals("de_DE", getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("default.ftl");
+ assertEquals(Locale.US, t.getLocale());
+ assertEquals("en_US", getTemplateOutput(t));
+ }
+ {
+ Template t = cfg.getTemplate("default.ftl", Locale.ITALY);
+ assertEquals(Locale.ITALY, t.getLocale());
+ assertEquals("it_IT", getTemplateOutput(t));
+ }
+ }
+
+ @Test
+ public void testConfigurableSettings() throws Exception {
+ String commonFTL = "${.locale} ${true?string} ${1.2}";
+ StringTemplateLoader loader = new StringTemplateLoader();
+ loader.putTemplate("default", commonFTL);
+ loader.putTemplate("(fr)", commonFTL);
+ loader.putTemplate("(yn)(00)", commonFTL);
+ loader.putTemplate("(00)(fr)", commonFTL);
+
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateConfigurations(
+ new MergingTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(fr)*"),
+ new TemplateConfiguration.Builder().locale(Locale.FRANCE).build()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(yn)*"),
+ new TemplateConfiguration.Builder().booleanFormat("Y,N").build()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(00)*"),
+ new TemplateConfiguration.Builder().numberFormat("0.00").build())))
+ .templateLoader(loader)
+ .build();
+
+ assertEquals("en_US true 1.2", getTemplateOutput(cfg.getTemplate("default")));
+ assertEquals("fr_FR true 1,2", getTemplateOutput(cfg.getTemplate("(fr)")));
+ assertEquals("en_US Y 1.20", getTemplateOutput(cfg.getTemplate("(yn)(00)")));
+ assertEquals("fr_FR true 1,20", getTemplateOutput(cfg.getTemplate("(00)(fr)")));
+ }
+
+ @Test
+ public void testCustomAttributes() throws Exception {
+ String commonFTL = "<#ftl attributes={ 'a3': 'a3temp' }>";
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("(tc1)", commonFTL);
+ tl.putTemplate("(tc1)noHeader", "");
+ tl.putTemplate("(tc2)", commonFTL);
+ tl.putTemplate("(tc1)(tc2)", commonFTL);
+
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateConfigurations(
+ new MergingTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(tc1)*"),
+ new TemplateConfiguration.Builder()
+ .customAttribute("a1", "a1tc1")
+ .customAttribute("a2", "a2tc1")
+ .customAttribute("a3", "a3tc1")
+ .customAttribute(CUST_ATT_1, "ca1tc1")
+ .customAttribute(CUST_ATT_2, "ca2tc1")
+ .build()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*(tc2)*"),
+ new TemplateConfiguration.Builder()
+ .customAttribute("a1", "a1tc2")
+ .customAttribute(CUST_ATT_1, "ca1tc2")
+ .build())))
+ .templateLoader(tl)
+ .build();
+
+ {
+ Template t = cfg.getTemplate("(tc1)");
+ assertEquals("a1tc1", t.getCustomAttribute("a1"));
+ assertEquals("a2tc1", t.getCustomAttribute("a2"));
+ assertEquals("a3temp", t.getCustomAttribute("a3"));
+ assertEquals("ca1tc1", t.getCustomAttribute(CUST_ATT_1));
+ assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
+ }
+ {
+ Template t = cfg.getTemplate("(tc1)noHeader");
+ assertEquals("a1tc1", t.getCustomAttribute("a1"));
+ assertEquals("a2tc1", t.getCustomAttribute("a2"));
+ assertEquals("a3tc1", t.getCustomAttribute("a3"));
+ assertEquals("ca1tc1", t.getCustomAttribute(CUST_ATT_1));
+ assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
+ }
+ {
+ Template t = cfg.getTemplate("(tc2)");
+ assertEquals("a1tc2", t.getCustomAttribute("a1"));
+ assertNull(t.getCustomAttribute("a2"));
+ assertEquals("a3temp", t.getCustomAttribute("a3"));
+ assertEquals("ca1tc2", t.getCustomAttribute(CUST_ATT_1));
+ assertNull(t.getCustomAttribute(CUST_ATT_2));
+ }
+ {
+ Template t = cfg.getTemplate("(tc1)(tc2)");
+ assertEquals("a1tc2", t.getCustomAttribute("a1"));
+ assertEquals("a2tc1", t.getCustomAttribute("a2"));
+ assertEquals("a3temp", t.getCustomAttribute("a3"));
+ assertEquals("ca1tc2", t.getCustomAttribute(CUST_ATT_1));
+ assertEquals("ca2tc1", t.getCustomAttribute(CUST_ATT_2));
+ }
+ }
+
+ private String getTemplateOutput(Template t) throws TemplateException, IOException {
+ StringWriter sw = new StringWriter();
+ t.process(null, sw);
+ return sw.toString();
+ }
+
+ private Configuration createCommonEncodingTesterConfig() throws UnsupportedEncodingException {
+ ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
+ tl.putTemplate("utf8.ftl", TEXT_WITH_ACCENTS.getBytes(StandardCharsets.UTF_8));
+ tl.putTemplate("utf16.ftl", TEXT_WITH_ACCENTS.getBytes(StandardCharsets.UTF_16LE));
+ tl.putTemplate("default.ftl", TEXT_WITH_ACCENTS.getBytes(ISO_8859_2));
+ tl.putTemplate("utf8-latin2.ftl",
+ ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes(ISO_8859_2));
+ tl.putTemplate("default-latin2.ftl",
+ ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes(ISO_8859_2));
+
+ return new TestConfigurationBuilder()
+ .sourceEncoding(StandardCharsets.ISO_8859_1)
+ .locale(Locale.US)
+ .templateLoader(tl)
+ .templateConfigurations(
+ new FirstMatchTemplateConfigurationFactory(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*utf8*"),
+ new TemplateConfiguration.Builder()
+ .sourceEncoding(StandardCharsets.UTF_8)
+ .build()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*utf16*"),
+ new TemplateConfiguration.Builder()
+ .sourceEncoding(StandardCharsets.UTF_16LE)
+ .build())
+ )
+ .allowNoMatch(true))
+ .build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
new file mode 100644
index 0000000..97c43ad
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+public class TemplateConstructorsTest {
+
+ private static final String CONTENT = "From a reader...";
+ private static final String CONTENT_FORCE_UTF8 = "<#ftl encoding='utf-8'>From a reader...";
+
+ @Test
+ public void test() throws IOException {
+ final Configuration cfg = new TestConfigurationBuilder().sourceEncoding(StandardCharsets.ISO_8859_1).build();
+
+ final String name = "foo/bar.ftl";
+ final String sourceName = "foo/bar_de.ftl";
+ final Charset sourceEncoding = StandardCharsets.UTF_16LE;
+ {
+ Template t = new Template(name, createReader(), cfg);
+ assertEquals(name, t.getLookupName());
+ assertNull(t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertNull(t.getActualSourceEncoding());
+ }
+ {
+ Template t = new Template(name, CONTENT, cfg);
+ assertEquals(name, t.getLookupName());
+ assertNull(t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertNull(t.getActualSourceEncoding());
+ }
+ {
+ Template t = new Template(name, CONTENT_FORCE_UTF8, cfg);
+ assertEquals(name, t.getLookupName());
+ assertNull(t.getSourceName());
+ // assertEquals(CONTENT_FORCE_UTF8, t.toString()); // FIXME the #ftl header is missing from the dump, why?
+ assertNull(t.getActualSourceEncoding()); // Because it was created from a String
+ }
+ {
+ Template t = new Template(name, createReader(), cfg, sourceEncoding);
+ assertEquals(name, t.getLookupName());
+ assertNull(t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
+ }
+ {
+ Template t = new Template(name, sourceName, createReader(), cfg);
+ assertEquals(name, t.getLookupName());
+ assertEquals(sourceName, t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertNull(t.getActualSourceEncoding());
+ }
+ {
+ Template t = new Template(name, sourceName, createReader(), cfg, sourceEncoding);
+ assertEquals(name, t.getLookupName());
+ assertEquals(sourceName, t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertEquals(StandardCharsets.UTF_16LE, t.getActualSourceEncoding());
+ }
+ {
+ Template t = Template.createPlainTextTemplate(name, CONTENT, cfg);
+ assertEquals(name, t.getLookupName());
+ assertNull(t.getSourceName());
+ assertEquals(CONTENT, t.toString());
+ assertNull(t.getActualSourceEncoding());
+ }
+ {
+ try {
+ new Template(name, sourceName, createReaderForceUTF8(), cfg, sourceEncoding);
+ fail();
+ } catch (WrongTemplateCharsetException e) {
+ assertThat(e.getMessage(), containsString(StandardCharsets.UTF_8.name()));
+ assertThat(e.getMessage(), containsString(sourceEncoding.name()));
+ }
+ }
+ }
+
+ private Reader createReader() {
+ return new StringReader(CONTENT);
+ }
+
+ private Reader createReaderForceUTF8() {
+ return new StringReader(CONTENT_FORCE_UTF8);
+ }
+
+}
[33/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
new file mode 100644
index 0000000..70ea42a
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/HashAndScalarModel.java
@@ -0,0 +1,84 @@
+/*
+ * 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.TemplateCollectionModel;
+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.TemplateScalarModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+public class HashAndScalarModel implements TemplateHashModelEx, TemplateScalarModel {
+
+ public static final HashAndScalarModel INSTANCE = new HashAndScalarModel();
+
+ private final TemplateCollectionModel EMPTY_COLLECTION = new TemplateCollectionModel() {
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ return null;
+ }
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return false;
+ }
+
+ };
+ }
+ };
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return "scalarValue";
+ }
+
+ @Override
+ public TemplateModel get(String key) throws TemplateModelException {
+ return new SimpleScalar("mapValue for " + key);
+ }
+
+ @Override
+ public boolean isEmpty() throws TemplateModelException {
+ return true;
+ }
+
+ @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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
new file mode 100644
index 0000000..4673b09
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/JavaObjectInfo.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util._StringUtil;
+
+public class JavaObjectInfo {
+
+ public static final Object INSTANCE = new JavaObjectInfo();
+
+ private JavaObjectInfo() { }
+
+ public String info(Object o) {
+ if (o == null) return "null";
+ return o.getClass().getName() + " " + _StringUtil.jQuote(o.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
new file mode 100644
index 0000000..c2d7c90
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/Listables.java
@@ -0,0 +1,185 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx;
+import org.apache.freemarker.core.model.TemplateHashModelEx2;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.WrappingTemplateModel;
+import org.apache.freemarker.core.model.impl.DefaultMapAdapter;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleCollection;
+import org.apache.freemarker.core.model.impl.SimpleHash;
+
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class Listables {
+
+ private static final List<Integer> LIST;
+ static {
+ List<Integer> list = new ArrayList<>();
+ list.add(11);
+ list.add(22);
+ list.add(33);
+ LIST = list;
+ }
+
+ private static final List<Integer> LINKED_LIST;
+ static {
+ List<Integer> list = new LinkedList<>();
+ list.add(11);
+ list.add(22);
+ list.add(33);
+ LINKED_LIST = list;
+ }
+
+ private static final List<Integer> EMPTY_LINKED_LIST = new LinkedList<>();
+
+ private static final Set<Integer> SET;
+ static {
+ Set<Integer> set = new TreeSet<>();
+ set.add(11);
+ set.add(22);
+ set.add(33);
+ SET = set;
+ }
+
+ public List<Integer> getList() {
+ return LIST;
+ }
+
+ public List<Integer> getLinkedList() {
+ return LINKED_LIST;
+ }
+
+ public Set<Integer> getSet() {
+ return SET;
+ }
+
+ public Iterator<Integer> getIterator() {
+ return SET.iterator();
+ }
+
+ public List<Integer> getEmptyList() {
+ return Collections.emptyList();
+ }
+
+ public List<Integer> getEmptyLinkedList() {
+ return Collections.emptyList();
+ }
+
+ public Set<Integer> getEmptySet() {
+ return Collections.emptySet();
+ }
+
+ public Iterator<Integer> getEmptyIterator() {
+ return Collections.<Integer>emptySet().iterator();
+ }
+
+ public List<TemplateHashModelEx2> getHashEx2s() throws TemplateModelException {
+ Map<Object, Object> map;
+ map = new LinkedHashMap<>();
+ map.put("k1", "v1");
+ map.put(2, "v2");
+ map.put("k3", "v3");
+ map.put(null, "v4");
+ map.put(true, "v5");
+ map.put(false, null);
+
+ return getMapsWrappedAsEx2(map);
+ }
+
+ public List<? extends TemplateHashModelEx> getEmptyHashes() throws TemplateModelException {
+ List<TemplateHashModelEx> emptyMaps = new ArrayList<>();
+ emptyMaps.addAll(getMapsWrappedAsEx2(Collections.emptyMap()));
+ emptyMaps.add((TemplateHashModelEx) new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build()
+ .wrap(Collections.emptyMap()));
+ return emptyMaps;
+ }
+
+ /**
+ * Returns the map wrapped on various ways.
+ */
+ private List<TemplateHashModelEx2> getMapsWrappedAsEx2(Map<?, ?> map) throws TemplateModelException {
+ List<TemplateHashModelEx2> maps = new ArrayList<>();
+
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ maps.add(new SimpleHash(map, ow));
+ maps.add((DefaultMapAdapter) ow.wrap(map));
+
+ return maps;
+ }
+
+ public TemplateHashModelEx getHashNonEx2() {
+ return new NonEx2MapAdapter(ImmutableMap.of("k1", 11, "k2", 22),
+ new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
+ }
+
+ public static class NonEx2MapAdapter extends WrappingTemplateModel implements TemplateHashModelEx {
+
+ private final Map<?, ?> map;
+
+ public NonEx2MapAdapter(Map<?, ?> map, ObjectWrapper wrapper) {
+ super(wrapper);
+ this.map = map;
+ }
+
+ @Override
+ public TemplateModel get(String key) throws TemplateModelException {
+ return wrap(map.get(key));
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public TemplateCollectionModel keys() {
+ return new SimpleCollection(map.keySet(), getObjectWrapper());
+ }
+
+ @Override
+ public TemplateCollectionModel values() {
+ return new SimpleCollection(map.values(), getObjectWrapper());
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
new file mode 100644
index 0000000..66a0ffe
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel1.java
@@ -0,0 +1,116 @@
+/*
+ * 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.Configuration;
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleHash;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Testcase to see how FreeMarker deals with multiple Template models.
+ */
+public class MultiModel1 implements TemplateHashModel,
+ TemplateSequenceModel, TemplateScalarModel {
+
+ private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ private TemplateModel m_cSubModel = new MultiModel2();
+ private TemplateModel m_cListHashModel1 = new MultiModel4(ow);
+ private TemplateModel m_cListHashModel2 = new MultiModel5(ow);
+ private TemplateSequenceModel m_cListModel = new SimpleSequence(ow);
+ private TemplateHashModel m_cHashModel = new SimpleHash(ow);
+
+ /** Creates new MultiModel1 */
+ public MultiModel1() {
+ for ( int i = 0; i < 10; i++ ) {
+ ((SimpleSequence) m_cListModel).add( "Model1 value: " + Integer.toString( i ));
+ }
+ ((SimpleSequence) m_cListModel).add( new MultiModel3() );
+ ((SimpleHash) m_cHashModel).put( "nested", new MultiModel3() );
+ }
+
+ /**
+ * 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( "model2" )) {
+ return m_cSubModel;
+ } else if ( key.equals( "modellist" )) {
+ return m_cListModel;
+ } else if ( key.equals( "selftest" )) {
+ return new SimpleScalar( "Selftest of a hash from MultiModel1" );
+ } else if ( key.equals( "one" )) {
+ return m_cListHashModel1;
+ } else if ( key.equals( "two" )) {
+ return m_cListHashModel2;
+ } else if ( key.equals( "size" )) {
+ return new SimpleScalar( "Nasty!" );
+ } else if ( key.equals( "nesting1" )) {
+ return m_cHashModel;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * @return the specified index in the list
+ */
+ @Override
+ public TemplateModel get(int i) throws TemplateModelException {
+ return m_cListModel.get( i );
+ }
+
+ /**
+ * Returns the scalar's value as a String.
+ *
+ * @return the String value of this scalar.
+ */
+ @Override
+ public String getAsString() {
+ return "MultiModel1 as a string!";
+ }
+
+ @Override
+ public int size() throws TemplateModelException {
+ return m_cListModel.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/MultiModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java
new file mode 100644
index 0000000..a7a75b5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel2.java
@@ -0,0 +1,63 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * Testcase to see how FreeMarker deals with multiple Template models.
+ */
+public class MultiModel2 implements TemplateScalarModel, TemplateMethodModel {
+
+ /**
+ * Returns the scalar's value as a String.
+ *
+ * @return the String value of this scalar.
+ */
+ @Override
+ public String getAsString() {
+ return "Model2 is alive!";
+ }
+
+ /**
+ * Executes a method call.
+ *
+ * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing the values
+ * of the arguments passed to the method.
+ * @return the <tt>TemplateModel</tt> produced by the method, or null.
+ */
+ @Override
+ public Object exec(List arguments) {
+ StringBuilder aResults = new StringBuilder( "Arguments are:<br />" );
+ Iterator iList = arguments.iterator();
+
+ while ( iList.hasNext() ) {
+ aResults.append( (String) iList.next() );
+ aResults.append( "<br />" );
+ }
+
+ return new SimpleScalar( aResults.toString() );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
new file mode 100644
index 0000000..4434afc
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel3.java
@@ -0,0 +1,69 @@
+/*
+ * 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;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * Testcase to see how FreeMarker deals with multiple Template models.
+ */
+public class MultiModel3 implements TemplateScalarModel, TemplateHashModel {
+
+ /**
+ * Returns the scalar's value as a String.
+ *
+ * @return the String value of this scalar.
+ */
+ @Override
+ public String getAsString() {
+ return "Model3 is alive!";
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * 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( "selftest" )) {
+ return new SimpleScalar( "Selftest from MultiModel3!" );
+ } else if ( key.equals( "message" )) {
+ return new SimpleScalar( "Hello world from MultiModel3!" );
+ } else {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
new file mode 100644
index 0000000..bdd11fc
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel4.java
@@ -0,0 +1,77 @@
+/*
+ * 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.TemplateHashModel;
+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.SimpleScalar;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Testcase to see how FreeMarker deals with multiple Template models.
+ */
+public class MultiModel4 implements TemplateSequenceModel, TemplateHashModel {
+
+ private final SimpleSequence m_cList;
+
+ public MultiModel4(ObjectWrapper ow) {
+ this.m_cList = new SimpleSequence(ow);
+ }
+
+ /**
+ * @return the specified index in the list
+ */
+ @Override
+ public TemplateModel get(int i) throws TemplateModelException {
+ return m_cList.get( i );
+ }
+
+ /**
+ * 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( "size" )) {
+ return new SimpleScalar( "Key size, not the listSize method." );
+ } else {
+ return null;
+ }
+ }
+
+
+ @Override
+ public int size() {
+ return m_cList.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
new file mode 100644
index 0000000..01f7a3e
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/MultiModel5.java
@@ -0,0 +1,81 @@
+/*
+ * 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.TemplateHashModel;
+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.SimpleScalar;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Testcase to see how FreeMarker deals with multiple Template models.
+ */
+public class MultiModel5 implements TemplateSequenceModel, TemplateHashModel {
+
+ private final SimpleSequence m_cList;
+
+ /** Creates new MultiModel5 */
+ public MultiModel5(ObjectWrapper ow) {
+ this.m_cList = new SimpleSequence(ow);
+ m_cList.add( new SimpleScalar( "Dummy to make list non-empty" ));
+ }
+
+ /**
+ * @return the specified index in the list
+ */
+ @Override
+ public TemplateModel get(int i) throws TemplateModelException {
+ return m_cList.get( i );
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public int size() {
+ return m_cList.size();
+ }
+
+ /**
+ * 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( "empty" )) {
+ return new SimpleScalar( "Dummy hash value, for test purposes." );
+ } else {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
new file mode 100644
index 0000000..9f51458
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel.java
@@ -0,0 +1,52 @@
+/*
+ * 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.TemplateScalarModel;
+
+/**
+ * Testcase to see how FreeMarker's ?new built-in deals with constructors.
+ */
+public class NewTestModel
+implements
+ TemplateScalarModel {
+ private final String string;
+
+ public NewTestModel() {
+ string = "default constructor";
+ }
+
+ public NewTestModel(String str) {
+ string = str;
+ }
+
+ public NewTestModel(long i) {
+ string = Long.toString(i);
+ }
+
+ public NewTestModel(Object o1, java.io.Serializable o2) {
+ string = o1 + ":" + o2;
+ }
+
+ @Override
+ public String getAsString() {
+ return string;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
new file mode 100644
index 0000000..420b4fa
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NewTestModel2.java
@@ -0,0 +1,52 @@
+/*
+ * 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.TemplateScalarModel;
+
+/**
+ * Testcase to see how FreeMarker's ?new built-in deals with constructors.
+ */
+public class NewTestModel2
+implements
+ TemplateScalarModel {
+ private final String string;
+
+ public NewTestModel2() {
+ string = "default constructor";
+ }
+
+ public NewTestModel2(String str) {
+ string = str;
+ }
+
+ public NewTestModel2(long i) {
+ string = Long.toString(i);
+ }
+
+ public NewTestModel2(Object o1, java.io.Serializable o2) {
+ string = o1 + ":" + o2;
+ }
+
+ @Override
+ public String getAsString() {
+ return string;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
new file mode 100644
index 0000000..5c8e7db
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/NumberAndStringModel.java
@@ -0,0 +1,47 @@
+/*
+ * 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.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+
+public class NumberAndStringModel implements TemplateNumberModel,
+ TemplateScalarModel {
+
+ private final String s;
+
+ public NumberAndStringModel(String s) {
+ super();
+ this.s = s;
+ }
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return s;
+ }
+
+ @Override
+ @SuppressWarnings("boxing")
+ public Number getAsNumber() throws TemplateModelException {
+ return s.length();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
new file mode 100644
index 0000000..6e09053
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedConstructor.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+public class OverloadedConstructor implements TemplateScalarModel {
+
+ String value;
+
+ public OverloadedConstructor(int i) {
+ value = "int " + i;
+ }
+
+ public OverloadedConstructor(String s) {
+ value = "String " + s;
+ }
+
+ public OverloadedConstructor(CharSequence s) {
+ value = "CharSequence " + s;
+ }
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ return value;
+ }
+
+}
\ 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/test/templatesuite/models/OverloadedMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.java
new file mode 100644
index 0000000..ebd505a
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods.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.test.templatesuite.models;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.freemarker.core.util.FTLUtil;
+
+/**
+ * For testing overloaded method selection.
+ */
+public class OverloadedMethods {
+
+ public String oneArg(Object a1) {
+ return methodCallToStr("oneArg<Object>", a1);
+ }
+
+ public String oneArg(String a1) {
+ return methodCallToStr("oneArg<String>", a1);
+ }
+
+ public String oneArg(Boolean a1) {
+ return methodCallToStr("oneArg<Boolean>", a1);
+ }
+
+ public String oneArg(boolean a1) {
+ return methodCallToStr("oneArg<boolean>", Boolean.valueOf(a1));
+ }
+
+ public String oneArg(List a1) {
+ return methodCallToStr("oneArg<List>", a1);
+ }
+
+ public String oneArg(Map a1) {
+ return methodCallToStr("oneArg<Map>", a1);
+ }
+
+ public String oneArg2(Map a1) {
+ return methodCallToStr("oneArg2<Map>", a1);
+ }
+
+ public String oneArg2(List a1) {
+ return methodCallToStr("oneArg2<List>", a1);
+ }
+
+ public String oneArg3(List a1, List a2) {
+ return methodCallToStr("oneArg3<List, List>", a1, a2);
+ }
+
+ public String oneArg3(List a1) {
+ return methodCallToStr("oneArg3<List>", a1);
+ }
+
+ public String oneArg4(Integer a1) {
+ return methodCallToStr("oneArg4<Integer>", a1);
+ }
+
+ public String oneArg4(int a1) {
+ return methodCallToStr("oneArg4<int>", Integer.valueOf(a1));
+ }
+
+ public String notOverloaded(List a1) {
+ return methodCallToStr("notOverloaded<List>", a1);
+ }
+
+ public String varargsIssue1(Map a1, List a2) {
+ return methodCallToStr("varargsIssue1<Map, List>", a1, a2);
+ }
+
+ public String varargsIssue1(Object... a1) {
+ return methodCallToStr("varargsIssue1<Object...>", a1);
+ }
+
+ public String varargsIssue2(String a1, List a2) {
+ return methodCallToStr("varargsIssue2<String, List>", a1, a2);
+ }
+
+ public String varargsIssue2(String a1, Map a2) {
+ return methodCallToStr("varargsIssue2<String, Map>", a1, a2);
+ }
+
+ public String varargsIssue2(Object... a1) {
+ return methodCallToStr("varargsIssue2<Object...>", a1);
+ }
+
+ public String numberIssue1(int a1) {
+ return methodCallToStr("numberIssue1<int>", a1);
+ }
+
+ public String numberIssue1(float a1) {
+ return methodCallToStr("numberIssue1<float>", a1);
+ }
+
+ public String numberIssue2(int a1) {
+ return methodCallToStr("numberIssue2<int>", a1);
+ }
+
+ public String numberIssue2(BigDecimal a1) {
+ return methodCallToStr("numberIssue2<BigDecimal>", a1);
+ }
+
+ public String numberIssue3(int a1) {
+ return methodCallToStr("numberIssue3<int>", a1);
+ }
+
+ public String numberIssue3(double a1) {
+ return methodCallToStr("numberIssue3<double>", a1);
+ }
+
+ private String methodCallToStr(String methodName, Object... args) {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(methodName);
+ sb.append('(');
+ boolean hadItems = false;
+ for (Object arg : args) {
+ if (hadItems) sb.append(", ");
+ sb.append(valueToStr(arg));
+ hadItems = true;
+ }
+ sb.append(')');
+
+ return sb.toString();
+ }
+
+ private String valueToStr(Object value) {
+ if (value == null) {
+ return "null";
+ } else if (value instanceof Character) {
+ return "'" + FTLUtil.escapeStringLiteralPart(value.toString()) + "'";
+ } else if (value instanceof String) {
+ return "\"" + FTLUtil.escapeStringLiteralPart((String) value) + "\"";
+ } else if (value instanceof Map) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ boolean hadItems = false;
+ for (Map.Entry<?, ?> ent : ((Map<?, ?>) value).entrySet()) {
+ if (hadItems) sb.append(", ");
+ sb.append(valueToStr(ent.getKey()));
+ sb.append(": ");
+ sb.append(valueToStr(ent.getValue()));
+ hadItems = true;
+ }
+ sb.append("}");
+ return sb.toString();
+ } else if (value instanceof Collection || value.getClass().isArray()) {
+ StringBuilder sb = new StringBuilder();
+
+ if (value.getClass().isArray()) {
+ value = Arrays.asList(value);
+ sb.append("array");
+ } else if (value instanceof Set) {
+ sb.append("set");
+ }
+ sb.append("[");
+ boolean hadItems = false;
+ for (Object i : (Collection) value) {
+ if (hadItems) sb.append(", ");
+ sb.append(i);
+ hadItems = true;
+ }
+ sb.append("]");
+ return sb.toString();
+ } else {
+ return value.toString();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
new file mode 100644
index 0000000..2c5a5df
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/OverloadedMethods2.java
@@ -0,0 +1,1110 @@
+/*
+ * 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.io.File;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.model.AdapterTemplateModel;
+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.TemplateNumberModel;
+import org.apache.freemarker.core.model.WrapperTemplateModel;
+import org.apache.freemarker.core.model.impl.RationalNumber;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TestUtil;
+
+public class OverloadedMethods2 {
+
+ public String mVarargs(String... a1) {
+ StringBuilder sb = new StringBuilder();
+ for (String s : a1) {
+ sb.append(s);
+ }
+ return "mVarargs(String... a1 = " + sb + ")";
+ }
+
+ public BigInteger bigInteger(BigDecimal n) {
+ return n.toBigInteger();
+ }
+
+ public RationalNumber rational(int a, int b) {
+ return new RationalNumber(a, b);
+ }
+
+ public String mVarargs(File a1, String... a2) {
+ return "mVarargs(File a1, String... a2)";
+ }
+
+ public NumberAndStringModel getNnS(String s) {
+ return new NumberAndStringModel(s);
+ }
+
+ public String mNull1(String a1) {
+ return "mNull1(String a1 = " + a1 + ")";
+ }
+
+ public String mNull1(int a1) {
+ return "mNull1(int a1 = " + a1 + ")";
+ }
+
+ public String mNull2(String a1) {
+ return "mNull2(String a1 = " + a1 + ")";
+ }
+
+ public String mNull2(Object a1) {
+ return "mNull2(Object a1 = " + a1 + ")";
+ }
+
+ public String mSpecificity(Object a1, String a2) {
+ return "mSpecificity(Object a1, String a2)";
+ }
+
+ public String mSpecificity(String a1, Object a2) {
+ return "mSpecificity(String a1, Object a2)";
+ }
+
+ public String mChar(char a1) {
+ return "mChar(char a1 = " + a1 + ")";
+ }
+
+ public String mChar(Character a1) {
+ return "mChar(Character a1 = " + a1 + ")";
+ }
+
+ public String mBoolean(boolean a1) {
+ return "mBoolean(boolean a1 = " + a1 + ")";
+ }
+
+ public String mBoolean(Boolean a1) {
+ return "mBoolean(Boolean a1 = " + a1 + ")";
+ }
+
+ public int mIntNonOverloaded(int a1) {
+ return a1;
+ }
+
+ public String mIntPrimVSBoxed(int a1) {
+ return "mIntPrimVSBoxed(int a1 = " + a1 + ")";
+ }
+
+ public String mIntPrimVSBoxed(Integer a1) {
+ return "mIntPrimVSBoxed(Integer a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimVSPrim(short a1) {
+ return "mNumPrimVSPrim(short a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimVSPrim(long a1) {
+ return "mNumPrimVSPrim(long a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedVSBoxed(Short a1) {
+ return "mNumBoxedVSBoxed(Short a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedVSBoxed(Long a1) {
+ return "mNumBoxedVSBoxed(Long a1 = " + a1 + ")";
+ }
+
+ public String mNumUnambigous(Short a1, boolean otherOverload) {
+ return "mmNumUnambigous won't be called";
+ }
+
+ public String mNumUnambigous(Integer a1) {
+ return "mNumUnambigous(Integer a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Byte a1) {
+ return "mNumBoxedAll(Byte a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Short a1) {
+ return "mNumBoxedAll(Short a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Integer a1) {
+ return "mNumBoxedAll(Integer a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Long a1) {
+ return "mNumBoxedAll(Long a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Float a1) {
+ return "mNumBoxedAll(Float a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(Double a1) {
+ return "mNumBoxedAll(Double a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(BigInteger a1) {
+ return "mNumBoxedAll(BigInteger a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll(BigDecimal a1) {
+ return "mNumBoxedAll(BigDecimal a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(byte a1) {
+ return "mNumPrimAll(byte a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(short a1) {
+ return "mNumPrimAll(short a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(int a1) {
+ return "mNumPrimAll(int a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(long a1) {
+ return "mNumPrimAll(long a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(float a1) {
+ return "mNumPrimAll(float a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(double a1) {
+ return "mNumPrimAll(double a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(BigInteger a1) {
+ return "mNumPrimAll(BigInteger a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll(BigDecimal a1) {
+ return "mNumPrimAll(BigDecimal a1 = " + a1 + ")";
+ }
+
+
+ public String mNumBoxedAll2nd(Short a1) {
+ return "mNumBoxedAll2nd(Short a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll2nd(Long a1) {
+ return "mNumBoxedAll2nd(Long a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedAll2nd(Double a1) {
+ return "mNumBoxedAll2nd(Double a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll2nd(short a1) {
+ return "mNumPrimAll2nd(short a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll2nd(long a1) {
+ return "mNumPrimAll2nd(long a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimAll2nd(double a1) {
+ return "mNumPrimAll2nd(double a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimFallbackToNumber(long a1) {
+ return "mNumPrimFallbackToNumber(long a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimFallbackToNumber(Number a1) {
+ return "mNumPrimFallbackToNumber(Number a1 = " + a1 + ")";
+ }
+
+ public String mNumPrimFallbackToNumber(Object a1) {
+ return "mNumPrimFallbackToNumber(Object a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedFallbackToNumber(Long a1) {
+ return "mNumBoxedFallbackToNumber(Long a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedFallbackToNumber(Number a1) {
+ return "mNumBoxedFallbackToNumber(Number a1 = " + a1 + ")";
+ }
+
+ public String mNumBoxedFallbackToNumber(Object a1) {
+ return "mNumBoxedFallbackToNumber(Object a1 = " + a1 + ")";
+ }
+
+ public String mDecimalLoss(int a1) {
+ return "mDecimalLoss(int a1 = " + a1 + ")";
+ }
+
+ public String mDecimalLoss(double a1) {
+ return "mDecimalLoss(double a1 = " + a1 + ")";
+ }
+
+ public String mNumConversionLoses1(byte i, Object o1, Object o2) {
+ return "byte " + i;
+ }
+
+ public String mNumConversionLoses1(double i, Object o1, Object o2) {
+ return "double " + i;
+ }
+
+ public String mNumConversionLoses1(Number i, String o1, String o2) {
+ return "Number " + i + " " + i.getClass().getName();
+ }
+
+ public String mNumConversionLoses2(int i, Object o1, Object o2) {
+ return "int " + i;
+ }
+
+ public String mNumConversionLoses2(long i, Object o1, Object o2) {
+ return "long " + i;
+ }
+
+ public String mNumConversionLoses2(Number i, String o1, String o2) {
+ return "Number " + i + " " + i.getClass().getName();
+ }
+
+ public String mNumConversionLoses3(int i, Object o1, Object o2) {
+ return "int " + i;
+ }
+
+ public String mNumConversionLoses3(Serializable i, String o1, String o2) {
+ return "Serializable " + i + " " + i.getClass().getName();
+ }
+
+ public String nIntAndLong(int i) {
+ return "nIntAndLong(int " + i + ")";
+ }
+
+ public String nIntAndLong(long i) {
+ return "nIntAndLong(long " + i + ")";
+ }
+
+ public String nIntAndShort(int i) {
+ return "nIntAndShort(int " + i + ")";
+ }
+
+ public String nIntAndShort(short i) {
+ return "nIntAndShort(short " + i + ")";
+ }
+
+ public String nLongAndShort(long i) {
+ return "nLongAndShort(long " + i + ")";
+ }
+
+ public String nLongAndShort(short i) {
+ return "nLongAndShort(short " + i + ")";
+ }
+
+ public String varargs1(String s, int... xs) {
+ return "varargs1(String s = " + _StringUtil.jQuote(s) + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs1(String s, double... xs) {
+ return "varargs1(String s = " + _StringUtil.jQuote(s) + ", double... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs1(String s, Object... xs) {
+ return "varargs1(String s = " + _StringUtil.jQuote(s) + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs1(Object s, Object... xs) {
+ return "varargs1(Object s = " + s + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs2(int... xs) {
+ return "varargs2(int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs2(double... xs) {
+ return "varargs2(double... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs3(String... xs) {
+ return "varargs3(String... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs3(Comparable... xs) {
+ return "varargs3(Comparable... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs3(Object... xs) {
+ return "varargs3(Object... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs4(Integer... xs) {
+ return "varargs4(Integer... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs4(int... xs) {
+ return "varargs4(int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs5(int... xs) {
+ return "varargs5(int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs5(int a1, int... xs) {
+ return "varargs5(int a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs5(int a1, int a2, int... xs) {
+ return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs5(int a1, int a2, int a3, int... xs) {
+ return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int a3 = " + a3
+ + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs6(String a1, int... xs) {
+ return "varargs6(String a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs6(Object a1, int a2, int... xs) {
+ return "varargs6(Object a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs7(int... xs) {
+ return "varargs7(int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String varargs7(short a1, int... xs) {
+ return "varargs7(short a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
+ }
+
+ public String mNullAmbiguous(String s) {
+ return "mNullAmbiguous(String s = " + s + ")";
+ }
+
+ public String mNullAmbiguous(int i) {
+ return "mNullAmbiguous(int i = " + i + ")";
+ }
+
+ public String mNullAmbiguous(File f) {
+ return "mNullAmbiguous(File f = " + f + ")";
+ }
+
+ public String mNullAmbiguous2(String s) {
+ return "mNullNonAmbiguous(String s = " + s + ")";
+ }
+
+ public String mNullAmbiguous2(File f) {
+ return "mNullAmbiguous(File f = " + f + ")";
+ }
+
+ public String mNullAmbiguous2(Object o) {
+ return "mNullAmbiguous(Object o = " + o + ")";
+ }
+
+ public String mNullNonAmbiguous(String s) {
+ return "mNullNonAmbiguous(String s = " + s + ")";
+ }
+
+ public String mNullNonAmbiguous(int i) {
+ return "mNullNonAmbiguous(int i = " + i + ")";
+ }
+
+ public String mVarargsIgnoredTail(int i, double... ds) {
+ return "mVarargsIgnoredTail(int i = " + i + ", double... ds = " + TestUtil.arrayToString(ds) + ")";
+ }
+
+ public String mVarargsIgnoredTail(int... is) {
+ return "mVarargsIgnoredTail(int... is = " + TestUtil.arrayToString(is) + ")";
+ }
+
+ public String mLowRankWins(int x, int y, Object o) {
+ return "mLowRankWins(int x = " + x + ", int y = " + y + ", Object o = " + o + ")";
+ }
+
+ public String mLowRankWins(Integer x, Integer y, String s) {
+ return "mLowRankWins(Integer x = " + x + ", Integer y = " + y + ", String s = " + s + ")";
+ }
+
+ public String mRareWrappings(File f, double d1, Double d2, double d3, boolean b) {
+ return "mRareWrappings(File f = " + f + ", double d1 = " + d1 + ", Double d2 = " + d2
+ + ", double d3 = " + d3 + ", b = " + b + ")";
+ }
+
+ public String mRareWrappings(Object o, double d1, Double d2, Double d3, boolean b) {
+ return "mRareWrappings(Object o = " + o + ", double d1 = " + d1 + ", Double d2 = " + d2
+ + ", double d3 = " + d3 + ", b = " + b + ")";
+ }
+
+ public String mRareWrappings(String s, double d1, Double d2, Double d3, boolean b) {
+ return "mRareWrappings(String s = " + s + ", double d1 = " + d1 + ", Double d2 = " + d2
+ + ", double d3 = " + d3 + ", b = " + b + ")";
+ }
+
+ public String mRareWrappings2(String s) {
+ return "mRareWrappings2(String s = " + s + ")";
+ }
+
+ public String mRareWrappings2(byte b) {
+ return "mRareWrappings2(byte b = " + b + ")";
+ }
+
+ public File getFile() {
+ return new File("file");
+ }
+
+ public String mSeqToArrayNonOverloaded(String[] items, String s) {
+ return "mSeqToArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
+ }
+
+ public String mSeqToArrayGoodHint(String[] items, String s) {
+ return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
+ }
+
+ public String mSeqToArrayGoodHint(String[] items, int i) {
+ return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
+ }
+
+ public String mSeqToArrayGoodHint2(String[] items, String s) {
+ return "mSeqToArrayGoodHint2(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
+ }
+
+ public String mSeqToArrayGoodHint2(String item) {
+ return "mSeqToArrayGoodHint2(String " + item + ")";
+ }
+
+ public String mSeqToArrayPoorHint(String[] items, String s) {
+ return "mSeqToArrayPoorHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
+ }
+
+ public String mSeqToArrayPoorHint(String item, int i) {
+ return "mSeqToArrayPoorHint(String " + item + ", int " + i + ")";
+ }
+
+ public String mSeqToArrayPoorHint2(String[] items) {
+ return "mSeqToArrayPoorHint2(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mSeqToArrayPoorHint2(String item) {
+ return "mSeqToArrayPoorHint2(String " + item + ")";
+ }
+
+ public String mSeqToArrayPoorHint3(String[] items) {
+ return "mSeqToArrayPoorHint3(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mSeqToArrayPoorHint3(int[] items) {
+ return "mSeqToArrayPoorHint3(int[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVsListPreference(String[] items) {
+ return "mStringArrayVsListPreference(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVsListPreference(List items) {
+ return "mStringArrayVsListPreference(List " + TestUtil.listToString(items) + ")";
+ }
+
+ public String mStringArrayVsObjectArrayPreference(String[] items) {
+ return "mStringArrayVsObjectArrayPreference(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVsObjectArrayPreference(Object[] items) {
+ return "mStringArrayVsObjectArrayPreference(Object[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntArrayVsIntegerArrayPreference(int[] items) {
+ return "mIntArrayVsIntegerArrayPreference(int[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntArrayVsIntegerArrayPreference(Integer[] items) {
+ return "mIntArrayVsIntegerArrayPreference(Integer[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntArrayNonOverloaded(int[] items) {
+ return "mIntArrayNonOverloaded(int[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntegerArrayNonOverloaded(Integer[] items) {
+ return "mIntegerArrayNonOverloaded(Integer[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntegerListNonOverloaded(List<Integer> items) {
+ return "mIntegerListNonOverloaded(List<Integer> " + items + ")";
+ }
+
+ public String mStringListNonOverloaded(List<String> items) {
+ return "mStringListNonOverloaded(List<String> " + items + ")";
+ }
+
+ public String mStringArrayNonOverloaded(String[] items) {
+ return "mStringArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mObjectListNonOverloaded(List<Object> items) {
+ return "mObjectListNonOverloaded(List<Object> " + items + ")";
+ }
+
+ public String mObjectArrayNonOverloaded(Object[] items) {
+ return "mObjectArrayNonOverloaded(Object[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mIntegerArrayOverloaded(Integer[] items, int i) {
+ return "mIntegerArrayOverloaded(Integer[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
+ }
+
+ public String mIntegerArrayOverloaded(Object obj, boolean b) {
+ return "mIntegerArrayOverloaded(Object " + obj + ", boolean " + b + ")";
+ }
+
+ public String mStringArrayOverloaded(String[] items, int i) {
+ return "mStringArrayOverloaded(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
+ }
+
+ public String mStringArrayOverloaded(Object obj, boolean b) {
+ return "mStringArrayOverloaded(Object " + obj + ", boolean " + b + ")";
+ }
+
+ public String mCharArrayOverloaded(char[] items, int i) {
+ return "mCharArrayOverloaded(char[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
+ }
+
+ public String mCharArrayOverloaded(Character[] items, String s) {
+ return "mCharArrayOverloaded(Character[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
+ }
+
+ public String mCharArrayOverloaded(Object obj, boolean b) {
+ return "mCharArrayOverloaded(Object " + obj + ", boolean " + b + ")";
+ }
+
+ public String mStringArrayArrayOverloaded(String[][] arrayArray, int i) {
+ return "mStringArrayArrayOverloaded(String[][] " + TestUtil.arrayToString(arrayArray) + ", int " + i + ")";
+ }
+
+ public String mStringArrayArrayOverloaded(Object obj, boolean b) {
+ return "mStringArrayArrayOverloaded(Object " + obj + ", boolean " + b + ")";
+ }
+
+ public String mIntArrayArrayOverloaded(int[][] xss) {
+ return "mIntArrayArrayOverloaded(" + TestUtil.arrayToString(xss) + ")";
+ }
+
+ public String mIntArrayArrayOverloaded(String s) {
+ return "mIntArrayArrayOverloaded(" + s + ")";
+ }
+
+ public String mArrayOfListsOverloaded(List[] xss) {
+ return "mArrayOfListsOverloaded(" + TestUtil.arrayToString(xss) + ")";
+ }
+
+ public String mArrayOfListsOverloaded(String x) {
+ return "mArrayOfListsOverloaded(" + x + ")";
+ }
+
+ public String mIntArrayArrayNonOverloaded(int[][] xss) {
+ return "mIntArrayArrayNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
+ }
+
+ public String mArrayOfListsNonOverloaded(List[] xss) {
+ return "mArrayOfListsNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
+ }
+
+ public String mStringArrayVarargsNonOverloaded(String... items) {
+ return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded(String... items) {
+ return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded1(String... items) {
+ return "mStringArrayVarargsOverloaded1(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded1(List<String> items) {
+ return "mStringArrayVarargsOverloaded1(List " + TestUtil.listToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded2(String... items) {
+ return "mStringArrayVarargsOverloaded2(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded2(String item) {
+ return "mStringArrayVarargsOverloaded2(String " + item + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded3(String... items) {
+ return "mStringArrayVarargsOverloaded3(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded3(String item1, String item2) {
+ return "mStringArrayVarargsOverloaded3(String " + item1 + ", String " + item2 + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded4(String... items) {
+ return "mStringArrayVarargsOverloaded4(String[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mStringArrayVarargsOverloaded4(List... items) {
+ return "mStringArrayVarargsOverloaded4(List[] " + TestUtil.arrayToString(items) + ")";
+ }
+
+ public String mListOrString(List<String> items) {
+ return "mListOrString(List " + TestUtil.listToString(items) + ")";
+ }
+
+ public String mListOrString(String item) {
+ return "mListOrString(String " + item + ")";
+ }
+
+ public String mListListOrString(List<List<Object>> items) {
+ return "mListListOrString(List " + TestUtil.listToString(items) + ")";
+ }
+
+ public String mListListOrString(String item) {
+ return "mListListOrString(String " + item + ")";
+ }
+
+ public String mMapOrBoolean(Map v) {
+ return "mMapOrBoolean(Map " + v + ")";
+ }
+
+ public String mMapOrBoolean(boolean v) {
+ return "mMapOrBoolean(boolean " + v + ")";
+ }
+
+ public String mMapOrBooleanVarargs(Map... v) {
+ return "mMapOrBooleanVarargs(Map... " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mMapOrBooleanVarargs(boolean... v) {
+ return "mMapOrBooleanVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mMapOrBooleanFixedAndVarargs(Map v) {
+ return "mMapOrBooleanFixedAndVarargs(Map " + v + ")";
+ }
+
+ public String mMapOrBooleanFixedAndVarargs(boolean v) {
+ return "mMapOrBooleanFixedAndVarargs(boolean " + v + ")";
+ }
+
+ public String mMapOrBooleanFixedAndVarargs(Map... v) {
+ return "mMapOrBooleanFixedAndVarargs(Map... " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mMapOrBooleanFixedAndVarargs(boolean... v) {
+ return "mMapOrBooleanFixedAndVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mNumberOrArray(Number v) {
+ return "mNumberOrArray(Number " + v + ")";
+ }
+
+ public String mNumberOrArray(Object[] v) {
+ return "mNumberOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mIntOrArray(int v) {
+ return "mIntOrArray(int " + v + ")";
+ }
+
+ public String mIntOrArray(Object[] v) {
+ return "mIntOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mDateOrArray(Date v) {
+ return "mDateOrArray(Date " + v.getTime() + ")";
+ }
+
+ public String mDateOrArray(Object[] v) {
+ return "mDateOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mStringOrArray(String v) {
+ return "mStringOrArray(String " + v + ")";
+ }
+
+ public String mStringOrArray(Object[] v) {
+ return "mStringOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mBooleanOrArray(boolean v) {
+ return "mBooleanOrArray(boolean " + v + ")";
+ }
+
+ public String mBooleanOrArray(Object[] v) {
+ return "mBooleanOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mMapOrArray(Map v) {
+ return "mMapOrArray(Map " + v + ")";
+ }
+
+ public String mMapOrArray(Object[] v) {
+ return "mMapOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mListOrArray(List v) {
+ return "mListOrArray(List " + v + ")";
+ }
+
+ public String mListOrArray(Object[] v) {
+ return "mListOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mSetOrArray(Set v) {
+ return "mSetOrArray(Set " + v + ")";
+ }
+
+ public String mSetOrArray(Object[] v) {
+ return "mSetOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
+ }
+
+ public String mCharNonOverloaded(char c) {
+ return "mCharNonOverloaded(char " + c + ")";
+ }
+
+ public String mCharacterNonOverloaded(Character c) {
+ return "mCharacterNonOverloaded(Character " + c + ")";
+ }
+
+ public String mCharOrCharacterOverloaded(char c) {
+ return "mCharOrCharacterOverloaded(char " + c + ")";
+ }
+
+ public String mCharOrCharacterOverloaded(Character c) {
+ return "mCharOrCharacterOverloaded(Character " + c + ")";
+ }
+
+ public String mCharOrBooleanOverloaded(char c) {
+ return "mCharOrBooleanOverloaded(char " + c + ")";
+ }
+
+ public String mCharOrBooleanOverloaded(boolean b) {
+ return "mCharOrBooleanOverloaded(boolean " + b + ")";
+ }
+
+ public String mCharOrStringOverloaded(char c, boolean b) {
+ return "mCharOrStringOverloaded(char " + c + ", boolean " + b + ")";
+ }
+
+ public String mCharOrStringOverloaded(String s, int i) {
+ return "mCharOrStringOverloaded(String " + s + ", int " + i + ")";
+ }
+
+ public String mCharacterOrStringOverloaded(Character c, boolean b) {
+ return "mCharacterOrStringOverloaded(Character " + c + ", boolean " + b + ")";
+ }
+
+ public String mCharacterOrStringOverloaded(String s, int i) {
+ return "mCharacterOrStringOverloaded(String " + s + ", int " + i + ")";
+ }
+
+ public String mCharOrStringOverloaded2(String s) {
+ return "mCharOrStringOverloaded2(String " + s + ")";
+ }
+
+ public String mCharOrStringOverloaded2(char c) {
+ return "mCharOrStringOverloaded2(char " + c + ")";
+ }
+
+ public String mCharacterOrStringOverloaded2(String s) {
+ return "mCharacterOrStringOverloaded2(String " + s + ")";
+ }
+
+ public String mCharacterOrStringOverloaded2(Character c) {
+ return "mCharacterOrStringOverloaded2(Character " + c + ")";
+ }
+
+
+ public String getJavaString() {
+ return "s";
+ }
+
+ public List getJavaStringList() {
+ List list = new ArrayList();
+ list.add("a");
+ list.add("b");
+ return list;
+ }
+
+ public List getJavaString2List() {
+ List list = new ArrayList();
+ list.add("aa");
+ list.add("bb");
+ return list;
+ }
+
+ public List getJavaStringListList() {
+ List listList = new ArrayList();
+ {
+ List list = new ArrayList();
+ list.add("a");
+ list.add("b");
+
+ listList.add(list);
+ }
+ {
+ List list = new ArrayList();
+ list.add("c");
+
+ listList.add(list);
+ }
+ return listList;
+ }
+
+ public List getJavaStringSequenceList() throws TemplateModelException {
+ ObjectWrapper ow = Environment.getCurrentEnvironment().getObjectWrapper();
+
+ List listList = new ArrayList();
+ {
+ List list = new ArrayList();
+ list.add("a");
+ list.add("b");
+
+ listList.add(ow.wrap(list));
+ }
+ {
+ List list = new ArrayList();
+ list.add("c");
+
+ listList.add(ow.wrap(list));
+ }
+ return listList;
+ }
+
+ public List<int[]> getJavaListOfIntArrays() {
+ List list = new ArrayList();
+ list.add(new int[] {1, 2, 3});
+ list.add(new int[] {});
+ list.add(new int[] {4});
+ return list;
+ }
+
+ @SuppressWarnings("boxing")
+ public List getJavaIntegerListList() {
+ List listList = new ArrayList();
+ {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+
+ listList.add(list);
+ }
+ {
+ List list = new ArrayList();
+ list.add(3);
+
+ listList.add(list);
+ }
+ return listList;
+ }
+
+ @SuppressWarnings("boxing")
+ public List<Integer> getJavaIntegerList() {
+ List<Integer> list = new ArrayList<>();
+ list.add(1);
+ list.add(2);
+ return list;
+ }
+
+ @SuppressWarnings("boxing")
+ public List<Byte> getJavaByteList() {
+ List<Byte> list = new ArrayList<>();
+ list.add((byte) 1);
+ list.add((byte) 2);
+ return list;
+ }
+
+ @SuppressWarnings("boxing")
+ public List<Character> getJavaCharacterList() {
+ List<Character> list = new ArrayList<>();
+ list.add('c');
+ list.add('C');
+ return list;
+ }
+
+ public String[] getJavaStringArray() {
+ return new String[] { "a", "b" };
+ }
+
+ public int[] getJavaIntArray() {
+ return new int[] { 11, 22 };
+ }
+
+ public Integer[] getJavaIntegerArray() {
+ return new Integer[] { Integer.valueOf(11), Integer.valueOf(22) };
+ }
+
+ public String[] getJavaEmptyStringArray() {
+ return new String[] { };
+ }
+
+ public String[][] getJavaStringArrayArray() {
+ return new String[][] { new String[] { "a", "b" }, new String[] { }, new String[] { "c" } };
+ }
+
+ public Object[] getJavaObjectArray() {
+ return new Object[] { "a", "b" };
+ }
+
+ public TemplateModel getHashAndScalarModel() {
+ return HashAndScalarModel.INSTANCE;
+ }
+
+ public TemplateModel getBooleanAndScalarModel() {
+ return BooleanAndScalarModel.INSTANCE;
+ }
+
+ public TemplateModel getAllModels() {
+ return AllTemplateModels.INSTANCE;
+ }
+
+ public TemplateNumberModel getAdaptedNumber() {
+ return new MyAdapterNumberModel();
+ }
+
+ public TemplateNumberModel getWrapperNumber() {
+ return new MyWrapperNumberModel();
+ }
+
+ public TemplateBooleanModel getStringAdaptedToBoolean() {
+ return new MyStringAdaptedToBooleanModel();
+ }
+
+ public TemplateBooleanModel getStringAdaptedToBoolean2() {
+ return new MyStringAdaptedToBooleanModel2();
+ }
+
+ public TemplateBooleanModel getStringWrappedAsBoolean() {
+ return new MyStringWrapperAsBooleanModel();
+ }
+
+ public TemplateBooleanModel getBooleanWrappedAsAnotherBoolean() {
+ return new MyBooleanWrapperAsAnotherBooleanModel();
+ }
+
+ public String bugReport363(Map<String, ?> fields, List<?> listField) {
+ return "Executed: testMethod(Map fields, List listField) on input: fields=" + fields
+ + " and listField=" + listField;
+ }
+
+ public String bugReport363(Object... fields) {
+ return "Executed: testMethod(Object... fields) on input: fields=" + TestUtil.arrayToString(fields);
+ }
+
+ private static class MyAdapterNumberModel implements TemplateNumberModel, AdapterTemplateModel {
+
+ @Override
+ public Object getAdaptedObject(Class hint) {
+ if (hint == double.class) {
+ return Double.valueOf(123.0001);
+ } else if (hint == Double.class) {
+ return Double.valueOf(123.0002);
+ } else {
+ return Long.valueOf(124L);
+ }
+ }
+
+ @Override
+ public Number getAsNumber() throws TemplateModelException {
+ return Integer.valueOf(122);
+ }
+
+ }
+
+ private static class MyWrapperNumberModel implements TemplateNumberModel, WrapperTemplateModel {
+
+ @Override
+ public Number getAsNumber() throws TemplateModelException {
+ return Integer.valueOf(122);
+ }
+
+ @Override
+ public Object getWrappedObject() {
+ return Double.valueOf(123.0001);
+ }
+
+ }
+
+ private static class MyStringWrapperAsBooleanModel implements TemplateBooleanModel, WrapperTemplateModel {
+
+ @Override
+ public Object getWrappedObject() {
+ return "yes";
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return true;
+ }
+
+ }
+
+ private static class MyBooleanWrapperAsAnotherBooleanModel implements TemplateBooleanModel, WrapperTemplateModel {
+
+ @Override
+ public Object getWrappedObject() {
+ return Boolean.TRUE;
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return false;
+ }
+
+ }
+
+ private static class MyStringAdaptedToBooleanModel implements TemplateBooleanModel, AdapterTemplateModel {
+
+ @Override
+ public Object getAdaptedObject(Class hint) {
+ if (hint != Boolean.class && hint != boolean.class) {
+ return "yes";
+ } else {
+ return Boolean.TRUE;
+ }
+ }
+
+ @Override
+ public boolean getAsBoolean() throws TemplateModelException {
+ return false;
+ }
+
+ }
+
+ private static class MyStringAdaptedToBooleanModel2 implements TemplateBooleanModel, AdapterTemplateModel {
+
+ @Override
+ public Object getAdaptedObject(Class hint) {
+ return "yes";
+ }
+
+ @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/SimpleMapAndCollectionObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleMapAndCollectionObjectWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleMapAndCollectionObjectWrapper.java
new file mode 100644
index 0000000..bd445c6
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleMapAndCollectionObjectWrapper.java
@@ -0,0 +1,60 @@
+/*
+ * 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.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.freemarker.core.Version;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleHash;
+import org.apache.freemarker.core.model.impl.SimpleSequence;
+
+/**
+ * Forces using "simple" models for {@link Map}-s, {@link Collection}-s and arrays. This is mostly useful for template
+ * test cases that wish to test with these models, but otherwise need to able to wrap beans and such.
+ */
+public class SimpleMapAndCollectionObjectWrapper extends DefaultObjectWrapper {
+
+ public SimpleMapAndCollectionObjectWrapper(Version incompatibleImprovements) {
+ super(new DefaultObjectWrapper.Builder(incompatibleImprovements), true);
+ }
+
+ @Override
+ public TemplateModel wrap(Object obj) throws TemplateModelException {
+ if (obj == null) {
+ return super.wrap(null);
+ }
+ if (obj.getClass().isArray()) {
+ obj = Arrays.asList((Object[]) obj);
+ }
+ if (obj instanceof Collection) {
+ return new SimpleSequence((Collection<?>) obj, this);
+ }
+ if (obj instanceof Map) {
+ return new SimpleHash((Map<?, ?>) obj, this);
+ }
+
+ return super.wrap(obj);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.java
new file mode 100644
index 0000000..85e27d7
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/SimpleTestMethod.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.test.templatesuite.models;
+
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * A simple method model used as a test bed.
+ */
+public class SimpleTestMethod implements TemplateMethodModel {
+
+ /**
+ * Executes a method call.
+ *
+ * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
+ * the values of the arguments passed to the method.
+ * @return the <tt>TemplateModel</tt> produced by the method, or null.
+ */
+ @Override
+ public Object exec(List arguments) {
+ if ( arguments.size() == 0 ) {
+ return new SimpleScalar( "Empty list provided" );
+ } else if ( arguments.size() > 1 ) {
+ return new SimpleScalar( "Argument size is: " + arguments.size() );
+ } else {
+ return new SimpleScalar( "Single argument value is: " + arguments.get(0) );
+ }
+ }
+}
[45/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
new file mode 100644
index 0000000..49534fa
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ObjectBuilderSettingsTest.java
@@ -0,0 +1,1499 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
+import org.apache.freemarker.core.arithmetic.impl.BigDecimalArithmeticEngine;
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.templateresolver.CacheStorage;
+import org.apache.freemarker.core.templateresolver.TemplateLoader;
+import org.apache.freemarker.core.templateresolver.TemplateLoaderSession;
+import org.apache.freemarker.core.templateresolver.TemplateLoadingResult;
+import org.apache.freemarker.core.templateresolver.TemplateLoadingSource;
+import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage;
+import org.apache.freemarker.core.userpkg.PublicWithMixedConstructors;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class ObjectBuilderSettingsTest {
+
+ @Test
+ public void newInstanceTest() throws Exception {
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(4f, res.f, 0);
+ assertFalse(res.b);
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(4f, res.f, 0);
+ assertFalse(res.b);
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1.5, -20, 8589934592, true)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(1.5f, res.f, 0);
+ assertEquals(Integer.valueOf(-20), res.i);
+ assertEquals(8589934592l, res.l);
+ assertTrue(res.b);
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1, true)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(2f, res.f, 0);
+ assertEquals(Integer.valueOf(1), res.i);
+ assertEquals(2l, res.l);
+ assertTrue(res.b);
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(3f, res.f, 0);
+ assertEquals(Integer.valueOf(11), res.i);
+ assertEquals(22l, res.l);
+ assertFalse(res.b);
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(p1 = 1, p2 = 2, p3 = true, p4 = 's')",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(4f, res.f, 0);
+ assertFalse(res.b);
+ assertEquals(1d, res.getP1(), 0);
+ assertEquals(2, res.getP2());
+ assertTrue(res.isP3());
+ assertEquals("s", res.getP4());
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
+ + "null, 2, p1 = 1, p2 = 2, p3 = false, p4 = null)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertNull(res.i);
+ assertEquals(2, res.l, 0);
+ assertEquals(3f, res.f, 0);
+ assertFalse(res.b);
+ assertEquals(1d, res.getP1(), 0);
+ assertEquals(2, res.getP2());
+ assertFalse(res.isP3());
+ assertNull(res.getP4());
+ }
+
+ {
+ // Deliberately odd spacings
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "\t\torg.apache.freemarker .core . \n"
+ + "\tObjectBuilderSettingsTest$TestBean1(\n\r\tp1=1\n,p2=2,p3=true,p4='s' )",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(4f, res.f, 0);
+ assertFalse(res.b);
+ assertEquals(1d, res.getP1(), 0);
+ assertEquals(2, res.getP2());
+ assertTrue(res.isP3());
+ assertEquals("s", res.getP4());
+ }
+
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1, true, p2 = 2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(2f, res.f, 0);
+ assertEquals(Integer.valueOf(1), res.i);
+ assertEquals(2l, res.l);
+ assertTrue(res.b);
+ assertEquals(0d, res.getP1(), 0);
+ assertEquals(2, res.getP2());
+ assertFalse(res.isP3());
+ }
+ }
+
+ @Test
+ public void builderTest() throws Exception {
+ {
+ // `()`-les syntax:
+ TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertTrue(res.built);
+ assertEquals(0, res.x);
+ }
+
+ {
+ TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertTrue(res.built);
+ assertEquals(0, res.x);
+ }
+
+ {
+ TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertTrue(res.built);
+ assertEquals(1, res.x);
+ }
+
+ {
+ TestBean2 res = (TestBean2) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertTrue(res.built);
+ assertEquals(1, res.x);
+ }
+ }
+
+ @Test
+ public void staticInstanceTest() throws Exception {
+ // ()-les syntax:
+ {
+ TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(0, res.i);
+ assertEquals(0, res.x);
+ assertSame(TestBean5.INSTANCE, res); //!
+ }
+
+ {
+ TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(0, res.i);
+ assertEquals(0, res.x);
+ assertSame(TestBean5.INSTANCE, res); //!
+ }
+
+ {
+ TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5(x = 1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(0, res.i);
+ assertEquals(1, res.x);
+ assertNotSame(TestBean5.INSTANCE, res);
+ }
+
+ {
+ TestBean5 res = (TestBean5) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5(1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(1, res.i);
+ assertEquals(0, res.x);
+ assertNotSame(TestBean5.INSTANCE, res);
+ }
+ }
+
+ @Test
+ public void stringLiteralsTest() throws Exception {
+ {
+ TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"\", '', s3 = r\"\", s4 = r'')",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("", res.getS1());
+ assertEquals("", res.getS2());
+ assertEquals("", res.getS3());
+ assertEquals("", res.getS4());
+ }
+
+ {
+ TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"a\", 'b', s3 = r\"c\", s4 = r'd')",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("a", res.getS1());
+ assertEquals("b", res.getS2());
+ assertEquals("c", res.getS3());
+ assertEquals("d", res.getS4());
+ }
+
+ {
+ TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4(\"a'A\", 'b\"B', s3 = r\"c'C\", s4 = r'd\"D')",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("a'A", res.getS1());
+ assertEquals("b\"B", res.getS2());
+ assertEquals("c'C", res.getS3());
+ assertEquals("d\"D", res.getS4());
+ }
+
+ {
+ TestBean4 res = (TestBean4) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean4("
+ + "\"a\\nA\\\"a\\\\A\", 'a\\nA\\'a\\\\A', s3 = r\"a\\n\\A\", s4 = r'a\\n\\A')",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("a\nA\"a\\A", res.getS1());
+ assertEquals("a\nA'a\\A", res.getS2());
+ assertEquals("a\\n\\A", res.getS3());
+ assertEquals("a\\n\\A", res.getS4());
+ }
+ }
+
+ @Test
+ public void nestedBuilderTest() throws Exception {
+ {
+ TestBean6 res = (TestBean6) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
+ + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22, p4 = 'foo'),"
+ + "1,"
+ + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(11),"
+ + "y=2,"
+ + "b3=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 22)"
+ + ")",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(Integer.valueOf(11), res.b1.i);
+ assertEquals(22, res.b1.l);
+ assertEquals("foo", res.b1.p4);
+ assertEquals(1, res.x);
+ assertEquals(11, res.b2.x);
+ assertEquals(2, res.y);
+ assertEquals(22, res.b3.x);
+ assertNull(res.b4);
+ }
+
+ {
+ TestBean6 res = (TestBean6) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
+ + "null,"
+ + "-1,"
+ + "null,"
+ + "b4=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean6("
+ + " org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(11, 22, p4 = 'foo'),"
+ + " 1,"
+ + " org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(11),"
+ + " y=2,"
+ + " b3=org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean2(x = 22)"
+ + "),"
+ + "y=2"
+ + ")",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertNull(res.b1);
+ assertEquals(-1, res.x);
+ assertNull(res.b2);
+ assertEquals(2, res.y);
+ assertEquals(Integer.valueOf(11), res.b4.b1.i);
+ assertEquals(22, res.b4.b1.l);
+ assertEquals("foo", res.b4.b1.p4);
+ assertEquals(1, res.b4.x);
+ assertEquals(11, res.b4.b2.x);
+ assertEquals(2, res.b4.y);
+ assertEquals(22, res.b4.b3.x);
+ assertNull(res.b4.b4);
+ }
+ }
+
+ @Test
+ public void defaultObjectWrapperTest() throws Exception {
+ DefaultObjectWrapper ow = (DefaultObjectWrapper) _ObjectBuilderSettingEvaluator.eval(
+ "DefaultObjectWrapper(3.0.0)",
+ ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ assertFalse(ow.isExposeFields());
+ }
+
+ @Test
+ public void defaultObjectWrapperTest2() throws Exception {
+ DefaultObjectWrapper ow = (DefaultObjectWrapper) _ObjectBuilderSettingEvaluator.eval(
+ "DefaultObjectWrapper(3.0.0, exposeFields=true)",
+ ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
+ assertTrue(ow.isExposeFields());
+ }
+
+ @Test
+ public void configurationPropertiesTest() throws Exception {
+ final Configuration.Builder cfgB = new Configuration.Builder(Configuration.getVersion());
+
+ {
+ Properties props = new Properties();
+ props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY,
+ "org.apache.freemarker.core.model.impl.DefaultObjectWrapper(3.0.0)");
+ props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyArithmeticEngine");
+ props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateExceptionHandler");
+ props.setProperty(Configuration.ExtendableBuilder.CACHE_STORAGE_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyCacheStorage()");
+ props.setProperty(MutableProcessingConfiguration.NEW_BUILTIN_CLASS_RESOLVER_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyNewBuiltinClassResolver()");
+ props.setProperty(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY, "utf-8");
+ props.setProperty(Configuration.ExtendableBuilder.TEMPLATE_LOADER_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateLoader()");
+ cfgB.setSettings(props);
+ assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
+ assertEquals(
+ Configuration.VERSION_3_0_0, ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
+ assertEquals(DummyArithmeticEngine.class, cfgB.getArithmeticEngine().getClass());
+ assertEquals(DummyTemplateExceptionHandler.class, cfgB.getTemplateExceptionHandler().getClass());
+ assertEquals(DummyCacheStorage.class, cfgB.getCacheStorage().getClass());
+ assertEquals(DummyNewBuiltinClassResolver.class, cfgB.getNewBuiltinClassResolver().getClass());
+ assertEquals(DummyTemplateLoader.class, cfgB.getTemplateLoader().getClass());
+ assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
+ }
+
+ {
+ Properties props = new Properties();
+ props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "defAult");
+ props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyArithmeticEngine(x = 1)");
+ props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY,
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$DummyTemplateExceptionHandler(x = 1)");
+ props.setProperty(Configuration.ExtendableBuilder.CACHE_STORAGE_KEY,
+ "soft: 500, strong: 100");
+ props.setProperty(MutableProcessingConfiguration.NEW_BUILTIN_CLASS_RESOLVER_KEY,
+ "allows_nothing");
+ cfgB.setSettings(props);
+ assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
+ assertEquals(1, ((DummyArithmeticEngine) cfgB.getArithmeticEngine()).getX());
+ assertEquals(1, ((DummyTemplateExceptionHandler) cfgB.getTemplateExceptionHandler()).getX());
+ assertEquals(Configuration.VERSION_3_0_0,
+ ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
+ assertEquals(500, ((MruCacheStorage) cfgB.getCacheStorage()).getSoftSizeLimit());
+ assertEquals(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER, cfgB.getNewBuiltinClassResolver());
+ assertEquals(StandardCharsets.UTF_8, cfgB.getSourceEncoding());
+ }
+
+ {
+ Properties props = new Properties();
+ props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "Default");
+ props.setProperty(MutableProcessingConfiguration.ARITHMETIC_ENGINE_KEY, "bigdecimal");
+ props.setProperty(MutableProcessingConfiguration.TEMPLATE_EXCEPTION_HANDLER_KEY, "rethrow");
+ cfgB.setSettings(props);
+ assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
+ assertSame(BigDecimalArithmeticEngine.INSTANCE, cfgB.getArithmeticEngine());
+ assertSame(TemplateExceptionHandler.RETHROW_HANDLER, cfgB.getTemplateExceptionHandler());
+ assertEquals(Configuration.VERSION_3_0_0,
+ ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
+ }
+
+ {
+ Properties props = new Properties();
+ props.setProperty(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, "DefaultObjectWrapper(3.0.0)");
+ cfgB.setSettings(props);
+ assertEquals(DefaultObjectWrapper.class, cfgB.getObjectWrapper().getClass());
+ assertEquals(
+ Configuration.VERSION_3_0_0,
+ ((DefaultObjectWrapper) cfgB.getObjectWrapper()).getIncompatibleImprovements());
+ }
+ }
+
+ @Test
+ public void timeZoneTest() throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException,
+ InstantiationException, IllegalAccessException {
+ for (String timeZoneId : new String[] { "GMT+01", "GMT", "UTC" }) {
+ TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(timeZone=TimeZone('"
+ + timeZoneId + "'))",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ assertEquals(TimeZone.getTimeZone(timeZoneId), result.getTimeZone());
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(timeZone=TimeZone('foobar'))",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getCause().getMessage(),
+ allOf(containsStringIgnoringCase("unrecognized"), containsString("foobar")));
+ }
+ }
+
+ @Test
+ public void charsetTest() throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException,
+ InstantiationException, IllegalAccessException {
+ for (String timeZoneId : new String[] { "uTf-8", "GMT", "UTC" }) {
+ TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(charset=Charset('iso-8859-1'))",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ assertEquals(StandardCharsets.ISO_8859_1, result.getCharset());
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(charset=Charset('noSuchCS'))",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getCause(), instanceOf(UnsupportedCharsetException.class));
+ }
+ }
+
+ @Test
+ public void configureBeanTest() throws Exception {
+ final TestBean7 bean = new TestBean7();
+ final String src = "a/b(s='foo', x=1, b=true), bar";
+ int nextPos = _ObjectBuilderSettingEvaluator.configureBean(src, src.indexOf('(') + 1, bean,
+ _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("foo", bean.getS());
+ assertEquals(1, bean.getX());
+ assertTrue(bean.isB());
+ assertEquals(", bar", src.substring(nextPos));
+ }
+
+ @Test
+ public void parsingErrors() throws Exception {
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1,,2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("\",\""));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x=1,2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("must precede named"));
+ }
+
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x=1;2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("\";\""));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(1,2))",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("\")\""));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "foo.Bar('s${x}s'))",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("${...}"));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "foo.Bar('s#{x}s'))",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("#{...}"));
+ }
+ }
+
+ @Test
+ public void semanticErrors() throws Exception {
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$XTestBean1(1,2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("Failed to get class"));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(true, 2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("constructor"));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(x = 1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsStringIgnoringCase("no writeable JavaBeans property called \"x\""));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1(p1 = 1, p1 = 2)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("twice"));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "java.util.HashMap()",
+ ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("is not a(n) " + ObjectWrapper.class.getName()));
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "null",
+ ObjectWrapper.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("can't be null"));
+ }
+ }
+
+ @Test
+ public void testLiteralAsObjectBuilder() throws Exception {
+ assertNull(_ObjectBuilderSettingEvaluator.eval(
+ "null",
+ ObjectWrapper.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals("foo", _ObjectBuilderSettingEvaluator.eval(
+ "'foo'",
+ CharSequence.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Boolean.TRUE, _ObjectBuilderSettingEvaluator.eval(
+ " true ",
+ Object.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Double.valueOf("1.23"), _ObjectBuilderSettingEvaluator.eval(
+ "1.23 ",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(new Version(1, 2, 3), _ObjectBuilderSettingEvaluator.eval(
+ " 1.2.3",
+ Object.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ }
+
+ @Test
+ public void testNumberLiteralJavaTypes() throws Exception {
+ assertEquals(Double.valueOf("1.0"), _ObjectBuilderSettingEvaluator.eval(
+ "1.0",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(new BigInteger("-9223372036854775809"), _ObjectBuilderSettingEvaluator.eval(
+ "-9223372036854775809",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(new BigInteger("9223372036854775808"), _ObjectBuilderSettingEvaluator.eval(
+ "9223372036854775808",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(Long.valueOf(-9223372036854775808L), _ObjectBuilderSettingEvaluator.eval(
+ "-9223372036854775808",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Long.valueOf(9223372036854775807L), _ObjectBuilderSettingEvaluator.eval(
+ "9223372036854775807",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(Integer.valueOf(-2147483648), _ObjectBuilderSettingEvaluator.eval(
+ "-2147483648",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Integer.valueOf(2147483647), _ObjectBuilderSettingEvaluator.eval(
+ "2147483647",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(Integer.valueOf(-1), _ObjectBuilderSettingEvaluator.eval(
+ "-1",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Integer.valueOf(1), _ObjectBuilderSettingEvaluator.eval(
+ "1",
+ Number.class, true, _SettingEvaluationEnvironment.getCurrent()));
+ }
+
+ @Test
+ public void testListLiterals() throws Exception {
+ {
+ ArrayList<Object> expected = new ArrayList();
+ expected.add("s");
+ expected.add(null);
+ expected.add(true);
+ expected.add(new TestBean9(1));
+ expected.add(ImmutableList.of(11, 22, 33));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ "['s', null, true, org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1), [11, 22, 33]]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ " [ 's' , null , true , org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1) ,"
+ + " [ 11 , 22 , 33 ] ] ",
+ Collection.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ "['s',null,true,org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1),[11,22,33]]",
+ List.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ }
+
+ assertEquals(Collections.emptyList(), _ObjectBuilderSettingEvaluator.eval(
+ "[]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Collections.emptyList(), _ObjectBuilderSettingEvaluator.eval(
+ "[ ]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(Collections.singletonList(123), _ObjectBuilderSettingEvaluator.eval(
+ "[123]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Collections.singletonList(123), _ObjectBuilderSettingEvaluator.eval(
+ "[ 123 ]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(new TestBean9(1, ImmutableList.of("a", "b")), _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1, ['a', 'b'])",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "[1,]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \"]\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "[,1]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \",\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "1]",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \"]\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "[1",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("end of"));
+ }
+ }
+
+ @Test
+ public void testMapLiterals() throws Exception {
+ {
+ HashMap<String, Object> expected = new HashMap();
+ expected.put("k1", "s");
+ expected.put("k2", null);
+ expected.put("k3", true);
+ expected.put("k4", new TestBean9(1));
+ expected.put("k5", ImmutableList.of(11, 22, 33));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ "{'k1': 's', 'k2': null, 'k3': true, "
+ + "'k4': org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1), 'k5': [11, 22, 33]}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ " { 'k1' : 's' , 'k2' : null , 'k3' : true , "
+ + "'k4' : org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9 ( 1 ) , 'k5' : [ 11 , 22 , 33 ] } ",
+ Map.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ " {'k1':'s','k2':null,'k3':true,"
+ + "'k4':org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1),'k5':[11,22,33]}",
+ LinkedHashMap.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ }
+
+ {
+ HashMap<Object, String> expected = new HashMap();
+ expected.put(true, "T");
+ expected.put(1, "O");
+ expected.put(new TestBean9(1), "B");
+ expected.put(ImmutableList.of(11, 22, 33), "L");
+ assertEquals(expected, _ObjectBuilderSettingEvaluator.eval(
+ "{ true: 'T', 1: 'O', org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1): 'B', "
+ + "[11, 22, 33]: 'L' }",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ }
+
+ assertEquals(Collections.emptyMap(), _ObjectBuilderSettingEvaluator.eval(
+ "{}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Collections.emptyMap(), _ObjectBuilderSettingEvaluator.eval(
+ "{ }",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(Collections.singletonMap("k1", 123), _ObjectBuilderSettingEvaluator.eval(
+ "{'k1':123}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+ assertEquals(Collections.singletonMap("k1", 123), _ObjectBuilderSettingEvaluator.eval(
+ "{ 'k1' : 123 }",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ assertEquals(new TestBean9(1, ImmutableMap.of(11, "a", 22, "b")), _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean9(1, { 11: 'a', 22: 'b' })",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent()));
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "{1:2,}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \"}\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "{,1:2}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \",\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "1:2}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \":\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "1}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("found character \"}\""));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "{1",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("end of"));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "{1:",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("end of"));
+ }
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "{null:1}",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(), containsString("null as key"));
+ }
+ }
+
+ @Test
+ public void testMethodParameterNumberTypes() throws Exception {
+ {
+ TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=1)",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ assertEquals(result.getAnyObject(), 1);
+ }
+ {
+ TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=2147483649)",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ assertEquals(result.getAnyObject(), 2147483649L);
+ }
+ {
+ TestBean8 result = (TestBean8) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean8(anyObject=1.0)",
+ TestBean8.class, false, new _SettingEvaluationEnvironment());
+ // Like in FTL, non-integer numbers are BigDecimal-s, that are later coerced to the actual parameter type.
+ // However, here the type is Object, so it remains BigDecimal.
+ assertEquals(new BigDecimal("1.0"), result.getAnyObject());
+ }
+ }
+
+ @Test
+ public void testNonMethodParameterNumberTypes() throws Exception {
+ assertEqualsEvaled(Integer.valueOf(1), "1");
+ assertEqualsEvaled(Double.valueOf(1), "1.0");
+ assertEqualsEvaled(Long.valueOf(2147483649l), "2147483649");
+
+ assertEqualsEvaled(Double.valueOf(1), "1d");
+ assertEqualsEvaled(Double.valueOf(1), "1D");
+ assertEqualsEvaled(Float.valueOf(1), "1f");
+ assertEqualsEvaled(Float.valueOf(1), "1F");
+ assertEqualsEvaled(Long.valueOf(1), "1l");
+ assertEqualsEvaled(Long.valueOf(1), "1L");
+ assertEqualsEvaled(BigDecimal.valueOf(1), "1bd");
+ assertEqualsEvaled(BigDecimal.valueOf(1), "1Bd");
+ assertEqualsEvaled(BigDecimal.valueOf(1), "1BD");
+ assertEqualsEvaled(BigInteger.valueOf(1), "1bi");
+ assertEqualsEvaled(BigInteger.valueOf(1), "1bI");
+
+ assertEqualsEvaled(Float.valueOf(1.5f), "1.5f");
+ assertEqualsEvaled(Double.valueOf(1.5), "1.5d");
+ assertEqualsEvaled(BigDecimal.valueOf(1.5), "1.5bd");
+
+ assertEqualsEvaled(
+ ImmutableList.of(-1, -0.5, new BigDecimal("-0.1")),
+ "[ -1, -0.5, -0.1bd ]");
+ assertEqualsEvaled(
+ ImmutableMap.of(-1, -11, -0.5, -0.55, new BigDecimal("-0.1"), new BigDecimal("-0.11")),
+ "{ -1: -11, -0.5: -0.55, -0.1bd: -0.11bd }");
+ }
+
+ @Test
+ public void testStaticFields() throws Exception {
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
+ + "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST, true)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(TestStaticFields.CONST, (int) res.i);
+ }
+ {
+ TestBean1 res = (TestBean1) _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
+ + "p2 = org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(TestStaticFields.CONST, res.getP2());
+ }
+ assertEqualsEvaled(123, "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST");
+
+ // With shorthand class name:
+ assertEqualsEvaled(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX, "Configuration.AUTO_DETECT_TAG_SYNTAX");
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean1("
+ + "p2 = org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST())",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(),
+ containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST"));
+ }
+ try {
+ assertEqualsEvaled(123, "org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST()");
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(),
+ containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestStaticFields.CONST"));
+ }
+ try {
+ assertEqualsEvaled(123, "java.lang.String(org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5.INSTANCE)");
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertThat(e.getMessage(),
+ containsString("org.apache.freemarker.core.ObjectBuilderSettingsTest$TestBean5()"));
+ }
+ }
+
+ private void assertEqualsEvaled(Object expectedValue, String s)
+ throws _ObjectBuilderSettingEvaluationException, ClassNotFoundException, InstantiationException,
+ IllegalAccessException {
+ Object actualValue = _ObjectBuilderSettingEvaluator.eval(
+ s, Object.class, true, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(expectedValue, actualValue);
+ }
+
+ @Test
+ public void visibilityTest() throws Exception {
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PackageVisibleAll()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertEquals(IllegalAccessException.class, e.getCause().getClass());
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PackageVisibleWithPublicConstructor()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertEquals(IllegalAccessException.class, e.getCause().getClass());
+ }
+
+ try {
+ _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PublicWithPackageVisibleConstructor()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ fail();
+ } catch (_ObjectBuilderSettingEvaluationException e) {
+ assertEquals(IllegalAccessException.class, e.getCause().getClass());
+ }
+
+ {
+ Object o = _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PublicAll()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals(org.apache.freemarker.core.userpkg.PublicAll.class, o.getClass());
+ }
+
+ {
+ Object o = _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PublicWithMixedConstructors(1)",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("Integer", ((PublicWithMixedConstructors) o).getS());
+ }
+
+
+ {
+ Object o = _ObjectBuilderSettingEvaluator.eval(
+ "org.apache.freemarker.core.userpkg.PackageVisibleAllWithBuilder()",
+ Object.class, false, _SettingEvaluationEnvironment.getCurrent());
+ assertEquals("org.apache.freemarker.core.userpkg.PackageVisibleAllWithBuilder", o.getClass().getName());
+ }
+ }
+
+ public static class TestBean1 {
+ float f;
+ Integer i;
+ long l;
+ boolean b;
+
+ double p1;
+ int p2;
+ boolean p3;
+ String p4;
+
+ public TestBean1(float f, Integer i, long l, boolean b) {
+ this.f = f;
+ this.i = i;
+ this.l = l;
+ this.b = b;
+ }
+
+ public TestBean1(Integer i, boolean b) {
+ f = 2;
+ this.i = i;
+ l = 2;
+ this.b = b;
+ }
+
+ public TestBean1(Integer i, long l) {
+ f = 3;
+ this.i = i;
+ this.l = l;
+ b = false;
+ }
+
+ public TestBean1() {
+ f = 4;
+ }
+
+ public double getP1() {
+ return p1;
+ }
+
+ public void setP1(double p1) {
+ this.p1 = p1;
+ }
+
+ public int getP2() {
+ return p2;
+ }
+
+ public void setP2(int p2) {
+ this.p2 = p2;
+ }
+
+ public boolean isP3() {
+ return p3;
+ }
+
+ public void setP3(boolean p3) {
+ this.p3 = p3;
+ }
+
+ public String getP4() {
+ return p4;
+ }
+
+ public void setP4(String p4) {
+ this.p4 = p4;
+ }
+
+ }
+
+ public static class TestBean2 {
+ final boolean built;
+ final int x;
+
+ public TestBean2() {
+ built = false;
+ x = 0;
+ }
+
+ public TestBean2(int x) {
+ built = false;
+ this.x = x;
+ }
+
+ public TestBean2(TestBean2Builder builder) {
+ built = true;
+ x = builder.x;
+ }
+
+ }
+
+ public static class TestBean2Builder {
+ int x;
+
+ public TestBean2Builder() { }
+
+ public TestBean2Builder(int x) {
+ this.x = x;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public TestBean2 build() {
+ return new TestBean2(this);
+ }
+
+ }
+
+ public static class TestBean3 {
+
+ private int x;
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ }
+
+ public static class TestBean4 {
+ private final String s1, s2;
+ private String s3, s4;
+
+ public TestBean4(String s1, String s2) {
+ this.s1 = s1;
+ this.s2 = s2;
+ }
+
+ public String getS1() {
+ return s1;
+ }
+
+ public String getS2() {
+ return s2;
+ }
+
+ public String getS3() {
+ return s3;
+ }
+
+ public void setS3(String s3) {
+ this.s3 = s3;
+ }
+
+ public String getS4() {
+ return s4;
+ }
+
+ public void setS4(String s4) {
+ this.s4 = s4;
+ }
+
+ }
+
+ public static class TestBean5 {
+
+ public final static TestBean5 INSTANCE = new TestBean5();
+
+ private final int i;
+ private int x;
+
+ public TestBean5() {
+ i = 0;
+ }
+
+ public TestBean5(int i) {
+ this.i = i;
+ }
+
+ public int getI() {
+ return i;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ }
+
+ public static class TestBean6 {
+ private final TestBean1 b1;
+ private int x;
+ private final TestBean2 b2;
+ private int y;
+ private TestBean2 b3;
+ private TestBean6 b4;
+
+ public TestBean6(TestBean1 b1, int x, TestBean2 b2) {
+ this.b1 = b1;
+ this.x = x;
+ this.b2 = b2;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public TestBean2 getB3() {
+ return b3;
+ }
+
+ public void setB3(TestBean2 b3) {
+ this.b3 = b3;
+ }
+
+ public TestBean1 getB1() {
+ return b1;
+ }
+
+ public TestBean2 getB2() {
+ return b2;
+ }
+
+ public TestBean6 getB4() {
+ return b4;
+ }
+
+ public void setB4(TestBean6 b4) {
+ this.b4 = b4;
+ }
+
+ }
+
+ public class TestBean7 {
+
+ private String s;
+ private int x;
+ private boolean b;
+
+ public String getS() {
+ return s;
+ }
+
+ public void setS(String s) {
+ this.s = s;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public boolean isB() {
+ return b;
+ }
+
+ public void setB(boolean b) {
+ this.b = b;
+ }
+
+ @Override
+ public String toString() {
+ return "TestBean [s=" + s + ", x=" + x + ", b=" + b + "]";
+ }
+
+ }
+
+ public static class TestBean8 {
+ private TimeZone timeZone;
+ private Charset charset;
+ private Object anyObject;
+ private List<?> list;
+
+ public TimeZone getTimeZone() {
+ return timeZone;
+ }
+
+ public void setTimeZone(TimeZone timeZone) {
+ this.timeZone = timeZone;
+ }
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ public void setCharset(Charset charset) {
+ this.charset = charset;
+ }
+
+ public Object getAnyObject() {
+ return anyObject;
+ }
+
+ public void setAnyObject(Object anyObject) {
+ this.anyObject = anyObject;
+ }
+
+ public List<?> getList() {
+ return list;
+ }
+
+ public void setList(List<?> list) {
+ this.list = list;
+ }
+
+ }
+
+ public static class TestBean9 {
+
+ private final int n;
+ private final List<?> list;
+ private final Map<?, ?> map;
+
+ public TestBean9(int n) {
+ this(n, null, null);
+ }
+
+ public TestBean9(int n, List<?> list) {
+ this(n, list, null);
+ }
+
+ public TestBean9(int n, Map<?, ?> map) {
+ this(n, null, map);
+ }
+
+ public TestBean9(int n, List<?> list, Map<?, ?> map) {
+ this.n = n;
+ this.list = list;
+ this.map = map;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((list == null) ? 0 : list.hashCode());
+ result = prime * result + ((map == null) ? 0 : map.hashCode());
+ result = prime * result + n;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ TestBean9 other = (TestBean9) obj;
+ if (list == null) {
+ if (other.list != null) return false;
+ } else if (!list.equals(other.list)) return false;
+ if (map == null) {
+ if (other.map != null) return false;
+ } else if (!map.equals(other.map)) return false;
+ return n == other.n;
+ }
+
+ }
+
+ public static class TestStaticFields {
+ public static final int CONST = 123;
+ }
+
+ public static class DummyArithmeticEngine extends ArithmeticEngine {
+
+ private int x;
+
+ @Override
+ public int compareNumbers(Number first, Number second) throws TemplateException {
+ return 0;
+ }
+
+ @Override
+ public Number add(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number subtract(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number multiply(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number divide(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number modulus(Number first, Number second) throws TemplateException {
+ return null;
+ }
+
+ @Override
+ public Number toNumber(String s) {
+ return null;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ }
+
+ public static class DummyTemplateExceptionHandler implements TemplateExceptionHandler {
+
+ private int x;
+
+ @Override
+ public void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException {
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ }
+
+ public static class DummyCacheStorage implements CacheStorage {
+
+ @Override
+ public Object get(Object key) {
+ return null;
+ }
+
+ @Override
+ public void put(Object key, Object value) {
+ }
+
+ @Override
+ public void remove(Object key) {
+ }
+
+ @Override
+ public void clear() {
+ }
+
+ }
+
+ public static class DummyNewBuiltinClassResolver implements TemplateClassResolver {
+
+ @Override
+ public Class resolve(String className, Environment env, Template template) throws TemplateException {
+ return null;
+ }
+
+ }
+
+ public static class DummyTemplateLoader implements TemplateLoader {
+
+ @Override
+ public TemplateLoaderSession createSession() {
+ return null;
+ }
+
+ @Override
+ public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom,
+ Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException {
+ return TemplateLoadingResult.NOT_FOUND;
+ }
+
+ @Override
+ public void resetState() {
+ // Do nothing
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
new file mode 100644
index 0000000..06e863c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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.core;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.freemarker.core.util.OptInTemplateClassResolver;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+public class OptInTemplateClassResolverTest extends TestCase {
+
+ public OptInTemplateClassResolverTest(String name) {
+ super(name);
+ }
+
+ private static final Set ALLOWED_CLASSES = new HashSet();
+ static {
+ ALLOWED_CLASSES.add("java.lang.String");
+ ALLOWED_CLASSES.add("java.lang.Integer");
+ }
+
+ private static final List TRUSTED_TEMPLATES = new ArrayList();
+ static {
+ TRUSTED_TEMPLATES.add("lib/*");
+ TRUSTED_TEMPLATES.add("/include/*");
+ TRUSTED_TEMPLATES.add("trusted.ftl");
+ }
+
+ private OptInTemplateClassResolver resolver = new OptInTemplateClassResolver(
+ ALLOWED_CLASSES, TRUSTED_TEMPLATES);
+
+
+ public void testOptIn() throws TemplateException {
+ Template dummyTemp = Template.createPlainTextTemplate("foo.ftl", "",
+ new TestConfigurationBuilder().build());
+
+ assertEquals(String.class, resolver.resolve("java.lang.String", null, dummyTemp));
+ assertEquals(Integer.class, resolver.resolve("java.lang.Integer", null, dummyTemp));
+ try {
+ resolver.resolve("java.lang.Long", null, dummyTemp);
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ }
+
+ public void testTrusted() throws TemplateException {
+ Configuration cfg = new TestConfigurationBuilder().build();
+
+ assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("lib/foo.ftl", "", cfg)));
+ assertEquals(String.class, resolver.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("lib/foo.ftl", "", cfg)));
+ assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("/lib/foo.ftl", "", cfg)));
+ assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("include/foo.ftl", "", cfg)));
+ assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("trusted.ftl", "", cfg)));
+ assertEquals(Long.class, resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("/trusted.ftl", "", cfg)));
+ }
+
+ public void testCraftedTrusted() throws TemplateException {
+ testTrusted_checkFails("lib/../foo.ftl");
+ testTrusted_checkFails("lib\\..\\foo.ftl");
+ testTrusted_checkFails("lib\\../foo.ftl");
+ testTrusted_checkFails("lib/..\\foo.ftl");
+ testTrusted_checkFails("lib/..");
+ testTrusted_checkFails("lib%2f%2E%2e%5cfoo.ftl");
+ testTrusted_checkFails("/lib%5C%.%2e%2Efoo.ftl");
+
+ try {
+ testTrusted_checkFails("lib/./foo.ftl");
+ fail();
+ } catch (AssertionFailedError e) {
+ // Expected
+ }
+ try {
+ testTrusted_checkFails("lib/foo..ftl");
+ fail();
+ } catch (AssertionFailedError e) {
+ // Expected
+ }
+ try {
+ testTrusted_checkFails("lib/%2e/foo.ftl");
+ fail();
+ } catch (AssertionFailedError e) {
+ // Expected
+ }
+ }
+
+ public void testTrusted_checkFails(String templateName) {
+ try {
+ resolver.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate(templateName, "",
+ new TestConfigurationBuilder().build()));
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ }
+
+ public void testSettingParser() throws Exception {
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .setting(
+ "new_builtin_class_resolver",
+ "trusted_templates: foo.ftl, \"lib/*\"")
+ .build();
+
+ TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
+ assertEquals(String.class, res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("foo.ftl", "", cfg)));
+ assertEquals(String.class, res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("lib/bar.ftl", "", cfg)));
+ try {
+ res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("bar.ftl", "", cfg));
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ }
+
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .setting(
+ "new_builtin_class_resolver",
+ "allowed_classes: java.lang.String, java.lang.Integer")
+ .build();
+
+ TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
+ assertEquals(String.class, res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("foo.ftl", "", cfg)));
+ assertEquals(Integer.class, res.resolve("java.lang.Integer", null,
+ Template.createPlainTextTemplate("foo.ftl", "", cfg)));
+ try {
+ res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("foo.ftl", "", cfg));
+ fail();
+ } catch (TemplateException e) {
+ // good
+ }
+ }
+
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .setting(
+ "new_builtin_class_resolver",
+ "trusted_templates: foo.ftl, 'lib/*', allowed_classes: 'java.lang.String',"
+ + " java.lang.Integer")
+ .build();
+ TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
+ assertEquals(String.class, res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg)));
+ assertEquals(Integer.class, res.resolve("java.lang.Integer", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg)));
+ try {
+ res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg));
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ assertEquals(Long.class, res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("foo.ftl", "", cfg)));
+ assertEquals(Long.class, res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("lib/bar.ftl", "", cfg)));
+ try {
+ res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg));
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ }
+
+ try {
+ new TestConfigurationBuilder().setSetting("new_builtin_class_resolver", "wrong: foo");
+ fail();
+ } catch (ConfigurationException e) {
+ // Expected
+ }
+
+ {
+ Configuration cfg = new TestConfigurationBuilder()
+ .setting(
+ "new_builtin_class_resolver",
+ "\"allowed_classes\" : java.lang.String , 'trusted_templates' :\"lib:*\"")
+ .build();
+ TemplateClassResolver res = cfg.getNewBuiltinClassResolver();
+ assertEquals(String.class, res.resolve("java.lang.String", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg)));
+ try {
+ res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("x.ftl", "", cfg));
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+ assertEquals(Long.class, res.resolve("java.lang.Long", null,
+ Template.createPlainTextTemplate("lib:bar.ftl", "", cfg)));
+ }
+ }
+
+}
[10/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
deleted file mode 100644
index e8d5f2b..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PrintfGTemplateNumberFormatFactory.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-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.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.core.valueformat.InvalidFormatParametersException;
-import org.apache.freemarker.core.valueformat.TemplateFormatUtil;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.UnformattableValueException;
-
-/**
- * Formats like {@code %G} in {@code printf}, with the specified number of significant digits. Also has special
- * formatter for HTML output format, where it uses the HTML "sup" element for exponents.
- */
-public class PrintfGTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
-
- public static final PrintfGTemplateNumberFormatFactory INSTANCE = new PrintfGTemplateNumberFormatFactory();
-
- private PrintfGTemplateNumberFormatFactory() {
- // Defined to decrease visibility
- }
-
- @Override
- public TemplateNumberFormat get(String params, Locale locale, Environment env)
- throws InvalidFormatParametersException {
- Integer significantDigits;
- if (!params.isEmpty()) {
- try {
- significantDigits = Integer.valueOf(params);
- } catch (NumberFormatException e) {
- throw new InvalidFormatParametersException(
- "The format parameter must be an integer, but was (shown quoted) "
- + _StringUtil.jQuote(params) + ".");
- }
- } else {
- // Use the default of %G
- significantDigits = null;
- }
- return new PrintfGTemplateNumberFormat(significantDigits, locale);
- }
-
- private static class PrintfGTemplateNumberFormat extends TemplateNumberFormat {
-
- private final Locale locale;
- private final String printfFormat;
-
- private PrintfGTemplateNumberFormat(Integer significantDigits, Locale locale) {
- printfFormat = "%" + (significantDigits != null ? "." + significantDigits : "") + "G";
- this.locale = locale;
- }
-
- @Override
- public String formatToPlainText(TemplateNumberModel numberModel)
- throws UnformattableValueException, TemplateModelException {
- final Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
-
- // printf %G only accepts Double, BigDecimal and Float
- final Number gCompatibleN;
- if (n instanceof Double || n instanceof BigDecimal || n instanceof Float) {
- gCompatibleN = n;
- } else {
- if (n instanceof BigInteger) {
- gCompatibleN = new BigDecimal((BigInteger) n);
- } else if (n instanceof Long) {
- gCompatibleN = BigDecimal.valueOf(n.longValue());
- } else {
- gCompatibleN = Double.valueOf(n.doubleValue());
- }
- }
-
- return String.format(locale, printfFormat, gCompatibleN);
- }
-
- @Override
- public Object format(TemplateNumberModel numberModel)
- throws UnformattableValueException, TemplateModelException {
- String strResult = formatToPlainText(numberModel);
-
- int expIdx = strResult.indexOf('E');
- if (expIdx == -1) {
- return strResult;
- }
-
- String expStr = strResult.substring(expIdx + 1);
- int expSignifNumBegin = 0;
- while (expSignifNumBegin < expStr.length() && isExpSignifNumPrefix(expStr.charAt(expSignifNumBegin))) {
- expSignifNumBegin++;
- }
-
- return HTMLOutputFormat.INSTANCE.fromMarkup(
- strResult.substring(0, expIdx)
- + "*10<sup>"
- + (expStr.charAt(0) == '-' ? "-" : "") + expStr.substring(expSignifNumBegin)
- + "</sup>");
- }
-
- private boolean isExpSignifNumPrefix(char c) {
- return c == '+' || c == '-' || c == '0';
- }
-
- @Override
- public boolean isLocaleBound() {
- return true;
- }
-
- @Override
- public String getDescription() {
- return "printf " + printfFormat;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
deleted file mode 100644
index 5767e93..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicAll.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.core.userpkg;
-
-public class PublicAll {
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java
deleted file mode 100644
index e521d75..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithMixedConstructors.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core.userpkg;
-
-public class PublicWithMixedConstructors {
-
- private final String s;
-
- public PublicWithMixedConstructors(Integer x) {
- s = "Integer";
- }
-
- PublicWithMixedConstructors(int x) {
- s = "int";
- }
-
- public String getS() {
- return s;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
deleted file mode 100644
index 9fdec49..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/PublicWithPackageVisibleConstructor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core.userpkg;
-
-public class PublicWithPackageVisibleConstructor {
-
- PublicWithPackageVisibleConstructor() { }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
deleted file mode 100644
index b8cab13..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/SeldomEscapedOutputFormat.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
-
-public class SeldomEscapedOutputFormat extends CommonMarkupOutputFormat<TemplateSeldomEscapedOutputModel> {
-
- public static final SeldomEscapedOutputFormat INSTANCE = new SeldomEscapedOutputFormat();
-
- private SeldomEscapedOutputFormat() {
- // hide
- }
-
- @Override
- public String getName() {
- return "seldomEscaped";
- }
-
- @Override
- public String getMimeType() {
- return "text/seldomEscaped";
- }
-
- @Override
- public void output(String textToEsc, Writer out) throws IOException, TemplateModelException {
- out.write(escapePlainText(textToEsc));
- }
-
- @Override
- public String escapePlainText(String plainTextContent) {
- return plainTextContent.replaceAll("(\\.|\\\\)", "\\\\$1");
- }
-
- @Override
- public boolean isLegacyBuiltInBypassed(String builtInName) {
- return false;
- }
-
- @Override
- public boolean isAutoEscapedByDefault() {
- return false;
- }
-
- @Override
- protected TemplateSeldomEscapedOutputModel newTemplateMarkupOutputModel(
- String plainTextContent, String markupContent) {
- return new TemplateSeldomEscapedOutputModel(plainTextContent, markupContent);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java
deleted file mode 100644
index c98df53..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateDummyOutputModel.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
-
-public class TemplateDummyOutputModel extends CommonTemplateMarkupOutputModel<TemplateDummyOutputModel> {
-
- TemplateDummyOutputModel(String plainTextContent, String markupContet) {
- super(plainTextContent, markupContet);
- }
-
- @Override
- public DummyOutputFormat getOutputFormat() {
- return DummyOutputFormat.INSTANCE;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java b/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java
deleted file mode 100644
index b0a21f7..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/userpkg/TemplateSeldomEscapedOutputModel.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.core.userpkg;
-
-import org.apache.freemarker.core.outputformat.CommonTemplateMarkupOutputModel;
-
-public class TemplateSeldomEscapedOutputModel extends CommonTemplateMarkupOutputModel<TemplateSeldomEscapedOutputModel> {
-
- TemplateSeldomEscapedOutputModel(String plainTextContent, String markupContet) {
- super(plainTextContent, markupContet);
- }
-
- @Override
- public SeldomEscapedOutputFormat getOutputFormat() {
- return SeldomEscapedOutputFormat.INSTANCE;
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java
deleted file mode 100644
index 0cd8fc0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/util/DateUtilTest.java
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*
- * 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.core.util;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import javax.xml.datatype.DatatypeConfigurationException;
-import javax.xml.datatype.DatatypeFactory;
-import javax.xml.datatype.XMLGregorianCalendar;
-
-import org.apache.freemarker.core.util._DateUtil.CalendarFieldsToDateConverter;
-import org.apache.freemarker.core.util._DateUtil.DateParseException;
-import org.apache.freemarker.core.util._DateUtil.DateToISO8601CalendarFactory;
-import org.apache.freemarker.core.util._DateUtil.TrivialCalendarFieldsToDateConverter;
-
-import junit.framework.TestCase;
-
-public class DateUtilTest extends TestCase {
-
- private final TimeZone originalDefaultTZ = TimeZone.getDefault();
-
- @Override
- protected void setUp() throws Exception {
- TimeZone.setDefault(TimeZone.getTimeZone("Europe/Prague"));
- }
-
- @Override
- protected void tearDown() throws Exception {
- TimeZone.setDefault(originalDefaultTZ);
- }
-
- private final DateFormat df
- = new SimpleDateFormat("G yyyy-MM-dd HH:mm:ss:S Z", Locale.US);
- {
- df.setTimeZone(_DateUtil.UTC);
- }
-
- private CalendarFieldsToDateConverter cf2dc = new TrivialCalendarFieldsToDateConverter();
-
- private DateToISO8601CalendarFactory calendarFactory
- = new _DateUtil.TrivialDateToISO8601CalendarFactory();
-
- public DateUtilTest(String name) {
- super(name);
- }
-
- public void testDateToUTCString() throws ParseException {
- assertEquals(
- "1998-10-30T15:30:00.512Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:512 +0400"), true));
- assertEquals(
- "1998-10-30T15:30:00.5Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:500 +0400"), true));
- assertEquals(
- "1998-10-30T15:30:00.51Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:510 +0400"), true));
- assertEquals(
- "1998-10-30T15:30:00.1Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:100 +0400"), true));
- assertEquals(
- "1998-10-30T15:30:00.01Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:10 +0400"), true));
- assertEquals(
- "1998-10-30T15:30:00.001Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 1998-10-30 19:30:00:1 +0400"), true));
- assertEquals(
- "2000-02-08T06:05:04Z",
- dateToISO8601UTCDateTimeMSString(
- df.parse("AD 2000-02-08 09:05:04:0 +0300"), true));
- assertEquals(
- "0099-02-28T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse(
- "AD 0099-03-02 09:15:24:0 +0300"), true));
- assertEquals(
- "0010-02-28T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse("AD 0010-03-02 09:15:24:0 +0300"), true));
- assertEquals(
- "0001-02-28T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse("AD 0001-03-02 09:15:24:0 +0300"), true));
- assertEquals(
- "0000-02-29T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse("BC 0001-03-02 09:15:24:0 +0300"), true));
- assertEquals(
- "-1-02-28T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse("BC 2-03-02 09:15:24:0 +0300"), true));
- assertEquals(
- "10000-02-28T06:15:24Z",
- dateToISO8601UTCDateTimeString(
- df.parse("AD 10000-02-28 09:15:24:0 +0300"), true));
-
- Date d = df.parse("AD 1998-10-30 19:30:00:512 +0400");
- assertEquals(
- "1998-10-30",
- dateToISO8601UTCDateString(d));
- assertEquals(
- "15:30:00.512Z",
- dateToISO8601UTCTimeMSString(d, true));
- assertEquals(
- "15:30:00.512",
- dateToISO8601UTCTimeMSString(d, false));
- assertEquals(
- "1998-10-30",
- dateToISO8601UTCDateString(
- new java.sql.Date(d.getTime())));
- assertEquals(
- "15:30:00.512Z",
- dateToISO8601UTCTimeMSString(
- new java.sql.Time(d.getTime()), true));
- }
-
- public void testLocalTime() throws ParseException {
- Date dsum = df.parse("AD 2010-05-09 20:00:00:0 UTC");
- Date dwin = df.parse("AD 2010-01-01 20:00:00:0 UTC");
-
- TimeZone tzRome = TimeZone.getTimeZone("Europe/Rome");
- if (tzRome.getOffset(0) == 0) {
- throw new RuntimeException(
- "Can't get time zone for Europe/Rome!");
- }
- assertEquals(
- "2010-05-09T22:00:00+02:00",
- dateToISO8601DateTimeString(dsum, tzRome));
- assertEquals(
- "2010-01-01T21:00:00+01:00",
- dateToISO8601DateTimeString(dwin, tzRome));
- assertEquals(
- "2010-05-09",
- dateToISO8601DateString(dsum, tzRome));
- assertEquals(
- "2010-01-01",
- dateToISO8601DateString(dwin, tzRome));
- assertEquals(
- "22:00:00+02:00",
- dateToISO8601TimeString(dsum, tzRome));
- assertEquals(
- "21:00:00+01:00",
- dateToISO8601TimeString(dwin, tzRome));
-
- TimeZone tzNY = TimeZone.getTimeZone("America/New_York");
- if (tzNY.getOffset(0) == 0) {
- throw new RuntimeException(
- "Can't get time zone for America/New_York!");
- }
- assertEquals(
- "2010-05-09T16:00:00-04:00",
- dateToISO8601DateTimeString(dsum, tzNY));
- assertEquals(
- "2010-01-01T15:00:00-05:00",
- dateToISO8601DateTimeString(dwin, tzNY));
- assertEquals(
- "2010-05-09",
- dateToISO8601DateString(dsum, tzNY));
- assertEquals(
- "2010-01-01",
- dateToISO8601DateString(dwin, tzNY));
- assertEquals(
- "16:00:00-04:00",
- dateToISO8601TimeString(dsum, tzNY));
- assertEquals(
- "15:00:00-05:00",
- dateToISO8601TimeString(dwin, tzNY));
-
- TimeZone tzFixed = TimeZone.getTimeZone("GMT+02:30");
- assertEquals(
- "2010-05-09T22:30:00+02:30",
- dateToISO8601DateTimeString(dsum, tzFixed));
- assertEquals(
- "2010-01-01T22:30:00+02:30",
- dateToISO8601DateTimeString(dwin, tzFixed));
- }
-
- public void testGetTimeZone() throws Exception {
- assertTrue(_DateUtil.getTimeZone("GMT") != _DateUtil.UTC);
- assertTrue(_DateUtil.getTimeZone("UT1") != _DateUtil.UTC);
- assertEquals(_DateUtil.getTimeZone("UTC"), _DateUtil.UTC);
-
- assertEquals(_DateUtil.getTimeZone("Europe/Rome"),
- TimeZone.getTimeZone("Europe/Rome"));
-
- assertEquals(_DateUtil.getTimeZone("Iceland"), // GMT and no DST
- TimeZone.getTimeZone("Iceland"));
-
- try {
- _DateUtil.getTimeZone("Europe/NoSuch");
- fail();
- } catch (UnrecognizedTimeZoneException e) {
- // good
- }
- }
-
- public void testTimeOnlyDate() throws UnrecognizedTimeZoneException {
- Date t = new Date(0L);
- SimpleDateFormat tf = new SimpleDateFormat("HH:mm:ss");
-
- tf.setTimeZone(_DateUtil.UTC);
- assertEquals("00:00:00", tf.format(t));
- assertEquals("00:00:00",
- dateToISO8601UTCTimeString(t, false));
-
- TimeZone gmt1 = _DateUtil.getTimeZone("GMT+01");
- tf.setTimeZone(gmt1);
- assertEquals("01:00:00", tf.format(t));
- assertEquals("01:00:00+01:00",
- dateToISO8601TimeString(t, gmt1));
- }
-
- public void testAccuracy() throws ParseException {
- Date d = df.parse("AD 2000-02-08 09:05:04:250 UTC");
- assertEquals("2000-02-08T09:05:04Z",
- dateToISO8601UTCDateTimeString(d, true));
- assertEquals("2000-02-08T09:05:04.25Z",
- dateToISO8601String(d, true, true, true,
- _DateUtil.ACCURACY_MILLISECONDS, null));
- assertEquals("2000-02-08T09:05:04Z",
- dateToISO8601String(d, true, true, true,
- _DateUtil.ACCURACY_SECONDS, null));
- assertEquals("2000-02-08T09:05Z",
- dateToISO8601String(d, true, true, true,
- _DateUtil.ACCURACY_MINUTES, null));
- assertEquals("2000-02-08T09Z",
- dateToISO8601String(d, true, true, true,
- _DateUtil.ACCURACY_HOURS, null));
-
- d = df.parse("AD 1998-10-30 19:30:00:000 +0400");
- assertEquals(
- "15:30:00Z",
- dateToISO8601UTCTimeMSString(d, true));
- assertEquals(
- "15:30:00.000Z",
- dateToISO8601UTCTimeMSFString(d, true));
- assertEquals(
- "1998-10-30T15:30:00Z",
- dateToISO8601UTCDateTimeMSString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.000Z",
- dateToISO8601UTCDateTimeMSFString(d, true));
-
- d = df.parse("AD 1998-10-30 19:30:00:100 +0400");
- assertEquals(
- "15:30:00.1Z",
- dateToISO8601UTCTimeMSString(d, true));
- assertEquals(
- "15:30:00.100Z",
- dateToISO8601UTCTimeMSFString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.1Z",
- dateToISO8601UTCDateTimeMSString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.100Z",
- dateToISO8601UTCDateTimeMSFString(d, true));
-
- d = df.parse("AD 1998-10-30 19:30:00:010 +0400");
- assertEquals(
- "15:30:00.01Z",
- dateToISO8601UTCTimeMSString(d, true));
- assertEquals(
- "15:30:00.010Z",
- dateToISO8601UTCTimeMSFString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.01Z",
- dateToISO8601UTCDateTimeMSString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.010Z",
- dateToISO8601UTCDateTimeMSFString(d, true));
-
- d = df.parse("AD 1998-10-30 19:30:00:001 +0400");
- assertEquals(
- "15:30:00.001Z",
- dateToISO8601UTCTimeMSString(d, true));
- assertEquals(
- "15:30:00.001Z",
- dateToISO8601UTCTimeMSFString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.001Z",
- dateToISO8601UTCDateTimeMSString(d, true));
- assertEquals(
- "1998-10-30T15:30:00.001Z",
- dateToISO8601UTCDateTimeMSFString(d, true));
- }
-
- public void testXSFormatISODeviations() throws ParseException, UnrecognizedTimeZoneException {
- Date dsum = df.parse("AD 2010-05-09 20:00:00:0 UTC");
- Date dwin = df.parse("AD 2010-01-01 20:00:00:0 UTC");
-
- TimeZone tzRome = _DateUtil.getTimeZone("Europe/Rome");
-
- assertEquals(
- "2010-01-01T21:00:00+01:00",
- _DateUtil.dateToXSString(dwin, true, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
- assertEquals(
- "2010-05-09T22:00:00+02:00",
- _DateUtil.dateToXSString(dsum, true, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
- assertEquals(
- "2010-01-01+01:00", // ISO doesn't allow date-only with TZ
- _DateUtil.dateToXSString(dwin, true, false, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
- assertEquals(
- "2010-05-09+02:00", // ISO doesn't allow date-only with TZ
- _DateUtil.dateToXSString(dsum, true, false, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
- assertEquals(
- "21:00:00+01:00",
- _DateUtil.dateToXSString(dwin, false, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
- assertEquals(
- "22:00:00+02:00",
- _DateUtil.dateToXSString(dsum, false, true, true, _DateUtil.ACCURACY_SECONDS, tzRome, calendarFactory));
-
- assertEquals(
- "-1-02-29T06:15:24Z", // ISO uses 0 for BC 1
- _DateUtil.dateToXSString(
- df.parse("BC 0001-03-02 09:15:24:0 +0300"),
- true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC, calendarFactory));
- assertEquals(
- "-2-02-28T06:15:24Z", // ISO uses -1 for BC 2
- _DateUtil.dateToXSString(
- df.parse("BC 2-03-02 09:15:24:0 +0300"),
- true, true, true, _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC, calendarFactory));
- }
-
- private String dateToISO8601DateTimeString(
- Date date, TimeZone tz) {
- return dateToISO8601String(date, true, true, true,
- _DateUtil.ACCURACY_SECONDS, tz);
- }
-
- private String dateToISO8601UTCDateTimeString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, true, true, offsetPart,
- _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
- }
-
- private String dateToISO8601UTCDateTimeMSString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, true, true, offsetPart,
- _DateUtil.ACCURACY_MILLISECONDS, _DateUtil.UTC);
- }
-
- private String dateToISO8601UTCDateTimeMSFString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, true, true, offsetPart,
- _DateUtil.ACCURACY_MILLISECONDS_FORCED, _DateUtil.UTC);
- }
-
- private String dateToISO8601DateString(Date date, TimeZone tz) {
- return dateToISO8601String(date, true, false, false,
- _DateUtil.ACCURACY_SECONDS, tz);
- }
-
- private String dateToISO8601UTCDateString(Date date) {
- return dateToISO8601String(date, true, false, false,
- _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
- }
-
- private String dateToISO8601TimeString(
- Date date, TimeZone tz) {
- return dateToISO8601String(date, false, true, true,
- _DateUtil.ACCURACY_SECONDS, tz);
- }
-
- private String dateToISO8601UTCTimeString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, false, true, offsetPart,
- _DateUtil.ACCURACY_SECONDS, _DateUtil.UTC);
- }
-
- private String dateToISO8601UTCTimeMSString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, false, true, offsetPart,
- _DateUtil.ACCURACY_MILLISECONDS, _DateUtil.UTC);
- }
-
- private String dateToISO8601UTCTimeMSFString(
- Date date, boolean offsetPart) {
- return dateToISO8601String(date, false, true, offsetPart,
- _DateUtil.ACCURACY_MILLISECONDS_FORCED, _DateUtil.UTC);
- }
-
- private String dateToISO8601String(
- Date date,
- boolean datePart, boolean timePart, boolean offsetPart,
- int accuracy,
- TimeZone timeZone) {
- return _DateUtil.dateToISO8601String(
- date,
- datePart, timePart, offsetPart,
- accuracy,
- timeZone,
- calendarFactory);
- }
-
- public void testParseDate() throws DateParseException {
- assertDateParsing(
- "AD 1998-10-29 20:00:00:0 +0000",
- null,
- "1998-10-30+04:00", _DateUtil.UTC);
- assertDateParsing(
- "AD 1998-10-30 02:00:00:0 +0000",
- null,
- "1998-10-30-02:00", _DateUtil.UTC);
- assertDateParsing(
- "AD 1998-10-30 02:00:00:0 +0000",
- "1998-10-30", _DateUtil.parseXSTimeZone("-02:00"));
- assertDateParsing(
- null,
- "AD 1998-10-30 02:00:00:0 +0000",
- "19981030", _DateUtil.parseXSTimeZone("-02:00"));
- assertDateParsing(
- "AD 1998-10-30 00:00:00:0 +0000",
- null,
- "1998-10-30Z", _DateUtil.UTC);
- assertDateParsing(
- "AD 1998-10-30 00:00:00:0 +0000",
- "1998-10-30", _DateUtil.UTC);
- assertDateParsing(
- null,
- "AD 1998-10-30 00:00:00:0 +0000",
- "19981030", _DateUtil.UTC);
-
- assertDateParsing(
- "AD 1998-10-29 20:00:00:0 +0000",
- null,
- "1998-10-30+04:00", _DateUtil.UTC);
- assertDateParsing(
- "AD 1998-10-30 04:00:00:0 +0000",
- null,
- "1998-10-30-04:00", _DateUtil.UTC);
- assertDateParsing(
- "AD 1998-10-30 00:00:00:0 +0000",
- null,
- "1998-10-30Z", _DateUtil.UTC);
-
- try {
- // XS doesn't have year 0
- assertDateParsing(
- "BC 0000-02-05 00:00:00:0 +0000",
- null,
- "0000-02-03Z", _DateUtil.UTC);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- assertDateParsing(
- null,
- "BC 0001-02-05 00:00:00:0 +0000",
- "0000-02-03", _DateUtil.UTC);
- assertDateParsing(
- null,
- "BC 0001-02-05 00:00:00:0 +0000",
- "00000203", _DateUtil.UTC);
-
- assertDateParsing(
- "BC 0001-02-05 00:00:00:0 +0000", // Julian
- "BC 0002-02-05 00:00:00:0 +0000", // Julian
- "-0001-02-03", _DateUtil.UTC); // Proleptic Gregorian
- assertDateParsing(
- null,
- "BC 0002-02-05 00:00:00:0 +0000", // Julian
- "-00010203", _DateUtil.UTC); // Proleptic Gregorian
-
- assertDateParsing(
- "AD 0001-02-05 00:00:00:0 +0000", // Julian
- null,
- "0001-02-03Z", _DateUtil.UTC); // Proleptic Gregorian
- assertDateParsing(
- "AD 0001-02-05 00:00:00:0 +0000", // Julian
- "0001-02-03", _DateUtil.UTC); // Proleptic Gregorian
- assertDateParsing(
- null,
- "AD 0001-02-05 00:00:00:0 +0000", // Julian
- "00010203", _DateUtil.UTC); // Proleptic Gregorian
- assertDateParsing(
- "AD 1001-12-07 00:00:00:0 +0000", // Julian
- null,
- "1001-12-13Z", _DateUtil.UTC); // Proleptic Gregorian
- assertDateParsing(
- "AD 1001-12-07 00:00:00:0 +0000", // Julian
- "1001-12-13", _DateUtil.UTC); // Proleptic Gregorian
-
- assertDateParsing(
- "AD 2006-12-31 00:00:00:0 +0000",
- null,
- "2006-12-31Z", _DateUtil.UTC);
- assertDateParsing(
- "AD 2006-12-31 00:00:00:0 +0000",
- "2006-12-31", _DateUtil.UTC);
- assertDateParsing(
- "AD 2006-01-01 00:00:00:0 +0000",
- null,
- "2006-01-01Z", _DateUtil.UTC);
- assertDateParsing(
- "AD 2006-01-01 00:00:00:0 +0000",
- "2006-01-01", _DateUtil.UTC);
- assertDateParsing(
- "AD 12006-01-01 00:00:00:0 +0000",
- "12006-01-01", _DateUtil.UTC);
- assertDateParsing(
- null,
- "AD 12006-01-01 00:00:00:0 +0000",
- "120060101", _DateUtil.UTC);
- }
-
- public void testParseDateMalformed() {
- assertDateMalformed("1998-10-30x");
- assertDateMalformed("+1998-10-30");
- assertDateMalformed("1998-10-");
- assertDateMalformed("1998-1-30");
- assertDateMalformed("1998-10-30+01");
- assertDateMalformed("1998-00-01");
- assertDateMalformed("1998-13-01");
- assertDateMalformed("1998-10-00");
- assertDateMalformed("1998-10-32");
- assertDateMalformed("1998-02-31");
-
- assertISO8601DateMalformed("2100103");
- assertISO8601DateMalformed("210-01-03");
- assertISO8601DateMalformed("2012-0301");
- assertISO8601DateMalformed("201203-01");
- assertISO8601DateMalformed("2012-01-01+01:00");
- }
-
- public void testParseTime() throws DateParseException {
- assertTimeParsing(
- "AD 1970-01-01 17:30:05:0 +0000",
- "17:30:05", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 17:30:05:0 +0000",
- "173005", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:100 +0000",
- "07:30:00.1", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:120 +0000",
- "07:30:00.12", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "07:30:00.123", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "07:30:00.1235", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "07:30:00.12346", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 07:30:00:123 +0000",
- "073000.12346", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 07:30:00:123 +0000",
- "073000,12346", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:120 +0000",
- "07:30:00.12", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 07:30:00:500 +0000",
- "07:30:00.5", _DateUtil.UTC);
-
- assertTimeParsing(
- "AD 1970-01-01 16:30:05:0 +0000",
- "17:30:05+01:00", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:30:05:0 +0000",
- "173005+01", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 19:00:05:0 +0000",
- "17:30:05-01:30", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 19:00:05:0 +0000",
- "173005-0130", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-01 16:30:05:500 +0000",
- "17:30:05.5+01:00", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:30:05:500 +0000",
- "173005.5+0100", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:30:05:500 +0000",
- "173005.5+01", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:00:00:0 +0000",
- "170000+01", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:00:00:0 +0000",
- "1700+01", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-01 16:00:00:0 +0000",
- "17+01", _DateUtil.UTC);
-
- assertTimeParsing(
- "AD 1970-01-01 00:00:00:0 +0000",
- "00:00:00", _DateUtil.UTC);
- assertTimeParsing(
- "AD 1970-01-02 00:00:00:0 +0000",
- "24:00:00", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-02 00:00:00:0 +0000",
- "240000", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-02 00:00:00:0 +0000",
- "2400", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-02 00:00:00:0 +0000",
- "24:00", _DateUtil.UTC);
- assertTimeParsing(
- null,
- "AD 1970-01-02 00:00:00:0 +0000",
- "24", _DateUtil.UTC);
-
- assertTimeParsing(
- "AD 1970-01-01 23:59:59:999 +0000",
- "23:59:59.999", _DateUtil.UTC);
- }
-
- public void testParseTimeMalformed() {
- assertTimeMalformed("00:0000");
- assertTimeMalformed("00:00:00-01:60");
- assertTimeMalformed("24:00:01");
- assertTimeMalformed("00:00:61");
- assertTimeMalformed("00:60:00");
- assertTimeMalformed("25:00:00");
- assertTimeMalformed("2:00:00");
- assertTimeMalformed("02:0:00");
- assertTimeMalformed("02:00:0");
-
- assertISO8601TimeMalformed("1010101");
- assertISO8601TimeMalformed("10101");
- assertISO8601TimeMalformed("101");
- assertISO8601TimeMalformed("1");
- assertISO8601TimeMalformed("101010-1");
- assertISO8601TimeMalformed("101010-100");
- assertISO8601TimeMalformed("101010-10000");
- assertISO8601TimeMalformed("101010+1");
- assertISO8601TimeMalformed("101010+100");
- assertISO8601TimeMalformed("101010+10000");
- }
-
- public void testParseDateTime() throws DateParseException {
- assertDateTimeParsing(
- "AD 1998-10-30 11:30:00:0 +0000",
- "1998-10-30T15:30:00+04:00", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 11:30:00:0 +0000",
- "19981030T153000+0400", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 11:30:00:500 +0000",
- "1998-10-30T15:30:00.5+04:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 15:30:00:0 +0000",
- "1998-10-30T15:30:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 15:30:00:0 +0000",
- "19981030T1530Z", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 15:30:00:500 +0000",
- "1998-10-30T15:30:00.5Z", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 11:30:00:0 +0000",
- "1998-10-30T15:30:00+04:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 15:30:00:0 +0000",
- "1998-10-30T15:30:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 15:30:00:0 +0000",
- "1998-10-30T15:30:00", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 15:30:00:0 +0000",
- "1998-10-30T15:30", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1998-10-29 20:00:00:0 +0000",
- "1998-10-30T00:00:00+04:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 02:00:00:0 +0000",
- "1998-10-30T00:00:00-02:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 00:00:00:0 +0000",
- "1998-10-30T00:00:00Z", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1998-10-29 20:00:00:0 +0000",
- "1998-10-30T00:00:00+04:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1998-10-30 00:00:00:0 +0000",
- "1998-10-30T00:00:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 00:00:00:0 +0000",
- "1998-10-30T00:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 00:00:00:0 +0000",
- "1998-10-30T00:00", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 1998-10-30 00:00:00:0 +0000",
- "19981030T00Z", _DateUtil.UTC);
-
- // BC years
- try {
- assertDateTimeParsing(
- "",
- null,
- "0000-02-03T00:00:00Z", _DateUtil.UTC);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- assertDateTimeParsing(
- null,
- "BC 0001-02-05 00:00:00:0 +0000",
- "0000-02-03T00:00:00Z", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "BC 0001-02-05 00:00:00:0 +0000", // Julian
- "BC 0002-02-05 00:00:00:0 +0000", // Julian
- "-0001-02-03T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
-
- assertDateTimeParsing(
- "AD 0001-02-05 00:00:00:0 +0000", // Julian
- "0001-02-03T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
- assertDateTimeParsing(
- "AD 1001-12-07 00:00:00:0 +0000", // Julian
- "1001-12-13T00:00:00Z", _DateUtil.UTC); // Proleptic Gregorian
- assertDateTimeParsing(
- "AD 11001-12-13 00:00:00:0 +0000",
- "11001-12-13T00:00:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- null,
- "AD 11001-12-13 00:00:00:0 +0000",
- "110011213T00Z", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 2006-12-31 00:00:00:0 +0000",
- "2006-12-31T00:00:00Z", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 2006-01-01 00:00:00:0 +0000",
- "2006-01-01T00:00:00Z", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "1970-01-01T07:30:00.123", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "1970-01-01T07:30:00.1235", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-01 07:30:00:123 +0000",
- "1970-01-01T07:30:00.12346", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-01 07:30:00:120 +0000",
- "1970-01-01T07:30:00.12", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-01 07:30:00:500 +0000",
- "1970-01-01T07:30:00.5", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1970-01-01 16:30:05:0 +0000",
- "1970-01-01T17:30:05+01:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-01 16:30:05:500 +0000",
- "1970-01-01T17:30:05.5+01:00", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1970-01-01 00:00:00:0 +0000",
- "1970-01-01T00:00:00", _DateUtil.UTC);
- assertDateTimeParsing(
- "AD 1970-01-02 00:00:00:0 +0000",
- "1970-01-01T24:00:00", _DateUtil.UTC);
-
- assertDateTimeParsing(
- "AD 1970-01-01 23:59:59:999 +0000",
- "1970-01-01T23:59:59.999", _DateUtil.UTC);
- }
-
- public void testParseDateTimeMalformed() throws DateParseException {
- assertDateTimeMalformed("1998-00-01T00:00:00");
- assertDateTimeMalformed("1998-13-01T00:00:00");
- assertDateTimeMalformed("1998-10-00T00:00:00");
- assertDateTimeMalformed("1998-10-32T00:00:00");
- assertDateTimeMalformed("1998-02-31T00:00:00");
- assertDateTimeMalformed("1970-01-02T24:00:01");
- assertDateTimeMalformed("1970-01-01T00:00:61");
- assertDateTimeMalformed("1970-01-01T00:60:00");
- assertDateTimeMalformed("1970-01-01T25:00:00");
-
- assertISO8601DateTimeMalformed("197-01-01T20:00:00");
- }
-
- public void testParseXSTimeZone() throws DateParseException {
- assertEquals(0,
- _DateUtil.parseXSTimeZone("Z").getOffset(0));
- assertEquals(0,
- _DateUtil.parseXSTimeZone("-00:00").getOffset(0));
- assertEquals(0,
- _DateUtil.parseXSTimeZone("+00:00").getOffset(0));
- assertEquals(90 * 60 * 1000,
- _DateUtil.parseXSTimeZone("+01:30").getOffset(0));
- assertEquals(-4 * 60 * 60 * 1000,
- _DateUtil.parseXSTimeZone("-04:00").getOffset(0));
- assertEquals(((-23 * 60) - 59) * 60 * 1000,
- _DateUtil.parseXSTimeZone("-23:59").getOffset(0));
- assertEquals(((23 * 60) + 59) * 60 * 1000,
- _DateUtil.parseXSTimeZone("+23:59").getOffset(0));
- }
-
- public void testParseXSTimeZoneWrong() {
- try {
- _DateUtil.parseXSTimeZone("04:00").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- try {
- _DateUtil.parseXSTimeZone("-04:00x").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- try {
- _DateUtil.parseXSTimeZone("-04").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- try {
- _DateUtil.parseXSTimeZone("+24:00").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- try {
- _DateUtil.parseXSTimeZone("-24:00").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- try {
- _DateUtil.parseXSTimeZone("-01:60").getOffset(0);
- fail();
- } catch (DateParseException e) {
- echo(e);
- }
- }
-
- public void testParseXSDateTimeFTLAndJavax() throws DateParseException {
- // Explicit time zone:
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08Z");
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08+02:00");
-
- // Default time zone:
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T13:35:08"); // winter
- assertJavaxAndFTLXSDateTimesSame("2014-07-01T13:35:08"); // summer
-
- // Proleptic Gregorian
- assertJavaxAndFTLXSDateTimesSame("1500-01-01T13:35:08Z");
- assertJavaxAndFTLXSDateTimesSame("0200-01-01T13:35:08Z");
- assertJavaxAndFTLXSDateTimesSame("0001-01-01T00:00:00+05:00");
-
- // BC
- assertJavaxAndFTLXSDateTimesSame("0001-01-01T13:35:08Z");
- assertJavaxAndFTLXSDateTimesSame("-0001-01-01T13:35:08Z");
-
- // Hour 24
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59");
- if (isAtLeastJava6()) { // Java 5 has broken parser that doesn't allow 24.
- assertJavaxAndFTLXSDateTimesSame("2014-01-31T24:00:00");
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T24:00:00");
- }
- assertJavaxAndFTLXSDateTimesSame("2014-01-02T00:00:00"); // same as the previous
- assertJavaxAndFTLXSDateTimesSame("2014-02-01T00:00:00"); // same as the previous
-
- // Under ms
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59.123456789");
- assertJavaxAndFTLXSDateTimesSame("2014-01-01T23:59:59.1235");
- }
-
- private boolean isAtLeastJava6() {
- try {
- Class.forName("java.lang.management.LockInfo");
- } catch (ClassNotFoundException e) {
- return false;
- }
- return true;
- }
-
- private final DatatypeFactory datetypeFactory;
- {
- try {
- datetypeFactory = DatatypeFactory.newInstance();
- } catch (DatatypeConfigurationException e) {
- throw new RuntimeException(e);
- }
- }
-
- private void assertJavaxAndFTLXSDateTimesSame(String s) throws DateParseException {
- XMLGregorianCalendar xgc = datetypeFactory.newXMLGregorianCalendar(s);
- Date javaxDate = xgc.toGregorianCalendar().getTime();
- Date ftlDate = _DateUtil.parseXSDateTime(s, TimeZone.getDefault(), cf2dc);
- assertEquals(javaxDate, ftlDate);
- }
-
- private void assertDateParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
- assertDateParsing(expected, expected, parsed, tz);
- }
-
- private void assertDateParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
- throws DateParseException {
- if (expectedXS != null) {
- assertEquals(
- expectedXS,
- df.format(_DateUtil.parseXSDate(parsed, tz, cf2dc)));
- }
- if (expectedISO8601 != null) {
- assertEquals(
- expectedISO8601,
- df.format(_DateUtil.parseISO8601Date(parsed, tz, cf2dc)));
- }
- }
-
- private void assertDateTimeParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
- assertDateTimeParsing(expected, expected, parsed, tz);
- }
-
- private void assertDateTimeParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
- throws DateParseException {
- if (expectedXS != null) {
- assertEquals(
- expectedXS,
- df.format(_DateUtil.parseXSDateTime(parsed, tz, cf2dc)));
- }
- if (expectedISO8601 != null) {
- assertEquals(
- expectedISO8601,
- df.format(_DateUtil.parseISO8601DateTime(parsed, tz, cf2dc)));
- }
- }
-
- private void assertTimeParsing(String expected, String parsed, TimeZone tz) throws DateParseException {
- assertTimeParsing(expected, expected, parsed, tz);
- }
-
- private void assertTimeParsing(String expectedXS, String expectedISO8601, String parsed, TimeZone tz)
- throws DateParseException {
- if (expectedXS != null) {
- assertEquals(
- expectedXS,
- df.format(_DateUtil.parseXSTime(parsed, tz, cf2dc)));
- }
- if (expectedISO8601 != null) {
- assertEquals(
- expectedISO8601,
- df.format(_DateUtil.parseISO8601Time(parsed, tz, cf2dc)));
- }
- }
-
- private void assertDateMalformed(String parsed) {
- try {
- _DateUtil.parseXSDate(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- try {
- _DateUtil.parseISO8601Date(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void assertTimeMalformed(String parsed) {
- try {
- _DateUtil.parseXSTime(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- try {
- _DateUtil.parseISO8601Time(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void assertDateTimeMalformed(String parsed) {
- try {
- _DateUtil.parseXSDateTime(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- try {
- _DateUtil.parseISO8601DateTime(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void assertISO8601DateMalformed(String parsed) {
- try {
- _DateUtil.parseISO8601Date(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void assertISO8601TimeMalformed(String parsed) {
- try {
- _DateUtil.parseISO8601Time(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void assertISO8601DateTimeMalformed(String parsed) {
- try {
- _DateUtil.parseISO8601DateTime(parsed, _DateUtil.UTC, cf2dc);
- fail();
- } catch (DateParseException e) {
- // Expected
- echo(e);
- }
- }
-
- private void echo(@SuppressWarnings("unused") DateParseException e) {
- // System.out.println(e);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java
deleted file mode 100644
index f1e44f3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.core.util;
-
-import static junit.framework.TestCase.assertFalse;
-import static junit.framework.TestCase.assertNull;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class FTLUtilTest {
-
- @Test
- public void testEscapeStringLiteralPart() {
- assertEquals("", FTLUtil.escapeStringLiteralPart(""));
- assertEquals("abc", FTLUtil.escapeStringLiteralPart("abc"));
- assertEquals("{", FTLUtil.escapeStringLiteralPart("{"));
- assertEquals("a{b}c", FTLUtil.escapeStringLiteralPart("a{b}c"));
- assertEquals("a#b", FTLUtil.escapeStringLiteralPart("a#b"));
- assertEquals("a$b", FTLUtil.escapeStringLiteralPart("a$b"));
- assertEquals("a#\\{b}c", FTLUtil.escapeStringLiteralPart("a#{b}c"));
- assertEquals("a$\\{b}c", FTLUtil.escapeStringLiteralPart("a${b}c"));
- assertEquals("a'c\\\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '"'));
- assertEquals("a\\'c\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '\''));
- assertEquals("a\\'c\"d", FTLUtil.escapeStringLiteralPart("a'c\"d", '\''));
- assertEquals("\\n\\r\\t\\f\\x0002\\\\", FTLUtil.escapeStringLiteralPart("\n\r\t\f\u0002\\"));
- assertEquals("\\l\\g\\a", FTLUtil.escapeStringLiteralPart("<>&"));
- }
-
- @Test
- public void testEscapeStringLiteralAll() {
- assertFTLEsc("", "", "", "", "\"\"");
- assertFTLEsc("\'", "\\'", "'", "\\'", "\"'\"");
- assertFTLEsc("\"", "\\\"", "\\\"", "\"", "'\"'");
- assertFTLEsc("\"", "\\\"", "\\\"", "\"", "'\"'");
- assertFTLEsc("foo", "foo", "foo", "foo", "\"foo\"");
- assertFTLEsc("foo's", "foo\\'s", "foo's", "foo\\'s", "\"foo's\"");
- assertFTLEsc("foo \"", "foo \\\"", "foo \\\"", "foo \"", "'foo \"'");
- assertFTLEsc("foo's \"", "foo\\'s \\\"", "foo's \\\"", "foo\\'s \"", "\"foo's \\\"\"");
- assertFTLEsc("foo\nb\u0000c", "foo\\nb\\x0000c", "foo\\nb\\x0000c", "foo\\nb\\x0000c", "\"foo\\nb\\x0000c\"");
- }
-
- private void assertFTLEsc(String s, String partAny, String partQuot, String partApos, String quoted) {
- assertEquals(partAny, FTLUtil.escapeStringLiteralPart(s));
- assertEquals(partQuot, FTLUtil.escapeStringLiteralPart(s, '\"'));
- assertEquals(partApos, FTLUtil.escapeStringLiteralPart(s, '\''));
- assertEquals(quoted, FTLUtil.toStringLiteral(s));
- }
-
- @Test
- public void testUnescapeStringLiteralPart() throws Exception {
- assertEquals("", FTLUtil.unescapeStringLiteralPart(""));
- assertEquals("1", FTLUtil.unescapeStringLiteralPart("1"));
- assertEquals("123", FTLUtil.unescapeStringLiteralPart("123"));
- assertEquals("1&2&3", FTLUtil.unescapeStringLiteralPart("1\\a2\\a3"));
- assertEquals("&", FTLUtil.unescapeStringLiteralPart("\\a"));
- assertEquals("&&&", FTLUtil.unescapeStringLiteralPart("\\a\\a\\a"));
- assertEquals(
- "\u0000\u0000&\u0000\u0000\u0000\u0000",
- FTLUtil.unescapeStringLiteralPart("\\x0000\\x0000\\a\\x0000\\x000\\x00\\x0"));
- assertEquals(
- "'\"\n\b\u0000c><&{\\",
- FTLUtil.unescapeStringLiteralPart("\\'\\\"\\n\\b\\x0000c\\g\\l\\a\\{\\\\"));
- }
-
- @Test
- public void testEscapeIdentifier() {
- assertNull(FTLUtil.escapeIdentifier(null));
- assertEquals("", FTLUtil.escapeIdentifier(""));
- assertEquals("a", FTLUtil.escapeIdentifier("a"));
- assertEquals("ab", FTLUtil.escapeIdentifier("ab"));
- assertEquals("\\.", FTLUtil.escapeIdentifier("."));
- assertEquals("\\.\\:\\-", FTLUtil.escapeIdentifier(".:-"));
- assertEquals("a\\.b", FTLUtil.escapeIdentifier("a.b"));
- assertEquals("a\\.b\\:c\\-d", FTLUtil.escapeIdentifier("a.b:c-d"));
- }
-
- @Test
- public void testIsNonEscapedIdentifierStart() {
- assertTrue(FTLUtil.isNonEscapedIdentifierPart('a'));
- assertTrue(FTLUtil.isNonEscapedIdentifierPart('á'));
- assertTrue(FTLUtil.isNonEscapedIdentifierPart('1'));
- assertFalse(FTLUtil.isNonEscapedIdentifierPart('-'));
- assertFalse(FTLUtil.isNonEscapedIdentifierPart(' '));
- assertFalse(FTLUtil.isNonEscapedIdentifierPart('\u0000'));
- assertFalse(FTLUtil.isNonEscapedIdentifierPart('\\'));
- }
-
- @Test
- public void testisNonEscapedIdentifierStart() {
- assertTrue(FTLUtil.isNonEscapedIdentifierStart('a'));
- assertTrue(FTLUtil.isNonEscapedIdentifierStart('á'));
- assertFalse(FTLUtil.isNonEscapedIdentifierStart('1'));
- assertFalse(FTLUtil.isNonEscapedIdentifierStart('-'));
- assertFalse(FTLUtil.isNonEscapedIdentifierStart(' '));
- assertFalse(FTLUtil.isNonEscapedIdentifierStart('\u0000'));
- assertFalse(FTLUtil.isNonEscapedIdentifierStart('\\'));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
deleted file mode 100644
index d5709da..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/util/NumberUtilTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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.core.util;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import org.junit.Test;
-
-import junit.framework.TestCase;
-
-public class NumberUtilTest extends TestCase {
-
- @Test
- public void testGetSignum() {
- assertEquals(1, _NumberUtil.getSignum(Double.valueOf(Double.POSITIVE_INFINITY)));
- assertEquals(1, _NumberUtil.getSignum(Double.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(Double.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(Double.valueOf(-3)));
- assertEquals(-1, _NumberUtil.getSignum(Double.valueOf(Double.NEGATIVE_INFINITY)));
- try {
- _NumberUtil.getSignum(Double.valueOf(Double.NaN));
- fail();
- } catch (ArithmeticException e) {
- // expected
- }
-
- assertEquals(1, _NumberUtil.getSignum(Float.valueOf(Float.POSITIVE_INFINITY)));
- assertEquals(1, _NumberUtil.getSignum(Float.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(Float.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(Float.valueOf(-3)));
- assertEquals(-1, _NumberUtil.getSignum(Float.valueOf(Float.NEGATIVE_INFINITY)));
- try {
- _NumberUtil.getSignum(Float.valueOf(Float.NaN));
- fail();
- } catch (ArithmeticException e) {
- // expected
- }
-
- assertEquals(1, _NumberUtil.getSignum(Long.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(Long.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(Long.valueOf(-3)));
-
- assertEquals(1, _NumberUtil.getSignum(Integer.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(Integer.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(Integer.valueOf(-3)));
-
- assertEquals(1, _NumberUtil.getSignum(Short.valueOf((short) 3)));
- assertEquals(0, _NumberUtil.getSignum(Short.valueOf((short) 0)));
- assertEquals(-1, _NumberUtil.getSignum(Short.valueOf((short) -3)));
-
- assertEquals(1, _NumberUtil.getSignum(Byte.valueOf((byte) 3)));
- assertEquals(0, _NumberUtil.getSignum(Byte.valueOf((byte) 0)));
- assertEquals(-1, _NumberUtil.getSignum(Byte.valueOf((byte) -3)));
-
- assertEquals(1, _NumberUtil.getSignum(BigDecimal.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(BigDecimal.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(BigDecimal.valueOf(-3)));
-
- assertEquals(1, _NumberUtil.getSignum(BigInteger.valueOf(3)));
- assertEquals(0, _NumberUtil.getSignum(BigInteger.valueOf(0)));
- assertEquals(-1, _NumberUtil.getSignum(BigInteger.valueOf(-3)));
- }
-
- @Test
- public void testIsBigDecimalInteger() {
- BigDecimal n1 = new BigDecimal("1.125");
- if (n1.precision() != 4 || n1.scale() != 3) {
- throw new RuntimeException("Wrong: " + n1);
- }
- BigDecimal n2 = new BigDecimal("1.125").subtract(new BigDecimal("0.005"));
- if (n2.precision() != 4 || n2.scale() != 3) {
- throw new RuntimeException("Wrong: " + n2);
- }
- BigDecimal n3 = new BigDecimal("123");
- BigDecimal n4 = new BigDecimal("6000");
- BigDecimal n5 = new BigDecimal("1.12345").subtract(new BigDecimal("0.12345"));
- if (n5.precision() != 6 || n5.scale() != 5) {
- throw new RuntimeException("Wrong: " + n5);
- }
- BigDecimal n6 = new BigDecimal("0");
- BigDecimal n7 = new BigDecimal("0.001").subtract(new BigDecimal("0.001"));
- BigDecimal n8 = new BigDecimal("60000.5").subtract(new BigDecimal("0.5"));
- BigDecimal n9 = new BigDecimal("6").movePointRight(3).setScale(-3);
-
- BigDecimal[] ns = new BigDecimal[] {
- n1, n2, n3, n4, n5, n6, n7, n8, n9,
- n1.negate(), n2.negate(), n3.negate(), n4.negate(), n5.negate(), n6.negate(), n7.negate(), n8.negate(),
- n9.negate(),
- };
-
- for (BigDecimal n : ns) {
- assertEquals(n.doubleValue() == n.longValue(), _NumberUtil.isIntegerBigDecimal(n));
- }
-
- }
-
- @Test
- public void testToIntExcact() {
- for (int n : new int[] { Integer.MIN_VALUE, Byte.MIN_VALUE, -1, 0, 1, Byte.MAX_VALUE, Integer.MAX_VALUE }) {
- if (n != Integer.MIN_VALUE && n != Integer.MAX_VALUE) {
- assertEquals(n, _NumberUtil.toIntExact(Byte.valueOf((byte) n)));
- assertEquals(n, _NumberUtil.toIntExact(Short.valueOf((short) n)));
- assertEquals(n, _NumberUtil.toIntExact(Float.valueOf(n)));
- }
- assertEquals(n, _NumberUtil.toIntExact(Integer.valueOf(n)));
- assertEquals(n, _NumberUtil.toIntExact(Long.valueOf(n)));
- assertEquals(n, _NumberUtil.toIntExact(Double.valueOf(n)));
- assertEquals(n, _NumberUtil.toIntExact(BigDecimal.valueOf(n)));
- assertEquals(n, _NumberUtil.toIntExact(BigDecimal.valueOf(n * 10L).divide(BigDecimal.TEN)));
- assertEquals(n, _NumberUtil.toIntExact(BigInteger.valueOf(n)));
- }
-
- try {
- _NumberUtil.toIntExact(Long.valueOf(Integer.MIN_VALUE - 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(Long.valueOf(Integer.MAX_VALUE + 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
-
- try {
- _NumberUtil.toIntExact(Float.valueOf(1.00001f));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(Float.valueOf(Integer.MIN_VALUE - 129L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(Float.valueOf(Integer.MAX_VALUE));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
-
- try {
- _NumberUtil.toIntExact(Double.valueOf(1.00001));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(Double.valueOf(Integer.MIN_VALUE - 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(Double.valueOf(Integer.MAX_VALUE + 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
-
- try {
- _NumberUtil.toIntExact(new BigDecimal("100.000001"));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(BigDecimal.valueOf(Integer.MIN_VALUE - 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(BigDecimal.valueOf(Integer.MAX_VALUE + 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
-
- try {
- _NumberUtil.toIntExact(BigInteger.valueOf(Integer.MIN_VALUE - 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- try {
- _NumberUtil.toIntExact(BigInteger.valueOf(Integer.MAX_VALUE + 1L));
- fail();
- } catch (ArithmeticException e) {
- // Expected
- }
- }
-
-}
[15/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
deleted file mode 100644
index ef15dae..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-
-import junit.framework.TestCase;
-
-public class CommonSupertypeForUnwrappingHintTest extends TestCase {
-
- final OverloadedMethodsSubset oms = new DummyOverloadedMethodsSubset();
-
- public CommonSupertypeForUnwrappingHintTest(String name) {
- super(name);
- }
-
- public void testInterfaces() {
- assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(String.class, Number.class));
- assertEquals(C1I1.class, oms.getCommonSupertypeForUnwrappingHint(C2ExtC1I1.class, C3ExtC1I1.class));
- assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, C4I1I2.class));
- assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, C5I1.class));
- assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, I1.class));
- assertEquals(I2.class, oms.getCommonSupertypeForUnwrappingHint(C3I1I2.class, I2.class));
- assertEquals(I1.class, oms.getCommonSupertypeForUnwrappingHint(I1I2.class, I1.class));
- assertEquals(I2.class, oms.getCommonSupertypeForUnwrappingHint(I1I2.class, I2.class));
- assertEquals(CharSequence.class, oms.getCommonSupertypeForUnwrappingHint(String.class, StringBuilder.class));
- assertEquals(C6.class, oms.getCommonSupertypeForUnwrappingHint(C7ExtC6I1.class, C8ExtC6I1.class));
- }
-
- public void testArrayAndOther() {
- testArrayAndOther(oms);
- }
-
- /** These will be the same with oms and buggy: */
- private void testArrayAndOther(OverloadedMethodsSubset oms) {
- assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, String.class));
- assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, String.class));
-
- assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, List.class));
- assertEquals(Object.class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, List.class));
-
- assertEquals(int[].class, oms.getCommonSupertypeForUnwrappingHint(int[].class, int[].class));
- assertEquals(Object[].class, oms.getCommonSupertypeForUnwrappingHint(Object[].class, Object[].class));
- }
-
- public void testArrayAndDifferentArray() {
- assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, Object[].class));
- assertEquals(Serializable.class, oms.getCommonSupertypeForUnwrappingHint(int[].class, long[].class));
- }
-
- public void testPrimitive() {
- assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(int.class, Integer.class));
- assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, int.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(int.class, Long.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Long.class, int.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, long.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(long.class, Integer.class));
- assertEquals(Boolean.class, oms.getCommonSupertypeForUnwrappingHint(boolean.class, Boolean.class));
- assertEquals(Boolean.class, oms.getCommonSupertypeForUnwrappingHint(Boolean.class, boolean.class));
- assertEquals(Character.class, oms.getCommonSupertypeForUnwrappingHint(char.class, Character.class));
- assertEquals(Character.class, oms.getCommonSupertypeForUnwrappingHint(Character.class, char.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(int.class, short.class));
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(short.class, int.class));
- }
-
- public void testMisc() {
- assertEquals(Number.class, oms.getCommonSupertypeForUnwrappingHint(Long.class, Integer.class));
- assertEquals(char.class, oms.getCommonSupertypeForUnwrappingHint(char.class, char.class));
- assertEquals(Integer.class, oms.getCommonSupertypeForUnwrappingHint(Integer.class, Integer.class));
- assertEquals(String.class, oms.getCommonSupertypeForUnwrappingHint(String.class, String.class));
- }
-
- static interface I1 { };
- static class C1I1 implements I1 { };
- static class C2ExtC1I1 extends C1I1 { };
- static class C3ExtC1I1 extends C1I1 { };
- static interface I2 { };
- static class C3I1I2 implements I1, I2 { };
- static class C4I1I2 implements I1, I2 { };
- static class C5I1 implements I1 { };
- static interface I1I2 extends I1, I2 { };
- static class C6 { };
- static class C7ExtC6I1 extends C6 implements I1 { };
- static class C8ExtC6I1 extends C6 implements I1 { };
-
- private static class DummyOverloadedMethodsSubset extends OverloadedMethodsSubset {
-
- DummyOverloadedMethodsSubset() {
- super();
- }
-
- @Override
- Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
- return memberDesc.getParamTypes();
- }
-
- @Override
- void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) {
- // Do nothing
- }
-
- @Override
- MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, DefaultObjectWrapper w) throws TemplateModelException {
- throw new RuntimeException("Not implemented in this dummy.");
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
deleted file mode 100644
index 0ed6e7c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperDesc.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.Configuration;
-
-public class DefaultObjectWrapperDesc extends DefaultObjectWrapper {
-
- public DefaultObjectWrapperDesc() {
- super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .methodSorter(new AlphabeticalMethodSorter(true)), true);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
deleted file mode 100644
index eb2cda0..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperInc.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.Configuration;
-
-public class DefaultObjectWrapperInc extends DefaultObjectWrapper {
-
- public DefaultObjectWrapperInc() {
- super(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .methodSorter(new AlphabeticalMethodSorter(false)), true);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
deleted file mode 100644
index 5c2f653..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperModelFactoryRegistrationTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import java.lang.ref.Reference;
-
-import org.apache.freemarker.core.Configuration;
-import org.junit.Test;
-
-public class DefaultObjectWrapperModelFactoryRegistrationTest {
-
- @Test
- public void introspectionSettingChanges() {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
- .build();
- ClassIntrospector ci1 = ow.getClassIntrospector();
- checkRegisteredModelFactories(ci1, ow.getStaticModels(), ow.getEnumModels());
- }
-
- private void checkRegisteredModelFactories(ClassIntrospector ci, Object... expected) {
- Object[] actualRefs = ci.getRegisteredModelFactoriesSnapshot();
-
- scanActuals: for (Object actaulRef : actualRefs) {
- Object actualItem = ((Reference) actaulRef).get();
- for (Object expectedItem : expected) {
- if (actualItem == expectedItem) {
- continue scanActuals;
- }
- }
- fail("Actual item " + actualItem + " is not among the expected items");
- }
-
- scanExpecteds: for (Object expectedItem : expected) {
- for (Object ref : actualRefs) {
- Object actualItem = ((Reference) ref).get();
- if (actualItem == expectedItem) {
- continue scanExpecteds;
- }
- }
- fail("Expected item " + expectedItem + " is not among the actual items");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
deleted file mode 100644
index 767b640..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperSingletonsTest.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.lang.ref.Reference;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Version;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.test.util.CoreTestUtil;
-
-import junit.framework.TestCase;
-
-public class DefaultObjectWrapperSingletonsTest extends TestCase {
-
- public DefaultObjectWrapperSingletonsTest(String name) {
- super(name);
- }
-
- @Override
- protected void setUp() throws Exception {
- DefaultObjectWrapper.Builder.clearInstanceCache();
- }
-
- public void testBuilderEqualsAndHash() throws Exception {
- assertEquals(Configuration.VERSION_3_0_0, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).getIncompatibleImprovements());
- try {
- new DefaultObjectWrapper.Builder(CoreTestUtil.getClosestFutureVersion());
- fail("Maybe you need to update this test for the new FreeMarker version");
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("upgrade"));
- }
-
- DefaultObjectWrapper.Builder builder1;
- DefaultObjectWrapper.Builder builder2;
-
- builder1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- assertEquals(builder1, builder2);
-
- builder1.setExposeFields(true);
- assertNotEquals(builder1, builder2);
- assertNotEquals(builder1.hashCode(), builder2.hashCode());
- builder2.setExposeFields(true);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- builder1.setExposureLevel(0);
- assertNotEquals(builder1, builder2);
- assertNotEquals(builder1.hashCode(), builder2.hashCode());
- builder2.setExposureLevel(0);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- builder1.setExposureLevel(1);
- assertNotEquals(builder1, builder2);
- assertNotEquals(builder1.hashCode(), builder2.hashCode());
- builder2.setExposureLevel(1);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- builder1.setDefaultDateType(TemplateDateModel.DATE);
- assertNotEquals(builder1, builder2);
- builder2.setDefaultDateType(TemplateDateModel.DATE);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- builder1.setStrict(true);
- assertNotEquals(builder1, builder2);
- assertNotEquals(builder1.hashCode(), builder2.hashCode());
- builder2.setStrict(true);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- builder1.setUseModelCache(true);
- assertNotEquals(builder1, builder2);
- assertNotEquals(builder1.hashCode(), builder2.hashCode());
- builder2.setUseModelCache(true);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- AlphabeticalMethodSorter ms = new AlphabeticalMethodSorter(true);
- builder1.setMethodSorter(ms);
- assertNotEquals(builder1, builder2);
- builder2.setMethodSorter(ms);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
-
- MethodAppearanceFineTuner maft = new MethodAppearanceFineTuner() {
- @Override
- public void process(DecisionInput in, Decision out) { }
- };
- builder1.setMethodAppearanceFineTuner(maft);
- assertNotEquals(builder1, builder2);
- builder2.setMethodAppearanceFineTuner(maft);
- assertEquals(builder1, builder2);
- assertEquals(builder1.hashCode(), builder2.hashCode());
- }
-
- public void testDefaultObjectWrapperBuilderProducts() throws Exception {
- List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
-
- assertEquals(0, getDefaultObjectWrapperInstanceCacheSize());
-
- {
- DefaultObjectWrapper ow = getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, true);
- assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
- assertSame(ow.getClass(), DefaultObjectWrapper.class);
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- assertFalse(ow.isStrict());
- assertTrue(ow.getUseModelCache());
- assertEquals(TemplateDateModel.UNKNOWN, ow.getDefaultDateType());
- assertSame(ow, ow.getOuterIdentity());
- assertTrue(ow.isClassIntrospectionCacheRestricted());
- assertNull(ow.getMethodAppearanceFineTuner());
- assertNull(ow.getMethodSorter());
-
- assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, true));
- assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
-
- hardReferences.add(ow);
- }
-
- {
- DefaultObjectWrapper ow = getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, false);
- assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
- assertSame(ow.getClass(), DefaultObjectWrapper.class);
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- assertFalse(ow.getUseModelCache());
-
- assertSame(ow, getDefaultObjectWrapperWithSetting(Configuration.VERSION_3_0_0, false));
-
- hardReferences.add(ow);
- }
-
- {
- DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- factory.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
- DefaultObjectWrapper ow1 = factory.build();
- DefaultObjectWrapper ow2 = factory.build();
- assertEquals(3, getDefaultObjectWrapperInstanceCacheSize());
- assertSame(ow1, ow2);
-
- assertSame(ow1.getClass(), DefaultObjectWrapper.class);
- assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
- assertEquals(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY, ow1.getExposureLevel());
- assertFalse(ow1.isStrict());
- assertEquals(TemplateDateModel.UNKNOWN, ow1.getDefaultDateType());
- assertSame(ow1, ow1.getOuterIdentity());
-
- hardReferences.add(ow1);
- }
-
- {
- DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- factory.setExposeFields(true);
- DefaultObjectWrapper ow1 = factory.build();
- DefaultObjectWrapper ow2 = factory.build();
- assertEquals(4, getDefaultObjectWrapperInstanceCacheSize());
- assertSame(ow1, ow2);
-
- assertSame(ow1.getClass(), DefaultObjectWrapper.class);
- assertEquals(Configuration.VERSION_3_0_0, ow1.getIncompatibleImprovements());
- assertTrue(ow1.isExposeFields());
-
- hardReferences.add(ow1);
- }
-
- {
- DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- factory.setStrict(true);
- factory.setDefaultDateType(TemplateDateModel.DATETIME);
- factory.setOuterIdentity(new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- DefaultObjectWrapper ow = factory.build();
- assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
- assertTrue(ow.isStrict());
- assertEquals(TemplateDateModel.DATETIME, ow.getDefaultDateType());
- assertSame(RestrictedObjectWrapper.class, ow.getOuterIdentity().getClass());
-
- hardReferences.add(ow);
- }
-
- // Effect of reference and cache clearings:
- {
- DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
- assertEquals(5, getDefaultObjectWrapperNonClearedInstanceCacheSize());
-
- clearDefaultObjectWrapperInstanceCacheReferences(false);
- assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
- assertEquals(0, getDefaultObjectWrapperNonClearedInstanceCacheSize());
-
- DefaultObjectWrapper bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertNotSame(bw1, bw2);
- assertEquals(5, getDefaultObjectWrapperInstanceCacheSize());
- assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
-
- assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
-
- clearDefaultObjectWrapperInstanceCacheReferences(true);
- DefaultObjectWrapper bw3 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertNotSame(bw2, bw3);
- assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
- assertEquals(1, getDefaultObjectWrapperNonClearedInstanceCacheSize());
- }
-
- {
- DefaultObjectWrapper.Builder factory = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- factory.setUseModelCache(true);
- DefaultObjectWrapper ow = factory.build();
- assertTrue(ow.getUseModelCache());
- assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
-
- hardReferences.add(ow);
- }
-
- assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
- }
-
- private DefaultObjectWrapper getDefaultObjectWrapperWithSetting(Version ici, boolean useModelCache) {
- DefaultObjectWrapper.Builder f = new DefaultObjectWrapper.Builder(ici);
- f.setUseModelCache(useModelCache);
- return f.build();
- }
-
- public void testMultipleTCCLs() {
- List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
-
- assertEquals(0, getDefaultObjectWrapperInstanceCacheSize());
-
- DefaultObjectWrapper bw1 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertEquals(1, getDefaultObjectWrapperInstanceCacheSize());
- hardReferences.add(bw1);
-
- ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader();
- // Doesn't mater what, just be different from oldTCCL:
- ClassLoader newTCCL = oldTCCL == null ? getClass().getClassLoader() : null;
-
- DefaultObjectWrapper bw2;
- Thread.currentThread().setContextClassLoader(newTCCL);
- try {
- bw2 = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
- hardReferences.add(bw2);
-
- assertNotSame(bw1, bw2);
- assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- } finally {
- Thread.currentThread().setContextClassLoader(oldTCCL);
- }
-
- assertSame(bw1, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
- assertEquals(2, getDefaultObjectWrapperInstanceCacheSize());
-
- DefaultObjectWrapper bw3;
- Thread.currentThread().setContextClassLoader(newTCCL);
- try {
- assertSame(bw2, new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build());
-
- DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- bwb.setExposeFields(true);
- bw3 = bwb.build();
- assertEquals(3, getDefaultObjectWrapperInstanceCacheSize());
- hardReferences.add(bw3);
- } finally {
- Thread.currentThread().setContextClassLoader(oldTCCL);
- }
-
- {
- DefaultObjectWrapper.Builder bwb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- bwb.setExposeFields(true);
- DefaultObjectWrapper bw4 = bwb.build();
- assertEquals(4, getDefaultObjectWrapperInstanceCacheSize());
- assertNotSame(bw3, bw4);
- hardReferences.add(bw4);
- }
-
- assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
- }
-
- public void testClassInrospectorCache() throws TemplateModelException {
- assertFalse(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .usePrivateCaches(true).build().isClassIntrospectionCacheRestricted());
- assertTrue(new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .build().isClassIntrospectionCacheRestricted());
-
- ClassIntrospector.Builder.clearInstanceCache();
- DefaultObjectWrapper.Builder.clearInstanceCache();
- checkClassIntrospectorCacheSize(0);
-
- List<DefaultObjectWrapper> hardReferences = new LinkedList<>();
- DefaultObjectWrapper.Builder builder;
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
-
- DefaultObjectWrapper bw1 = builder.build();
- checkClassIntrospectorCacheSize(1);
-
- builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_SAFE); // this was already set to this
- builder.setUseModelCache(true); // this shouldn't matter for the introspection cache
- DefaultObjectWrapper bw2 = builder.build();
- checkClassIntrospectorCacheSize(1);
-
- assertSame(bw2.getClassIntrospector(), bw1.getClassIntrospector());
- assertNotSame(bw1, bw2);
-
- // Wrapping tests:
- assertFalse(exposesFields(bw1));
- assertTrue(exposesProperties(bw1));
- assertTrue(exposesMethods(bw1));
- assertFalse(exposesUnsafe(bw1));
- assertTrue(bw1.isClassIntrospectionCacheRestricted());
- // Prevent introspection cache GC:
- hardReferences.add(bw1);
- hardReferences.add(bw2);
- }
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder.setExposeFields(true);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(2);
- // Wrapping tests:
- assertTrue(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertTrue(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_ALL);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(3);
- // Wrapping tests:
- assertTrue(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertTrue(exposesMethods(ow));
- assertTrue(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder.setExposeFields(false);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(4);
- // Wrapping tests:
- assertFalse(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertTrue(exposesMethods(ow));
- assertTrue(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_NOTHING);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(5);
- // Wrapping tests:
- assertFalse(exposesFields(ow));
- assertFalse(exposesProperties(ow));
- assertFalse(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder.setExposeFields(true);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(6);
- // Wrapping tests:
- assertTrue(exposesFields(ow));
- assertFalse(exposesProperties(ow));
- assertFalse(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(7);
- // Wrapping tests:
- assertTrue(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertFalse(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder.setUseModelCache(true);
- builder.setExposeFields(false);
- builder.setExposureLevel(DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
-
- DefaultObjectWrapper bw1 = builder.build();
- checkClassIntrospectorCacheSize(8);
- ClassIntrospector ci1 = bw1.getClassIntrospector();
-
- builder.setUseModelCache(false); // Shouldn't mater for the ClassIntrospector
- DefaultObjectWrapper bw2 = builder.build();
- ClassIntrospector ci2 = bw2.getClassIntrospector();
- checkClassIntrospectorCacheSize(8);
-
- assertSame(ci1, ci2);
- assertNotSame(bw1, bw2);
-
- // Wrapping tests:
- assertFalse(exposesFields(bw1));
- assertTrue(exposesProperties(bw1));
- assertFalse(exposesMethods(bw1));
- assertFalse(exposesUnsafe(bw1));
-
- // Prevent introspection cache GC:
- hardReferences.add(bw1);
- hardReferences.add(bw2);
- }
-
- // The ClassInrospector cache couldn't become cleared in reality otherwise:
- DefaultObjectWrapper.Builder.clearInstanceCache();
-
- clearClassIntrospectorInstanceCacheReferences(false);
- checkClassIntrospectorCacheSize(8);
- assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
-
- {
- builder.setExposeFields(false);
-
- DefaultObjectWrapper bw1 = builder.build();
- checkClassIntrospectorCacheSize(8);
- assertEquals(1, getClassIntrospectorNonClearedInstanceCacheSize());
- ClassIntrospector ci1 = bw1.getClassIntrospector();
-
- builder.setUseModelCache(true); // Shouldn't mater
- DefaultObjectWrapper bw2 = builder.build();
- ClassIntrospector ci2 = bw2.getClassIntrospector();
-
- assertSame(ci1, ci2);
- assertNotSame(bw1, bw2);
-
- // Wrapping tests:
- assertFalse(exposesFields(bw1));
- assertTrue(exposesProperties(bw1));
- assertFalse(exposesMethods(bw1));
- assertFalse(exposesUnsafe(bw1));
-
- // Prevent introspection cache GC:
- hardReferences.add(bw1);
- hardReferences.add(bw2);
- }
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(8);
- assertEquals(2, getClassIntrospectorNonClearedInstanceCacheSize());
- // Wrapping tests:
- assertFalse(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertTrue(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- clearClassIntrospectorInstanceCacheReferences(true);
- checkClassIntrospectorCacheSize(8);
- assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder.setExposeFields(true);
- DefaultObjectWrapper ow = builder.build();
- checkClassIntrospectorCacheSize(1);
- // Wrapping tests:
- assertTrue(exposesFields(ow));
- assertTrue(exposesProperties(ow));
- assertTrue(exposesMethods(ow));
- assertFalse(exposesUnsafe(ow));
- // Prevent introspection cache GC:
- hardReferences.add(ow);
- }
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
- @Override
- public void process(DecisionInput in, Decision out) {
- }
- }); // spoils ClassIntrospector() sharing
-
- builder.setUseModelCache(false);
- DefaultObjectWrapper bw1 = builder.build();
- assertSame(bw1, builder.build());
-
- builder.setUseModelCache(true);
- DefaultObjectWrapper bw2 = builder.build();
- checkClassIntrospectorCacheSize(1);
- assertNotSame(bw1, bw2);
- assertNotSame(bw1.getClassIntrospector(), bw2.getClassIntrospector());
- assertTrue(bw1.isClassIntrospectionCacheRestricted());
- assertTrue(bw2.isClassIntrospectionCacheRestricted());
- }
-
- {
- builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- builder.setMethodAppearanceFineTuner(
- GetlessMethodsAsPropertyGettersRule.INSTANCE); // doesn't spoils sharing
-
- builder.setUseModelCache(false);
- DefaultObjectWrapper bw1 = builder.build();
- assertSame(bw1, builder.build());
- checkClassIntrospectorCacheSize(2);
-
- builder.setUseModelCache(true);
- DefaultObjectWrapper bw2 = builder.build();
- checkClassIntrospectorCacheSize(2);
-
- assertNotSame(bw1, bw2);
- assertSame(bw1.getClassIntrospector(), bw2.getClassIntrospector()); // !
- assertTrue(bw2.isClassIntrospectionCacheRestricted());
- }
-
- assertTrue(hardReferences.size() != 0); // just to save it from GC until this line
- }
-
- private void checkClassIntrospectorCacheSize(int expectedSize) {
- assertEquals(expectedSize, getClassIntrospectorInstanceCacheSize());
- }
-
- public class C {
-
- public String foo = "FOO";
-
- public String getBar() {
- return "BAR";
- }
-
- }
-
- private boolean exposesFields(DefaultObjectWrapper ow) throws TemplateModelException {
- TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
- TemplateScalarModel r = (TemplateScalarModel) thm.get("foo");
- if (r == null) return false;
- assertEquals("FOO", r.getAsString());
- return true;
- }
-
- private boolean exposesProperties(DefaultObjectWrapper ow) throws TemplateModelException {
- TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
- TemplateScalarModel r = (TemplateScalarModel) thm.get("bar");
- if (r == null) return false;
- assertEquals("BAR", r.getAsString());
- return true;
- }
-
- private boolean exposesMethods(DefaultObjectWrapper ow) throws TemplateModelException {
- TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
- return thm.get("getBar") != null;
- }
-
- private boolean exposesUnsafe(DefaultObjectWrapper ow) throws TemplateModelException {
- TemplateHashModel thm = (TemplateHashModel) ow.wrap(new C());
- return thm.get("wait") != null;
- }
-
- static int getClassIntrospectorInstanceCacheSize() {
- Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
- synchronized (instanceCache) {
- return instanceCache.size();
- }
- }
-
- static int getClassIntrospectorNonClearedInstanceCacheSize() {
- Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
- synchronized (instanceCache) {
- int cnt = 0;
- for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
- if (((Reference) it.next()).get() != null) cnt++;
- }
- return cnt;
- }
- }
-
- static void clearClassIntrospectorInstanceCacheReferences(boolean enqueue) {
- Map instanceCache = ClassIntrospector.Builder.getInstanceCache();
- synchronized (instanceCache) {
- for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
- Reference ref = ((Reference) it.next());
- ref.clear();
- if (enqueue) {
- ref.enqueue();
- }
- }
- }
- }
-
- static int getDefaultObjectWrapperInstanceCacheSize() {
- Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
- synchronized (instanceCache) {
- int size = 0;
- for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
- size += ((Map) it1.next()).size();
- }
- return size;
- }
- }
-
- static int getDefaultObjectWrapperNonClearedInstanceCacheSize() {
- Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
- synchronized (instanceCache) {
- int cnt = 0;
- for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
- Map tcclScope = (Map) it1.next();
- for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
- if (((Reference) it2.next()).get() != null) cnt++;
- }
- }
- return cnt;
- }
- }
-
- static void clearDefaultObjectWrapperInstanceCacheReferences(boolean enqueue) {
- Map instanceCache = DefaultObjectWrapper.Builder.getInstanceCache();
- synchronized (instanceCache) {
- for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
- Map tcclScope = (Map) it1.next();
- for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
- Reference ref = ((Reference) it2.next());
- ref.clear();
- if (enqueue) {
- ref.enqueue();
- }
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
deleted file mode 100644
index 6e9ae25..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.Vector;
-
-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.Template;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.Version;
-import org.apache.freemarker.core._CoreAPI;
-import org.apache.freemarker.core.model.AdapterTemplateModel;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateCollectionModelEx;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-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.TemplateModelWithAPISupport;
-import org.apache.freemarker.core.model.TemplateNodeModel;
-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.WrapperTemplateModel;
-import org.apache.freemarker.core.model.WrappingTemplateModel;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class DefaultObjectWrapperTest {
-
- private final static DefaultObjectWrapper OW = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .build();
-
- // This will make sense if we will have multipe incompatibleImprovement versions.
- @Test
- public void testIncompatibleImprovementsVersionBreakPoints() throws Exception {
- List<Version> expected = new ArrayList<>();
- expected.add(Configuration.VERSION_3_0_0);
-
- List<Version> actual = new ArrayList<>();
- int i = _CoreAPI.VERSION_INT_3_0_0;
- while (i <= Configuration.getVersion().intValue()) {
- int major = i / 1000000;
- int minor = i % 1000000 / 1000;
- int micro = i % 1000;
- final Version version = new Version(major, minor, micro);
-
- final Version normalizedVersion = DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(version);
- actual.add(normalizedVersion);
-
- final DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(version);
- assertEquals(normalizedVersion, builder.getIncompatibleImprovements());
- assertEquals(normalizedVersion, builder.build().getIncompatibleImprovements());
-
- i++;
- }
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testIncompatibleImprovementsVersionOutOfBounds() throws Exception {
- try {
- DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(new Version(2, 2, 0));
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- Version curVersion = Configuration.getVersion();
- final Version futureVersion = new Version(curVersion.getMajor(), curVersion.getMicro(),
- curVersion.getMicro() + 1);
- try {
- DefaultObjectWrapper.normalizeIncompatibleImprovementsVersion(futureVersion);
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- new DefaultObjectWrapper.Builder(futureVersion);
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testBuilder() throws Exception {
- DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- DefaultObjectWrapper ow = builder.build();
- assertSame(ow, builder.build());
- assertSame(ow.getClass(), DefaultObjectWrapper.class);
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- }
-
- @Test
- public void testWrappedTypes() throws Exception {
- DefaultObjectWrapper.Builder builder = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- DefaultObjectWrapper ow = builder.build();
-
- assertThat(ow.wrap(new HashMap()), instanceOf(DefaultMapAdapter.class));
- assertThat(ow.wrap(new ArrayList()), instanceOf(DefaultListAdapter.class));
- assertThat(ow.wrap(new String[] {}), instanceOf(DefaultArrayAdapter.class));
- assertThat(ow.wrap(new HashSet()), instanceOf(DefaultNonListCollectionAdapter.class));
- assertThat(ow.wrap(new PureIterable()), instanceOf(DefaultIterableAdapter.class));
- assertThat(ow.wrap(new Vector<>().iterator()), instanceOf(DefaultIteratorAdapter.class));
- assertThat(ow.wrap(new Vector<>().elements()), instanceOf(DefaultEnumerationAdapter.class));
- }
-
- @Test
- public void testConstructors() throws Exception {
- {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .usePrivateCaches(true).build();
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
- }
-
- try {
- new DefaultObjectWrapper.Builder(new Version(99, 9, 9)).build();
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage(), containsString("version"));
- }
- }
-
-
- @Test
- public void testCustomization() throws TemplateModelException {
- CustomizedDefaultObjectWrapper ow = new CustomizedDefaultObjectWrapper(Configuration.VERSION_3_0_0);
- assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
-
- TemplateSequenceModel seq = (TemplateSequenceModel) ow.wrap(new Tupple(11, 22));
- assertEquals(2, seq.size());
- assertEquals(11, ow.unwrap(seq.get(0)));
- assertEquals(22, ow.unwrap(seq.get(1)));
-
- assertTrue(ow.wrap("x") instanceof SimpleScalar);
- assertTrue(ow.wrap(1.5) instanceof SimpleNumber);
- assertTrue(ow.wrap(new Date()) instanceof SimpleDate);
- assertEquals(TemplateBooleanModel.TRUE, ow.wrap(true));
-
- assertTrue(ow.wrap(Collections.emptyMap()) instanceof DefaultMapAdapter);
- assertTrue(ow.wrap(Collections.emptyList()) instanceof DefaultListAdapter);
- assertTrue(ow.wrap(new boolean[] { }) instanceof DefaultArrayAdapter);
- assertTrue(ow.wrap(new HashSet()) instanceof DefaultNonListCollectionAdapter);
- assertTrue(ow.wrap('c') instanceof TemplateScalarModel); // BeanAndStringModel right now, but should change later
-
- TemplateHashModel bean = (TemplateHashModel) ow.wrap(new TestBean());
- assertEquals(1, ow.unwrap(bean.get("x")));
- {
- // Check method calls, and also if the return value is wrapped with the overidden "wrap".
- final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("m")).exec(Collections.emptyList());
- assertEquals(
- Collections.singletonList(1),
- ow.unwrap(mr));
- assertTrue(DefaultListAdapter.class.isInstance(mr));
- }
- {
- // Check custom TM usage and round trip:
- final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("incTupple"))
- .exec(Collections.singletonList(ow.wrap(new Tupple<>(1, 2))));
- assertEquals(new Tupple<>(2, 3), ow.unwrap(mr));
- assertTrue(TuppleAdapter.class.isInstance(mr));
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testCompositeValueWrapping() throws TemplateModelException, ClassNotFoundException {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- final Map hashMap = new HashMap();
- inintTestMap(hashMap);
- final Map treeMap = new TreeMap();
- inintTestMap(treeMap);
- final Map linkedHashMap = new LinkedHashMap();
- inintTestMap(linkedHashMap);
- final Map gMap = ImmutableMap.<String, Object> of("a", 1, "b", 2, "c", 3);
- final LinkedList linkedList = new LinkedList();
- linkedList.add("a");
- linkedList.add("b");
- linkedList.add("c");
- final int[] intArray = new int[] { 1, 2, 3 };
- final String[] stringArray = new String[] { "a", "b", "c" };
- final PureIterable pureIterable = new PureIterable();
- final HashSet hashSet = new HashSet();
-
- assertRoundtrip(ow, linkedHashMap, DefaultMapAdapter.class, LinkedHashMap.class, linkedHashMap.toString());
- assertRoundtrip(ow, treeMap, DefaultMapAdapter.class, TreeMap.class, treeMap.toString());
- assertRoundtrip(ow, gMap, DefaultMapAdapter.class, ImmutableMap.class, gMap.toString());
- assertRoundtrip(ow, linkedList, DefaultListAdapter.class, LinkedList.class, linkedList.toString());
- assertRoundtrip(ow, intArray, DefaultArrayAdapter.class, int[].class, null);
- assertRoundtrip(ow, stringArray, DefaultArrayAdapter.class, String[].class, null);
- assertRoundtrip(ow, pureIterable, DefaultIterableAdapter.class, PureIterable.class, pureIterable.toString());
- assertRoundtrip(ow, hashSet, DefaultNonListCollectionAdapter.class, HashSet.class, hashSet.toString());
- }
-
- @SuppressWarnings("boxing")
- private void inintTestMap(Map map) {
- map.put("a", 1);
- map.put("b", 2);
- map.put("c", 3);
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testMapAdapter() throws TemplateModelException {
- HashMap<String, Object> testMap = new LinkedHashMap<>();
- testMap.put("a", 1);
- testMap.put("b", null);
- testMap.put("c", "C");
- testMap.put("d", Collections.singletonList("x"));
-
- {
- TemplateHashModelEx hash = (TemplateHashModelEx) OW.wrap(testMap);
- assertEquals(4, hash.size());
- assertFalse(hash.isEmpty());
- assertNull(hash.get("e"));
- assertEquals(1, ((TemplateNumberModel) hash.get("a")).getAsNumber());
- assertNull(hash.get("b"));
- assertEquals("C", ((TemplateScalarModel) hash.get("c")).getAsString());
- assertTrue(hash.get("d") instanceof DefaultListAdapter);
-
- assertCollectionTMEquals(hash.keys(), "a", "b", "c", "d");
- assertCollectionTMEquals(hash.values(), 1, null, "C", Collections.singletonList("x"));
-
- assertSizeThroughAPIModel(4, hash);
- }
-
- {
- assertTrue(((TemplateHashModel) OW.wrap(Collections.emptyMap())).isEmpty());
- }
- }
-
- private void assertCollectionTMEquals(TemplateCollectionModel coll, Object... expectedItems)
- throws TemplateModelException {
- for (int i = 0; i < 2; i++) { // Run twice to check if we always get a new iterator
- int idx = 0;
- TemplateModelIterator it2 = null;
- for (TemplateModelIterator it = coll.iterator(); it.hasNext(); ) {
- TemplateModel actualItem = it.next();
- if (idx >= expectedItems.length) {
- fail("Number of items is more than the expected " + expectedItems.length);
- }
- assertEquals(expectedItems[idx], OW.unwrap(actualItem));
- if (i == 1) {
- // In the 2nd round we also test with two iterators in parallel.
- // This 2nd iterator is also special in that its hasNext() is never called.
- if (it2 == null) {
- it2 = coll.iterator();
- }
- assertEquals(expectedItems[idx], OW.unwrap(it2.next()));
- }
- idx++;
- }
- if (expectedItems.length != idx) {
- fail("Number of items is " + idx + ", which is less than the expected " + expectedItems.length);
- }
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testListAdapter() throws TemplateModelException {
- {
- List testList = new ArrayList<>();
- testList.add(1);
- testList.add(null);
- testList.add("c");
- testList.add(new String[] { "x" });
-
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testList);
- assertTrue(seq instanceof DefaultListAdapter);
- assertFalse(seq instanceof TemplateCollectionModel); // Maybe changes at 2.4.0
- assertEquals(4, seq.size());
- assertNull(seq.get(-1));
- assertEquals(1, ((TemplateNumberModel) seq.get(0)).getAsNumber());
- assertNull(seq.get(1));
- assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
- assertTrue(seq.get(3) instanceof DefaultArrayAdapter);
- assertNull(seq.get(4));
-
- assertSizeThroughAPIModel(4, seq);
- }
-
- {
- List testList = new LinkedList<>();
- testList.add(1);
- testList.add(null);
- testList.add("c");
-
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testList);
- assertTrue(seq instanceof DefaultListAdapter);
- assertTrue(seq instanceof TemplateCollectionModel); // Maybe changes at 2.4.0
- assertEquals(3, seq.size());
- assertNull(seq.get(-1));
- assertEquals(1, ((TemplateNumberModel) seq.get(0)).getAsNumber());
- assertNull(seq.get(1));
- assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
- assertNull(seq.get(3));
-
- assertCollectionTMEquals((TemplateCollectionModel) seq, 1, null, "c");
-
- TemplateModelIterator it = ((TemplateCollectionModel) seq).iterator();
- it.next();
- it.next();
- it.next();
- try {
- it.next();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("no more"));
- }
- }
- }
-
- @Test
- public void testArrayAdapterTypes() throws TemplateModelException {
- assertArrayAdapterClass("Object", OW.wrap(new Object[] {}));
- assertArrayAdapterClass("Object", OW.wrap(new String[] {}));
- assertArrayAdapterClass("byte", OW.wrap(new byte[] {}));
- assertArrayAdapterClass("short", OW.wrap(new short[] {}));
- assertArrayAdapterClass("int", OW.wrap(new int[] {}));
- assertArrayAdapterClass("long", OW.wrap(new long[] {}));
- assertArrayAdapterClass("float", OW.wrap(new float[] {}));
- assertArrayAdapterClass("double", OW.wrap(new double[] {}));
- assertArrayAdapterClass("boolean", OW.wrap(new boolean[] {}));
- assertArrayAdapterClass("char", OW.wrap(new char[] {}));
- }
-
- private void assertArrayAdapterClass(String adapterCompType, TemplateModel adaptedArray) {
- assertTrue(adaptedArray instanceof DefaultArrayAdapter);
- assertThat(adaptedArray.getClass().getName(),
- containsString("$" + adapterCompType.substring(0, 1).toUpperCase() + adapterCompType.substring(1)));
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testArrayAdapters() throws TemplateModelException {
- {
- final String[] testArray = new String[] { "a", null, "c" };
-
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
- assertEquals(3, seq.size());
- assertNull(seq.get(-1));
- assertEquals("a", ((TemplateScalarModel) seq.get(0)).getAsString());
- assertNull(seq.get(1));
- assertEquals("c", ((TemplateScalarModel) seq.get(2)).getAsString());
- assertNull(seq.get(3));
- }
-
- {
- final int[] testArray = new int[] { 11, 22 };
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
- assertEquals(2, seq.size());
- assertNull(seq.get(-1));
- assertEqualsAndSameClass(Integer.valueOf(11), ((TemplateNumberModel) seq.get(0)).getAsNumber());
- assertEqualsAndSameClass(Integer.valueOf(22), ((TemplateNumberModel) seq.get(1)).getAsNumber());
- assertNull(seq.get(2));
- }
-
- {
- final double[] testArray = new double[] { 11, 22 };
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
- assertEquals(2, seq.size());
- assertNull(seq.get(-1));
- assertEqualsAndSameClass(Double.valueOf(11), ((TemplateNumberModel) seq.get(0)).getAsNumber());
- assertEqualsAndSameClass(Double.valueOf(22), ((TemplateNumberModel) seq.get(1)).getAsNumber());
- assertNull(seq.get(2));
- }
-
- {
- final boolean[] testArray = new boolean[] { true, false };
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
- assertEquals(2, seq.size());
- assertNull(seq.get(-1));
- assertEqualsAndSameClass(Boolean.valueOf(true), ((TemplateBooleanModel) seq.get(0)).getAsBoolean());
- assertEqualsAndSameClass(Boolean.valueOf(false), ((TemplateBooleanModel) seq.get(1)).getAsBoolean());
- assertNull(seq.get(2));
- }
-
- {
- final char[] testArray = new char[] { 'a', 'b' };
- TemplateSequenceModel seq = (TemplateSequenceModel) OW.wrap(testArray);
- assertEquals(2, seq.size());
- assertNull(seq.get(-1));
- assertEquals("a", ((TemplateScalarModel) seq.get(0)).getAsString());
- assertEquals("b", ((TemplateScalarModel) seq.get(1)).getAsString());
- assertNull(seq.get(2));
- }
- }
-
- private void assertEqualsAndSameClass(Object expected, Object actual) {
- assertEquals(expected, actual);
- if (expected != null) {
- assertEquals(expected.getClass(), actual.getClass());
- }
- }
-
- private void assertRoundtrip(DefaultObjectWrapper dow, Object obj, Class expectedTMClass,
- Class expectedPojoClass,
- String expectedPojoToString)
- throws TemplateModelException {
- final TemplateModel objTM = dow.wrap(obj);
- assertThat(objTM.getClass(), typeCompatibleWith(expectedTMClass));
-
- final TemplateHashModel testBeanTM = (TemplateHashModel) dow.wrap(new RoundtripTesterBean());
-
- {
- TemplateMethodModelEx getClassM = (TemplateMethodModelEx) testBeanTM.get("getClass");
- Object r = getClassM.exec(Collections.singletonList(objTM));
- final Class rClass = (Class) ((WrapperTemplateModel) r).getWrappedObject();
- assertThat(rClass, typeCompatibleWith(expectedPojoClass));
- }
-
- if (expectedPojoToString != null) {
- TemplateMethodModelEx getToStringM = (TemplateMethodModelEx) testBeanTM.get("toString");
- Object r = getToStringM.exec(Collections.singletonList(objTM));
- assertEquals(expectedPojoToString, ((TemplateScalarModel) r).getAsString());
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testCollectionAdapterBasics() throws TemplateModelException {
- {
- Set set = new TreeSet();
- set.add("a");
- set.add("b");
- set.add("c");
- TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
- assertTrue(coll instanceof DefaultNonListCollectionAdapter);
- assertEquals(3, coll.size());
- assertFalse(coll.isEmpty());
- assertCollectionTMEquals(coll, "a", "b", "c");
-
- assertRoundtrip(OW, set, DefaultNonListCollectionAdapter.class, TreeSet.class, "[a, b, c]");
-
- assertSizeThroughAPIModel(3, coll);
- }
-
- {
- Set set = new HashSet();
- final List<String> list = Collections.singletonList("b");
- set.add(list);
- set.add(null);
- TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
- TemplateModelIterator it = coll.iterator();
- final TemplateModel tm1 = it.next();
- Object obj1 = OW.unwrap(tm1);
- final TemplateModel tm2 = it.next();
- Object obj2 = OW.unwrap(tm2);
- assertTrue(obj1 == null || obj2 == null);
- assertTrue(obj1 != null && obj1.equals(list) || obj2 != null && obj2.equals(list));
- assertTrue(tm1 instanceof DefaultListAdapter || tm2 instanceof DefaultListAdapter);
-
- assertRoundtrip(OW, set, DefaultNonListCollectionAdapter.class, HashSet.class, "[" + obj1 + ", "
- + obj2 + "]");
- }
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testCollectionAdapterOutOfBounds() throws TemplateModelException {
- Set set = Collections.singleton(123);
-
- TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
- TemplateModelIterator it = coll.iterator();
-
- for (int i = 0; i < 3; i++) {
- assertTrue(it.hasNext());
- }
-
- assertEquals(123, OW.unwrap(it.next()));
-
- for (int i = 0; i < 3; i++) {
- assertFalse(it.hasNext());
- try {
- it.next();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
- }
- }
- }
-
- @Test
- public void testCollectionAdapterAndNulls() throws TemplateModelException {
- Set set = new HashSet();
- set.add(null);
-
- TemplateCollectionModelEx coll = (TemplateCollectionModelEx) OW.wrap(set);
- assertEquals(1, coll.size());
- assertFalse(coll.isEmpty());
- assertNull(coll.iterator().next());
- }
-
- @Test
- public void testIteratorWrapping() throws TemplateModelException, ClassNotFoundException {
- final List<String> list = ImmutableList.of("a", "b", "c");
- Iterator<String> it = list.iterator();
- TemplateCollectionModel coll = (TemplateCollectionModel) OW.wrap(it);
-
- assertRoundtrip(OW, coll, DefaultIteratorAdapter.class, Iterator.class, null);
-
- TemplateModelIterator itIt = coll.iterator();
- TemplateModelIterator itIt2 = coll.iterator(); // used later
- assertTrue(itIt.hasNext());
- assertEquals("a", OW.unwrap(itIt.next()));
- assertTrue(itIt.hasNext());
- assertEquals("b", OW.unwrap(itIt.next()));
- assertTrue(itIt.hasNext());
- assertEquals("c", OW.unwrap(itIt.next()));
- assertFalse(itIt.hasNext());
- try {
- itIt.next();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
- }
-
- try {
- itIt2.hasNext();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("can be listed only once"));
- }
-
- TemplateModelIterator itIt3 = coll.iterator();
- try {
- itIt3.hasNext();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsString("can be listed only once"));
- }
- }
-
- @Test
- public void testIteratorApiSupport() throws TemplateModelException {
- TemplateModel wrappedIterator = OW.wrap(Collections.emptyIterator());
- assertThat(wrappedIterator, instanceOf(DefaultIteratorAdapter.class));
- DefaultIteratorAdapter iteratorAdapter = (DefaultIteratorAdapter) wrappedIterator;
-
- TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
- api.get("hasNext")).exec(Collections.emptyList())).getAsBoolean());
- }
-
- @SuppressWarnings("boxing")
- @Test
- public void testCharKeyFallback() throws TemplateModelException {
- Map hashMapS = new HashMap<>();
- hashMapS.put("a", 1);
- Map sortedMapS = new TreeMap<>();
- sortedMapS.put("a", 1);
- Map hashMapC = new HashMap<>();
- hashMapC.put('a', 1);
- Map sortedMapC = new TreeMap<>();
- sortedMapC.put('a', 1);
-
- assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(hashMapS)).get("a")));
- assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(hashMapC)).get("a")));
- assertEquals(1, OW.unwrap(((TemplateHashModel) OW.wrap(sortedMapS)).get("a")));
- try {
- ((TemplateHashModel) OW.wrap(sortedMapC)).get("a");
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("String key"));
- }
-
- assertNull(((TemplateHashModel) OW.wrap(hashMapS)).get("b"));
- assertNull(((TemplateHashModel) OW.wrap(hashMapC)).get("b"));
- assertNull(((TemplateHashModel) OW.wrap(sortedMapS)).get("b"));
- try {
- ((TemplateHashModel) OW.wrap(sortedMapC)).get("b");
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("String key"));
- }
- }
-
- @Test
- public void testIterableSupport() throws TemplateException, IOException {
- Iterable<String> iterable = new PureIterable();
-
- String listingFTL = "<#list value as x>${x}<#sep>, </#list>";
-
- DefaultObjectWrapper ow = OW;
- TemplateModel tm = ow.wrap(iterable);
- assertThat(tm, instanceOf(TemplateCollectionModel.class));
- TemplateCollectionModel iterableTM = (TemplateCollectionModel) tm;
-
- for (int i = 0; i < 2; i++) {
- TemplateModelIterator iteratorTM = iterableTM.iterator();
- assertTrue(iteratorTM.hasNext());
- assertEquals("a", ow.unwrap(iteratorTM.next()));
- assertTrue(iteratorTM.hasNext());
- assertEquals("b", ow.unwrap(iteratorTM.next()));
- assertTrue(iteratorTM.hasNext());
- assertEquals("c", ow.unwrap(iteratorTM.next()));
- assertFalse(iteratorTM.hasNext());
- try {
- iteratorTM.next();
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("no more"));
- }
- }
-
- assertTemplateOutput(OW, iterable, listingFTL, "a, b, c");
- }
-
- @Test
- public void testEnumerationAdapter() throws TemplateModelException {
- Vector<String> vector = new Vector<String>();
- vector.add("a");
- vector.add("b");
-
- TemplateModel wrappedEnumeration = OW.wrap(vector.elements());
- assertThat(wrappedEnumeration, instanceOf(DefaultEnumerationAdapter.class));
- DefaultEnumerationAdapter enumAdapter = (DefaultEnumerationAdapter) wrappedEnumeration;
- TemplateModelIterator iterator = enumAdapter.iterator();
- assertTrue(iterator.hasNext());
- assertEquals("a", ((TemplateScalarModel) iterator.next()).getAsString());
- assertTrue(iterator.hasNext());
- assertEquals("b", ((TemplateScalarModel) iterator.next()).getAsString());
- assertFalse(iterator.hasNext());
-
- iterator = enumAdapter.iterator();
- try {
- iterator.hasNext();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsStringIgnoringCase("only once"));
- }
-
- TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
- api.get("hasMoreElements")).exec(Collections.emptyList())).getAsBoolean());
- }
-
- @Test
- public void assertCanWrapDOM() throws SAXException, IOException, ParserConfigurationException,
- TemplateModelException {
- DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- InputSource is = new InputSource();
- is.setCharacterStream(new StringReader("<doc><sub a='1' /></doc>"));
- Document doc = db.parse(is);
- assertTrue(OW.wrap(doc) instanceof TemplateNodeModel);
- }
-
- @Test
- public void testExposureLevel() throws Exception {
- TestBean bean = new TestBean();
-
- {
- TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_SAFE);
- assertNotNull(tm.get("hashCode"));
- assertNotNull(tm.get("class"));
- }
-
- {
- TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_PROPERTIES_ONLY);
- assertNull(tm.get("hashCode"));
- assertNotNull(tm.get("class"));
- }
-
- {
- TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_NOTHING);
- assertNull(tm.get("hashCode"));
- assertNull(tm.get("class"));
- }
-
- {
- TemplateHashModel tm = wrapWithExposureLevel(bean, DefaultObjectWrapper.EXPOSE_ALL);
- assertNotNull(tm.get("hashCode"));
- assertNotNull(tm.get("class"));
- }
- }
-
- private TemplateHashModel wrapWithExposureLevel(Object bean, int exposureLevel) throws TemplateModelException {
- return (TemplateHashModel) new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .exposureLevel(exposureLevel).build()
- .wrap(bean);
- }
-
- private void assertSizeThroughAPIModel(int expectedSize, TemplateModel normalModel) throws TemplateModelException {
- if (!(normalModel instanceof TemplateModelWithAPISupport)) {
- fail();
- }
- TemplateHashModel apiModel = (TemplateHashModel) ((TemplateModelWithAPISupport) normalModel).getAPI();
- TemplateMethodModelEx sizeMethod = (TemplateMethodModelEx) apiModel.get("size");
- TemplateNumberModel r = (TemplateNumberModel) sizeMethod.exec(Collections.emptyList());
- assertEquals(expectedSize, r.getAsNumber().intValue());
- }
-
- private void assertTemplateOutput(ObjectWrapper objectWrapper, Object value, String ftl, String expectedOutput)
- throws TemplateException, IOException {
- assertEquals(expectedOutput, processTemplate(objectWrapper, value, ftl));
- }
-
- private void assertTemplateFails(ObjectWrapper objectWrapper, Object value, String ftl, String expectedMessagePart)
- throws TemplateException, IOException {
- try {
- processTemplate(objectWrapper, value, ftl);
- fail();
- } catch (TemplateException e) {
- assertThat(e.getMessage(), containsString(expectedMessagePart));
- }
- }
-
- private String processTemplate(ObjectWrapper objectWrapper, Object value, String ftl)
- throws TemplateException, IOException {
- Configuration cfg = new TestConfigurationBuilder()
- .logTemplateExceptions(false)
- .objectWrapper(objectWrapper)
- .build();
- StringWriter out = new StringWriter();
- new Template(null, ftl, cfg).process(ImmutableMap.of("value", value), out);
- return out.toString();
- }
-
- private static final class PureIterable implements Iterable<String> {
- @Override
- public Iterator<String> iterator() {
- return ImmutableList.of("a", "b", "c").iterator();
- }
- }
-
- public static class RoundtripTesterBean {
-
- public Class getClass(Object o) {
- return o.getClass();
- }
-
- public String toString(Object o) {
- return o.toString();
- }
-
- }
-
- private static class Tupple<E1, E2> {
-
- private final E1 e1;
- private final E2 e2;
-
- public Tupple(E1 e1, E2 e2) {
- if (e1 == null || e2 == null) throw new NullPointerException();
- this.e1 = e1;
- this.e2 = e2;
- }
-
- public E1 getE1() {
- return e1;
- }
-
- public E2 getE2() {
- return e2;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((e1 == null) ? 0 : e1.hashCode());
- result = prime * result + ((e2 == null) ? 0 : e2.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- Tupple other = (Tupple) obj;
- if (e1 == null) {
- if (other.e1 != null) return false;
- } else if (!e1.equals(other.e1)) return false;
- if (e2 == null) {
- if (other.e2 != null) return false;
- } else if (!e2.equals(other.e2)) return false;
- return true;
- }
-
- }
-
- @SuppressWarnings("boxing")
- public static class TestBean {
-
- public int getX() {
- return 1;
- }
-
- public List<Integer> m() {
- return Collections.singletonList(1);
- }
-
- public Tupple incTupple(Tupple<Integer, Integer> tupple) {
- return new Tupple(tupple.e1 + 1, tupple.e2 + 1);
- }
-
- }
-
- private static class CustomizedDefaultObjectWrapper extends DefaultObjectWrapper {
-
- private CustomizedDefaultObjectWrapper(Version incompatibleImprovements) {
- super(new DefaultObjectWrapper.Builder(incompatibleImprovements), true);
- }
-
- @Override
- protected TemplateModel handleNonBasicTypes(final Object obj) throws TemplateModelException {
- if (obj instanceof Tupple) {
- return new TuppleAdapter((Tupple<?, ?>) obj, this);
- }
-
- return super.handleNonBasicTypes(obj);
- }
-
- }
-
- private static class TuppleAdapter extends WrappingTemplateModel implements TemplateSequenceModel,
- AdapterTemplateModel {
-
- private final Tupple<?, ?> tupple;
-
- public TuppleAdapter(Tupple<?, ?> tupple, ObjectWrapper ow) {
- super(ow);
- this.tupple = tupple;
- }
-
- @Override
- public int size() throws TemplateModelException {
- return 2;
- }
-
- @Override
- public TemplateModel get(int index) throws TemplateModelException {
- switch (index) {
- case 0: return wrap(tupple.getE1());
- case 1: return wrap(tupple.getE2());
- default: return null;
- }
- }
-
- @Override
- public Object getAdaptedObject(Class hint) {
- return tupple;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
deleted file mode 100644
index fc19bb7..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class EnumModelsTest {
-
- @Test
- public void modelCaching() throws Exception {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
- .build();
- TemplateHashModel enums = ow.getEnumModels();
- TemplateHashModel e = (TemplateHashModel) enums.get(E.class.getName());
- assertNotNull(e);
- assertNotNull(e.get("A"));
- assertNotNull(e.get("B"));
- assertNull(e.get("C"));
-
- try {
- enums.get("no.such.ClassExists");
- fail();
- } catch (TemplateModelException ex) {
- assertTrue(ex.getCause() instanceof ClassNotFoundException);
- }
-
- TemplateModel a = e.get("A");
- assertTrue(a instanceof TemplateScalarModel);
- assertTrue(a instanceof TemplateHashModel);
- assertEquals(((TemplateScalarModel) a).getAsString(), "ts:A");
- TemplateMethodModelEx nameMethod = (TemplateMethodModelEx) ((TemplateHashModel) a).get("name");
- assertEquals(((TemplateScalarModel) nameMethod.exec(new ArrayList())).getAsString(), "A");
-
- assertSame(e, enums.get(E.class.getName()));
-
- ow.clearClassIntrospecitonCache();
- TemplateHashModel eAfterClean = (TemplateHashModel) enums.get(E.class.getName());
- assertNotSame(e, eAfterClean);
- assertSame(eAfterClean, enums.get(E.class.getName()));
- assertNotNull(eAfterClean.get("A"));
- assertNotNull(eAfterClean.get("B"));
- assertNull(eAfterClean.get("C"));
- }
-
- public enum E {
- A, B;
-
- @Override
- public String toString() {
- return "ts:" + super.toString();
- }
-
- }
-
-}
[47/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/DateFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DateFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DateFormatTest.java
new file mode 100644
index 0000000..4ad5937
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DateFormatTest.java
@@ -0,0 +1,464 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.SimpleDate;
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.userpkg.AppMetaTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.EpochMillisTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.HTMLISOTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.LocAndTZSensitiveTemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateDateFormat;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.UndefinedCustomFormatException;
+import org.apache.freemarker.core.valueformat.impl.AliasTemplateDateFormatFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class DateFormatTest extends TemplateTest {
+
+ /** 2015-09-06T12:00:00Z */
+ private static long T = 1441540800000L;
+ private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
+
+ private TestConfigurationBuilder createConfigurationBuilder() {
+ return new TestConfigurationBuilder()
+ .locale(Locale.US)
+ .timeZone(TimeZone.getTimeZone("GMT+01:00"))
+ .sqlDateAndTimeTimeZone(TimeZone.getTimeZone("UTC"))
+ .customDateFormats(ImmutableMap.of(
+ "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
+ "loc", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE,
+ "div", EpochMillisDivTemplateDateFormatFactory.INSTANCE,
+ "appMeta", AppMetaTemplateDateFormatFactory.INSTANCE,
+ "htmlIso", HTMLISOTemplateDateFormatFactory.INSTANCE));
+ }
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return createConfigurationBuilder().build();
+ }
+
+ @Test
+ public void testCustomFormat() throws Exception {
+ addToDataModel("d", new Date(123456789));
+ assertOutput(
+ "${d?string.@epoch} ${d?string.@epoch} <#setting locale='de_DE'>${d?string.@epoch}",
+ "123456789 123456789 123456789");
+
+ setConfigurationWithDateTimeFormat("@epoch");
+ assertOutput(
+ "<#assign d = d?datetime>"
+ + "${d} ${d?string} <#setting locale='de_DE'>${d}",
+ "123456789 123456789 123456789");
+
+ setConfigurationWithDateTimeFormat("@htmlIso");
+ assertOutput(
+ "<#assign d = d?datetime>"
+ + "${d} ${d?string} <#setting locale='de_DE'>${d}",
+ "1970-01-02<span class='T'>T</span>10:17:36Z "
+ + "1970-01-02T10:17:36Z "
+ + "1970-01-02<span class='T'>T</span>10:17:36Z");
+ }
+
+ @Test
+ public void testLocaleChange() throws Exception {
+ addToDataModel("d", new Date(123456789));
+ assertOutput(
+ "${d?string.@loc} ${d?string.@loc} "
+ + "<#setting locale='de_DE'>"
+ + "${d?string.@loc} ${d?string.@loc} "
+ + "<#setting locale='en_US'>"
+ + "${d?string.@loc} ${d?string.@loc}",
+ "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
+ + "123456789@de_DE:GMT+01:00 123456789@de_DE:GMT+01:00 "
+ + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
+
+ setConfigurationWithDateTimeFormat("@loc");
+ assertOutput(
+ "<#assign d = d?datetime>"
+ + "${d} ${d?string} "
+ + "<#setting locale='de_DE'>"
+ + "${d} ${d?string} "
+ + "<#setting locale='en_US'>"
+ + "${d} ${d?string}",
+ "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
+ + "123456789@de_DE:GMT+01:00 123456789@de_DE:GMT+01:00 "
+ + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
+ }
+
+ @Test
+ public void testTimeZoneChange() throws Exception {
+ addToDataModel("d", new Date(123456789));
+ setConfigurationWithDateTimeFormat("iso");
+ assertOutput(
+ "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal} "
+ + "<#setting timeZone='GMT+02:00'>"
+ + "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal} "
+ + "<#setting timeZone='GMT+01:00'>"
+ + "${d?string.@loc} ${d?string.@loc} ${d?datetime?isoLocal}",
+ "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 1970-01-02T11:17:36+01:00 "
+ + "123456789@en_US:GMT+02:00 123456789@en_US:GMT+02:00 1970-01-02T12:17:36+02:00 "
+ + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 1970-01-02T11:17:36+01:00");
+
+ setConfigurationWithDateTimeFormat("@loc");
+ assertOutput(
+ "<#assign d = d?datetime>"
+ + "${d} ${d?string} "
+ + "<#setting timeZone='GMT+02:00'>"
+ + "${d} ${d?string} "
+ + "<#setting timeZone='GMT+01:00'>"
+ + "${d} ${d?string}",
+ "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00 "
+ + "123456789@en_US:GMT+02:00 123456789@en_US:GMT+02:00 "
+ + "123456789@en_US:GMT+01:00 123456789@en_US:GMT+01:00");
+ }
+
+ @Test
+ public void testWrongFormatStrings() throws Exception {
+ setConfigurationWithDateTimeFormat("x1");
+ assertErrorContains("${.now}", "\"x1\"", "'x'");
+ assertErrorContains("${.now?string}", "\"x1\"", "'x'");
+ setConfigurationWithDateTimeFormat("short");
+ assertErrorContains("${.now?string('x2')}", "\"x2\"", "'x'");
+ assertErrorContains("${.now?string('[wrong]')}", "format string", "[wrong]");
+
+ setConfiguration(createConfigurationBuilder()
+ .dateFormat("[wrong d]")
+ .dateTimeFormat("[wrong dt]")
+ .timeFormat("[wrong t]")
+ .build());
+ assertErrorContains("${.now?date}", "\"date_format\"", "[wrong d]");
+ assertErrorContains("${.now?datetime}", "\"datetime_format\"", "[wrong dt]");
+ assertErrorContains("${.now?time}", "\"time_format\"", "[wrong t]");
+ }
+
+ @Test
+ public void testCustomParameterized() throws Exception {
+ Configuration cfg = getConfiguration();
+ addToDataModel("d", new SimpleDate(new Date(12345678L), TemplateDateModel.DATETIME));
+ setConfigurationWithDateTimeFormat("@div 1000");
+ assertOutput("${d}", "12345");
+ assertOutput("${d?string}", "12345");
+ assertOutput("${d?string.@div_100}", "123456");
+
+ assertErrorContains("${d?string.@div_xyz}", "\"@div_xyz\"", "\"xyz\"");
+ setConfigurationWithDateTimeFormat("@div");
+ assertErrorContains("${d}", "\"datetime_format\"", "\"@div\"", "format parameter is required");
+ }
+
+ @Test
+ public void testUnknownCustomFormat() throws Exception {
+ {
+ setConfigurationWithDateTimeFormat("@noSuchFormat");
+ Throwable exc = assertErrorContains(
+ "${.now}",
+ "\"@noSuchFormat\"", "\"noSuchFormat\"", "\"datetime_format\"");
+ assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
+
+ }
+ {
+ setConfiguration(createConfigurationBuilder().dateFormat("@noSuchFormatD").build());
+ assertErrorContains(
+ "${.now?date}",
+ "\"@noSuchFormatD\"", "\"noSuchFormatD\"", "\"date_format\"");
+ }
+ {
+ setConfiguration(createConfigurationBuilder().timeFormat("@noSuchFormatT").build());
+ assertErrorContains(
+ "${.now?time}",
+ "\"@noSuchFormatT\"", "\"noSuchFormatT\"", "\"time_format\"");
+ }
+
+ {
+ setConfigurationWithDateTimeFormat("");
+ Throwable exc = assertErrorContains("${.now?string('@noSuchFormat2')}",
+ "\"@noSuchFormat2\"", "\"noSuchFormat2\"");
+ assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
+ }
+ }
+
+ private void setConfigurationWithDateTimeFormat(String formatString) {
+ setConfiguration(createConfigurationBuilder().dateTimeFormat(formatString).build());
+ }
+
+ @Test
+ public void testNullInModel() throws Exception {
+ addToDataModel("d", new MutableTemplateDateModel());
+ assertErrorContains("${d}", "nothing inside it");
+ assertErrorContains("${d?string}", "nothing inside it");
+ }
+
+ @Test
+ public void testIcIAndEscaping() throws Exception {
+ addToDataModel("d", new SimpleDate(new Date(12345678L), TemplateDateModel.DATETIME));
+
+ setConfigurationWithDateTimeFormat("@epoch");
+ assertOutput("${d}", "12345678");
+ setConfigurationWithDateTimeFormat("'@'yyyy");
+ assertOutput("${d}", "@1970");
+ setConfigurationWithDateTimeFormat("@@yyyy");
+ assertOutput("${d}", "@@1970");
+
+ setConfiguration(createConfigurationBuilder()
+ .customDateFormats(Collections.<String, TemplateDateFormatFactory>emptyMap())
+ .dateTimeFormat("@epoch")
+ .build());
+ assertErrorContains("${d}", "custom", "\"epoch\"");
+ }
+
+ @Test
+ public void testEnvironmentGetters() throws Exception {
+ String dateFormatStr = "yyyy.MM.dd. (Z)";
+ String timeFormatStr = "HH:mm";
+ String dateTimeFormatStr = "yyyy.MM.dd. HH:mm";
+
+ setConfiguration(createConfigurationBuilder()
+ .dateFormat(dateFormatStr)
+ .timeFormat(timeFormatStr)
+ .dateTimeFormat(dateTimeFormatStr)
+ .build());
+
+ Configuration cfg = getConfiguration();
+
+ Template t = new Template(null, "", cfg);
+ Environment env = t.createProcessingEnvironment(null, null);
+
+ // Test that values are coming from the cache if possible
+ for (Class dateClass : new Class[] { Date.class, Timestamp.class, java.sql.Date.class, Time.class } ) {
+ for (int dateType
+ : new int[] { TemplateDateModel.DATE, TemplateDateModel.TIME, TemplateDateModel.DATETIME }) {
+ String formatString =
+ dateType == TemplateDateModel.DATE ? cfg.getDateFormat() :
+ (dateType == TemplateDateModel.TIME ? cfg.getTimeFormat()
+ : cfg.getDateTimeFormat());
+ TemplateDateFormat expectedF = env.getTemplateDateFormat(formatString, dateType, dateClass);
+ assertSame(expectedF, env.getTemplateDateFormat(dateType, dateClass)); // Note: Only reads the cache
+ assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass));
+ assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass, cfg.getLocale()));
+ assertSame(expectedF, env.getTemplateDateFormat(formatString, dateType, dateClass, cfg.getLocale(),
+ cfg.getTimeZone(), cfg.getSQLDateAndTimeTimeZone()));
+ }
+ }
+
+ String dateFormatStr2 = dateFormatStr + "'!'";
+ String timeFormatStr2 = timeFormatStr + "'!'";
+ String dateTimeFormatStr2 = dateTimeFormatStr + "'!'";
+
+ assertEquals("2015.09.06. 13:00",
+ env.getTemplateDateFormat(TemplateDateModel.DATETIME, Date.class).formatToPlainText(TM));
+ assertEquals("2015.09.06. 13:00!",
+ env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Date.class).formatToPlainText(TM));
+
+ assertEquals("2015.09.06. (+0100)",
+ env.getTemplateDateFormat(TemplateDateModel.DATE, Date.class).formatToPlainText(TM));
+ assertEquals("2015.09.06. (+0100)!",
+ env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, Date.class).formatToPlainText(TM));
+
+ assertEquals("13:00",
+ env.getTemplateDateFormat(TemplateDateModel.TIME, Date.class).formatToPlainText(TM));
+ assertEquals("13:00!",
+ env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Date.class).formatToPlainText(TM));
+
+ assertEquals("2015.09.06. 13:00",
+ env.getTemplateDateFormat(TemplateDateModel.DATETIME, Timestamp.class).formatToPlainText(TM));
+ assertEquals("2015.09.06. 13:00!",
+ env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Timestamp.class).formatToPlainText(TM));
+
+ assertEquals("2015.09.06. (+0000)",
+ env.getTemplateDateFormat(TemplateDateModel.DATE, java.sql.Date.class).formatToPlainText(TM));
+ assertEquals("2015.09.06. (+0000)!",
+ env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, java.sql.Date.class).formatToPlainText(TM));
+
+ assertEquals("12:00",
+ env.getTemplateDateFormat(TemplateDateModel.TIME, Time.class).formatToPlainText(TM));
+ assertEquals("12:00!",
+ env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Time.class).formatToPlainText(TM));
+
+ {
+ String dateTimeFormatStrLoc = dateTimeFormatStr + " EEEE";
+ // Gets into cache:
+ TemplateDateFormat format1
+ = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
+ assertEquals("2015.09.06. 13:00 Sunday", format1.formatToPlainText(TM));
+ // Different locale (not cached):
+ assertEquals("2015.09.06. 13:00 Sonntag",
+ env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
+ Locale.GERMANY).formatToPlainText(TM));
+ // Different locale and zone (not cached):
+ assertEquals("2015.09.06. 14:00 Sonntag",
+ env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
+ Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToPlainText(TM));
+ // Different locale and zone (not cached):
+ assertEquals("2015.09.06. 15:00 Sonntag",
+ env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, java.sql.Date.class,
+ Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToPlainText(TM));
+ // Check for corrupted cache:
+ TemplateDateFormat format2
+ = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
+ assertEquals("2015.09.06. 13:00 Sunday", format2.formatToPlainText(TM));
+ assertSame(format1, format2);
+ }
+ }
+
+ @Test
+ public void testAliases() throws Exception {
+ setConfiguration(createConfigurationBuilder()
+ .customDateFormats(ImmutableMap.of(
+ "d", new AliasTemplateDateFormatFactory("yyyy-MMM-dd"),
+ "m", new AliasTemplateDateFormatFactory("yyyy-MMM"),
+ "epoch", EpochMillisTemplateDateFormatFactory.INSTANCE))
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*2*"),
+ new TemplateConfiguration.Builder()
+ .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
+ "m", new AliasTemplateDateFormatFactory("yyyy-MMMM"),
+ "i", new AliasTemplateDateFormatFactory("@epoch")))
+ .build()))
+ .build());
+
+ addToDataModel("d", TM);
+ String commonFtl = "${d?string.@d} ${d?string.@m} "
+ + "<#setting locale='fr_FR'>${d?string.@m} "
+ + "<#attempt>${d?string.@i}<#recover>E</#attempt>";
+ addTemplate("t1.ftl", commonFtl);
+ addTemplate("t2.ftl", commonFtl);
+
+ // 2015-09-06T12:00:00Z
+ assertOutputForNamed("t1.ftl", "2015-Sep-06 2015-Sep 2015-sept. E");
+ assertOutputForNamed("t2.ftl", "2015-Sep-06 2015-September 2015-septembre " + T);
+ }
+
+ @Test
+ public void testAliases2() throws Exception {
+ setConfiguration(
+ createConfigurationBuilder()
+ .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
+ "d", new AliasTemplateDateFormatFactory("yyyy-MMM",
+ ImmutableMap.of(
+ new Locale("en"), "yyyy-MMM'_en'",
+ Locale.UK, "yyyy-MMM'_en_GB'",
+ Locale.FRANCE, "yyyy-MMM'_fr_FR'"))))
+ .dateTimeFormat("@d")
+ .build());
+ addToDataModel("d", TM);
+ assertOutput(
+ "<#setting locale='en_US'>${d} "
+ + "<#setting locale='en_GB'>${d} "
+ + "<#setting locale='en_GB_Win'>${d} "
+ + "<#setting locale='fr_FR'>${d} "
+ + "<#setting locale='hu_HU'>${d}",
+ "2015-Sep_en 2015-Sep_en_GB 2015-Sep_en_GB 2015-sept._fr_FR 2015-szept.");
+ }
+
+ /**
+ * ?date() and such are new in 2.3.24.
+ */
+ @Test
+ public void testZeroArgDateBI() throws IOException, TemplateException {
+ setConfiguration(
+ createConfigurationBuilder()
+ .dateFormat("@epoch")
+ .dateTimeFormat("@epoch")
+ .timeFormat("@epoch")
+ .build());
+
+ addToDataModel("t", String.valueOf(T));
+
+ assertOutput(
+ "${t?date?string.xs_u} ${t?date()?string.xs_u}",
+ "2015-09-06Z 2015-09-06Z");
+ assertOutput(
+ "${t?time?string.xs_u} ${t?time()?string.xs_u}",
+ "12:00:00Z 12:00:00Z");
+ assertOutput(
+ "${t?datetime?string.xs_u} ${t?datetime()?string.xs_u}",
+ "2015-09-06T12:00:00Z 2015-09-06T12:00:00Z");
+ }
+
+ @Test
+ public void testAppMetaRoundtrip() throws IOException, TemplateException {
+ setConfiguration(
+ createConfigurationBuilder()
+ .dateFormat("@appMeta")
+ .dateTimeFormat("@appMeta")
+ .timeFormat("@appMeta")
+ .build());
+
+ addToDataModel("t", String.valueOf(T) + "/foo");
+
+ assertOutput(
+ "${t?date} ${t?date()}",
+ T + " " + T + "/foo");
+ assertOutput(
+ "${t?time} ${t?time()}",
+ T + " " + T + "/foo");
+ assertOutput(
+ "${t?datetime} ${t?datetime()}",
+ T + " " + T + "/foo");
+ }
+
+ @Test
+ public void testUnknownDateType() throws IOException, TemplateException {
+ addToDataModel("u", new Date(T));
+ assertErrorContains("${u?string}", "isn't known");
+ assertOutput("${u?string('yyyy')}", "2015");
+ assertOutput("<#assign s = u?string>${s('yyyy')}", "2015");
+ }
+
+ private static class MutableTemplateDateModel implements TemplateDateModel {
+
+ private Date date;
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ @Override
+ public Date getAsDate() throws TemplateModelException {
+ return date;
+ }
+
+ @Override
+ public int getDateType() {
+ return DATETIME;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
new file mode 100644
index 0000000..29220c4
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
@@ -0,0 +1,249 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.freemarker.core.model.TemplateDirectiveBody;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.util.ObjectFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class DirectiveCallPlaceTest extends TemplateTest {
+
+ @Test
+ public void testCustomDataBasics() throws IOException, TemplateException {
+ addTemplate(
+ "customDataBasics.ftl",
+ "<@u...@uc> <@u...@uc> <@uc>Ab<#-- -->c</...@uc> <@l...@lc> <@l...@lc>");
+
+ CachingTextConverterDirective.resetCacheRecreationCount();
+ for (int i = 0; i < 3; i++) {
+ assertOutputForNamed(
+ "customDataBasics.ftl",
+ "ABC[cached 1] X=123 ABC[cached 2] abc[cached 3]");
+ }
+ }
+
+ @Test
+ public void testCustomDataProviderMismatch() throws IOException, TemplateException {
+ addTemplate(
+ "customDataProviderMismatch.ftl",
+ "<#list [uc, lc, uc] as d><#list 1..2 as _><@d...@d></#list></#list>");
+
+ CachingTextConverterDirective.resetCacheRecreationCount();
+ assertOutputForNamed(
+ "customDataProviderMismatch.ftl",
+ "ABC[cached 1]ABC[cached 1]abc[cached 2]abc[cached 2]ABC[cached 3]ABC[cached 3]");
+ assertOutputForNamed(
+ "customDataProviderMismatch.ftl",
+ "ABC[cached 3]ABC[cached 3]abc[cached 4]abc[cached 4]ABC[cached 5]ABC[cached 5]");
+ }
+
+ @Test
+ public void testPositions() throws IOException, TemplateException {
+ addTemplate(
+ "positions.ftl",
+ "<@pa />\n"
+ + "..<@pa\n"
+ + "/><@pa>xxx</@>\n"
+ + "<@pa>{<@pa/> <@pa/>}</@>\n"
+ + "${curDirLine}<@argP p=curDirLine?string>${curDirLine}</...@argP>${curDirLine}\n"
+ + "<#macro m p>(p=${p}){<#nested>}</#macro>\n"
+ + "${curDirLine}<@m p=curDirLine?string>${curDirLine}</...@m>${curDirLine}");
+
+ assertOutputForNamed(
+ "positions.ftl",
+ "[positions.ftl:1:1-1:7]"
+ + "..[positions.ftl:2:3-3:2]"
+ + "[positions.ftl:3:3-3:14]xxx\n"
+ + "[positions.ftl:4:1-4:24]{[positions.ftl:4:7-4:12] [positions.ftl:4:14-4:19]}\n"
+ + "-(p=5){-}-\n"
+ + "-(p=7){-}-"
+ );
+ }
+
+ @SuppressWarnings("boxing")
+ @Override
+ protected Object createDataModel() {
+ Map<String, Object> dm = new HashMap<>();
+ dm.put("uc", new CachingUpperCaseDirective());
+ dm.put("lc", new CachingLowerCaseDirective());
+ dm.put("pa", new PositionAwareDirective());
+ dm.put("argP", new ArgPrinterDirective());
+ dm.put("curDirLine", new CurDirLineScalar());
+ dm.put("x", 123);
+ return dm;
+ }
+
+ private abstract static class CachingTextConverterDirective implements TemplateDirectiveModel {
+
+ /** Only needed for testing. */
+ private static AtomicInteger cacheRecreationCount = new AtomicInteger();
+
+ /** Only needed for testing. */
+ static void resetCacheRecreationCount() {
+ cacheRecreationCount.set(0);
+ }
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, final TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ if (body == null) {
+ return;
+ }
+
+ final String convertedText;
+
+ final DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
+ if (callPlace.isNestedOutputCacheable()) {
+ try {
+ convertedText = (String) callPlace.getOrCreateCustomData(
+ getTextConversionIdentity(), new ObjectFactory<String>() {
+
+ @Override
+ public String createObject() throws TemplateException, IOException {
+ return convertBodyText(body)
+ + "[cached " + cacheRecreationCount.incrementAndGet() + "]";
+ }
+
+ });
+ } catch (CallPlaceCustomDataInitializationException e) {
+ throw new TemplateModelException("Failed to pre-render nested content", e);
+ }
+ } else {
+ convertedText = convertBodyText(body);
+ }
+
+ env.getOut().write(convertedText);
+ }
+
+ protected abstract Class getTextConversionIdentity();
+
+ private String convertBodyText(TemplateDirectiveBody body) throws TemplateException,
+ IOException {
+ StringWriter sw = new StringWriter();
+ body.render(sw);
+ return convertText(sw.toString());
+ }
+
+ protected abstract String convertText(String s);
+
+ }
+
+ private static class CachingUpperCaseDirective extends CachingTextConverterDirective {
+
+ @Override
+ protected String convertText(String s) {
+ return s.toUpperCase();
+ }
+
+ @Override
+ protected Class getTextConversionIdentity() {
+ return CachingUpperCaseDirective.class;
+ }
+
+ }
+
+ private static class CachingLowerCaseDirective extends CachingTextConverterDirective {
+
+ @Override
+ protected String convertText(String s) {
+ return s.toLowerCase();
+ }
+
+ @Override
+ protected Class getTextConversionIdentity() {
+ return CachingLowerCaseDirective.class;
+ }
+
+ }
+
+ private static class PositionAwareDirective implements TemplateDirectiveModel {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ Writer out = env.getOut();
+ DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
+ out.write("[");
+ out.write(getTemplateSourceName(callPlace));
+ out.write(":");
+ out.write(Integer.toString(callPlace.getBeginLine()));
+ out.write(":");
+ out.write(Integer.toString(callPlace.getBeginColumn()));
+ out.write("-");
+ out.write(Integer.toString(callPlace.getEndLine()));
+ out.write(":");
+ out.write(Integer.toString(callPlace.getEndColumn()));
+ out.write("]");
+ if (body != null) {
+ body.render(out);
+ }
+ }
+
+ private String getTemplateSourceName(DirectiveCallPlace callPlace) {
+ return ((ASTDirUserDefined) callPlace).getTemplate().getSourceName();
+ }
+
+ }
+
+ private static class ArgPrinterDirective implements TemplateDirectiveModel {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ final Writer out = env.getOut();
+ if (params.size() > 0) {
+ out.write("(p=");
+ out.write(((TemplateScalarModel) params.get("p")).getAsString());
+ out.write(")");
+ }
+ if (body != null) {
+ out.write("{");
+ body.render(out);
+ out.write("}");
+ }
+ }
+
+ }
+
+ private static class CurDirLineScalar implements TemplateScalarModel {
+
+ @Override
+ public String getAsString() throws TemplateModelException {
+ DirectiveCallPlace callPlace = Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace();
+ return callPlace != null
+ ? String.valueOf(Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace().getBeginLine())
+ : "-";
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.java
new file mode 100644
index 0000000..b1acead
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EncodingOverrideTest.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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.junit.Test;
+
+public class EncodingOverrideTest {
+
+ @Test
+ public void testMarchingCharset() throws Exception {
+ Template t = createConfig(StandardCharsets.UTF_8).getTemplate("encodingOverride-UTF-8.ftl");
+ assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
+ checkTemplateOutput(t);
+ }
+
+ @Test
+ public void testDifferentCharset() throws Exception {
+ Template t = createConfig(StandardCharsets.UTF_8).getTemplate("encodingOverride-ISO-8859-1.ftl");
+ assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
+ checkTemplateOutput(t);
+ }
+
+ private void checkTemplateOutput(Template t) throws TemplateException, IOException {
+ StringWriter out = new StringWriter();
+ t.process(Collections.emptyMap(), out);
+ assertEquals("Béka", out.toString());
+ }
+
+ private Configuration createConfig(Charset charset) {
+ return new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(new ClassTemplateLoader(EncodingOverrideTest.class, ""))
+ .sourceEncoding(charset)
+ .build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
new file mode 100644
index 0000000..b79559c
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.freemarker.core.model.TemplateDirectiveBody;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class EnvironmentGetTemplateVariantsTest extends TemplateTest {
+
+ private static final StringTemplateLoader TEMPLATES = new StringTemplateLoader();
+ static {
+ TEMPLATES.putTemplate("main",
+ "<@tNames />\n"
+ + "---1---\n"
+ + "[imp: <#import 'imp' as i>${i.impIni}]\n"
+ + "---2---\n"
+ + "<@i.impM>"
+ + "<@tNames />"
+ + "</@>\n"
+ + "---3---\n"
+ + "[inc: <#include 'inc'>]\n"
+ + "---4---\n"
+ + "<@incM>"
+ + "<@tNames />"
+ + "</@>\n"
+ + "---5---\n"
+ + "[inc2: <#include 'inc2'>]\n"
+ + "---6---\n"
+ + "<#import 'imp2' as i2>"
+ + "<@i.impM2><@tNames /></@>\n"
+ + "---7---\n"
+ + "<#macro mainM>"
+ + "[mainM: <@tNames /> {<#nested>} <@tNames />]"
+ + "</#macro>"
+ + "[inc3: <#include 'inc3'>]\n"
+ + "<@mainM><@tNames /> <#include 'inc4'> <@tNames /></@>\n"
+ + "<@tNames />\n"
+ + "---8---\n"
+ + "<#function mainF>"
+ + "<@tNames />"
+ + "<#return lastTNamesResult>"
+ + "</#function>"
+ + "mainF: ${mainF()}, impF: ${i.impF()}, incF: ${incF()}\n"
+ );
+ TEMPLATES.putTemplate("inc",
+ "<@tNames />\n"
+ + "<#macro incM>"
+ + "[incM: <@tNames /> {<#nested>}]"
+ + "</#macro>"
+ + "<#function incF>"
+ + "<@tNames />"
+ + "<#return lastTNamesResult>"
+ + "</#function>"
+ + "<@incM><@tNames /></@>\n"
+ + "<#if !included!false>[incInc: <#assign included=true><#include 'inc'>]\n</#if>"
+ );
+ TEMPLATES.putTemplate("imp",
+ "<#assign impIni><@tNames /></#assign>\n"
+ + "<#macro impM>"
+ + "[impM: <@tNames />\n"
+ + "{<#nested>}\n"
+ + "[inc: <#include 'inc'>]\n"
+ + "<@incM><@tNames /></@>\n"
+ + "]"
+ + "</#macro>"
+ + "<#macro impM2>"
+ + "[impM2: <@tNames />\n"
+ + "{<#nested>}\n"
+ + "<@i2.imp2M><@tNames /></@>\n"
+ + "]"
+ + "</#macro>"
+ + "<#function impF>"
+ + "<@tNames />"
+ + "<#return lastTNamesResult>"
+ + "</#function>"
+ );
+ TEMPLATES.putTemplate("inc2",
+ "<@tNames />\n"
+ + "<@i.impM><@tNames /></@>\n"
+ );
+ TEMPLATES.putTemplate("imp2",
+ "<#macro imp2M>"
+ + "[imp2M: <@tNames /> {<#nested>}]"
+ + "</#macro>");
+ TEMPLATES.putTemplate("inc3",
+ "<@tNames />\n"
+ + "<@mainM><@tNames /></@>\n"
+ );
+ TEMPLATES.putTemplate("inc4",
+ "<@tNames />"
+ );
+ }
+
+ @Test
+ public void test() throws IOException, TemplateException {
+ setConfiguration(createConfiguration(Configuration.VERSION_3_0_0));
+ assertOutputForNamed(
+ "main",
+ "<ct=main mt=main>\n"
+ + "---1---\n"
+ + "[imp: <ct=imp mt=main>]\n"
+ + "---2---\n"
+ + "[impM: <ct=imp mt=main>\n"
+ + "{<ct=main mt=main>}\n"
+ + "[inc: <ct=inc mt=main>\n"
+ + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
+ + "[incInc: <ct=inc mt=main>\n"
+ + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
+ + "]\n"
+ + "]\n"
+ + "[incM: <ct=inc mt=main> {<ct=imp mt=main>}]\n"
+ + "]\n"
+ + "---3---\n"
+ + "[inc: <ct=inc mt=main>\n"
+ + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
+ + "[incInc: <ct=inc mt=main>\n"
+ + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
+ + "]\n"
+ + "]\n"
+ + "---4---\n"
+ + "[incM: <ct=inc mt=main> {<ct=main mt=main>}]\n"
+ + "---5---\n"
+ + "[inc2: <ct=inc2 mt=main>\n"
+ + "[impM: <ct=imp mt=main>\n"
+ + "{<ct=inc2 mt=main>}\n"
+ + "[inc: <ct=inc mt=main>\n"
+ + "[incM: <ct=inc mt=main> {<ct=inc mt=main>}]\n"
+ + "]\n"
+ + "[incM: <ct=inc mt=main> {<ct=imp mt=main>}]\n"
+ + "]\n"
+ + "]\n"
+ + "---6---\n"
+ + "[impM2: <ct=imp mt=main>\n"
+ + "{<ct=main mt=main>}\n"
+ + "[imp2M: <ct=imp2 mt=main> {<ct=imp mt=main>}]\n"
+ + "]\n"
+ + "---7---\n"
+ + "[inc3: <ct=inc3 mt=main>\n"
+ + "[mainM: <ct=main mt=main> {<ct=inc3 mt=main>} <ct=main mt=main>]\n"
+ + "]\n"
+ + "[mainM: "
+ + "<ct=main mt=main> "
+ + "{<ct=main mt=main> <ct=inc4 mt=main> <ct=main mt=main>} "
+ + "<ct=main mt=main>"
+ + "]\n"
+ + "<ct=main mt=main>\n"
+ + "---8---\n"
+ + "mainF: <ct=main mt=main>, impF: <ct=imp mt=main>, incF: <ct=inc mt=main>\n"
+ .replaceAll("<t=\\w+", "<t=main"));
+ }
+
+ @Test
+ public void testNotStarted() throws IOException, TemplateException {
+ Template t = new Template("foo", "", createConfiguration(Configuration.VERSION_3_0_0));
+ final Environment env = t.createProcessingEnvironment(null, null);
+ assertSame(t, env.getMainTemplate());
+ assertSame(t, env.getCurrentTemplate());
+ }
+
+ private Configuration createConfiguration(Version iciVersion) {
+ return new TestConfigurationBuilder(iciVersion)
+ .templateLoader(TEMPLATES)
+ .whitespaceStripping(false)
+ .build();
+ }
+
+ @Override
+ protected Object createDataModel() {
+ return Collections.singletonMap("tNames", new TemplateDirectiveModel() {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ Writer out = env.getOut();
+ final String r = "<ct=" + env.getCurrentTemplate().getLookupName() + " mt="
+ + env.getMainTemplate().getLookupName() + ">";
+ out.write(r);
+ env.setGlobalVariable("lastTNamesResult", new SimpleScalar(r));
+ }
+
+ });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ExceptionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ExceptionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ExceptionTest.java
new file mode 100644
index 0000000..19c3b6e
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ExceptionTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Locale;
+
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.core.util._NullWriter;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+
+import junit.framework.TestCase;
+public class ExceptionTest extends TestCase {
+
+ public ExceptionTest(String name) {
+ super(name);
+ }
+
+ public void testParseExceptionSerializable() throws IOException, ClassNotFoundException {
+ try {
+ new Template(null, new StringReader("<@>"), new TestConfigurationBuilder().build());
+ fail();
+ } catch (ParseException e) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ new ObjectOutputStream(out).writeObject(e);
+ new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
+ }
+ }
+
+ public void testTemplateErrorSerializable() throws IOException, ClassNotFoundException {
+ Template tmp = new Template(null, new StringReader("${noSuchVar}"),
+ new TestConfigurationBuilder().build());
+ try {
+ tmp.process(Collections.EMPTY_MAP, new StringWriter());
+ fail();
+ } catch (TemplateException e) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ new ObjectOutputStream(out).writeObject(e);
+ new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ public void testTemplateExceptionLocationInformation() throws IOException {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("foo_en.ftl", "\n\nxxx${noSuchVariable}");
+
+ Template t = new TestConfigurationBuilder().templateLoader(tl).build()
+ .getTemplate("foo.ftl", Locale.US);
+ try {
+ t.process(null, _NullWriter.INSTANCE);
+ fail();
+ } catch (TemplateException e) {
+ assertEquals("foo.ftl", t.getLookupName());
+ assertEquals("foo.ftl", e.getTemplateLookupName());
+ assertEquals("foo_en.ftl", e.getTemplateSourceName());
+ assertEquals(3, (int) e.getLineNumber());
+ assertEquals(6, (int) e.getColumnNumber());
+ assertEquals(3, (int) e.getEndLineNumber());
+ assertEquals(19, (int) e.getEndColumnNumber());
+ assertThat(e.getMessage(), containsString("foo_en.ftl"));
+ assertThat(e.getMessage(), containsString("noSuchVariable"));
+ }
+ }
+
+ @SuppressWarnings("cast")
+ public void testParseExceptionLocationInformation() throws IOException {
+ StringTemplateLoader tl = new StringTemplateLoader();
+ tl.putTemplate("foo_en.ftl", "\n\nxxx<#noSuchDirective>");
+
+ try {
+ new TestConfigurationBuilder().templateLoader(tl).build()
+ .getTemplate("foo.ftl", Locale.US);
+ fail();
+ } catch (ParseException e) {
+ System.out.println(e.getMessage());
+ assertEquals("foo_en.ftl", e.getTemplateSourceName());
+ assertEquals("foo.ftl", e.getTemplateLookupName());
+ assertEquals(3, e.getLineNumber());
+ assertEquals(5, e.getColumnNumber());
+ assertEquals(3, e.getEndLineNumber());
+ assertEquals(20, e.getEndColumnNumber());
+ assertThat(e.getMessage(), containsString("foo_en.ftl"));
+ assertThat(e.getMessage(), containsString("noSuchDirective"));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/GetSourceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/GetSourceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/GetSourceTest.java
new file mode 100644
index 0000000..1462bfc
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/GetSourceTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class GetSourceTest {
+
+ @Test
+ public void testGetSource() throws Exception {
+ {
+ // Note: Default tab size is 8.
+ Template t = new Template(null, "a\n\tb\nc",
+ new TestConfigurationBuilder().build());
+ // A historical quirk we keep for B.C.: it repaces tabs with spaces.
+ assertEquals("a\n b\nc", t.getSource(1, 1, 1, 3));
+ }
+
+ {
+ Template t = new Template(null, "a\n\tb\nc",
+ new TestConfigurationBuilder().tabSize(4).build());
+ assertEquals("a\n b\nc", t.getSource(1, 1, 1, 3));
+ }
+
+ {
+ Template t = new Template(null, "a\n\tb\nc",
+ new TestConfigurationBuilder().tabSize(1).build());
+ // If tab size is 1, it behaves as it always should have: it keeps the tab.
+ assertEquals("a\n\tb\nc", t.getSource(1, 1, 1, 3));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
new file mode 100644
index 0000000..6f8851d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/HeaderParsingTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class HeaderParsingTest extends TemplateTest {
+
+ private final Configuration cfgStripWS = new TestConfigurationBuilder().build();
+ private final Configuration cfgNoStripWS = new TestConfigurationBuilder().whitespaceStripping(false).build();
+
+ @Test
+ public void test() throws IOException, TemplateException {
+ assertOutput("<#ftl>text", "text", "text");
+ assertOutput(" <#ftl> text", " text", " text");
+ assertOutput("\n<#ftl>\ntext", "text", "text");
+ assertOutput("\n \n\n<#ftl> \ntext", "text", "text");
+ assertOutput("\n \n\n<#ftl>\n\ntext", "\ntext", "\ntext");
+ }
+
+ private void assertOutput(final String ftl, String expectedOutStripped, String expectedOutNonStripped)
+ throws IOException, TemplateException {
+ for (int i = 0; i < 4; i++) {
+ String ftlPermutation = ftl;
+ if ((i & 1) == 1) {
+ ftlPermutation = ftlPermutation.replace("<#ftl>", "<#ftl encoding='utf-8'>");
+ }
+ if ((i & 2) == 2) {
+ ftlPermutation = ftlPermutation.replace('<', '[').replace('>', ']');
+ }
+
+ setConfiguration(cfgStripWS);
+ assertOutput(ftlPermutation, expectedOutStripped);
+ setConfiguration(cfgNoStripWS);
+ assertOutput(ftlPermutation, expectedOutNonStripped);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
new file mode 100644
index 0000000..738b4de
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportConfigurableLayersTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class IncludeAndImportConfigurableLayersTest {
+
+ @Test
+ public void test3LayerImportNoClashes() throws Exception {
+ TestConfigurationBuilder cfgB = createConfigurationBuilder()
+ .autoImports(ImmutableMap.of("t1", "t1.ftl"))
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("main.ftl"),
+ new TemplateConfiguration.Builder()
+ .autoImports(ImmutableMap.of("t2", "t2.ftl"))
+ .build()));
+ Configuration cfg = cfgB.build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoImport("t3", "t3.ftl");
+
+ env.process();
+ assertEquals("In main: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+
+ env.process();
+ assertEquals("In main: t1;t2;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main2.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoImport("t3", "t3.ftl");
+
+ env.process();
+ assertEquals("In main2: t1;t3;", sw.toString());
+ }
+
+ cfgB.removeAutoImport("t1");
+ cfg = cfgB.build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoImport("t3", "t3.ftl");
+
+ env.process();
+ assertEquals("In main: t2;t3;", sw.toString());
+ }
+ }
+
+ @Test
+ public void test3LayerImportClashes() throws Exception {
+ Configuration cfg = createConfigurationBuilder()
+ .autoImports(ImmutableMap.of(
+ "t1", "t1.ftl",
+ "t2", "t2.ftl",
+ "t3", "t3.ftl"))
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("main.ftl"),
+ new TemplateConfiguration.Builder()
+ .autoImports(ImmutableMap.of("t2", "t2b.ftl"))
+ .build()))
+ .build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoImport("t3", "t3b.ftl");
+
+ env.process();
+ assertEquals("In main: t1;t2b;t3b;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main2.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoImport("t3", "t3b.ftl");
+
+ env.process();
+ assertEquals("In main2: t1;t2;t3b;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+
+ env.process();
+ assertEquals("In main: t1;t3;t2b;", sw.toString());
+ }
+ }
+
+ @Test
+ public void test3LayerIncludesNoClashes() throws Exception {
+ TestConfigurationBuilder cfgB = createConfigurationBuilder()
+ .autoIncludes(ImmutableList.of("t1.ftl"))
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("main.ftl"),
+ new TemplateConfiguration.Builder()
+ .autoIncludes(ImmutableList.of("t2.ftl"))
+ .build()));
+
+ Configuration cfg = cfgB.build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T1;T2;T3;In main: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+
+ env.process();
+ assertEquals("T1;T2;In main: t1;t2;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main2.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T1;T3;In main2: t1;t3;", sw.toString());
+ }
+
+ cfgB.removeAutoInclude("t1.ftl");
+ cfg = cfgB.build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T2;T3;In main: t2;t3;", sw.toString());
+ }
+ }
+
+ @Test
+ public void test3LayerIncludeClashes() throws Exception {
+ Configuration cfg = createConfigurationBuilder()
+ .autoIncludes(ImmutableList.of(
+ "t1.ftl",
+ "t2.ftl",
+ "t3.ftl"))
+ .templateConfigurations(new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("main.ftl"),
+ new TemplateConfiguration.Builder()
+ .autoIncludes(ImmutableList.of("t2.ftl"))
+ .build()))
+ .build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T1;T2;T3;In main: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main2.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T1;T2;T3;In main2: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+
+ env.process();
+ assertEquals("T1;T3;T2;In main: t1;t3;t2;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t1.ftl");
+
+ env.process();
+ assertEquals("T3;T2;T1;In main: t3;t2;t1;", sw.toString());
+ }
+ }
+
+ @Test
+ public void test3LayerIncludesClashes2() throws Exception {
+ Configuration cfg = createConfigurationBuilder()
+ .autoIncludes(ImmutableList.of("t1.ftl", "t1.ftl"))
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("main.ftl"),
+ new TemplateConfiguration.Builder()
+ .autoIncludes(ImmutableList.of("t2.ftl", "t2.ftl"))
+ .build()))
+ .build();
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+ env.addAutoInclude("t3.ftl");
+ env.addAutoInclude("t1.ftl");
+ env.addAutoInclude("t1.ftl");
+
+ env.process();
+ assertEquals("T2;T3;T1;In main: t2;t3;t1;", sw.toString());
+ }
+ }
+
+ @Test
+ public void test3LayerLaziness() throws Exception {
+ for (Class<?> layer : new Class<?>[] { Configuration.class, Template.class, Environment.class }) {
+ test3LayerLaziness(layer, null, null, false, "t1;t2;");
+ test3LayerLaziness(layer, null, null, true, "t1;t2;");
+ test3LayerLaziness(layer, null, false, true, "t1;t2;");
+ test3LayerLaziness(layer, null, true, true, "t2;");
+
+ test3LayerLaziness(layer, false, null, false, "t1;t2;");
+ test3LayerLaziness(layer, false, null, true, "t1;t2;");
+ test3LayerLaziness(layer, false, false, true, "t1;t2;");
+ test3LayerLaziness(layer, false, true, true, "t2;");
+
+ test3LayerLaziness(layer, true, null, false, "");
+ test3LayerLaziness(layer, true, null, true, "");
+ test3LayerLaziness(layer, true, false, true, "t1;");
+ test3LayerLaziness(layer, true, true, true, "");
+ }
+ }
+
+ private void test3LayerLaziness(
+ Class<?> layer,
+ Boolean lazyImports,
+ Boolean lazyAutoImports, boolean setLazyAutoImports,
+ String expectedOutput)
+ throws Exception {
+ Configuration cfg;
+ {
+ TestConfigurationBuilder cfgB = createConfigurationBuilder()
+ .autoImports(ImmutableMap.of("t1", "t1.ftl"));
+ if (layer == Configuration.class) {
+ setLazinessOfConfigurable(cfgB, lazyImports, lazyAutoImports, setLazyAutoImports);
+ }
+ cfg = cfgB.build();
+ }
+
+ TemplateConfiguration tc;
+ if (layer == Template.class) {
+ TemplateConfiguration.Builder tcb = new TemplateConfiguration.Builder();
+ setLazinessOfConfigurable(tcb, lazyImports, lazyAutoImports, setLazyAutoImports);
+ tc = tcb.build();
+ } else {
+ tc = null;
+ }
+
+ Template t = new Template(null, "<#import 't2.ftl' as t2>${loaded!}", cfg, tc);
+ StringWriter sw = new StringWriter();
+
+ Environment env = t.createProcessingEnvironment(null, sw);
+ if (layer == Environment.class) {
+ setLazinessOfConfigurable(env, lazyImports, lazyAutoImports, setLazyAutoImports);
+ }
+
+ env.process();
+ assertEquals(expectedOutput, sw.toString());
+ }
+
+ private void setLazinessOfConfigurable(
+ MutableProcessingConfiguration<?> cfg,
+ Boolean lazyImports, Boolean lazyAutoImports, boolean setLazyAutoImports) {
+ if (lazyImports != null) {
+ cfg.setLazyImports(lazyImports);
+ }
+ if (setLazyAutoImports) {
+ cfg.setLazyAutoImports(lazyAutoImports);
+ }
+ }
+
+ private TestConfigurationBuilder createConfigurationBuilder() {
+ StringTemplateLoader loader = new StringTemplateLoader();
+ loader.putTemplate("main.ftl", "In main: ${loaded}");
+ loader.putTemplate("main2.ftl", "In main2: ${loaded}");
+ loader.putTemplate("t1.ftl", "<#global loaded = (loaded!) + 't1;'>T1;");
+ loader.putTemplate("t2.ftl", "<#global loaded = (loaded!) + 't2;'>T2;");
+ loader.putTemplate("t3.ftl", "<#global loaded = (loaded!) + 't3;'>T3;");
+ loader.putTemplate("t1b.ftl", "<#global loaded = (loaded!) + 't1b;'>T1b;");
+ loader.putTemplate("t2b.ftl", "<#global loaded = (loaded!) + 't2b;'>T2b;");
+ loader.putTemplate("t3b.ftl", "<#global loaded = (loaded!) + 't3b;'>T3b;");
+
+ return new TestConfigurationBuilder().templateLoader(loader);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
new file mode 100644
index 0000000..fa767ff
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java
@@ -0,0 +1,270 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.freemarker.core.Environment.LazilyInitializedNamespace;
+import org.apache.freemarker.core.Environment.Namespace;
+import org.apache.freemarker.core.model.WrappingTemplateModel;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class IncludeAndImportTest extends TemplateTest {
+
+ @Override
+ protected void addCommonTemplates() {
+ addTemplate("inc1.ftl", "[inc1]<#global inc1Cnt = (inc1Cnt!0) + 1><#global history = (history!) + 'I'>");
+ addTemplate("inc2.ftl", "[inc2]");
+ addTemplate("inc3.ftl", "[inc3]");
+ addTemplate("lib1.ftl", "<#global lib1Cnt = (lib1Cnt!0) + 1><#global history = (history!) + 'L1'>"
+ + "<#macro m>In lib1</#macro>");
+ addTemplate("lib2.ftl", "<#global history = (history!) + 'L2'>"
+ + "<#macro m>In lib2</#macro>");
+ addTemplate("lib3.ftl", "<#global history = (history!) + 'L3'>"
+ + "<#macro m>In lib3</#macro>");
+
+ addTemplate("lib2CallsLib1.ftl", "<#global history = (history!) + 'L2'>"
+ + "<#macro m>In lib2 (<@lib1.m/>)</#macro>");
+ addTemplate("lib3ImportsLib1.ftl", "<#import 'lib1.ftl' as lib1><#global history = (history!) + 'L3'>"
+ + "<#macro m>In lib3 (<@lib1.m/>)</#macro>");
+
+ addTemplate("lib_de.ftl", "<#global history = (history!) + 'LDe'><#assign initLocale=.locale>"
+ + "<#macro m>de</#macro>");
+ addTemplate("lib_en.ftl", "<#global history = (history!) + 'LEn'><#assign initLocale=.locale>"
+ + "<#macro m>en</#macro>");
+ }
+
+ @Test
+ public void includeSameTwice() throws IOException, TemplateException {
+ assertOutput("<#include 'inc1.ftl'>${inc1Cnt}<#include 'inc1.ftl'>${inc1Cnt}", "[inc1]1[inc1]2");
+ }
+
+ @Test
+ public void importSameTwice() throws IOException, TemplateException {
+ assertOutput("<#import 'lib1.ftl' as i1>${lib1Cnt} <#import 'lib1.ftl' as i2>${lib1Cnt}", "1 1");
+ }
+
+ @Test
+ public void importInMainCreatesGlobal() throws IOException, TemplateException {
+ String ftl = "${.main.lib1???c} ${.globals.lib1???c}"
+ + "<#import 'lib1.ftl' as lib1> ${.main.lib1???c} ${.globals.lib1???c}";
+ String expectedOut = "false false true true";
+ assertOutput(ftl, expectedOut);
+ }
+
+ @Test
+ public void importInMainCreatesGlobalBugfix() throws IOException, TemplateException {
+ // An import in the main namespace should invoke a global variable, even if the imported library was already
+ // initialized elsewhere.
+ String ftl = "<#import 'lib3ImportsLib1.ftl' as lib3>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}, "
+ + "<#import 'lib1.ftl' as lib1>${lib1Cnt} ${.main.lib1???c} ${.globals.lib1???c}";
+ assertOutput(ftl, "1 false false, 1 true true");
+ }
+
+ /**
+ * Tests the order of auto-includes and auto-imports, also that they only effect the main template directly.
+ */
+ @Test
+ public void autoIncludeAndAutoImport() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .autoImports(ImmutableMap.of(
+ "lib1", "lib1.ftl",
+ "lib2", "lib2CallsLib1.ftl"
+ ))
+ .autoIncludes(ImmutableList.of(
+ "inc1.ftl",
+ "inc2.ftl"))
+ .build());
+ assertOutput(
+ "<#include 'inc3.ftl'>[main] ${inc1Cnt}, ${history}, <@lib1.m/>, <@lib2.m/>",
+ "[inc1][inc2][inc3][main] 1, L1L2I, In lib1, In lib2 (In lib1)");
+ }
+
+ /**
+ * Demonstrates design issue in FreeMarker 2.3.x where the lookupStrategy is not factored in when identifying
+ * already existing namespaces.
+ */
+ @Test
+ public void lookupSrategiesAreNotConsideredProperly() throws IOException, TemplateException {
+ // As only the name of the template is used for the finding the already existing namespace, the settings that
+ // influence the lookup are erroneously ignored.
+ assertOutput(
+ "<#setting locale='en_US'><#import 'lib.ftl' as ns1>"
+ + "<#setting locale='de_DE'><#import 'lib.ftl' as ns2>"
+ + "<@ns1.m/> <@ns2.m/> ${history}",
+ "en en LEn");
+
+ // The opposite of the prevous, where differn names refer to the same template after a lookup:
+ assertOutput(
+ "<#setting locale='en_US'>"
+ + "<#import '*/lib.ftl' as ns1>"
+ + "<#import 'lib.ftl' as ns2>"
+ + "<@ns1.m/> <@ns2.m/> ${history}",
+ "en en LEnLEn");
+ }
+
+ @Test
+ public void lazyImportBasics() throws IOException, TemplateException {
+ String ftlImports = "<#import 'lib1.ftl' as l1><#import 'lib2.ftl' as l2><#import 'lib3ImportsLib1.ftl' as l3>";
+ String ftlCalls = "<@l2.m/>, <@l1.m/>; ${history}";
+ String ftl = ftlImports + ftlCalls;
+
+ assertOutput(ftl, "In lib2, In lib1; L1L2L3");
+
+ setConfiguration(new TestConfigurationBuilder().lazyImports(true).build());
+ assertOutput(ftl, "In lib2, In lib1; L2L1");
+
+ assertOutput(ftlImports + "<@l3.m/>, " + ftlCalls, "In lib3 (In lib1), In lib2, In lib1; L3L1L2");
+ }
+
+ @Test
+ public void lazyImportAndLocale() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder().lazyImports(true).build());
+ assertOutput("<#setting locale = 'de_DE'><#import 'lib.ftl' as lib>"
+ + "[${history!}] "
+ + "<#setting locale = 'en'>"
+ + "<@lib.m/> ${lib.initLocale} [${history}]",
+ "[] de de_DE [LDe]");
+ }
+
+ @Test
+ public void lazyAutoImportSettings() throws IOException, TemplateException {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
+ .autoImports(ImmutableMap.of(
+ "l1", "lib1.ftl",
+ "l2", "lib2.ftl",
+ "l3", "lib3.ftl"
+ ));
+
+ String ftl = "<@l2.m/>, <@l1.m/>; ${history}";
+ String expectedEagerOutput = "In lib2, In lib1; L1L2L3";
+ String expecedLazyOutput = "In lib2, In lib1; L2L1";
+
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expectedEagerOutput);
+ cfgB.setLazyImports(true);
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expecedLazyOutput);
+ cfgB.setLazyImports(false);
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expectedEagerOutput);
+ cfgB.setLazyAutoImports(true);
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expecedLazyOutput);
+ cfgB.setLazyAutoImports(null);
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expectedEagerOutput);
+ cfgB.setLazyImports(true);
+ cfgB.setLazyAutoImports(false);
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expectedEagerOutput);
+ }
+
+ @Test
+ public void lazyAutoImportMixedWithManualImport() throws IOException, TemplateException {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
+ .autoImports(ImmutableMap.of(
+ "l1", "lib1.ftl",
+ "l2", "/./lib2.ftl",
+ "l3", "lib3.ftl"))
+ .lazyAutoImports(true);
+
+ String ftl = "<@l2.m/>, <@l1.m/>; ${history}";
+ String expectOutputWithoutHistory = "In lib2, In lib1; ";
+ String expecedOutput = expectOutputWithoutHistory + "L2L1";
+
+ setConfiguration(cfgB.build());
+ assertOutput(ftl, expecedOutput);
+ assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2");
+ assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2");
+ assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput);
+ assertOutput("<#import 'lib3.ftl' as l3>" + ftl, expectOutputWithoutHistory + "L3L2L1");
+
+ cfgB.setLazyImports(true);
+ setConfiguration(cfgB.build());
+ assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expecedOutput);
+ assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expecedOutput);
+ assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput);
+ assertOutput("<#import 'lib3.ftl' as l3>" + ftl, expecedOutput);
+ }
+
+ @Test
+ public void lazyImportErrors() throws IOException, TemplateException {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
+ cfgB.setLazyImports(true);
+
+ setConfiguration(cfgB.build());
+ assertOutput("<#import 'noSuchTemplate.ftl' as wrong>x", "x");
+
+ cfgB.addAutoImport("wrong", "noSuchTemplate.ftl");
+ setConfiguration(cfgB.build());
+ assertOutput("x", "x");
+
+ try {
+ assertOutput("${wrong.x}", "");
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(),
+ allOf(containsString("Lazy initialization"), containsString("noSuchTemplate.ftl")));
+ assertThat(e.getCause(), instanceOf(TemplateNotFoundException.class));
+ }
+
+ addTemplate("containsError.ftl", "${noSuchVar}");
+ try {
+ assertOutput("<#import 'containsError.ftl' as lib>${lib.x}", "");
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(),
+ allOf(containsString("Lazy initialization"), containsString("containsError.ftl")));
+ assertThat(e.getCause(), instanceOf(InvalidReferenceException.class));
+ assertThat(e.getCause().getMessage(), containsString("noSuchVar"));
+ }
+ }
+
+ /**
+ * Ensures that all methods are overridden so that they will do the lazy initialization.
+ */
+ @Test
+ public void lazilyInitializingNamespaceOverridesAll() throws SecurityException, NoSuchMethodException {
+ for (Method m : Namespace.class.getMethods()) {
+ Class<?> declClass = m.getDeclaringClass();
+ if (declClass == Object.class || declClass == WrappingTemplateModel.class
+ || (m.getModifiers() & Modifier.STATIC) != 0
+ || m.getName().equals("synchronizedWrapper")) {
+ continue;
+ }
+ Method lazyM = LazilyInitializedNamespace.class.getMethod(m.getName(), m.getParameterTypes());
+ if (lazyM.getDeclaringClass() != LazilyInitializedNamespace.class) {
+ fail("The " + lazyM + " method wasn't overidden in " + LazilyInitializedNamespace.class.getName());
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.java
new file mode 100644
index 0000000..f4908b8
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncudeFromNamelessTest.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.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+
+import junit.framework.TestCase;
+
+public class IncudeFromNamelessTest extends TestCase {
+
+ public IncudeFromNamelessTest(String name) {
+ super(name);
+ }
+
+ public void test() throws IOException, TemplateException {
+ StringTemplateLoader loader = new StringTemplateLoader();
+ loader.putTemplate("i.ftl", "[i]");
+ loader.putTemplate("sub/i.ftl", "[sub/i]");
+ loader.putTemplate("import.ftl", "<#assign x = 1>");
+
+ Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
+
+ Template t = new Template(null, new StringReader(
+ "<#include 'i.ftl'>\n"
+ + "<#include '/i.ftl'>\n"
+ + "<#include 'sub/i.ftl'>\n"
+ + "<#include '/sub/i.ftl'>"
+ + "<#import 'import.ftl' as i>${i.x}"
+ ),
+ cfg);
+ StringWriter out = new StringWriter();
+ t.process(null, out);
+ assertEquals("[i][i][sub/i][sub/i]1", out.toString());
+ }
+
+}
[50/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
deleted file mode 100644
index c01422e..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.core.model.impl;
-
-public interface Java8DefaultMethodsBeanBase {
-
- static final String DEFAULT_METHOD_PROP = "defaultMethodProp";
- static final String DEFAULT_METHOD_PROP_VALUE = "defaultMethodPropValue";
- static final String DEFAULT_METHOD_PROP_2 = "defaultMethodProp2";
- static final String DEFAULT_METHOD_INDEXED_PROP = "defaultMethodIndexedProp";
- static final String DEFAULT_METHOD_INDEXED_PROP_GETTER = "getDefaultMethodIndexedProp";
- static final String DEFAULT_METHOD_INDEXED_PROP_VALUE = "defaultMethodIndexedPropValue";
- static final String DEFAULT_METHOD_INDEXED_PROP_2 = "defaultMethodIndexedProp2";
- static final String DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0 = "defaultMethodIndexedProp2(0).value";
- static final String DEFAULT_METHOD_INDEXED_PROP_3 = "defaultMethodIndexedProp3";
- static final String DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0 = "indexedProp3Value[0]";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP = "defaultMethodNotAnIndexedProp";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_VALUE = "defaultMethodNotAnIndexedPropValue";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2 = "defaultMethodNotAnIndexedProp2";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE = "defaultMethodNotAnIndexedProp2Value";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3 = "defaultMethodNotAnIndexedProp3";
- static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 = "defaultMethodNotAnIndexedProp3Value[0]";
- static final String DEFAULT_METHOD_ACTION = "defaultMethodAction";
- static final String DEFAULT_METHOD_ACTION_RETURN_VALUE = "defaultMethodActionReturnValue";
- static final String OVERRIDDEN_DEFAULT_METHOD_ACTION = "overriddenDefaultMethodAction";
-
- default String getDefaultMethodProp() {
- return DEFAULT_METHOD_PROP_VALUE;
- }
-
- default String getDefaultMethodProp2() {
- return "";
- }
-
- /**
- * Will be kept as there's no non-indexed read methods for this.
- */
- default String getDefaultMethodIndexedProp(int i) {
- return DEFAULT_METHOD_INDEXED_PROP_VALUE;
- }
-
- /**
- * Will be kept as there will be a matching non-indexed read method in the subclass.
- * However, as of FM3, the non-indexed read method is used if it's available.
- */
- default String getDefaultMethodIndexedProp2(int i) {
- return DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0;
- }
-
- /**
- * This is not an indexed reader method, but a matching indexed reader method will be added in the subclass.
- * However, as of FM3, the non-indexed read method is used if it's available.
- */
- default String[] getDefaultMethodIndexedProp3() {
- return new String[] {DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0};
- }
-
- /** Will be discarded because of a non-matching non-indexed read method in a subclass */
- default String getDefaultMethodNotAnIndexedProp(int i) {
- return "";
- }
-
- /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
- default String getDefaultMethodNotAnIndexedProp2() {
- return DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE;
- }
-
- /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
- default String[] getDefaultMethodNotAnIndexedProp3() {
- return new String[] { DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 };
- }
-
- default String defaultMethodAction() {
- return DEFAULT_METHOD_ACTION_RETURN_VALUE;
- }
-
- default Object overriddenDefaultMethodAction() {
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
deleted file mode 100644
index 495f3f9..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import java.util.Collections;
-
-import org.junit.Test;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-public class Java8DefaultObjectWrapperBridgeMethodsTest {
-
- @Test
- public void testWithoutDefaultMethod() throws TemplateModelException {
- test(BridgeMethodsBean.class);
- }
-
- @Test
- public void testWithDefaultMethod() throws TemplateModelException {
- test(Java8BridgeMethodsWithDefaultMethodBean.class);
- }
-
- @Test
- public void testWithDefaultMethod2() throws TemplateModelException {
- test(Java8BridgeMethodsWithDefaultMethodBean2.class);
- }
-
- private void test(Class<?> pClass) throws TemplateModelException {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- TemplateHashModel wrapped;
- try {
- wrapped = (TemplateHashModel) ow.wrap(pClass.newInstance());
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
-
- TemplateMethodModelEx m1 = (TemplateMethodModelEx) wrapped.get("m1");
- assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.exec(Collections.emptyList()));
-
- TemplateMethodModelEx m2 = (TemplateMethodModelEx) wrapped.get("m2");
- assertNull(m2.exec(Collections.emptyList()));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java b/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
deleted file mode 100644
index 905d536..0000000
--- a/freemarker-core-java8-test/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import java.util.Collections;
-
-import org.junit.Test;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-
-public class Java8DefaultObjectWrapperTest {
-
- @Test
- public void testDefaultMethodRecognized() throws TemplateModelException {
- DefaultObjectWrapper.Builder owb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
- DefaultObjectWrapper ow = owb.build();
- TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
-
- {
- TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
- }
- {
- // This is overridden in the subclass, so it's visible even without default method support:
- TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
- }
- {
- TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
- Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP_VALUE, prop.getAsString());
- }
- {
- // Has only indexed read method, so it's not exposed as a property
- assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
-
- TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_GETTER);
- assertNotNull(indexedReadMethod);
- assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE,
- ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
- .getAsString
- ());
- }
- {
- // We see default method indexed read method, but it's invalidated by normal getter in the subclass
- TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
- }
- {
- // The default method read method invalidates the indexed read method in the subclass
- TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE, prop.getAsString());
- }
- {
- // The default method read method invalidates the indexed read method in the subclass
- TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0,
- ((TemplateScalarModel) prop.get(0)).getAsString());
- }
- {
- // We see the default method indexed reader, which overrides the plain array reader in the subclass.
- TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBean.ARRAY_PROP_2_VALUE_0,
- ((TemplateScalarModel) prop.get(0)).getAsString());
- }
- {
- // We do see the default method non-indexed reader, but the subclass has a matching indexed reader, so that
- // takes over.
- TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
- assertNotNull(prop);
- assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0,
- ((TemplateScalarModel) prop.get(0)).getAsString());
- }
- {
- // Only present in the subclass.
-
- // Has only indexed read method, so it's not exposed as a property
- assertNull(wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4));
-
- TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBean.INDEXED_PROP_GETTER_4);
- assertNotNull(indexedReadMethod);
- assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
- ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
- .getAsString());
- }
- {
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBean.NORMAL_ACTION);
- assertNotNull(action);
- assertEquals(
- Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
- }
-
- {
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBean.NORMAL_ACTION);
- assertNotNull(action);
- assertEquals(
- Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
- }
- {
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
- assertNotNull(action);
- assertEquals(
- Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
- }
- {
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
- Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
- assertNotNull(action);
- assertEquals(
- Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/build.gradle
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/build.gradle b/freemarker-core-test-java8/build.gradle
new file mode 100644
index 0000000..44b95ae
--- /dev/null
+++ b/freemarker-core-test-java8/build.gradle
@@ -0,0 +1,25 @@
+description = """\
+The unit tests of freemarker-core that need Java 8 features. These were moved to a separate project to avoid \
+a project that contains java files that require varous Java versions.
+"""
+
+// Override inherited default Java version:
+sourceCompatibility = "1.8"
+targetCompatibility = "1.8"
+[compileJava, compileTestJava]*.options*.bootClasspath = bootClasspathJava8
+
+dependencies {
+ compile project(":freemarker-core")
+ compile project(":freemarker-test-utils")
+}
+
+// We have nothing to put into the jar, as we have test classes only
+jar.enabled = false
+
+javadoc.enabled = false
+
+// Must not be deployed to a public Maven repository
+uploadArchives.enabled = false
+
+// Doesn't make sense to Maven "install" this, as the artifact won't contain test classes
+install.enabled = false
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/main/resources/META-INF/DISCLAIMER
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/main/resources/META-INF/DISCLAIMER b/freemarker-core-test-java8/src/main/resources/META-INF/DISCLAIMER
new file mode 100644
index 0000000..569ba05
--- /dev/null
+++ b/freemarker-core-test-java8/src/main/resources/META-INF/DISCLAIMER
@@ -0,0 +1,8 @@
+Apache FreeMarker is an effort undergoing incubation at The Apache Software
+Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of
+all newly accepted projects until a further review indicates that the
+infrastructure, communications, and decision making process have stabilized in
+a manner consistent with other successful ASF projects. While incubation
+status is not necessarily a reflection of the completeness or stability of the
+code, it does indicate that the project has yet to be fully endorsed by the
+ASF.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/main/resources/META-INF/LICENSE b/freemarker-core-test-java8/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/freemarker-core-test-java8/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.java
new file mode 100644
index 0000000..2c9d4e9
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBean.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.core.model.impl;
+
+public class BridgeMethodsBean extends BridgeMethodsBeanBase<String> {
+
+ static final String M1_RETURN_VALUE = "m1ReturnValue";
+
+ @Override
+ public String m1() {
+ return M1_RETURN_VALUE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
new file mode 100644
index 0000000..4ecec7c
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/BridgeMethodsBeanBase.java
@@ -0,0 +1,29 @@
+/*
+ * 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.core.model.impl;
+
+public abstract class BridgeMethodsBeanBase<T> {
+
+ public abstract T m1();
+
+ public T m2() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
new file mode 100644
index 0000000..c7d27a6
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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.core.model.impl;
+
+public class Java8BridgeMethodsWithDefaultMethodBean implements Java8BridgeMethodsWithDefaultMethodBeanBase<String> {
+
+ static final String M1_RETURN_VALUE = "m1ReturnValue";
+
+ public String m1() {
+ return M1_RETURN_VALUE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
new file mode 100644
index 0000000..7dfb39a
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBean2.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.model.impl;
+
+public class Java8BridgeMethodsWithDefaultMethodBean2 implements Java8BridgeMethodsWithDefaultMethodBeanBase2 {
+ // All inherited
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
new file mode 100644
index 0000000..fdd8821
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.model.impl;
+
+public interface Java8BridgeMethodsWithDefaultMethodBeanBase<T> {
+
+ default T m1() {
+ return null;
+ }
+
+ default T m2() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
new file mode 100644
index 0000000..6f68dc7
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8BridgeMethodsWithDefaultMethodBeanBase2.java
@@ -0,0 +1,28 @@
+/*
+ * 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.core.model.impl;
+
+public interface Java8BridgeMethodsWithDefaultMethodBeanBase2 extends Java8BridgeMethodsWithDefaultMethodBeanBase<String> {
+
+ @Override
+ default String m1() {
+ return Java8BridgeMethodsWithDefaultMethodBean.M1_RETURN_VALUE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
new file mode 100644
index 0000000..eabc3d0
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBean.java
@@ -0,0 +1,84 @@
+/*
+ * 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.core.model.impl;
+
+public class Java8DefaultMethodsBean implements Java8DefaultMethodsBeanBase {
+
+ static final String NORMAL_PROP = "normalProp";
+ static final String NORMAL_PROP_VALUE = "normalPropValue";
+ static final String PROP_2_OVERRIDE_VALUE = "prop2OverrideValue";
+ static final int NOT_AN_INDEXED_PROP_VALUE = 1;
+ static final String ARRAY_PROP_2_VALUE_0 = "arrayProp2[0].value";
+ private static final int NOT_AN_INDEXED_PROP_3_VALUE = 3;
+ private static final String NOT_AN_INDEXED_PROP_2_VALUE = "notAnIndecedProp2Value";
+ static final String INDEXED_PROP_4 = "indexedProp4";
+ static final String INDEXED_PROP_GETTER_4 = "getIndexedProp4";
+ static final String INDEXED_PROP_4_VALUE = "indexedProp4Value[0]";
+ static final String NORMAL_ACTION = "normalAction";
+ static final String NORMAL_ACTION_RETURN_VALUE = "normalActionReturnValue";
+ static final String OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE = "overriddenValue";
+
+ public String getNormalProp() {
+ return NORMAL_PROP_VALUE;
+ }
+
+ @Override
+ public String getDefaultMethodProp2() {
+ return PROP_2_OVERRIDE_VALUE;
+ }
+
+ public String[] getDefaultMethodIndexedProp2() {
+ return new String[] { ARRAY_PROP_2_VALUE_0 };
+ }
+
+ /**
+ * There's a matching non-indexed reader method in the base class, but as this is indexed, it takes over.
+ */
+ public String getDefaultMethodIndexedProp3(int index) {
+ return "";
+ }
+
+ public int getDefaultMethodNotAnIndexedProp() {
+ return NOT_AN_INDEXED_PROP_VALUE;
+ }
+
+ /** Actually, this will be indexed if the default method support is off. */
+ public String getDefaultMethodNotAnIndexedProp2(int index) {
+ return NOT_AN_INDEXED_PROP_2_VALUE;
+ }
+
+ /** Actually, this will be indexed if the default method support is off. */
+ public int getDefaultMethodNotAnIndexedProp3(int index) {
+ return NOT_AN_INDEXED_PROP_3_VALUE;
+ }
+
+ public String getIndexedProp4(int index) {
+ return INDEXED_PROP_4_VALUE;
+ }
+
+ public String normalAction() {
+ return NORMAL_ACTION_RETURN_VALUE;
+ }
+
+ @Override
+ public String overriddenDefaultMethodAction() {
+ return OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
new file mode 100644
index 0000000..c01422e
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultMethodsBeanBase.java
@@ -0,0 +1,97 @@
+/*
+ * 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.core.model.impl;
+
+public interface Java8DefaultMethodsBeanBase {
+
+ static final String DEFAULT_METHOD_PROP = "defaultMethodProp";
+ static final String DEFAULT_METHOD_PROP_VALUE = "defaultMethodPropValue";
+ static final String DEFAULT_METHOD_PROP_2 = "defaultMethodProp2";
+ static final String DEFAULT_METHOD_INDEXED_PROP = "defaultMethodIndexedProp";
+ static final String DEFAULT_METHOD_INDEXED_PROP_GETTER = "getDefaultMethodIndexedProp";
+ static final String DEFAULT_METHOD_INDEXED_PROP_VALUE = "defaultMethodIndexedPropValue";
+ static final String DEFAULT_METHOD_INDEXED_PROP_2 = "defaultMethodIndexedProp2";
+ static final String DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0 = "defaultMethodIndexedProp2(0).value";
+ static final String DEFAULT_METHOD_INDEXED_PROP_3 = "defaultMethodIndexedProp3";
+ static final String DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0 = "indexedProp3Value[0]";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP = "defaultMethodNotAnIndexedProp";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_VALUE = "defaultMethodNotAnIndexedPropValue";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2 = "defaultMethodNotAnIndexedProp2";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE = "defaultMethodNotAnIndexedProp2Value";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3 = "defaultMethodNotAnIndexedProp3";
+ static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 = "defaultMethodNotAnIndexedProp3Value[0]";
+ static final String DEFAULT_METHOD_ACTION = "defaultMethodAction";
+ static final String DEFAULT_METHOD_ACTION_RETURN_VALUE = "defaultMethodActionReturnValue";
+ static final String OVERRIDDEN_DEFAULT_METHOD_ACTION = "overriddenDefaultMethodAction";
+
+ default String getDefaultMethodProp() {
+ return DEFAULT_METHOD_PROP_VALUE;
+ }
+
+ default String getDefaultMethodProp2() {
+ return "";
+ }
+
+ /**
+ * Will be kept as there's no non-indexed read methods for this.
+ */
+ default String getDefaultMethodIndexedProp(int i) {
+ return DEFAULT_METHOD_INDEXED_PROP_VALUE;
+ }
+
+ /**
+ * Will be kept as there will be a matching non-indexed read method in the subclass.
+ * However, as of FM3, the non-indexed read method is used if it's available.
+ */
+ default String getDefaultMethodIndexedProp2(int i) {
+ return DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0;
+ }
+
+ /**
+ * This is not an indexed reader method, but a matching indexed reader method will be added in the subclass.
+ * However, as of FM3, the non-indexed read method is used if it's available.
+ */
+ default String[] getDefaultMethodIndexedProp3() {
+ return new String[] {DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0};
+ }
+
+ /** Will be discarded because of a non-matching non-indexed read method in a subclass */
+ default String getDefaultMethodNotAnIndexedProp(int i) {
+ return "";
+ }
+
+ /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
+ default String getDefaultMethodNotAnIndexedProp2() {
+ return DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE;
+ }
+
+ /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
+ default String[] getDefaultMethodNotAnIndexedProp3() {
+ return new String[] { DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 };
+ }
+
+ default String defaultMethodAction() {
+ return DEFAULT_METHOD_ACTION_RETURN_VALUE;
+ }
+
+ default Object overriddenDefaultMethodAction() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
new file mode 100644
index 0000000..495f3f9
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModelException;
+
+public class Java8DefaultObjectWrapperBridgeMethodsTest {
+
+ @Test
+ public void testWithoutDefaultMethod() throws TemplateModelException {
+ test(BridgeMethodsBean.class);
+ }
+
+ @Test
+ public void testWithDefaultMethod() throws TemplateModelException {
+ test(Java8BridgeMethodsWithDefaultMethodBean.class);
+ }
+
+ @Test
+ public void testWithDefaultMethod2() throws TemplateModelException {
+ test(Java8BridgeMethodsWithDefaultMethodBean2.class);
+ }
+
+ private void test(Class<?> pClass) throws TemplateModelException {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ TemplateHashModel wrapped;
+ try {
+ wrapped = (TemplateHashModel) ow.wrap(pClass.newInstance());
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ TemplateMethodModelEx m1 = (TemplateMethodModelEx) wrapped.get("m1");
+ assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.exec(Collections.emptyList()));
+
+ TemplateMethodModelEx m2 = (TemplateMethodModelEx) wrapped.get("m2");
+ assertNull(m2.exec(Collections.emptyList()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
new file mode 100644
index 0000000..905d536
--- /dev/null
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+
+public class Java8DefaultObjectWrapperTest {
+
+ @Test
+ public void testDefaultMethodRecognized() throws TemplateModelException {
+ DefaultObjectWrapper.Builder owb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
+ DefaultObjectWrapper ow = owb.build();
+ TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
+
+ {
+ TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
+ }
+ {
+ // This is overridden in the subclass, so it's visible even without default method support:
+ TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
+ }
+ {
+ TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+ Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP_VALUE, prop.getAsString());
+ }
+ {
+ // Has only indexed read method, so it's not exposed as a property
+ assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
+
+ TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_GETTER);
+ assertNotNull(indexedReadMethod);
+ assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE,
+ ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
+ .getAsString
+ ());
+ }
+ {
+ // We see default method indexed read method, but it's invalidated by normal getter in the subclass
+ TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
+ }
+ {
+ // The default method read method invalidates the indexed read method in the subclass
+ TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE, prop.getAsString());
+ }
+ {
+ // The default method read method invalidates the indexed read method in the subclass
+ TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0,
+ ((TemplateScalarModel) prop.get(0)).getAsString());
+ }
+ {
+ // We see the default method indexed reader, which overrides the plain array reader in the subclass.
+ TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBean.ARRAY_PROP_2_VALUE_0,
+ ((TemplateScalarModel) prop.get(0)).getAsString());
+ }
+ {
+ // We do see the default method non-indexed reader, but the subclass has a matching indexed reader, so that
+ // takes over.
+ TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
+ assertNotNull(prop);
+ assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_3_VALUE_0,
+ ((TemplateScalarModel) prop.get(0)).getAsString());
+ }
+ {
+ // Only present in the subclass.
+
+ // Has only indexed read method, so it's not exposed as a property
+ assertNull(wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4));
+
+ TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBean.INDEXED_PROP_GETTER_4);
+ assertNotNull(indexedReadMethod);
+ assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
+ ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
+ .getAsString());
+ }
+ {
+ TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBean.NORMAL_ACTION);
+ assertNotNull(action);
+ assertEquals(
+ Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
+ ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ }
+
+ {
+ TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBean.NORMAL_ACTION);
+ assertNotNull(action);
+ assertEquals(
+ Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
+ ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ }
+ {
+ TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
+ assertNotNull(action);
+ assertEquals(
+ Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
+ ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ }
+ {
+ TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
+ assertNotNull(action);
+ assertEquals(
+ Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
+ ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/build.gradle
----------------------------------------------------------------------
diff --git a/freemarker-core-test/build.gradle b/freemarker-core-test/build.gradle
new file mode 100644
index 0000000..411f6ea
--- /dev/null
+++ b/freemarker-core-test/build.gradle
@@ -0,0 +1,19 @@
+description = """\
+The unit tests of freemarker-core. These tests used to be in freemarker-core, but to avoid depenency loop \
+through freemarker-test-utils, they had to be moved into a separate project."""
+
+dependencies {
+ compile project(":freemarker-core")
+ compile project(":freemarker-test-utils")
+}
+
+// We have nothing to put into the jar, as we have test classes only
+jar.enabled = false
+
+javadoc.enabled = false
+
+// Must not be deployed to a public Maven repository
+uploadArchives.enabled = false
+
+// Doesn't make sense to Maven "install" this, as the artifact won't contain test classes
+install.enabled = false
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
new file mode 100644
index 0000000..10d63b3
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTBasedErrorMessagesTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.core;
+
+import java.util.Map;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class ASTBasedErrorMessagesTest extends TemplateTest {
+
+ @Test
+ public void testInvalidRefBasic() {
+ assertErrorContains("${foo}", "foo", "specify a default");
+ assertErrorContains("${map[foo]}", "foo", "\\!map[", "specify a default");
+ }
+
+ @Test
+ public void testInvalidRefDollar() {
+ assertErrorContains("${$x}", "$x", "must not start with \"$\"", "specify a default");
+ assertErrorContains("${map.$x}", "map.$x", "must not start with \"$\"", "specify a default");
+ }
+
+ @Test
+ public void testInvalidRefAfterDot() {
+ assertErrorContains("${map.foo.bar}", "map.foo", "\\!foo.bar", "after the last dot", "specify a default");
+ }
+
+ @Test
+ public void testInvalidRefInSquareBrackets() {
+ assertErrorContains("${map['foo']}", "map", "final [] step", "specify a default");
+ }
+
+ @Test
+ public void testInvalidRefSize() {
+ assertErrorContains("${map.size()}", "map.size", "?size", "specify a default");
+ assertErrorContains("${map.length()}", "map.length", "?length", "specify a default");
+ }
+
+ @Override
+ protected Object createDataModel() {
+ Map<String, Object> dataModel = createCommonTestValuesDataModel();
+ dataModel.put("overloads", new Overloads());
+ return dataModel;
+ }
+
+ public static class Overloads {
+
+ @SuppressWarnings("unused")
+ public void m(String s) {}
+
+ @SuppressWarnings("unused")
+ public void m(int i) {}
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTPrinter.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTPrinter.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTPrinter.java
new file mode 100644
index 0000000..3518b29
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTPrinter.java
@@ -0,0 +1,438 @@
+/*
+ * 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.core;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util.FTLUtil;
+import org.apache.freemarker.core.util._ClassUtil;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+
+/**
+ * Static methods and command-line tool for printing the AST of a template.
+ */
+public class ASTPrinter {
+
+ private final Configuration cfg;
+ private int successfulCounter;
+ private int failedCounter;
+
+ static public void main(String[] args) throws IOException {
+ if (args.length == 0) {
+ usage();
+ System.exit(-1);
+ }
+
+ ASTPrinter astp = new ASTPrinter();
+ if (args[0].equalsIgnoreCase("-r")) {
+ astp.mainRecursive(args);
+ } else {
+ astp.mainSingleTemplate(args);
+ }
+ }
+
+ private ASTPrinter() {
+ cfg = new TestConfigurationBuilder(Configuration.VERSION_3_0_0).build();
+ }
+
+ private void mainSingleTemplate(String[] args) throws IOException, FileNotFoundException {
+ final String templateFileName;
+ final String templateContent;
+ if (args[0].startsWith("ftl:")) {
+ templateFileName = null;
+ templateContent = args[0];
+ } else {
+ templateFileName = args[0];
+ templateContent = null;
+ }
+
+ Template t = new Template(
+ templateFileName,
+ templateFileName == null ? new StringReader(templateContent) : new FileReader(templateFileName),
+ cfg);
+
+ p(getASTAsString(t));
+ }
+
+ private void mainRecursive(String[] args) throws IOException {
+ if (args.length != 4) {
+ p("Number of arguments must be 4, but was: " + args.length);
+ usage();
+ System.exit(-1);
+ }
+
+ final String srcDirPath = args[1].trim();
+ File srcDir = new File(srcDirPath);
+ if (!srcDir.isDirectory()) {
+ p("This should be an existing directory: " + srcDirPath);
+ System.exit(-1);
+ }
+
+ Pattern fnPattern;
+ try {
+ fnPattern = Pattern.compile(args[2]);
+ } catch (PatternSyntaxException e) {
+ p(_StringUtil.jQuote(args[2]) + " is not a valid regular expression");
+ System.exit(-1);
+ return;
+ }
+
+ final String dstDirPath = args[3].trim();
+ File dstDir = new File(dstDirPath);
+ if (!dstDir.isDirectory()) {
+ p("This should be an existing directory: " + dstDirPath);
+ System.exit(-1);
+ }
+
+ long startTime = System.currentTimeMillis();
+ recurse(srcDir, fnPattern, dstDir);
+ long endTime = System.currentTimeMillis();
+
+ p("Templates successfully processed " + successfulCounter + ", failed " + failedCounter
+ + ". Time taken: " + (endTime - startTime) / 1000.0 + " s");
+ }
+
+ private void recurse(File srcDir, Pattern fnPattern, File dstDir) throws IOException {
+ File[] files = srcDir.listFiles();
+ if (files == null) {
+ throw new IOException("Failed to kust directory: " + srcDir);
+ }
+ for (File file : files) {
+ if (file.isDirectory()) {
+ recurse(file, fnPattern, new File(dstDir, file.getName()));
+ } else {
+ if (fnPattern.matcher(file.getName()).matches()) {
+ File dstFile = new File(dstDir, file.getName());
+ String res;
+ try {
+ Template t = new Template(file.getPath().replace('\\', '/'), loadIntoString(file), cfg);
+ res = getASTAsString(t);
+ successfulCounter++;
+ } catch (ParseException e) {
+ res = "<<<FAILED>>>\n" + e.getMessage();
+ failedCounter++;
+ p("");
+ p("-------------------------failed-------------------------");
+ p("Error message was saved into: " + dstFile.getAbsolutePath());
+ p("");
+ p(e.getMessage());
+ }
+ save(res, dstFile);
+ }
+ }
+ }
+ }
+
+ private String loadIntoString(File file) throws IOException {
+ long ln = file.length();
+ if (ln < 0) {
+ throw new IOException("Failed to get the length of " + file);
+ }
+ byte[] buffer = new byte[(int) ln];
+ InputStream in = new FileInputStream(file);
+ try {
+ int offset = 0;
+ int bytesRead;
+ while (offset < buffer.length) {
+ bytesRead = in.read(buffer, offset, buffer.length - offset);
+ if (bytesRead == -1) {
+ throw new IOException("Unexpected end of file: " + file);
+ }
+ offset += bytesRead;
+ }
+ } finally {
+ in.close();
+ }
+
+ try {
+ return decode(buffer, StandardCharsets.UTF_8);
+ } catch (CharacterCodingException e) {
+ return decode(buffer, StandardCharsets.ISO_8859_1);
+ }
+ }
+
+ private String decode(byte[] buffer, Charset charset) throws CharacterCodingException {
+ return charset.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT)
+ .decode(ByteBuffer.wrap(buffer)).toString();
+ }
+
+ private void save(String astStr, File file) throws IOException {
+ File parentDir = file.getParentFile();
+ if (!parentDir.isDirectory() && !parentDir.mkdirs()) {
+ throw new IOException("Failed to invoke parent directory: " + parentDir);
+ }
+
+ Writer w = new BufferedWriter(new FileWriter(file));
+ try {
+ w.write(astStr);
+ } finally {
+ w.close();
+ }
+ }
+
+ private static void usage() {
+ p("Prints template Abstract Syntax Tree (AST) as plain text.");
+ p("Usage:");
+ p(" java org.apache.freemarker.core.PrintAST <templateFile>");
+ p(" java org.apache.freemarker.core.PrintAST ftl:<templateSource>");
+ p(" java org.apache.freemarker.core.PrintAST -r <src-directory> <regexp> <dst-directory>");
+ }
+
+ private static final String INDENTATION = " ";
+
+ public static String getASTAsString(String ftl) throws IOException {
+ return getASTAsString(ftl, (Options) null);
+ }
+
+ public static String getASTAsString(String ftl, Options opts) throws IOException {
+ return getASTAsString(null, ftl, opts);
+ }
+
+ public static String getASTAsString(String templateName, String ftl) throws IOException {
+ return getASTAsString(templateName, ftl, null);
+ }
+
+ public static String getASTAsString(String templateName, String ftl, Options opts) throws IOException {
+ Template t = new Template(templateName, ftl, new TestConfigurationBuilder().build());
+ return getASTAsString(t, opts);
+ }
+
+ public static String getASTAsString(Template t) throws IOException {
+ return getASTAsString(t, null);
+ }
+
+ public static String getASTAsString(Template t, Options opts) throws IOException {
+ validateAST(t);
+
+ StringWriter out = new StringWriter();
+ printNode(t.getRootASTNode(), "", null, opts != null ? opts : Options.DEFAULT_INSTANCE, out);
+ return out.toString();
+ }
+
+ public static void validateAST(Template t) throws InvalidASTException {
+ final ASTElement node = t.getRootASTNode();
+ if (node.getParent() != null) {
+ throw new InvalidASTException("Root node parent must be null."
+ + "\nRoot node: " + node.dump(false)
+ + "\nParent"
+ + ": " + node.getParent().getClass() + ", " + node.getParent().dump(false));
+ }
+ validateAST(node);
+ }
+
+ private static void validateAST(ASTElement te) {
+ int childCount = te.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ ASTElement child = te.getChild(i);
+ ASTElement parentElement = child.getParent();
+ // As ASTImplicitParent.accept does nothing but returns its children, it's optimized out in the final
+ // AST tree. While it will be present as a child, the parent element also will have children
+ // that contains the children of the ASTImplicitParent directly.
+ if (parentElement instanceof ASTImplicitParent && parentElement.getParent() != null) {
+ parentElement = parentElement.getParent();
+ }
+ if (parentElement != te) {
+ throw new InvalidASTException("Wrong parent node."
+ + "\nNode: " + child.dump(false)
+ + "\nExpected parent: " + te.dump(false)
+ + "\nActual parent: " + parentElement.dump(false));
+ }
+ if (child.getIndex() != i) {
+ throw new InvalidASTException("Wrong node index."
+ + "\nNode: " + child.dump(false)
+ + "\nExpected index: " + i
+ + "\nActual index: " + child.getIndex());
+ }
+ }
+ if (te instanceof ASTImplicitParent && te.getChildCount() < 2) {
+ throw new InvalidASTException("Mixed content with child count less than 2 should removed by optimizatoin, "
+ + "but found one with " + te.getChildCount() + " child(ren).");
+ }
+ ASTElement[] children = te.getChildBuffer();
+ if (children != null) {
+ if (childCount == 0) {
+ throw new InvalidASTException(
+ "Children must be null when childCount is 0."
+ + "\nNode: " + te.dump(false));
+ }
+ for (int i = 0; i < te.getChildCount(); i++) {
+ if (children[i] == null) {
+ throw new InvalidASTException(
+ "Child can't be null at index " + i
+ + "\nNode: " + te.dump(false));
+ }
+ }
+ for (int i = te.getChildCount(); i < children.length; i++) {
+ if (children[i] != null) {
+ throw new InvalidASTException(
+ "Children can't be non-null at index " + i
+ + "\nNode: " + te.dump(false));
+ }
+ }
+ } else {
+ if (childCount != 0) {
+ throw new InvalidASTException(
+ "Children mustn't be null when child count isn't 0."
+ + "\nNode: " + te.dump(false));
+ }
+ }
+ }
+
+ private static void printNode(Object node, String ind, ParameterRole paramRole, Options opts, Writer out) throws IOException {
+ if (node instanceof ASTNode) {
+ ASTNode tObj = (ASTNode) node;
+
+ printNodeLineStart(paramRole, ind, out);
+ out.write(tObj.getNodeTypeSymbol());
+ printNodeLineEnd(node, out, opts);
+
+ if (opts.getShowConstantValue() && node instanceof ASTExpression) {
+ TemplateModel tm = ((ASTExpression) node).constantValue;
+ if (tm != null) {
+ out.write(INDENTATION);
+ out.write(ind);
+ out.write("= const ");
+ out.write(FTLUtil.getTypeDescription(tm));
+ out.write(' ');
+ out.write(tm.toString());
+ out.write('\n');
+ }
+ }
+
+ int paramCnt = tObj.getParameterCount();
+ for (int i = 0; i < paramCnt; i++) {
+ ParameterRole role = tObj.getParameterRole(i);
+ if (role == null) throw new NullPointerException("parameter role");
+ Object value = tObj.getParameterValue(i);
+ printNode(value, ind + INDENTATION, role, opts, out);
+ }
+ if (tObj instanceof ASTElement) {
+ Enumeration enu = ((ASTElement) tObj).children();
+ while (enu.hasMoreElements()) {
+ printNode(enu.nextElement(), INDENTATION + ind, null, opts, out);
+ }
+ }
+ } else {
+ printNodeLineStart(paramRole, ind, out);
+ out.write(_StringUtil.jQuote(node));
+ printNodeLineEnd(node, out, opts);
+ }
+ }
+
+ protected static void printNodeLineEnd(Object node, Writer out, Options opts) throws IOException {
+ boolean commentStared = false;
+ if (opts.getShowJavaClass()) {
+ out.write(" // ");
+ commentStared = true;
+ out.write(_ClassUtil.getShortClassNameOfObject(node, true));
+ }
+ if (opts.getShowLocation() && node instanceof ASTNode) {
+ if (!commentStared) {
+ out.write(" // ");
+ commentStared = true;
+ } else {
+ out.write("; ");
+ }
+ ASTNode tObj = (ASTNode) node;
+ out.write("Location " + tObj.beginLine + ":" + tObj.beginColumn + "-" + tObj.endLine + ":" + tObj.endColumn);
+ }
+ out.write('\n');
+ }
+
+ private static void printNodeLineStart(ParameterRole paramRole, String ind, Writer out) throws IOException {
+ out.write(ind);
+ if (paramRole != null) {
+ out.write("- ");
+ out.write(paramRole.toString());
+ out.write(": ");
+ }
+ }
+
+ public static class Options {
+
+ private final static Options DEFAULT_INSTANCE = new Options();
+
+ private boolean showJavaClass = true;
+ private boolean showConstantValue = false;
+ private boolean showLocation = false;
+
+ public boolean getShowJavaClass() {
+ return showJavaClass;
+ }
+
+ public void setShowJavaClass(boolean showJavaClass) {
+ this.showJavaClass = showJavaClass;
+ }
+
+ public boolean getShowConstantValue() {
+ return showConstantValue;
+ }
+
+ public void setShowConstantValue(boolean showConstantValue) {
+ this.showConstantValue = showConstantValue;
+ }
+
+ public boolean getShowLocation() {
+ return showLocation;
+ }
+
+ public void setShowLocation(boolean showLocation) {
+ this.showLocation = showLocation;
+ }
+
+ }
+
+ private static void p(Object obj) {
+ System.out.println(obj);
+ }
+
+ public static class InvalidASTException extends RuntimeException {
+
+ public InvalidASTException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidASTException(String message) {
+ super(message);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTTest.java
new file mode 100644
index 0000000..7379e28
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ASTTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.core;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.freemarker.core.ASTPrinter.Options;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TestUtil;
+import org.apache.freemarker.test.FileTestCase;
+
+public class ASTTest extends FileTestCase {
+
+ public ASTTest(String name) {
+ super(name);
+ }
+
+ public void test1() throws Exception {
+ testAST("ast-1");
+ }
+
+ public void testRange() throws Exception {
+ testAST("ast-range");
+ }
+
+ public void testAssignments() throws Exception {
+ testAST("ast-assignments");
+ }
+
+ public void testBuiltins() throws Exception {
+ testAST("ast-builtins");
+ }
+
+ public void testStringLiteralInterpolation() throws Exception {
+ testAST("ast-strlitinterpolation");
+ }
+
+ public void testWhitespaceStripping() throws Exception {
+ testAST("ast-whitespacestripping");
+ }
+
+ public void testMixedContentSimplifications() throws Exception {
+ testAST("ast-mixedcontentsimplifications");
+ }
+
+ public void testMultipleIgnoredChildren() throws Exception {
+ testAST("ast-multipleignoredchildren");
+ }
+
+ public void testNestedIgnoredChildren() throws Exception {
+ testAST("ast-nestedignoredchildren");
+ }
+
+ public void testLocations() throws Exception {
+ testASTWithLocations("ast-locations");
+ }
+
+ private void testAST(String testName) throws FileNotFoundException, IOException {
+ testAST(testName, null);
+ }
+
+ private void testASTWithLocations(String testName) throws FileNotFoundException, IOException {
+ Options options = new Options();
+ options.setShowLocation(true);
+ testAST(testName, options);
+ }
+
+ private void testAST(String testName, Options ops) throws FileNotFoundException, IOException {
+ final String templateName = testName + ".ftl";
+ assertExpectedFileEqualsString(
+ testName + ".ast",
+ ASTPrinter.getASTAsString(templateName,
+ TestUtil.removeFTLCopyrightComment(
+ normalizeLineBreaks(
+ loadTestTextResource(
+ getTestFileURL(
+ getExpectedContentFileDirectoryResourcePath(), templateName)))
+ ), ops));
+ }
+
+ private String normalizeLineBreaks(final String s) throws FileNotFoundException, IOException {
+ return _StringUtil.replace(s, "\r\n", "\n").replace('\r', '\n');
+ }
+
+}
[40/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
new file mode 100644
index 0000000..4306a50
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.core.model.impl;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+import java.util.Date;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.TemplateHTMLOutputModel;
+import org.junit.Test;
+
+public class ErrorMessagesTest {
+
+ @Test
+ public void getterMessage() throws TemplateModelException {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ TemplateHashModel thm= (TemplateHashModel) ow.wrap(new TestBean());
+
+ try {
+ thm.get("foo");
+ } catch (TemplateModelException e) {
+ e.printStackTrace();
+ final String msg = e.getMessage();
+ assertThat(msg, containsString("\"foo\""));
+ assertThat(msg, containsString("existing sub-variable"));
+ }
+ assertNull(thm.get("bar"));
+ }
+
+ @Test
+ public void markupOutputParameter() throws Exception {
+ TemplateHTMLOutputModel html = HTMLOutputFormat.INSTANCE.fromMarkup("<p>a");
+
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ TemplateHashModel thm = (TemplateHashModel) ow.wrap(new TestBean());
+
+ {
+ TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1");
+ try {
+ m.exec(Collections.singletonList(html));
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("String"), containsString("convert"), containsString("markup_output"),
+ containsString("Tip:"), containsString("?markup_string")));
+ }
+ }
+
+ {
+ TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2");
+ try {
+ m.exec(Collections.singletonList(html));
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("Date"), containsString("convert"), containsString("markup_output"),
+ not(containsString("?markup_string"))));
+ }
+ }
+
+ for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
+ TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName);
+ try {
+ m.exec(Collections.singletonList(html));
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("No compatible overloaded"),
+ containsString("String"), containsString("markup_output"),
+ containsString("Tip:"), containsString("?markup_string")));
+ }
+ }
+
+ {
+ TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2");
+ try {
+ m.exec(Collections.singletonList(html));
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("No compatible overloaded"),
+ containsString("Integer"), containsString("markup_output"),
+ not(containsString("?markup_string"))));
+ }
+ }
+
+ {
+ TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4");
+ Object r = m.exec(Collections.singletonList(html));
+ if (r instanceof TemplateScalarModel) {
+ r = ((TemplateScalarModel) r).getAsString();
+ }
+ assertEquals("<p>a", r);
+ }
+ }
+
+ public static class TestBean {
+
+ public String getFoo() {
+ throw new RuntimeException("Dummy");
+ }
+
+ public void m1(String s) {
+ // nop
+ }
+
+ public void m2(Date s) {
+ // nop
+ }
+
+ public void mOverloaded(String s) {
+ // nop
+ }
+
+ public void mOverloaded(Date d) {
+ // nop
+ }
+
+ public void mOverloaded2(Integer n) {
+ // nop
+ }
+
+ public void mOverloaded2(Date d) {
+ // nop
+ }
+
+ public void mOverloaded3(String... s) {
+ // nop
+ }
+
+ public void mOverloaded3(Date d) {
+ // nop
+ }
+
+ public String mOverloaded4(String s) {
+ return s;
+ }
+
+ public String mOverloaded4(TemplateHTMLOutputModel s) throws TemplateModelException {
+ return s.getOutputFormat().getMarkupString(s);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
new file mode 100644
index 0000000..92f59fb
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FineTuneMethodAppearanceTest {
+
+ @Test
+ public void newWayOfConfiguring() throws TemplateModelException {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .methodAppearanceFineTuner(GetlessMethodsAsPropertyGettersRule.INSTANCE)
+ .exposeFields(true)
+ .build();
+ checkIfProperlyWrapped(ow.wrap(new C()));
+ }
+
+ private void checkIfProperlyWrapped(TemplateModel tm) throws TemplateModelException {
+ TemplateHashModel thm = (TemplateHashModel) tm;
+ assertEquals("v1", ((TemplateScalarModel) thm.get("v1")).getAsString());
+ assertEquals("v2()", ((TemplateScalarModel) thm.get("v2")).getAsString());
+ assertEquals("getV3()", ((TemplateScalarModel) thm.get("v3")).getAsString());
+ assertTrue(thm.get("getV3") instanceof TemplateMethodModelEx);
+ }
+
+ static public class C {
+
+ public String v1 = "v1";
+
+ public String v2 = "v2";
+ public String v2() { return "v2()"; }
+
+ public String v3() { return "v3()"; }
+ public String getV3() { return "getV3()"; }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
new file mode 100644
index 0000000..716f863
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
@@ -0,0 +1,67 @@
+/*
+ * 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.core.model.impl;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+
+class GetlessMethodsAsPropertyGettersRule implements MethodAppearanceFineTuner, SingletonCustomizer {
+
+ static final GetlessMethodsAsPropertyGettersRule INSTANCE = new GetlessMethodsAsPropertyGettersRule();
+
+ // Can't be constructed from outside
+ private GetlessMethodsAsPropertyGettersRule() { }
+
+ @Override
+ public void process(
+ DecisionInput in, Decision out) {
+ legacyProcess(in.getContainingClass(), in.getMethod(), out);
+ }
+
+ /** This only exists as the tests need to call this through the deprecated method too. */
+ public void legacyProcess(
+ Class clazz, Method m, Decision decision) {
+ if (m.getDeclaringClass() != Object.class
+ && m.getReturnType() != void.class
+ && m.getParameterTypes().length == 0) {
+ String mName = m.getName();
+ if (!looksLikePropertyReadMethod(mName)) {
+ decision.setExposeMethodAs(null);
+ try {
+ decision.setExposeAsProperty(new PropertyDescriptor(
+ mName, clazz, mName, null));
+ } catch (IntrospectionException e) { // Won't happen...
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ private static boolean looksLikePropertyReadMethod(String name) {
+ final int verbEnd;
+ if (name.startsWith("get")) verbEnd = 3;
+ else if (name.startsWith("is")) verbEnd = 2;
+ else return false;
+
+ return name.length() == verbEnd || Character.isUpperCase(name.charAt(verbEnd));
+ }
+
+}
\ 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/core/model/impl/IsApplicableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java
new file mode 100644
index 0000000..599e6f2
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.core.model.impl;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("boxing")
+public class IsApplicableTest extends TestCase {
+
+ public IsApplicableTest(String name) {
+ super(name);
+ }
+
+ public void testSingle() {
+ ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object() });
+ assertApplicable(ats, Object.class);
+ assertNotApplicable(ats, String.class);
+ assertNotApplicable(ats, CharSequence.class);
+ assertNotApplicable(ats, Integer.class);
+ assertNotApplicable(ats, Integer.TYPE);
+
+ ats = new ArgumentTypes(new Object[] { "" });
+ assertApplicable(ats, Object.class);
+ assertApplicable(ats, CharSequence.class);
+ assertApplicable(ats, String.class);
+ assertNotApplicable(ats, Integer.class);
+ assertNotApplicable(ats, Integer.TYPE);
+
+ ats = new ArgumentTypes(new Object[] { 1 });
+ assertApplicable(ats, Object.class);
+ assertNotApplicable(ats, CharSequence.class);
+ assertNotApplicable(ats, String.class);
+ assertNotApplicable(ats, Short.class);
+ assertNotApplicable(ats, Short.TYPE);
+ assertApplicable(ats, Integer.class);
+ assertApplicable(ats, Integer.TYPE);
+ assertApplicable(ats, Float.class);
+ assertApplicable(ats, Float.TYPE);
+ assertApplicable(ats, Double.class);
+ assertApplicable(ats, Double.TYPE);
+ assertApplicable(ats, BigDecimal.class);
+ assertApplicable(ats, BigInteger.class);
+
+ ats = new ArgumentTypes(new Object[] { new OverloadedNumberUtil.IntegerOrByte(1, (byte) 1) });
+ assertApplicable(ats, Object.class);
+ assertNotApplicable(ats, CharSequence.class);
+ assertNotApplicable(ats, String.class);
+ assertApplicable(ats, Short.class);
+ assertApplicable(ats, Short.TYPE);
+ assertApplicable(ats, Integer.class);
+ assertApplicable(ats, Integer.TYPE);
+ assertApplicable(ats, Float.class);
+ assertApplicable(ats, Float.TYPE);
+ assertApplicable(ats, Double.class);
+ assertApplicable(ats, Double.TYPE);
+ assertApplicable(ats, BigDecimal.class);
+ assertApplicable(ats, BigInteger.class);
+
+ ats = new ArgumentTypes(new Object[] { 1.0f });
+ assertApplicable(ats, Object.class);
+ assertNotApplicable(ats, CharSequence.class);
+ assertNotApplicable(ats, String.class);
+ assertNotApplicable(ats, Integer.class);
+ assertNotApplicable(ats, Integer.TYPE);
+ assertApplicable(ats, Float.class);
+ assertApplicable(ats, Float.TYPE);
+ assertApplicable(ats, Double.class);
+ assertApplicable(ats, Double.TYPE);
+ assertApplicable(ats, BigDecimal.class);
+ assertNotApplicable(ats, BigInteger.class);
+
+ ats = new ArgumentTypes(new Object[] { null });
+ assertApplicable(ats, Object.class);
+ assertApplicable(ats, String.class);
+ assertApplicable(ats, Integer.class);
+ assertNotApplicable(ats, Integer.TYPE);
+ assertNotApplicable(ats, Boolean.TYPE);
+ assertNotApplicable(ats, Object.class, Object.class);
+ assertNotApplicable(ats);
+ }
+
+ public void testMulti() {
+ ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object(), "", 1, true });
+ assertApplicable(ats, Object.class, Object.class, Object.class, Object.class);
+ assertApplicable(ats, Object.class, String.class, Number.class, Boolean.class);
+ assertApplicable(ats, Object.class, CharSequence.class, Integer.class, Serializable.class);
+ assertApplicable(ats, Object.class, Comparable.class, Integer.TYPE, Serializable.class);
+ assertNotApplicable(ats, Object.class, String.class, Number.class, Number.class);
+ assertNotApplicable(ats, Object.class, StringBuilder.class, Number.class, Boolean.class);
+ assertNotApplicable(ats, int.class, Object.class, Object.class, Object.class);
+ assertNotApplicable(ats, Object.class, Object.class, Object.class);
+ assertNotApplicable(ats, Object.class, Object.class, Object.class, Object.class, Object.class);
+ }
+
+ public void testNoParam() {
+ ArgumentTypes ats = new ArgumentTypes(new Object[] { });
+ assertApplicable(ats);
+ assertNotApplicable(ats, Object.class);
+ }
+
+ public void testVarags() {
+ Object[][] argLists = new Object[][] {
+ new Object[] { "", 1, 2, 3 },
+ new Object[] { "", 1, (byte) 2, 3 },
+ new Object[] { "", 1},
+ new Object[] { "" },
+ };
+ for (Object[] args : argLists) {
+ ArgumentTypes ats = new ArgumentTypes(args);
+ assertApplicable(ats, true, String.class, int[].class);
+ assertApplicable(ats, true, String.class, Integer[].class);
+ assertApplicable(ats, true, Object.class, Comparable[].class);
+ assertApplicable(ats, true, Object.class, Object[].class);
+ assertNotApplicable(ats, true, StringBuilder.class, int[].class);
+ if (args.length > 1) {
+ assertNotApplicable(ats, true, String.class, String[].class);
+ } else {
+ assertApplicable(ats, true, String.class, String[].class);
+ }
+ }
+ }
+
+ private void assertNotApplicable(ArgumentTypes ats, Class... paramTypes) {
+ assertNotApplicable(ats, false, paramTypes);
+ }
+
+ private void assertNotApplicable(ArgumentTypes ats, boolean varargs, Class... paramTypes) {
+ List tested = new ArrayList();
+ tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes));
+ if (ats.getApplicables(tested, varargs).size() != 0) {
+ fail("Parameter types were applicable");
+ }
+ }
+
+ private void assertApplicable(ArgumentTypes ats, Class<?>... paramTypes) {
+ assertApplicable(ats, false, paramTypes);
+ }
+
+ private void assertApplicable(ArgumentTypes ats, boolean varargs, Class<?>... paramTypes) {
+ List tested = new ArrayList();
+ tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes));
+ if (ats.getApplicables(tested, varargs).size() != 1) {
+ fail("Parameter types weren't applicable");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
new file mode 100644
index 0000000..3de3f13
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.core.model.impl;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class IsMoreSpecificParameterTypeTest extends TestCase {
+
+ public IsMoreSpecificParameterTypeTest(String name) {
+ super(name);
+ }
+
+ public void testFixed() {
+ assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, true, 0));
+ assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, true, 0));
+
+ assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, true, 0));
+ assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, true, 0));
+
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, true, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, true, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, true, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, true, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, true, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, true, 0));
+
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, true, 0));
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, true, 0));
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, true, 0));
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, true, 0));
+
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0));
+ }
+
+ public void testBuggy() {
+ assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, false, 0));
+ assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, false, 0));
+
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, false, 0));
+
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, false, 0));
+ assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, false, 0));
+
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, false, 0));
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, false, 0));
+ assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, false, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, false, 0));
+
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0));
+ assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
new file mode 100644
index 0000000..96c1adf
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
@@ -0,0 +1,101 @@
+/*
+ * 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.core.model.impl;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Version;
+
+/**
+ * A hack to keep some unit tests producing exactly the same results on Java 8 as on Java 5-7, by hiding members
+ * added after Java 7.
+ */
+public class Java7MembersOnlyDefaultObjectWrapper extends DefaultObjectWrapper {
+
+ private static final Set<String> POST_JAVA_7_MAP_METHODS = newHashSet(
+ "compute", "computeIfAbsent", "computeIfPresent",
+ "forEach", "getOrDefault", "merge", "putIfAbsent", "replace", "replaceAll");
+
+ private static final Set<String> POST_JAVA_7_ITERABLE_METHODS = newHashSet("forEach");
+ private static final Set<String> POST_JAVA_7_COLLECTION_METHODS = newHashSet("parallelStream", "removeIf", "stream");
+ private static final Set<String> POST_JAVA_7_LIST_METHODS = newHashSet("sort", "spliterator");
+
+ static final MethodAppearanceFineTuner POST_JAVA_7_FILTER = new MethodAppearanceFineTuner() {
+
+ @Override
+ public void process(DecisionInput in, Decision out) {
+ Method m = in.getMethod();
+ Class declCl = m.getDeclaringClass();
+ if (Map.class.isAssignableFrom(declCl)) {
+ if (POST_JAVA_7_MAP_METHODS.contains(m.getName())) {
+ hideMember(out);
+ return;
+ }
+ }
+ if (Iterable.class.isAssignableFrom(declCl)) {
+ if (POST_JAVA_7_ITERABLE_METHODS.contains(m.getName())) {
+ hideMember(out);
+ return;
+ }
+ }
+ if (Collection.class.isAssignableFrom(declCl)) {
+ if (POST_JAVA_7_COLLECTION_METHODS.contains(m.getName())) {
+ hideMember(out);
+ return;
+ }
+ }
+ if (List.class.isAssignableFrom(declCl)) {
+ if (POST_JAVA_7_LIST_METHODS.contains(m.getName())) {
+ hideMember(out);
+ return;
+ }
+ }
+ }
+
+ private void hideMember(Decision out) {
+ out.setExposeMethodAs(null);
+ out.setExposeAsProperty(null);
+ }
+
+ };
+
+ public Java7MembersOnlyDefaultObjectWrapper(Version version) {
+ super(new DefaultObjectWrapper.Builder(version).methodAppearanceFineTuner(POST_JAVA_7_FILTER), true);
+ }
+
+ private static <T> Set<T> newHashSet(T... items) {
+ HashSet<T> r = new HashSet<>();
+ for (T item : items) {
+ r.add(item);
+ }
+ return r;
+ }
+
+ public Java7MembersOnlyDefaultObjectWrapper() {
+ this(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
new file mode 100644
index 0000000..fa7ce29
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
@@ -0,0 +1,249 @@
+/*
+ * 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.core.model.impl;
+
+// FMPP template source:
+// ----
+// package org.apache.freemarker.core.model.impl;
+//
+// // FMPP template source:
+// // ----
+// <#assign src><#include "ManyObjectsOfDifferentClasses.java.ftl" parse=false></#assign>
+// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')}
+// // ----
+//
+// <#assign MAX_CLA = 8 - 1>
+// <#assign MAX_MET = 10 - 1>
+// <#assign MAX_PRO = 10 - 1>
+//
+// public class ManyObjectsOfDifferentClasses {
+//
+// public static final Object[] OBJECTS = new Object[] {
+// <#list 0..MAX_CLA as claI>
+// new C${claI}(),
+// </#list>
+// };
+//
+// <#list 0..MAX_CLA as claI>
+// static public class C${claI} {
+// <#list 0..MAX_PRO as proI>
+// public int getP${proI}() { return ${claI} * 1000 + ${proI}; }
+// </#list>
+// <#list 0..MAX_MET as metI>
+// public int m${metI}() { return ${claI} * 1000 + ${metI}; };
+// </#list>
+// }
+// </#list>
+//
+// }
+// ----
+
+
+public class ManyObjectsOfDifferentClasses {
+
+ public static final Object[] OBJECTS = new Object[] {
+ new C0(),
+ new C1(),
+ new C2(),
+ new C3(),
+ new C4(),
+ new C5(),
+ new C6(),
+ new C7(),
+ };
+
+ static public class C0 {
+ public int getP0() { return 0 * 1000 + 0; }
+ public int getP1() { return 0 * 1000 + 1; }
+ public int getP2() { return 0 * 1000 + 2; }
+ public int getP3() { return 0 * 1000 + 3; }
+ public int getP4() { return 0 * 1000 + 4; }
+ public int getP5() { return 0 * 1000 + 5; }
+ public int getP6() { return 0 * 1000 + 6; }
+ public int getP7() { return 0 * 1000 + 7; }
+ public int getP8() { return 0 * 1000 + 8; }
+ public int getP9() { return 0 * 1000 + 9; }
+ public int m0() { return 0 * 1000 + 0; };
+ public int m1() { return 0 * 1000 + 1; };
+ public int m2() { return 0 * 1000 + 2; };
+ public int m3() { return 0 * 1000 + 3; };
+ public int m4() { return 0 * 1000 + 4; };
+ public int m5() { return 0 * 1000 + 5; };
+ public int m6() { return 0 * 1000 + 6; };
+ public int m7() { return 0 * 1000 + 7; };
+ public int m8() { return 0 * 1000 + 8; };
+ public int m9() { return 0 * 1000 + 9; };
+ }
+ static public class C1 {
+ public int getP0() { return 1 * 1000 + 0; }
+ public int getP1() { return 1 * 1000 + 1; }
+ public int getP2() { return 1 * 1000 + 2; }
+ public int getP3() { return 1 * 1000 + 3; }
+ public int getP4() { return 1 * 1000 + 4; }
+ public int getP5() { return 1 * 1000 + 5; }
+ public int getP6() { return 1 * 1000 + 6; }
+ public int getP7() { return 1 * 1000 + 7; }
+ public int getP8() { return 1 * 1000 + 8; }
+ public int getP9() { return 1 * 1000 + 9; }
+ public int m0() { return 1 * 1000 + 0; };
+ public int m1() { return 1 * 1000 + 1; };
+ public int m2() { return 1 * 1000 + 2; };
+ public int m3() { return 1 * 1000 + 3; };
+ public int m4() { return 1 * 1000 + 4; };
+ public int m5() { return 1 * 1000 + 5; };
+ public int m6() { return 1 * 1000 + 6; };
+ public int m7() { return 1 * 1000 + 7; };
+ public int m8() { return 1 * 1000 + 8; };
+ public int m9() { return 1 * 1000 + 9; };
+ }
+ static public class C2 {
+ public int getP0() { return 2 * 1000 + 0; }
+ public int getP1() { return 2 * 1000 + 1; }
+ public int getP2() { return 2 * 1000 + 2; }
+ public int getP3() { return 2 * 1000 + 3; }
+ public int getP4() { return 2 * 1000 + 4; }
+ public int getP5() { return 2 * 1000 + 5; }
+ public int getP6() { return 2 * 1000 + 6; }
+ public int getP7() { return 2 * 1000 + 7; }
+ public int getP8() { return 2 * 1000 + 8; }
+ public int getP9() { return 2 * 1000 + 9; }
+ public int m0() { return 2 * 1000 + 0; };
+ public int m1() { return 2 * 1000 + 1; };
+ public int m2() { return 2 * 1000 + 2; };
+ public int m3() { return 2 * 1000 + 3; };
+ public int m4() { return 2 * 1000 + 4; };
+ public int m5() { return 2 * 1000 + 5; };
+ public int m6() { return 2 * 1000 + 6; };
+ public int m7() { return 2 * 1000 + 7; };
+ public int m8() { return 2 * 1000 + 8; };
+ public int m9() { return 2 * 1000 + 9; };
+ }
+ static public class C3 {
+ public int getP0() { return 3 * 1000 + 0; }
+ public int getP1() { return 3 * 1000 + 1; }
+ public int getP2() { return 3 * 1000 + 2; }
+ public int getP3() { return 3 * 1000 + 3; }
+ public int getP4() { return 3 * 1000 + 4; }
+ public int getP5() { return 3 * 1000 + 5; }
+ public int getP6() { return 3 * 1000 + 6; }
+ public int getP7() { return 3 * 1000 + 7; }
+ public int getP8() { return 3 * 1000 + 8; }
+ public int getP9() { return 3 * 1000 + 9; }
+ public int m0() { return 3 * 1000 + 0; };
+ public int m1() { return 3 * 1000 + 1; };
+ public int m2() { return 3 * 1000 + 2; };
+ public int m3() { return 3 * 1000 + 3; };
+ public int m4() { return 3 * 1000 + 4; };
+ public int m5() { return 3 * 1000 + 5; };
+ public int m6() { return 3 * 1000 + 6; };
+ public int m7() { return 3 * 1000 + 7; };
+ public int m8() { return 3 * 1000 + 8; };
+ public int m9() { return 3 * 1000 + 9; };
+ }
+ static public class C4 {
+ public int getP0() { return 4 * 1000 + 0; }
+ public int getP1() { return 4 * 1000 + 1; }
+ public int getP2() { return 4 * 1000 + 2; }
+ public int getP3() { return 4 * 1000 + 3; }
+ public int getP4() { return 4 * 1000 + 4; }
+ public int getP5() { return 4 * 1000 + 5; }
+ public int getP6() { return 4 * 1000 + 6; }
+ public int getP7() { return 4 * 1000 + 7; }
+ public int getP8() { return 4 * 1000 + 8; }
+ public int getP9() { return 4 * 1000 + 9; }
+ public int m0() { return 4 * 1000 + 0; };
+ public int m1() { return 4 * 1000 + 1; };
+ public int m2() { return 4 * 1000 + 2; };
+ public int m3() { return 4 * 1000 + 3; };
+ public int m4() { return 4 * 1000 + 4; };
+ public int m5() { return 4 * 1000 + 5; };
+ public int m6() { return 4 * 1000 + 6; };
+ public int m7() { return 4 * 1000 + 7; };
+ public int m8() { return 4 * 1000 + 8; };
+ public int m9() { return 4 * 1000 + 9; };
+ }
+ static public class C5 {
+ public int getP0() { return 5 * 1000 + 0; }
+ public int getP1() { return 5 * 1000 + 1; }
+ public int getP2() { return 5 * 1000 + 2; }
+ public int getP3() { return 5 * 1000 + 3; }
+ public int getP4() { return 5 * 1000 + 4; }
+ public int getP5() { return 5 * 1000 + 5; }
+ public int getP6() { return 5 * 1000 + 6; }
+ public int getP7() { return 5 * 1000 + 7; }
+ public int getP8() { return 5 * 1000 + 8; }
+ public int getP9() { return 5 * 1000 + 9; }
+ public int m0() { return 5 * 1000 + 0; };
+ public int m1() { return 5 * 1000 + 1; };
+ public int m2() { return 5 * 1000 + 2; };
+ public int m3() { return 5 * 1000 + 3; };
+ public int m4() { return 5 * 1000 + 4; };
+ public int m5() { return 5 * 1000 + 5; };
+ public int m6() { return 5 * 1000 + 6; };
+ public int m7() { return 5 * 1000 + 7; };
+ public int m8() { return 5 * 1000 + 8; };
+ public int m9() { return 5 * 1000 + 9; };
+ }
+ static public class C6 {
+ public int getP0() { return 6 * 1000 + 0; }
+ public int getP1() { return 6 * 1000 + 1; }
+ public int getP2() { return 6 * 1000 + 2; }
+ public int getP3() { return 6 * 1000 + 3; }
+ public int getP4() { return 6 * 1000 + 4; }
+ public int getP5() { return 6 * 1000 + 5; }
+ public int getP6() { return 6 * 1000 + 6; }
+ public int getP7() { return 6 * 1000 + 7; }
+ public int getP8() { return 6 * 1000 + 8; }
+ public int getP9() { return 6 * 1000 + 9; }
+ public int m0() { return 6 * 1000 + 0; };
+ public int m1() { return 6 * 1000 + 1; };
+ public int m2() { return 6 * 1000 + 2; };
+ public int m3() { return 6 * 1000 + 3; };
+ public int m4() { return 6 * 1000 + 4; };
+ public int m5() { return 6 * 1000 + 5; };
+ public int m6() { return 6 * 1000 + 6; };
+ public int m7() { return 6 * 1000 + 7; };
+ public int m8() { return 6 * 1000 + 8; };
+ public int m9() { return 6 * 1000 + 9; };
+ }
+ static public class C7 {
+ public int getP0() { return 7 * 1000 + 0; }
+ public int getP1() { return 7 * 1000 + 1; }
+ public int getP2() { return 7 * 1000 + 2; }
+ public int getP3() { return 7 * 1000 + 3; }
+ public int getP4() { return 7 * 1000 + 4; }
+ public int getP5() { return 7 * 1000 + 5; }
+ public int getP6() { return 7 * 1000 + 6; }
+ public int getP7() { return 7 * 1000 + 7; }
+ public int getP8() { return 7 * 1000 + 8; }
+ public int getP9() { return 7 * 1000 + 9; }
+ public int m0() { return 7 * 1000 + 0; };
+ public int m1() { return 7 * 1000 + 1; };
+ public int m2() { return 7 * 1000 + 2; };
+ public int m3() { return 7 * 1000 + 3; };
+ public int m4() { return 7 * 1000 + 4; };
+ public int m5() { return 7 * 1000 + 5; };
+ public int m6() { return 7 * 1000 + 6; };
+ public int m7() { return 7 * 1000 + 7; };
+ public int m8() { return 7 * 1000 + 8; };
+ public int m9() { return 7 * 1000 + 9; };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
new file mode 100644
index 0000000..dd73bee
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
@@ -0,0 +1,236 @@
+/*
+ * 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.core.model.impl;
+
+// FMPP template source:
+// ----
+// package org.apache.freemarker.core.model.impl;
+//
+// // FMPP template source:
+// // ----
+// <#assign src><#include "ManyStaticsOfDifferentClasses.java.ftl" parse=false></#assign>
+// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')}
+// // ----
+//
+// <#assign MAX_CLA = 8 - 1>
+// <#assign MAX_MET = 10 - 1>
+// <#assign MAX_PRO = 10 - 1>
+//
+// public class ManyStaticsOfDifferentClasses {
+//
+// private ManyStaticsOfDifferentClasses() { }
+//
+// <#list 0..MAX_CLA as claI>
+// static public class C${claI} {
+// <#list 0..MAX_PRO as proI>
+// public static int p${proI} = ${claI} * 1000 + ${proI};
+// </#list>
+// <#list 0..MAX_MET as metI>
+// public static int m${metI}() { return ${claI} * 1000 + ${metI}; };
+// </#list>
+// }
+// </#list>
+//
+// }
+// ----
+
+
+public class ManyStaticsOfDifferentClasses {
+
+ private ManyStaticsOfDifferentClasses() { }
+
+ static public class C0 {
+ public static int p0 = 0 * 1000 + 0;
+ public static int p1 = 0 * 1000 + 1;
+ public static int p2 = 0 * 1000 + 2;
+ public static int p3 = 0 * 1000 + 3;
+ public static int p4 = 0 * 1000 + 4;
+ public static int p5 = 0 * 1000 + 5;
+ public static int p6 = 0 * 1000 + 6;
+ public static int p7 = 0 * 1000 + 7;
+ public static int p8 = 0 * 1000 + 8;
+ public static int p9 = 0 * 1000 + 9;
+ public static int m0() { return 0 * 1000 + 0; };
+ public static int m1() { return 0 * 1000 + 1; };
+ public static int m2() { return 0 * 1000 + 2; };
+ public static int m3() { return 0 * 1000 + 3; };
+ public static int m4() { return 0 * 1000 + 4; };
+ public static int m5() { return 0 * 1000 + 5; };
+ public static int m6() { return 0 * 1000 + 6; };
+ public static int m7() { return 0 * 1000 + 7; };
+ public static int m8() { return 0 * 1000 + 8; };
+ public static int m9() { return 0 * 1000 + 9; };
+ }
+ static public class C1 {
+ public static int p0 = 1 * 1000 + 0;
+ public static int p1 = 1 * 1000 + 1;
+ public static int p2 = 1 * 1000 + 2;
+ public static int p3 = 1 * 1000 + 3;
+ public static int p4 = 1 * 1000 + 4;
+ public static int p5 = 1 * 1000 + 5;
+ public static int p6 = 1 * 1000 + 6;
+ public static int p7 = 1 * 1000 + 7;
+ public static int p8 = 1 * 1000 + 8;
+ public static int p9 = 1 * 1000 + 9;
+ public static int m0() { return 1 * 1000 + 0; };
+ public static int m1() { return 1 * 1000 + 1; };
+ public static int m2() { return 1 * 1000 + 2; };
+ public static int m3() { return 1 * 1000 + 3; };
+ public static int m4() { return 1 * 1000 + 4; };
+ public static int m5() { return 1 * 1000 + 5; };
+ public static int m6() { return 1 * 1000 + 6; };
+ public static int m7() { return 1 * 1000 + 7; };
+ public static int m8() { return 1 * 1000 + 8; };
+ public static int m9() { return 1 * 1000 + 9; };
+ }
+ static public class C2 {
+ public static int p0 = 2 * 1000 + 0;
+ public static int p1 = 2 * 1000 + 1;
+ public static int p2 = 2 * 1000 + 2;
+ public static int p3 = 2 * 1000 + 3;
+ public static int p4 = 2 * 1000 + 4;
+ public static int p5 = 2 * 1000 + 5;
+ public static int p6 = 2 * 1000 + 6;
+ public static int p7 = 2 * 1000 + 7;
+ public static int p8 = 2 * 1000 + 8;
+ public static int p9 = 2 * 1000 + 9;
+ public static int m0() { return 2 * 1000 + 0; };
+ public static int m1() { return 2 * 1000 + 1; };
+ public static int m2() { return 2 * 1000 + 2; };
+ public static int m3() { return 2 * 1000 + 3; };
+ public static int m4() { return 2 * 1000 + 4; };
+ public static int m5() { return 2 * 1000 + 5; };
+ public static int m6() { return 2 * 1000 + 6; };
+ public static int m7() { return 2 * 1000 + 7; };
+ public static int m8() { return 2 * 1000 + 8; };
+ public static int m9() { return 2 * 1000 + 9; };
+ }
+ static public class C3 {
+ public static int p0 = 3 * 1000 + 0;
+ public static int p1 = 3 * 1000 + 1;
+ public static int p2 = 3 * 1000 + 2;
+ public static int p3 = 3 * 1000 + 3;
+ public static int p4 = 3 * 1000 + 4;
+ public static int p5 = 3 * 1000 + 5;
+ public static int p6 = 3 * 1000 + 6;
+ public static int p7 = 3 * 1000 + 7;
+ public static int p8 = 3 * 1000 + 8;
+ public static int p9 = 3 * 1000 + 9;
+ public static int m0() { return 3 * 1000 + 0; };
+ public static int m1() { return 3 * 1000 + 1; };
+ public static int m2() { return 3 * 1000 + 2; };
+ public static int m3() { return 3 * 1000 + 3; };
+ public static int m4() { return 3 * 1000 + 4; };
+ public static int m5() { return 3 * 1000 + 5; };
+ public static int m6() { return 3 * 1000 + 6; };
+ public static int m7() { return 3 * 1000 + 7; };
+ public static int m8() { return 3 * 1000 + 8; };
+ public static int m9() { return 3 * 1000 + 9; };
+ }
+ static public class C4 {
+ public static int p0 = 4 * 1000 + 0;
+ public static int p1 = 4 * 1000 + 1;
+ public static int p2 = 4 * 1000 + 2;
+ public static int p3 = 4 * 1000 + 3;
+ public static int p4 = 4 * 1000 + 4;
+ public static int p5 = 4 * 1000 + 5;
+ public static int p6 = 4 * 1000 + 6;
+ public static int p7 = 4 * 1000 + 7;
+ public static int p8 = 4 * 1000 + 8;
+ public static int p9 = 4 * 1000 + 9;
+ public static int m0() { return 4 * 1000 + 0; };
+ public static int m1() { return 4 * 1000 + 1; };
+ public static int m2() { return 4 * 1000 + 2; };
+ public static int m3() { return 4 * 1000 + 3; };
+ public static int m4() { return 4 * 1000 + 4; };
+ public static int m5() { return 4 * 1000 + 5; };
+ public static int m6() { return 4 * 1000 + 6; };
+ public static int m7() { return 4 * 1000 + 7; };
+ public static int m8() { return 4 * 1000 + 8; };
+ public static int m9() { return 4 * 1000 + 9; };
+ }
+ static public class C5 {
+ public static int p0 = 5 * 1000 + 0;
+ public static int p1 = 5 * 1000 + 1;
+ public static int p2 = 5 * 1000 + 2;
+ public static int p3 = 5 * 1000 + 3;
+ public static int p4 = 5 * 1000 + 4;
+ public static int p5 = 5 * 1000 + 5;
+ public static int p6 = 5 * 1000 + 6;
+ public static int p7 = 5 * 1000 + 7;
+ public static int p8 = 5 * 1000 + 8;
+ public static int p9 = 5 * 1000 + 9;
+ public static int m0() { return 5 * 1000 + 0; };
+ public static int m1() { return 5 * 1000 + 1; };
+ public static int m2() { return 5 * 1000 + 2; };
+ public static int m3() { return 5 * 1000 + 3; };
+ public static int m4() { return 5 * 1000 + 4; };
+ public static int m5() { return 5 * 1000 + 5; };
+ public static int m6() { return 5 * 1000 + 6; };
+ public static int m7() { return 5 * 1000 + 7; };
+ public static int m8() { return 5 * 1000 + 8; };
+ public static int m9() { return 5 * 1000 + 9; };
+ }
+ static public class C6 {
+ public static int p0 = 6 * 1000 + 0;
+ public static int p1 = 6 * 1000 + 1;
+ public static int p2 = 6 * 1000 + 2;
+ public static int p3 = 6 * 1000 + 3;
+ public static int p4 = 6 * 1000 + 4;
+ public static int p5 = 6 * 1000 + 5;
+ public static int p6 = 6 * 1000 + 6;
+ public static int p7 = 6 * 1000 + 7;
+ public static int p8 = 6 * 1000 + 8;
+ public static int p9 = 6 * 1000 + 9;
+ public static int m0() { return 6 * 1000 + 0; };
+ public static int m1() { return 6 * 1000 + 1; };
+ public static int m2() { return 6 * 1000 + 2; };
+ public static int m3() { return 6 * 1000 + 3; };
+ public static int m4() { return 6 * 1000 + 4; };
+ public static int m5() { return 6 * 1000 + 5; };
+ public static int m6() { return 6 * 1000 + 6; };
+ public static int m7() { return 6 * 1000 + 7; };
+ public static int m8() { return 6 * 1000 + 8; };
+ public static int m9() { return 6 * 1000 + 9; };
+ }
+ static public class C7 {
+ public static int p0 = 7 * 1000 + 0;
+ public static int p1 = 7 * 1000 + 1;
+ public static int p2 = 7 * 1000 + 2;
+ public static int p3 = 7 * 1000 + 3;
+ public static int p4 = 7 * 1000 + 4;
+ public static int p5 = 7 * 1000 + 5;
+ public static int p6 = 7 * 1000 + 6;
+ public static int p7 = 7 * 1000 + 7;
+ public static int p8 = 7 * 1000 + 8;
+ public static int p9 = 7 * 1000 + 9;
+ public static int m0() { return 7 * 1000 + 0; };
+ public static int m1() { return 7 * 1000 + 1; };
+ public static int m2() { return 7 * 1000 + 2; };
+ public static int m3() { return 7 * 1000 + 3; };
+ public static int m4() { return 7 * 1000 + 4; };
+ public static int m5() { return 7 * 1000 + 5; };
+ public static int m6() { return 7 * 1000 + 6; };
+ public static int m7() { return 7 * 1000 + 7; };
+ public static int m8() { return 7 * 1000 + 8; };
+ public static int m9() { return 7 * 1000 + 9; };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
new file mode 100644
index 0000000..9e175e5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.core.model.impl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.junit.Assert;
+
+import junit.framework.TestCase;
+
+public class MiscNumericalOperationsTest extends TestCase {
+
+ public MiscNumericalOperationsTest(String name) {
+ super(name);
+ }
+
+ public void testForceUnwrappedNumberToType() {
+ // Usual type to to all other types:
+ Double n = Double.valueOf(123.75);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.class), Short.valueOf(n.shortValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.TYPE), Short.valueOf(n.shortValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.class), Byte.valueOf(n.byteValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.TYPE), Byte.valueOf(n.byteValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.class), Integer.valueOf(n.intValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.TYPE), Integer.valueOf(n.intValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.class), Long.valueOf(n.longValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.TYPE), Long.valueOf(n.longValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.class), Float.valueOf(n.floatValue()));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.TYPE), Float.valueOf(n.floatValue()));
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.class) == n);
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.TYPE) == n);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigInteger.class), new BigInteger("123"));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigDecimal.class), new BigDecimal("123.75"));
+
+ // Cases of conversion to BigDecimal:
+ BigDecimal bd = new BigDecimal("123");
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigInteger("123"), BigDecimal.class), bd);
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bd, BigDecimal.class) == bd);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigDecimal.class), bd);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123), BigDecimal.class), bd);
+
+ // Cases of conversion to BigInteger:
+ BigInteger bi = new BigInteger("123");
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigDecimal("123.6"), BigInteger.class), bi);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(
+ new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal("123")), BigInteger.class), bi);
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bi, BigInteger.class) == bi);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigInteger.class), bi);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123.6), BigInteger.class), bi);
+
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Number.class) == n);
+ assertNull(DefaultObjectWrapper.forceUnwrappedNumberToType(n, RationalNumber.class));
+ RationalNumber r = new RationalNumber(1, 2);
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, RationalNumber.class) == r);
+ assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Number.class) == r);
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Double.class), Double.valueOf(0.5));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigDecimal.class), new BigDecimal("0.5"));
+ assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigInteger.class), BigInteger.ZERO);
+ }
+
+ @SuppressWarnings("boxing")
+ public void testForceNumberArgumentsToParameterTypes() {
+ OverloadedMethodsSubset oms = new OverloadedFixArgsMethods();
+ Class[] paramTypes = new Class[] { Short.TYPE, Short.class, Double.TYPE, BigDecimal.class, BigInteger.class };
+ Object[] args;
+
+ args = newArgs();
+ oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF });
+ Assert.assertArrayEquals(
+ args,
+ new Object[] { (short) 123, (short) 123, 123.75, new BigDecimal("123.75"), BigInteger.valueOf(123) });
+
+ args = newArgs();
+ oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0, 0, 0, 0, 0 });
+ Assert.assertArrayEquals(args, newArgs());
+
+ args = newArgs();
+ oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 8, 8, 8, 8, 8 });
+ Assert.assertArrayEquals(args, newArgs());
+
+ args = newArgs();
+ oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0, 0xFFFF, 0, 0xFFFF });
+ Assert.assertArrayEquals(
+ args,
+ new Object[] { (short) 123, 123.75, 123.75, 123.75, BigInteger.valueOf(123) });
+ }
+
+ @SuppressWarnings("boxing")
+ private Object[] newArgs() {
+ return new Object[] { 123.75, 123.75, 123.75, 123.75, 123.75 };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
new file mode 100644
index 0000000..0b0a614
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.core.model.impl;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.test.TestUtil;
+
+import junit.framework.TestCase;
+
+public class ModelAPINewInstanceTest extends TestCase {
+
+ private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+
+ public ModelAPINewInstanceTest(String name) {
+ super(name);
+ }
+
+ @SuppressWarnings("boxing")
+ public void test() throws Exception {
+ testClassConstructors("");
+ testClassConstructors("int... [1]", 1);
+ testClassConstructors("int 1, int 2", 1, 2);
+ testClassConstructors("int... [1, 2, 3]", 1, 2, 3);
+ testClassConstructors("int... [1, 2, 3]", 1, (byte) 2, (short) 3);
+ try {
+ testClassConstructors("int... [1, 2, 3]", 1, 2, (long) 3);
+ fail();
+ } catch (NoSuchMethodException e) {
+ // Expected
+ }
+
+ testClassConstructors("int 1, int 2", (byte) 1, (short) 2);
+ testClassConstructors("double 1.0, double 2.0", (long) 1, (short) 2);
+ testClassConstructors("double 1.0, double 2.0", 1, 2f);
+ testClassConstructors("Integer null, Integer null", null, null);
+ testClassConstructors("Integer null, Integer 1", null, 1);
+ testClassConstructors("int 1, String s", 1, "s");
+ testClassConstructors("int 1, String null", 1, null);
+ testClassConstructors("Object null, Object s", null, "s");
+ testClassConstructors("Object 1.0, Object s", 1f, "s");
+
+ testClassConstructors("Object s, int... [1, 2]", "s", 1, 2);
+ testClassConstructors("Object s, int... []", "s");
+
+ testClassConstructors2("int 1, int 2", (byte) 1, (short) 2);
+ try {
+ testClassConstructors2("int 1, int 2", 1, 2L);
+ fail();
+ } catch (NoSuchMethodException e) {
+ // Expected
+ }
+ try {
+ testClassConstructors2("", "", "");
+ fail();
+ } catch (NoSuchMethodException e) {
+ // Expected
+ }
+ try {
+ testClassConstructors2("int 1", 1);
+ fail();
+ } catch (NoSuchMethodException e) {
+ // Expected
+ }
+ try {
+ testClassConstructors2("");
+ fail();
+ } catch (NoSuchMethodException e) {
+ // Expected
+ }
+ }
+
+ private void testClassConstructors(String expected, Object... args) throws Exception {
+ testCall(expected, Constructors.class, args);
+ }
+
+ private void testClassConstructors2(String expected, Object... args) throws Exception {
+ testCall(expected, Constructors2.class, args);
+ }
+
+ private void testCall(String expected, Class cl, Object... args) throws Exception {
+ Object obj = _ModelAPI.newInstance(cl, args, ow);
+ assertEquals(expected, obj.toString());
+ }
+
+ public static class Constructors {
+ private final String s;
+
+ public Constructors() { s = ""; }
+
+ public Constructors(int x, int y) { s = "int " + x + ", int " + y; }
+ public Constructors(int x, String y) { s = "int " + x + ", String " + y; }
+ public Constructors(int x, long y) { s = "int " + x + ", long " + y; }
+ public Constructors(double x, double y) { s = "double " + x + ", double " + y; }
+ public Constructors(Integer x, Integer y) { s = "Integer " + x + ", Integer " + y; }
+ public Constructors(Object x, Object y) { s = "Object " + x + ", Object " + y; }
+
+ public Constructors(int... xs) { s = "int... " + TestUtil.arrayToString(xs); }
+ public Constructors(Object x, int... ys) { s = "Object " + x + ", int... " + TestUtil.arrayToString(ys); }
+
+ @Override
+ public String toString() {
+ return s;
+ }
+ }
+
+ public static class Constructors2 {
+ private final String s;
+
+ public Constructors2(int x, int y) { s = "int " + x + ", int " + y; }
+
+ @Override
+ public String toString() {
+ return s;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
new file mode 100644
index 0000000..2498859
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.core.model.impl;
+
+import static org.junit.Assert.*;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ModelCacheTest {
+
+ @Test
+ public void modelCacheOff() throws Exception {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ assertFalse(ow.getUseModelCache()); // default is off
+
+ String s = "foo";
+ assertNotSame(ow.wrap(s), ow.wrap(s));
+
+ C c = new C();
+ assertNotSame(ow.wrap(c), ow.wrap(c));
+ }
+
+ @Test
+ @Ignore // ModelCache is current removed in FM3
+ public void modelCacheOn() throws Exception {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .useModelCache(true).build();
+ assertTrue(ow.getUseModelCache());
+
+ TestBean obj = new TestBean();
+ assertSame(ow.wrap(obj), ow.wrap(obj));
+
+ C c = new C();
+ TemplateModel wrappedC = ow.wrap(c);
+ assertSame(wrappedC, ow.wrap(c));
+
+ ow.clearClassIntrospecitonCache();
+ assertNotSame(wrappedC, ow.wrap(c));
+ assertSame(ow.wrap(c), ow.wrap(c));
+ }
+
+ static public class C { }
+
+ public static class TestBean {
+ //
+ }
+
+}
[49/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
new file mode 100644
index 0000000..57e40fa
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class ActualNamingConvetionTest {
+
+ @Test
+ public void testUndetectable() throws IOException {
+ final String ftl = "<#if true>${x?size}</#if>";
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION);
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+ }
+
+ @Test
+ public void testLegacyDetected() throws IOException {
+ final String ftl = "${x?upper_case}";
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION);
+ }
+
+ @Test
+ public void testCamelCaseDetected() throws IOException {
+ final String ftl = "${x?upperCase}";
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+ assertEquals(getActualNamingConvention(ftl,
+ ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION);
+ }
+
+ private int getActualNamingConvention(String ftl, int namingConvention) throws IOException {
+ return new Template(null, ftl,
+ new TestConfigurationBuilder().namingConvention(namingConvention).build())
+ .getActualNamingConvention();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
new file mode 100644
index 0000000..88f0646
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.core;
+
+import static org.apache.freemarker.core.ParsingConfiguration.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class ActualTagSyntaxTest {
+
+ @Test
+ public void testWithFtlHeader() throws IOException {
+ testWithFtlHeader(AUTO_DETECT_TAG_SYNTAX);
+ testWithFtlHeader(ANGLE_BRACKET_TAG_SYNTAX);
+ testWithFtlHeader(SQUARE_BRACKET_TAG_SYNTAX);
+ }
+
+ private void testWithFtlHeader(int cfgTagSyntax) throws IOException {
+ assertEquals(getActualTagSyntax("[#ftl]foo", cfgTagSyntax), SQUARE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("<#ftl>foo", cfgTagSyntax), ANGLE_BRACKET_TAG_SYNTAX);
+ }
+
+ @Test
+ public void testUndecidable() throws IOException {
+ assertEquals(getActualTagSyntax("foo", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
+ }
+
+ @Test
+ public void testDecidableWithoutFtlHeader() throws IOException {
+ assertEquals(getActualTagSyntax("foo<#if true></#if>", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo<#if true></#if>", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo<#if true></#if>", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
+
+ assertEquals(getActualTagSyntax("foo[#if true][/#if]", AUTO_DETECT_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo[#if true][/#if]", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX);
+ assertEquals(getActualTagSyntax("foo[#if true][/#if]", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX);
+ }
+
+ private int getActualTagSyntax(String ftl, int cfgTagSyntax) throws IOException {
+ return new Template(
+ null, ftl,
+ new TestConfigurationBuilder().tagSyntax(cfgTagSyntax).build()).getActualTagSyntax();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
new file mode 100644
index 0000000..61ba02b
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class BreakPlacementTest extends TemplateTest {
+
+ private static final String BREAK_NESTING_ERROR_MESSAGE_PART = "<#break> must be nested";
+
+ @Test
+ public void testValidPlacements() throws IOException, TemplateException {
+ assertOutput("<#assign x = 1><#switch x><#case 1>one<#break><#case 2>two</#switch>", "one");
+ assertOutput("<#list 1..2 as x>${x}<#break></#list>", "1");
+ assertOutput("<#list 1..2>[<#items as x>${x}<#break></#items>]</#list>", "[1]");
+ assertOutput("<#list 1..2 as x>${x}<#list 1..3>B<#break>E<#items as y></#items></#list>E</#list>.", "1B.");
+ assertOutput("<#list 1..2 as x>${x}<#list 3..4 as x>${x}<#break></#list>;</#list>", "13;23;");
+ assertOutput("<#list [1..2, 3..4, [], 5..6] as xs>[<#list xs as x>${x}<#else><#break></#list>]</#list>.",
+ "[12][34][.");
+ assertOutput("<#list [1..2, 3..4, [], 5..6] as xs>"
+ + "<#list xs>[<#items as x>${x}</#items>]<#else><#break></#list>"
+ + "</#list>.",
+ "[12][34].");
+ }
+
+ @Test
+ public void testInvalidPlacements() throws IOException, TemplateException {
+ assertErrorContains("<#break>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ assertErrorContains("<#list 1..2 as x>${x}</#list><#break>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ assertErrorContains("<#if false><#break></#if>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ assertErrorContains("<#list xs><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ assertErrorContains("<#list 1..2 as x>${x}<#else><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ assertErrorContains("<#list 1..2 as x>${x}<#macro m><#break></#macro></#list>", BREAK_NESTING_ERROR_MESSAGE_PART);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CamelCaseTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
new file mode 100644
index 0000000..95572ad
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
@@ -0,0 +1,486 @@
+/*
+ * 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.core;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class CamelCaseTest extends TemplateTest {
+
+ @Test
+ public void camelCaseSpecialVars() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .outputEncoding(StandardCharsets.UTF_8)
+ .urlEscapingCharset(StandardCharsets.ISO_8859_1)
+ .locale(Locale.GERMANY)
+ .build());
+ assertOutput("${.dataModel?isHash?c}", "true");
+ assertOutput("${.data_model?is_hash?c}", "true");
+ assertOutput("${.localeObject.toString()}", "de_DE");
+ assertOutput("${.locale_object.toString()}", "de_DE");
+ assertOutput("${.templateName!'null'}", "null");
+ assertOutput("${.template_name!'null'}", "null");
+ assertOutput("${.currentTemplateName!'null'}", "null");
+ assertOutput("${.current_template_name!'null'}", "null");
+ assertOutput("${.mainTemplateName!'null'}", "null");
+ assertOutput("${.main_template_name!'null'}", "null");
+ assertOutput("${.outputEncoding}", StandardCharsets.UTF_8.name());
+ assertOutput("${.output_encoding}", StandardCharsets.UTF_8.name());
+ assertOutput("${.outputFormat}", UndefinedOutputFormat.INSTANCE.getName());
+ assertOutput("${.output_format}", UndefinedOutputFormat.INSTANCE.getName());
+ assertOutput("${.urlEscapingCharset}", StandardCharsets.ISO_8859_1.name());
+ assertOutput("${.url_escaping_charset}", StandardCharsets.ISO_8859_1.name());
+ assertOutput("${.currentNode!'-'}", "-");
+ assertOutput("${.current_node!'-'}", "-");
+ }
+
+ @Test
+ public void camelCaseSpecialVarsInErrorMessage() throws IOException, TemplateException {
+ assertErrorContains("${.fooBar}", "dataModel", "\\!data_model");
+ assertErrorContains("${.foo_bar}", "data_model", "\\!dataModel");
+ // [2.4] If camel case will be the recommended style, then this need to be inverted:
+ assertErrorContains("${.foo}", "data_model", "\\!dataModel");
+
+ assertErrorContains("<#if x><#elseIf y></#if>${.foo}", "dataModel", "\\!data_model");
+ assertErrorContains("<#if x><#elseif y></#if>${.foo}", "data_model", "\\!dataModel");
+
+ setConfigurationToCamelCaseNamingConvention();
+ assertErrorContains("${.foo}", "dataModel", "\\!data_model");
+
+ setConfigurationToLegacyCaseNamingConvention();
+ assertErrorContains("${.foo}", "data_model", "\\!dataModel");
+ }
+
+ @Test
+ public void camelCaseSettingNames() throws IOException, TemplateException {
+ assertOutput("<#setting booleanFormat='Y,N'>${true} <#setting booleanFormat='+,-'>${true}", "Y +");
+ assertOutput("<#setting boolean_format='Y,N'>${true} <#setting boolean_format='+,-'>${true}", "Y +");
+
+ // Still works inside ?interpret
+ assertOutput("<@r\"<#setting booleanFormat='Y,N'>${true}\"?interpret />", "Y");
+ }
+
+ @Test
+ public void camelCaseFtlHeaderParameters() throws IOException, TemplateException {
+ assertOutput(
+ "<#ftl "
+ + "stripWhitespace=false "
+ + "stripText=true "
+ + "outputFormat='" + HTMLOutputFormat.INSTANCE.getName() + "' "
+ + "autoEsc=true "
+ + "nsPrefixes={} "
+ + ">\nx\n<#if true>\n${.outputFormat}\n</#if>\n",
+ "\nHTML\n");
+
+ assertOutput(
+ "<#ftl "
+ + "strip_whitespace=false "
+ + "strip_text=true "
+ + "output_format='" + HTMLOutputFormat.INSTANCE.getName() + "' "
+ + "auto_esc=true "
+ + "ns_prefixes={} "
+ + ">\nx\n<#if true>\n${.output_format}\n</#if>\n",
+ "\nHTML\n");
+
+ assertErrorContains("<#ftl strip_text=true xmlns={}>", "ns_prefixes", "\\!nsPrefixes");
+ assertErrorContains("<#ftl stripText=true xmlns={}>", "nsPrefixes");
+
+ assertErrorContains("<#ftl stripWhitespace=true strip_text=true>", "naming convention");
+ assertErrorContains("<#ftl strip_whitespace=true stripText=true>", "naming convention");
+ assertErrorContains("<#ftl stripWhitespace=true>${.foo_bar}", "naming convention");
+ assertErrorContains("<#ftl strip_whitespace=true>${.fooBar}", "naming convention");
+
+ setConfiguration(new TestConfigurationBuilder()
+ .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
+ .outputEncoding(StandardCharsets.UTF_8)
+ .build());
+ assertErrorContains("<#ftl strip_whitespace=true>", "naming convention");
+ assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
+
+ setConfiguration(new TestConfigurationBuilder()
+ .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
+ .outputEncoding(StandardCharsets.UTF_8)
+ .build());
+ assertErrorContains("<#ftl stripWhitespace=true>", "naming convention");
+ assertOutput("<#ftl strip_whitespace=true>${.output_encoding}", StandardCharsets.UTF_8.name());
+
+ setConfiguration(new TestConfigurationBuilder()
+ .namingConvention(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION)
+ .outputEncoding(StandardCharsets.UTF_8)
+ .build());
+ assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
+ assertOutput("<#ftl encoding='iso-8859-1' stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
+ assertOutput("<#ftl stripWhitespace=true encoding='iso-8859-1'>${.outputEncoding}", StandardCharsets.UTF_8.name());
+ assertOutput("<#ftl encoding='iso-8859-1' strip_whitespace=true>${.output_encoding}", StandardCharsets.UTF_8.name());
+ assertOutput("<#ftl strip_whitespace=true encoding='iso-8859-1'>${.output_encoding}", StandardCharsets.UTF_8.name());
+ }
+
+ @Test
+ public void camelCaseSettingNamesInErrorMessages() throws IOException, TemplateException {
+ assertErrorContains("<#setting fooBar=1>", "booleanFormat", "\\!boolean_format");
+ assertErrorContains("<#setting foo_bar=1>", "boolean_format", "\\!booleanFormat");
+ // [2.4] If camel case will be the recommended style, then this need to be inverted:
+ assertErrorContains("<#setting foo=1>", "boolean_format", "\\!booleanFormat");
+
+ assertErrorContains("<#if x><#elseIf y></#if><#setting foo=1>", "booleanFormat", "\\!boolean_format");
+ assertErrorContains("<#if x><#elseif y></#if><#setting foo=1>", "boolean_format", "\\!booleanFormat");
+
+ setConfigurationToCamelCaseNamingConvention();
+ assertErrorContains("<#setting foo=1>", "booleanFormat", "\\!boolean_format");
+
+ setConfigurationToLegacyCaseNamingConvention();
+ assertErrorContains("<#setting foo=1>", "boolean_format", "\\!booleanFormat");
+ }
+
+ @Test
+ public void camelCaseIncludeParameters() throws IOException, TemplateException {
+ assertOutput("<#ftl stripWhitespace=true>[<#include 'noSuchTemplate' ignoreMissing=true>]", "[]");
+ assertOutput("<#ftl strip_whitespace=true>[<#include 'noSuchTemplate' ignore_missing=true>]", "[]");
+ assertErrorContains("<#ftl stripWhitespace=true>[<#include 'noSuchTemplate' ignore_missing=true>]",
+ "naming convention", "ignore_missing");
+ assertErrorContains("<#ftl strip_whitespace=true>[<#include 'noSuchTemplate' ignoreMissing=true>]",
+ "naming convention", "ignoreMissing");
+ }
+
+ @Test
+ public void specialVarsHasBothNamingStyle() throws IOException, TemplateException {
+ assertContainsBothNamingStyles(
+ new HashSet(Arrays.asList(ASTExpBuiltInVariable.SPEC_VAR_NAMES)),
+ new NamePairAssertion() { @Override
+ public void assertPair(String name1, String name2) { } });
+ }
+
+ @Test
+ public void camelCaseBuiltIns() throws IOException, TemplateException {
+ assertOutput("${'x'?upperCase}", "X");
+ assertOutput("${'x'?upper_case}", "X");
+ }
+
+ @Test
+ public void stringLiteralInterpolation() throws IOException, TemplateException {
+ assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention());
+ addToDataModel("x", "x");
+
+ assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X");
+ assertOutput("${x?upperCase} ${'-${x?upperCase}-'}", "X -X-");
+ assertOutput("${'-${x?upper_case}-'} ${x?upper_case}", "-X- X");
+ assertOutput("${x?upper_case} ${'-${x?upper_case}-'}", "X -X-");
+
+ assertErrorContains("${'-${x?upper_case}-'} ${x?upperCase}",
+ "naming convention", "legacy", "upperCase", "detection", "9");
+ assertErrorContains("${x?upper_case} ${'-${x?upperCase}-'}",
+ "naming convention", "legacy", "upperCase", "detection", "5");
+ assertErrorContains("${'-${x?upperCase}-'} ${x?upper_case}",
+ "naming convention", "camel", "upper_case");
+ assertErrorContains("${x?upperCase} ${'-${x?upper_case}-'}",
+ "naming convention", "camel", "upper_case");
+
+ setConfigurationToCamelCaseNamingConvention();
+ assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X");
+ assertErrorContains("${'-${x?upper_case}-'}",
+ "naming convention", "camel", "upper_case", "\\!detection");
+
+ setConfigurationToLegacyCaseNamingConvention();
+ assertOutput("${'-${x?upper_case}-'} ${x?upper_case}", "-X- X");
+ assertErrorContains("${'-${x?upperCase}-'}",
+ "naming convention", "legacy", "upperCase", "\\!detection");
+ }
+
+ @Test
+ public void evalAndInterpret() throws IOException, TemplateException {
+ assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention());
+ // The naming convention detected doesn't affect the enclosing template's naming convention.
+ // - ?eval:
+ assertOutput("${\"'x'?upperCase\"?eval}${'x'?upper_case}", "XX");
+ assertOutput("${\"'x'?upper_case\"?eval}${'x'?upperCase}", "XX");
+ assertOutput("${'x'?upperCase}${\"'x'?upper_case\"?eval}", "XX");
+ assertErrorContains("${\"'x'\n?upperCase\n?is_string\"?eval}",
+ "naming convention", "camel", "upperCase", "is_string", "line 2", "line 3");
+ // - ?interpret:
+ assertOutput("<@r\"${'x'?upperCase}\"?interpret />${'x'?upper_case}", "XX");
+ assertOutput("<@r\"${'x'?upper_case}\"?interpret />${'x'?upperCase}", "XX");
+ assertOutput("${'x'?upper_case}<@r\"${'x'?upperCase}\"?interpret />", "XX");
+ assertErrorContains("<@r\"${'x'\n?upperCase\n?is_string}\"?interpret />",
+ "naming convention", "camel", "upperCase", "is_string", "line 2", "line 3");
+
+ // Will be inherited by ?eval-ed/?interpreted fragments:
+ setConfigurationToCamelCaseNamingConvention();
+ // - ?eval:
+ assertErrorContains("${\"'x'?upper_case\"?eval}", "naming convention", "camel", "upper_case");
+ assertOutput("${\"'x'?upperCase\"?eval}", "X");
+ // - ?interpret:
+ assertErrorContains("<@r\"${'x'?upper_case}\"?interpret />", "naming convention", "camel", "upper_case");
+ assertOutput("<@r\"${'x'?upperCase}\"?interpret />", "X");
+
+ // Again, will be inherited by ?eval-ed/?interpreted fragments:
+ setConfigurationToLegacyCaseNamingConvention();
+ // - ?eval:
+ assertErrorContains("${\"'x'?upperCase\"?eval}", "naming convention", "legacy", "upperCase");
+ assertOutput("${\"'x'?upper_case\"?eval}", "X");
+ // - ?interpret:
+ assertErrorContains("<@r\"${'x'?upperCase}\"?interpret />", "naming convention", "legacy", "upperCase");
+ assertOutput("<@r\"${'x'?upper_case}\"?interpret />", "X");
+ }
+
+ private void setConfigurationToLegacyCaseNamingConvention() {
+ setConfiguration(new TestConfigurationBuilder()
+ .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
+ .build());
+ }
+
+ @Test
+ public void camelCaseBuiltInErrorMessage() throws IOException, TemplateException {
+ assertErrorContains("${'x'?upperCasw}", "upperCase", "\\!upper_case");
+ assertErrorContains("${'x'?upper_casw}", "upper_case", "\\!upperCase");
+ // [2.4] If camel case will be the recommended style, then this need to be inverted:
+ assertErrorContains("${'x'?foo}", "upper_case", "\\!upperCase");
+
+ assertErrorContains("<#if x><#elseIf y></#if> ${'x'?foo}", "upperCase", "\\!upper_case");
+ assertErrorContains("<#if x><#elseif y></#if>${'x'?foo}", "upper_case", "\\!upperCase");
+
+ setConfigurationToCamelCaseNamingConvention();
+ assertErrorContains("${'x'?foo}", "upperCase", "\\!upper_case");
+ setConfigurationToLegacyCaseNamingConvention();
+ assertErrorContains("${'x'?foo}", "upper_case", "\\!upperCase");
+ }
+
+ private void setConfigurationToCamelCaseNamingConvention() {
+ setConfiguration(new TestConfigurationBuilder()
+ .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
+ .build());
+ }
+
+ @Test
+ public void builtInsHasBothNamingStyle() throws IOException, TemplateException {
+ assertContainsBothNamingStyles(getConfiguration().getSupportedBuiltInNames(), new NamePairAssertion() {
+
+ @Override
+ public void assertPair(String name1, String name2) {
+ ASTExpBuiltIn bi1 = ASTExpBuiltIn.BUILT_INS_BY_NAME.get(name1);
+ ASTExpBuiltIn bi2 = ASTExpBuiltIn.BUILT_INS_BY_NAME.get(name2);
+ assertTrue("\"" + name1 + "\" and \"" + name2 + "\" doesn't belong to the same BI object.",
+ bi1 == bi2);
+ }
+
+ });
+ }
+
+ private void assertContainsBothNamingStyles(Set<String> names, NamePairAssertion namePairAssertion) {
+ Set<String> underscoredNamesWithCamelCasePair = new HashSet<>();
+ for (String name : names) {
+ if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) {
+ String underscoredName = correctIsoBIExceptions(_StringUtil.camelCaseToUnderscored(name));
+ assertTrue(
+ "Missing underscored variation \"" + underscoredName + "\" for \"" + name + "\".",
+ names.contains(underscoredName));
+ assertTrue(underscoredNamesWithCamelCasePair.add(underscoredName));
+
+ namePairAssertion.assertPair(name, underscoredName);
+ }
+ }
+ for (String name : names) {
+ if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.LEGACY_NAMING_CONVENTION) {
+ assertTrue("Missing camel case variation for \"" + name + "\".",
+ underscoredNamesWithCamelCasePair.contains(name));
+ }
+ }
+ }
+
+ private String correctIsoBIExceptions(String underscoredName) {
+ return underscoredName.replace("_n_z", "_nz").replace("_f_z", "_fz");
+ }
+
+ @Test
+ public void camelCaseDirectives() throws IOException, TemplateException {
+ camelCaseDirectives(false);
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
+ .build());
+ camelCaseDirectives(true);
+ }
+
+ private void camelCaseDirectives(boolean squared) throws IOException, TemplateException {
+ assertOutput(
+ squared("<#list 1..4 as x><#if x == 1>one <#elseIf x == 2>two <#elseIf x == 3>three "
+ + "<#else>more</#if></#list>", squared),
+ "one two three more");
+ assertOutput(
+ squared("<#list 1..4 as x><#if x == 1>one <#elseif x == 2>two <#elseif x == 3>three "
+ + "<#else>more</#if></#list>", squared),
+ "one two three more");
+
+ assertOutput(
+ squared("<#escape x as x?upperCase>${'a'}<#noEscape>${'b'}</#noEscape></#escape>", squared),
+ "Ab");
+ assertOutput(
+ squared("<#escape x as x?upper_case>${'a'}<#noescape>${'b'}</#noescape></#escape>", squared),
+ "Ab");
+
+ assertOutput(
+ squared("<#noParse></#noparse></#noParse>", squared),
+ squared("</#noparse>", squared));
+ assertOutput(
+ squared("<#noparse></#noParse></#noparse>", squared),
+ squared("</#noParse>", squared));
+ }
+
+ private String squared(String ftl, boolean squared) {
+ return squared ? ftl.replace('<', '[').replace('>', ']') : ftl;
+ }
+
+ @Test
+ public void explicitNamingConvention() throws IOException, TemplateException {
+ explicitNamingConvention(false);
+ explicitNamingConvention(true);
+ }
+
+ private void explicitNamingConvention(boolean squared) throws IOException, TemplateException {
+ int tagSyntax = squared ? ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX
+ : ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX;
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(tagSyntax)
+ .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
+ .build());
+
+ assertErrorContains(
+ squared("<#if true>t<#elseif false>f</#if>", squared),
+ "naming convention", "camel", "#elseif");
+ assertOutput(
+ squared("<#if true>t<#elseIf false>f</#if>", squared),
+ "t");
+
+ assertErrorContains(
+ squared("<#noparse>${x}</#noparse>", squared),
+ "naming convention", "camel", "#noparse");
+ assertOutput(
+ squared("<#noParse>${x}</#noParse>", squared),
+ "${x}");
+
+ assertErrorContains(
+ squared("<#escape x as -x><#noescape>${1}</#noescape></#escape>", squared),
+ "naming convention", "camel", "#noescape");
+ assertOutput(
+ squared("<#escape x as -x><#noEscape>${1}</#noEscape></#escape>", squared),
+ "1");
+
+ // ---
+
+ setConfiguration(new TestConfigurationBuilder()
+ .tagSyntax(tagSyntax)
+ .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
+ .build());
+
+ assertErrorContains(
+ squared("<#if true>t<#elseIf false>f</#if>", squared),
+ "naming convention", "legacy", "#elseIf");
+ assertOutput(
+ squared("<#if true>t<#elseif false>f</#if>", squared),
+ "t");
+
+ assertErrorContains(
+ squared("<#noParse>${x}</#noParse>", squared),
+ "naming convention", "legacy", "#noParse");
+ assertOutput(
+ squared("<#noparse>${x}</#noparse>", squared),
+ "${x}");
+
+ assertErrorContains(
+ squared("<#escape x as -x><#noEscape>${1}</#noEscape></#escape>", squared),
+ "naming convention", "legacy", "#noEscape");
+ assertOutput(
+ squared("<#escape x as -x><#noescape>${1}</#noescape></#escape>", squared),
+ "1");
+ }
+
+ @Test
+ public void inconsistentAutoDetectedNamingConvention() {
+ assertErrorContains(
+ "<#if x><#elseIf y><#elseif z></#if>",
+ "naming convention", "camel");
+ assertErrorContains(
+ "<#if x><#elseif y><#elseIf z></#if>",
+ "naming convention", "legacy");
+ assertErrorContains(
+ "<#if x><#elseIf y></#if><#noparse></#noparse>",
+ "naming convention", "camel");
+ assertErrorContains(
+ "<#if x><#elseif y></#if><#noParse></#noParse>",
+ "naming convention", "legacy");
+ assertErrorContains(
+ "<#if x><#elseif y><#elseIf z></#if>",
+ "naming convention", "legacy");
+ assertErrorContains(
+ "<#escape x as x + 1><#noEscape></#noescape></#escape>",
+ "naming convention", "camel");
+ assertErrorContains(
+ "<#escape x as x + 1><#noEscape></#noEscape><#noescape></#noescape></#escape>",
+ "naming convention", "camel");
+ assertErrorContains(
+ "<#escape x as x + 1><#noescape></#noEscape></#escape>",
+ "naming convention", "legacy");
+ assertErrorContains(
+ "<#escape x as x + 1><#noescape></#noescape><#noEscape></#noEscape></#escape>",
+ "naming convention", "legacy");
+
+ assertErrorContains("${x?upperCase?is_string}",
+ "naming convention", "camel", "upperCase", "is_string");
+ assertErrorContains("${x?upper_case?isString}",
+ "naming convention", "legacy", "upper_case", "isString");
+
+ assertErrorContains("<#setting outputEncoding='utf-8'>${x?is_string}",
+ "naming convention", "camel", "outputEncoding", "is_string");
+ assertErrorContains("<#setting output_encoding='utf-8'>${x?isString}",
+ "naming convention", "legacy", "output_encoding", "isString");
+
+ assertErrorContains("${x?isString}<#setting output_encoding='utf-8'>",
+ "naming convention", "camel", "isString", "output_encoding");
+ assertErrorContains("${x?is_string}<#setting outputEncoding='utf-8'>",
+ "naming convention", "legacy", "is_string", "outputEncoding");
+
+ assertErrorContains("${.outputEncoding}${x?is_string}",
+ "naming convention", "camel", "outputEncoding", "is_string");
+ assertErrorContains("${.output_encoding}${x?isString}",
+ "naming convention", "legacy", "output_encoding", "isString");
+
+ assertErrorContains("${x?upperCase}<#noparse></#noparse>",
+ "naming convention", "camel", "upperCase", "noparse");
+ assertErrorContains("${x?upper_case}<#noParse></#noParse>",
+ "naming convention", "legacy", "upper_case", "noParse");
+ }
+
+ private interface NamePairAssertion {
+
+ void assertPair(String name1, String name2);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
new file mode 100644
index 0000000..fd1a5a5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.apache.freemarker.test.CopyrightCommentRemoverTemplateLoader;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.apache.freemarker.test.FileTestCase;
+
+public class CanonicalFormTest extends FileTestCase {
+
+ public CanonicalFormTest(String name) {
+ super(name);
+ }
+
+ public void testMacrosCanonicalForm() throws Exception {
+ assertCanonicalFormOf("cano-macros.ftl");
+ }
+
+ public void testIdentifierEscapingCanonicalForm() throws Exception {
+ assertCanonicalFormOf("cano-identifier-escaping.ftl");
+ }
+
+ public void testAssignmentCanonicalForm() throws Exception {
+ assertCanonicalFormOf("cano-assignments.ftl");
+ }
+
+ public void testBuiltInCanonicalForm() throws Exception {
+ assertCanonicalFormOf("cano-builtins.ftl");
+ }
+
+ public void testStringLiteralInterpolationCanonicalForm() throws Exception {
+ assertCanonicalFormOf("cano-strlitinterpolation.ftl");
+ }
+
+ private void assertCanonicalFormOf(String ftlFileName)
+ throws IOException {
+ Configuration cfg = new TestConfigurationBuilder()
+ .templateLoader(
+ new CopyrightCommentRemoverTemplateLoader(
+ new ClassTemplateLoader(CanonicalFormTest.class, "")))
+ .build();
+ StringWriter sw = new StringWriter();
+ cfg.getTemplate(ftlFileName).dump(sw);
+ assertExpectedFileEqualsString(ftlFileName + ".out", sw.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
new file mode 100644
index 0000000..91d3749
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.SimpleDate;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.userpkg.HTMLISOTemplateDateFormatFactory;
+import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class CoercionToTextualTest extends TemplateTest {
+
+ /** 2015-09-06T12:00:00Z */
+ private static long T = 1441540800000L;
+ private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
+
+ @Test
+ public void testBasicStringBuiltins() throws IOException, TemplateException {
+ assertOutput("${s?upperCase}", "ABC");
+ assertOutput("${n?string?lowerCase}", "1.50e+03");
+ assertErrorContains("${n?lowerCase}", "convert", "string", "markup", "text/html");
+ assertOutput("${dt?string?lowerCase}", "2015-09-06t12:00:00z");
+ assertErrorContains("${dt?lowerCase}", "convert", "string", "markup", "text/html");
+ assertOutput("${b?upperCase}", "Y");
+ assertErrorContains("${m?upperCase}", "convertible to string", "HTMLOutputModel");
+ }
+
+ @Test
+ public void testEscBuiltin() throws IOException, TemplateException {
+ setConfiguration(createDefaultConfigurationBuilder()
+ .outputFormat(HTMLOutputFormat.INSTANCE)
+ .autoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY)
+ .booleanFormat("<y>,<n>")
+ .build());
+ assertOutput("${'a<b'?esc}", "a<b");
+ assertOutput("${n?string?esc}", "1.50E+03");
+ assertOutput("${n?esc}", "1.50*10<sup>3</sup>");
+ assertOutput("${dt?string?esc}", "2015-09-06T12:00:00Z");
+ assertOutput("${dt?esc}", "2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${b?esc}", "<y>");
+ assertOutput("${m?esc}", "<p>M</p>");
+ }
+
+ @Test
+ public void testStringOverloadedBuiltIns() throws IOException, TemplateException {
+ assertOutput("${s?contains('b')}", "y");
+ assertOutput("${n?string?contains('E')}", "y");
+ assertErrorContains("${n?contains('E')}", "convert", "string", "markup", "text/html");
+ assertErrorContains("${n?indexOf('E')}", "convert", "string", "markup", "text/html");
+ assertOutput("${dt?string?contains('0')}", "y");
+ assertErrorContains("${dt?contains('0')}", "convert", "string", "markup", "text/html");
+ assertErrorContains("${m?contains('0')}", "convertible to string", "HTMLOutputModel");
+ assertErrorContains("${m?indexOf('0')}", "convertible to string", "HTMLOutputModel");
+ }
+
+ @Test
+ public void testMarkupStringBuiltIns() throws IOException, TemplateException {
+ assertErrorContains("${n?string?markupString}", "Expected", "markup", "string");
+ assertErrorContains("${n?markupString}", "Expected", "markup", "number");
+ assertErrorContains("${dt?markupString}", "Expected", "markup", "date");
+ }
+
+ @Test
+ public void testSimpleInterpolation() throws IOException, TemplateException {
+ assertOutput("${s}", "abc");
+ assertOutput("${n?string}", "1.50E+03");
+ assertOutput("${n}", "1.50*10<sup>3</sup>");
+ assertOutput("${dt?string}", "2015-09-06T12:00:00Z");
+ assertOutput("${dt}", "2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${b}", "y");
+ assertOutput("${m}", "<p>M</p>");
+ }
+
+ @Test
+ public void testConcatenation() throws IOException, TemplateException {
+ assertOutput("${s + '&'}", "abc&");
+ assertOutput("${n?string + '&'}", "1.50E+03&");
+ assertOutput("${n + '&'}", "1.50*10<sup>3</sup>&");
+ assertOutput("${dt?string + '&'}", "2015-09-06T12:00:00Z&");
+ assertOutput("${dt + '&'}", "2015-09-06<span class='T'>T</span>12:00:00Z&");
+ assertOutput("${b + '&'}", "y&");
+ assertOutput("${m + '&'}", "<p>M</p>&");
+ }
+
+ @Test
+ public void testConcatenation2() throws IOException, TemplateException {
+ assertOutput("${'&' + s}", "&abc");
+ assertOutput("${'&' + n?string}", "&1.50E+03");
+ assertOutput("${'&' + n}", "&1.50*10<sup>3</sup>");
+ assertOutput("${'&' + dt?string}", "&2015-09-06T12:00:00Z");
+ assertOutput("${'&' + dt}", "&2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${'&' + b}", "&y");
+ assertOutput("${'&' + m}", "&<p>M</p>");
+ }
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return createDefaultConfigurationBuilder().build();
+ }
+
+ private TestConfigurationBuilder createDefaultConfigurationBuilder() {
+ return new TestConfigurationBuilder()
+ .customNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
+ "G", PrintfGTemplateNumberFormatFactory.INSTANCE))
+ .customDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
+ "HI", HTMLISOTemplateDateFormatFactory.INSTANCE))
+ .numberFormat("@G 3")
+ .dateTimeFormat("@HI")
+ .booleanFormat("y,n");
+ }
+
+ @Before
+ public void setup() throws TemplateModelException {
+ addToDataModel("s", "abc");
+ addToDataModel("n", 1500);
+ addToDataModel("dt", TM);
+ addToDataModel("b", Boolean.TRUE);
+ addToDataModel("m", HTMLOutputFormat.INSTANCE.fromMarkup("<p>M</p>"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurableTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
new file mode 100644
index 0000000..ebcc465
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.core;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.freemarker.core.util._StringUtil;
+import org.junit.Test;
+
+public class ConfigurableTest {
+
+ @Test
+ public void testGetSettingNamesAreSorted() throws Exception {
+ MutableProcessingConfiguration cfgable = createConfigurable();
+ for (boolean camelCase : new boolean[] { false, true }) {
+ Collection<String> names = cfgable.getSettingNames(camelCase);
+ String prevName = null;
+ for (String name : names) {
+ if (prevName != null) {
+ assertThat(name, greaterThan(prevName));
+ }
+ prevName = name;
+ }
+ }
+ }
+
+ @Test
+ public void testStaticFieldKeysCoverAllGetSettingNames() throws Exception {
+ MutableProcessingConfiguration cfgable = createConfigurable();
+ Collection<String> names = cfgable.getSettingNames(false);
+ for (String name : names) {
+ assertTrue("No field was found for " + name, keyFieldExists(name));
+ }
+ }
+
+ @Test
+ public void testGetSettingNamesCoversAllStaticKeyFields() throws Exception {
+ MutableProcessingConfiguration cfgable = createConfigurable();
+ Collection<String> names = cfgable.getSettingNames(false);
+
+ for (Field f : MutableProcessingConfiguration.class.getFields()) {
+ if (f.getName().endsWith("_KEY")) {
+ final Object name = f.get(null);
+ assertTrue("Missing setting name: " + name, names.contains(name));
+ }
+ }
+ }
+
+ @Test
+ public void testKeyStaticFieldsHasAllVariationsAndCorrectFormat() throws IllegalArgumentException, IllegalAccessException {
+ ConfigurableTest.testKeyStaticFieldsHasAllVariationsAndCorrectFormat(MutableProcessingConfiguration.class);
+ }
+
+ @Test
+ public void testGetSettingNamesNameConventionsContainTheSame() throws Exception {
+ MutableProcessingConfiguration cfgable = createConfigurable();
+ ConfigurableTest.testGetSettingNamesNameConventionsContainTheSame(
+ new ArrayList<>(cfgable.getSettingNames(false)),
+ new ArrayList<>(cfgable.getSettingNames(true)));
+ }
+
+ public static void testKeyStaticFieldsHasAllVariationsAndCorrectFormat(
+ Class<? extends MutableProcessingConfiguration> confClass) throws IllegalArgumentException, IllegalAccessException {
+ // For all _KEY fields there must be a _KEY_CAMEL_CASE and a _KEY_SNAKE_CASE field.
+ // Their content must not contradict the expected naming convention.
+ // They _KEY filed value must be deducable from the field name
+ // The _KEY value must be the same as _KEY_SNAKE_CASE field.
+ // The _KEY_CAMEL_CASE converted to snake case must give the value of the _KEY_SNAKE_CASE.
+ for (Field field : confClass.getFields()) {
+ String fieldName = field.getName();
+ if (fieldName.endsWith("_KEY")) {
+ String keyFieldValue = (String) field.get(null);
+ assertNotEquals(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION,
+ _StringUtil.getIdentifierNamingConvention(keyFieldValue));
+ assertEquals(fieldName.substring(0, fieldName.length() - 4).toLowerCase(), keyFieldValue);
+
+ try {
+ String keySCFieldValue = (String) confClass.getField(fieldName + "_SNAKE_CASE").get(null);
+ assertEquals(keyFieldValue, keySCFieldValue);
+ } catch (NoSuchFieldException e) {
+ fail("Missing ..._SNAKE_CASE field for " + fieldName);
+ }
+
+ try {
+ String keyCCFieldValue = (String) confClass.getField(fieldName + "_CAMEL_CASE").get(null);
+ assertNotEquals(ParsingConfiguration.LEGACY_NAMING_CONVENTION,
+ _StringUtil.getIdentifierNamingConvention(keyCCFieldValue));
+ assertEquals(keyFieldValue, _StringUtil.camelCaseToUnderscored(keyCCFieldValue));
+ } catch (NoSuchFieldException e) {
+ fail("Missing ..._CAMEL_CASE field for " + fieldName);
+ }
+ }
+ }
+
+ // For each _KEY_SNAKE_CASE field there must be a _KEY field.
+ for (Field field : confClass.getFields()) {
+ String fieldName = field.getName();
+ if (fieldName.endsWith("_KEY_SNAKE_CASE")) {
+ try {
+ confClass.getField(fieldName.substring(0, fieldName.length() - 11)).get(null);
+ } catch (NoSuchFieldException e) {
+ fail("Missing ..._KEY field for " + fieldName);
+ }
+ }
+ }
+
+ // For each _KEY_CAMEL_CASE field there must be a _KEY field.
+ for (Field field : confClass.getFields()) {
+ String fieldName = field.getName();
+ if (fieldName.endsWith("_KEY_CAMEL_CASE")) {
+ try {
+ confClass.getField(fieldName.substring(0, fieldName.length() - 11)).get(null);
+ } catch (NoSuchFieldException e) {
+ fail("Missing ..._KEY field for " + fieldName);
+ }
+ }
+ }
+ }
+
+ public static void testGetSettingNamesNameConventionsContainTheSame(List<String> namesSCList, List<String> namesCCList) {
+ Set<String> namesSC = new HashSet<>(namesSCList);
+ assertEquals(namesSCList.size(), namesSC.size());
+
+ Set<String> namesCC = new HashSet<>(namesCCList);
+ assertEquals(namesCCList.size(), namesCC.size());
+
+ assertEquals(namesSC.size(), namesCC.size());
+
+ for (String nameCC : namesCC) {
+ final String nameSC = _StringUtil.camelCaseToUnderscored(nameCC);
+ if (!namesSC.contains(nameSC)) {
+ fail("\"" + nameCC + "\" misses corresponding snake case name, \"" + nameSC + "\".");
+ }
+ }
+ }
+
+ private MutableProcessingConfiguration createConfigurable() throws IOException {
+ return new TemplateConfiguration.Builder();
+ }
+
+ private boolean keyFieldExists(String name) throws Exception {
+ try {
+ MutableProcessingConfiguration.class.getField(name.toUpperCase() + "_KEY");
+ } catch (NoSuchFieldException e) {
+ return false;
+ }
+ return true;
+ }
+
+}
[23/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/CamelCaseTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
deleted file mode 100644
index 95572ad..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/CamelCaseTest.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
-import org.apache.freemarker.core.util._StringUtil;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class CamelCaseTest extends TemplateTest {
-
- @Test
- public void camelCaseSpecialVars() throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder()
- .outputEncoding(StandardCharsets.UTF_8)
- .urlEscapingCharset(StandardCharsets.ISO_8859_1)
- .locale(Locale.GERMANY)
- .build());
- assertOutput("${.dataModel?isHash?c}", "true");
- assertOutput("${.data_model?is_hash?c}", "true");
- assertOutput("${.localeObject.toString()}", "de_DE");
- assertOutput("${.locale_object.toString()}", "de_DE");
- assertOutput("${.templateName!'null'}", "null");
- assertOutput("${.template_name!'null'}", "null");
- assertOutput("${.currentTemplateName!'null'}", "null");
- assertOutput("${.current_template_name!'null'}", "null");
- assertOutput("${.mainTemplateName!'null'}", "null");
- assertOutput("${.main_template_name!'null'}", "null");
- assertOutput("${.outputEncoding}", StandardCharsets.UTF_8.name());
- assertOutput("${.output_encoding}", StandardCharsets.UTF_8.name());
- assertOutput("${.outputFormat}", UndefinedOutputFormat.INSTANCE.getName());
- assertOutput("${.output_format}", UndefinedOutputFormat.INSTANCE.getName());
- assertOutput("${.urlEscapingCharset}", StandardCharsets.ISO_8859_1.name());
- assertOutput("${.url_escaping_charset}", StandardCharsets.ISO_8859_1.name());
- assertOutput("${.currentNode!'-'}", "-");
- assertOutput("${.current_node!'-'}", "-");
- }
-
- @Test
- public void camelCaseSpecialVarsInErrorMessage() throws IOException, TemplateException {
- assertErrorContains("${.fooBar}", "dataModel", "\\!data_model");
- assertErrorContains("${.foo_bar}", "data_model", "\\!dataModel");
- // [2.4] If camel case will be the recommended style, then this need to be inverted:
- assertErrorContains("${.foo}", "data_model", "\\!dataModel");
-
- assertErrorContains("<#if x><#elseIf y></#if>${.foo}", "dataModel", "\\!data_model");
- assertErrorContains("<#if x><#elseif y></#if>${.foo}", "data_model", "\\!dataModel");
-
- setConfigurationToCamelCaseNamingConvention();
- assertErrorContains("${.foo}", "dataModel", "\\!data_model");
-
- setConfigurationToLegacyCaseNamingConvention();
- assertErrorContains("${.foo}", "data_model", "\\!dataModel");
- }
-
- @Test
- public void camelCaseSettingNames() throws IOException, TemplateException {
- assertOutput("<#setting booleanFormat='Y,N'>${true} <#setting booleanFormat='+,-'>${true}", "Y +");
- assertOutput("<#setting boolean_format='Y,N'>${true} <#setting boolean_format='+,-'>${true}", "Y +");
-
- // Still works inside ?interpret
- assertOutput("<@r\"<#setting booleanFormat='Y,N'>${true}\"?interpret />", "Y");
- }
-
- @Test
- public void camelCaseFtlHeaderParameters() throws IOException, TemplateException {
- assertOutput(
- "<#ftl "
- + "stripWhitespace=false "
- + "stripText=true "
- + "outputFormat='" + HTMLOutputFormat.INSTANCE.getName() + "' "
- + "autoEsc=true "
- + "nsPrefixes={} "
- + ">\nx\n<#if true>\n${.outputFormat}\n</#if>\n",
- "\nHTML\n");
-
- assertOutput(
- "<#ftl "
- + "strip_whitespace=false "
- + "strip_text=true "
- + "output_format='" + HTMLOutputFormat.INSTANCE.getName() + "' "
- + "auto_esc=true "
- + "ns_prefixes={} "
- + ">\nx\n<#if true>\n${.output_format}\n</#if>\n",
- "\nHTML\n");
-
- assertErrorContains("<#ftl strip_text=true xmlns={}>", "ns_prefixes", "\\!nsPrefixes");
- assertErrorContains("<#ftl stripText=true xmlns={}>", "nsPrefixes");
-
- assertErrorContains("<#ftl stripWhitespace=true strip_text=true>", "naming convention");
- assertErrorContains("<#ftl strip_whitespace=true stripText=true>", "naming convention");
- assertErrorContains("<#ftl stripWhitespace=true>${.foo_bar}", "naming convention");
- assertErrorContains("<#ftl strip_whitespace=true>${.fooBar}", "naming convention");
-
- setConfiguration(new TestConfigurationBuilder()
- .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
- .outputEncoding(StandardCharsets.UTF_8)
- .build());
- assertErrorContains("<#ftl strip_whitespace=true>", "naming convention");
- assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
-
- setConfiguration(new TestConfigurationBuilder()
- .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
- .outputEncoding(StandardCharsets.UTF_8)
- .build());
- assertErrorContains("<#ftl stripWhitespace=true>", "naming convention");
- assertOutput("<#ftl strip_whitespace=true>${.output_encoding}", StandardCharsets.UTF_8.name());
-
- setConfiguration(new TestConfigurationBuilder()
- .namingConvention(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION)
- .outputEncoding(StandardCharsets.UTF_8)
- .build());
- assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
- assertOutput("<#ftl encoding='iso-8859-1' stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name());
- assertOutput("<#ftl stripWhitespace=true encoding='iso-8859-1'>${.outputEncoding}", StandardCharsets.UTF_8.name());
- assertOutput("<#ftl encoding='iso-8859-1' strip_whitespace=true>${.output_encoding}", StandardCharsets.UTF_8.name());
- assertOutput("<#ftl strip_whitespace=true encoding='iso-8859-1'>${.output_encoding}", StandardCharsets.UTF_8.name());
- }
-
- @Test
- public void camelCaseSettingNamesInErrorMessages() throws IOException, TemplateException {
- assertErrorContains("<#setting fooBar=1>", "booleanFormat", "\\!boolean_format");
- assertErrorContains("<#setting foo_bar=1>", "boolean_format", "\\!booleanFormat");
- // [2.4] If camel case will be the recommended style, then this need to be inverted:
- assertErrorContains("<#setting foo=1>", "boolean_format", "\\!booleanFormat");
-
- assertErrorContains("<#if x><#elseIf y></#if><#setting foo=1>", "booleanFormat", "\\!boolean_format");
- assertErrorContains("<#if x><#elseif y></#if><#setting foo=1>", "boolean_format", "\\!booleanFormat");
-
- setConfigurationToCamelCaseNamingConvention();
- assertErrorContains("<#setting foo=1>", "booleanFormat", "\\!boolean_format");
-
- setConfigurationToLegacyCaseNamingConvention();
- assertErrorContains("<#setting foo=1>", "boolean_format", "\\!booleanFormat");
- }
-
- @Test
- public void camelCaseIncludeParameters() throws IOException, TemplateException {
- assertOutput("<#ftl stripWhitespace=true>[<#include 'noSuchTemplate' ignoreMissing=true>]", "[]");
- assertOutput("<#ftl strip_whitespace=true>[<#include 'noSuchTemplate' ignore_missing=true>]", "[]");
- assertErrorContains("<#ftl stripWhitespace=true>[<#include 'noSuchTemplate' ignore_missing=true>]",
- "naming convention", "ignore_missing");
- assertErrorContains("<#ftl strip_whitespace=true>[<#include 'noSuchTemplate' ignoreMissing=true>]",
- "naming convention", "ignoreMissing");
- }
-
- @Test
- public void specialVarsHasBothNamingStyle() throws IOException, TemplateException {
- assertContainsBothNamingStyles(
- new HashSet(Arrays.asList(ASTExpBuiltInVariable.SPEC_VAR_NAMES)),
- new NamePairAssertion() { @Override
- public void assertPair(String name1, String name2) { } });
- }
-
- @Test
- public void camelCaseBuiltIns() throws IOException, TemplateException {
- assertOutput("${'x'?upperCase}", "X");
- assertOutput("${'x'?upper_case}", "X");
- }
-
- @Test
- public void stringLiteralInterpolation() throws IOException, TemplateException {
- assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention());
- addToDataModel("x", "x");
-
- assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X");
- assertOutput("${x?upperCase} ${'-${x?upperCase}-'}", "X -X-");
- assertOutput("${'-${x?upper_case}-'} ${x?upper_case}", "-X- X");
- assertOutput("${x?upper_case} ${'-${x?upper_case}-'}", "X -X-");
-
- assertErrorContains("${'-${x?upper_case}-'} ${x?upperCase}",
- "naming convention", "legacy", "upperCase", "detection", "9");
- assertErrorContains("${x?upper_case} ${'-${x?upperCase}-'}",
- "naming convention", "legacy", "upperCase", "detection", "5");
- assertErrorContains("${'-${x?upperCase}-'} ${x?upper_case}",
- "naming convention", "camel", "upper_case");
- assertErrorContains("${x?upperCase} ${'-${x?upper_case}-'}",
- "naming convention", "camel", "upper_case");
-
- setConfigurationToCamelCaseNamingConvention();
- assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X");
- assertErrorContains("${'-${x?upper_case}-'}",
- "naming convention", "camel", "upper_case", "\\!detection");
-
- setConfigurationToLegacyCaseNamingConvention();
- assertOutput("${'-${x?upper_case}-'} ${x?upper_case}", "-X- X");
- assertErrorContains("${'-${x?upperCase}-'}",
- "naming convention", "legacy", "upperCase", "\\!detection");
- }
-
- @Test
- public void evalAndInterpret() throws IOException, TemplateException {
- assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention());
- // The naming convention detected doesn't affect the enclosing template's naming convention.
- // - ?eval:
- assertOutput("${\"'x'?upperCase\"?eval}${'x'?upper_case}", "XX");
- assertOutput("${\"'x'?upper_case\"?eval}${'x'?upperCase}", "XX");
- assertOutput("${'x'?upperCase}${\"'x'?upper_case\"?eval}", "XX");
- assertErrorContains("${\"'x'\n?upperCase\n?is_string\"?eval}",
- "naming convention", "camel", "upperCase", "is_string", "line 2", "line 3");
- // - ?interpret:
- assertOutput("<@r\"${'x'?upperCase}\"?interpret />${'x'?upper_case}", "XX");
- assertOutput("<@r\"${'x'?upper_case}\"?interpret />${'x'?upperCase}", "XX");
- assertOutput("${'x'?upper_case}<@r\"${'x'?upperCase}\"?interpret />", "XX");
- assertErrorContains("<@r\"${'x'\n?upperCase\n?is_string}\"?interpret />",
- "naming convention", "camel", "upperCase", "is_string", "line 2", "line 3");
-
- // Will be inherited by ?eval-ed/?interpreted fragments:
- setConfigurationToCamelCaseNamingConvention();
- // - ?eval:
- assertErrorContains("${\"'x'?upper_case\"?eval}", "naming convention", "camel", "upper_case");
- assertOutput("${\"'x'?upperCase\"?eval}", "X");
- // - ?interpret:
- assertErrorContains("<@r\"${'x'?upper_case}\"?interpret />", "naming convention", "camel", "upper_case");
- assertOutput("<@r\"${'x'?upperCase}\"?interpret />", "X");
-
- // Again, will be inherited by ?eval-ed/?interpreted fragments:
- setConfigurationToLegacyCaseNamingConvention();
- // - ?eval:
- assertErrorContains("${\"'x'?upperCase\"?eval}", "naming convention", "legacy", "upperCase");
- assertOutput("${\"'x'?upper_case\"?eval}", "X");
- // - ?interpret:
- assertErrorContains("<@r\"${'x'?upperCase}\"?interpret />", "naming convention", "legacy", "upperCase");
- assertOutput("<@r\"${'x'?upper_case}\"?interpret />", "X");
- }
-
- private void setConfigurationToLegacyCaseNamingConvention() {
- setConfiguration(new TestConfigurationBuilder()
- .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
- .build());
- }
-
- @Test
- public void camelCaseBuiltInErrorMessage() throws IOException, TemplateException {
- assertErrorContains("${'x'?upperCasw}", "upperCase", "\\!upper_case");
- assertErrorContains("${'x'?upper_casw}", "upper_case", "\\!upperCase");
- // [2.4] If camel case will be the recommended style, then this need to be inverted:
- assertErrorContains("${'x'?foo}", "upper_case", "\\!upperCase");
-
- assertErrorContains("<#if x><#elseIf y></#if> ${'x'?foo}", "upperCase", "\\!upper_case");
- assertErrorContains("<#if x><#elseif y></#if>${'x'?foo}", "upper_case", "\\!upperCase");
-
- setConfigurationToCamelCaseNamingConvention();
- assertErrorContains("${'x'?foo}", "upperCase", "\\!upper_case");
- setConfigurationToLegacyCaseNamingConvention();
- assertErrorContains("${'x'?foo}", "upper_case", "\\!upperCase");
- }
-
- private void setConfigurationToCamelCaseNamingConvention() {
- setConfiguration(new TestConfigurationBuilder()
- .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
- .build());
- }
-
- @Test
- public void builtInsHasBothNamingStyle() throws IOException, TemplateException {
- assertContainsBothNamingStyles(getConfiguration().getSupportedBuiltInNames(), new NamePairAssertion() {
-
- @Override
- public void assertPair(String name1, String name2) {
- ASTExpBuiltIn bi1 = ASTExpBuiltIn.BUILT_INS_BY_NAME.get(name1);
- ASTExpBuiltIn bi2 = ASTExpBuiltIn.BUILT_INS_BY_NAME.get(name2);
- assertTrue("\"" + name1 + "\" and \"" + name2 + "\" doesn't belong to the same BI object.",
- bi1 == bi2);
- }
-
- });
- }
-
- private void assertContainsBothNamingStyles(Set<String> names, NamePairAssertion namePairAssertion) {
- Set<String> underscoredNamesWithCamelCasePair = new HashSet<>();
- for (String name : names) {
- if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) {
- String underscoredName = correctIsoBIExceptions(_StringUtil.camelCaseToUnderscored(name));
- assertTrue(
- "Missing underscored variation \"" + underscoredName + "\" for \"" + name + "\".",
- names.contains(underscoredName));
- assertTrue(underscoredNamesWithCamelCasePair.add(underscoredName));
-
- namePairAssertion.assertPair(name, underscoredName);
- }
- }
- for (String name : names) {
- if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.LEGACY_NAMING_CONVENTION) {
- assertTrue("Missing camel case variation for \"" + name + "\".",
- underscoredNamesWithCamelCasePair.contains(name));
- }
- }
- }
-
- private String correctIsoBIExceptions(String underscoredName) {
- return underscoredName.replace("_n_z", "_nz").replace("_f_z", "_fz");
- }
-
- @Test
- public void camelCaseDirectives() throws IOException, TemplateException {
- camelCaseDirectives(false);
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX)
- .build());
- camelCaseDirectives(true);
- }
-
- private void camelCaseDirectives(boolean squared) throws IOException, TemplateException {
- assertOutput(
- squared("<#list 1..4 as x><#if x == 1>one <#elseIf x == 2>two <#elseIf x == 3>three "
- + "<#else>more</#if></#list>", squared),
- "one two three more");
- assertOutput(
- squared("<#list 1..4 as x><#if x == 1>one <#elseif x == 2>two <#elseif x == 3>three "
- + "<#else>more</#if></#list>", squared),
- "one two three more");
-
- assertOutput(
- squared("<#escape x as x?upperCase>${'a'}<#noEscape>${'b'}</#noEscape></#escape>", squared),
- "Ab");
- assertOutput(
- squared("<#escape x as x?upper_case>${'a'}<#noescape>${'b'}</#noescape></#escape>", squared),
- "Ab");
-
- assertOutput(
- squared("<#noParse></#noparse></#noParse>", squared),
- squared("</#noparse>", squared));
- assertOutput(
- squared("<#noparse></#noParse></#noparse>", squared),
- squared("</#noParse>", squared));
- }
-
- private String squared(String ftl, boolean squared) {
- return squared ? ftl.replace('<', '[').replace('>', ']') : ftl;
- }
-
- @Test
- public void explicitNamingConvention() throws IOException, TemplateException {
- explicitNamingConvention(false);
- explicitNamingConvention(true);
- }
-
- private void explicitNamingConvention(boolean squared) throws IOException, TemplateException {
- int tagSyntax = squared ? ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX
- : ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX;
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(tagSyntax)
- .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION)
- .build());
-
- assertErrorContains(
- squared("<#if true>t<#elseif false>f</#if>", squared),
- "naming convention", "camel", "#elseif");
- assertOutput(
- squared("<#if true>t<#elseIf false>f</#if>", squared),
- "t");
-
- assertErrorContains(
- squared("<#noparse>${x}</#noparse>", squared),
- "naming convention", "camel", "#noparse");
- assertOutput(
- squared("<#noParse>${x}</#noParse>", squared),
- "${x}");
-
- assertErrorContains(
- squared("<#escape x as -x><#noescape>${1}</#noescape></#escape>", squared),
- "naming convention", "camel", "#noescape");
- assertOutput(
- squared("<#escape x as -x><#noEscape>${1}</#noEscape></#escape>", squared),
- "1");
-
- // ---
-
- setConfiguration(new TestConfigurationBuilder()
- .tagSyntax(tagSyntax)
- .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION)
- .build());
-
- assertErrorContains(
- squared("<#if true>t<#elseIf false>f</#if>", squared),
- "naming convention", "legacy", "#elseIf");
- assertOutput(
- squared("<#if true>t<#elseif false>f</#if>", squared),
- "t");
-
- assertErrorContains(
- squared("<#noParse>${x}</#noParse>", squared),
- "naming convention", "legacy", "#noParse");
- assertOutput(
- squared("<#noparse>${x}</#noparse>", squared),
- "${x}");
-
- assertErrorContains(
- squared("<#escape x as -x><#noEscape>${1}</#noEscape></#escape>", squared),
- "naming convention", "legacy", "#noEscape");
- assertOutput(
- squared("<#escape x as -x><#noescape>${1}</#noescape></#escape>", squared),
- "1");
- }
-
- @Test
- public void inconsistentAutoDetectedNamingConvention() {
- assertErrorContains(
- "<#if x><#elseIf y><#elseif z></#if>",
- "naming convention", "camel");
- assertErrorContains(
- "<#if x><#elseif y><#elseIf z></#if>",
- "naming convention", "legacy");
- assertErrorContains(
- "<#if x><#elseIf y></#if><#noparse></#noparse>",
- "naming convention", "camel");
- assertErrorContains(
- "<#if x><#elseif y></#if><#noParse></#noParse>",
- "naming convention", "legacy");
- assertErrorContains(
- "<#if x><#elseif y><#elseIf z></#if>",
- "naming convention", "legacy");
- assertErrorContains(
- "<#escape x as x + 1><#noEscape></#noescape></#escape>",
- "naming convention", "camel");
- assertErrorContains(
- "<#escape x as x + 1><#noEscape></#noEscape><#noescape></#noescape></#escape>",
- "naming convention", "camel");
- assertErrorContains(
- "<#escape x as x + 1><#noescape></#noEscape></#escape>",
- "naming convention", "legacy");
- assertErrorContains(
- "<#escape x as x + 1><#noescape></#noescape><#noEscape></#noEscape></#escape>",
- "naming convention", "legacy");
-
- assertErrorContains("${x?upperCase?is_string}",
- "naming convention", "camel", "upperCase", "is_string");
- assertErrorContains("${x?upper_case?isString}",
- "naming convention", "legacy", "upper_case", "isString");
-
- assertErrorContains("<#setting outputEncoding='utf-8'>${x?is_string}",
- "naming convention", "camel", "outputEncoding", "is_string");
- assertErrorContains("<#setting output_encoding='utf-8'>${x?isString}",
- "naming convention", "legacy", "output_encoding", "isString");
-
- assertErrorContains("${x?isString}<#setting output_encoding='utf-8'>",
- "naming convention", "camel", "isString", "output_encoding");
- assertErrorContains("${x?is_string}<#setting outputEncoding='utf-8'>",
- "naming convention", "legacy", "is_string", "outputEncoding");
-
- assertErrorContains("${.outputEncoding}${x?is_string}",
- "naming convention", "camel", "outputEncoding", "is_string");
- assertErrorContains("${.output_encoding}${x?isString}",
- "naming convention", "legacy", "output_encoding", "isString");
-
- assertErrorContains("${x?upperCase}<#noparse></#noparse>",
- "naming convention", "camel", "upperCase", "noparse");
- assertErrorContains("${x?upper_case}<#noParse></#noParse>",
- "naming convention", "legacy", "upper_case", "noParse");
- }
-
- private interface NamePairAssertion {
-
- void assertPair(String name1, String name2);
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
deleted file mode 100644
index c78c90e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.apache.freemarker.test.CopyrightCommentRemoverTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.apache.freemarker.test.util.FileTestCase;
-
-public class CanonicalFormTest extends FileTestCase {
-
- public CanonicalFormTest(String name) {
- super(name);
- }
-
- public void testMacrosCanonicalForm() throws Exception {
- assertCanonicalFormOf("cano-macros.ftl");
- }
-
- public void testIdentifierEscapingCanonicalForm() throws Exception {
- assertCanonicalFormOf("cano-identifier-escaping.ftl");
- }
-
- public void testAssignmentCanonicalForm() throws Exception {
- assertCanonicalFormOf("cano-assignments.ftl");
- }
-
- public void testBuiltInCanonicalForm() throws Exception {
- assertCanonicalFormOf("cano-builtins.ftl");
- }
-
- public void testStringLiteralInterpolationCanonicalForm() throws Exception {
- assertCanonicalFormOf("cano-strlitinterpolation.ftl");
- }
-
- private void assertCanonicalFormOf(String ftlFileName)
- throws IOException {
- Configuration cfg = new TestConfigurationBuilder()
- .templateLoader(
- new CopyrightCommentRemoverTemplateLoader(
- new ClassTemplateLoader(CanonicalFormTest.class, "")))
- .build();
- StringWriter sw = new StringWriter();
- cfg.getTemplate(ftlFileName).dump(sw);
- assertExpectedFileEqualsString(ftlFileName + ".out", sw.toString());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
deleted file mode 100644
index 91d3749..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Date;
-
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.SimpleDate;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.userpkg.HTMLISOTemplateDateFormatFactory;
-import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
-import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Before;
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class CoercionToTextualTest extends TemplateTest {
-
- /** 2015-09-06T12:00:00Z */
- private static long T = 1441540800000L;
- private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
-
- @Test
- public void testBasicStringBuiltins() throws IOException, TemplateException {
- assertOutput("${s?upperCase}", "ABC");
- assertOutput("${n?string?lowerCase}", "1.50e+03");
- assertErrorContains("${n?lowerCase}", "convert", "string", "markup", "text/html");
- assertOutput("${dt?string?lowerCase}", "2015-09-06t12:00:00z");
- assertErrorContains("${dt?lowerCase}", "convert", "string", "markup", "text/html");
- assertOutput("${b?upperCase}", "Y");
- assertErrorContains("${m?upperCase}", "convertible to string", "HTMLOutputModel");
- }
-
- @Test
- public void testEscBuiltin() throws IOException, TemplateException {
- setConfiguration(createDefaultConfigurationBuilder()
- .outputFormat(HTMLOutputFormat.INSTANCE)
- .autoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY)
- .booleanFormat("<y>,<n>")
- .build());
- assertOutput("${'a<b'?esc}", "a<b");
- assertOutput("${n?string?esc}", "1.50E+03");
- assertOutput("${n?esc}", "1.50*10<sup>3</sup>");
- assertOutput("${dt?string?esc}", "2015-09-06T12:00:00Z");
- assertOutput("${dt?esc}", "2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${b?esc}", "<y>");
- assertOutput("${m?esc}", "<p>M</p>");
- }
-
- @Test
- public void testStringOverloadedBuiltIns() throws IOException, TemplateException {
- assertOutput("${s?contains('b')}", "y");
- assertOutput("${n?string?contains('E')}", "y");
- assertErrorContains("${n?contains('E')}", "convert", "string", "markup", "text/html");
- assertErrorContains("${n?indexOf('E')}", "convert", "string", "markup", "text/html");
- assertOutput("${dt?string?contains('0')}", "y");
- assertErrorContains("${dt?contains('0')}", "convert", "string", "markup", "text/html");
- assertErrorContains("${m?contains('0')}", "convertible to string", "HTMLOutputModel");
- assertErrorContains("${m?indexOf('0')}", "convertible to string", "HTMLOutputModel");
- }
-
- @Test
- public void testMarkupStringBuiltIns() throws IOException, TemplateException {
- assertErrorContains("${n?string?markupString}", "Expected", "markup", "string");
- assertErrorContains("${n?markupString}", "Expected", "markup", "number");
- assertErrorContains("${dt?markupString}", "Expected", "markup", "date");
- }
-
- @Test
- public void testSimpleInterpolation() throws IOException, TemplateException {
- assertOutput("${s}", "abc");
- assertOutput("${n?string}", "1.50E+03");
- assertOutput("${n}", "1.50*10<sup>3</sup>");
- assertOutput("${dt?string}", "2015-09-06T12:00:00Z");
- assertOutput("${dt}", "2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${b}", "y");
- assertOutput("${m}", "<p>M</p>");
- }
-
- @Test
- public void testConcatenation() throws IOException, TemplateException {
- assertOutput("${s + '&'}", "abc&");
- assertOutput("${n?string + '&'}", "1.50E+03&");
- assertOutput("${n + '&'}", "1.50*10<sup>3</sup>&");
- assertOutput("${dt?string + '&'}", "2015-09-06T12:00:00Z&");
- assertOutput("${dt + '&'}", "2015-09-06<span class='T'>T</span>12:00:00Z&");
- assertOutput("${b + '&'}", "y&");
- assertOutput("${m + '&'}", "<p>M</p>&");
- }
-
- @Test
- public void testConcatenation2() throws IOException, TemplateException {
- assertOutput("${'&' + s}", "&abc");
- assertOutput("${'&' + n?string}", "&1.50E+03");
- assertOutput("${'&' + n}", "&1.50*10<sup>3</sup>");
- assertOutput("${'&' + dt?string}", "&2015-09-06T12:00:00Z");
- assertOutput("${'&' + dt}", "&2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${'&' + b}", "&y");
- assertOutput("${'&' + m}", "&<p>M</p>");
- }
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return createDefaultConfigurationBuilder().build();
- }
-
- private TestConfigurationBuilder createDefaultConfigurationBuilder() {
- return new TestConfigurationBuilder()
- .customNumberFormats(Collections.<String, TemplateNumberFormatFactory>singletonMap(
- "G", PrintfGTemplateNumberFormatFactory.INSTANCE))
- .customDateFormats(Collections.<String, TemplateDateFormatFactory>singletonMap(
- "HI", HTMLISOTemplateDateFormatFactory.INSTANCE))
- .numberFormat("@G 3")
- .dateTimeFormat("@HI")
- .booleanFormat("y,n");
- }
-
- @Before
- public void setup() throws TemplateModelException {
- addToDataModel("s", "abc");
- addToDataModel("n", 1500);
- addToDataModel("dt", TM);
- addToDataModel("b", Boolean.TRUE);
- addToDataModel("m", HTMLOutputFormat.INSTANCE.fromMarkup("<p>M</p>"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurableTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
deleted file mode 100644
index ebcc465..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/ConfigurableTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.freemarker.core.util._StringUtil;
-import org.junit.Test;
-
-public class ConfigurableTest {
-
- @Test
- public void testGetSettingNamesAreSorted() throws Exception {
- MutableProcessingConfiguration cfgable = createConfigurable();
- for (boolean camelCase : new boolean[] { false, true }) {
- Collection<String> names = cfgable.getSettingNames(camelCase);
- String prevName = null;
- for (String name : names) {
- if (prevName != null) {
- assertThat(name, greaterThan(prevName));
- }
- prevName = name;
- }
- }
- }
-
- @Test
- public void testStaticFieldKeysCoverAllGetSettingNames() throws Exception {
- MutableProcessingConfiguration cfgable = createConfigurable();
- Collection<String> names = cfgable.getSettingNames(false);
- for (String name : names) {
- assertTrue("No field was found for " + name, keyFieldExists(name));
- }
- }
-
- @Test
- public void testGetSettingNamesCoversAllStaticKeyFields() throws Exception {
- MutableProcessingConfiguration cfgable = createConfigurable();
- Collection<String> names = cfgable.getSettingNames(false);
-
- for (Field f : MutableProcessingConfiguration.class.getFields()) {
- if (f.getName().endsWith("_KEY")) {
- final Object name = f.get(null);
- assertTrue("Missing setting name: " + name, names.contains(name));
- }
- }
- }
-
- @Test
- public void testKeyStaticFieldsHasAllVariationsAndCorrectFormat() throws IllegalArgumentException, IllegalAccessException {
- ConfigurableTest.testKeyStaticFieldsHasAllVariationsAndCorrectFormat(MutableProcessingConfiguration.class);
- }
-
- @Test
- public void testGetSettingNamesNameConventionsContainTheSame() throws Exception {
- MutableProcessingConfiguration cfgable = createConfigurable();
- ConfigurableTest.testGetSettingNamesNameConventionsContainTheSame(
- new ArrayList<>(cfgable.getSettingNames(false)),
- new ArrayList<>(cfgable.getSettingNames(true)));
- }
-
- public static void testKeyStaticFieldsHasAllVariationsAndCorrectFormat(
- Class<? extends MutableProcessingConfiguration> confClass) throws IllegalArgumentException, IllegalAccessException {
- // For all _KEY fields there must be a _KEY_CAMEL_CASE and a _KEY_SNAKE_CASE field.
- // Their content must not contradict the expected naming convention.
- // They _KEY filed value must be deducable from the field name
- // The _KEY value must be the same as _KEY_SNAKE_CASE field.
- // The _KEY_CAMEL_CASE converted to snake case must give the value of the _KEY_SNAKE_CASE.
- for (Field field : confClass.getFields()) {
- String fieldName = field.getName();
- if (fieldName.endsWith("_KEY")) {
- String keyFieldValue = (String) field.get(null);
- assertNotEquals(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION,
- _StringUtil.getIdentifierNamingConvention(keyFieldValue));
- assertEquals(fieldName.substring(0, fieldName.length() - 4).toLowerCase(), keyFieldValue);
-
- try {
- String keySCFieldValue = (String) confClass.getField(fieldName + "_SNAKE_CASE").get(null);
- assertEquals(keyFieldValue, keySCFieldValue);
- } catch (NoSuchFieldException e) {
- fail("Missing ..._SNAKE_CASE field for " + fieldName);
- }
-
- try {
- String keyCCFieldValue = (String) confClass.getField(fieldName + "_CAMEL_CASE").get(null);
- assertNotEquals(ParsingConfiguration.LEGACY_NAMING_CONVENTION,
- _StringUtil.getIdentifierNamingConvention(keyCCFieldValue));
- assertEquals(keyFieldValue, _StringUtil.camelCaseToUnderscored(keyCCFieldValue));
- } catch (NoSuchFieldException e) {
- fail("Missing ..._CAMEL_CASE field for " + fieldName);
- }
- }
- }
-
- // For each _KEY_SNAKE_CASE field there must be a _KEY field.
- for (Field field : confClass.getFields()) {
- String fieldName = field.getName();
- if (fieldName.endsWith("_KEY_SNAKE_CASE")) {
- try {
- confClass.getField(fieldName.substring(0, fieldName.length() - 11)).get(null);
- } catch (NoSuchFieldException e) {
- fail("Missing ..._KEY field for " + fieldName);
- }
- }
- }
-
- // For each _KEY_CAMEL_CASE field there must be a _KEY field.
- for (Field field : confClass.getFields()) {
- String fieldName = field.getName();
- if (fieldName.endsWith("_KEY_CAMEL_CASE")) {
- try {
- confClass.getField(fieldName.substring(0, fieldName.length() - 11)).get(null);
- } catch (NoSuchFieldException e) {
- fail("Missing ..._KEY field for " + fieldName);
- }
- }
- }
- }
-
- public static void testGetSettingNamesNameConventionsContainTheSame(List<String> namesSCList, List<String> namesCCList) {
- Set<String> namesSC = new HashSet<>(namesSCList);
- assertEquals(namesSCList.size(), namesSC.size());
-
- Set<String> namesCC = new HashSet<>(namesCCList);
- assertEquals(namesCCList.size(), namesCC.size());
-
- assertEquals(namesSC.size(), namesCC.size());
-
- for (String nameCC : namesCC) {
- final String nameSC = _StringUtil.camelCaseToUnderscored(nameCC);
- if (!namesSC.contains(nameSC)) {
- fail("\"" + nameCC + "\" misses corresponding snake case name, \"" + nameSC + "\".");
- }
- }
- }
-
- private MutableProcessingConfiguration createConfigurable() throws IOException {
- return new TemplateConfiguration.Builder();
- }
-
- private boolean keyFieldExists(String name) throws Exception {
- try {
- MutableProcessingConfiguration.class.getField(name.toUpperCase() + "_KEY");
- } catch (NoSuchFieldException e) {
- return false;
- }
- return true;
- }
-
-}
[12/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
deleted file mode 100644
index fe11d1c..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/TypeFlagsTest.java
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.freemarker.core.Configuration;
-
-import junit.framework.TestCase;
-
-public class TypeFlagsTest extends TestCase {
-
- public TypeFlagsTest(String name) {
- super(name);
- }
-
- private final DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- public void testSingleNumType() {
- checkTypeFlags(SingleNumTypeC.class, "mInt",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.INTEGER | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- | TypeFlags.ACCEPTS_STRING);
- checkTypeFlags(SingleNumTypeC.class, "mLong",
- TypeFlags.LONG | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mShort",
- TypeFlags.SHORT | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mByte",
- TypeFlags.BYTE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.ACCEPTS_ANY_OBJECT);
- checkTypeFlags(SingleNumTypeC.class, "mDouble",
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mFloat",
- TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mUnknown",
- TypeFlags.UNKNOWN_NUMERICAL_TYPE | TypeFlags.ACCEPTS_NUMBER);
-
- checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
- TypeFlags.BIG_DECIMAL | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
- TypeFlags.BIG_INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(SingleNumTypeC.class, "mVarParamCnt",
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER);
- }
-
- static public class SingleNumTypeC {
- public void mInt(int a1, String a2) { }
- public void mInt(int a1, int a2) { }
- public void mLong(long a1) { }
- public void mLong(Long a1) { }
- public void mShort(short a1) { }
- public void mByte(byte a1, boolean a2) { }
- public void mByte(byte a1, String a2) { }
- public void mByte(byte a1, Object a2) { }
- public void mDouble(double a1) { }
- public void mFloat(float a1) { }
- public void mUnknown(RationalNumber a1) { };
-
- public void mVarParamCnt(BigDecimal a1) { }
- public void mVarParamCnt(BigInteger a1, Double a2) { }
- public void mVarParamCnt(Double a1, Float a2, Integer a3) { }
- public void mVarParamCnt(Object a1, char a2, boolean a3, File a4, Map a5, Boolean a6) { }
- public void mVarParamCnt(Long a1, int a2, short a3, byte a4, double a5, float a6) { }
- }
-
- public void testMultipleNumTypes() {
- checkTypeFlags(MultiNumTypeC.class, "m1",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.BYTE | TypeFlags.DOUBLE | TypeFlags.INTEGER
- | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(MultiNumTypeC.class, "m2",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.SHORT | TypeFlags.LONG | TypeFlags.FLOAT
- | TypeFlags.ACCEPTS_NUMBER | TypeFlags.CHARACTER
- );
-
- checkTypeFlags(MultiNumTypeC.class, "m3",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.BIG_DECIMAL | TypeFlags.BIG_INTEGER
- | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.BIG_INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.BIG_DECIMAL | TypeFlags.UNKNOWN_NUMERICAL_TYPE
- | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(MultiNumTypeC.class, "m4",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.FLOAT | TypeFlags.ACCEPTS_NUMBER
- | TypeFlags.CHARACTER
- );
-
- checkTypeFlags(MultiNumTypeC.class, "m5",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.FLOAT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(MultiNumTypeC.class, "m6",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
- );
- assertSame(getTypeFlags(MultiNumTypeC.class, "m6", false, 2), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
- assertSame(getTypeFlags(MultiNumTypeC.class, "m6", true, 2), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
- assertSame(getTypeFlags(MultiNumTypeC.class, "m6", false, 3), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
- assertSame(getTypeFlags(MultiNumTypeC.class, "m6", true, 3), OverloadedMethodsSubset.ALL_ZEROS_ARRAY);
- checkTypeFlags(MultiNumTypeC.class, "m6",
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- 0
- );
- }
-
- static public class MultiNumTypeC {
- public void m1(byte a1) { };
- public void m1(int a1) { };
- public void m1(double a2) { };
-
- public void m2(short a1) { };
- public void m2(long a1) { };
- public void m2(float a1) { };
- public void m2(char a1) { };
-
- public void m3(BigInteger a1, BigInteger a2, BigDecimal a3) { };
- public void m3(BigDecimal a1, BigInteger a2, RationalNumber a3) { };
-
- public void m4(float a1) { };
- public void m4(char a1) { };
-
- public void m5(Float a1) { };
- public void m5(Double a1) { };
- public void m5(Enum a1) { };
-
- public void m6(int a1) { };
- public void m6(File a1, Throwable a2) { };
- public void m6(File a1, Throwable a2, StringBuilder a3) { };
- public void m6(File a1, Throwable a2, Throwable a3) { };
- public void m6(double a1, int a2, File a3, File a4) { };
- public void m6(File a1, int a2, double a3, File a4) { };
- }
-
- public void testVarargsNums() {
- checkTypeFlags(VarArgsC.class, "m1",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m2",
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m3",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m3",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.INTEGER
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m3",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.INTEGER
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.INTEGER
- | TypeFlags.BIG_DECIMAL | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m4",
- TypeFlags.INTEGER | TypeFlags.LONG
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m5",
- TypeFlags.LONG | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m6",
- TypeFlags.LONG | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- | TypeFlags.ACCEPTS_STRING
- );
-
- checkTypeFlags(VarArgsC.class, "m7",
- TypeFlags.INTEGER | TypeFlags.BYTE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.FLOAT
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m8",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.FLOAT
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m9",
- TypeFlags.INTEGER | TypeFlags.BYTE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m10",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m10",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.LONG | TypeFlags.DOUBLE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m11",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.SHORT | TypeFlags.ACCEPTS_NUMBER
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m11",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.SHORT
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.LONG | TypeFlags.DOUBLE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m12",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER
- );
- checkTypeFlags(VarArgsC.class, "m12",
- TypeFlags.INTEGER | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.SHORT
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.BYTE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.LONG | TypeFlags.DOUBLE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
-
- checkTypeFlags(VarArgsC.class, "m13",
- TypeFlags.CHARACTER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER);
- checkTypeFlags(VarArgsC.class, "m13",
- TypeFlags.CHARACTER,
- TypeFlags.DOUBLE | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.UNKNOWN_NUMERICAL_TYPE
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER,
- TypeFlags.DOUBLE | TypeFlags.LONG
- | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT | TypeFlags.ACCEPTS_NUMBER
- );
- }
-
- static public class VarArgsC {
- public void m1(int... va) { }
-
- public void m2(double a1, int... va) { }
-
- public void m3(int... va) { }
- public void m3(int a1, double... va) { }
- public void m3(int a1, double a2, BigDecimal... va) { }
-
- public void m4(int... va) { }
- public void m4(long... va) { }
-
- public void m5(Long... va) { }
- public void m5(long... va) { }
-
- public void m6(long... va) { }
- public void m6(String... va) { }
-
- public void m7(int a1, double... va) { }
- public void m7(byte a1, float... va) { }
-
- public void m8(int a1, double... va) { }
- public void m8(int a1, float... va) { }
-
- public void m9(int a1, double... va) { }
- public void m9(byte a1, double... va) { }
-
- public void m10(int a1, double a2, long... va) { }
- public void m10(int a1, double... va) { }
-
- public void m11(int a1, short a2, long... va) { }
- public void m11(int a1, double... va) { }
-
- public void m12(int a1, short a2, byte a3, long... va) { }
- public void m12(int a1, double... va) { }
-
- public void m13(char a1, double a2, RationalNumber a3, Long... va) { }
- public void m13(char a1, Double... va) { }
- }
-
- public void testAllZeros() {
- for (boolean reverse : new boolean[] { true, false }) {
- assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m1", reverse, 0));
- assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m2", reverse, 2));
- assertSame(OverloadedMethodsSubset.ALL_ZEROS_ARRAY, getTypeFlags(AllZeroC.class, "m3", reverse, 1));
- }
- }
-
- static public class AllZeroC {
- public void m1() {}
-
- public void m2(File a1, File a2) {}
-
- public void m3(File a1) {}
- public void m3(StringBuilder a1) {}
- }
-
- public void testAcceptanceNonOverloaded() {
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber1", TypeFlags.ACCEPTS_NUMBER | TypeFlags.UNKNOWN_NUMERICAL_TYPE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber2", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BYTE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber3", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BYTE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber4", TypeFlags.ACCEPTS_NUMBER | TypeFlags.SHORT);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber5", TypeFlags.ACCEPTS_NUMBER | TypeFlags.SHORT);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber6", TypeFlags.ACCEPTS_NUMBER | TypeFlags.INTEGER);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber7", TypeFlags.ACCEPTS_NUMBER | TypeFlags.INTEGER);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber8", TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber9", TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber10", TypeFlags.ACCEPTS_NUMBER | TypeFlags.FLOAT);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber11", TypeFlags.ACCEPTS_NUMBER | TypeFlags.FLOAT);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber12", TypeFlags.ACCEPTS_NUMBER | TypeFlags.DOUBLE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber13", TypeFlags.ACCEPTS_NUMBER | TypeFlags.DOUBLE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber14", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BIG_INTEGER);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber15", TypeFlags.ACCEPTS_NUMBER | TypeFlags.BIG_DECIMAL);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mNumber16", TypeFlags.ACCEPTS_NUMBER | TypeFlags.UNKNOWN_NUMERICAL_TYPE);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mDate", TypeFlags.ACCEPTS_DATE);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mSQLDate1", 0);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mSQLDate2", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mString", TypeFlags.ACCEPTS_STRING);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mCharSequence", TypeFlags.ACCEPTS_STRING);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mStringBuilder", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mBool", TypeFlags.ACCEPTS_BOOLEAN);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mBoolean", TypeFlags.ACCEPTS_BOOLEAN);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mMap1", TypeFlags.ACCEPTS_MAP);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mMap2", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mList1", TypeFlags.ACCEPTS_LIST);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mList2", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mSet1", TypeFlags.ACCEPTS_SET);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mSet2", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mCollection", TypeFlags.ACCEPTS_SET | TypeFlags.ACCEPTS_LIST);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mChar1", TypeFlags.CHARACTER);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mChar2", TypeFlags.CHARACTER);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray1", TypeFlags.ACCEPTS_ARRAY);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray2", TypeFlags.ACCEPTS_ARRAY);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray3", TypeFlags.ACCEPTS_ARRAY);
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mArray4", TypeFlags.ACCEPTS_ARRAY);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mObject", TypeFlags.ACCEPTS_ANY_OBJECT);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_NUMBER) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_STRING) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_BOOLEAN) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_MAP) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_LIST) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_SET) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.ACCEPTS_ARRAY) != 0);
- assertTrue((TypeFlags.ACCEPTS_ANY_OBJECT & TypeFlags.CHARACTER) == 0); // deliberatly 0
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mMapDate", 0);
-
- checkTypeFlags(AcceptanceNonoverloadedC.class, "mDateBooleanList",
- TypeFlags.ACCEPTS_DATE, TypeFlags.ACCEPTS_BOOLEAN, TypeFlags.ACCEPTS_LIST);
- }
-
- static public class AcceptanceNonoverloadedC {
- public void mNumber1(Number a1) {}
- public void mNumber2(Byte a1) {}
- public void mNumber3(byte a1) {}
- public void mNumber4(Short a1) {}
- public void mNumber5(short a1) {}
- public void mNumber6(Integer a1) {}
- public void mNumber7(int a1) {}
- public void mNumber8(Long a1) {}
- public void mNumber9(long a1) {}
- public void mNumber10(Float a1) {}
- public void mNumber11(float a1) {}
- public void mNumber12(Double a1) {}
- public void mNumber13(double a1) {}
- public void mNumber14(BigInteger a1) {}
- public void mNumber15(BigDecimal a1) {}
- public void mNumber16(RationalNumber a1) {}
-
- public void mDate(Date a1) {}
- public void mSQLDate1(java.sql.Date a1) {}
- public void mSQLDate2(java.sql.Timestamp a1) {}
-
- public void mString(String a1) {}
- public void mCharSequence(CharSequence a1) {}
- public void mStringBuilder(StringBuilder a1) {}
-
- public void mBool(boolean a1) {}
- public void mBoolean(Boolean a1) {}
-
- public void mMap1(Map a1) {}
- public void mMap2(LinkedHashMap a1) {}
-
- public void mList1(List a1) {}
- public void mList2(ArrayList a1) {}
-
- public void mSet1(Set a1) {}
- public void mSet2(HashSet a1) {}
-
- public void mCollection(Collection a1) {}
-
- public void mMapDate(MapDate a1) {}
-
- public void mChar1(Character a1) {}
- public void mChar2(char a1) {}
-
- public void mArray1(Object[] a1) {}
- public void mArray2(int[] a1) {}
- public void mArray3(Integer[] a1) {}
- public void mArray4(Void[] a1) {}
-
- public void mObject(Object a1) {}
-
- public void mDateBooleanList(Date a1, boolean a2, List a3) {}
- }
-
- public void testAcceptanceOverloaded() {
- checkTypeFlags(AcceptanceOverloadedC.class, "mLongDateList",
- TypeFlags.ACCEPTS_NUMBER | TypeFlags.LONG | TypeFlags.WIDENED_NUMERICAL_UNWRAPPING_HINT
- | TypeFlags.ACCEPTS_DATE | TypeFlags.ACCEPTS_LIST);
- checkTypeFlags(AcceptanceOverloadedC.class, "mBoolean", TypeFlags.ACCEPTS_BOOLEAN);
- checkTypeFlags(AcceptanceOverloadedC.class, "mStringChar",
- TypeFlags.ACCEPTS_STRING | TypeFlags.CHARACTER);
- checkTypeFlags(AcceptanceOverloadedC.class, "mStringFile", TypeFlags.ACCEPTS_STRING);
- checkTypeFlags(AcceptanceOverloadedC.class, "mMapObject", TypeFlags.ACCEPTS_ANY_OBJECT);
- checkTypeFlags(AcceptanceOverloadedC.class, "mSetMap", TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_SET);
- checkTypeFlags(AcceptanceOverloadedC.class, "mCollectionMap",
- TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_SET | TypeFlags.ACCEPTS_LIST);
- checkTypeFlags(AcceptanceOverloadedC.class, "mArray", TypeFlags.ACCEPTS_ARRAY);
- checkTypeFlags(AcceptanceOverloadedC.class, "mArrayList", TypeFlags.ACCEPTS_ARRAY | TypeFlags.ACCEPTS_LIST);
-
- checkTypeFlags(AcceptanceOverloadedC.class, "mStringCollectionThenBooleanThenMapList",
- TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_LIST | TypeFlags.ACCEPTS_SET,
- TypeFlags.ACCEPTS_BOOLEAN,
- TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_LIST);
- }
-
- static public class AcceptanceOverloadedC {
- public void mLongDateList(long a1) {}
- public void mLongDateList(Date a1) {}
- public void mLongDateList(List a1) {}
-
- public void mBoolean(boolean a1) {}
- public void mBoolean(Boolean a1) {}
-
- public void mDate(Date a1) {}
- public void mDate(java.sql.Date a1) {}
- public void mDate(java.sql.Timestamp a1) {}
-
- public void mStringChar(String a1) {}
- public void mStringChar(char a1) {}
- public void mStringChar(Character a1) {}
-
- public void mStringFile(String a1) {}
- public void mStringFile(File a1) {}
-
- public void mMapObject(Map a1) {}
- public void mMapObject(Object a1) {}
-
- public void mSetMap(Set a1) {}
- public void mSetMap(Map a1) {}
-
- public void mCollectionMap(Collection a1) {}
- public void mCollectionMap(Map a1) {}
-
- public void mArray(Object[] a1) {}
- public void mArray(int[] a1) {}
- public void mArray(Integer[] a1) {}
- public void mArray(Void[] a1) {}
-
- public void mArrayList(String[] a1) {}
- public void mArrayList(List a1) {}
-
- public void mStringCollectionThenBooleanThenMapList(String a1, boolean a2, Map a3) {}
- public void mStringCollectionThenBooleanThenMapList(Collection a1, boolean a2, Map a3) {}
- public void mStringCollectionThenBooleanThenMapList(String a1, boolean a2, List a3) {}
- }
-
- public void testAcceptanceVarargsC() {
- checkTypeFlags(AcceptanceVarArgsC.class, "m1",
- TypeFlags.ACCEPTS_LIST | TypeFlags.ACCEPTS_STRING);
-
- checkTypeFlags(AcceptanceVarArgsC.class, "m2",
- TypeFlags.ACCEPTS_MAP,
- TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_BOOLEAN,
- TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING);
- checkTypeFlags(AcceptanceVarArgsC.class, "m2",
- TypeFlags.ACCEPTS_MAP,
- TypeFlags.ACCEPTS_MAP | TypeFlags.ACCEPTS_STRING | TypeFlags.ACCEPTS_BOOLEAN);
- checkTypeFlags(AcceptanceVarArgsC.class, "m2",
- TypeFlags.ACCEPTS_MAP);
-
- checkTypeFlags(AcceptanceVarArgsC.class, "m3",
- TypeFlags.ACCEPTS_BOOLEAN);
- checkTypeFlags(AcceptanceVarArgsC.class, "m3",
- TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.ACCEPTS_STRING,
- TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.ACCEPTS_MAP,
- TypeFlags.ACCEPTS_BOOLEAN | TypeFlags.CHARACTER,
- TypeFlags.ACCEPTS_BOOLEAN);
- }
-
- static public class AcceptanceVarArgsC {
- public void m1(List... a1) {}
- public void m1(String... a1) {}
-
- public void m2(Map a1, String... a2) {}
- public void m2(Map a1, boolean a2, String... a3) {}
- public void m2(Map... a1) {}
-
- public void m3(String a1, Map a2, char a3, Boolean... a4) {}
- public void m3(boolean... a1) {}
- }
-
- static public class MapDate extends Date implements Map {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public boolean containsKey(Object key) {
- return false;
- }
-
- @Override
- public boolean containsValue(Object value) {
- return false;
- }
-
- @Override
- public Object get(Object key) {
- return null;
- }
-
- @Override
- public Object put(Object key, Object value) {
- return null;
- }
-
- @Override
- public Object remove(Object key) {
- return null;
- }
-
- @Override
- public void putAll(Map m) {
- }
-
- @Override
- public void clear() {
- }
-
- @Override
- public Set keySet() {
- return null;
- }
-
- @Override
- public Collection values() {
- return null;
- }
-
- @Override
- public Set entrySet() {
- return null;
- }
-
- }
-
- private OverloadedMethodsSubset newOverloadedMethodsSubset(Class cl, String methodName, final boolean desc) {
- final Method[] ms = cl.getMethods();
-
- final List<Method> filteredMethods = new ArrayList();
- for (Method m : ms) {
- if (m.getName().equals(methodName)) {
- filteredMethods.add(m);
- }
- }
- // As the order in which getMethods() returns the methods is undefined, we sort them for test predictability:
- Collections.sort(filteredMethods, new Comparator<Method>() {
- @Override
- public int compare(Method o1, Method o2) {
- int res = o1.toString().compareTo(o2.toString());
- return desc ? -res : res;
- }
- });
-
- final OverloadedMethodsSubset oms = cl.getName().indexOf("VarArgs") == -1
- ? new OverloadedFixArgsMethods() : new OverloadedVarArgsMethods();
- for (Method m : filteredMethods) {
- oms.addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(m, m.getParameterTypes()));
- }
- return oms;
- }
-
- private void checkTypeFlags(Class cl, String methodName, int... expectedTypeFlags) {
- checkTypeFlags(cl, methodName, false, expectedTypeFlags);
- checkTypeFlags(cl, methodName, true, expectedTypeFlags);
- }
-
- private void checkTypeFlags(Class cl, String methodName, boolean revMetOrder, int... expectedTypeFlags) {
- int[] actualParamTypes = getTypeFlags(cl, methodName, revMetOrder, expectedTypeFlags.length);
- assertNotNull("Method " + methodName + "(#" + expectedTypeFlags.length + ") doesn't exist", actualParamTypes);
- if (actualParamTypes != OverloadedMethodsSubset.ALL_ZEROS_ARRAY) {
- assertEquals(expectedTypeFlags.length, actualParamTypes.length);
- for (int i = 0; i < expectedTypeFlags.length; i++) {
- assertEquals(expectedTypeFlags[i], actualParamTypes[i]);
- }
- } else {
- for (int expectedTypeFlag : expectedTypeFlags) {
- assertEquals(expectedTypeFlag, 0);
- }
- }
- }
-
- private int[] getTypeFlags(Class cl, String methodName, boolean revMetOrder, int paramCnt) {
- OverloadedMethodsSubset oms = newOverloadedMethodsSubset(cl, methodName, revMetOrder);
- int[] actualParamTypes = oms.getTypeFlags(paramCnt);
- return actualParamTypes;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java b/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
deleted file mode 100644
index 0a479aa..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/_OutputFormatTestAPI.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.core.outputformat;
-
-public final class _OutputFormatTestAPI {
-
- private _OutputFormatTestAPI() {
- //
- }
-
- public static String getMarkupContent(CommonTemplateMarkupOutputModel<?> tm) {
- return tm.getMarkupContent();
- }
-
- public static String getPlainTextContent(CommonTemplateMarkupOutputModel<?> tm) {
- return tm.getPlainTextContent();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
deleted file mode 100644
index 19e45de..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormatTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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.core.outputformat.impl;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
-import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
-import org.junit.Test;
-
-public class CombinedMarkupOutputFormatTest {
-
- private static final CombinedMarkupOutputFormat HTML_RTF = new CombinedMarkupOutputFormat(
- HTMLOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE);
- private static final CombinedMarkupOutputFormat XML_XML = new CombinedMarkupOutputFormat(
- XMLOutputFormat.INSTANCE, XMLOutputFormat.INSTANCE);
-
- @Test
- public void testName() {
- assertEquals("HTML{RTF}", HTML_RTF.getName());
- assertEquals("XML{XML}", XML_XML.getName());
- }
-
- @Test
- public void testOutputMO() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- HTML_RTF.output(HTML_RTF.fromMarkup("<pre>\\par Test "), out);
- HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("foo { bar } \\ "), out);
- HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("& baaz "), out);
- HTML_RTF.output(HTML_RTF.fromPlainTextByEscaping("\\par & qwe"), out);
- HTML_RTF.output(HTML_RTF.fromMarkup("\\par{0} End</pre>"), out);
-
- assertEquals(
- "<pre>\\par Test "
- + "foo \\{ bar \\} \\\\ "
- + "& baaz "
- + "\\\\par & qwe"
- + "\\par{0} End</pre>",
- out.toString());
- }
-
- @Test
- public void testOutputMO2() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- XML_XML.output(XML_XML.fromMarkup("<pre><p> Test "), out);
- XML_XML.output(XML_XML.fromPlainTextByEscaping("a & b < c"), out);
- XML_XML.output(XML_XML.fromMarkup(" End</pre>"), out);
-
- assertEquals(
- "<pre><p> Test "
- + "a &amp; b &lt; c"
- + " End</pre>",
- out.toString());
- }
-
- @Test
- public void testOutputMO3() throws TemplateModelException, IOException {
- MarkupOutputFormat outputFormat = new CombinedMarkupOutputFormat(
- RTFOutputFormat.INSTANCE,
- new CombinedMarkupOutputFormat(RTFOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE));
- StringWriter out = new StringWriter();
-
- outputFormat.output(outputFormat.fromPlainTextByEscaping("b{}"), out);
- outputFormat.output(outputFormat.fromMarkup("a{}"), out);
-
- assertEquals(
- "b\\\\\\\\\\\\\\{\\\\\\\\\\\\\\}"
- + "a{}",
- out.toString());
- }
-
- @Test
- public void testOutputString() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- HTML_RTF.output("a", out);
- HTML_RTF.output("{", out);
- HTML_RTF.output("<b>}c", out);
-
- assertEquals("a\\{<b>\\}c", out.toString());
- }
-
- @Test
- public void testOutputString2() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- XML_XML.output("a", out);
- XML_XML.output("&", out);
- XML_XML.output("<b>", out);
-
- assertEquals("a&amp;&lt;b&gt;", out.toString());
- }
-
- @Test
- public void testFromPlainTextByEscaping() throws TemplateModelException {
- String plainText = "a\\b&c";
- TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromPlainTextByEscaping(plainText);
- assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testFromMarkup() throws TemplateModelException {
- String markup = "a \\par <b>";
- TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromMarkup(markup);
- assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
- assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testGetMarkup() throws TemplateModelException {
- {
- String markup = "a \\par <b>";
- TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromMarkup(markup);
- assertSame(markup, HTML_RTF.getMarkupString(mo));
- }
-
- {
- String safe = "abc";
- TemplateCombinedMarkupOutputModel mo = HTML_RTF.fromPlainTextByEscaping(safe);
- assertSame(safe, HTML_RTF.getMarkupString(mo));
- }
- }
-
- @Test
- public void testConcat() throws Exception {
- assertMO(
- "ab", null,
- HTML_RTF.concat(
- new TemplateCombinedMarkupOutputModel("a", null, HTML_RTF),
- new TemplateCombinedMarkupOutputModel("b", null, HTML_RTF)));
- assertMO(
- null, "ab",
- HTML_RTF.concat(
- new TemplateCombinedMarkupOutputModel(null, "a", HTML_RTF),
- new TemplateCombinedMarkupOutputModel(null, "b", HTML_RTF)));
- assertMO(
- null, "{<a>}\\{<b>\\}",
- HTML_RTF.concat(
- new TemplateCombinedMarkupOutputModel(null, "{<a>}", HTML_RTF),
- new TemplateCombinedMarkupOutputModel("{<b>}", null, HTML_RTF)));
- assertMO(
- null, "\\{<a>\\}{<b>}",
- HTML_RTF.concat(
- new TemplateCombinedMarkupOutputModel("{<a>}", null, HTML_RTF),
- new TemplateCombinedMarkupOutputModel(null, "{<b>}", HTML_RTF)));
- }
-
- @Test
- public void testEscaplePlainText() throws TemplateModelException {
- assertEquals("", HTML_RTF.escapePlainText(""));
- assertEquals("a", HTML_RTF.escapePlainText("a"));
- assertEquals("\\{a\\\\b&\\}", HTML_RTF.escapePlainText("{a\\b&}"));
- assertEquals("a\\\\b&", HTML_RTF.escapePlainText("a\\b&"));
- assertEquals("\\{\\}&", HTML_RTF.escapePlainText("{}&"));
-
- assertEquals("a", XML_XML.escapePlainText("a"));
- assertEquals("a&apos;b", XML_XML.escapePlainText("a'b"));
- }
-
- private void assertMO(String pc, String mc, TemplateCombinedMarkupOutputModel mo) {
- assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
- }
-
- @Test
- public void testGetMimeType() {
- assertEquals("text/html", HTML_RTF.getMimeType());
- assertEquals("application/xml", XML_XML.getMimeType());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
deleted file mode 100644
index 2199179..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/HTMLOutputFormatTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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.core.outputformat.impl;
-
-import static org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
-import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
-import org.junit.Test;
-
-/**
- * This actually more a {@link CommonMarkupOutputFormat} test.
- */
-public class HTMLOutputFormatTest {
-
- @Test
- public void testOutputMO() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- INSTANCE.output(INSTANCE.fromMarkup("<p>Test "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("foo & bar "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("baaz "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("<b>A</b> <b>B</b> <b>C</b>"), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping(""), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("\"' x's \"y\" \""), out);
- INSTANCE.output(INSTANCE.fromMarkup("</p>"), out);
-
- assertEquals(
- "<p>Test "
- + "foo & bar "
- + "baaz "
- + "<b>A</b> <b>B</b> <b>C</b>"
- + ""' x's "y" ""
- + "</p>",
- out.toString());
- }
-
- @Test
- public void testOutputString() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- INSTANCE.output("a", out);
- INSTANCE.output("<", out);
- INSTANCE.output("b'c", out);
-
- assertEquals("a<b'c", out.toString());
- }
-
- @Test
- public void testFromPlainTextByEscaping() throws TemplateModelException {
- String plainText = "a&b";
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(plainText);
- assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testFromMarkup() throws TemplateModelException {
- String markup = "a&b";
- TemplateHTMLOutputModel mo = INSTANCE.fromMarkup(markup);
- assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
- assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testGetMarkup() throws TemplateModelException {
- {
- String markup = "a&b";
- TemplateHTMLOutputModel mo = INSTANCE.fromMarkup(markup);
- assertSame(markup, INSTANCE.getMarkupString(mo));
- }
-
- {
- String safe = "abc";
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
- assertSame(safe, INSTANCE.getMarkupString(mo));
- }
- {
- String safe = "";
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
- assertSame(safe, INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<abc");
- assertEquals("<abc", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("abc>");
- assertEquals("abc>", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<abc>");
- assertEquals("<abc>", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a&bc");
- assertEquals("a&bc", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a&b&c");
- assertEquals("a&b&c", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("a<&>b&c");
- assertEquals("a<&>b&c", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("\"<a<&>b&c>\"");
- assertEquals(""<a<&>b&c>"", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("<");
- assertEquals("<", INSTANCE.getMarkupString(mo));
- }
- {
- TemplateHTMLOutputModel mo = INSTANCE.fromPlainTextByEscaping("'");
- String mc = INSTANCE.getMarkupString(mo);
- assertEquals("'", mc);
- assertSame(mc, INSTANCE.getMarkupString(mo)); // cached
- }
- }
-
- @Test
- public void testConcat() throws Exception {
- assertMO(
- "ab", null,
- INSTANCE.concat(new TemplateHTMLOutputModel("a", null), new TemplateHTMLOutputModel("b", null)));
- assertMO(
- null, "ab",
- INSTANCE.concat(new TemplateHTMLOutputModel(null, "a"), new TemplateHTMLOutputModel(null, "b")));
- assertMO(
- null, "<a><b>",
- INSTANCE.concat(new TemplateHTMLOutputModel(null, "<a>"), new TemplateHTMLOutputModel("<b>", null)));
- assertMO(
- null, "<a><b>",
- INSTANCE.concat(new TemplateHTMLOutputModel("<a>", null), new TemplateHTMLOutputModel(null, "<b>")));
- }
-
- @Test
- public void testEscaplePlainText() {
- assertEquals("", INSTANCE.escapePlainText(""));
- assertEquals("a", INSTANCE.escapePlainText("a"));
- assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
- assertEquals("a&b", INSTANCE.escapePlainText("a&b"));
- assertEquals("<>", INSTANCE.escapePlainText("<>"));
- }
-
- @Test
- public void testIsEmpty() throws Exception {
- assertTrue(INSTANCE.isEmpty(INSTANCE.fromMarkup("")));
- assertTrue(INSTANCE.isEmpty(INSTANCE.fromPlainTextByEscaping("")));
- assertFalse(INSTANCE.isEmpty(INSTANCE.fromMarkup(" ")));
- assertFalse(INSTANCE.isEmpty(INSTANCE.fromPlainTextByEscaping(" ")));
- }
-
- private void assertMO(String pc, String mc, TemplateHTMLOutputModel mo) {
- assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
- }
-
- @Test
- public void testGetMimeType() {
- assertEquals("text/html", INSTANCE.getMimeType());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
deleted file mode 100644
index 13563f5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/outputformat/impl/RTFOutputFormatTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.core.outputformat.impl;
-
-import static org.apache.freemarker.core.outputformat.impl.RTFOutputFormat.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.outputformat._OutputFormatTestAPI;
-import org.junit.Test;
-
-public class RTFOutputFormatTest {
-
- @Test
- public void testOutputMO() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- INSTANCE.output(INSTANCE.fromMarkup("\\par Test "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("foo { bar } \\ "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("baaz "), out);
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("\\par qweqwe"), out);
- INSTANCE.output(INSTANCE.fromMarkup("\\par{0} End"), out);
-
- assertEquals(
- "\\par Test "
- + "foo \\{ bar \\} \\\\ "
- + "baaz "
- + "\\\\par qweqwe"
- + "\\par{0} End",
- out.toString());
- }
-
- @Test
- public void testOutputString() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
-
- INSTANCE.output("a", out);
- INSTANCE.output("{", out);
- INSTANCE.output("b}c", out);
-
- assertEquals("a\\{b\\}c", out.toString());
- }
-
- @Test
- public void testFromPlainTextByEscaping() throws TemplateModelException {
- String plainText = "a\\b";
- TemplateRTFOutputModel mo = INSTANCE.fromPlainTextByEscaping(plainText);
- assertSame(plainText, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertNull(_OutputFormatTestAPI.getMarkupContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testFromMarkup() throws TemplateModelException {
- String markup = "a \\par b";
- TemplateRTFOutputModel mo = INSTANCE.fromMarkup(markup);
- assertSame(markup, _OutputFormatTestAPI.getMarkupContent(mo));
- assertNull(_OutputFormatTestAPI.getPlainTextContent(mo)); // Not the MO's duty to calculate it!
- }
-
- @Test
- public void testGetMarkup() throws TemplateModelException {
- {
- String markup = "a \\par b";
- TemplateRTFOutputModel mo = INSTANCE.fromMarkup(markup);
- assertSame(markup, INSTANCE.getMarkupString(mo));
- }
-
- {
- String safe = "abc";
- TemplateRTFOutputModel mo = INSTANCE.fromPlainTextByEscaping(safe);
- assertSame(safe, INSTANCE.getMarkupString(mo));
- }
- }
-
- @Test
- public void testConcat() throws Exception {
- assertMO(
- "ab", null,
- INSTANCE.concat(new TemplateRTFOutputModel("a", null), new TemplateRTFOutputModel("b", null)));
- assertMO(
- null, "ab",
- INSTANCE.concat(new TemplateRTFOutputModel(null, "a"), new TemplateRTFOutputModel(null, "b")));
- assertMO(
- null, "{a}\\{b\\}",
- INSTANCE.concat(new TemplateRTFOutputModel(null, "{a}"), new TemplateRTFOutputModel("{b}", null)));
- assertMO(
- null, "\\{a\\}{b}",
- INSTANCE.concat(new TemplateRTFOutputModel("{a}", null), new TemplateRTFOutputModel(null, "{b}")));
- }
-
- @Test
- public void testEscaplePlainText() {
- assertEquals("", INSTANCE.escapePlainText(""));
- assertEquals("a", INSTANCE.escapePlainText("a"));
- assertEquals("\\{a\\\\b\\}", INSTANCE.escapePlainText("{a\\b}"));
- assertEquals("a\\\\b", INSTANCE.escapePlainText("a\\b"));
- assertEquals("\\{\\}", INSTANCE.escapePlainText("{}"));
- }
-
- private void assertMO(String pc, String mc, TemplateRTFOutputModel mo) {
- assertEquals(pc, _OutputFormatTestAPI.getPlainTextContent(mo));
- assertEquals(mc, _OutputFormatTestAPI.getMarkupContent(mo));
- }
-
- @Test
- public void testGetMimeType() {
- assertEquals("application/rtf", INSTANCE.getMimeType());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
deleted file mode 100644
index a7063fd..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
-import org.apache.freemarker.test.MonitoredTemplateLoader;
-import org.apache.freemarker.test.MonitoredTemplateLoader.CloseSessionEvent;
-import org.apache.freemarker.test.MonitoredTemplateLoader.CreateSessionEvent;
-import org.apache.freemarker.test.MonitoredTemplateLoader.LoadEvent;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class DefaultTemplateResolverTest {
-
- @Test
- public void testCachedException() throws Exception {
- MockTemplateLoader loader = new MockTemplateLoader();
- DefaultTemplateResolver tr = new DefaultTemplateResolver(
- loader,
- new StrongCacheStorage(), 1000L,
- DefaultTemplateLookupStrategy.INSTANCE, true,
- DefaultTemplateNameFormat.INSTANCE,
- null,
- new TestConfigurationBuilder().build());
- loader.setThrowException(true);
- try {
- tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
- fail();
- } catch (IOException e) {
- assertEquals("mock IO exception", e.getMessage());
- assertEquals(1, loader.getLoadAttemptCount());
- try {
- tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
- fail();
- } catch (IOException e2) {
- // Still 1 - returned cached exception
- assertThat(e2.getMessage(),
- Matchers.allOf(Matchers.containsString("There was an error loading the template on an " +
- "earlier attempt")));
- assertSame(e, e2.getCause());
- assertEquals(1, loader.getLoadAttemptCount());
- try {
- Thread.sleep(1100L);
- tr.getTemplate("t", Locale.getDefault(), null).getTemplate();
- fail();
- } catch (IOException e3) {
- // Cache had to retest
- assertEquals("mock IO exception", e.getMessage());
- assertEquals(2, loader.getLoadAttemptCount());
- }
- }
- }
- }
-
- @Test
- public void testCachedNotFound() throws Exception {
- MockTemplateLoader loader = new MockTemplateLoader();
- DefaultTemplateResolver cache = new DefaultTemplateResolver(
- loader,
- new StrongCacheStorage(), 1000L,
- DefaultTemplateLookupStrategy.INSTANCE, false,
- DefaultTemplateNameFormat.INSTANCE,
- null, new TestConfigurationBuilder().build());
- assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
- assertEquals(1, loader.getLoadAttemptCount());
- assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
- // Still 1 - returned cached exception
- assertEquals(1, loader.getLoadAttemptCount());
- Thread.sleep(1100L);
- assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate());
- // Cache had to retest
- assertEquals(2, loader.getLoadAttemptCount());
- }
-
- private static class MockTemplateLoader implements TemplateLoader {
- private boolean throwException;
- private int loadAttemptCount;
-
- public void setThrowException(boolean throwException) {
- this.throwException = throwException;
- }
-
- public int getLoadAttemptCount() {
- return loadAttemptCount;
- }
-
- @Override
- public TemplateLoaderSession createSession() {
- return null;
- }
-
- @Override
- public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom,
- Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException {
- ++loadAttemptCount;
- if (throwException) {
- throw new IOException("mock IO exception");
- }
- return TemplateLoadingResult.NOT_FOUND;
- }
-
- @Override
- public void resetState() {
- //
- }
-
- }
-
- @Test
- public void testManualRemovalPlain() throws Exception {
- StringTemplateLoader loader = new StringTemplateLoader();
- Configuration cfg = new TestConfigurationBuilder()
- .cacheStorage(new StrongCacheStorage())
- .templateLoader(loader)
- .templateUpdateDelayMilliseconds(Long.MAX_VALUE)
- .build();
-
- loader.putTemplate("1.ftl", "1 v1");
- loader.putTemplate("2.ftl", "2 v1");
- assertEquals("1 v1", cfg.getTemplate("1.ftl").toString());
- assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
-
- loader.putTemplate("1.ftl", "1 v2");
- loader.putTemplate("2.ftl", "2 v2");
- assertEquals("1 v1", cfg.getTemplate("1.ftl").toString()); // no change
- assertEquals("2 v1", cfg.getTemplate("2.ftl").toString()); // no change
-
- cfg.removeTemplateFromCache("1.ftl", cfg.getLocale(), null);
- assertEquals("1 v2", cfg.getTemplate("1.ftl").toString()); // changed
- assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
-
- cfg.removeTemplateFromCache("2.ftl", cfg.getLocale(), null);
- assertEquals("1 v2", cfg.getTemplate("1.ftl").toString());
- assertEquals("2 v2", cfg.getTemplate("2.ftl").toString()); // changed
- }
-
- @Test
- public void testManualRemovalI18ed() throws Exception {
- StringTemplateLoader loader = new StringTemplateLoader();
- Configuration cfg = new TestConfigurationBuilder()
- .cacheStorage(new StrongCacheStorage())
- .templateLoader(loader)
- .templateUpdateDelayMilliseconds(Long.MAX_VALUE)
- .build();
-
- loader.putTemplate("1_en_US.ftl", "1_en_US v1");
- loader.putTemplate("1_en.ftl", "1_en v1");
- loader.putTemplate("1.ftl", "1 v1");
-
- assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());
- assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
- assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
-
- loader.putTemplate("1_en_US.ftl", "1_en_US v2");
- loader.putTemplate("1_en.ftl", "1_en v2");
- loader.putTemplate("1.ftl", "1 v2");
- assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());
- assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
- assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
-
- cfg.removeTemplateFromCache("1.ftl", cfg.getLocale(), null);
- assertEquals("1_en_US v2", cfg.getTemplate("1.ftl").toString());
- assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
- assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
- assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.ITALY).toString());
-
- cfg.removeTemplateFromCache("1.ftl", Locale.GERMANY, null);
- assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
- assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
-
- cfg.removeTemplateFromCache("1.ftl", Locale.CANADA, null);
- assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
-
- cfg.removeTemplateFromCache("1.ftl", Locale.UK, null);
- assertEquals("1_en v2", cfg.getTemplate("1.ftl", Locale.UK).toString());
- }
-
- @Test
- public void testZeroUpdateDelay() throws Exception {
- MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
- TestConfigurationBuilder cfgB = new TestConfigurationBuilder()
- .cacheStorage(new StrongCacheStorage())
- .templateLoader(loader)
- .templateUpdateDelayMilliseconds(0);
-
- Configuration cfg = cfgB.build();
-
- for (int i = 1; i <= 3; i++) {
- loader.putTextTemplate("t.ftl", "v" + i);
- assertEquals("v" + i, cfg.getTemplate("t.ftl").toString());
- }
-
- loader.clearEvents();
- loader.putTextTemplate("t.ftl", "v8");
- assertEquals("v8", cfg.getTemplate("t.ftl").toString());
- assertEquals("v8", cfg.getTemplate("t.ftl").toString());
- loader.putTextTemplate("t.ftl", "v9");
- assertEquals("v9", cfg.getTemplate("t.ftl").toString());
- assertEquals("v9", cfg.getTemplate("t.ftl").toString());
- assertEquals(
- ImmutableList.of(
- new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8
- new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED),
-
- new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8
- new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
-
- new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9
- new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED),
-
- new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9
- new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED)
- ),
- loader.getEvents(LoadEvent.class));
-
- cfg = cfgB.localizedLookup(false).build();
- loader.clearEvents();
- loader.putTextTemplate("t.ftl", "v10");
- assertEquals("v10", cfg.getTemplate("t.ftl").toString());
- loader.putTextTemplate("t.ftl", "v11"); // same time stamp, different content
- assertEquals("v11", cfg.getTemplate("t.ftl").toString());
- assertEquals("v11", cfg.getTemplate("t.ftl").toString());
- assertEquals("v11", cfg.getTemplate("t.ftl").toString());
- Thread.sleep(17L);
- assertEquals("v11", cfg.getTemplate("t.ftl").toString());
- loader.putTextTemplate("t.ftl", "v12");
- assertEquals("v12", cfg.getTemplate("t.ftl").toString());
- assertEquals("v12", cfg.getTemplate("t.ftl").toString());
- assertEquals(
- ImmutableList.of(
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v10
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v11
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED),
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v12
- new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED)
- ),
- loader.getEvents(LoadEvent.class));
- }
-
- @Test
- public void testWrongEncodingReload() throws Exception {
- MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
- loader.putBinaryTemplate("utf-8_en.ftl", "<#ftl encoding='utf-8'>Béka");
- loader.putBinaryTemplate("utf-8.ftl", "Bar");
- loader.putBinaryTemplate("iso-8859-1_en_US.ftl", "<#ftl encoding='ISO-8859-1'>Béka",
- StandardCharsets.ISO_8859_1, "v1");
- Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
-
- {
- Template t = cfg.getTemplate("utf-8.ftl");
- assertEquals("utf-8.ftl", t.getLookupName());
- assertEquals("utf-8_en.ftl", t.getSourceName());
- assertEquals(StandardCharsets.UTF_8, t.getActualSourceEncoding());
- assertEquals("Béka", t.toString());
-
- assertEquals(
- ImmutableList.of(
- CreateSessionEvent.INSTANCE,
- new LoadEvent("utf-8_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("utf-8_en.ftl", TemplateLoadingResultStatus.OPENED),
- CloseSessionEvent.INSTANCE),
- loader.getEvents());
- }
-
- {
- loader.clearEvents();
-
- Template t = cfg.getTemplate("iso-8859-1.ftl");
- assertEquals("iso-8859-1.ftl", t.getLookupName());
- assertEquals("iso-8859-1_en_US.ftl", t.getSourceName());
- assertEquals(StandardCharsets.ISO_8859_1, t.getActualSourceEncoding());
- assertEquals("Béka", t.toString());
-
- assertEquals(
- ImmutableList.of(
- CreateSessionEvent.INSTANCE,
- new LoadEvent("iso-8859-1_en_US.ftl", TemplateLoadingResultStatus.OPENED),
- CloseSessionEvent.INSTANCE),
- loader.getEvents());
- }
- }
-
- @Test
- public void testNoWrongEncodingForTemplateLoader2WithReader() throws Exception {
- MonitoredTemplateLoader loader = new MonitoredTemplateLoader();
- loader.putTextTemplate("foo_en.ftl", "<#ftl encoding='utf-8'>ő");
- loader.putTextTemplate("foo.ftl", "B");
- Configuration cfg = new TestConfigurationBuilder().templateLoader(loader).build();
-
- {
- Template t = cfg.getTemplate("foo.ftl");
- assertEquals("foo.ftl", t.getLookupName());
- assertEquals("foo_en.ftl", t.getSourceName());
- assertNull(t.getActualSourceEncoding());
- assertEquals("ő", t.toString());
-
- assertEquals(
- ImmutableList.of(
- CreateSessionEvent.INSTANCE,
- new LoadEvent("foo_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND),
- new LoadEvent("foo_en.ftl", TemplateLoadingResultStatus.OPENED),
- CloseSessionEvent.INSTANCE),
- loader.getEvents());
- }
- }
-
- @Test
- public void testTemplateNameFormatException() throws Exception {
- Configuration cfg = new TestConfigurationBuilder()
- .templateNameFormat(DefaultTemplateNameFormat.INSTANCE)
- .build();
- try {
- cfg.getTemplate("../x");
- fail();
- } catch (MalformedTemplateNameException e) {
- // expected
- }
- try {
- cfg.getTemplate("\\x");
- fail();
- } catch (MalformedTemplateNameException e) {
- // expected
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
deleted file mode 100644
index 393dbae..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/FileTemplateLoaderTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.TemplateNotFoundException;
-import org.apache.freemarker.core.templateresolver.impl.FileTemplateLoader;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.io.Files;
-
-public class FileTemplateLoaderTest {
-
- private File templateRootDir;
-
- private Configuration cfg;
-
- @Before
- public void setup() throws IOException {
- templateRootDir = Files.createTempDir();
- File sub1Dir = new File(templateRootDir, "sub1");
- File sub2Dir = new File(sub1Dir, "sub2");
- if (!sub2Dir.mkdirs()) {
- throw new IOException("Failed to invoke subdirectories");
- }
- File tFile = new File(sub2Dir, "t.ftl");
- FileUtils.write(tFile, "foo");
-
- cfg = new TestConfigurationBuilder().templateLoader(new FileTemplateLoader(templateRootDir)).build();
- }
-
- @Test
- public void testSuccessful() throws Exception {
- for (int i = 0; i < 2; i++) {
- assertEquals("foo", cfg.getTemplate("sub1/sub2/t.ftl").toString());
- }
- }
-
- @Test
- public void testSuccessful2() throws Exception {
- ((FileTemplateLoader) cfg.getTemplateLoader()).setEmulateCaseSensitiveFileSystem(true);
- for (int i = 0; i < 2; i++) {
- cfg.clearTemplateCache();
- assertEquals("foo", cfg.getTemplate("sub1/sub2/t.ftl").toString());
- }
- }
-
-
- @Test
- public void testNotFound() throws Exception {
- for (int i = 0; i < 2; i++) {
- try {
- cfg.getTemplate("sub1X/sub2/t.ftl");
- fail();
- } catch (TemplateNotFoundException e) {
- assertThat(e.getMessage(), containsString("sub1X"));
- assertNull(e.getCause());
- }
- }
- }
-
- @Test
- public void testCaseSensitivity() throws Exception {
- for (boolean emuCaseSensFS : new boolean[] { false, true }) {
- for (String nameWithBadCase : new String[] { "SUB1/sub2/t.ftl", "sub1/SUB2/t.ftl", "sub1/sub2/T.FTL" }) {
- ((FileTemplateLoader) cfg.getTemplateLoader()).setEmulateCaseSensitiveFileSystem(emuCaseSensFS);
- cfg.clearTemplateCache();
-
- if ((SystemUtils.IS_OS_WINDOWS || SystemUtils.IS_OS_MAC_OSX) && !emuCaseSensFS) {
- assertEquals("foo", cfg.getTemplate(nameWithBadCase).toString());
- } else {
- assertEquals("foo", cfg.getTemplate(nameWithBadCase.toLowerCase()).toString());
- try {
- cfg.getTemplate(nameWithBadCase);
- fail();
- } catch (TemplateNotFoundException e) {
- assertThat(e.getMessage(), containsString(nameWithBadCase));
- assertNull(e.getCause());
- }
- }
- }
- }
- }
-
- @Test
- public void testDefault() throws IOException {
- assertFalse(new FileTemplateLoader(templateRootDir).getEmulateCaseSensitiveFileSystem());
- }
-
- @After
- public void tearDown() throws IOException {
- FileUtils.deleteDirectory(templateRootDir);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
deleted file mode 100644
index c8531c5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/templateresolver/MultiTemplateLoaderTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.core.templateresolver;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.junit.Test;
-
-public class MultiTemplateLoaderTest {
-
- @Test
- public void testBasics() throws IOException {
- StringTemplateLoader stl1 = new StringTemplateLoader();
- stl1.putTemplate("1.ftl", "1");
- stl1.putTemplate("both.ftl", "both 1");
-
- StringTemplateLoader stl2 = new StringTemplateLoader();
- stl2.putTemplate("2.ftl", "2");
- stl2.putTemplate("both.ftl", "both 2");
-
- MultiTemplateLoader mtl = new MultiTemplateLoader(stl1, stl2);
- assertEquals("1", getTemplateContent(mtl, "1.ftl"));
- assertEquals("2", getTemplateContent(mtl, "2.ftl"));
- assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
- assertNull(getTemplateContent(mtl, "neither.ftl"));
- }
-
- @Test
- public void testSticky() throws IOException {
- testStickiness(true);
- }
-
- @Test
- public void testNonSticky() throws IOException {
- testStickiness(false);
- }
-
- private void testStickiness(boolean sticky) throws IOException {
- StringTemplateLoader stl1 = new StringTemplateLoader();
- stl1.putTemplate("both.ftl", "both 1");
-
- ByteArrayTemplateLoader stl2 = new ByteArrayTemplateLoader();
- stl2.putTemplate("both.ftl", "both 2".getBytes(StandardCharsets.UTF_8));
-
- MultiTemplateLoader mtl = new MultiTemplateLoader(stl1, stl2);
- mtl.setSticky(sticky);
-
- assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
- assertTrue(stl1.removeTemplate("both.ftl"));
- assertEquals("both 2", getTemplateContent(mtl, "both.ftl"));
- stl1.putTemplate("both.ftl", "both 1");
- assertEquals(sticky ? "both 2" : "both 1", getTemplateContent(mtl, "both.ftl"));
- assertTrue(stl2.removeTemplate("both.ftl"));
- assertEquals("both 1", getTemplateContent(mtl, "both.ftl"));
- }
-
- private String getTemplateContent(TemplateLoader tl, String name) throws IOException {
- TemplateLoaderSession ses = tl.createSession();
- try {
- TemplateLoadingResult res = tl.load(name, null, null, ses);
- if (res.getStatus() == TemplateLoadingResultStatus.NOT_FOUND) {
- return null;
- }
- return IOUtils.toString(
- res.getReader() != null
- ? res.getReader()
- : new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8));
- } finally {
- if (ses != null) {
- ses.close();
- }
- }
- }
-
-}
[39/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
new file mode 100644
index 0000000..37e4726
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/OverloadedNumberUtilTest.java
@@ -0,0 +1,585 @@
+/*
+ * 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.core.model.impl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("boxing")
+public class OverloadedNumberUtilTest extends TestCase {
+
+ public OverloadedNumberUtilTest(String name) {
+ super(name);
+ }
+
+ public void testIntegerCoercions() {
+ cipEqu(Byte.valueOf(Byte.MAX_VALUE));
+ cipEqu(Byte.valueOf((byte) 0));
+ cipEqu(Byte.valueOf(Byte.MIN_VALUE));
+
+ cipEqu(Short.valueOf(Byte.MAX_VALUE),
+ new OverloadedNumberUtil.ShortOrByte((short) Byte.MAX_VALUE, Byte.MAX_VALUE));
+ cipEqu(Short.valueOf((short) 0),
+ new OverloadedNumberUtil.ShortOrByte((short) 0, (byte) 0));
+ cipEqu(Short.valueOf(Byte.MIN_VALUE),
+ new OverloadedNumberUtil.ShortOrByte((short) Byte.MIN_VALUE, Byte.MIN_VALUE));
+
+ cipEqu(Short.valueOf((short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Short.valueOf((short) (Byte.MIN_VALUE - 1)));
+ cipEqu(Short.valueOf(Short.MAX_VALUE));
+ cipEqu(Short.valueOf(Short.MIN_VALUE));
+
+ cipEqu(Integer.valueOf(Byte.MAX_VALUE),
+ new OverloadedNumberUtil.IntegerOrByte((int) Byte.MAX_VALUE, Byte.MAX_VALUE));
+ cipEqu(Integer.valueOf(0),
+ new OverloadedNumberUtil.IntegerOrByte(0, (byte) 0));
+ cipEqu(Integer.valueOf(Byte.MIN_VALUE),
+ new OverloadedNumberUtil.IntegerOrByte((int) Byte.MIN_VALUE, Byte.MIN_VALUE));
+
+ cipEqu(Integer.valueOf(Byte.MAX_VALUE + 1),
+ new OverloadedNumberUtil.IntegerOrShort(Byte.MAX_VALUE + 1, (short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Integer.valueOf(Byte.MIN_VALUE - 1),
+ new OverloadedNumberUtil.IntegerOrShort(Byte.MIN_VALUE - 1, (short) (Byte.MIN_VALUE - 1)));
+ cipEqu(Integer.valueOf(Short.MAX_VALUE),
+ new OverloadedNumberUtil.IntegerOrShort((int) Short.MAX_VALUE, Short.MAX_VALUE));
+ cipEqu(Integer.valueOf(Short.MIN_VALUE),
+ new OverloadedNumberUtil.IntegerOrShort((int) Short.MIN_VALUE, Short.MIN_VALUE));
+
+ cipEqu(Integer.valueOf(Short.MAX_VALUE + 1));
+ cipEqu(Integer.valueOf(Short.MIN_VALUE - 1));
+ cipEqu(Integer.valueOf(Integer.MAX_VALUE));
+ cipEqu(Integer.valueOf(Integer.MIN_VALUE));
+
+ cipEqu(Long.valueOf(Byte.MAX_VALUE),
+ new OverloadedNumberUtil.LongOrByte((long) Byte.MAX_VALUE, Byte.MAX_VALUE));
+ cipEqu(Long.valueOf(0),
+ new OverloadedNumberUtil.LongOrByte((long) 0, (byte) 0));
+ cipEqu(Long.valueOf(Byte.MIN_VALUE),
+ new OverloadedNumberUtil.LongOrByte((long) Byte.MIN_VALUE, Byte.MIN_VALUE));
+
+ cipEqu(Long.valueOf(Byte.MAX_VALUE + 1),
+ new OverloadedNumberUtil.LongOrShort((long) (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Long.valueOf(Byte.MIN_VALUE - 1),
+ new OverloadedNumberUtil.LongOrShort((long) (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
+ cipEqu(Long.valueOf(Short.MAX_VALUE),
+ new OverloadedNumberUtil.LongOrShort((long) Short.MAX_VALUE, Short.MAX_VALUE));
+ cipEqu(Long.valueOf(Short.MIN_VALUE),
+ new OverloadedNumberUtil.LongOrShort((long) Short.MIN_VALUE, Short.MIN_VALUE));
+
+ cipEqu(Long.valueOf(Short.MAX_VALUE + 1),
+ new OverloadedNumberUtil.LongOrInteger((long) Short.MAX_VALUE + 1, Short.MAX_VALUE + 1));
+ cipEqu(Long.valueOf(Short.MIN_VALUE - 1),
+ new OverloadedNumberUtil.LongOrInteger((long) Short.MIN_VALUE - 1, Short.MIN_VALUE - 1));
+ cipEqu(Long.valueOf(Integer.MAX_VALUE),
+ new OverloadedNumberUtil.LongOrInteger((long) Integer.MAX_VALUE, Integer.MAX_VALUE));
+ cipEqu(Long.valueOf(Integer.MIN_VALUE),
+ new OverloadedNumberUtil.LongOrInteger((long) Integer.MIN_VALUE, Integer.MIN_VALUE));
+
+ cipEqu(Long.valueOf(Integer.MAX_VALUE + 1L));
+ cipEqu(Long.valueOf(Integer.MIN_VALUE - 1L));
+ cipEqu(Long.valueOf(Long.MAX_VALUE));
+ cipEqu(Long.valueOf(Long.MIN_VALUE));
+ }
+
+ public void testIntegerNoCoercions() {
+ cipEqu(Integer.valueOf(Byte.MAX_VALUE), Integer.valueOf(Byte.MAX_VALUE), 0);
+ cipEqu(Integer.valueOf(0), Integer.valueOf(0), 0);
+ cipEqu(Integer.valueOf(Byte.MIN_VALUE), Integer.valueOf(Byte.MIN_VALUE), 0);
+ }
+
+ public void testIntegerLimitedCoercions() {
+ cipEqu(Integer.valueOf(Byte.MAX_VALUE), Integer.valueOf(Byte.MAX_VALUE), TypeFlags.INTEGER);
+ cipEqu(Integer.valueOf(0), Integer.valueOf(0), TypeFlags.INTEGER);
+ cipEqu(Integer.valueOf(Byte.MIN_VALUE), Integer.valueOf(Byte.MIN_VALUE), TypeFlags.INTEGER);
+
+ cipEqu(Long.valueOf(Integer.MAX_VALUE + 1L), Long.valueOf(Integer.MAX_VALUE + 1L), TypeFlags.INTEGER);
+
+ for (int n = -1; n < 2; n++) {
+ final Long longN = Long.valueOf(n);
+ cipEqu(longN, new OverloadedNumberUtil.LongOrInteger(longN, n), TypeFlags.INTEGER);
+ cipEqu(longN, new OverloadedNumberUtil.LongOrShort(longN, (short) n), TypeFlags.SHORT);
+ cipEqu(longN, new OverloadedNumberUtil.LongOrByte(longN, (byte) n), TypeFlags.BYTE);
+ cipEqu(longN, new OverloadedNumberUtil.LongOrShort(longN, (short) n),
+ TypeFlags.SHORT | TypeFlags.INTEGER);
+ }
+ }
+
+ public void testBigDecimalCoercions() {
+ cipEqu(new BigDecimal(123), new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal(123)));
+ cipEqu(new BigDecimal(123), new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal(123)),
+ TypeFlags.DOUBLE | TypeFlags.INTEGER);
+ cipEqu(new BigDecimal(123), TypeFlags.INTEGER);
+ cipEqu(new BigDecimal(123), TypeFlags.INTEGER | TypeFlags.LONG);
+ cipEqu(new BigDecimal(123), TypeFlags.DOUBLE);
+ cipEqu(new BigDecimal(123), TypeFlags.DOUBLE | TypeFlags.FLOAT);
+
+ cipEqu(new BigDecimal(123.5));
+ // Not wasting time with check if it's a whole number if we only have integer-only or non-integer-only targets:
+ cipEqu(new BigDecimal(123.5), TypeFlags.INTEGER | TypeFlags.LONG);
+ cipEqu(new BigDecimal(123.5), TypeFlags.DOUBLE | TypeFlags.FLOAT);
+
+ cipEqu(new BigDecimal("0.01"));
+ cipEqu(new BigDecimal("-0.01"));
+ cipEqu(BigDecimal.ZERO, new OverloadedNumberUtil.IntegerBigDecimal(BigDecimal.ZERO));
+ }
+
+ public void testUnknownNumberCoercion() {
+ cipEqu(new RationalNumber(2, 3));
+ }
+
+ @SuppressWarnings("boxing")
+ public void testDoubleCoercion() {
+ cipEqu(Double.valueOf(1.5), new OverloadedNumberUtil.DoubleOrFloat(1.5));
+ cipEqu(Double.valueOf(-0.125), new OverloadedNumberUtil.DoubleOrFloat(-0.125));
+ cipEqu(Double.valueOf(Float.MAX_VALUE), new OverloadedNumberUtil.DoubleOrFloat((double) Float.MAX_VALUE));
+ cipEqu(Double.valueOf(-Float.MAX_VALUE), new OverloadedNumberUtil.DoubleOrFloat((double) -Float.MAX_VALUE));
+ cipEqu(Double.valueOf(Float.MAX_VALUE * 10.0));
+ cipEqu(Double.valueOf(-Float.MAX_VALUE * 10.0));
+
+ cipEqu(Double.valueOf(0), new OverloadedNumberUtil.DoubleOrByte(0.0, (byte) 0));
+ cipEqu(Double.valueOf(Byte.MAX_VALUE), new OverloadedNumberUtil.DoubleOrByte((double) Byte.MAX_VALUE, Byte.MAX_VALUE));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE), new OverloadedNumberUtil.DoubleOrByte((double) Byte.MIN_VALUE, Byte.MIN_VALUE));
+
+ cipEqu(Double.valueOf(Byte.MAX_VALUE + 1), new OverloadedNumberUtil.DoubleOrShort((double)
+ (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE - 1), new OverloadedNumberUtil.DoubleOrShort((double)
+ (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
+
+ cipEqu(Double.valueOf(Short.MAX_VALUE + 1),
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat((double) Short.MAX_VALUE + 1, Short.MAX_VALUE + 1));
+ cipEqu(Double.valueOf(Short.MIN_VALUE - 1),
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat((double) Short.MIN_VALUE - 1, Short.MIN_VALUE - 1));
+ cipEqu(Double.valueOf(16777216), new OverloadedNumberUtil.DoubleOrIntegerOrFloat(16777216.0, 16777216));
+ cipEqu(Double.valueOf(-16777216), new OverloadedNumberUtil.DoubleOrIntegerOrFloat(-16777216.0, -16777216));
+
+ cipEqu(Double.valueOf(Integer.MAX_VALUE),
+ new OverloadedNumberUtil.DoubleOrInteger((double) Integer.MAX_VALUE, Integer.MAX_VALUE));
+ cipEqu(Double.valueOf(Integer.MIN_VALUE),
+ new OverloadedNumberUtil.DoubleOrInteger((double) Integer.MIN_VALUE, Integer.MIN_VALUE));
+
+ cipEqu(Double.valueOf(Integer.MAX_VALUE + 1L),
+ new OverloadedNumberUtil.DoubleOrLong(Double.valueOf(Integer.MAX_VALUE + 1L), Integer.MAX_VALUE + 1L));
+ cipEqu(Double.valueOf(Integer.MIN_VALUE - 1L),
+ new OverloadedNumberUtil.DoubleOrLong(Double.valueOf(Integer.MIN_VALUE - 1L), Integer.MIN_VALUE - 1L));
+ cipEqu(Double.valueOf(Long.MAX_VALUE),
+ new OverloadedNumberUtil.DoubleOrFloat((double) Long.MAX_VALUE));
+ cipEqu(Double.valueOf(Long.MIN_VALUE),
+ new OverloadedNumberUtil.DoubleOrFloat((double) Long.MIN_VALUE));
+
+ // When only certain target types are present:
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrByte(5.0, (byte) 5), TypeFlags.BYTE);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrByte(5.0, (byte) 5), TypeFlags.BYTE | TypeFlags.SHORT);
+ cipEqu(Double.valueOf(-129), TypeFlags.BYTE);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrShort(5.0, (short) 5), TypeFlags.SHORT);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrInteger(5.0, 5), TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrLong(5.0, 5), TypeFlags.LONG);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrFloat(5.0), TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(5), Double.valueOf(5), TypeFlags.DOUBLE);
+ cipEqu(Double.valueOf(5), new OverloadedNumberUtil.DoubleOrFloat(5.0),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(5.9), new OverloadedNumberUtil.DoubleOrFloat(5.9),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(5.9),
+ TypeFlags.DOUBLE | TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(5.9), new OverloadedNumberUtil.DoubleOrFloat(5.9),
+ TypeFlags.FLOAT | TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(5.9), TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(Long.MAX_VALUE),
+ new OverloadedNumberUtil.DoubleOrFloat((double) Long.MAX_VALUE),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(Long.MAX_VALUE),
+ TypeFlags.DOUBLE | TypeFlags.LONG);
+ cipEqu(Double.valueOf(Long.MIN_VALUE),
+ new OverloadedNumberUtil.DoubleOrFloat((double) Long.MIN_VALUE),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(Float.MAX_VALUE * 10),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(Double.valueOf(-Float.MAX_VALUE * 10),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+
+ // Rounded values:
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrByte(0.0000009, (byte) 0));
+ cipEqu(Double.valueOf(-0.0000009),
+ new OverloadedNumberUtil.DoubleOrByte(-0.0000009, (byte) 0));
+ cipEqu(Double.valueOf(0.9999991),
+ new OverloadedNumberUtil.DoubleOrByte(0.9999991, (byte) 1));
+ cipEqu(Double.valueOf(-0.9999991),
+ new OverloadedNumberUtil.DoubleOrByte(-0.9999991, (byte) -1));
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrShort(0.0000009, (short) 0),
+ TypeFlags.SHORT | TypeFlags.DOUBLE);
+ cipEqu(Double.valueOf(0.0000009), new OverloadedNumberUtil.DoubleOrInteger(0.0000009, 0),
+ TypeFlags.INTEGER | TypeFlags.DOUBLE);
+ cipEqu(Double.valueOf(0.0000009), new OverloadedNumberUtil.DoubleOrLong(0.0000009, 0),
+ TypeFlags.LONG | TypeFlags.DOUBLE);
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrByte(0.0000009, (byte) 0), TypeFlags.BYTE);
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrShort(0.0000009, (short) 0), TypeFlags.SHORT);
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrInteger(0.0000009, 0), TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(0.0000009),
+ new OverloadedNumberUtil.DoubleOrLong(0.0000009, 0L), TypeFlags.LONG);
+ cipEqu(Double.valueOf(0.9999999),
+ new OverloadedNumberUtil.DoubleOrInteger(0.9999999, 1), TypeFlags.INTEGER);
+ cipEqu(Double.valueOf(Byte.MAX_VALUE + 0.9e-6),
+ new OverloadedNumberUtil.DoubleOrByte(Byte.MAX_VALUE + 0.9e-6, Byte.MAX_VALUE));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE - 0.9e-6),
+ new OverloadedNumberUtil.DoubleOrByte(Byte.MIN_VALUE - 0.9e-6, Byte.MIN_VALUE));
+ cipEqu(Double.valueOf(Byte.MAX_VALUE + 1.1e-6),
+ new OverloadedNumberUtil.DoubleOrFloat(Byte.MAX_VALUE + 1.1e-6));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE - 1.1e-6),
+ new OverloadedNumberUtil.DoubleOrFloat(Byte.MIN_VALUE - 1.1e-6));
+ cipEqu(Double.valueOf(Byte.MAX_VALUE + 0.9999991),
+ new OverloadedNumberUtil.DoubleOrShort(
+ Byte.MAX_VALUE + 0.9999991, (short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE - 0.9999991),
+ new OverloadedNumberUtil.DoubleOrShort(
+ Byte.MIN_VALUE - 0.9999991, (short) (Byte.MIN_VALUE - 1)));
+
+ cipEqu(Double.valueOf(Byte.MAX_VALUE + 1), new OverloadedNumberUtil.DoubleOrShort((double)
+ (Byte.MAX_VALUE + 1), (short) (Byte.MAX_VALUE + 1)));
+ cipEqu(Double.valueOf(Byte.MIN_VALUE - 1), new OverloadedNumberUtil.DoubleOrShort((double)
+ (Byte.MIN_VALUE - 1), (short) (Byte.MIN_VALUE - 1)));
+
+ cipEqu(Short.MAX_VALUE + 0.9999991,
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat(Short.MAX_VALUE + 0.9999991, Short.MAX_VALUE + 1));
+ cipEqu(Short.MIN_VALUE - 0.9999991,
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat(Short.MIN_VALUE - 0.9999991, Short.MIN_VALUE - 1));
+ cipEqu(16777216 + 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat(16777216 + 0.9e-6, 16777216));
+ cipEqu(-16777216 - 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrIntegerOrFloat(-16777216 - 0.9e-6, -16777216));
+
+ cipEqu(Integer.MAX_VALUE + 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrInteger(Integer.MAX_VALUE + 0.9e-6, Integer.MAX_VALUE));
+ cipEqu(Integer.MIN_VALUE - 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrInteger(Integer.MIN_VALUE - 0.9e-6, Integer.MIN_VALUE));
+
+ cipEqu(Integer.MAX_VALUE + 1L + 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrFloat(Integer.MAX_VALUE + 1L + 0.9e-6));
+ cipEqu(Integer.MIN_VALUE - 1L - 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrFloat(Integer.MIN_VALUE - 1L - 0.9e-6));
+ cipEqu(Long.MAX_VALUE + 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrFloat(Long.MAX_VALUE + 0.9e-6));
+ cipEqu(Long.MIN_VALUE - 0.9e-6,
+ new OverloadedNumberUtil.DoubleOrFloat(Long.MIN_VALUE - 0.9e-6));
+ }
+
+ @SuppressWarnings("boxing")
+ public void testFloatCoercion() {
+ cipEqu(1.00002f);
+ cipEqu(-1.00002f);
+ cipEqu(1.999989f);
+ cipEqu(-1.999989f);
+ cipEqu(16777218f);
+ cipEqu(-16777218f);
+
+ cipEqu(1f, new OverloadedNumberUtil.FloatOrByte(1f, (byte) 1));
+ cipEqu(-1f, new OverloadedNumberUtil.FloatOrByte(-1f, (byte) -1));
+ cipEqu(1.000009f, new OverloadedNumberUtil.FloatOrByte(1.000009f, (byte) 1));
+ cipEqu(-1.000009f, new OverloadedNumberUtil.FloatOrByte(-1.000009f, (byte) -1));
+ cipEqu(1.999991f, new OverloadedNumberUtil.FloatOrByte(1.999991f, (byte) 2));
+ cipEqu(-1.999991f, new OverloadedNumberUtil.FloatOrByte(-1.999991f, (byte) -2));
+
+ cipEqu(1000f, new OverloadedNumberUtil.FloatOrShort(1000f, (short) 1000));
+ cipEqu(-1000f, new OverloadedNumberUtil.FloatOrShort(-1000f, (short) -1000));
+ cipEqu(1000.00006f);
+
+ cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000));
+ cipEqu(-60000f, new OverloadedNumberUtil.FloatOrInteger(-60000f, -60000));
+ cipEqu(60000.004f);
+
+ cipEqu(100f, new OverloadedNumberUtil.FloatOrByte(100f, (byte) 100), TypeFlags.MASK_KNOWN_INTEGERS);
+ cipEqu(1000f, new OverloadedNumberUtil.FloatOrShort(1000f, (short) 1000), TypeFlags.MASK_KNOWN_INTEGERS);
+ cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000), TypeFlags.MASK_KNOWN_INTEGERS);
+ cipEqu(60000f, new OverloadedNumberUtil.FloatOrInteger(60000f, 60000), TypeFlags.LONG);
+ cipEqu((float) Integer.MAX_VALUE, (float) Integer.MAX_VALUE, TypeFlags.LONG);
+ cipEqu((float) -Integer.MAX_VALUE, (float) -Integer.MAX_VALUE);
+
+ cipEqu(0.5f, 0.5f, TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(0.5f, 0.5f, TypeFlags.DOUBLE);
+ }
+
+ public void testBigIntegerCoercion() {
+ BigInteger bi;
+
+ cipEqu(BigInteger.ZERO, new OverloadedNumberUtil.BigIntegerOrByte(BigInteger.ZERO));
+ bi = new BigInteger(String.valueOf(Byte.MAX_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrByte(bi));
+ bi = new BigInteger(String.valueOf(Byte.MIN_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrByte(bi));
+
+ bi = new BigInteger(String.valueOf(Byte.MAX_VALUE + 1));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
+ bi = new BigInteger(String.valueOf(Byte.MIN_VALUE - 1));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
+ bi = new BigInteger(String.valueOf(Short.MAX_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
+ bi = new BigInteger(String.valueOf(Short.MIN_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrShort(bi));
+
+ bi = new BigInteger(String.valueOf(Short.MAX_VALUE + 1));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
+ bi = new BigInteger(String.valueOf(Short.MIN_VALUE - 1));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
+ bi = new BigInteger(String.valueOf(Integer.MAX_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
+ bi = new BigInteger(String.valueOf(Integer.MIN_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrInteger(bi));
+
+ bi = new BigInteger(String.valueOf(Integer.MAX_VALUE + 1L));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
+ bi = new BigInteger(String.valueOf(Integer.MIN_VALUE - 1L));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
+ bi = new BigInteger(String.valueOf(Long.MAX_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
+ bi = new BigInteger(String.valueOf(Long.MIN_VALUE));
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrLong(bi));
+
+ cipEqu(new BigInteger(String.valueOf(Long.MAX_VALUE)).add(BigInteger.ONE));
+ cipEqu(new BigInteger(String.valueOf(Long.MIN_VALUE)).subtract(BigInteger.ONE));
+
+ bi = new BigInteger("0");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
+ TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
+ TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi),
+ TypeFlags.FLOAT);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi),
+ TypeFlags.DOUBLE);
+
+ bi = new BigInteger("16777215");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ bi = new BigInteger("-16777215");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+
+ bi = new BigInteger("16777216");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ bi = new BigInteger("-16777216");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrFloat(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+
+ bi = new BigInteger("16777217");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, TypeFlags.FLOAT);
+ bi = new BigInteger("-16777217");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, TypeFlags.FLOAT);
+
+ bi = new BigInteger("9007199254740991");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
+ bi = new BigInteger("-9007199254740991");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
+
+ bi = new BigInteger("9007199254740992");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
+ bi = new BigInteger("-9007199254740992");
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, new OverloadedNumberUtil.BigIntegerOrDouble(bi), TypeFlags.DOUBLE);
+
+ bi = new BigInteger("9007199254740993");
+ cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(bi, TypeFlags.FLOAT);
+ cipEqu(bi, TypeFlags.DOUBLE);
+ bi = new BigInteger("-9007199254740993");
+ cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
+ cipEqu(bi, TypeFlags.DOUBLE | TypeFlags.FLOAT);
+ cipEqu(bi, TypeFlags.FLOAT);
+ cipEqu(bi, TypeFlags.DOUBLE);
+
+ bi = new BigInteger("9007199254740994");
+ cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
+ bi = new BigInteger("-9007199254740994");
+ cipEqu(bi, TypeFlags.MASK_KNOWN_NONINTEGERS);
+ }
+
+ private void cipEqu(Number actualAndExpected) {
+ cipEqu(actualAndExpected, actualAndExpected, -1);
+ }
+
+ private void cipEqu(Number actual, Number expected) {
+ cipEqu(actual, expected, -1);
+ }
+
+ private void cipEqu(Number actualAndExpected, int flags) {
+ cipEqu(actualAndExpected, actualAndExpected, flags);
+ }
+
+ @SuppressWarnings("boxing")
+ private void cipEqu(Number actual, Number expected, int flags) {
+ Number res = OverloadedNumberUtil.addFallbackType(actual, flags);
+ assertEquals(expected.getClass(), res.getClass());
+ assertEquals(expected, res);
+
+ // Some number types wrap the number with multiple types and equals() only compares one of them. So we try to
+ // catch any inconsistency:
+ assertEquals(expected.byteValue(), res.byteValue());
+ assertEquals(expected.shortValue(), res.shortValue());
+ assertEquals(expected.intValue(), res.intValue());
+ assertEquals(expected.longValue(), res.longValue());
+ assertEquals(expected.floatValue(), res.floatValue());
+ assertEquals(expected.doubleValue(), res.doubleValue());
+ }
+
+ public void testGetArgumentConversionPrice() {
+ // Unknown number types:
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ RationalNumber.class, Integer.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, RationalNumber.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ RationalNumber.class, Float.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ Float.class, RationalNumber.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ RationalNumber.class, RationalNumber.class));
+
+ // Fully check some rows (not all of them; the code is generated anyways):
+
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Byte.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Short.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Integer.class));
+ assertEquals(10004, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Long.class));
+ assertEquals(10005, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, BigInteger.class));
+ assertEquals(30006, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Float.class));
+ assertEquals(20007, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, Double.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, BigDecimal.class));
+
+ assertEquals(45001, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Byte.class));
+ assertEquals(44002, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Short.class));
+ assertEquals(41003, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Integer.class));
+ assertEquals(41004, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Long.class));
+ assertEquals(40005, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, BigInteger.class));
+ assertEquals(33006, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Float.class));
+ assertEquals(32007, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, Double.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, BigDecimal.class));
+
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Byte.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Short.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Integer.class));
+ assertEquals(21004, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Long.class));
+ assertEquals(21005, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, BigInteger.class));
+ assertEquals(40006, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Float.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, Double.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, BigDecimal.class));
+
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Byte.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Short.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Integer.class));
+ assertEquals(Integer.MAX_VALUE, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Long.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, BigInteger.class));
+ assertEquals(40006, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Float.class));
+ assertEquals(20007, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, Double.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, BigDecimal.class));
+
+ // Check if all fromC is present:
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Byte.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Short.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Integer.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Long.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigInteger.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Float.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ Double.class, BigDecimal.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ BigDecimal.class, BigDecimal.class));
+ assertEquals(0, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.IntegerBigDecimal.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrFloat.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.FloatOrByte.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrShort.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.FloatOrByte.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.FloatOrShort.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.FloatOrInteger.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrByte.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrIntegerOrFloat.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrInteger.class, BigDecimal.class));
+ assertEquals(20008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.DoubleOrLong.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrByte.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrShort.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrInteger.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrLong.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrFloat.class, BigDecimal.class));
+ assertEquals(10008, OverloadedNumberUtil.getArgumentConversionPrice(
+ OverloadedNumberUtil.BigIntegerOrDouble.class, BigDecimal.class));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
new file mode 100644
index 0000000..3e6c2ed
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ParameterListPreferabilityTest.java
@@ -0,0 +1,445 @@
+/*
+ * 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.core.model.impl;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.freemarker.core.util._NumberUtil;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("boxing")
+public class ParameterListPreferabilityTest extends TestCase {
+
+ public ParameterListPreferabilityTest(String name) {
+ super(name);
+ }
+
+ public void testNumberical() {
+ // Note: the signature lists consists of the same elements, only their order changes depending on the type
+ // of the argument value.
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { byte.class },
+ new Class[] { Byte.class },
+ new Class[] { short.class },
+ new Class[] { Short.class },
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { BigInteger.class },
+ new Class[] { float.class },
+ new Class[] { Float.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { BigDecimal.class },
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class }
+ },
+ new Object[] { (byte) 1 });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { BigDecimal.class },
+ new Class[] { BigInteger.class },
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { float.class },
+ new Class[] { Float.class },
+ new Class[] { short.class },
+ new Class[] { Short.class },
+ new Class[] { byte.class },
+ new Class[] { Byte.class },
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class },
+ },
+ new Object[] { new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal("1")) });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { BigDecimal.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { float.class },
+ new Class[] { Float.class },
+ new Class[] { BigInteger.class },
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { short.class },
+ new Class[] { Short.class },
+ new Class[] { byte.class },
+ new Class[] { Byte.class },
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class },
+ },
+ new Object[] { new BigDecimal("1") /* possibly non-integer */ });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { float.class },
+ new Class[] { Float.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { BigDecimal.class },
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { short.class },
+ new Class[] { Short.class },
+ new Class[] { byte.class },
+ new Class[] { Byte.class },
+ new Class[] { BigInteger.class },
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class },
+ },
+ new Object[] { new OverloadedNumberUtil.FloatOrByte(1f, (byte) 1) });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { BigInteger.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { BigDecimal.class },
+ new Class[] { short.class },
+ new Class[] { Short.class },
+ new Class[] { float.class },
+ new Class[] { Float.class },
+
+ // Two incompatibles removed, would be removed in reality:
+ new Class[] { byte.class },
+ new Class[] { Byte.class },
+
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class }
+ },
+ new Object[] { new OverloadedNumberUtil.IntegerOrShort(1, (short) 1) });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { long.class },
+ new Class[] { Long.class },
+ new Class[] { BigInteger.class },
+ new Class[] { BigDecimal.class },
+ new Class[] { double.class },
+ new Class[] { Double.class },
+ new Class[] { float.class },
+ new Class[] { Float.class },
+ // skip byte and short as the would be equal with int (all invalid target types)
+ new Class[] { int.class }, // In reality, this and Integer are removed as not-applicable overloads
+ new Class[] { Integer.class },
+ new Class[] { Number.class },
+ new Class[] { Serializable.class },
+ new Class[] { Object.class }
+ },
+ new Object[] { 1L });
+
+ // Undecidable comparisons:
+
+ testAllCmpPermutationsEqu(
+ new Class[][] {
+ new Class[] { Byte.class },
+ new Class[] { Short.class },
+ new Class[] { Integer.class },
+ new Class[] { Long.class },
+ new Class[] { BigInteger.class },
+ new Class[] { Float.class },
+ },
+ new Object[] { 1.0 });
+
+ testAllCmpPermutationsEqu(
+ new Class[][] {
+ new Class[] { byte.class },
+ new Class[] { short.class },
+ new Class[] { int.class },
+ new Class[] { long.class },
+ new Class[] { float.class },
+ },
+ new Object[] { 1.0 });
+ }
+
+ public void testPrimitiveIsMoreSpecific() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { boolean.class },
+ new Class[] { Boolean.class }
+ },
+ new Object[] { true });
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { char.class },
+ new Class[] { Character.class }
+ },
+ new Object[] { 'x' });
+ }
+
+ public void testCharIsMoreSpecificThanString() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { char.class },
+ new Class[] { Character.class },
+ new Class[] { String.class },
+ new Class[] { CharSequence.class }
+ },
+ new Object[] { "s" });
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { char.class },
+ new Class[] { Character.class },
+ new Class[] { String.class }
+ },
+ new Object[] { 'c' });
+ }
+
+ public void testClassHierarchy() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { LinkedHashMap.class },
+ new Class[] { HashMap.class },
+ new Class[] { Map.class },
+ new Class[] { Object.class }
+ },
+ new Object[] { new LinkedHashMap() });
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { LinkedHashMap.class },
+ new Class[] { Cloneable.class },
+ new Class[] { Object.class }
+ },
+ new Object[] { new LinkedHashMap() });
+ }
+
+ public void testNumericalWithNonNumerical() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { Comparable.class },
+ new Class[] { Object.class },
+ },
+ new Object[] { 1 });
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { int.class },
+ new Class[] { Integer.class },
+ new Class[] { char.class },
+ new Class[] { Character.class },
+ },
+ new Object[] { 1 });
+ }
+
+ public void testUnrelated() {
+ testAllCmpPermutationsEqu(
+ new Class[][] {
+ new Class[] { Serializable.class },
+ new Class[] { CharSequence.class },
+ new Class[] { Comparable.class }
+ },
+ new Object[] { "s" });
+
+ testAllCmpPermutationsEqu(
+ new Class[][] {
+ new Class[] { HashMap.class },
+ new Class[] { TreeMap.class }
+ },
+ new Object[] { null });
+ }
+
+ public void testMultiParameter() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, String.class, String.class },
+
+ new Class[] { String.class, String.class, Object.class },
+ new Class[] { String.class, Object.class, String.class },
+ new Class[] { Object.class, String.class, String.class },
+
+ new Class[] { String.class, Object.class, Object.class },
+ new Class[] { Object.class, String.class, Object.class },
+ new Class[] { Object.class, Object.class, String.class },
+
+ new Class[] { Object.class, Object.class, Object.class },
+ },
+ new Object[] { "a", "b", "c" });
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, String.class },
+ new Class[] { String.class, Object.class },
+ new Class[] { CharSequence.class, CharSequence.class },
+ new Class[] { CharSequence.class, Object.class },
+ new Class[] { Object.class, String.class },
+ new Class[] { Object.class, CharSequence.class },
+ new Class[] { Object.class, Object.class },
+ },
+ new Object[] { "a", "b" });
+
+ // Subclassing is more important than primitive-VS-boxed:
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { boolean.class, boolean.class, boolean.class, String.class },
+ new Class[] { Boolean.class, boolean.class, boolean.class, String.class },
+ new Class[] { boolean.class, Boolean.class, Boolean.class, String.class },
+ new Class[] { Boolean.class, boolean.class, Boolean.class, String.class },
+ new Class[] { Boolean.class, Boolean.class, boolean.class, String.class },
+ new Class[] { Boolean.class, Boolean.class, Boolean.class, String.class },
+ new Class[] { Boolean.class, Boolean.class, Boolean.class, CharSequence.class },
+ new Class[] { boolean.class, boolean.class, boolean.class, Object.class },
+ new Class[] { Boolean.class, boolean.class, boolean.class, Object.class },
+ new Class[] { boolean.class, Boolean.class, Boolean.class, Object.class },
+ new Class[] { Boolean.class, boolean.class, Boolean.class, Object.class },
+ new Class[] { Boolean.class, Boolean.class, boolean.class, Object.class },
+ new Class[] { Boolean.class, Boolean.class, Boolean.class, Object.class },
+ },
+ new Object[] { true, false, true, "a" });
+
+ // Subclassing is more important than primitive-VS-boxed:
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { int.class, int.class, int.class, String.class },
+ new Class[] { Integer.class, int.class, int.class, String.class },
+ new Class[] { int.class, Integer.class, Integer.class, String.class },
+ new Class[] { Integer.class, int.class, Integer.class, String.class },
+ new Class[] { Integer.class, Integer.class, int.class, String.class },
+ new Class[] { Integer.class, Integer.class, Integer.class, String.class },
+ new Class[] { Integer.class, Integer.class, Integer.class, CharSequence.class },
+ new Class[] { int.class, int.class, int.class, Object.class },
+ new Class[] { Integer.class, int.class, int.class, Object.class },
+ new Class[] { int.class, Integer.class, Integer.class, Object.class },
+ new Class[] { Integer.class, int.class, Integer.class, Object.class },
+ new Class[] { Integer.class, Integer.class, int.class, Object.class },
+ new Class[] { Integer.class, Integer.class, Integer.class, Object.class },
+ },
+ new Object[] { 1, 2, 3, "a" });
+ }
+
+ public void testVarargs() {
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, String[].class },
+ new Class[] { String.class, CharSequence[].class },
+ new Class[] { String.class, Object[].class },
+ },
+ new Object[] { "a", "b", "c" },
+ true);
+
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, int[].class },
+ new Class[] { String.class, Integer[].class },
+ new Class[] { String.class, long[].class },
+ new Class[] { String.class, Long[].class },
+ new Class[] { String.class, double[].class },
+ new Class[] { String.class, Double[].class },
+ new Class[] { String.class, Serializable[].class },
+ new Class[] { String.class, Object[].class },
+ },
+ new Object[] { "a", 1, 2, 3 },
+ true);
+
+ // 0-long varargs list; in case of ambiguity, the varargs component type decides:
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, Object[].class },
+ new Class[] { CharSequence.class, int[].class },
+ new Class[] { CharSequence.class, Integer[].class },
+ new Class[] { CharSequence.class, long[].class },
+ new Class[] { CharSequence.class, Long[].class },
+ new Class[] { CharSequence.class, double[].class },
+ new Class[] { CharSequence.class, Double[].class },
+ new Class[] { CharSequence.class, Serializable[].class },
+ new Class[] { CharSequence.class, Object[].class },
+ new Class[] { Object.class, int[].class },
+ },
+ new Object[] { "a" },
+ true);
+
+
+ // Different oms prefix length; in the case of ambiguity, the one with higher oms param count wins.
+ testAllCmpPermutationsInc(
+ new Class[][] {
+ new Class[] { String.class, int.class, int.class, int[].class },
+ new Class[] { String.class, int.class, int[].class },
+ new Class[] { String.class, int[].class },
+ },
+ new Object[] { "a", 1, 2, 3 },
+ true);
+ }
+
+ private void testAllCmpPermutationsInc(Class[][] sortedSignatures, Object[] args) {
+ testAllCmpPermutationsInc(sortedSignatures, args, false);
+ }
+
+ /**
+ * Compares all items with all other items in the provided descending sorted array of signatures, checking that
+ * for all valid indexes i and j, where j > i, it stands that sortedSignatures[i] > sortedSignatures[j].
+ * The comparisons are done with both operand orders, also each items is compared to itself too.
+ *
+ * @param sortedSignatures method signatures sorted by decreasing specificity
+ */
+ private void testAllCmpPermutationsInc(Class[][] sortedSignatures, Object[] args, boolean varargs) {
+ final ArgumentTypes argTs = new ArgumentTypes(args);
+ for (int i = 0; i < sortedSignatures.length; i++) {
+ for (int j = 0; j < sortedSignatures.length; j++) {
+ assertEquals("sortedSignatures[" + i + "] <==> sortedSignatures [" + j + "]",
+ _NumberUtil.getSignum(
+ Integer.valueOf(j).compareTo(i)),
+ _NumberUtil.getSignum(
+ argTs.compareParameterListPreferability(
+ sortedSignatures[i], sortedSignatures[j], varargs)));
+ }
+ }
+ }
+
+ private void testAllCmpPermutationsEqu(Class[][] signatures, Object[] args) {
+ final ArgumentTypes argTs = new ArgumentTypes(args);
+ for (int i = 0; i < signatures.length; i++) {
+ for (int j = 0; j < signatures.length; j++) {
+ assertEquals("sortedSignatures[" + i + "] <==> sortedSignatures [" + j + "]",
+ 0,
+ argTs.compareParameterListPreferability(signatures[i], signatures[j], false));
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.java
new file mode 100644
index 0000000..4f4c0a1
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelObjectIntrospectionTest.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.core.model.impl;
+
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+
+public class PrallelObjectIntrospectionTest extends AbstractParallelIntrospectionTest {
+
+ public PrallelObjectIntrospectionTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ new PrallelObjectIntrospectionTest("almostForever")
+ .testReliability(Integer.MAX_VALUE);
+ }
+
+ @Override
+ protected TemplateHashModel getWrappedEntity(int objIdx)
+ throws TemplateModelException {
+ return (TemplateHashModel) getObjectWrapper().wrap(
+ ManyObjectsOfDifferentClasses.OBJECTS[objIdx]);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
new file mode 100644
index 0000000..836d559
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/PrallelStaticIntrospectionTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.core.model.impl;
+
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+
+public class PrallelStaticIntrospectionTest extends AbstractParallelIntrospectionTest {
+
+ private static final String STATICS_CLASS_CONTAINER_CLASS_NAME
+ = ManyStaticsOfDifferentClasses.class.getName();
+
+ public PrallelStaticIntrospectionTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ new PrallelStaticIntrospectionTest("almostForever")
+ .testReliability(Integer.MAX_VALUE);
+ }
+
+ @Override
+ protected TemplateHashModel getWrappedEntity(int clIdx)
+ throws TemplateModelException {
+ return (TemplateHashModel) getObjectWrapper().getStaticModels().get(
+ STATICS_CLASS_CONTAINER_CLASS_NAME + "$C"
+ + clIdx);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
new file mode 100644
index 0000000..806a186
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/RationalNumber.java
@@ -0,0 +1,90 @@
+/*
+ * 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.core.model.impl;
+
+public final class RationalNumber extends Number {
+
+ final int divident;
+ final int divisor;
+
+ public RationalNumber(int divident, int divisor) {
+ this.divident = divident;
+ this.divisor = divisor;
+ }
+
+ @Override
+ public int intValue() {
+ return divident / divisor;
+ }
+
+ @Override
+ public long longValue() {
+ return divident / (long) divisor;
+ }
+
+ @Override
+ public float floatValue() {
+ return (float) (divident / (double) divisor);
+ }
+
+ @Override
+ public double doubleValue() {
+ return divident / (double) divisor;
+ }
+
+ public int getDivident() {
+ return divident;
+ }
+
+ public int getDivisor() {
+ return divisor;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + divident;
+ result = prime * result + divisor;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RationalNumber other = (RationalNumber) obj;
+ if (divident != other.divident)
+ return false;
+ if (divisor != other.divisor)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return divident + "/" + divisor;
+ }
+
+}
\ 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/core/model/impl/StaticModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
new file mode 100644
index 0000000..609d632
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.core.model.impl;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class StaticModelsTest {
+
+ @Test
+ public void modelCaching() throws Exception {
+ DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).usePrivateCaches(true)
+ .build();
+ TemplateHashModel statics = ow.getStaticModels();
+ TemplateHashModel s = (TemplateHashModel) statics.get(S.class.getName());
+ assertNotNull(s);
+ assertNotNull(s.get("F"));
+ assertNotNull(s.get("m"));
+ try {
+ s.get("x");
+ fail();
+ } catch (TemplateModelException e) {
+ assertThat(e.getMessage(), containsString("No such key"));
+ }
+
+ try {
+ statics.get("no.such.ClassExists");
+ fail();
+ } catch (TemplateModelException e) {
+ assertTrue(e.getCause() instanceof ClassNotFoundException);
+ }
+
+ TemplateModel f = s.get("F");
+ assertTrue(f instanceof TemplateScalarModel);
+ assertEquals(((TemplateScalarModel) f).getAsString(), "F OK");
+
+ TemplateModel m = s.get("m");
+ assertTrue(m instanceof TemplateMethodModelEx);
+ assertEquals(((TemplateScalarModel) ((TemplateMethodModelEx) m).exec(new ArrayList())).getAsString(), "m OK");
+
+ assertSame(s, statics.get(S.class.getName()));
+
+ ow.clearClassIntrospecitonCache();
+ TemplateHashModel sAfterClean = (TemplateHashModel) statics.get(S.class.getName());
+ assertNotSame(s, sAfterClean);
+ assertSame(sAfterClean, statics.get(S.class.getName()));
+ assertNotNull(sAfterClean.get("F"));
+ assertNotNull(sAfterClean.get("m"));
+ }
+
+ public static class S {
+
+ public static final String F = "F OK";
+
+ public static String m() {
+ return "m OK";
+ }
+
+ }
+
+}
[32/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
new file mode 100644
index 0000000..4602b67
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformHashWrapper.java
@@ -0,0 +1,79 @@
+/*
+ * 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.Configuration;
+import org.apache.freemarker.core.model.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.SimpleHash;
+import org.apache.freemarker.core.util.HtmlEscape;
+import org.apache.freemarker.core.util.StandardCompress;
+
+/**
+ * Part of the TestTransform testcase suite.
+ */
+public class TransformHashWrapper implements TemplateHashModel,
+ TemplateScalarModel {
+
+ private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
+ private SimpleHash m_cHashModel = new SimpleHash(ow);
+
+ /** Creates new TransformHashWrapper */
+ public TransformHashWrapper() {
+ m_cHashModel.put( "htmlEscape", new HtmlEscape() );
+ m_cHashModel.put( "compress", new StandardCompress() );
+ m_cHashModel.put( "escape", new TransformMethodWrapper1() );
+ m_cHashModel.put( "special", new TransformMethodWrapper2() );
+ }
+
+ /**
+ * 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) throws TemplateModelException {
+ return m_cHashModel.get( key );
+ }
+
+ /**
+ * @return true if this object is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * Returns the scalar's value as a String.
+ * @return the String value of this scalar.
+ */
+ @Override
+ public String getAsString() {
+ return "Utility transformations";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.java
new file mode 100644
index 0000000..8311134
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper1.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.test.templatesuite.models;
+
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.util.HtmlEscape;
+import org.apache.freemarker.core.util.XmlEscape;
+
+/**
+ * Simple test of the interaction between MethodModels and TransformModels.
+ */
+public class TransformMethodWrapper1 implements TemplateMethodModel {
+
+ /**
+ * Executes a method call.
+ *
+ * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
+ * the values of the arguments passed to the method.
+ * @return the <tt>TemplateModel</tt> produced by the method, or null.
+ */
+ @Override
+ public Object exec(List arguments) {
+
+ if (( arguments.size() > 0 ) && ( arguments.get( 0 ).toString().equals( "xml" ))) {
+ return new XmlEscape();
+ } else {
+ return new HtmlEscape();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
new file mode 100644
index 0000000..96eb1a5
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformMethodWrapper2.java
@@ -0,0 +1,64 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateMethodModel;
+
+/**
+ * Another test of the interaction between MethodModels and TransformModels.
+ */
+public class TransformMethodWrapper2 implements TemplateMethodModel {
+
+ /**
+ * Executes a method call.
+ *
+ * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
+ * the values of the arguments passed to the method.
+ * @return the <tt>TemplateModel</tt> produced by the method, or null.
+ */
+ @Override
+ public Object exec(List arguments) {
+ TransformModel1 cTransformer = new TransformModel1();
+ Iterator iArgument = arguments.iterator();
+
+ // Sets up properties of the Transform model based on the arguments
+ // passed into this method
+
+ while ( iArgument.hasNext() ) {
+ String aArgument = (String) iArgument.next();
+
+ if ( aArgument.equals( "quote" )) {
+ cTransformer.setQuotes( true );
+ } else if ( aArgument.equals( "tag" )) {
+ cTransformer.setTags( true );
+ } else if ( aArgument.equals( "ampersand" )) {
+ cTransformer.setAmpersands( true );
+ } else {
+ cTransformer.setComment( aArgument );
+ }
+ }
+
+ // Now return the transform class.
+ return cTransformer;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
new file mode 100644
index 0000000..0875679
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/TransformModel1.java
@@ -0,0 +1,175 @@
+/*
+ * 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.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.freemarker.core.model.TemplateTransformModel;
+
+/**
+ * A TemplateTransformModel that includes properties. These properties can be
+ * set at model construction time, or, for the purposes of this demonstration,
+ * can be passed in from a wrapper TemplateMethodModel.
+ */
+public class TransformModel1 implements TemplateTransformModel {
+
+ private boolean m_bAmpersands = false;
+ private boolean m_bQuotes = false;
+ private boolean m_bTags = false;
+ private String m_aComment = "";
+
+ private static final int READER_BUFFER_SIZE = 4096;
+
+ @Override
+ public Writer getWriter(final Writer out,
+ final Map args) {
+ final StringBuilder buf = new StringBuilder();
+ return new Writer(out) {
+ @Override
+ public void write(char cbuf[], int off, int len) {
+ buf.append(cbuf, off, len);
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws IOException {
+ StringReader sr = new StringReader(buf.toString());
+ StringWriter sw = new StringWriter();
+ transform(sr, sw);
+ out.write(sw.toString());
+ }
+ };
+ }
+
+
+ /**
+ * Indicates whether we escape ampersands. This property can be set either
+ * while the model is being constructed, or via a property passed in through
+ * a <code>TemplateMethodModel</code>.
+ */
+ public void setAmpersands( boolean bAmpersands ) {
+ m_bAmpersands = bAmpersands;
+ }
+
+ /**
+ * Indicates whether we escape quotes. This property can be set either
+ * while the model is being constructed, or via a property passed in through
+ * a <code>TemplateMethodModel</code>.
+ */
+ public void setQuotes( boolean bQuotes ) {
+ m_bQuotes = bQuotes;
+ }
+
+ /**
+ * Indicates whether we escape tags. This property can be set either
+ * while the model is being constructed, or via a property passed in through
+ * a <code>TemplateMethodModel</code>.
+ */
+ public void setTags( boolean bTags ) {
+ m_bTags = bTags;
+ }
+
+ /**
+ * Sets a comment for this transformation. This property can be set either
+ * while the model is being constructed, or via a property passed in through
+ * a <code>TemplateMethodModel</code>.
+ */
+ public void setComment( String aComment ) {
+ m_aComment = aComment;
+ }
+
+ /**
+ * Performs a transformation/filter on FreeMarker output.
+ *
+ * @param source the input to be transformed
+ * @param output the destination of the transformation
+ */
+ public void transform(Reader source, Writer output)
+ throws IOException {
+ // Output the source, converting unsafe certain characters to their
+ // equivalent entities.
+ int n = 0;
+ boolean bCommentSent = false;
+ char[] aBuffer = new char[ READER_BUFFER_SIZE ];
+ int i = source.read( aBuffer );
+ while (i >= 0) {
+ for ( int j = 0; j < i; j++ ) {
+ char c = aBuffer[j];
+ switch (c) {
+ case '&':
+ if ( m_bAmpersands ) {
+ output.write("&");
+ } else {
+ output.write( c );
+ }
+ break;
+ case '<':
+ if ( m_bTags ) {
+ output.write("<");
+ } else {
+ output.write( c );
+ }
+ break;
+ case '>':
+ if ( m_bTags ) {
+ output.write(">");
+ } else {
+ output.write( c );
+ }
+ break;
+ case '"':
+ if ( m_bQuotes ) {
+ output.write(""");
+ } else {
+ output.write( c );
+ }
+ break;
+ case '\'':
+ if ( m_bQuotes ) {
+ output.write("'");
+ } else {
+ output.write( c );
+ }
+ break;
+ case '*':
+ if ( ! bCommentSent ) {
+ output.write( m_aComment );
+ bCommentSent = true;
+ } else {
+ output.write( c );
+ }
+ break;
+ default:
+ output.write(c);
+ }
+ n++;
+ }
+ i = source.read( aBuffer );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
new file mode 100644
index 0000000..940cb17
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/models/VarArgTestModel.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+public class VarArgTestModel {
+
+ public int bar(Integer... xs) {
+ int sum = 0;
+ for (Integer x : xs) {
+ if (x != null) {
+ sum *= 100;
+ sum += x;
+ }
+ }
+ return sum;
+ }
+
+ public int bar2(int first, int... xs) {
+ int sum = 0;
+ for (int x : xs) {
+ sum *= 100;
+ sum += x;
+ }
+ return -(sum * 100 + first);
+ }
+
+ public int overloaded(int x, int y) {
+ return x * 100 + y;
+ }
+
+ public int overloaded(int... xs) {
+ int sum = 0;
+ for (int x : xs) {
+ sum *= 100;
+ sum += x;
+ }
+ return -sum;
+ }
+
+ public String noVarArgs(String s, boolean b, int i, Date d) {
+ return s + ", " + b + ", " + i + ", " + d.getTime();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/package.html
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/package.html b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/package.html
new file mode 100644
index 0000000..cabffb0
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/test/templatesuite/package.html
@@ -0,0 +1,42 @@
+<!--
+ 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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+<p>JUnit test-suite that processes FreeMarker templates and compare their
+output to reference files.</p>
+
+<p>To add a test-case, go to
+<tt>src/test/resources/freemarker/test/templatesuite/</tt> and inside that
+directory:</p>
+<ol>
+ <li>Add a template to under <tt>templates/</tt> with whatever meaningful
+ file name</li>
+ <li>Add the expected output to <tt>references/</tt> with exactly the same
+ file name</li>
+ <li>Add a new <tt>testcase</tt> elemen to <tt>testcases.xml</tt></li>
+ <li>If you want to add items to the data-model or do something else special,
+ modify the <tt>setUp()</tt> method in
+ <tt>src/test/java/freemarker/test/templatesuite/TemplateTestCase.java</tt>
+ </li>
+</ol>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ast
new file mode 100644
index 0000000..1cdd496
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ast
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #text // o.a.f.c.ASTStaticText
+ - content: "1 " // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: foo // o.a.f.c.ASTExpVariable
+ - argument name: "x" // String
+ - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
+ - argument name: "y" // String
+ - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
+ - target loop variable: "b1" // String
+ - target loop variable: "b2" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "x" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n2 " // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: . // o.a.f.c.ASTExpDot
+ - left-hand operand: ns // o.a.f.c.ASTExpVariable
+ - right-hand operand: "bar" // String
+ - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
+ - target loop variable: "b1" // String
+ - target loop variable: "b2" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "y" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n3 " // String
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: ns // o.a.f.c.ASTExpVariable
+ #global // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "3" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n4 " // String
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: == // o.a.f.c.ASTExpComparison
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "foo" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: y // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "bar" // String
+ #else // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: null // Null
+ - AST-node subtype: "1" // Integer
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: "static" // o.a.f.c.ASTExpStringLiteral
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: dynamic "..." // o.a.f.c.ASTExpStringLiteral
+ - value part: "x" // String
+ - value part: ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: * // o.a.f.c.ArithmeticExpression
+ - left-hand operand: baaz // o.a.f.c.ASTExpVariable
+ - right-hand operand: 10 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "1" // Integer
+ - value part: "y" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n5 " // String
+ #switch // o.a.f.c.ASTDirSwitch
+ - value: x // o.a.f.c.ASTExpVariable
+ #case // o.a.f.c.ASTDirCase
+ - condition: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "one" // String
+ #case // o.a.f.c.ASTDirCase
+ - condition: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "two" // String
+ #default // o.a.f.c.ASTDirCase
+ - condition: null // Null
+ - AST-node subtype: "1" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "more" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n6 " // String
+ #macro // o.a.f.c.ASTDirMacro
+ - assignment target: "foo" // String
+ - parameter name: "x" // String
+ - parameter default: null // Null
+ - parameter name: "y" // String
+ - parameter default: 2 // o.a.f.c.ASTExpNumberLiteral
+ - parameter name: "z" // String
+ - parameter default: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: y // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - catch-all parameter name: "q" // String
+ - AST-node subtype: "0" // Integer
+ #nested // o.a.f.c.ASTDirNested
+ - passed value: x // o.a.f.c.ASTExpVariable
+ - passed value: y // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n7 " // String
+ #function // o.a.f.c.ASTDirMacro
+ - assignment target: "foo" // String
+ - parameter name: "x" // String
+ - parameter default: null // Null
+ - parameter name: "y" // String
+ - parameter default: null // Null
+ - catch-all parameter name: null // Null
+ - AST-node subtype: "1" // Integer
+ #local // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 123 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "2" // Integer
+ - namespace: null // Null
+ #return // o.a.f.c.ASTDirReturn
+ - value: 1 // o.a.f.c.ASTExpNumberLiteral
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n8 " // String
+ #list // o.a.f.c.ASTDirList
+ - list source: xs // o.a.f.c.ASTExpVariable
+ - target loop variable: "x" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n9 " // String
+ #list-#else-container // o.a.f.c.ASTDirListElseContainer
+ #list // o.a.f.c.ASTDirList
+ - list source: xs // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "[" // String
+ #items // o.a.f.c.ASTDirItems
+ - target loop variable: "x" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ #sep // o.a.f.c.ASTDirSep
+ #text // o.a.f.c.ASTStaticText
+ - content: ", " // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "]" // String
+ #else // o.a.f.c.ASTDirElseOfList
+ #text // o.a.f.c.ASTStaticText
+ - content: "None" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n10 " // String
+ #--...-- // o.a.f.c.ASTComment
+ - content: " A comment " // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n11 " // String
+ #outputformat // o.a.f.c.ASTDirOutputFormat
+ - value: "XML" // o.a.f.c.ASTExpStringLiteral
+ #noautoesc // o.a.f.c.ASTDirNoAutoEsc
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: a // o.a.f.c.ASTExpVariable
+ #autoesc // o.a.f.c.ASTDirAutoEsc
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: b // o.a.f.c.ASTExpVariable
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: c // o.a.f.c.ASTExpVariable
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ftl
new file mode 100644
index 0000000..8c8953a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-1.ftl
@@ -0,0 +1,29 @@
+<#--
+ 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.
+-->
+1 <@foo x=1 y=2; b1, b2>x</...@foo>
+2 <@ns.bar 1 2; b1, b2>y</@>
+3 <#assign x = 123><#assign x = 123 in ns><#global x = 123>
+4 <#if x + 1 == 0>foo${y}bar<#else>${"static"}${'x${baaz * 10}y'}</#if>
+5 <#switch x><#case 1>one<#case 2>two<#default>more</#switch>
+6 <#macro foo x y=2 z=y+1 q...><#nested x y></#macro>
+7 <#function foo x y><#local x = 123><#return 1></#function>
+8 <#list xs as x></#list>
+9 <#list xs>[<#items as x>${x}<#sep>, </#items>]<#else>None</#list>
+10 <#-- A comment -->
+11 <#outputFormat "XML"><#noAutoEsc>${a}<#autoEsc>${b}</#autoEsc>${c}</#noAutoEsc></#outputFormat>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
new file mode 100644
index 0000000..4839892
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ast
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #text // o.a.f.c.ASTStaticText
+ - content: "1 " // String
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n2 " // String
+ #assign // o.a.f.c.ASTDirAssignmentsContainer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "y" // String
+ - assignment operator: "=" // String
+ - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n3 " // String
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: ns // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n4 " // String
+ #assign // o.a.f.c.ASTDirAssignmentsContainer
+ - variable scope: "1" // Integer
+ - namespace: ns // o.a.f.c.ASTExpVariable
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: ns // o.a.f.c.ASTExpVariable
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "y" // String
+ - assignment operator: "=" // String
+ - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: ns // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n5 " // String
+ #global // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "3" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n6 " // String
+ #global // o.a.f.c.ASTDirAssignmentsContainer
+ - variable scope: "3" // Integer
+ - namespace: null // Null
+ #global // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "3" // Integer
+ - namespace: null // Null
+ #global // o.a.f.c.ASTDirAssignment
+ - assignment target: "y" // String
+ - assignment operator: "=" // String
+ - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "3" // Integer
+ - namespace: null // Null
+ #macro // o.a.f.c.ASTDirMacro
+ - assignment target: "m" // String
+ - catch-all parameter name: null // Null
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: " 7 " // String
+ #local // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "2" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n 8 " // String
+ #local // o.a.f.c.ASTDirAssignmentsContainer
+ - variable scope: "2" // Integer
+ - namespace: null // Null
+ #local // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "2" // Integer
+ - namespace: null // Null
+ #local // o.a.f.c.ASTDirAssignment
+ - assignment target: "y" // String
+ - assignment operator: "=" // String
+ - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "2" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "9 " // String
+ #assign // o.a.f.c.ASTDirAssignmentsContainer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "a" // String
+ - assignment operator: "+=" // String
+ - assignment source: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "b" // String
+ - assignment operator: "-=" // String
+ - assignment source: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "c" // String
+ - assignment operator: "*=" // String
+ - assignment source: 3 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "d" // String
+ - assignment operator: "/=" // String
+ - assignment source: 4 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "e" // String
+ - assignment operator: "%=" // String
+ - assignment source: 5 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "f" // String
+ - assignment operator: "++" // String
+ - assignment source: null // Null
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "g" // String
+ - assignment operator: "--" // String
+ - assignment source: null // Null
+ - variable scope: "1" // Integer
+ - namespace: null // Null
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
new file mode 100644
index 0000000..c070635
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-assignments.ftl
@@ -0,0 +1,29 @@
+<#--
+ 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.
+-->
+1 <#assign x = 1>
+2 <#assign x = 1, y = 2>
+3 <#assign x = 1 in ns>
+4 <#assign x = 1, y = 2 in ns>
+5 <#global x = 1>
+6 <#global x = 1, y = 2>
+<#macro m>
+ 7 <#local x = 1>
+ 8 <#local x = 1, y = 2>
+</#macro>
+9 <#assign a += 1, b -= 2, c *= 3, d /= 4, e %= 5, f++, g-->
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
new file mode 100644
index 0000000..b8b696f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ?trim // o.a.f.c.BuiltInsForStringsBasic$trimBI
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: "trim" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - callee: ?left_pad // o.a.f.c.BuiltInsForStringsBasic$padBI
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: "left_pad" // String
+ - argument value: 5 // o.a.f.c.ASTExpNumberLiteral
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - callee: ?left_pad // o.a.f.c.BuiltInsForStringsBasic$padBI
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: "left_pad" // String
+ - argument value: 5 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: "-" // o.a.f.c.ASTExpStringLiteral
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ?then(...) // o.a.f.c.BuiltInsWithParseTimeParameters$then_BI
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: "then" // String
+ - argument value: "y" // o.a.f.c.ASTExpStringLiteral
+ - argument value: "n" // o.a.f.c.ASTExpStringLiteral
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ?switch(...) // o.a.f.c.BuiltInsWithParseTimeParameters$switch_BI
+ - left-hand operand: x // o.a.f.c.ASTExpVariable
+ - right-hand operand: "switch" // String
+ - argument value: 1 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: 11 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: 2 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: 22 // o.a.f.c.ASTExpNumberLiteral
+ - argument value: 33 // o.a.f.c.ASTExpNumberLiteral
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
new file mode 100644
index 0000000..74aee52
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ftl
@@ -0,0 +1,23 @@
+<#--
+ 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.
+-->
+${x?trim}
+${x?left_pad(5)}
+${x?left_pad(5, '-')}
+${x?then('y', 'n')}
+${x?switch(1, 11, 2, 22, 33)}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ast
new file mode 100644
index 0000000..7770d72
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ast
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent; Location 1:1-18:8
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 1:1-1:15
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 1:6-1:8
+ - AST-node subtype: "0" // Integer
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 2:1-2:16
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 2:6-2:8
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText; Location 2:10-2:10
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 2:17-2:17
+ - content: "\n" // String
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 3:1-3:20
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 3:6-3:8
+ - AST-node subtype: "0" // Integer
+ ${...} // o.a.f.c.ASTDollarInterpolation; Location 3:10-3:13
+ - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 3:12-3:12
+ #text // o.a.f.c.ASTStaticText; Location 3:14-3:14
+ - content: "2" // String
+ #text // o.a.f.c.ASTStaticText; Location 3:21-3:21
+ - content: "\n" // String
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 4:1-4:22
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 4:1-4:9
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 4:6-4:8
+ - AST-node subtype: "0" // Integer
+ #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 4:10-4:16
+ - condition: null // Null
+ - AST-node subtype: "1" // Integer
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 5:1-5:24
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 5:1-5:10
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 5:6-5:8
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText; Location 5:10-5:10
+ - content: "1" // String
+ #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 5:11-5:18
+ - condition: null // Null
+ - AST-node subtype: "1" // Integer
+ #text // o.a.f.c.ASTStaticText; Location 5:18-5:18
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 5:25-5:25
+ - content: "\n" // String
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 6:1-6:32
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 6:1-6:14
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 6:6-6:8
+ - AST-node subtype: "0" // Integer
+ ${...} // o.a.f.c.ASTDollarInterpolation; Location 6:10-6:13
+ - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 6:12-6:12
+ #text // o.a.f.c.ASTStaticText; Location 6:14-6:14
+ - content: "2" // String
+ #else // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 6:15-6:26
+ - condition: null // Null
+ - AST-node subtype: "1" // Integer
+ ${...} // o.a.f.c.ASTDollarInterpolation; Location 6:22-6:25
+ - content: 1 // o.a.f.c.ASTExpNumberLiteral; Location 6:24-6:24
+ #text // o.a.f.c.ASTStaticText; Location 6:26-6:26
+ - content: "2" // String
+ #text // o.a.f.c.ASTStaticText; Location 6:33-6:33
+ - content: "\n" // String
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 7:1-7:28
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 7:1-7:9
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 7:6-7:8
+ - AST-node subtype: "0" // Integer
+ #elseif // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 7:10-7:22
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 7:19-7:21
+ - AST-node subtype: "2" // Integer
+ #if-#elseif-#else-container // o.a.f.c.ASTDirIfElseIfElseContainer; Location 8:1-8:29
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 8:1-8:9
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 8:6-8:8
+ - AST-node subtype: "0" // Integer
+ #elseif // o.a.f.c.ASTDirIfOrElseOrElseIf; Location 8:10-8:23
+ - condition: exp // o.a.f.c.ASTExpVariable; Location 8:19-8:21
+ - AST-node subtype: "2" // Integer
+ #text // o.a.f.c.ASTStaticText; Location 8:23-8:23
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 8:30-8:30
+ - content: "\n" // String
+ #attempt // o.a.f.c.ASTDirAttemptRecoverContainer; Location 9:1-9:31
+ - error handler: #recover // o.a.f.c.ASTDirRecover; Location 9:11-9:20
+ #recover // o.a.f.c.ASTDirRecover; Location 9:11-9:20
+ #attempt // o.a.f.c.ASTDirAttemptRecoverContainer; Location 10:1-10:33
+ - error handler: #recover // o.a.f.c.ASTDirRecover; Location 10:12-10:22
+ #text // o.a.f.c.ASTStaticText; Location 10:22-10:22
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 10:11-10:11
+ - content: "1" // String
+ #recover // o.a.f.c.ASTDirRecover; Location 10:12-10:22
+ #text // o.a.f.c.ASTStaticText; Location 10:22-10:22
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 10:34-10:34
+ - content: "\n" // String
+ #list // o.a.f.c.ASTDirList; Location 11:1-11:22
+ - list source: s // o.a.f.c.ASTExpVariable; Location 11:8-11:8
+ - target loop variable: "i" // String
+ #list // o.a.f.c.ASTDirList; Location 12:1-12:23
+ - list source: s // o.a.f.c.ASTExpVariable; Location 12:8-12:8
+ - target loop variable: "i" // String
+ #text // o.a.f.c.ASTStaticText; Location 12:15-12:15
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 12:24-12:24
+ - content: "\n" // String
+ #list // o.a.f.c.ASTDirList; Location 13:1-13:28
+ - list source: s // o.a.f.c.ASTExpVariable; Location 13:8-13:8
+ - target loop variable: "i" // String
+ #sep // o.a.f.c.ASTDirSep; Location 13:15-13:20
+ #list // o.a.f.c.ASTDirList; Location 14:1-14:30
+ - list source: s // o.a.f.c.ASTExpVariable; Location 14:8-14:8
+ - target loop variable: "i" // String
+ #text // o.a.f.c.ASTStaticText; Location 14:15-14:15
+ - content: "1" // String
+ #sep // o.a.f.c.ASTDirSep; Location 14:16-14:22
+ #text // o.a.f.c.ASTStaticText; Location 14:22-14:22
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 14:31-14:31
+ - content: "\n" // String
+ #list // o.a.f.c.ASTDirList; Location 15:1-15:45
+ - list source: s // o.a.f.c.ASTExpVariable; Location 15:8-15:8
+ #items // o.a.f.c.ASTDirItems; Location 15:10-15:37
+ - target loop variable: "i" // String
+ #sep // o.a.f.c.ASTDirSep; Location 15:23-15:28
+ #list // o.a.f.c.ASTDirList; Location 16:1-16:49
+ - list source: s // o.a.f.c.ASTExpVariable; Location 16:8-16:8
+ #text // o.a.f.c.ASTStaticText; Location 16:10-16:10
+ - content: "1" // String
+ #items // o.a.f.c.ASTDirItems; Location 16:11-16:40
+ - target loop variable: "i" // String
+ #text // o.a.f.c.ASTStaticText; Location 16:24-16:24
+ - content: "1" // String
+ #sep // o.a.f.c.ASTDirSep; Location 16:25-16:31
+ #text // o.a.f.c.ASTStaticText; Location 16:31-16:31
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 16:41-16:41
+ - content: "1" // String
+ #text // o.a.f.c.ASTStaticText; Location 16:50-17:2
+ - content: "\n1\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation; Location 18:1-18:8
+ - content: + // o.a.f.c.ASTExpAddOrConcat; Location 18:3-18:7
+ - left-hand operand: x // o.a.f.c.ASTExpVariable; Location 18:3-18:3
+ - right-hand operand: y // o.a.f.c.ASTExpVariable; Location 18:7-18:7
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
new file mode 100644
index 0000000..99fa244
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-locations.ftl
@@ -0,0 +1,36 @@
+<#--
+ 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.
+-->
+<#if exp></#if>
+<#if exp>1</#if>
+<#if exp>${1}2</#if>
+<#if exp><#else></#if>
+<#if exp>1<#else>1</#if>
+<#if exp>${1}2<#else>${1}2</#if>
+<#if exp><#elseif exp></#if>
+<#if exp><#elseif exp>1</#if>
+<#attempt><#recover></#attempt>
+<#attempt>1<#recover>1</#attempt>
+<#list s as i></#list>
+<#list s as i>1</#list>
+<#list s as i><#sep></#list>
+<#list s as i>1<#sep>1</#list>
+<#list s><#items as i><#sep></#items></#list>
+<#list s>1<#items as i>1<#sep>1</#items>1</#list>
+1
+${x + y}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
new file mode 100644
index 0000000..41fc90b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ast
@@ -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.
+ */
+#if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: true // o.a.f.c.ASTExpBooleanLiteral
+ - AST-node subtype: "0" // Integer
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: true // o.a.f.c.ASTExpBooleanLiteral
+ - AST-node subtype: "0" // Integer
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: true // o.a.f.c.ASTExpBooleanLiteral
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: " text\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: " " // String
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: true // o.a.f.c.ASTExpBooleanLiteral
+ - AST-node subtype: "0" // Integer
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: x // o.a.f.c.ASTExpVariable
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
new file mode 100644
index 0000000..53716e4
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-mixedcontentsimplifications.ftl
@@ -0,0 +1,26 @@
+<#--
+ 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.
+-->
+<#if true>
+ <#if true>
+ </#if>
+ <#if true>
+ text
+ </#if>
+ <#if true>${x}</#if>
+</#if>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
new file mode 100644
index 0000000..7675522
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ast
@@ -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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #text // o.a.f.c.ASTStaticText
+ - content: "a\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "b\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "c\n" // String
+ #text // o.a.f.c.ASTStaticText
+ - content: "d\n" // String
+ #if // o.a.f.c.ASTDirIfOrElseOrElseIf
+ - condition: true // o.a.f.c.ASTExpBooleanLiteral
+ - AST-node subtype: "0" // Integer
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
new file mode 100644
index 0000000..501802a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-multipleignoredchildren.ftl
@@ -0,0 +1,33 @@
+<#--
+ 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.
+-->
+a
+<#compress></#compress>
+b
+<#compress></#compress>
+<#compress></#compress>
+c
+<#compress></#compress>
+<#compress></#compress>
+<#compress></#compress>
+d
+<#if true>
+ <#compress></#compress>
+ <#compress></#compress>
+ <#compress></#compress>
+</#if>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
new file mode 100644
index 0000000..eefa5b1
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ast
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+#outputformat // o.a.f.c.ASTDirOutputFormat
+ - value: "HTML" // o.a.f.c.ASTExpStringLiteral
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
new file mode 100644
index 0000000..fbdb342
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-nestedignoredchildren.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+<#outputFormat 'HTML'><#outputFormat 'HTML'><#outputFormat 'HTML'></#outputFormat></#outputFormat></#outputFormat>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
new file mode 100644
index 0000000..831c7dc
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+#mixed_content // o.a.f.c.ASTImplicitParent
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: null // Null
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: ..< // o.a.f.c.ASTExpRange
+ - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: ..< // o.a.f.c.ASTExpRange
+ - left-hand operand: 0 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: ..< // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: ..< // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: * // o.a.f.c.ArithmeticExpression
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "1" // Integer
+ - right-hand operand: * // o.a.f.c.ArithmeticExpression
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "1" // Integer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: ?abs // o.a.f.c.BuiltInsForNumbers$absBI
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: "abs" // String
+ - right-hand operand: ?abs // o.a.f.c.BuiltInsForNumbers$absBI
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: "abs" // String
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
+ - callee: ?index_of // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: "index_of" // String
+ - argument value: "x" // o.a.f.c.ASTExpStringLiteral
+ - right-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
+ - callee: ?index_of // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: "index_of" // String
+ - argument value: "y" // o.a.f.c.ASTExpStringLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: == // o.a.f.c.ASTExpComparison
+ - left-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: o // o.a.f.c.ASTExpVariable
+ - right-hand operand: p // o.a.f.c.ASTExpVariable
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: == // o.a.f.c.ASTExpComparison
+ - left-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - right-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: o // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: p // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: a // o.a.f.c.ASTExpVariable
+ - right-hand operand: +... // o.a.f.c.ASTExpNegateOrPlus
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "1" // Integer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: a // o.a.f.c.ASTExpVariable
+ - AST-node subtype: "0" // Integer
+ - right-hand operand: -... // o.a.f.c.ASTExpNegateOrPlus
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: ..* // o.a.f.c.ASTExpRange
+ - left-hand operand: * // o.a.f.c.ArithmeticExpression
+ - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: a // o.a.f.c.ASTExpVariable
+ - AST-node subtype: "1" // Integer
+ - right-hand operand: 2 // o.a.f.c.ASTExpNumberLiteral
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: || // o.a.f.c.ASTExpOr
+ - left-hand operand: && // o.a.f.c.ASTExpAnd
+ - left-hand operand: a // o.a.f.c.ASTExpVariable
+ - right-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: b // o.a.f.c.ASTExpVariable
+ - right-hand operand: c // o.a.f.c.ASTExpVariable
+ - right-hand operand: d // o.a.f.c.ASTExpVariable
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #assign // o.a.f.c.ASTDirAssignment
+ - assignment target: "x" // String
+ - assignment operator: "=" // String
+ - assignment source: || // o.a.f.c.ASTExpOr
+ - left-hand operand: && // o.a.f.c.ASTExpAnd
+ - left-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: a // o.a.f.c.ASTExpVariable
+ - right-hand operand: null // Null
+ - right-hand operand: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: b // o.a.f.c.ASTExpVariable
+ - right-hand operand: null // Null
+ - right-hand operand: d // o.a.f.c.ASTExpVariable
+ - variable scope: "1" // Integer
+ - namespace: null // Null
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n" // String
+ ${...} // o.a.f.c.ASTDollarInterpolation
+ - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - callee: f // o.a.f.c.ASTExpVariable
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: null // Null
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - right-hand operand: null // Null
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ #text // o.a.f.c.ASTStaticText
+ - content: "\n\n" // String
+ @ // o.a.f.c.ASTDirUserDefined
+ - callee: m // o.a.f.c.ASTExpVariable
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: * // o.a.f.c.ArithmeticExpression
+ - left-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: m // o.a.f.c.ASTExpVariable
+ - AST-node subtype: "1" // Integer
+ - right-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: + // o.a.f.c.ASTExpAddOrConcat
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - right-hand operand: - // o.a.f.c.ArithmeticExpression
+ - left-hand operand: n // o.a.f.c.ASTExpVariable
+ - right-hand operand: 1 // o.a.f.c.ASTExpNumberLiteral
+ - AST-node subtype: "0" // Integer
+ - argument value: .. // o.a.f.c.ASTExpRange
+ - left-hand operand: m // o.a.f.c.ASTExpVariable
+ - right-hand operand: null // Null
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ftl
new file mode 100644
index 0000000..cb55c8a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<#assign x = 0..>
+
+<#assign x = 0..1>
+<#assign x = 0..<1>
+<#assign x = 0..!1>
+
+<#assign x = n + 1 .. m + 2>
+<#assign x = n + 1 ..< m + 2>
+<#assign x = n + 1 ..! m + 2>
+
+<#assign x = n * 1 .. m * 2>
+
+<#assign x = n?abs .. m?abs>
+
+<#assign x = n?index_of('x') .. m?index_of('y')>
+
+<#assign x = n..m == o..p>
+
+<#assign x = n+1+2..m-1-2 == o+1+2..p-1-2>
+
+<#assign x = 1+a..+2>
+<#assign x = 1-a..-2>
+<#assign x = 1*a..*2>
+<#assign x = a && b..c || d>
+<#assign x = a.. && b.. || d>
+
+${f(m.., m-1.., m+1..n-1)}
+
+<@m 1 * m .. m - 1 m + 1 .. n - 1 m .. />
[28/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-ns_prefix-scope.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-ns_prefix-scope.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-ns_prefix-scope.txt
new file mode 100644
index 0000000..bf8e6bd
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml-ns_prefix-scope.txt
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+//e: e in NS namespace-test, e in NS namespace-test
+//n:e: e in NS foo, e in NS foo
+//bar:e: e in NS bar, e in NS bar
+
+Included:
+//n:e: e in NS foo, e in NS foo
+//n:e: e in NS foo, e in NS foo
+
+Imported:
+//n:e: e in NS bar, e in NS bar
+//n:e: e in NS bar, e in NS bar
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml.txt
new file mode 100644
index 0000000..718bba1
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xml.txt
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+ <?firstPi customKey="something"?>
+ firstPi
+ customKey="something"
+ <?secondPi secondPiData?>
+ secondPi
+ secondPiData
+2
+p
+ customKey="something"
+
+<ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text1</ns1:e11><ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text2</ns1:e11>
+<ns1:e12 xmlns:ns1="http://www.foo.com/ns1/"><![CDATA[cdata-section1]]></ns1:e12><ns1:e12 xmlns:ns1="http://www.foo.com/ns1/"><![CDATA[cdata-section2<&]]></ns1:e12>
+<ns1:e1 xmlns:ns1="http://www.foo.com/ns1/" a1="v1" a2="v2">
+ <ns1:e11>text1</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section1]]></ns1:e12>
+ </ns1:e1>
+<ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text1</ns1:e11><ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text2</ns1:e11>
+a1
+v2
+rootroot
+root
+ root
+ e1
+ e11
+ e12
+ e2
+ e11
+ e12
+ root
+ root
+ e1
+ root
+ e1
+ e11
+ root
+ e1
+ e12
+ root
+ e2
+ root
+ e2
+ e11
+ root
+ e2
+ e12
+cdata-section2<&
+cdata-section2<&
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns1.txt
new file mode 100644
index 0000000..69af553
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns1.txt
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+<book xmlns="http://example.com/eBook">
+ <title>Test Book</title>
+ <chapter>
+ <title>Ch1</title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <chapter>
+ <title>Ch2</title>
+ <para>p2.1</para>
+ <para>p2.2</para>
+ </chapter>
+</book>
+
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns3.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns3.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns3.txt
new file mode 100644
index 0000000..f028f0a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns3.txt
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns4.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns4.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns4.txt
new file mode 100644
index 0000000..f028f0a
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns4.txt
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns5.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns5.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns5.txt
new file mode 100644
index 0000000..6e42b09
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/expected/xmlns5.txt
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+No NS = No NS
+x NS = x NS
+y NS = y NS
+x NS = x NS
+No NS = No NS
+- = -
+- = -
+- = -
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
new file mode 100644
index 0000000..609e20b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
@@ -0,0 +1,19 @@
+# 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.
+
+message=Message
+format={0,date,yyyy-MM-dd}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/defaultxmlns1.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/defaultxmlns1.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/defaultxmlns1.xml
new file mode 100644
index 0000000..ed289bb
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/defaultxmlns1.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+-->
+<root xmlns:x="http://x.com" xmlns:y="http://y.com">
+ <t1>No NS</t1>
+ <x:t2>x NS</x:t2>
+ <y:t3>y NS</y:t3>
+ <t4 xmlns="http://x.com">x NS</t4>
+</root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml-ns_prefix-scope.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml-ns_prefix-scope.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml-ns_prefix-scope.xml
new file mode 100644
index 0000000..934acac
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml-ns_prefix-scope.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<root xmlns="http://freemarker.org/test/namespace-test"
+ xmlns:foo="http://freemarker.org/test/foo"
+ xmlns:bar="http://freemarker.org/test/bar">
+ <e>e in NS namespace-test</e>
+ <foo:e>e in NS foo</foo:e>
+ <bar:e>e in NS bar</bar:e>
+</root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml.xml
new file mode 100644
index 0000000..abf7e96
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xml.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<?firstPi customKey="something"?>
+<?secondPi secondPiData?>
+<ns1:root xmlns:ns1="http://www.foo.com/ns1/">
+ <ns1:e1 a1="v1" a2="v2">
+ <ns1:e11>text1</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section1]]></ns1:e12>
+ </ns1:e1>
+ <ns1:e2>
+ <ns1:e11>text2</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section2<&]]></ns1:e12>
+ </ns1:e2>
+</ns1:root>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlfragment.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlfragment.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlfragment.xml
new file mode 100644
index 0000000..b5578b6
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlfragment.xml
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<root><a><b><c xmlns="http://x">C<>&"']]></c></b></a></root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns.xml
new file mode 100644
index 0000000..6f6453e
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+-->
+<book xmlns="http://example.com/eBook">
+ <title>Test Book</title>
+ <chapter>
+ <title>Ch1</title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <chapter>
+ <title>Ch2</title>
+ <para>p2.1</para>
+ <para>p2.2</para>
+ </chapter>
+</book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns2.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns2.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns2.xml
new file mode 100644
index 0000000..c8bfc9f
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns2.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+-->
+<eb:book xmlns:eb="http://example.com/eBook">
+ <eb:title>Test Book</eb:title>
+ <eb:chapter>
+ <eb:title>Ch1</eb:title>
+ <eb:para>p1.1</eb:para>
+ <eb:para>p1.2</eb:para>
+ <eb:para>p1.3</eb:para>
+ </eb:chapter>
+ <eb:chapter>
+ <eb:title>Ch2</eb:title>
+ <eb:para>p2.1</eb:para>
+ <eb:para>p2.2</eb:para>
+ </eb:chapter>
+</eb:book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns3.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns3.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns3.xml
new file mode 100644
index 0000000..8502ead
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/models/xmlns3.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+-->
+<book xmlns:x="http://x" xmlns:y="http://y">
+ <x:title>Test Book</x:title>
+ <chapter>
+ <y:title>Ch1</y:title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <x:chapter>
+ <y:title>Ch2</y:title>
+ <x:para>p2.1</x:para>
+ <y:para>p2.2</y:para>
+ </x:chapter>
+</book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/api-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/api-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/api-builtins.ftl
new file mode 100644
index 0000000..5a9e2d7
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/api-builtins.ftl
@@ -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.
+-->
+<@assertEquals expected="b" actual=map?api.get(2?int) />
+<@assertEquals expected=2 actual=list?api.indexOf(3?int) />
+<@assert test=set?api.contains("b") />
+<@assert test=!set?api.contains("d") />
+
+<#assign dump = "">
+<#list map?api.entrySet() as entry>
+ <#assign dump = dump + entry.key + ": " + entry.value>
+ <#if entry_has_next>
+ <#assign dump = dump + ", ">
+ </#if>
+</#list>
+<@assertEquals expected="1: a, 2: b, 3: c" actual=dump />
+
+<@assert test=map?has_api />
+<@assert test=list?has_api />
+<@assert test=set?has_api />
+<@assert test=!s?has_api />
+<@assert test=!1?has_api />
+<@assert test=!""?has_api />
+<@assert test=!{}?has_api />
+<@assert test=!true?has_api />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/arithmetic.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/arithmetic.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/arithmetic.ftl
new file mode 100644
index 0000000..afd4c28
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/arithmetic.ftl
@@ -0,0 +1,50 @@
+[#ftl]
+[#--
+ 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.
+--]
+<html>
+<head>
+<title>FreeMarker: Arithmetic Test</title>
+</head>
+<body>
+[#assign foo = 1234, bar = 23.77]
+
+<p>A simple test follows:</p>
+
+<p>Perform a number assignment:</p>
+
+[#setting locale="en_US"][#assign x = 1.2345, y=2]
+
+#{ x+y ; m2M3}
+#{ y ; m2M3}
+#{ x/y ; m40M40}
+#{y/x}
+#{ y/x ; M4}
+
+<P>Display a number with at least 3 digits after the decimal point</P>
+
+#{foo ; m3}
+
+<p>Now use numbers in assignment</p>
+
+[#assign mynumber = foo + bar [#-- a comment --] ]
+
+#{mynumber}
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/assignments.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/assignments.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/assignments.ftl
new file mode 100644
index 0000000..f9f546d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/assignments.ftl
@@ -0,0 +1,108 @@
+<#--
+ 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.
+-->
+<#assign x = 1>
+<@assertEquals expected=1 actual=x />
+<#assign x = x + 1>
+<@assertEquals expected=2 actual=x />
+<#assign x += 1>
+<@assertEquals expected=3 actual=x />
+<#assign x /= 2>
+<@assertEquals expected=1.5 actual=x />
+<#assign x *= 2>
+<@assertEquals expected=3 actual=x />
+<#assign x %= 2>
+<@assertEquals expected=1 actual=x />
+<#assign x += x x += x x += x>
+<@assertEquals expected=8 actual=x />
+<#assign x += x, x += x, x += x>
+<@assertEquals expected=64 actual=x />
+<#assign x++>
+<@assertEquals expected=65 actual=x />
+<#assign x-->
+<@assertEquals expected=64 actual=x />
+<#assign x--, x--, x--, x++, x -= 60>
+<@assertEquals expected=2 actual=x />
+
+<#assign x = 'a'>
+<#assign x += 1>
+<@assertEquals expected='a1' actual=x />
+
+<#assign x = 1>
+<#assign x += 'a'>
+<@assertEquals expected='1a' actual=x />
+
+<#assign x = [11]>
+<#assign x += [22]>
+<@assertEquals expected=11 actual=x[0] />
+<@assertEquals expected=22 actual=x[1] />
+<@assertEquals expected=2 actual=x?size />
+
+<#assign x = { 'a': 11 }>
+<#assign x += { 'b': 22 }>
+<@assertEquals expected=11 actual=x.a />
+<@assertEquals expected=22 actual=x.b />
+<@assertEquals expected=2 actual=x?size />
+
+<#assign x = 1>
+<#global g = 11>
+<#global g -= x>
+<@assertEquals expected=10 actual=g />
+<#global g *= 2>
+<@assertEquals expected=20 actual=g />
+<#global g /= 2.5>
+<@assertEquals expected=8 actual=g />
+<#global g += 2>
+<@assertEquals expected=10 actual=g />
+<#global g++>
+<@assertEquals expected=11 actual=g />
+<#global g-->
+<@assertEquals expected=10 actual=g />
+
+<#macro m>
+ <#local v = x + g>
+ <@assertEquals expected=11 actual=v />
+ <#local v -= x>
+ <@assertEquals expected=10 actual=v />
+ <#local v *= 2>
+ <@assertEquals expected=20 actual=v />
+ <#local v /= 2.5>
+ <@assertEquals expected=8 actual=v />
+ <#local v += 2>
+ <@assertEquals expected=10 actual=v />
+ <#local v++>
+ <@assertEquals expected=11 actual=v />
+ <#local v-->
+ <@assertEquals expected=10 actual=v />
+</#macro>
+<@m />
+
+<#assign foo = 'a'>
+<@assertFails messageRegexp=r".*expected.*number.*assignment.*foo.*string.*"><#assign foo -= 1></@>
+<@assertFails messageRegexp=r".*expected.*number.*assignment.*foo.*string.*"><#assign foo++></@>
+<@assertFails messageRegexp=r".*expected.*number.*assignment.*foo.*string.*"><#assign foo--></@>
+<#assign x = 1>
+<@assertFails messageRegexp=r"(?s).*expected.*number.*string.*'a'.*"><#assign x -= 'a'></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*-=.*"><#assign noSuchVar -= 1></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*\+=.*"><#assign noSuchVar += 1></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*\*=.*"><#assign noSuchVar *= 1></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*/=.*"><#assign noSuchVar /= 1></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*%=.*"><#assign noSuchVar %= 1></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*\+\+.*"><#assign noSuchVar++></@>
+<@assertFails messageRegexp=r"(?s).*assignment.*noSuchVar.*missing.*--.*"><#assign noSuchVar--></@>
+<@assertFails messageRegexp=r'(?s).*assignment.*noSuchVar.*missing.*\+=.*"\$".*'><#assign $noSuchVar += 1></@>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean-formatting.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean-formatting.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean-formatting.ftl
new file mode 100644
index 0000000..a521fe8
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean-formatting.ftl
@@ -0,0 +1,82 @@
+<#--
+ 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.
+-->
+<#assign suppress>
+<@assertFails message="true,false">${true}</@>
+<@assertFails message="true,false">${false}</@>
+<@assertFails message="true,false">${"" + true}</@>
+<@assertFails message="true,false">${"" + false}</@>
+<@assertFails message="true,false">${true?upper_case}</@>
+<@assertFails message="true,false">${false?upper_case}</@>
+<@assertEquals expected="true" actual=true?string />
+<@assertEquals expected="false" actual=false?string />
+<@assertEquals expected="true" actual=true?c />
+<@assertEquals expected="false" actual=false?c />
+<@assertEquals expected="t" actual=true?string('t', 'f') />
+<@assertEquals expected="f" actual=false?string('t', 'f') />
+<#setting boolean_format = 'true,false'>
+<@assertFails message="true,false">${true}</@>
+
+<#setting boolean_format = 'ja,nein'>
+<@assertEquals expected="ja" actual="" + true />
+<@assertEquals expected="nein" actual="" + false />
+<@assertEquals expected="JA" actual=true?upper_case />
+<@assertEquals expected="NEIN" actual=false?upper_case />
+<@assertEquals expected="ja" actual=true?string />
+<@assertEquals expected="nein" actual=false?string />
+<@assertEquals expected="true" actual=true?c />
+<@assertEquals expected="false" actual=false?c />
+<@assertEquals expected="t" actual=true?string('t', 'f') />
+<@assertEquals expected="f" actual=false?string('t', 'f') />
+
+<#setting boolean_format = 'y,n'>
+<#assign x = false>
+<#assign n = 123><#assign m = { x: 'foo', n: 'bar' }><@assertEquals actual=m['n'] + m['123'] expected='foobar' />
+<@assertFails exception="UnexpectedTypeException">${m[false]}</@>
+<@assertFails message="can't compare">${x == 'false'}</@>
+<@assertFails message="can't compare">${x != 'false'}</@>
+<@assertFails message="can't convert">${booleanVsStringMethods.expectsString(x)}</@>
+<@assertEquals actual=booleanVsStringMethods.expectsString(booleanAndString) expected="theStringValue" />
+<@assertEquals actual=booleanVsStringMethods.expectsBoolean(x) expected=false />
+<@assertEquals actual=booleanVsStringMethods.expectsBoolean(booleanAndString) expected=true />
+<@assertEquals actual=booleanVsStringMethods.overloaded(x) expected="boolean false" />
+<@assertEquals actual=123?upper_case expected="123" />
+<@assertEquals actual=true?upper_case expected="Y" />
+
+</#assign>
+<#escape x as x?upper_case>
+<#assign x = true>${x} ${true} ${true?string}
+<#assign x = false>${x} ${false} ${false?string}
+<#noescape><#assign x = true>${x} ${true} ${true?string}</#noescape>
+</#escape>
+<#assign x = false>${x} ${false} ${false?string}
+<#assign x = true>${x} ${true} ${true?string}
+<#assign x = false>${x} ${false} ${false?string}
+${'str:' + x} ${'str:' + false}
+${x?string('ja', 'nein')} ${true?string('ja', 'nein')}
+${booleanAndString} ${booleanAndString?string}
+
+<#setting boolean_format = 'y,n'>
+<@assertEquals actual='true'?boolean expected=true />
+<@assertEquals actual='false'?boolean expected=false />
+<@assertEquals actual='y'?boolean expected=true />
+<@assertEquals actual='n'?boolean expected=false />
+<@assertFails message="can't convert">${'N'?boolean}</@>
+<@assertFails message="can't convert">${'True'?boolean}</@>
+<@assertFails message="can't convert">${0?boolean}</@>
+<@assertFails message="sequence">${[]?boolean}</@>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean.ftl
new file mode 100644
index 0000000..ab11c64
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/boolean.ftl
@@ -0,0 +1,142 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Boolean Values Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<#assign b=true>
+
+<p>Now perform scalar boolean tests:</p>
+
+<p><#if b>
+ b is true.<br />
+<#else>
+ b is false.<br />
+</#if></p>
+
+<p><#if false>
+ This can't be!<br />
+<#else>
+ This makes sense.<br />
+</#if></p>
+
+<p><#if boolean3>
+ boolean3 succeeded.<br />
+<#else>
+ boolean3 failed.<br />
+</#if></p>
+
+<p><#if boolean4>
+ boolean4 succeeded.<br />
+<#else>
+ boolean4 failed.<br />
+</#if></p>
+
+<p><#if boolean4 || boolean5>
+ boolean4 || boolean5 succeeded.<br />
+<#else>
+ boolean4 || boolean5 failed.<br />
+</#if></p>
+
+<p><#if boolean5 || boolean4 || boolean5>
+ boolean5 || boolean4 || boolean5 succeeded.<br />
+<#else>
+ boolean5 || boolean4 || boolean5 failed.<br />
+</#if></p>
+
+<p><#if boolean4 && boolean5>
+ boolean4 && boolean5 succeeded.<br />
+<#else>
+ boolean4 && boolean5 failed.<br />
+</#if></p>
+
+<p>Now test list models:</p>
+
+<p><#if list1?exists>
+ list1 succeeded.<br />
+<#else>
+ list1 failed.<br />
+</#if></p>
+
+<p><#if list2?exists>
+ list2 succeeded.<br />
+<#else>
+ list2 failed.<br />
+</#if></p>
+
+<p>Test hash models:</p>
+
+<p><#if hash1?exists>
+ hash1 succeeded: ${hash1.temp}<br />
+<#else>
+ hash1 failed: ${hash1.temp}<br />
+</#if></p>
+
+<p><#if hash2?exists>
+ hash2 succeeded.<br />
+<#else>
+ hash2 failed.<br />
+</#if></p>
+
+<p>Test not operator:</p>
+
+<p><#if ! boolean1>
+ Not boolean1 succeeded
+<#else>
+ Not boolean1 failed
+</#if></p>
+
+<p><#if !boolean1>
+ Not boolean1 succeeded
+<#else>
+ Not boolean1 failed
+</#if></p>
+
+<p><#if ! boolean2>
+ Not boolean2 succeeded
+<#else>
+ Not boolean2 failed
+</#if></p>
+
+<p><#if !boolean2>
+ Not boolean2 succeeded
+<#else>
+ Not boolean2 failed
+</#if></p>
+
+<p><#if message == "Hello, world!">
+ Message is "Hello, world!"
+<#else>
+ Message is something else (${message})
+</#if></p>
+
+<p><#if message != "Hello, world!">
+ Message is not "Hello, world!" -- it's ${message}
+<#else>
+ Message is "Hello, world!"
+</#if></p>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header.ftl
new file mode 100644
index 0000000..638f4b9
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header.ftl
@@ -0,0 +1,27 @@
+<#ftl encoding="ISO-8859-2">
+<#--
+ 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.
+-->
+<head>
+ <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
+</head>
+<body>
+����
+<#include "charset-in-header_inc1.ftl">
+<#include "charset-in-header_inc2.ftl">
+</body>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc1.ftl
new file mode 100644
index 0000000..b8dc608
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc1.ftl
@@ -0,0 +1,20 @@
+<#ftl encoding="ISO-8859-1">
+<#--
+ 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.
+-->
+����
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc2.ftl
new file mode 100644
index 0000000..66100ec
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/charset-in-header_inc2.ftl
@@ -0,0 +1,19 @@
+<#--
+ 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.
+-->
+őŐűŰ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comment.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comment.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comment.ftl
new file mode 100644
index 0000000..9c47168
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comment.ftl
@@ -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.
+-->
+<html>
+<head>
+<title>FreeMarker: Comment Test</title>
+</head>
+<body>
+<#--
+
+A simple test follows:
+
+${message}
+
+A more rigorous test, showing that we're not faking it:
+
+${message@#$%&}
+
+--><#-- > --><#-- -> --><#-- -- --><#-- -- > -->
+<#if message?exists>
+ <p>Message exists!
+ <#--
+ ...and even generates output!
+ -->
+ </p>
+</#if>
+
+a <#-- < --> b
+a <#-- </#noparse> - -- --> b
+
+${1 + 2 + [#-- c --] <#-- c --> <!-- c --> 3}
+${<!-- > -> -- #> #] --> 7}
+${<#-- glitch... --] 8}
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comparisons.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comparisons.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comparisons.ftl
new file mode 100644
index 0000000..a711d4d
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/comparisons.ftl
@@ -0,0 +1,218 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Numeric Operations Test</title>
+</head>
+<body>
+
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<p>Start with the increment operator:</p>
+<#assign a1 = 0>
+<p>a1 = ${a1}</p>
+<#assign a1 = a1 + 1>
+<p>a1 = ${a1}</p>
+<#assign a1 = a1 + 1>
+<p>a1 = ${a1}</p>
+
+<p>Now the decrement operator:</p>
+<#assign a2 = 5>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+<p>a2 = ${a2}</p>
+<#assign a2 = a2 - 1>
+
+<p>Now the add operator:</p>
+<#assign op1 = 5>
+<#assign op2 = 3>
+<#assign op3 = op1 + op2>
+<p>op1 = ${op1}, op2 = ${op2}, op3 = ${op3}</p>
+<#assign op3 = op3 + op2>
+<p>op3 = ${op3}</p>
+
+<p>And the subtract operator:</p>
+<#assign op3 = op1 - op2 >
+<p>op1 = ${op1}, op2 = ${op2}, op3 = ${op3}</p>
+<#assign op3 = op3 - op2 >
+<p>op3 = ${op3}</p>
+
+<p>The comparison operators:</p>
+<#assign list1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]>
+<#list list1 as item>
+ <p>Item is: ${item}</p>
+ <#if item lt 5>
+ <p>Item is less than five.</p>
+ </#if>
+ <#if item <= 7>
+ <p>Item is less than or equals to seven.</p>
+ </#if>
+ <#if item gt 2>
+ <p>Item is greater than two.</p>
+ </#if>
+ <#if (item >= 10)>
+ <p>Item is greater than or equal to ten.</p>
+ </#if>
+</#list>
+
+<#-- Signum-based optimization test, all 9 permutations: -->
+<#-- 1 -->
+<@assert test= !(0 != 0) />
+<@assert test= (0 == 0) />
+<@assert test= !(0 > 0) />
+<@assert test= (0 >= 0) />
+<@assert test= !(0 < 0) />
+<@assert test= (0 <= 0) />
+<#-- 2 -->
+<@assert test= !(3 != 3) />
+<@assert test= (3 == 3) />
+<@assert test= !(3 > 3) />
+<@assert test= (3 >= 3) />
+<@assert test= !(3 < 3) />
+<@assert test= (3 <= 3) />
+<#-- 3 -->
+<@assert test= !(-3 != -3) />
+<@assert test= (-3 == -3) />
+<@assert test= !(-3 > -3) />
+<@assert test= (-3 >= -3) />
+<@assert test= !(-3 < -3) />
+<@assert test= (-3 <= -3) />
+<#-- 4 -->
+<@assert test= (3 != 0) />
+<@assert test= !(3 == 0) />
+<@assert test= (3 > 0) />
+<@assert test= (3 >= 0) />
+<@assert test= !(3 < 0) />
+<@assert test= !(3 <= 0) />
+<#-- 5 -->
+<@assert test= (0 != 3) />
+<@assert test= !(0 == 3) />
+<@assert test= !(0 > 3) />
+<@assert test= !(0 >= 3) />
+<@assert test= (0 < 3) />
+<@assert test= (0 <= 3) />
+<#-- 6 -->
+<@assert test= (-3 != 0) />
+<@assert test= !(-3 == 0) />
+<@assert test= !(-3 > 0) />
+<@assert test= !(-3 >= 0) />
+<@assert test= (-3 < 0) />
+<@assert test= (-3 <= 0) />
+<#-- 7 -->
+<@assert test= (0 != -3) />
+<@assert test= !(0 == -3) />
+<@assert test= (0 > -3) />
+<@assert test= (0 >= -3) />
+<@assert test= !(0 < -3) />
+<@assert test= !(0 <= -3) />
+<#-- 8 -->
+<@assert test= (-3 != 3) />
+<@assert test= !(-3 == 3) />
+<@assert test= !(-3 > 3) />
+<@assert test= !(-3 >= 3) />
+<@assert test= (-3 < 3) />
+<@assert test= (-3 <= 3) />
+<#-- 9 -->
+<@assert test= (3 != -3) />
+<@assert test= !(3 == -3) />
+<@assert test= (3 > -3) />
+<@assert test= (3 >= -3) />
+<@assert test= !(3 < -3) />
+<@assert test= !(3 <= -3) />
+<#-- Again, now on runtime: -->
+<#assign m3 = -3>
+<#assign p3 = 3>
+<#assign z = 0>
+<#-- 1 -->
+<@assert test= !(z != z) />
+<@assert test= (z == z) />
+<@assert test= !(z > z) />
+<@assert test= (z >= z) />
+<@assert test= !(z < z) />
+<@assert test= (z <= z) />
+<#-- 2 -->
+<@assert test= !(p3 != p3) />
+<@assert test= (p3 == p3) />
+<@assert test= !(p3 > p3) />
+<@assert test= (p3 >= p3) />
+<@assert test= !(p3 < p3) />
+<@assert test= (p3 <= p3) />
+<#-- 3 -->
+<@assert test= !(m3 != m3) />
+<@assert test= (m3 == m3) />
+<@assert test= !(m3 > m3) />
+<@assert test= (m3 >= m3) />
+<@assert test= !(m3 < m3) />
+<@assert test= (m3 <= m3) />
+<#-- 4 -->
+<@assert test= (p3 != z) />
+<@assert test= !(p3 == z) />
+<@assert test= (p3 > z) />
+<@assert test= (p3 >= z) />
+<@assert test= !(p3 < z) />
+<@assert test= !(p3 <= z) />
+<#-- 5 -->
+<@assert test= (z != p3) />
+<@assert test= !(z == p3) />
+<@assert test= !(z > p3) />
+<@assert test= !(z >= p3) />
+<@assert test= (z < p3) />
+<@assert test= (z <= p3) />
+<#-- 6 -->
+<@assert test= (m3 != z) />
+<@assert test= !(m3 == z) />
+<@assert test= !(m3 > z) />
+<@assert test= !(m3 >= z) />
+<@assert test= (m3 < z) />
+<@assert test= (m3 <= z) />
+<#-- 7 -->
+<@assert test= (z != m3) />
+<@assert test= !(z == m3) />
+<@assert test= (z > m3) />
+<@assert test= (z >= m3) />
+<@assert test= !(z < m3) />
+<@assert test= !(z <= m3) />
+<#-- 8 -->
+<@assert test= (m3 != p3) />
+<@assert test= !(m3 == p3) />
+<@assert test= !(m3 > p3) />
+<@assert test= !(m3 >= p3) />
+<@assert test= (m3 < p3) />
+<@assert test= (m3 <= p3) />
+<#-- 9 -->
+<@assert test= (p3 != m3) />
+<@assert test= !(p3 == m3) />
+<@assert test= (p3 > m3) />
+<@assert test= (p3 >= m3) />
+<@assert test= !(p3 < m3) />
+<@assert test= !(p3 <= m3) />
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/compress.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/compress.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/compress.ftl
new file mode 100644
index 0000000..faf4ad6
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/compress.ftl
@@ -0,0 +1,59 @@
+<#--
+ 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.
+-->
+<html>
+<head>
+<title>FreeMarker: Compress Test</title>
+</head>
+<body>
+
+<#assign utility={'standardCompress': "org.apache.freemarker.core.util.StandardCompress"?new()}>
+<p>A simple test follows:</p>
+
+<p>${message}</p>
+
+<#compress>
+
+ <p>This is the same message, using the "compress" tag:</p>
+
+
+<p>${message}</p>
+</#compress>
+
+<@utility.standardCompress buffer_size=8>
+
+ <p>This is the same message, using the "StandardCompress" transform model:</p>
+
+
+<p>${message}</p>
+</@>
+
+<@utility.standardCompress single_line=true>
+
+<p>This
+ multi-line message
+ should
+be compressed
+ to a single line.</p></@>
+
+<p>An example where the first character is not whitespace but the second character is:</p>
+<p><#compress>x y</#compress></p>
+
+<p>The end.</p>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/date-type-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/date-type-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/date-type-builtins.ftl
new file mode 100644
index 0000000..f05654b
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/date-type-builtins.ftl
@@ -0,0 +1,47 @@
+<#--
+ 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.
+-->
+<#setting time_zone = "UTC">
+
+<@assert test=unknown?is_unknown_date_like />
+<@assert test=!timeOnly?is_unknown_date_like />
+<@assert test=!dateOnly?is_unknown_date_like />
+<@assert test=!dateTime?is_unknown_date_like />
+
+<@assert test=!unknown?is_date_only />
+<@assert test=!timeOnly?is_date_only />
+<@assert test=dateOnly?is_date_only />
+<@assert test=!dateTime?is_date_only />
+
+<@assert test=!unknown?is_time />
+<@assert test=timeOnly?is_time />
+<@assert test=!dateOnly?is_time />
+<@assert test=!dateTime?is_time />
+
+<@assert test=!unknown?is_datetime />
+<@assert test=!timeOnly?is_datetime />
+<@assert test=!dateOnly?is_datetime />
+<@assert test=dateTime?is_datetime />
+
+<@assertFails message="isn't known if">${unknown?string.xs}</@>
+<@assertEquals expected="2003-04-05T06:07:08Z" actual=unknown?datetime_if_unknown?string.xs />
+<@assertEquals expected="2003-04-05Z" actual=unknown?date_if_unknown?string.xs />
+<@assertEquals expected="06:07:08Z" actual=unknown?time_if_unknown?string.xs />
+<@assertEquals expected="2003-04-05T06:07:08Z" actual=dateTime?date_if_unknown?string.xs />
+<@assertEquals expected="2003-04-05" actual=dateOnly?time_if_unknown?string.xs />
+<@assertEquals expected="06:07:08" actual=timeOnly?date_if_unknown?string.xs />
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-bi.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-bi.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-bi.ftl
new file mode 100644
index 0000000..85fb028
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-bi.ftl
@@ -0,0 +1,163 @@
+<#--
+ 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.
+-->
+<#assign d = "2010-05-15 22:38:05:23 +0200"?datetime("yyyy-MM-dd HH:mm:ss:S Z")>
+<#setting time_zone="GMT+02">
+<@assertEquals actual=d?iso_utc expected="2010-05-15T20:38:05Z" />
+<@assertEquals actual=d?iso_utc_ms expected="2010-05-15T20:38:05.023Z" />
+<@assertEquals actual=d?iso_utc_m expected="2010-05-15T20:38Z" />
+<@assertEquals actual=d?iso_utc_h expected="2010-05-15T20Z" />
+<@assertEquals actual=d?iso_utc_nz expected="2010-05-15T20:38:05" />
+<@assertEquals actual=d?iso_utc_ms_nz expected="2010-05-15T20:38:05.023" />
+<@assertEquals actual=d?iso_utc_m_nz expected="2010-05-15T20:38" />
+<@assertEquals actual=d?iso_utc_h_nz expected="2010-05-15T20" />
+<@assertEquals actual=d?iso_local expected="2010-05-15T22:38:05+02:00" />
+<@assertEquals actual=d?iso_local_ms expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?iso_local_m expected="2010-05-15T22:38+02:00" />
+<@assertEquals actual=d?iso_local_h expected="2010-05-15T22+02:00" />
+<@assertEquals actual=d?iso_local_nz expected="2010-05-15T22:38:05" />
+<@assertEquals actual=d?iso_local_ms_nz expected="2010-05-15T22:38:05.023" />
+<@assertEquals actual=d?iso_local_m_nz expected="2010-05-15T22:38" />
+<@assertEquals actual=d?iso_local_h_nz expected="2010-05-15T22" />
+
+<@assertEquals actual=d?date?iso_utc expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_ms expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_m expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_h expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_ms_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_m_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_utc_h_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_ms expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_m expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_h expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_ms_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_m_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_local_h_nz expected="2010-05-15" />
+
+<@assertEquals actual=d?time?iso_utc expected="20:38:05Z" />
+<@assertEquals actual=d?time?iso_utc_ms expected="20:38:05.023Z" />
+<@assertEquals actual=d?time?iso_utc_m expected="20:38Z" />
+<@assertEquals actual=d?time?iso_utc_h expected="20Z" />
+<@assertEquals actual=d?time?iso_utc_nz expected="20:38:05" />
+<@assertEquals actual=d?time?iso_utc_ms_nz expected="20:38:05.023" />
+<@assertEquals actual=d?time?iso_utc_m_nz expected="20:38" />
+<@assertEquals actual=d?time?iso_utc_h_nz expected="20" />
+<@assertEquals actual=d?time?iso_local expected="22:38:05+02:00" />
+<@assertEquals actual=d?time?iso_local_ms expected="22:38:05.023+02:00" />
+<@assertEquals actual=d?time?iso_local_m expected="22:38+02:00" />
+<@assertEquals actual=d?time?iso_local_h expected="22+02:00" />
+<@assertEquals actual=d?time?iso_local_nz expected="22:38:05" />
+<@assertEquals actual=d?time?iso_local_ms_nz expected="22:38:05.023" />
+<@assertEquals actual=d?time?iso_local_m_nz expected="22:38" />
+<@assertEquals actual=d?time?iso_local_h_nz expected="22" />
+
+<#assign dStrange = "600-01-01 23:59:59:123 +0000"?datetime("yyyy-MM-dd HH:mm:ss:S Z")>
+<@assertEquals actual=dStrange?iso_utc_ms expected="0600-01-03T23:59:59.123Z" />
+
+<#-- java.sql treatment -->
+<@assertEquals actual=sqlDate?iso_local expected="2010-05-15" />
+<@assertEquals actual=sqlDate?iso_local_nz expected="2010-05-15" />
+<@assertEquals actual=sqlTime?iso_local_nz expected="22:38:05" />
+<@assertEquals actual=sqlTime?iso_utc_nz expected="20:38:05" />
+
+<#setting time_zone="GMT+03"> <#-- should not mater -->
+<@assertEquals actual=d?iso("UTC") expected="2010-05-15T20:38:05Z" />
+<@assertEquals actual=d?iso_ms("UTC") expected="2010-05-15T20:38:05.023Z" />
+<@assertEquals actual=d?iso_m("UTC") expected="2010-05-15T20:38Z" />
+<@assertEquals actual=d?iso_h("UTC") expected="2010-05-15T20Z" />
+<@assertEquals actual=d?iso_nz("UTC") expected="2010-05-15T20:38:05" />
+<@assertEquals actual=d?iso_ms_nz("UTC") expected="2010-05-15T20:38:05.023" />
+<@assertEquals actual=d?iso_m_nz("UTC") expected="2010-05-15T20:38" />
+<@assertEquals actual=d?iso_h_nz("UTC") expected="2010-05-15T20" />
+<@assertEquals actual=d?iso("GMT+02") expected="2010-05-15T22:38:05+02:00" />
+<@assertEquals actual=d?iso_ms("GMT+02") expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?iso_m("GMT+02") expected="2010-05-15T22:38+02:00" />
+<@assertEquals actual=d?iso_h("GMT+02") expected="2010-05-15T22+02:00" />
+<@assertEquals actual=d?iso_nz("GMT+02") expected="2010-05-15T22:38:05" />
+<@assertEquals actual=d?iso_ms_nz("GMT+02") expected="2010-05-15T22:38:05.023" />
+<@assertEquals actual=d?iso_m_nz("GMT+02") expected="2010-05-15T22:38" />
+<@assertEquals actual=d?iso_h_nz("GMT+02") expected="2010-05-15T22" />
+
+<@assertEquals actual=d?date?iso("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_ms("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_m("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_h("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_nz("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_ms_nz("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_m_nz("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_h_nz("UTC") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_ms("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_m("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_h("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_nz("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_ms_nz("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_m_nz("GMT+02") expected="2010-05-15" />
+<@assertEquals actual=d?date?iso_h_nz("GMT+02") expected="2010-05-15" />
+
+<@assertEquals actual=d?time?iso("UTC") expected="20:38:05Z" />
+<@assertEquals actual=d?time?iso_ms("UTC") expected="20:38:05.023Z" />
+<@assertEquals actual=d?time?iso_m("UTC") expected="20:38Z" />
+<@assertEquals actual=d?time?iso_h("UTC") expected="20Z" />
+<@assertEquals actual=d?time?iso_nz("UTC") expected="20:38:05" />
+<@assertEquals actual=d?time?iso_ms_nz("UTC") expected="20:38:05.023" />
+<@assertEquals actual=d?time?iso_m_nz("UTC") expected="20:38" />
+<@assertEquals actual=d?time?iso_h_nz("UTC") expected="20" />
+<@assertEquals actual=d?time?iso("GMT+02") expected="22:38:05+02:00" />
+<@assertEquals actual=d?time?iso_ms("GMT+02") expected="22:38:05.023+02:00" />
+<@assertEquals actual=d?time?iso_m("GMT+02") expected="22:38+02:00" />
+<@assertEquals actual=d?time?iso_h("GMT+02") expected="22+02:00" />
+<@assertEquals actual=d?time?iso_nz("GMT+02") expected="22:38:05" />
+<@assertEquals actual=d?time?iso_ms_nz("GMT+02") expected="22:38:05.023" />
+<@assertEquals actual=d?time?iso_m_nz("GMT+02") expected="22:38" />
+<@assertEquals actual=d?time?iso_h_nz("GMT+02") expected="22" />
+
+<@assertEquals actual=d?iso(javaUTC) expected="2010-05-15T20:38:05Z" />
+<@assertEquals actual=d?iso(javaGMT02) expected="2010-05-15T22:38:05+02:00" />
+<@assertEquals actual=d?iso(adaptedToStringScalar) expected="2010-05-15T22:38:05+02:00" />
+
+<#assign d = "12:00:00:1 +0000"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?iso_utc_ms expected="12:00:00.001Z" />
+<#assign d = "12:00:00:10 +0000"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?iso_utc_ms expected="12:00:00.01Z" />
+<#assign d = "12:00:00:100 +0000"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?iso_utc_ms expected="12:00:00.1Z" />
+<#assign d = "12:00:00:0 +0000"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?iso_utc_ms expected="12:00:00Z" />
+
+<#setting time_zone="GMT+02">
+<#assign d = "2010-05-15"?date("yyyy-MM-dd")>
+<@assertEquals actual=d?iso_local expected="2010-05-15" />
+<@assertEquals actual=d?iso_utc expected="2010-05-14" />
+
+<#setting time_zone="GMT+02:30">
+<#assign d = "2010-05-15"?datetime("yyyy-MM-dd")>
+<@assertEquals actual=d?iso_local expected="2010-05-15T00:00:00+02:30" />
+
+<#setting time_zone="America/New_York">
+<@assertEquals actual="2010-05-09 20:00 +0000"?datetime("yyyy-MM-dd HH:mm Z")?iso_local expected="2010-05-09T16:00:00-04:00" />
+<@assertEquals actual="2010-01-01 20:00 +0000"?datetime("yyyy-MM-dd HH:mm Z")?iso_local expected="2010-01-01T15:00:00-05:00" />
+
+<@assertFails>${d?iso("no such zone")}</@>
+
+<#setting time_zone="GMT+02">
+<@assertEquals actual=sqlTime?iso_local expected="22:38:05" />
+<@assertEquals actual=sqlTime?iso_utc expected="20:38:05" />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-like.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-like.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-like.ftl
new file mode 100644
index 0000000..a5accaf
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-iso-like.ftl
@@ -0,0 +1,155 @@
+<#--
+ 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.
+-->
+<#assign d = "2010-05-15 22:38:05:23 +0200"?datetime("yyyy-MM-dd HH:mm:ss:S Z")>
+<#setting time_zone="GMT+02">
+<@assertEquals actual=d?string.xs expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string.iso expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string('xs') expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string('iso') expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string.xs_nz expected="2010-05-15T22:38:05.023" />
+<@assertEquals actual=d?string.iso_nz expected="2010-05-15T22:38:05.023" />
+<@assertEquals actual=d?string.xs_fz expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string.iso_fz expected="2010-05-15T22:38:05.023+02:00" />
+<@assertEquals actual=d?string.xs_u expected="2010-05-15T20:38:05.023Z" />
+<@assertEquals actual=d?string.iso_u expected="2010-05-15T20:38:05.023Z" />
+<@assertEquals actual=d?string.xs_s_u expected="2010-05-15T20:38:05Z" />
+<@assertEquals actual=d?string.iso_s_u expected="2010-05-15T20:38:05Z" />
+
+<@assertEquals actual=d?date?string.xs expected="2010-05-15+02:00" />
+<@assertEquals actual=d?date?string.iso expected="2010-05-15" />
+<@assertEquals actual=d?date?string.xs_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?string.iso_nz expected="2010-05-15" />
+<@assertEquals actual=d?date?string.xs_fz expected="2010-05-15+02:00" />
+<@assertEquals actual=d?date?string.iso_fz expected="2010-05-15" />
+
+<@assertEquals actual=d?time?string.xs expected="22:38:05.023+02:00" />
+<@assertEquals actual=d?time?string.iso expected="22:38:05.023+02:00" />
+<@assertEquals actual=d?time?string.xs_nz expected="22:38:05.023" />
+<@assertEquals actual=d?time?string.iso_nz expected="22:38:05.023" />
+<@assertEquals actual=d?time?string.xs_fz expected="22:38:05.023+02:00" />
+<@assertEquals actual=d?time?string.iso_fz expected="22:38:05.023+02:00" />
+
+<#-- java.sql treatment -->
+<@assertEquals actual=sqlDate?string.xs expected="2010-05-15" />
+<@assertEquals actual=sqlDate?string.iso expected="2010-05-15" />
+<@assertEquals actual=sqlDate?string.xs_fz expected="2010-05-15+02:00" />
+<@assertEquals actual=sqlDate?string.iso_fz expected="2010-05-15" />
+<@assertEquals actual=sqlDate?string.xs_nz expected="2010-05-15" />
+<@assertEquals actual=sqlDate?string.iso_nz expected="2010-05-15" />
+<@assertEquals actual=sqlTime?string.xs expected="22:38:05.023" />
+<@assertEquals actual=sqlTime?string.iso expected="22:38:05.023" />
+<@assertEquals actual=sqlTime?string.xs_fz expected="22:38:05.023+02:00" />
+<@assertEquals actual=sqlTime?string.iso_fz expected="22:38:05.023+02:00" />
+<@assertEquals actual=sqlTime?string.xs_nz expected="22:38:05.023" />
+<@assertEquals actual=sqlTime?string.iso_nz expected="22:38:05.023" />
+
+<#assign d = "12:30:15:1 +0200"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?string.xs expected="12:30:15.001+02:00" />
+<@assertEquals actual=d?string.iso expected="12:30:15.001+02:00" />
+<@assertEquals actual=d?string.xs_ms expected="12:30:15.001+02:00" />
+<@assertEquals actual=d?string.iso_ms expected="12:30:15.001+02:00" />
+<@assertEquals actual=d?string.iso_s expected="12:30:15+02:00" />
+<@assertEquals actual=d?string.iso_m expected="12:30+02:00" />
+<@assertEquals actual=d?string.iso_h expected="12+02:00" />
+<#assign d = "12:30:15:10 +0200"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?string.xs expected="12:30:15.01+02:00" />
+<@assertEquals actual=d?string.iso expected="12:30:15.01+02:00" />
+<@assertEquals actual=d?string.xs_ms expected="12:30:15.010+02:00" />
+<@assertEquals actual=d?string.iso_ms expected="12:30:15.010+02:00" />
+<#assign d = "12:30:15:100 +0200"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?string.xs expected="12:30:15.1+02:00" />
+<@assertEquals actual=d?string.iso expected="12:30:15.1+02:00" />
+<@assertEquals actual=d?string.xs_ms expected="12:30:15.100+02:00" />
+<@assertEquals actual=d?string.iso_ms expected="12:30:15.100+02:00" />
+<#assign d = "12:30:15:0 +0200"?time("HH:mm:ss:S Z")>
+<@assertEquals actual=d?string.xs expected="12:30:15+02:00" />
+<@assertEquals actual=d?string.iso expected="12:30:15+02:00" />
+<@assertEquals actual=d?string.xs_ms expected="12:30:15.000+02:00" />
+<@assertEquals actual=d?string.iso_ms expected="12:30:15.000+02:00" />
+
+<#setting time_zone="GMT+02">
+<#assign d = "2010-05-15"?date("yyyy-MM-dd")>
+<@assertEquals actual=d?string.xs expected="2010-05-15+02:00" />
+<@assertEquals actual=d?string.iso expected="2010-05-15" />
+<#setting time_zone="GMT+00">
+<@assertEquals actual=d?string.xs expected="2010-05-14Z" />
+<@assertEquals actual=d?string.iso expected="2010-05-14" />
+
+<#setting time_zone="GMT+02:30">
+<#assign d = "2010-05-15"?datetime("yyyy-MM-dd")>
+<@assertEquals actual=d?string.xs expected="2010-05-15T00:00:00+02:30" />
+<@assertEquals actual=d?string.iso expected="2010-05-15T00:00:00+02:30" />
+
+<#setting time_zone="GMT-05">
+<#setting locale = "en_US">
+<#assign d = "BC 0001-05-15"?date("G yyyy-MM-dd")>
+<#-- Tests that: (a) BC 1 isn't 0 like in ISO 8601; (b) No Julian calendar is used. -->
+<@assertEquals actual=d?string.xs expected="-1-05-13-05:00" />
+<@assertEquals actual=d?string.iso expected="0000-05-13" />
+
+<#assign dt = "2010-05-15T01:02:03"?datetime.xs>
+<#setting datetime_format="xs">
+<@assertEquals actual=dt?string expected="2010-05-15T01:02:03-05:00" />
+<#setting datetime_format="xs u">
+<@assertEquals actual=dt?string expected="2010-05-15T06:02:03Z" />
+<#setting datetime_format="iso u">
+<@assertEquals actual=dt?string expected="2010-05-15T06:02:03Z" />
+<#setting datetime_format="xs fz">
+<@assertEquals actual=dt?string expected="2010-05-15T01:02:03-05:00" />
+<#setting datetime_format="xs fz u">
+<@assertEquals actual=dt?string expected="2010-05-15T06:02:03Z" />
+<#setting datetime_format="xs nz u">
+<@assertEquals actual=dt?string expected="2010-05-15T06:02:03" />
+<#setting datetime_format="iso m nz">
+<@assertEquals actual=dt?string expected="2010-05-15T01:02" />
+
+<#assign d = dt?date>
+<#setting date_format="xs">
+<@assertEquals actual=d?string expected="2010-05-15-05:00" />
+<#setting date_format="iso">
+<@assertEquals actual=d?string expected="2010-05-15" />
+<#setting date_format="xs fz">
+<@assertEquals actual=d?string expected="2010-05-15-05:00" />
+<#setting date_format="xs fz u">
+<@assertEquals actual=d?string expected="2010-05-15Z" />
+<#setting date_format="iso fz u">
+<@assertEquals actual=d?string expected="2010-05-15" />
+<#setting date_format="xs nz">
+<@assertEquals actual=d?string expected="2010-05-15" />
+
+<#assign t = dt?time>
+<@assertEquals actual=d?string expected="2010-05-15" />
+<#setting time_format="xs">
+<@assertEquals actual=t?string expected="01:02:03-05:00" />
+<#setting time_format="iso_m">
+<@assertEquals actual=t?string expected="01:02-05:00" />
+<#setting time_format="xs fz">
+<@assertEquals actual=t?string expected="01:02:03-05:00" />
+<#setting time_format="xs nz">
+<@assertEquals actual=t?string expected="01:02:03" />
+<#setting time_format="iso nz ms">
+<@assertEquals actual=t?string expected="01:02:03.000" />
+
+<@assertFails message="Use ?date, ?time, or ?datetime">${unknownDate?string.xs}</@>
+<@assertFails message="Use ?date, ?time, or ?datetime">${unknownDate?string.iso}</@>
+<@assertFails message="format string">${.now?string.xs_fz_nz}</@>
+<@assertFails message="format string">${.now?string.xs_u_fu}</@>
+<@assertFails message="format string">${.now?string.xs_s_ms}</@>
+<@assertFails message="format string">${.now?string.xs_q}</@>
+<@assertFails message="format string">${.now?string.xss}</@>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-java.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-java.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-java.ftl
new file mode 100644
index 0000000..82001db
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateformat-java.ftl
@@ -0,0 +1,71 @@
+<#--
+ 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.
+-->
+<#setting locale="en_US">
+<#setting time_zone="GMT">
+<#setting datetime_format="">
+${date}
+${unknownDate?datetime}
+${date?string}
+${date?string[""]}
+${date?string.short}
+${date?string.medium}
+${date?string.long}
+${date?string.short_short}
+${date?string.short_medium}
+${date?string.short_long}
+${date?string.medium_short}
+${date?string.medium_medium}
+${date?string.medium_long}
+${date?string.long_short}
+${date?string.long_medium}
+${date?string.long_long}
+${unknownDate?date}
+${date?date?string[""]}
+${date?date?string.short}
+${date?date?string.medium}
+${date?date?string.long}
+${unknownDate?time}
+${date?time?string[""]}
+${date?time?string.short}
+${date?time?string.medium}
+${date?time?string.long}
+<#setting locale="hu_hu">
+<#setting datetime_format="long_long">
+${date}
+<#setting locale="en_US">
+<#setting datetime_format="EEE, dd MMM yyyyy HH:mm:ss z">
+${date}
+${unknownDate?string["EEE, dd MMM yyyy HH:mm:ss z"]}
+${unknownDate?string("EEE, dd MMM yyyy HH:mm:ss z")}
+${unknownDate?string.yyyy}
+
+<#setting datetime_format="yyyy">
+<#assign s = date?string>
+${s}
+<#setting datetime_format="MM">
+${s}
+
+<#-- Check ?string lazy evaluation bug was fixed: -->
+<#setting datetime_format="yyyy">
+<#assign s = date?string>
+<#-- no ${s} -->
+<#setting datetime_format="MM">
+${s}
+<#assign s = date?string>
+${s}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateparsing.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateparsing.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateparsing.ftl
new file mode 100644
index 0000000..d830f95
--- /dev/null
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/test/templatesuite/templates/dateparsing.ftl
@@ -0,0 +1,84 @@
+<#--
+ 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.
+-->
+<#setting locale="en_US">
+<#setting time_zone="GMT">
+<#setting datetime_format="G yyyy-MM-dd HH:mm:ss.S Z">
+<#setting date_format="G yyyy-MM-dd Z">
+<#setting time_format="HH:mm:ss.S Z">
+
+<@assertEquals expected="AD 1998-10-30 15:30:44.512 +0000" actual='AD 1998-10-30 19:30:44.512 +0400'?datetime?string />
+<@assertEquals expected="AD 1998-10-29 +0000" actual='AD 1998-10-30 +0400'?date?string />
+<@assertEquals expected="15:30:44.512 +0000" actual='19:30:44.512 +0400'?time?string />
+
+<@assertEquals expected="AD 1998-10-30 15:30:44.512 +0000"
+ actual='10/30/1998 19:30:44:512 GMT+04:00'?datetime("MM/dd/yyyy HH:mm:ss:S z")?string />
+<@assertEquals expected="AD 1998-10-29 +0000"
+ actual='10/30/1998 GMT+04:00'?date("MM/dd/yyyy z")?string />
+<@assertEquals expected="15:30:44.512 +0000"
+ actual='19:30:44:512 GMT+04:00'?time("HH:mm:ss:S z")?string />
+
+<@assertEquals expected="AD 1998-10-30 15:30:44.512 +0000" actual='1998-10-30T19:30:44.512+04:00'?datetime.xs?string />
+<@assertEquals expected="AD 1998-10-29 +0000" actual='1998-10-30+04:00'?date.xs?string />
+<@assertEquals expected="15:30:44.512 +0000" actual='19:30:44.512+04:00'?time.xs?string />
+
+<#assign gmtStr='1998-10-30T19:30:44.512'?datetime.xs?string />
+<#setting time_zone="GMT+01:00">
+<#assign gmt01Str='1998-10-30T19:30:44.512'?datetime.xs?string />
+<#setting time_zone="default">
+<#assign defStr='1998-10-30T19:30:44.512'?datetime.xs?string />
+<@assert test = gmtStr != gmt01Str />
+<@assert test = defStr != gmtStr || defStr != gmt01Str />
+
+<#assign refDate = "AD 1998-10-30 +0000"?date>
+<#assign refTime = "15:30:44.512 +0000"?time>
+<#assign refDateTime = "AD 1998-10-30 15:30:44.512 +0000"?datetime>
+<#setting time_zone="UTC">
+<#list ['xs', 'xs_nz', 'xs_fz', 'xs s', 'xs ms'] as format>
+ <#setting date_format=format>
+ <#setting time_format=format>
+ <#setting datetime_format=format>
+ <@assertEquals expected=refDate actual="1998-10-30Z"?date />
+ <@assertEquals expected=refTime actual="15:30:44.512Z"?time />
+ <@assertEquals expected=refDateTime actual="1998-10-30T15:30:44.512Z"?datetime />
+</#list>
+<#list ['iso', 'iso_nz', 'iso_fz', 'iso m'] as format>
+ <#setting date_format=format>
+ <#setting time_format=format>
+ <#setting datetime_format=format>
+ <@assertEquals expected=refDate actual="1998-10-30"?date />
+ <@assertEquals expected=refDate actual="19981030"?date />
+ <@assertEquals expected=refTime actual="15:30:44,512Z"?time />
+ <@assertEquals expected=refTime actual="153044,512Z"?time />
+ <@assertEquals expected=refDateTime actual="1998-10-30T15:30:44,512Z"?datetime />
+ <@assertEquals expected=refDateTime actual="19981030T153044,512Z"?datetime />
+</#list>
+
+<#setting time_zone="GMT+01:00">
+<#assign refDateTime='1998-10-30T19:30:44.512'?datetime.xs />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512"?datetime.xs />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512"?datetime.iso />
+<@assertEquals expected=refDateTime actual="1998-10-30T18:30:44.512"?datetime.xs_u />
+<@assertEquals expected=refDateTime actual="1998-10-30T18:30:44.512"?datetime.iso_u />
+<#setting time_zone="UTC">
+<@assertEquals expected=refDateTime actual="1998-10-30T18:30:44.512"?datetime.xs />
+<@assertEquals expected=refDateTime actual="1998-10-30T18:30:44.512"?datetime.iso />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512+01:00"?datetime.xs />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512+01:00"?datetime.xs_u />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512+01"?datetime.iso />
+<@assertEquals expected=refDateTime actual="1998-10-30T19:30:44.512+01"?datetime.iso_u />
\ No newline at end of file
[14/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
deleted file mode 100644
index 4306a50..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.util.Collections;
-import java.util.Date;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.TemplateHTMLOutputModel;
-import org.junit.Test;
-
-public class ErrorMessagesTest {
-
- @Test
- public void getterMessage() throws TemplateModelException {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- TemplateHashModel thm= (TemplateHashModel) ow.wrap(new TestBean());
-
- try {
- thm.get("foo");
- } catch (TemplateModelException e) {
- e.printStackTrace();
- final String msg = e.getMessage();
- assertThat(msg, containsString("\"foo\""));
- assertThat(msg, containsString("existing sub-variable"));
- }
- assertNull(thm.get("bar"));
- }
-
- @Test
- public void markupOutputParameter() throws Exception {
- TemplateHTMLOutputModel html = HTMLOutputFormat.INSTANCE.fromMarkup("<p>a");
-
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- TemplateHashModel thm = (TemplateHashModel) ow.wrap(new TestBean());
-
- {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1");
- try {
- m.exec(Collections.singletonList(html));
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), allOf(
- containsString("String"), containsString("convert"), containsString("markup_output"),
- containsString("Tip:"), containsString("?markup_string")));
- }
- }
-
- {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2");
- try {
- m.exec(Collections.singletonList(html));
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), allOf(
- containsString("Date"), containsString("convert"), containsString("markup_output"),
- not(containsString("?markup_string"))));
- }
- }
-
- for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName);
- try {
- m.exec(Collections.singletonList(html));
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), allOf(
- containsString("No compatible overloaded"),
- containsString("String"), containsString("markup_output"),
- containsString("Tip:"), containsString("?markup_string")));
- }
- }
-
- {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2");
- try {
- m.exec(Collections.singletonList(html));
- fail();
- } catch (TemplateModelException e) {
- assertThat(e.getMessage(), allOf(
- containsString("No compatible overloaded"),
- containsString("Integer"), containsString("markup_output"),
- not(containsString("?markup_string"))));
- }
- }
-
- {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4");
- Object r = m.exec(Collections.singletonList(html));
- if (r instanceof TemplateScalarModel) {
- r = ((TemplateScalarModel) r).getAsString();
- }
- assertEquals("<p>a", r);
- }
- }
-
- public static class TestBean {
-
- public String getFoo() {
- throw new RuntimeException("Dummy");
- }
-
- public void m1(String s) {
- // nop
- }
-
- public void m2(Date s) {
- // nop
- }
-
- public void mOverloaded(String s) {
- // nop
- }
-
- public void mOverloaded(Date d) {
- // nop
- }
-
- public void mOverloaded2(Integer n) {
- // nop
- }
-
- public void mOverloaded2(Date d) {
- // nop
- }
-
- public void mOverloaded3(String... s) {
- // nop
- }
-
- public void mOverloaded3(Date d) {
- // nop
- }
-
- public String mOverloaded4(String s) {
- return s;
- }
-
- public String mOverloaded4(TemplateHTMLOutputModel s) throws TemplateModelException {
- return s.getOutputFormat().getMarkupString(s);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
deleted file mode 100644
index 92f59fb..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class FineTuneMethodAppearanceTest {
-
- @Test
- public void newWayOfConfiguring() throws TemplateModelException {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .methodAppearanceFineTuner(GetlessMethodsAsPropertyGettersRule.INSTANCE)
- .exposeFields(true)
- .build();
- checkIfProperlyWrapped(ow.wrap(new C()));
- }
-
- private void checkIfProperlyWrapped(TemplateModel tm) throws TemplateModelException {
- TemplateHashModel thm = (TemplateHashModel) tm;
- assertEquals("v1", ((TemplateScalarModel) thm.get("v1")).getAsString());
- assertEquals("v2()", ((TemplateScalarModel) thm.get("v2")).getAsString());
- assertEquals("getV3()", ((TemplateScalarModel) thm.get("v3")).getAsString());
- assertTrue(thm.get("getV3") instanceof TemplateMethodModelEx);
- }
-
- static public class C {
-
- public String v1 = "v1";
-
- public String v2 = "v2";
- public String v2() { return "v2()"; }
-
- public String v3() { return "v3()"; }
- public String getV3() { return "getV3()"; }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
deleted file mode 100644
index 716f863..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-
-class GetlessMethodsAsPropertyGettersRule implements MethodAppearanceFineTuner, SingletonCustomizer {
-
- static final GetlessMethodsAsPropertyGettersRule INSTANCE = new GetlessMethodsAsPropertyGettersRule();
-
- // Can't be constructed from outside
- private GetlessMethodsAsPropertyGettersRule() { }
-
- @Override
- public void process(
- DecisionInput in, Decision out) {
- legacyProcess(in.getContainingClass(), in.getMethod(), out);
- }
-
- /** This only exists as the tests need to call this through the deprecated method too. */
- public void legacyProcess(
- Class clazz, Method m, Decision decision) {
- if (m.getDeclaringClass() != Object.class
- && m.getReturnType() != void.class
- && m.getParameterTypes().length == 0) {
- String mName = m.getName();
- if (!looksLikePropertyReadMethod(mName)) {
- decision.setExposeMethodAs(null);
- try {
- decision.setExposeAsProperty(new PropertyDescriptor(
- mName, clazz, mName, null));
- } catch (IntrospectionException e) { // Won't happen...
- throw new RuntimeException(e);
- }
- }
- }
- }
-
- private static boolean looksLikePropertyReadMethod(String name) {
- final int verbEnd;
- if (name.startsWith("get")) verbEnd = 3;
- else if (name.startsWith("is")) verbEnd = 2;
- else return false;
-
- return name.length() == verbEnd || Character.isUpperCase(name.charAt(verbEnd));
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java
deleted file mode 100644
index 599e6f2..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings("boxing")
-public class IsApplicableTest extends TestCase {
-
- public IsApplicableTest(String name) {
- super(name);
- }
-
- public void testSingle() {
- ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object() });
- assertApplicable(ats, Object.class);
- assertNotApplicable(ats, String.class);
- assertNotApplicable(ats, CharSequence.class);
- assertNotApplicable(ats, Integer.class);
- assertNotApplicable(ats, Integer.TYPE);
-
- ats = new ArgumentTypes(new Object[] { "" });
- assertApplicable(ats, Object.class);
- assertApplicable(ats, CharSequence.class);
- assertApplicable(ats, String.class);
- assertNotApplicable(ats, Integer.class);
- assertNotApplicable(ats, Integer.TYPE);
-
- ats = new ArgumentTypes(new Object[] { 1 });
- assertApplicable(ats, Object.class);
- assertNotApplicable(ats, CharSequence.class);
- assertNotApplicable(ats, String.class);
- assertNotApplicable(ats, Short.class);
- assertNotApplicable(ats, Short.TYPE);
- assertApplicable(ats, Integer.class);
- assertApplicable(ats, Integer.TYPE);
- assertApplicable(ats, Float.class);
- assertApplicable(ats, Float.TYPE);
- assertApplicable(ats, Double.class);
- assertApplicable(ats, Double.TYPE);
- assertApplicable(ats, BigDecimal.class);
- assertApplicable(ats, BigInteger.class);
-
- ats = new ArgumentTypes(new Object[] { new OverloadedNumberUtil.IntegerOrByte(1, (byte) 1) });
- assertApplicable(ats, Object.class);
- assertNotApplicable(ats, CharSequence.class);
- assertNotApplicable(ats, String.class);
- assertApplicable(ats, Short.class);
- assertApplicable(ats, Short.TYPE);
- assertApplicable(ats, Integer.class);
- assertApplicable(ats, Integer.TYPE);
- assertApplicable(ats, Float.class);
- assertApplicable(ats, Float.TYPE);
- assertApplicable(ats, Double.class);
- assertApplicable(ats, Double.TYPE);
- assertApplicable(ats, BigDecimal.class);
- assertApplicable(ats, BigInteger.class);
-
- ats = new ArgumentTypes(new Object[] { 1.0f });
- assertApplicable(ats, Object.class);
- assertNotApplicable(ats, CharSequence.class);
- assertNotApplicable(ats, String.class);
- assertNotApplicable(ats, Integer.class);
- assertNotApplicable(ats, Integer.TYPE);
- assertApplicable(ats, Float.class);
- assertApplicable(ats, Float.TYPE);
- assertApplicable(ats, Double.class);
- assertApplicable(ats, Double.TYPE);
- assertApplicable(ats, BigDecimal.class);
- assertNotApplicable(ats, BigInteger.class);
-
- ats = new ArgumentTypes(new Object[] { null });
- assertApplicable(ats, Object.class);
- assertApplicable(ats, String.class);
- assertApplicable(ats, Integer.class);
- assertNotApplicable(ats, Integer.TYPE);
- assertNotApplicable(ats, Boolean.TYPE);
- assertNotApplicable(ats, Object.class, Object.class);
- assertNotApplicable(ats);
- }
-
- public void testMulti() {
- ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object(), "", 1, true });
- assertApplicable(ats, Object.class, Object.class, Object.class, Object.class);
- assertApplicable(ats, Object.class, String.class, Number.class, Boolean.class);
- assertApplicable(ats, Object.class, CharSequence.class, Integer.class, Serializable.class);
- assertApplicable(ats, Object.class, Comparable.class, Integer.TYPE, Serializable.class);
- assertNotApplicable(ats, Object.class, String.class, Number.class, Number.class);
- assertNotApplicable(ats, Object.class, StringBuilder.class, Number.class, Boolean.class);
- assertNotApplicable(ats, int.class, Object.class, Object.class, Object.class);
- assertNotApplicable(ats, Object.class, Object.class, Object.class);
- assertNotApplicable(ats, Object.class, Object.class, Object.class, Object.class, Object.class);
- }
-
- public void testNoParam() {
- ArgumentTypes ats = new ArgumentTypes(new Object[] { });
- assertApplicable(ats);
- assertNotApplicable(ats, Object.class);
- }
-
- public void testVarags() {
- Object[][] argLists = new Object[][] {
- new Object[] { "", 1, 2, 3 },
- new Object[] { "", 1, (byte) 2, 3 },
- new Object[] { "", 1},
- new Object[] { "" },
- };
- for (Object[] args : argLists) {
- ArgumentTypes ats = new ArgumentTypes(args);
- assertApplicable(ats, true, String.class, int[].class);
- assertApplicable(ats, true, String.class, Integer[].class);
- assertApplicable(ats, true, Object.class, Comparable[].class);
- assertApplicable(ats, true, Object.class, Object[].class);
- assertNotApplicable(ats, true, StringBuilder.class, int[].class);
- if (args.length > 1) {
- assertNotApplicable(ats, true, String.class, String[].class);
- } else {
- assertApplicable(ats, true, String.class, String[].class);
- }
- }
- }
-
- private void assertNotApplicable(ArgumentTypes ats, Class... paramTypes) {
- assertNotApplicable(ats, false, paramTypes);
- }
-
- private void assertNotApplicable(ArgumentTypes ats, boolean varargs, Class... paramTypes) {
- List tested = new ArrayList();
- tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes));
- if (ats.getApplicables(tested, varargs).size() != 0) {
- fail("Parameter types were applicable");
- }
- }
-
- private void assertApplicable(ArgumentTypes ats, Class<?>... paramTypes) {
- assertApplicable(ats, false, paramTypes);
- }
-
- private void assertApplicable(ArgumentTypes ats, boolean varargs, Class<?>... paramTypes) {
- List tested = new ArrayList();
- tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes));
- if (ats.getApplicables(tested, varargs).size() != 1) {
- fail("Parameter types weren't applicable");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
deleted file mode 100644
index 3de3f13..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-public class IsMoreSpecificParameterTypeTest extends TestCase {
-
- public IsMoreSpecificParameterTypeTest(String name) {
- super(name);
- }
-
- public void testFixed() {
- assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, true, 0));
- assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, true, 0));
-
- assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, true, 0));
- assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, true, 0));
-
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, true, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, true, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, true, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, true, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, true, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, true, 0));
-
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, true, 0));
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, true, 0));
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, true, 0));
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, true, 0));
-
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0));
- }
-
- public void testBuggy() {
- assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, false, 0));
- assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, false, 0));
-
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, false, 0));
-
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, false, 0));
- assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, false, 0));
-
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, false, 0));
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, false, 0));
- assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, false, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, false, 0));
-
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0));
- assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
deleted file mode 100644
index 96c1adf..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Version;
-
-/**
- * A hack to keep some unit tests producing exactly the same results on Java 8 as on Java 5-7, by hiding members
- * added after Java 7.
- */
-public class Java7MembersOnlyDefaultObjectWrapper extends DefaultObjectWrapper {
-
- private static final Set<String> POST_JAVA_7_MAP_METHODS = newHashSet(
- "compute", "computeIfAbsent", "computeIfPresent",
- "forEach", "getOrDefault", "merge", "putIfAbsent", "replace", "replaceAll");
-
- private static final Set<String> POST_JAVA_7_ITERABLE_METHODS = newHashSet("forEach");
- private static final Set<String> POST_JAVA_7_COLLECTION_METHODS = newHashSet("parallelStream", "removeIf", "stream");
- private static final Set<String> POST_JAVA_7_LIST_METHODS = newHashSet("sort", "spliterator");
-
- static final MethodAppearanceFineTuner POST_JAVA_7_FILTER = new MethodAppearanceFineTuner() {
-
- @Override
- public void process(DecisionInput in, Decision out) {
- Method m = in.getMethod();
- Class declCl = m.getDeclaringClass();
- if (Map.class.isAssignableFrom(declCl)) {
- if (POST_JAVA_7_MAP_METHODS.contains(m.getName())) {
- hideMember(out);
- return;
- }
- }
- if (Iterable.class.isAssignableFrom(declCl)) {
- if (POST_JAVA_7_ITERABLE_METHODS.contains(m.getName())) {
- hideMember(out);
- return;
- }
- }
- if (Collection.class.isAssignableFrom(declCl)) {
- if (POST_JAVA_7_COLLECTION_METHODS.contains(m.getName())) {
- hideMember(out);
- return;
- }
- }
- if (List.class.isAssignableFrom(declCl)) {
- if (POST_JAVA_7_LIST_METHODS.contains(m.getName())) {
- hideMember(out);
- return;
- }
- }
- }
-
- private void hideMember(Decision out) {
- out.setExposeMethodAs(null);
- out.setExposeAsProperty(null);
- }
-
- };
-
- public Java7MembersOnlyDefaultObjectWrapper(Version version) {
- super(new DefaultObjectWrapper.Builder(version).methodAppearanceFineTuner(POST_JAVA_7_FILTER), true);
- }
-
- private static <T> Set<T> newHashSet(T... items) {
- HashSet<T> r = new HashSet<>();
- for (T item : items) {
- r.add(item);
- }
- return r;
- }
-
- public Java7MembersOnlyDefaultObjectWrapper() {
- this(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
deleted file mode 100644
index fa7ce29..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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.core.model.impl;
-
-// FMPP template source:
-// ----
-// package org.apache.freemarker.core.model.impl;
-//
-// // FMPP template source:
-// // ----
-// <#assign src><#include "ManyObjectsOfDifferentClasses.java.ftl" parse=false></#assign>
-// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')}
-// // ----
-//
-// <#assign MAX_CLA = 8 - 1>
-// <#assign MAX_MET = 10 - 1>
-// <#assign MAX_PRO = 10 - 1>
-//
-// public class ManyObjectsOfDifferentClasses {
-//
-// public static final Object[] OBJECTS = new Object[] {
-// <#list 0..MAX_CLA as claI>
-// new C${claI}(),
-// </#list>
-// };
-//
-// <#list 0..MAX_CLA as claI>
-// static public class C${claI} {
-// <#list 0..MAX_PRO as proI>
-// public int getP${proI}() { return ${claI} * 1000 + ${proI}; }
-// </#list>
-// <#list 0..MAX_MET as metI>
-// public int m${metI}() { return ${claI} * 1000 + ${metI}; };
-// </#list>
-// }
-// </#list>
-//
-// }
-// ----
-
-
-public class ManyObjectsOfDifferentClasses {
-
- public static final Object[] OBJECTS = new Object[] {
- new C0(),
- new C1(),
- new C2(),
- new C3(),
- new C4(),
- new C5(),
- new C6(),
- new C7(),
- };
-
- static public class C0 {
- public int getP0() { return 0 * 1000 + 0; }
- public int getP1() { return 0 * 1000 + 1; }
- public int getP2() { return 0 * 1000 + 2; }
- public int getP3() { return 0 * 1000 + 3; }
- public int getP4() { return 0 * 1000 + 4; }
- public int getP5() { return 0 * 1000 + 5; }
- public int getP6() { return 0 * 1000 + 6; }
- public int getP7() { return 0 * 1000 + 7; }
- public int getP8() { return 0 * 1000 + 8; }
- public int getP9() { return 0 * 1000 + 9; }
- public int m0() { return 0 * 1000 + 0; };
- public int m1() { return 0 * 1000 + 1; };
- public int m2() { return 0 * 1000 + 2; };
- public int m3() { return 0 * 1000 + 3; };
- public int m4() { return 0 * 1000 + 4; };
- public int m5() { return 0 * 1000 + 5; };
- public int m6() { return 0 * 1000 + 6; };
- public int m7() { return 0 * 1000 + 7; };
- public int m8() { return 0 * 1000 + 8; };
- public int m9() { return 0 * 1000 + 9; };
- }
- static public class C1 {
- public int getP0() { return 1 * 1000 + 0; }
- public int getP1() { return 1 * 1000 + 1; }
- public int getP2() { return 1 * 1000 + 2; }
- public int getP3() { return 1 * 1000 + 3; }
- public int getP4() { return 1 * 1000 + 4; }
- public int getP5() { return 1 * 1000 + 5; }
- public int getP6() { return 1 * 1000 + 6; }
- public int getP7() { return 1 * 1000 + 7; }
- public int getP8() { return 1 * 1000 + 8; }
- public int getP9() { return 1 * 1000 + 9; }
- public int m0() { return 1 * 1000 + 0; };
- public int m1() { return 1 * 1000 + 1; };
- public int m2() { return 1 * 1000 + 2; };
- public int m3() { return 1 * 1000 + 3; };
- public int m4() { return 1 * 1000 + 4; };
- public int m5() { return 1 * 1000 + 5; };
- public int m6() { return 1 * 1000 + 6; };
- public int m7() { return 1 * 1000 + 7; };
- public int m8() { return 1 * 1000 + 8; };
- public int m9() { return 1 * 1000 + 9; };
- }
- static public class C2 {
- public int getP0() { return 2 * 1000 + 0; }
- public int getP1() { return 2 * 1000 + 1; }
- public int getP2() { return 2 * 1000 + 2; }
- public int getP3() { return 2 * 1000 + 3; }
- public int getP4() { return 2 * 1000 + 4; }
- public int getP5() { return 2 * 1000 + 5; }
- public int getP6() { return 2 * 1000 + 6; }
- public int getP7() { return 2 * 1000 + 7; }
- public int getP8() { return 2 * 1000 + 8; }
- public int getP9() { return 2 * 1000 + 9; }
- public int m0() { return 2 * 1000 + 0; };
- public int m1() { return 2 * 1000 + 1; };
- public int m2() { return 2 * 1000 + 2; };
- public int m3() { return 2 * 1000 + 3; };
- public int m4() { return 2 * 1000 + 4; };
- public int m5() { return 2 * 1000 + 5; };
- public int m6() { return 2 * 1000 + 6; };
- public int m7() { return 2 * 1000 + 7; };
- public int m8() { return 2 * 1000 + 8; };
- public int m9() { return 2 * 1000 + 9; };
- }
- static public class C3 {
- public int getP0() { return 3 * 1000 + 0; }
- public int getP1() { return 3 * 1000 + 1; }
- public int getP2() { return 3 * 1000 + 2; }
- public int getP3() { return 3 * 1000 + 3; }
- public int getP4() { return 3 * 1000 + 4; }
- public int getP5() { return 3 * 1000 + 5; }
- public int getP6() { return 3 * 1000 + 6; }
- public int getP7() { return 3 * 1000 + 7; }
- public int getP8() { return 3 * 1000 + 8; }
- public int getP9() { return 3 * 1000 + 9; }
- public int m0() { return 3 * 1000 + 0; };
- public int m1() { return 3 * 1000 + 1; };
- public int m2() { return 3 * 1000 + 2; };
- public int m3() { return 3 * 1000 + 3; };
- public int m4() { return 3 * 1000 + 4; };
- public int m5() { return 3 * 1000 + 5; };
- public int m6() { return 3 * 1000 + 6; };
- public int m7() { return 3 * 1000 + 7; };
- public int m8() { return 3 * 1000 + 8; };
- public int m9() { return 3 * 1000 + 9; };
- }
- static public class C4 {
- public int getP0() { return 4 * 1000 + 0; }
- public int getP1() { return 4 * 1000 + 1; }
- public int getP2() { return 4 * 1000 + 2; }
- public int getP3() { return 4 * 1000 + 3; }
- public int getP4() { return 4 * 1000 + 4; }
- public int getP5() { return 4 * 1000 + 5; }
- public int getP6() { return 4 * 1000 + 6; }
- public int getP7() { return 4 * 1000 + 7; }
- public int getP8() { return 4 * 1000 + 8; }
- public int getP9() { return 4 * 1000 + 9; }
- public int m0() { return 4 * 1000 + 0; };
- public int m1() { return 4 * 1000 + 1; };
- public int m2() { return 4 * 1000 + 2; };
- public int m3() { return 4 * 1000 + 3; };
- public int m4() { return 4 * 1000 + 4; };
- public int m5() { return 4 * 1000 + 5; };
- public int m6() { return 4 * 1000 + 6; };
- public int m7() { return 4 * 1000 + 7; };
- public int m8() { return 4 * 1000 + 8; };
- public int m9() { return 4 * 1000 + 9; };
- }
- static public class C5 {
- public int getP0() { return 5 * 1000 + 0; }
- public int getP1() { return 5 * 1000 + 1; }
- public int getP2() { return 5 * 1000 + 2; }
- public int getP3() { return 5 * 1000 + 3; }
- public int getP4() { return 5 * 1000 + 4; }
- public int getP5() { return 5 * 1000 + 5; }
- public int getP6() { return 5 * 1000 + 6; }
- public int getP7() { return 5 * 1000 + 7; }
- public int getP8() { return 5 * 1000 + 8; }
- public int getP9() { return 5 * 1000 + 9; }
- public int m0() { return 5 * 1000 + 0; };
- public int m1() { return 5 * 1000 + 1; };
- public int m2() { return 5 * 1000 + 2; };
- public int m3() { return 5 * 1000 + 3; };
- public int m4() { return 5 * 1000 + 4; };
- public int m5() { return 5 * 1000 + 5; };
- public int m6() { return 5 * 1000 + 6; };
- public int m7() { return 5 * 1000 + 7; };
- public int m8() { return 5 * 1000 + 8; };
- public int m9() { return 5 * 1000 + 9; };
- }
- static public class C6 {
- public int getP0() { return 6 * 1000 + 0; }
- public int getP1() { return 6 * 1000 + 1; }
- public int getP2() { return 6 * 1000 + 2; }
- public int getP3() { return 6 * 1000 + 3; }
- public int getP4() { return 6 * 1000 + 4; }
- public int getP5() { return 6 * 1000 + 5; }
- public int getP6() { return 6 * 1000 + 6; }
- public int getP7() { return 6 * 1000 + 7; }
- public int getP8() { return 6 * 1000 + 8; }
- public int getP9() { return 6 * 1000 + 9; }
- public int m0() { return 6 * 1000 + 0; };
- public int m1() { return 6 * 1000 + 1; };
- public int m2() { return 6 * 1000 + 2; };
- public int m3() { return 6 * 1000 + 3; };
- public int m4() { return 6 * 1000 + 4; };
- public int m5() { return 6 * 1000 + 5; };
- public int m6() { return 6 * 1000 + 6; };
- public int m7() { return 6 * 1000 + 7; };
- public int m8() { return 6 * 1000 + 8; };
- public int m9() { return 6 * 1000 + 9; };
- }
- static public class C7 {
- public int getP0() { return 7 * 1000 + 0; }
- public int getP1() { return 7 * 1000 + 1; }
- public int getP2() { return 7 * 1000 + 2; }
- public int getP3() { return 7 * 1000 + 3; }
- public int getP4() { return 7 * 1000 + 4; }
- public int getP5() { return 7 * 1000 + 5; }
- public int getP6() { return 7 * 1000 + 6; }
- public int getP7() { return 7 * 1000 + 7; }
- public int getP8() { return 7 * 1000 + 8; }
- public int getP9() { return 7 * 1000 + 9; }
- public int m0() { return 7 * 1000 + 0; };
- public int m1() { return 7 * 1000 + 1; };
- public int m2() { return 7 * 1000 + 2; };
- public int m3() { return 7 * 1000 + 3; };
- public int m4() { return 7 * 1000 + 4; };
- public int m5() { return 7 * 1000 + 5; };
- public int m6() { return 7 * 1000 + 6; };
- public int m7() { return 7 * 1000 + 7; };
- public int m8() { return 7 * 1000 + 8; };
- public int m9() { return 7 * 1000 + 9; };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
deleted file mode 100644
index dd73bee..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.core.model.impl;
-
-// FMPP template source:
-// ----
-// package org.apache.freemarker.core.model.impl;
-//
-// // FMPP template source:
-// // ----
-// <#assign src><#include "ManyStaticsOfDifferentClasses.java.ftl" parse=false></#assign>
-// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')}
-// // ----
-//
-// <#assign MAX_CLA = 8 - 1>
-// <#assign MAX_MET = 10 - 1>
-// <#assign MAX_PRO = 10 - 1>
-//
-// public class ManyStaticsOfDifferentClasses {
-//
-// private ManyStaticsOfDifferentClasses() { }
-//
-// <#list 0..MAX_CLA as claI>
-// static public class C${claI} {
-// <#list 0..MAX_PRO as proI>
-// public static int p${proI} = ${claI} * 1000 + ${proI};
-// </#list>
-// <#list 0..MAX_MET as metI>
-// public static int m${metI}() { return ${claI} * 1000 + ${metI}; };
-// </#list>
-// }
-// </#list>
-//
-// }
-// ----
-
-
-public class ManyStaticsOfDifferentClasses {
-
- private ManyStaticsOfDifferentClasses() { }
-
- static public class C0 {
- public static int p0 = 0 * 1000 + 0;
- public static int p1 = 0 * 1000 + 1;
- public static int p2 = 0 * 1000 + 2;
- public static int p3 = 0 * 1000 + 3;
- public static int p4 = 0 * 1000 + 4;
- public static int p5 = 0 * 1000 + 5;
- public static int p6 = 0 * 1000 + 6;
- public static int p7 = 0 * 1000 + 7;
- public static int p8 = 0 * 1000 + 8;
- public static int p9 = 0 * 1000 + 9;
- public static int m0() { return 0 * 1000 + 0; };
- public static int m1() { return 0 * 1000 + 1; };
- public static int m2() { return 0 * 1000 + 2; };
- public static int m3() { return 0 * 1000 + 3; };
- public static int m4() { return 0 * 1000 + 4; };
- public static int m5() { return 0 * 1000 + 5; };
- public static int m6() { return 0 * 1000 + 6; };
- public static int m7() { return 0 * 1000 + 7; };
- public static int m8() { return 0 * 1000 + 8; };
- public static int m9() { return 0 * 1000 + 9; };
- }
- static public class C1 {
- public static int p0 = 1 * 1000 + 0;
- public static int p1 = 1 * 1000 + 1;
- public static int p2 = 1 * 1000 + 2;
- public static int p3 = 1 * 1000 + 3;
- public static int p4 = 1 * 1000 + 4;
- public static int p5 = 1 * 1000 + 5;
- public static int p6 = 1 * 1000 + 6;
- public static int p7 = 1 * 1000 + 7;
- public static int p8 = 1 * 1000 + 8;
- public static int p9 = 1 * 1000 + 9;
- public static int m0() { return 1 * 1000 + 0; };
- public static int m1() { return 1 * 1000 + 1; };
- public static int m2() { return 1 * 1000 + 2; };
- public static int m3() { return 1 * 1000 + 3; };
- public static int m4() { return 1 * 1000 + 4; };
- public static int m5() { return 1 * 1000 + 5; };
- public static int m6() { return 1 * 1000 + 6; };
- public static int m7() { return 1 * 1000 + 7; };
- public static int m8() { return 1 * 1000 + 8; };
- public static int m9() { return 1 * 1000 + 9; };
- }
- static public class C2 {
- public static int p0 = 2 * 1000 + 0;
- public static int p1 = 2 * 1000 + 1;
- public static int p2 = 2 * 1000 + 2;
- public static int p3 = 2 * 1000 + 3;
- public static int p4 = 2 * 1000 + 4;
- public static int p5 = 2 * 1000 + 5;
- public static int p6 = 2 * 1000 + 6;
- public static int p7 = 2 * 1000 + 7;
- public static int p8 = 2 * 1000 + 8;
- public static int p9 = 2 * 1000 + 9;
- public static int m0() { return 2 * 1000 + 0; };
- public static int m1() { return 2 * 1000 + 1; };
- public static int m2() { return 2 * 1000 + 2; };
- public static int m3() { return 2 * 1000 + 3; };
- public static int m4() { return 2 * 1000 + 4; };
- public static int m5() { return 2 * 1000 + 5; };
- public static int m6() { return 2 * 1000 + 6; };
- public static int m7() { return 2 * 1000 + 7; };
- public static int m8() { return 2 * 1000 + 8; };
- public static int m9() { return 2 * 1000 + 9; };
- }
- static public class C3 {
- public static int p0 = 3 * 1000 + 0;
- public static int p1 = 3 * 1000 + 1;
- public static int p2 = 3 * 1000 + 2;
- public static int p3 = 3 * 1000 + 3;
- public static int p4 = 3 * 1000 + 4;
- public static int p5 = 3 * 1000 + 5;
- public static int p6 = 3 * 1000 + 6;
- public static int p7 = 3 * 1000 + 7;
- public static int p8 = 3 * 1000 + 8;
- public static int p9 = 3 * 1000 + 9;
- public static int m0() { return 3 * 1000 + 0; };
- public static int m1() { return 3 * 1000 + 1; };
- public static int m2() { return 3 * 1000 + 2; };
- public static int m3() { return 3 * 1000 + 3; };
- public static int m4() { return 3 * 1000 + 4; };
- public static int m5() { return 3 * 1000 + 5; };
- public static int m6() { return 3 * 1000 + 6; };
- public static int m7() { return 3 * 1000 + 7; };
- public static int m8() { return 3 * 1000 + 8; };
- public static int m9() { return 3 * 1000 + 9; };
- }
- static public class C4 {
- public static int p0 = 4 * 1000 + 0;
- public static int p1 = 4 * 1000 + 1;
- public static int p2 = 4 * 1000 + 2;
- public static int p3 = 4 * 1000 + 3;
- public static int p4 = 4 * 1000 + 4;
- public static int p5 = 4 * 1000 + 5;
- public static int p6 = 4 * 1000 + 6;
- public static int p7 = 4 * 1000 + 7;
- public static int p8 = 4 * 1000 + 8;
- public static int p9 = 4 * 1000 + 9;
- public static int m0() { return 4 * 1000 + 0; };
- public static int m1() { return 4 * 1000 + 1; };
- public static int m2() { return 4 * 1000 + 2; };
- public static int m3() { return 4 * 1000 + 3; };
- public static int m4() { return 4 * 1000 + 4; };
- public static int m5() { return 4 * 1000 + 5; };
- public static int m6() { return 4 * 1000 + 6; };
- public static int m7() { return 4 * 1000 + 7; };
- public static int m8() { return 4 * 1000 + 8; };
- public static int m9() { return 4 * 1000 + 9; };
- }
- static public class C5 {
- public static int p0 = 5 * 1000 + 0;
- public static int p1 = 5 * 1000 + 1;
- public static int p2 = 5 * 1000 + 2;
- public static int p3 = 5 * 1000 + 3;
- public static int p4 = 5 * 1000 + 4;
- public static int p5 = 5 * 1000 + 5;
- public static int p6 = 5 * 1000 + 6;
- public static int p7 = 5 * 1000 + 7;
- public static int p8 = 5 * 1000 + 8;
- public static int p9 = 5 * 1000 + 9;
- public static int m0() { return 5 * 1000 + 0; };
- public static int m1() { return 5 * 1000 + 1; };
- public static int m2() { return 5 * 1000 + 2; };
- public static int m3() { return 5 * 1000 + 3; };
- public static int m4() { return 5 * 1000 + 4; };
- public static int m5() { return 5 * 1000 + 5; };
- public static int m6() { return 5 * 1000 + 6; };
- public static int m7() { return 5 * 1000 + 7; };
- public static int m8() { return 5 * 1000 + 8; };
- public static int m9() { return 5 * 1000 + 9; };
- }
- static public class C6 {
- public static int p0 = 6 * 1000 + 0;
- public static int p1 = 6 * 1000 + 1;
- public static int p2 = 6 * 1000 + 2;
- public static int p3 = 6 * 1000 + 3;
- public static int p4 = 6 * 1000 + 4;
- public static int p5 = 6 * 1000 + 5;
- public static int p6 = 6 * 1000 + 6;
- public static int p7 = 6 * 1000 + 7;
- public static int p8 = 6 * 1000 + 8;
- public static int p9 = 6 * 1000 + 9;
- public static int m0() { return 6 * 1000 + 0; };
- public static int m1() { return 6 * 1000 + 1; };
- public static int m2() { return 6 * 1000 + 2; };
- public static int m3() { return 6 * 1000 + 3; };
- public static int m4() { return 6 * 1000 + 4; };
- public static int m5() { return 6 * 1000 + 5; };
- public static int m6() { return 6 * 1000 + 6; };
- public static int m7() { return 6 * 1000 + 7; };
- public static int m8() { return 6 * 1000 + 8; };
- public static int m9() { return 6 * 1000 + 9; };
- }
- static public class C7 {
- public static int p0 = 7 * 1000 + 0;
- public static int p1 = 7 * 1000 + 1;
- public static int p2 = 7 * 1000 + 2;
- public static int p3 = 7 * 1000 + 3;
- public static int p4 = 7 * 1000 + 4;
- public static int p5 = 7 * 1000 + 5;
- public static int p6 = 7 * 1000 + 6;
- public static int p7 = 7 * 1000 + 7;
- public static int p8 = 7 * 1000 + 8;
- public static int p9 = 7 * 1000 + 9;
- public static int m0() { return 7 * 1000 + 0; };
- public static int m1() { return 7 * 1000 + 1; };
- public static int m2() { return 7 * 1000 + 2; };
- public static int m3() { return 7 * 1000 + 3; };
- public static int m4() { return 7 * 1000 + 4; };
- public static int m5() { return 7 * 1000 + 5; };
- public static int m6() { return 7 * 1000 + 6; };
- public static int m7() { return 7 * 1000 + 7; };
- public static int m8() { return 7 * 1000 + 8; };
- public static int m9() { return 7 * 1000 + 9; };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
deleted file mode 100644
index 9e175e5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import org.junit.Assert;
-
-import junit.framework.TestCase;
-
-public class MiscNumericalOperationsTest extends TestCase {
-
- public MiscNumericalOperationsTest(String name) {
- super(name);
- }
-
- public void testForceUnwrappedNumberToType() {
- // Usual type to to all other types:
- Double n = Double.valueOf(123.75);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.class), Short.valueOf(n.shortValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.TYPE), Short.valueOf(n.shortValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.class), Byte.valueOf(n.byteValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.TYPE), Byte.valueOf(n.byteValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.class), Integer.valueOf(n.intValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.TYPE), Integer.valueOf(n.intValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.class), Long.valueOf(n.longValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.TYPE), Long.valueOf(n.longValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.class), Float.valueOf(n.floatValue()));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.TYPE), Float.valueOf(n.floatValue()));
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.class) == n);
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.TYPE) == n);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigInteger.class), new BigInteger("123"));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigDecimal.class), new BigDecimal("123.75"));
-
- // Cases of conversion to BigDecimal:
- BigDecimal bd = new BigDecimal("123");
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigInteger("123"), BigDecimal.class), bd);
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bd, BigDecimal.class) == bd);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigDecimal.class), bd);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123), BigDecimal.class), bd);
-
- // Cases of conversion to BigInteger:
- BigInteger bi = new BigInteger("123");
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigDecimal("123.6"), BigInteger.class), bi);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(
- new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal("123")), BigInteger.class), bi);
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bi, BigInteger.class) == bi);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigInteger.class), bi);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123.6), BigInteger.class), bi);
-
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Number.class) == n);
- assertNull(DefaultObjectWrapper.forceUnwrappedNumberToType(n, RationalNumber.class));
- RationalNumber r = new RationalNumber(1, 2);
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, RationalNumber.class) == r);
- assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Number.class) == r);
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Double.class), Double.valueOf(0.5));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigDecimal.class), new BigDecimal("0.5"));
- assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigInteger.class), BigInteger.ZERO);
- }
-
- @SuppressWarnings("boxing")
- public void testForceNumberArgumentsToParameterTypes() {
- OverloadedMethodsSubset oms = new OverloadedFixArgsMethods();
- Class[] paramTypes = new Class[] { Short.TYPE, Short.class, Double.TYPE, BigDecimal.class, BigInteger.class };
- Object[] args;
-
- args = newArgs();
- oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF });
- Assert.assertArrayEquals(
- args,
- new Object[] { (short) 123, (short) 123, 123.75, new BigDecimal("123.75"), BigInteger.valueOf(123) });
-
- args = newArgs();
- oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0, 0, 0, 0, 0 });
- Assert.assertArrayEquals(args, newArgs());
-
- args = newArgs();
- oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 8, 8, 8, 8, 8 });
- Assert.assertArrayEquals(args, newArgs());
-
- args = newArgs();
- oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0, 0xFFFF, 0, 0xFFFF });
- Assert.assertArrayEquals(
- args,
- new Object[] { (short) 123, 123.75, 123.75, 123.75, BigInteger.valueOf(123) });
- }
-
- @SuppressWarnings("boxing")
- private Object[] newArgs() {
- return new Object[] { 123.75, 123.75, 123.75, 123.75, 123.75 };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
deleted file mode 100644
index 0b0a614..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.test.TestUtil;
-
-import junit.framework.TestCase;
-
-public class ModelAPINewInstanceTest extends TestCase {
-
- private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-
- public ModelAPINewInstanceTest(String name) {
- super(name);
- }
-
- @SuppressWarnings("boxing")
- public void test() throws Exception {
- testClassConstructors("");
- testClassConstructors("int... [1]", 1);
- testClassConstructors("int 1, int 2", 1, 2);
- testClassConstructors("int... [1, 2, 3]", 1, 2, 3);
- testClassConstructors("int... [1, 2, 3]", 1, (byte) 2, (short) 3);
- try {
- testClassConstructors("int... [1, 2, 3]", 1, 2, (long) 3);
- fail();
- } catch (NoSuchMethodException e) {
- // Expected
- }
-
- testClassConstructors("int 1, int 2", (byte) 1, (short) 2);
- testClassConstructors("double 1.0, double 2.0", (long) 1, (short) 2);
- testClassConstructors("double 1.0, double 2.0", 1, 2f);
- testClassConstructors("Integer null, Integer null", null, null);
- testClassConstructors("Integer null, Integer 1", null, 1);
- testClassConstructors("int 1, String s", 1, "s");
- testClassConstructors("int 1, String null", 1, null);
- testClassConstructors("Object null, Object s", null, "s");
- testClassConstructors("Object 1.0, Object s", 1f, "s");
-
- testClassConstructors("Object s, int... [1, 2]", "s", 1, 2);
- testClassConstructors("Object s, int... []", "s");
-
- testClassConstructors2("int 1, int 2", (byte) 1, (short) 2);
- try {
- testClassConstructors2("int 1, int 2", 1, 2L);
- fail();
- } catch (NoSuchMethodException e) {
- // Expected
- }
- try {
- testClassConstructors2("", "", "");
- fail();
- } catch (NoSuchMethodException e) {
- // Expected
- }
- try {
- testClassConstructors2("int 1", 1);
- fail();
- } catch (NoSuchMethodException e) {
- // Expected
- }
- try {
- testClassConstructors2("");
- fail();
- } catch (NoSuchMethodException e) {
- // Expected
- }
- }
-
- private void testClassConstructors(String expected, Object... args) throws Exception {
- testCall(expected, Constructors.class, args);
- }
-
- private void testClassConstructors2(String expected, Object... args) throws Exception {
- testCall(expected, Constructors2.class, args);
- }
-
- private void testCall(String expected, Class cl, Object... args) throws Exception {
- Object obj = _ModelAPI.newInstance(cl, args, ow);
- assertEquals(expected, obj.toString());
- }
-
- public static class Constructors {
- private final String s;
-
- public Constructors() { s = ""; }
-
- public Constructors(int x, int y) { s = "int " + x + ", int " + y; }
- public Constructors(int x, String y) { s = "int " + x + ", String " + y; }
- public Constructors(int x, long y) { s = "int " + x + ", long " + y; }
- public Constructors(double x, double y) { s = "double " + x + ", double " + y; }
- public Constructors(Integer x, Integer y) { s = "Integer " + x + ", Integer " + y; }
- public Constructors(Object x, Object y) { s = "Object " + x + ", Object " + y; }
-
- public Constructors(int... xs) { s = "int... " + TestUtil.arrayToString(xs); }
- public Constructors(Object x, int... ys) { s = "Object " + x + ", int... " + TestUtil.arrayToString(ys); }
-
- @Override
- public String toString() {
- return s;
- }
- }
-
- public static class Constructors2 {
- private final String s;
-
- public Constructors2(int x, int y) { s = "int " + x + ", int " + y; }
-
- @Override
- public String toString() {
- return s;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
deleted file mode 100644
index 2498859..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import static org.junit.Assert.*;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ModelCacheTest {
-
- @Test
- public void modelCacheOff() throws Exception {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
- assertFalse(ow.getUseModelCache()); // default is off
-
- String s = "foo";
- assertNotSame(ow.wrap(s), ow.wrap(s));
-
- C c = new C();
- assertNotSame(ow.wrap(c), ow.wrap(c));
- }
-
- @Test
- @Ignore // ModelCache is current removed in FM3
- public void modelCacheOn() throws Exception {
- DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .useModelCache(true).build();
- assertTrue(ow.getUseModelCache());
-
- TestBean obj = new TestBean();
- assertSame(ow.wrap(obj), ow.wrap(obj));
-
- C c = new C();
- TemplateModel wrappedC = ow.wrap(c);
- assertSame(wrappedC, ow.wrap(c));
-
- ow.clearClassIntrospecitonCache();
- assertNotSame(wrappedC, ow.wrap(c));
- assertSame(ow.wrap(c), ow.wrap(c));
- }
-
- static public class C { }
-
- public static class TestBean {
- //
- }
-
-}
[35/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
new file mode 100644
index 0000000..2a0ae9d
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringUtilTest.java
@@ -0,0 +1,403 @@
+/*
+ * 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.core.util;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.regex.Pattern;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+public class StringUtilTest {
+
+ @Test
+ public void testV2319() {
+ assertEquals("\\n\\r\\f\\b\\t\\x00\\x19", _StringUtil.javaScriptStringEnc("\n\r\f\b\t\u0000\u0019"));
+ }
+
+ @Test
+ public void testControlChars() {
+ assertEsc(
+ "\n\r\f\b\t \u0000\u0019\u001F \u007F\u0080\u009F \u2028\u2029",
+ "\\n\\r\\f\\b\\t \\x00\\x19\\x1F \\x7F\\x80\\x9F \\u2028\\u2029",
+ "\\n\\r\\f\\b\\t \\u0000\\u0019\\u001F \\u007F\\u0080\\u009F \\u2028\\u2029");
+ }
+
+ @Test
+ public void testHtmlChars() {
+ assertEsc(
+ "<safe>/>->]> </foo> <!-- --> <![CDATA[ ]]> <?php?>",
+ "<safe>/>->]> <\\/foo> \\x3C!-- --\\> \\x3C![CDATA[ ]]\\> \\x3C?php?>",
+ "<safe>/>->]> <\\/foo> \\u003C!-- --\\u003E \\u003C![CDATA[ ]]\\u003E \\u003C?php?>");
+ assertEsc("<!c", "\\x3C!c", "\\u003C!c");
+ assertEsc("c<!", "c\\x3C!", "c\\u003C!");
+ assertEsc("c<", "c\\x3C", "c\\u003C");
+ assertEsc("c<c", "c<c", "c<c");
+ assertEsc("<c", "<c", "<c");
+ assertEsc(">", "\\>", "\\u003E");
+ assertEsc("->", "-\\>", "-\\u003E");
+ assertEsc("-->", "--\\>", "--\\u003E");
+ assertEsc("c-->", "c--\\>", "c--\\u003E");
+ assertEsc("-->c", "--\\>c", "--\\u003Ec");
+ assertEsc("]>", "]\\>", "]\\u003E");
+ assertEsc("]]>", "]]\\>", "]]\\u003E");
+ assertEsc("c]]>", "c]]\\>", "c]]\\u003E");
+ assertEsc("]]>c", "]]\\>c", "]]\\u003Ec");
+ assertEsc("c->", "c->", "c->");
+ assertEsc("c>", "c>", "c>");
+ assertEsc("-->", "--\\>", "--\\u003E");
+ assertEsc("/", "\\/", "\\/");
+ assertEsc("/c", "\\/c", "\\/c");
+ assertEsc("</", "<\\/", "<\\/");
+ assertEsc("</c", "<\\/c", "<\\/c");
+ assertEsc("c/", "c/", "c/");
+ }
+
+ @Test
+ public void testJSChars() {
+ assertEsc("\"", "\\\"", "\\\"");
+ assertEsc("'", "\\'", "'");
+ assertEsc("\\", "\\\\", "\\\\");
+ }
+
+ @Test
+ public void testSameStringsReturned() {
+ String s = "==> I/m <safe>!";
+ assertTrue(s == _StringUtil.jsStringEnc(s, false)); // "==" because is must return the same object
+ assertTrue(s == _StringUtil.jsStringEnc(s, true));
+
+ s = "";
+ assertTrue(s == _StringUtil.jsStringEnc(s, false));
+ assertTrue(s == _StringUtil.jsStringEnc(s, true));
+
+ s = "\u00E1rv\u00EDzt\u0171r\u0151 \u3020";
+ assertEquals(s, _StringUtil.jsStringEnc(s, false));
+ assertTrue(s == _StringUtil.jsStringEnc(s, false));
+ assertTrue(s == _StringUtil.jsStringEnc(s, true));
+ }
+
+ @Test
+ public void testOneOffs() {
+ assertEsc("c\"c\"cc\"\"c", "c\\\"c\\\"cc\\\"\\\"c", "c\\\"c\\\"cc\\\"\\\"c");
+ assertEsc("\"c\"cc\"", "\\\"c\\\"cc\\\"", "\\\"c\\\"cc\\\"");
+ assertEsc("c/c/cc//c", "c/c/cc//c", "c/c/cc//c");
+ assertEsc("c<c<cc<<c", "c<c<cc<<c", "c<c<cc<<c");
+ assertEsc("/<", "\\/\\x3C", "\\/\\u003C");
+ assertEsc(">", "\\>", "\\u003E");
+ assertEsc("]>", "]\\>", "]\\u003E");
+ assertEsc("->", "-\\>", "-\\u003E");
+ }
+
+ private void assertEsc(String s, String javaScript, String json) {
+ assertEquals(javaScript, _StringUtil.jsStringEnc(s, false));
+ assertEquals(json, _StringUtil.jsStringEnc(s, true));
+ }
+
+ @Test
+ public void testTrim() {
+ assertSame(_CollectionUtil.EMPTY_CHAR_ARRAY, _StringUtil.trim(_CollectionUtil.EMPTY_CHAR_ARRAY));
+ assertSame(_CollectionUtil.EMPTY_CHAR_ARRAY, _StringUtil.trim(" \t\u0001 ".toCharArray()));
+ {
+ char[] cs = "foo".toCharArray();
+ assertSame(cs, cs);
+ }
+ assertArrayEquals("foo".toCharArray(), _StringUtil.trim("foo ".toCharArray()));
+ assertArrayEquals("foo".toCharArray(), _StringUtil.trim(" foo".toCharArray()));
+ assertArrayEquals("foo".toCharArray(), _StringUtil.trim(" foo ".toCharArray()));
+ assertArrayEquals("foo".toCharArray(), _StringUtil.trim("\t\tfoo \r\n".toCharArray()));
+ assertArrayEquals("x".toCharArray(), _StringUtil.trim(" x ".toCharArray()));
+ assertArrayEquals("x y z".toCharArray(), _StringUtil.trim(" x y z ".toCharArray()));
+ }
+
+ @Test
+ public void testIsTrimmedToEmpty() {
+ assertTrue(_StringUtil.isTrimmableToEmpty("".toCharArray()));
+ assertTrue(_StringUtil.isTrimmableToEmpty("\r\r\n\u0001".toCharArray()));
+ assertFalse(_StringUtil.isTrimmableToEmpty("x".toCharArray()));
+ assertFalse(_StringUtil.isTrimmableToEmpty(" x ".toCharArray()));
+ }
+
+ @Test
+ public void testJQuote() {
+ assertEquals("null", _StringUtil.jQuote(null));
+ assertEquals("\"foo\"", _StringUtil.jQuote("foo"));
+ assertEquals("\"123\"", _StringUtil.jQuote(Integer.valueOf(123)));
+ assertEquals("\"foo's \\\"bar\\\"\"",
+ _StringUtil.jQuote("foo's \"bar\""));
+ assertEquals("\"\\n\\r\\t\\u0001\"",
+ _StringUtil.jQuote("\n\r\t\u0001"));
+ assertEquals("\"<\\nb\\rc\\td\\u0001>\"",
+ _StringUtil.jQuote("<\nb\rc\td\u0001>"));
+ }
+
+ @Test
+ public void testJQuoteNoXSS() {
+ assertEquals("null", _StringUtil.jQuoteNoXSS(null));
+ assertEquals("\"foo\"", _StringUtil.jQuoteNoXSS("foo"));
+ assertEquals("\"123\"", _StringUtil.jQuoteNoXSS(Integer.valueOf(123)));
+ assertEquals("\"foo's \\\"bar\\\"\"",
+ _StringUtil.jQuoteNoXSS("foo's \"bar\""));
+ assertEquals("\"\\n\\r\\t\\u0001\"",
+ _StringUtil.jQuoteNoXSS("\n\r\t\u0001"));
+ assertEquals("\"\\u003C\\nb\\rc\\td\\u0001>\"",
+ _StringUtil.jQuoteNoXSS("<\nb\rc\td\u0001>"));
+ assertEquals("\"\\u003C\\nb\\rc\\td\\u0001>\"",
+ _StringUtil.jQuoteNoXSS((Object) "<\nb\rc\td\u0001>"));
+ }
+
+ @Test
+ public void testGlobToRegularExpression() {
+ assertGlobMatches("a/b/c.ftl", "a/b/c.ftl");
+ assertGlobDoesNotMatch("/a/b/cxftl", "/a/b/c.ftl", "a/b/C.ftl");
+
+ assertGlobMatches("a/b/*.ftl", "a/b/.ftl", "a/b/x.ftl", "a/b/xx.ftl");
+ assertGlobDoesNotMatch("a/b/*.ftl", "a/c/x.ftl", "a/b/c/x.ftl", "/a/b/x.ftl", "a/b/xxftl");
+
+ assertGlobMatches("a/b/?.ftl", "a/b/x.ftl");
+ assertGlobDoesNotMatch("a/b/?.ftl", "a/c/x.ftl", "a/b/.ftl", "a/b/xx.ftl", "a/b/xxftl");
+
+ assertGlobMatches("a/**/c.ftl", "a/b/c.ftl", "a/c.ftl", "a/b/b2/b3/c.ftl", "a//c.ftl");
+ assertGlobDoesNotMatch("a/**/c.ftl", "x/b/c.ftl", "a/b/x.ftl");
+
+ assertGlobMatches("**/c.ftl", "a/b/c.ftl", "c.ftl", "/c.ftl", "///c.ftl");
+ assertGlobDoesNotMatch("**/c.ftl", "a/b/x.ftl");
+
+ assertGlobMatches("a/b/**", "a/b/c.ftl", "a/b/c2/c.ftl", "a/b/", "a/b/c/");
+ assertGlobDoesNotMatch("a/b.ftl");
+
+ assertGlobMatches("**", "a/b/c.ftl", "");
+
+ assertGlobMatches("\\[\\{\\*\\?\\}\\]\\\\", "[{*?}]\\");
+ assertGlobDoesNotMatch("\\[\\{\\*\\?\\}\\]\\\\", "[{xx}]\\");
+
+ assertGlobMatches("a/b/\\?.ftl", "a/b/?.ftl");
+ assertGlobDoesNotMatch("a/b/\\?.ftl", "a/b/x.ftl");
+
+ assertGlobMatches("\\?\\?.ftl", "??.ftl");
+ assertGlobMatches("\\\\\\\\", "\\\\");
+ assertGlobMatches("\\\\\\\\?", "\\\\x");
+ assertGlobMatches("x\\", "x");
+
+ assertGlobMatches("???*", "123", "1234", "12345");
+ assertGlobDoesNotMatch("???*", "12", "1", "");
+
+ assertGlobMatches("**/a??/b*.ftl", "a11/b1.ftl", "x/a11/b123.ftl", "x/y/a11/b.ftl");
+ assertGlobDoesNotMatch("**/a??/b*.ftl", "a1/b1.ftl", "x/a11/c123.ftl");
+
+ assertFalse(_StringUtil.globToRegularExpression("ab*").matcher("aBc").matches());
+ assertTrue(_StringUtil.globToRegularExpression("ab*", true).matcher("aBc").matches());
+ assertTrue(_StringUtil.globToRegularExpression("ab", true).matcher("aB").matches());
+ assertTrue(_StringUtil.globToRegularExpression("\u00E1b*", true).matcher("\u00C1bc").matches());
+
+ try {
+ _StringUtil.globToRegularExpression("x**/y");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), Matchers.containsString("**"));
+ }
+
+ try {
+ _StringUtil.globToRegularExpression("**y");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), Matchers.containsString("**"));
+ }
+
+ try {
+ _StringUtil.globToRegularExpression("[ab]c");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), Matchers.containsString("unsupported"));
+ }
+
+ try {
+ _StringUtil.globToRegularExpression("{aa,bb}c");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage(), Matchers.containsString("unsupported"));
+ }
+ }
+
+ private void assertGlobMatches(String glob, String... ss) {
+ Pattern pattern = _StringUtil.globToRegularExpression(glob);
+ for (String s : ss) {
+ if (!pattern.matcher(s).matches()) {
+ fail("Glob " + glob + " (regexp: " + pattern + ") doesn't match " + s);
+ }
+ }
+ }
+
+ private void assertGlobDoesNotMatch(String glob, String... ss) {
+ Pattern pattern = _StringUtil.globToRegularExpression(glob);
+ for (String s : ss) {
+ if (pattern.matcher(s).matches()) {
+ fail("Glob " + glob + " (regexp: " + pattern + ") matches " + s);
+ }
+ }
+ }
+
+ @Test
+ public void testHTMLEnc() {
+ String s = "";
+ assertSame(s, _StringUtil.XMLEncNA(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.XMLEncNA(s));
+
+ assertEquals("a&b<c>d"e'f", _StringUtil.XMLEncNA("a&b<c>d\"e'f"));
+ assertEquals("<", _StringUtil.XMLEncNA("<"));
+ assertEquals("<a", _StringUtil.XMLEncNA("<a"));
+ assertEquals("<a>", _StringUtil.XMLEncNA("<a>"));
+ assertEquals("a>", _StringUtil.XMLEncNA("a>"));
+ assertEquals("<>", _StringUtil.XMLEncNA("<>"));
+ assertEquals("a<>b", _StringUtil.XMLEncNA("a<>b"));
+ }
+
+ @Test
+ public void testXHTMLEnc() throws IOException {
+ String s = "";
+ assertSame(s, _StringUtil.XHTMLEnc(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.XHTMLEnc(s));
+
+ testXHTMLEnc("a&b<c>d"e'f", "a&b<c>d\"e'f");
+ testXHTMLEnc("<", "<");
+ testXHTMLEnc("<a", "<a");
+ testXHTMLEnc("<a>", "<a>");
+ testXHTMLEnc("a>", "a>");
+ testXHTMLEnc("<>", "<>");
+ testXHTMLEnc("a<>b", "a<>b");
+ }
+
+ private void testXHTMLEnc(String expected, String in) throws IOException {
+ assertEquals(expected, _StringUtil.XHTMLEnc(in));
+
+ StringWriter sw = new StringWriter();
+ _StringUtil.XHTMLEnc(in, sw);
+ assertEquals(expected, sw.toString());
+ }
+
+ @Test
+ public void testXMLEnc() throws IOException {
+ String s = "";
+ assertSame(s, _StringUtil.XMLEnc(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.XMLEnc(s));
+
+ testXMLEnc("a&b<c>d"e'f", "a&b<c>d\"e'f");
+ testXMLEnc("<", "<");
+ testXMLEnc("<a", "<a");
+ testXMLEnc("<a>", "<a>");
+ testXMLEnc("a>", "a>");
+ testXMLEnc("<>", "<>");
+ testXMLEnc("a<>b", "a<>b");
+ }
+
+ private void testXMLEnc(String expected, String in) throws IOException {
+ assertEquals(expected, _StringUtil.XMLEnc(in));
+
+ StringWriter sw = new StringWriter();
+ _StringUtil.XMLEnc(in, sw);
+ assertEquals(expected, sw.toString());
+ }
+
+ @Test
+ public void testXMLEncQAttr() throws IOException {
+ String s = "";
+ assertSame(s, _StringUtil.XMLEncQAttr(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.XMLEncQAttr(s));
+
+ assertEquals("a&b<c>d"e'f", _StringUtil.XMLEncQAttr("a&b<c>d\"e'f"));
+ assertEquals("<", _StringUtil.XMLEncQAttr("<"));
+ assertEquals("<a", _StringUtil.XMLEncQAttr("<a"));
+ assertEquals("<a>", _StringUtil.XMLEncQAttr("<a>"));
+ assertEquals("a>", _StringUtil.XMLEncQAttr("a>"));
+ assertEquals("<>", _StringUtil.XMLEncQAttr("<>"));
+ assertEquals("a<>b", _StringUtil.XMLEncQAttr("a<>b"));
+ }
+
+ @Test
+ public void testXMLEncNQG() throws IOException {
+ String s = "";
+ assertSame(s, _StringUtil.XMLEncNQG(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.XMLEncNQG(s));
+
+ assertEquals("a&b<c>d\"e'f", _StringUtil.XMLEncNQG("a&b<c>d\"e'f"));
+ assertEquals("<", _StringUtil.XMLEncNQG("<"));
+ assertEquals("<a", _StringUtil.XMLEncNQG("<a"));
+ assertEquals("<a>", _StringUtil.XMLEncNQG("<a>"));
+ assertEquals("a>", _StringUtil.XMLEncNQG("a>"));
+ assertEquals("<>", _StringUtil.XMLEncNQG("<>"));
+ assertEquals("a<>b", _StringUtil.XMLEncNQG("a<>b"));
+
+ assertEquals(">", _StringUtil.XMLEncNQG(">"));
+ assertEquals("]>", _StringUtil.XMLEncNQG("]>"));
+ assertEquals("]]>", _StringUtil.XMLEncNQG("]]>"));
+ assertEquals("x]]>", _StringUtil.XMLEncNQG("x]]>"));
+ assertEquals("x]>", _StringUtil.XMLEncNQG("x]>"));
+ assertEquals("]x>", _StringUtil.XMLEncNQG("]x>"));
+ }
+
+ @Test
+ public void testRTFEnc() throws IOException {
+ String s = "";
+ assertSame(s, _StringUtil.RTFEnc(s));
+
+ s = "asd";
+ assertSame(s, _StringUtil.RTFEnc(s));
+
+ testRTFEnc("a\\{b\\}c\\\\d", "a{b}c\\d");
+ testRTFEnc("\\{", "{");
+ testRTFEnc("\\{a", "{a");
+ testRTFEnc("\\{a\\}", "{a}");
+ testRTFEnc("a\\}", "a}");
+ testRTFEnc("\\{\\}", "{}");
+ testRTFEnc("a\\{\\}b", "a{}b");
+ }
+
+ private void testRTFEnc(String expected, String in) throws IOException {
+ assertEquals(expected, _StringUtil.RTFEnc(in));
+
+ StringWriter sw = new StringWriter();
+ _StringUtil.RTFEnc(in, sw);
+ assertEquals(expected, sw.toString());
+ }
+
+ @Test
+ public void testNormalizeEOLs() {
+ assertNull(_StringUtil.normalizeEOLs(null));
+ assertEquals("", _StringUtil.normalizeEOLs(""));
+ assertEquals("x", _StringUtil.normalizeEOLs("x"));
+ assertEquals("x\ny", _StringUtil.normalizeEOLs("x\ny"));
+ assertEquals("x\ny", _StringUtil.normalizeEOLs("x\r\ny"));
+ assertEquals("x\ny", _StringUtil.normalizeEOLs("x\ry"));
+ assertEquals("\n\n\n\n\n\n", _StringUtil.normalizeEOLs("\n\r\r\r\n\r\n\r"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
new file mode 100644
index 0000000..8900d2b
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
@@ -0,0 +1,365 @@
+/*
+ * 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.core.valueformat;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateConfiguration;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.TemplateDirectiveBody;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.impl.SimpleNumber;
+import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
+import org.apache.freemarker.core.templateresolver.TemplateConfigurationFactory;
+import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.HexTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.LocaleSensitiveTemplateNumberFormatFactory;
+import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.impl.AliasTemplateNumberFormatFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class NumberFormatTest extends TemplateTest {
+
+ @Test
+ public void testUnknownCustomFormat() throws Exception {
+ {
+ setConfigurationWithNumberFormat("@noSuchFormat");
+ Throwable exc = assertErrorContains("${1}", "\"@noSuchFormat\"", "\"noSuchFormat\"");
+ assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
+ }
+
+ {
+ setConfigurationWithNumberFormat("number");
+ Throwable exc = assertErrorContains("${1?string('@noSuchFormat2')}",
+ "\"@noSuchFormat2\"", "\"noSuchFormat2\"");
+ assertThat(exc.getCause(), instanceOf(UndefinedCustomFormatException.class));
+ }
+ }
+
+ @Test
+ public void testStringBI() throws Exception {
+ setConfigurationWithNumberFormat(null);
+ assertOutput("${11} ${11?string.@hex} ${12} ${12?string.@hex}", "11 b 12 c");
+ }
+
+ @Test
+ public void testSetting() throws Exception {
+ setConfigurationWithNumberFormat("@hex");
+ assertOutput("${11?string.number} ${11} ${12?string.number} ${12}", "11 b 12 c");
+ }
+
+ @Test
+ public void testSetting2() throws Exception {
+ setConfigurationWithNumberFormat(null);
+ assertOutput(
+ "<#setting numberFormat='@hex'>${11?string.number} ${11} ${12?string.number} ${12} ${13?string}"
+ + "<#setting numberFormat='@loc'>${11?string.number} ${11} ${12?string.number} ${12} ${13?string}",
+ "11 b 12 c d"
+ + "11 11_en_US 12 12_en_US 13_en_US");
+ }
+
+ @Test
+ public void testUnformattableNumber() throws Exception {
+ setConfigurationWithNumberFormat("@hex");
+ assertErrorContains("${1.1}", "hexadecimal int", "doesn't fit into an int");
+ }
+
+ @Test
+ public void testLocaleSensitive() throws Exception {
+ setConfigurationWithNumberFormat("@loc");
+ assertOutput("${1.1}", "1.1_en_US");
+ setConfigurationWithNumberFormat("@loc", null, null, Locale.GERMANY);
+ assertOutput("${1.1}", "1.1_de_DE");
+ }
+
+ @Test
+ public void testLocaleSensitive2() throws Exception {
+ setConfigurationWithNumberFormat("@loc");
+ assertOutput("${1.1} <#setting locale='de_DE'>${1.1}", "1.1_en_US 1.1_de_DE");
+ }
+
+ @Test
+ public void testCustomParameterized() throws Exception {
+ setConfigurationWithNumberFormat("@base 2");
+ assertOutput("${11}", "1011");
+ assertOutput("${11?string}", "1011");
+ assertOutput("${11?string.@base_3}", "102");
+
+ assertErrorContains("${11?string.@base_xyz}", "\"@base_xyz\"", "\"xyz\"");
+ setConfigurationWithNumberFormat("@base");
+ assertErrorContains("${11}", "\"@base\"", "format parameter is required");
+ }
+
+ @Test
+ public void testCustomWithFallback() throws Exception {
+ Configuration cfg = getConfiguration();
+ setConfigurationWithNumberFormat("@base 2|0.0#");
+ assertOutput("${11}", "1011");
+ assertOutput("${11.34}", "11.34");
+ assertOutput("${11?string('@base 3|0.00')}", "102");
+ assertOutput("${11.2?string('@base 3|0.00')}", "11.20");
+ }
+
+ @Test
+ public void testEnvironmentGetters() throws Exception {
+ setConfigurationWithNumberFormat(null);
+
+ Template t = new Template(null, "", getConfiguration());
+ Environment env = t.createProcessingEnvironment(null, null);
+
+ TemplateNumberFormat defF = env.getTemplateNumberFormat();
+ //
+ TemplateNumberFormat explF = env.getTemplateNumberFormat("0.00");
+ assertEquals("1.25", explF.formatToPlainText(new SimpleNumber(1.25)));
+ //
+ TemplateNumberFormat expl2F = env.getTemplateNumberFormat("@loc");
+ assertEquals("1.25_en_US", expl2F.formatToPlainText(new SimpleNumber(1.25)));
+
+ TemplateNumberFormat explFFr = env.getTemplateNumberFormat("0.00", Locale.FRANCE);
+ assertNotSame(explF, explFFr);
+ assertEquals("1,25", explFFr.formatToPlainText(new SimpleNumber(1.25)));
+ //
+ TemplateNumberFormat expl2FFr = env.getTemplateNumberFormat("@loc", Locale.FRANCE);
+ assertEquals("1.25_fr_FR", expl2FFr.formatToPlainText(new SimpleNumber(1.25)));
+
+ assertSame(env.getTemplateNumberFormat(), defF);
+ //
+ assertSame(env.getTemplateNumberFormat("0.00"), explF);
+ //
+ assertSame(env.getTemplateNumberFormat("@loc"), expl2F);
+ }
+
+ /**
+ * ?string formats lazily (at least in 2.3.x), so it must make a snapshot of the format inputs when it's called.
+ */
+ @Test
+ @Ignore // [FM3] We want to rework BI-s so that lazy evaluation won't be needed. Then this will go away too.
+ public void testStringBIDoesSnapshot() throws Exception {
+ // TemplateNumberModel-s shouldn't change, but we have to keep BC when that still happens.
+ final MutableTemplateNumberModel nm = new MutableTemplateNumberModel();
+ nm.setNumber(123);
+ addToDataModel("n", nm);
+ addToDataModel("incN", new TemplateDirectiveModel() {
+
+ @Override
+ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ nm.setNumber(nm.getAsNumber().intValue() + 1);
+ }
+ });
+ assertOutput(
+ "<#assign s1 = n?string>"
+ + "<#setting numberFormat='@loc'>"
+ + "<#assign s2 = n?string>"
+ + "<#setting numberFormat='@hex'>"
+ + "<#assign s3 = n?string>"
+ + "${s1} ${s2} ${s3}",
+ "123 123_en_US 7b");
+ assertOutput(
+ "<#assign s1 = n?string>"
+ + "<@incN />"
+ + "<#assign s2 = n?string>"
+ + "${s1} ${s2}",
+ "123 124");
+ }
+
+ @Test
+ public void testNullInModel() throws Exception {
+ addToDataModel("n", new MutableTemplateNumberModel());
+ assertErrorContains("${n}", "nothing inside it");
+ assertErrorContains("${n?string}", "nothing inside it");
+ }
+
+ @Test
+ public void testAtPrefix() throws Exception {
+ Configuration cfg = getConfiguration();
+
+ setConfigurationWithNumberFormat("@hex");
+ assertOutput("${10}", "a");
+ setConfigurationWithNumberFormat("'@'0");
+ assertOutput("${10}", "@10");
+ setConfigurationWithNumberFormat("@@0");
+ assertOutput("${10}", "@@10");
+
+ setConfigurationWithNumberFormat(
+ "@hex", Collections.<String, TemplateNumberFormatFactory>emptyMap());
+ assertErrorContains("${10}", "custom", "\"hex\"");
+
+ setConfigurationWithNumberFormat(
+ "'@'0", Collections.<String, TemplateNumberFormatFactory>emptyMap());
+ assertOutput("${10}", "@10");
+
+ setConfigurationWithNumberFormat(
+ "@@0", Collections.<String, TemplateNumberFormatFactory>emptyMap());
+ assertOutput("${10}", "@@10");
+ }
+
+ @Test
+ public void testAlieses() throws Exception {
+ setConfigurationWithNumberFormat(
+ "'@'0",
+ ImmutableMap.of(
+ "f", new AliasTemplateNumberFormatFactory("0.#'f'"),
+ "d", new AliasTemplateNumberFormatFactory("0.0#"),
+ "hex", HexTemplateNumberFormatFactory.INSTANCE),
+ new ConditionalTemplateConfigurationFactory(
+ new FileNameGlobMatcher("*2*"),
+ new TemplateConfiguration.Builder()
+ .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
+ "d", new AliasTemplateNumberFormatFactory("0.#'d'"),
+ "i", new AliasTemplateNumberFormatFactory("@hex")))
+ .build()));
+
+ String commonFtl = "${1?string.@f} ${1?string.@d} "
+ + "<#setting locale='fr_FR'>${1.5?string.@d} "
+ + "<#attempt>${10?string.@i}<#recover>E</#attempt>";
+ addTemplate("t1.ftl", commonFtl);
+ addTemplate("t2.ftl", commonFtl);
+
+ assertOutputForNamed("t1.ftl", "1f 1.0 1,5 E");
+ assertOutputForNamed("t2.ftl", "1f 1d 1,5d a");
+ }
+
+ @Test
+ public void testAlieses2() throws Exception {
+ setConfigurationWithNumberFormat(
+ "@n",
+ ImmutableMap.<String, TemplateNumberFormatFactory>of(
+ "n", new AliasTemplateNumberFormatFactory("0.0",
+ ImmutableMap.of(
+ new Locale("en"), "0.0'_en'",
+ Locale.UK, "0.0'_en_GB'",
+ Locale.FRANCE, "0.0'_fr_FR'"))));
+ assertOutput(
+ "<#setting locale='en_US'>${1} "
+ + "<#setting locale='en_GB'>${1} "
+ + "<#setting locale='en_GB_Win'>${1} "
+ + "<#setting locale='fr_FR'>${1} "
+ + "<#setting locale='hu_HU'>${1}",
+ "1.0_en 1.0_en_GB 1.0_en_GB 1,0_fr_FR 1,0");
+ }
+
+ @Test
+ public void testMarkupFormat() throws IOException, TemplateException {
+ setConfigurationWithNumberFormat("@printfG_3");
+
+ String commonFTL = "${1234567} ${'cat:' + 1234567} ${0.0000123}";
+ String commonOutput = "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>";
+ assertOutput(commonFTL, commonOutput);
+ assertOutput("<#ftl outputFormat='HTML'>" + commonFTL, commonOutput);
+ assertOutput("<#escape x as x?html>" + commonFTL + "</#escape>", commonOutput);
+ assertOutput("<#escape x as x?xhtml>" + commonFTL + "</#escape>", commonOutput);
+ assertOutput("<#escape x as x?xml>" + commonFTL + "</#escape>", commonOutput);
+ assertOutput("${\"" + commonFTL + "\"}", "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>");
+ assertErrorContains("<#ftl outputFormat='plainText'>" + commonFTL, "HTML", "plainText", "conversion");
+ }
+
+ @Test
+ public void testPrintG() throws IOException, TemplateException {
+ setConfigurationWithNumberFormat(null);
+ for (Number n : new Number[] {
+ 1234567, 1234567L, 1234567d, 1234567f, BigInteger.valueOf(1234567), BigDecimal.valueOf(1234567) }) {
+ addToDataModel("n", n);
+
+ assertOutput("${n?string.@printfG}", "1.23457E+06");
+ assertOutput("${n?string.@printfG_3}", "1.23E+06");
+ assertOutput("${n?string.@printfG_7}", "1234567");
+ assertOutput("${0.0000123?string.@printfG}", "1.23000E-05");
+ }
+ }
+
+ private void setConfigurationWithNumberFormat(
+ String numberFormat,
+ Map<String, TemplateNumberFormatFactory> customNumberFormats,
+ TemplateConfigurationFactory templateConfigurationFactory,
+ Locale locale) {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder(Configuration.VERSION_3_0_0);
+
+ if (numberFormat != null) {
+ cfgB.setNumberFormat(numberFormat);
+ }
+ cfgB.setCustomNumberFormats(
+ customNumberFormats != null ? customNumberFormats
+ : ImmutableMap.of(
+ "hex", HexTemplateNumberFormatFactory.INSTANCE,
+ "loc", LocaleSensitiveTemplateNumberFormatFactory.INSTANCE,
+ "base", BaseNTemplateNumberFormatFactory.INSTANCE,
+ "printfG", PrintfGTemplateNumberFormatFactory.INSTANCE));
+ if (locale != null) {
+ cfgB.setLocale(locale);
+ }
+ if (templateConfigurationFactory != null) {
+ cfgB.setTemplateConfigurations(templateConfigurationFactory);
+ }
+
+ setConfiguration(cfgB.build());
+ }
+
+ private void setConfigurationWithNumberFormat(String numberFormat) {
+ setConfigurationWithNumberFormat(numberFormat, null, null, null);
+ }
+
+ private void setConfigurationWithNumberFormat(
+ String numberFormat, Map<String, TemplateNumberFormatFactory> customNumberFormats) {
+ setConfigurationWithNumberFormat(numberFormat, customNumberFormats, null, null);
+ }
+
+ private void setConfigurationWithNumberFormat(
+ String numberFormat, Map<String, TemplateNumberFormatFactory> customNumberFormats,
+ TemplateConfigurationFactory templateConfigurationFactory) {
+ setConfigurationWithNumberFormat(numberFormat, customNumberFormats, templateConfigurationFactory, null);
+ }
+
+ private static class MutableTemplateNumberModel implements TemplateNumberModel {
+
+ private Number number;
+
+ public void setNumber(Number number) {
+ this.number = number;
+ }
+
+ @Override
+ public Number getAsNumber() throws TemplateModelException {
+ return number;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
new file mode 100644
index 0000000..76c0bfc
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java
@@ -0,0 +1,343 @@
+/*
+ * 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.core.valueformat.impl;
+
+import static org.apache.freemarker.test.hamcerst.Matchers.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.util.Locale;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class ExtendedDecimalFormatTest extends TemplateTest {
+
+ private static final Locale LOC = Locale.US;
+ private static final DecimalFormatSymbols SYMS = DecimalFormatSymbols.getInstance(LOC);
+
+ @Test
+ public void testNonExtended() throws ParseException {
+ for (String fStr : new String[] { "0.00", "0.###", "#,#0.###", "#0.####", "0.0;m", "0.0;",
+ "0'x'", "0'x';'m'", "0';'", "0';';m", "0';';'#'m';'", "0';;'", "" }) {
+ assertFormatsEquivalent(new DecimalFormat(fStr, SYMS), ExtendedDecimalFormatParser.parse(fStr, LOC));
+ }
+
+ try {
+ new DecimalFormat(";");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";", LOC);
+ } catch (ParseException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testNonExtended2() throws ParseException {
+ assertFormatsEquivalent(new DecimalFormat("0.0", SYMS), ExtendedDecimalFormatParser.parse("0.0;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0.0", SYMS), ExtendedDecimalFormatParser.parse("0.0;;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0.0;m", SYMS), ExtendedDecimalFormatParser.parse("0.0;m;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("", SYMS), ExtendedDecimalFormatParser.parse(";;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0'x'", SYMS), ExtendedDecimalFormatParser.parse("0'x';;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0'x';'m'", SYMS),
+ ExtendedDecimalFormatParser.parse("0'x';'m';", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0';'", SYMS), ExtendedDecimalFormatParser.parse("0';';;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0';';m", SYMS), ExtendedDecimalFormatParser.parse("0';';m;", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0';';'#'m';'", SYMS),
+ ExtendedDecimalFormatParser.parse("0';';'#'m';';", LOC));
+ assertFormatsEquivalent(new DecimalFormat("0';;'", SYMS),
+ ExtendedDecimalFormatParser.parse("0';;';;", LOC));
+
+ try {
+ new DecimalFormat(";m");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ new DecimalFormat("; ;");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ ExtendedDecimalFormatParser.parse("; ;", LOC);
+ fail();
+ } catch (ParseException e) {
+ // Expected
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";m", LOC);
+ fail();
+ } catch (ParseException e) {
+ // Expected
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";m;", LOC);
+ fail();
+ } catch (ParseException e) {
+ // Expected
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testExtendedParamsParsing() throws ParseException {
+ for (String fs : new String[] {
+ "00.##;; decimalSeparator='D'",
+ "00.##;;decimalSeparator=D",
+ "00.##;; decimalSeparator = D ", "00.##;; decimalSeparator = 'D' " }) {
+ assertFormatted(fs, 1.125, "01D12");
+ }
+ for (String fs : new String[] {
+ ",#0.0;; decimalSeparator=D, groupingSeparator=_",
+ ",#0.0;;decimalSeparator=D,groupingSeparator=_",
+ ",#0.0;; decimalSeparator = D , groupingSeparator = _ ",
+ ",#0.0;; decimalSeparator='D', groupingSeparator='_'"
+ }) {
+ assertFormatted(fs, 12345, "1_23_45D0");
+ }
+
+ assertFormatted("0.0;;infinity=infinity", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity='infinity'", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity=\"infinity\"", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity=''", Double.POSITIVE_INFINITY, "");
+ assertFormatted("0.0;;infinity=\"\"", Double.POSITIVE_INFINITY, "");
+ assertFormatted("0.0;;infinity='x''y'", Double.POSITIVE_INFINITY, "x'y");
+ assertFormatted("0.0;;infinity=\"x'y\"", Double.POSITIVE_INFINITY, "x'y");
+ assertFormatted("0.0;;infinity='x\"\"y'", Double.POSITIVE_INFINITY, "x\"\"y");
+ assertFormatted("0.0;;infinity=\"x''y\"", Double.POSITIVE_INFINITY, "x''y");
+ assertFormatted("0.0;;decimalSeparator=''''", 1, "1'0");
+ assertFormatted("0.0;;decimalSeparator=\"'\"", 1, "1'0");
+ assertFormatted("0.0;;decimalSeparator='\"'", 1, "1\"0");
+ assertFormatted("0.0;;decimalSeparator=\"\"\"\"", 1, "1\"0");
+
+ try {
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=D,", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(),
+ allOf(containsStringIgnoringCase("expected a(n) name"), containsString(" end of ")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";;foo=D,", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(),
+ allOf(containsString("\"foo\""), containsString("name")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator='D", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(),
+ allOf(containsString("quotation"), containsString("closed")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=\"D", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(),
+ allOf(containsString("quotation"), containsString("closed")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator='D'groupingSeparator=G", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("separator"), containsString("whitespace"), containsString("comma")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=., groupingSeparator=G", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(), allOf(
+ containsStringIgnoringCase("expected a(n) value"), containsString("., gr[...]")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse("0.0;;decimalSeparator=''", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(), allOf(
+ containsStringIgnoringCase("\"decimalSeparator\""), containsString("exactly 1 char")));
+ }
+ try {
+ ExtendedDecimalFormatParser.parse("0.0;;multipier=ten", LOC);
+ fail();
+ } catch (java.text.ParseException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("\"multipier\""), containsString("\"ten\""), containsString("integer")));
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testExtendedParamsEffect() throws ParseException {
+ assertFormatted("0",
+ 1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
+ assertFormatted("0;; roundingMode=halfEven",
+ 1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
+ assertFormatted("0;; roundingMode=halfUp",
+ 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-3", -1.6, "-2");
+ assertFormatted("0;; roundingMode=halfDown",
+ 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-2");
+ assertFormatted("0;; roundingMode=floor",
+ 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
+ assertFormatted("0;; roundingMode=ceiling",
+ 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
+ assertFormatted("0;; roundingMode=up",
+ 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
+ assertFormatted("0;; roundingMode=down",
+ 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
+ assertFormatted("0;; roundingMode=unnecessary", 2, "2");
+ try {
+ assertFormatted("0;; roundingMode=unnecessary", 2.5, "2");
+ fail();
+ } catch (ArithmeticException e) {
+ // Expected
+ }
+
+ assertFormatted("0.##;; multipier=100", 12.345, "1234.5");
+ assertFormatted("0.##;; multipier=1000", 12.345, "12345");
+
+ assertFormatted(",##0.##;; groupingSeparator=_ decimalSeparator=D", 12345.1, "12_345D1", 1, "1");
+
+ assertFormatted("0.##E0;; exponentSeparator='*10^'", 12345.1, "1.23*10^4");
+
+ assertFormatted("0.##;; minusSign=m", -1, "m1", 1, "1");
+
+ assertFormatted("0.##;; infinity=foo", Double.POSITIVE_INFINITY, "foo", Double.NEGATIVE_INFINITY, "-foo");
+
+ assertFormatted("0.##;; nan=foo", Double.NaN, "foo");
+
+ assertFormatted("0%;; percent='c'", 0.75, "75c");
+
+ assertFormatted("0\u2030;; perMill='m'", 0.75, "750m");
+
+ assertFormatted("0.00;; zeroDigit='@'", 10.5, "A@.E@");
+
+ assertFormatted("0;; currencyCode=USD", 10, "10");
+ assertFormatted("0 \u00A4;; currencyCode=USD", 10, "10 $");
+ assertFormatted("0 \u00A4\u00A4;; currencyCode=USD", 10, "10 USD");
+ assertFormatted(Locale.GERMANY, "0 \u00A4;; currencyCode=EUR", 10, "10 \u20AC");
+ assertFormatted(Locale.GERMANY, "0 \u00A4\u00A4;; currencyCode=EUR", 10, "10 EUR");
+ try {
+ assertFormatted("0;; currencyCode=USDX", 10, "10");
+ } catch (ParseException e) {
+ assertThat(e.getMessage(), containsString("ISO 4217"));
+ }
+ assertFormatted("0 \u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 bucks");
+ // Order doesn't mater:
+ assertFormatted("0 \u00A4;; currencySymbol=bucks currencyCode=USD", 10, "10 bucks");
+ // International symbol isn't affected:
+ assertFormatted("0 \u00A4\u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 USD");
+
+ assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m", 10.5, "10m5 $");
+ assertFormatted("0.0 kg;; monetaryDecimalSeparator=m", 10.5, "10.5 kg");
+ assertFormatted("0.0 \u00A4;; decimalSeparator=d", 10.5, "10.5 $");
+ assertFormatted("0.0 kg;; decimalSeparator=d", 10.5, "10d5 kg");
+ assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10m5 $");
+ assertFormatted("0.0 kg;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10d5 kg");
+ }
+
+ @Test
+ public void testLocale() throws ParseException {
+ assertEquals("1000.0", ExtendedDecimalFormatParser.parse("0.0", Locale.US).format(1000));
+ assertEquals("1000,0", ExtendedDecimalFormatParser.parse("0.0", Locale.FRANCE).format(1000));
+ assertEquals("1_000.0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.US).format(1000));
+ assertEquals("1_000,0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.FRANCE).format(1000));
+ }
+
+ @Test
+ public void testTemplates() throws IOException, TemplateException {
+ TestConfigurationBuilder cfgB = new TestConfigurationBuilder();
+
+ setConfiguration(cfgB.numberFormat(",000.#").build());
+ assertOutput("${1000.15} ${1000.25}", "1,000.2 1,000.2");
+ setConfiguration(cfgB.numberFormat(",000.#;; roundingMode=halfUp groupingSeparator=_").build());;
+ assertOutput("${1000.15} ${1000.25}", "1_000.2 1_000.3");
+ setConfiguration(cfgB.locale(Locale.GERMANY).build());;
+ assertOutput("${1000.15} ${1000.25}", "1_000,2 1_000,3");
+ setConfiguration(cfgB.locale(Locale.US).build());;
+ assertOutput(
+ "${1000.15}; "
+ + "${1000.15?string(',##.#;;groupingSeparator=\" \"')}; "
+ + "<#setting locale='de_DE'>${1000.15}; "
+ + "<#setting numberFormat='0.0;;roundingMode=down'>${1000.15}",
+ "1_000.2; 10 00.2; 1_000,2; 1000,1");
+ assertErrorContains("${1?string('#E')}",
+ TemplateException.class, "\"#E\"", "format string", "exponential");
+ assertErrorContains("<#setting numberFormat='#E'>${1}",
+ TemplateException.class, "\"#E\"", "format string", "exponential");
+ assertErrorContains("<#setting numberFormat=';;foo=bar'>${1}",
+ TemplateException.class, "\"foo\"", "supported");
+ assertErrorContains("<#setting numberFormat='0;;roundingMode=unnecessary'>${1.5}",
+ TemplateException.class, "can't format", "1.5", "UNNECESSARY");
+ }
+
+ private void assertFormatted(String formatString, Object... numberAndExpectedOutput) throws ParseException {
+ assertFormatted(LOC, formatString, numberAndExpectedOutput);
+ }
+
+ private void assertFormatted(Locale loc, String formatString, Object... numberAndExpectedOutput) throws ParseException {
+ if (numberAndExpectedOutput.length % 2 != 0) {
+ throw new IllegalArgumentException();
+ }
+
+ DecimalFormat df = ExtendedDecimalFormatParser.parse(formatString, loc);
+ Number num = null;
+ for (int i = 0; i < numberAndExpectedOutput.length; i++) {
+ if (i % 2 == 0) {
+ num = (Number) numberAndExpectedOutput[i];
+ } else {
+ assertEquals(numberAndExpectedOutput[i], df.format(num));
+ }
+ }
+ }
+
+ private void assertFormatsEquivalent(DecimalFormat dfExpected, DecimalFormat dfActual) {
+ for (int signum : new int[] { 1, -1 }) {
+ assertFormatsEquivalent(dfExpected, dfActual, 0);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 0.5);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 0.25);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 0.125);
+ assertFormatsEquivalent(dfExpected, dfActual, signum);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 10);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 100);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 1000);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 10000);
+ assertFormatsEquivalent(dfExpected, dfActual, signum * 100000);
+ }
+ }
+
+ private void assertFormatsEquivalent(DecimalFormat dfExpected, DecimalFormat dfActual, double n) {
+ assertEquals(dfExpected.format(n), dfActual.format(n));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
new file mode 100644
index 0000000..56a15eb
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.dom;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.XMLLoader;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class DOMSiblingTest extends TemplateTest {
+
+ @Before
+ public void setUp() throws SAXException, IOException, ParserConfigurationException {
+ InputSource is = new InputSource(getClass().getResourceAsStream("DOMSiblingTest.xml"));
+ addToDataModel("doc", XMLLoader.toModel(is));
+ }
+
+ @Test
+ public void testBlankPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name?previousSibling}", "\n ");
+ assertOutput("${doc.person.name?previous_sibling}", "\n ");
+ }
+
+ @Test
+ public void testNonBlankPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.address?previousSibling}", "12th August");
+ }
+
+ @Test
+ public void testBlankNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name?nextSibling}", "\n ");
+ assertOutput("${doc.person.name?next_sibling}", "\n ");
+ }
+
+ @Test
+ public void testNonBlankNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.dob?nextSibling}", "Chennai, India");
+ }
+
+ @Test
+ public void testNullPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person?previousSibling?? ?c}", "false");
+ }
+
+ @Test
+ public void testSignificantPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name.@@previous_sibling_element}", "male");
+ }
+
+ @Test
+ public void testSignificantNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name.@@next_sibling_element}", "12th August");
+ }
+
+ @Test
+ public void testNullSignificantPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.phone.@@next_sibling_element?size}", "0");
+ }
+
+ @Test
+ public void testSkippingCommentNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.profession.@@previous_sibling_element}", "Chennai, India");
+ }
+
+ @Test
+ public void testSkippingEmptyCDataNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.hobby.@@previous_sibling_element}", "Software Engineer");
+ }
+
+ @Test
+ public void testValidCDataNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.phone.@@previous_sibling_element?size}", "0");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
new file mode 100644
index 0000000..f135873
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
@@ -0,0 +1,201 @@
+/*
+ * 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.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.test.XMLLoader;
+import org.junit.Test;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+public class DOMSimplifiersTest {
+
+ private static final String COMMON_TEST_XML
+ = "<!DOCTYPE a []><?p?><a>x<![CDATA[y]]><!--c--><?p?>z<?p?><b><!--c--></b><c></c>"
+ + "<d>a<e>c</e>b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>2</f></a><!--c-->";
+
+ private static final String TEXT_MERGE_CONTENT =
+ "<a>"
+ + "a<!--c--><s/>"
+ + "<!--c-->a<s/>"
+ + "a<!--c-->b<s/>"
+ + "<!--c-->a<!--c-->b<!--c--><s/>"
+ + "a<b>b</b>c<s/>"
+ + "a<b>b</b><!--c-->c<s/>"
+ + "a<!--c-->1<b>b<!--c--></b>c<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->1<e>c<!--c-->1</e>d<!--c-->1</b>e<!--c-->1<s/>"
+ + "</a>";
+ private static final String TEXT_MERGE_EXPECTED =
+ "<a>"
+ + "%a<s/>"
+ + "%a<s/>"
+ + "%ab<s/>"
+ + "%ab<s/>"
+ + "%a<b>%b</b>%c<s/>"
+ + "%a<b>%b</b>%c<s/>"
+ + "%a1<b>%b</b>%c1<s/>"
+ + "%a1<b>%bc</b>%d1<s/>"
+ + "%a1<b>%bc</b>%d1<s/>"
+ + "%a1<b>%b1<e>%c1</e>%d1</b>%e1<s/>"
+ + "</a>";
+
+ @Test
+ public void testTest() throws Exception {
+ String expected = "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>%2</f></a><!--c-->";
+ assertEquals(expected, toString(XMLLoader.toDOM(COMMON_TEST_XML)));
+ }
+
+ @Test
+ public void testMergeAdjacentText() throws Exception {
+ Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.mergeAdjacentText(dom);
+ assertEquals(
+ "<!DOCTYPE ...><?p?><a>%xy<!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[12]]></f></a><!--c-->",
+ toString(dom));
+ }
+
+ @Test
+ public void testRemoveComments() throws Exception {
+ Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.removeComments(dom);
+ assertEquals(
+ "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><?p?>%z<?p?><b/><c/>"
+ + "<d>%a<e>%c</e>%b<?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>%2</f></a>",
+ toString(dom));
+ }
+
+ @Test
+ public void testRemovePIs() throws Exception {
+ Document dom = XMLLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.removePIs(dom);
+ assertEquals(
+ "<!DOCTYPE ...><a>%x<![CDATA[y]]><!--c-->%z<b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--></d>"
+ + "<f><![CDATA[1]]>%2</f></a><!--c-->",
+ toString(dom));
+ }
+
+ @Test
+ public void testSimplify() throws Exception {
+ testSimplify(
+ "<!DOCTYPE ...><a>%xyz<b/><c/>"
+ + "<d>%a<e>%c</e>%b</d><f><![CDATA[12]]></f></a>",
+ COMMON_TEST_XML);
+ }
+
+ @Test
+ public void testSimplify2() throws Exception {
+ testSimplify(TEXT_MERGE_EXPECTED, TEXT_MERGE_CONTENT);
+ }
+
+ @Test
+ public void testSimplify3() throws Exception {
+ testSimplify("<a/>", "<a/>");
+ }
+
+ private void testSimplify(String expected, String content)
+ throws SAXException, IOException, ParserConfigurationException {
+ {
+ Document dom = XMLLoader.toDOM(content);
+ NodeModel.simplify(dom);
+ assertEquals(expected, toString(dom));
+ }
+
+ // Must be equivalent:
+ {
+ Document dom = XMLLoader.toDOM(content);
+ NodeModel.removeComments(dom);
+ NodeModel.removePIs(dom);
+ NodeModel.mergeAdjacentText(dom);
+ assertEquals(expected, toString(dom));
+ }
+
+ // Must be equivalent:
+ {
+ Document dom = XMLLoader.toDOM(content);
+ NodeModel.removeComments(dom);
+ NodeModel.removePIs(dom);
+ NodeModel.simplify(dom);
+ assertEquals(expected, toString(dom));
+ }
+ }
+
+ private String toString(Document doc) {
+ StringBuilder sb = new StringBuilder();
+ toString(doc, sb);
+ return sb.toString();
+ }
+
+ private void toString(Node node, StringBuilder sb) {
+ if (node instanceof Document) {
+ childrenToString(node, sb);
+ } else if (node instanceof Element) {
+ if (node.hasChildNodes()) {
+ sb.append("<").append(node.getNodeName()).append(">");
+ childrenToString(node, sb);
+ sb.append("</").append(node.getNodeName()).append(">");
+ } else {
+ sb.append("<").append(node.getNodeName()).append("/>");
+ }
+ } else if (node instanceof Text) {
+ if (node instanceof CDATASection) {
+ sb.append("<![CDATA[").append(node.getNodeValue()).append("]]>");
+ } else {
+ sb.append("%").append(node.getNodeValue());
+ }
+ } else if (node instanceof Comment) {
+ sb.append("<!--").append(node.getNodeValue()).append("-->");
+ } else if (node instanceof ProcessingInstruction) {
+ sb.append("<?").append(node.getNodeName()).append("?>");
+ } else if (node instanceof DocumentType) {
+ sb.append("<!DOCTYPE ...>");
+ } else {
+ throw new IllegalStateException("Unhandled node type: " + node.getClass().getName());
+ }
+ }
+
+ private void childrenToString(Node node, StringBuilder sb) {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ toString(child, sb);
+ child = child.getNextSibling();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMTest.java
new file mode 100644
index 0000000..847f503
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/dom/DOMTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.dom;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.XMLLoader;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class DOMTest extends TemplateTest {
+
+ @Test
+ public void xpathDetectionBugfix() throws Exception {
+ addDocToDataModel("<root><a>A</a><b>B</b><c>C</c></root>");
+ assertOutput("${doc.root.b['following-sibling::c']}", "C");
+ assertOutput("${doc.root.b['following-sibling::*']}", "C");
+ }
+
+ @Test
+ public void xmlnsPrefixes() throws Exception {
+ addDocToDataModel("<root xmlns='http://example.com/ns1' xmlns:ns2='http://example.com/ns2'>"
+ + "<a>A</a><ns2:b>B</ns2:b><c a1='1' ns2:a2='2'/></root>");
+
+ String ftlHeader = "<#ftl ns_prefixes={'D':'http://example.com/ns1', 'n2':'http://example.com/ns2'}>";
+
+ // @@markup:
+ assertOutput("${doc.@@markup}",
+ "<a:root xmlns:a=\"http://example.com/ns1\" xmlns:b=\"http://example.com/ns2\">"
+ + "<a:a>A</a:a><b:b>B</b:b><a:c a1=\"1\" b:a2=\"2\" />"
+ + "</a:root>");
+ assertOutput(ftlHeader
+ + "${doc.@@markup}",
+ "<root xmlns=\"http://example.com/ns1\" xmlns:n2=\"http://example.com/ns2\">"
+ + "<a>A</a><n2:b>B</n2:b><c a1=\"1\" n2:a2=\"2\" /></root>");
+ assertOutput("<#ftl ns_prefixes={'D':'http://example.com/ns1'}>"
+ + "${doc.@@markup}",
+ "<root xmlns=\"http://example.com/ns1\" xmlns:a=\"http://example.com/ns2\">"
+ + "<a>A</a><a:b>B</a:b><c a1=\"1\" a:a2=\"2\" /></root>");
+
+ // When there's no matching prefix declared via the #ftl header, return null for qname:
+ assertOutput("${doc?children[0].@@qname!'null'}", "null");
+ assertOutput("${doc?children[0]?children[1].@@qname!'null'}", "null");
+ assertOutput("${doc?children[0]?children[2]['@*'][1].@@qname!'null'}", "null");
+
+ // When we have prefix declared in the #ftl header:
+ assertOutput(ftlHeader + "${doc?children[0].@@qname}", "root");
+ assertOutput(ftlHeader + "${doc?children[0]?children[1].@@qname}", "n2:b");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2].@@qname}", "c");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][0].@@qname}", "a1");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][1].@@qname}", "n2:a2");
+ // Unfortunately these include the xmlns attributes, but that would be non-BC to fix now:
+ assertThat(getOutput(ftlHeader + "${doc?children[0].@@start_tag}"), startsWith("<root"));
+ assertThat(getOutput(ftlHeader + "${doc?children[0]?children[1].@@start_tag}"), startsWith("<n2:b"));
+ }
+
+ @Test
+ public void namespaceUnaware() throws Exception {
+ addNSUnawareDocToDataModel("<root><x:a>A</x:a><:>B</:><xyz::c>C</xyz::c></root>");
+ assertOutput("${doc.root['x:a']}", "A");
+ assertOutput("${doc.root[':']}", "B");
+ try {
+ assertOutput("${doc.root['xyz::c']}", "C");
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString("xyz"));
+ }
+ }
+
+ private void addDocToDataModel(String xml) throws SAXException, IOException, ParserConfigurationException {
+ addToDataModel("doc", XMLLoader.toModel(new InputSource(new StringReader(xml))));
+ }
+
+ private void addDocToDataModelNoSimplification(String xml) throws SAXException, IOException, ParserConfigurationException {
+ addToDataModel("doc", XMLLoader.toModel(new InputSource(new StringReader(xml)), false));
+ }
+
+ private void addNSUnawareDocToDataModel(String xml) throws ParserConfigurationException, SAXException, IOException {
+ DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
+ newFactory.setNamespaceAware(false);
+ DocumentBuilder builder = newFactory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(new StringReader(xml)));
+ addToDataModel("doc", doc);
+ }
+
+ @Test
+ public void testInvalidAtAtKeyErrors() throws Exception {
+ addDocToDataModel("<r><multipleMatches /><multipleMatches /></r>");
+ assertErrorContains("${doc.r.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.@@start_tag}", "@@start_tag", "not supported", "document");
+ assertErrorContains("${doc.@@}", "\"@@\"", "not supported", "document");
+ assertErrorContains("${doc.r.noMatch.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.r.multipleMatches.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.r.noMatch.@@attributes_markup}", "single XML node", "@@attributes_markup");
+ assertErrorContains("${doc.r.multipleMatches.@@attributes_markup}", "single XML node", "@@attributes_markup");
+ }
+
+ @Test
+ public void testAtAtSiblingElement() throws Exception {
+ addDocToDataModel("<r><a/><b/></r>");
+ assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModel("<r>\r\n\t <a/>\r\n\t <b/>\r\n\t </r>");
+ assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModel("<r>t<a/>t<b/>t</r>");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModelNoSimplification("<r><a/> <!-- --><?pi?> <b/></r>");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+
+ addDocToDataModelNoSimplification("<r><a/> <!-- -->t<!-- --> <b/></r>");
+ assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
new file mode 100644
index 0000000..036bace
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/AutoEscapingExample.java
@@ -0,0 +1,72 @@
+/*
+ * 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.Configuration;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class AutoEscapingExample extends TemplateTest {
+
+ @Test
+ public void testInfoBox() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-infoBox.ftlh");
+ }
+
+ @Test
+ public void testCapture() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-capture.ftlh");
+ }
+
+ @Test
+ public void testMarkup() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-markup.ftlh");
+ }
+
+ @Test
+ public void testConvert() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-convert.ftlh");
+ }
+
+ @Test
+ public void testConvert2() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-convert2.ftl");
+ }
+
+ @Test
+ public void testStringLiteral() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-stringLiteral.ftlh");
+ }
+
+ @Test
+ public void testStringLiteral2() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-stringLiteral2.ftlh");
+ }
+
+ @Test
+ public void testStringConcat() throws Exception {
+ assertOutputForNamed("AutoEscapingExample-stringConcat.ftlh");
+ }
+
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return new TestConfigurationBuilder(AutoEscapingExample.class).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
new file mode 100644
index 0000000..40c1297
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples.java
@@ -0,0 +1,105 @@
+/*
+ * 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.io.IOException;
+
+import org.apache.freemarker.core.TemplateConfiguration;
+import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
+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.FirstMatchTemplateConfigurationFactory;
+import org.apache.freemarker.core.templateresolver.OrMatcher;
+import org.apache.freemarker.core.templateresolver.PathGlobMatcher;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+public class ConfigureOutputFormatExamples extends TemplateTest {
+
+ @Test
+ public void test() throws Exception {
+ addTemplate("mail/t.ftl", "");
+ addTemplate("t.html", "");
+ addTemplate("t.htm", "");
+ addTemplate("t.xml", "");
+ addTemplate("t.rtf", "");
+
+ example2(true);
+ example2(false);
+ example3(true);
+ example3(false);
+ }
+
+ private void example2(boolean javaCfg) throws IOException {
+ setConfiguration(
+ javaCfg
+ ? new TestConfigurationBuilder()
+ .templateConfigurations(
+ new ConditionalTemplateConfigurationFactory(
+ new PathGlobMatcher("mail/**"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(HTMLOutputFormat.INSTANCE)
+ .build()))
+ .build()
+ : new TestConfigurationBuilder()
+ .settings(loadPropertiesFile("ConfigureOutputFormatExamples1.properties"))
+ .build());
+ assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("mail/t.ftl").getOutputFormat());
+ }
+
+ private void example3(boolean javaCfg) throws IOException {
+ setConfiguration(
+ javaCfg
+ ? new TestConfigurationBuilder()
+ .templateConfigurations(
+ 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()),
+ new ConditionalTemplateConfigurationFactory(
+ new FileExtensionMatcher("rtf"),
+ new TemplateConfiguration.Builder()
+ .outputFormat(RTFOutputFormat.INSTANCE)
+ .build()))
+ .allowNoMatch(true))
+ .build()
+ : new TestConfigurationBuilder()
+ .settings(loadPropertiesFile("ConfigureOutputFormatExamples2.properties"))
+ .build());
+ assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.html").getOutputFormat());
+ assertEquals(HTMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.htm").getOutputFormat());
+ assertEquals(XMLOutputFormat.INSTANCE, getConfiguration().getTemplate("t.xml").getOutputFormat());
+ assertEquals(RTFOutputFormat.INSTANCE, getConfiguration().getTemplate("t.rtf").getOutputFormat());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
new file mode 100644
index 0000000..f38bb14
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/CustomFormatsExample.java
@@ -0,0 +1,84 @@
+/*
+ * 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.io.IOException;
+import java.math.BigDecimal;
+import java.util.Date;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
+import org.apache.freemarker.core.valueformat.impl.AliasTemplateDateFormatFactory;
+import org.apache.freemarker.core.valueformat.impl.AliasTemplateNumberFormatFactory;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+@SuppressWarnings("boxing")
+public class CustomFormatsExample extends TemplateTest {
+
+ @Test
+ public void aliases1() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder(this.getClass())
+ .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
+ "price", new AliasTemplateNumberFormatFactory(",000.00"),
+ "weight", new AliasTemplateNumberFormatFactory("0.##;; roundingMode=halfUp")))
+ .customDateFormats(ImmutableMap.<String, TemplateDateFormatFactory>of(
+ "fileDate", new AliasTemplateDateFormatFactory("dd/MMM/yy hh:mm a"),
+ "logEventTime", new AliasTemplateDateFormatFactory("iso ms u")
+ ))
+ .build());
+
+ addToDataModel("p", 10000);
+ addToDataModel("w", new BigDecimal("10.305"));
+ addToDataModel("fd", new Date(1450904944213L));
+ addToDataModel("let", new Date(1450904944213L));
+
+ assertOutputForNamed("CustomFormatsExample-alias1.ftlh");
+ }
+
+ @Test
+ public void aliases2() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder(this.getClass())
+ .customNumberFormats(ImmutableMap.of(
+ "base", BaseNTemplateNumberFormatFactory.INSTANCE,
+ "oct", new AliasTemplateNumberFormatFactory("@base 8")))
+ .build());
+
+ assertOutputForNamed("CustomFormatsExample-alias2.ftlh");
+ }
+
+ @Test
+ public void modelAware() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder(this.getClass())
+ .customNumberFormats(ImmutableMap.<String, TemplateNumberFormatFactory>of(
+ "ua", UnitAwareTemplateNumberFormatFactory.INSTANCE))
+ .numberFormat("@ua 0.####;; roundingMode=halfUp")
+ .build());
+
+ addToDataModel("weight", new UnitAwareTemplateNumberModel(1.5, "kg"));
+
+ assertOutputForNamed("CustomFormatsExample-modelAware.ftlh");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
new file mode 100644
index 0000000..a676bc4
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/manualtest/GettingStartedExample.java
@@ -0,0 +1,69 @@
+/*
+ * 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.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateExceptionHandler;
+import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
+import org.junit.Test;
+
+public class GettingStartedExample {
+
+ @Test
+ public void main() throws Exception {
+ /* ------------------------------------------------------------------------ */
+ /* You should do this ONLY ONCE in the whole application life-cycle: */
+
+ /* Create the configuration singleton (using builder pattern) */
+ Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
+ .templateLoader(new ClassTemplateLoader(GettingStartedExample.class, ""))
+ .sourceEncoding(StandardCharsets.UTF_8)
+ .templateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
+ .logTemplateExceptions(false)
+ .build();
+
+ /* ------------------------------------------------------------------------ */
+ /* You usually do these for MULTIPLE TIMES in the application life-cycle: */
+
+ /* Create a data-model */
+ Map<String, Object> root = new HashMap();
+ root.put("user", "Big Joe");
+ Product latest = new Product();
+ latest.setUrl("products/greenmouse.html");
+ latest.setName("green mouse");
+ root.put("latestProduct", latest);
+
+ /* Get the template (uses cache internally) */
+ Template temp = cfg.getTemplate("test.ftlh");
+
+ /* Merge data-model with template */
+ Writer out = new OutputStreamWriter(System.out);
+ temp.process(root, out);
+ // Note: Depending on what `out` is, you may need to call `out.close()`.
+ // This is usually the case for file output, but not for servlet output.
+ }
+
+}
[16/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
deleted file mode 100644
index 4b5bf59..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateGetEncodingTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-
-import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
-import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
-import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage;
-import org.apache.freemarker.test.MonitoredTemplateLoader;
-import org.junit.Test;
-
-public class TemplateGetEncodingTest {
-
- private static final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
-
- @Test
- public void test() throws IOException {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- {
- cfgB.setSourceEncoding(ISO_8859_2);
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putBinaryTemplate("bin", "test");
- tl.putBinaryTemplate("bin-static", "<#test>");
- tl.putTextTemplate("text", "test");
- tl.putTextTemplate("text-static", "<#test>");
- TemplateConfiguration.Builder staticTextTCB = new TemplateConfiguration.Builder();
- staticTextTCB.setTemplateLanguage(TemplateLanguage.STATIC_TEXT);
- cfgB.setTemplateConfigurations(
- new ConditionalTemplateConfigurationFactory(
- new FileNameGlobMatcher("*-static*"), staticTextTCB.build()));
- cfgB.setTemplateLoader(tl);
- cfgB.setCacheStorage(new StrongCacheStorage());
- }
-
- Configuration cfg = cfgB.build();
- assertEquals(ISO_8859_2, cfg.getTemplate("bin").getActualSourceEncoding());
- assertEquals(ISO_8859_2, cfg.getTemplate("bin-static").getActualSourceEncoding());
- assertNull(cfg.getTemplate("text").getActualSourceEncoding());
- assertNull(cfg.getTemplate("text-static").getActualSourceEncoding());
- assertNull(new Template(null, "test", cfg).getActualSourceEncoding());
- assertNull(Template.createPlainTextTemplate(null, "<#test>", cfg).getActualSourceEncoding());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
deleted file mode 100644
index f0e63a8..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.core.Configuration.ExtendableBuilder.TEMPLATE_LOOKUP_STRATEGY_KEY;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.util.Locale;
-
-import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
-import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
-import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
-import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy;
-import org.apache.freemarker.test.MonitoredTemplateLoader;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class TemplateLookupStrategyTest {
-
- @Test
- public void testSetSetting() throws Exception {
- assertSame(
- DefaultTemplateLookupStrategy.INSTANCE,
- new Configuration.Builder(Configuration.VERSION_3_0_0).build()
- .getTemplateLookupStrategy());
-
- assertTrue(
- new Configuration.Builder(Configuration.VERSION_3_0_0)
- .setting(TEMPLATE_LOOKUP_STRATEGY_KEY, MyTemplateLookupStrategy.class.getName() + "()")
- .build()
- .getTemplateLookupStrategy() instanceof MyTemplateLookupStrategy);
-
- assertSame(
- DefaultTemplateLookupStrategy.INSTANCE,
- new Configuration.Builder(Configuration.VERSION_3_0_0)
- .setting(TEMPLATE_LOOKUP_STRATEGY_KEY, "dEfault")
- .build()
- .getTemplateLookupStrategy());
- }
-
- @Test
- public void testCustomStrategy() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("test.ftl", "");
- tl.putTextTemplate("aa/test.ftl", "");
-
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(tl)
- .templateLookupStrategy(MyTemplateLookupStrategy.INSTANCE)
- .build();
-
- final Locale locale = new Locale("aa", "BB", "CC_DD");
-
- try {
- cfg.getTemplate("missing.ftl", locale);
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("missing.ftl", e.getTemplateName());
- assertEquals(ImmutableList.of("aa/missing.ftl", "missing.ftl"), tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Template t = cfg.getTemplate("test.ftl", locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("aa/test.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(ImmutableList.of("aa/test.ftl"), tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
- }
-
- @Test
- public void testDefaultStrategy() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("test.ftl", "");
- tl.putTextTemplate("test_aa.ftl", "");
- tl.putTextTemplate("test_aa_BB.ftl", "");
- tl.putTextTemplate("test_aa_BB_CC.ftl", "");
- tl.putTextTemplate("test_aa_BB_CC_DD.ftl", "");
-
- try {
- new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate("missing.ftl", new Locale("aa", "BB", "CC_DD"));
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("missing.ftl", e.getTemplateName());
- assertEquals(
- ImmutableList.of(
- "missing_aa_BB_CC_DD.ftl",
- "missing_aa_BB_CC.ftl",
- "missing_aa_BB.ftl",
- "missing_aa.ftl",
- "missing.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- try {
- new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
- .locale(new Locale("xx")).build()
- .getTemplate("missing.ftl");
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("missing.ftl", e.getTemplateName());
- assertEquals(
- ImmutableList.of("missing_xx.ftl", "missing.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- try {
- new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
- .locale(new Locale("xx"))
- .localizedLookup(false).build()
- .getTemplate("missing.ftl");
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("missing.ftl", e.getTemplateName());
- assertEquals(
- ImmutableList.of("missing.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- try {
- new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate("_a_b_.ftl", new Locale("xx", "yy"));
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("_a_b_.ftl", e.getTemplateName());
- assertEquals(
- ImmutableList.of("_a_b__xx_YY.ftl", "_a_b__xx.ftl", "_a_b_.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- for (String templateName : new String[] { "test.ftl", "./test.ftl", "/test.ftl", "x/foo/../../test.ftl" }) {
- {
- final Locale locale = new Locale("aa", "BB", "CC_DD");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate("test.ftl", locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test_aa_BB_CC_DD.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(ImmutableList.of("test_aa_BB_CC_DD.ftl"), tl.getLoadNames());
- assertNull(t.getCustomLookupCondition());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("aa", "BB", "CC_XX");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test_aa_BB_CC.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(ImmutableList.of("test_aa_BB_CC_XX.ftl", "test_aa_BB_CC.ftl"), tl.getLoadNames());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("aa", "BB", "XX_XX");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test_aa_BB.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of("test_aa_BB_XX_XX.ftl", "test_aa_BB_XX.ftl", "test_aa_BB.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("aa", "BB", "XX_XX");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl)
- .localizedLookup(false).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of("test.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("aa", "XX", "XX_XX");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test_aa.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of("test_aa_XX_XX_XX.ftl", "test_aa_XX_XX.ftl", "test_aa_XX.ftl", "test_aa.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("xx", "XX", "XX_XX");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of(
- "test_xx_XX_XX_XX.ftl", "test_xx_XX_XX.ftl", "test_xx_XX.ftl", "test_xx.ftl", "test.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
-
- {
- final Locale locale = new Locale("xx", "BB", "CC_DD");
- final Template t = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build()
- .getTemplate(templateName, locale);
- assertEquals("test.ftl", t.getLookupName());
- assertEquals("test.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of(
- "test_xx_BB_CC_DD.ftl", "test_xx_BB_CC.ftl", "test_xx_BB.ftl", "test_xx.ftl", "test.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- }
- }
- }
-
- @Test
- public void testAcquisition() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("t.ftl", "");
- tl.putTextTemplate("sub/i.ftl", "");
- tl.putTextTemplate("x/sub/i.ftl", "");
-
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
-
- final Locale locale = new Locale("xx");
-
- {
- final Template t = cfg.getTemplate("/./moo/../x/y/*/sub/i.ftl", locale);
- assertEquals("x/y/*/sub/i.ftl", t.getLookupName());
- assertEquals("x/sub/i.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of(
- "x/y/sub/i_xx.ftl", "x/sub/i_xx.ftl", "sub/i_xx.ftl",
- "x/y/sub/i.ftl", "x/sub/i.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Template t = cfg.getTemplate("a/b/*/./sub/i.ftl", locale);
- assertEquals("a/b/*/sub/i.ftl", t.getLookupName());
- assertEquals("sub/i.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertNull(t.getCustomLookupCondition());
- assertEquals(
- ImmutableList.of(
- "a/b/sub/i_xx.ftl", "a/sub/i_xx.ftl", "sub/i_xx.ftl",
- "a/b/sub/i.ftl", "a/sub/i.ftl", "sub/i.ftl"),
- tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
- }
-
- @Test
- public void testCustomLookupCondition() throws IOException, TemplateException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
-
- final Configuration cfg;
- final Configuration cfgNoLocLU;
- {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(tl)
- .templateLookupStrategy(new DomainTemplateLookupStrategy());
- cfg = cfgB.build();
- cfgNoLocLU = cfgB.localizedLookup(false).build();
- }
-
- final String iAtDefaultContent = "i at default";
- final String iXxAtDefaultContent = "i_xx at default";
- final String iAtBaazComContent = "i at baaz.com";
- final String iAtFooComContent = "i at foo.com";
- final String tAtDefaultWithoutIncludeContent = "t at default ";
- final String tAtDefaultContent = toCanonicalFTL(tAtDefaultWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
- final String tAtBarComWithoutIncludeContent = "t at bar.com ";
- final String tAtBarComContent = toCanonicalFTL(tAtBarComWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
- final String tAtFooComWithoutIncludeContent = "t at foo.com ";
- final String tAtFooComContent = toCanonicalFTL(tAtFooComWithoutIncludeContent + "<#include 'i.ftl'>", cfg);
- final String t2XxLocaleExpectedOutput = "i3_xx at foo.com";
- final String t2OtherLocaleExpectedOutput = "i3 at foo.com";
-
- tl.putTextTemplate("@foo.com/t.ftl", tAtFooComContent);
- tl.putTextTemplate("@bar.com/t.ftl", tAtBarComContent);
- tl.putTextTemplate("@default/t.ftl", tAtDefaultContent);
- tl.putTextTemplate("@foo.com/i.ftl", iAtFooComContent);
- tl.putTextTemplate("@baaz.com/i.ftl", iAtBaazComContent);
- tl.putTextTemplate("@default/i_xx.ftl", iXxAtDefaultContent);
- tl.putTextTemplate("@default/i.ftl", iAtDefaultContent);
- tl.putTextTemplate("@foo.com/t2.ftl", "<#import 'i2.ftl' as i2 />${proof}");
- tl.putTextTemplate("@default/i2.ftl", "<#import 'i3.ftl' as i3 />");
- tl.putTextTemplate("@foo.com/i3.ftl", "<#global proof = '" + t2OtherLocaleExpectedOutput + "'>");
- tl.putTextTemplate("@foo.com/i3_xx.ftl", "<#global proof = '" + t2XxLocaleExpectedOutput + "'>");
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("foo.com");
- final Template t = cfg.getTemplate("t.ftl", locale, domain);
- assertEquals("t.ftl", t.getLookupName());
- assertEquals("@foo.com/t.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertEquals(domain, t.getCustomLookupCondition());
- assertEquals(tAtFooComContent, t.toString());
- assertEquals(
- ImmutableList.of("@foo.com/t_xx.ftl", "@foo.com/t.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- assertOutputEquals(tAtFooComWithoutIncludeContent + iAtFooComContent, t);
- assertEquals(
- ImmutableList.of("@foo.com/i_xx.ftl", "@foo.com/i.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("bar.com");
- final Template t = cfg.getTemplate("t.ftl", locale, domain);
- assertEquals("t.ftl", t.getLookupName());
- assertEquals("@bar.com/t.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertEquals(domain, t.getCustomLookupCondition());
- assertEquals(tAtBarComContent, t.toString());
- assertEquals(
- ImmutableList.of("@bar.com/t_xx.ftl", "@bar.com/t.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- assertOutputEquals(tAtBarComWithoutIncludeContent + iXxAtDefaultContent, t);
- assertEquals(
- ImmutableList.of(
- "@bar.com/i_xx.ftl", "@bar.com/i.ftl",
- "@default/i_xx.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx", "YY");
- final Domain domain = new Domain("baaz.com");
- final Template t = cfg.getTemplate("t.ftl", locale, domain);
- assertEquals("t.ftl", t.getLookupName());
- assertEquals("@default/t.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertEquals(domain, t.getCustomLookupCondition());
- assertEquals(tAtDefaultContent, t.toString());
- assertEquals(
- ImmutableList.of(
- "@baaz.com/t_xx_YY.ftl", "@baaz.com/t_xx.ftl", "@baaz.com/t.ftl",
- "@default/t_xx_YY.ftl", "@default/t_xx.ftl", "@default/t.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- assertOutputEquals(tAtDefaultWithoutIncludeContent + iAtBaazComContent, t);
- assertEquals(
- ImmutableList.of("@baaz.com/i_xx_YY.ftl", "@baaz.com/i_xx.ftl", "@baaz.com/i.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx", "YY");
- final Domain domain = new Domain("nosuch.com");
- final Template t = cfg.getTemplate("i.ftl", locale, domain);
- assertEquals("i.ftl", t.getLookupName());
- assertEquals("@default/i_xx.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertEquals(domain, t.getCustomLookupCondition());
- assertEquals(iXxAtDefaultContent, t.toString());
- assertEquals(
- ImmutableList.of(
- "@nosuch.com/i_xx_YY.ftl", "@nosuch.com/i_xx.ftl", "@nosuch.com/i.ftl",
- "@default/i_xx_YY.ftl", "@default/i_xx.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx", "YY");
- final Domain domain = new Domain("nosuch.com");
- final Template t = cfgNoLocLU.getTemplate("i.ftl", locale, domain);
- assertEquals("i.ftl", t.getLookupName());
- assertEquals("@default/i.ftl", t.getSourceName());
- assertEquals(locale, t.getLocale());
- assertEquals(domain, t.getCustomLookupCondition());
- assertEquals(iAtDefaultContent, t.toString());
- assertEquals(
- ImmutableList.of("@nosuch.com/i.ftl", "@default/i.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfgNoLocLU.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("foo.com");
- final Template t = cfg.getTemplate("t2.ftl", locale, domain);
- assertOutputEquals(t2XxLocaleExpectedOutput, t);
- assertEquals(
- ImmutableList.of(
- "@foo.com/t2_xx.ftl", "@foo.com/t2.ftl",
- "@foo.com/i2_xx.ftl", "@foo.com/i2.ftl", "@default/i2_xx.ftl", "@default/i2.ftl",
- "@foo.com/i3_xx.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("yy");
- final Domain domain = new Domain("foo.com");
- final Template t = cfg.getTemplate("t2.ftl", locale, domain);
- assertOutputEquals(t2OtherLocaleExpectedOutput, t);
- assertEquals(
- ImmutableList.of(
- "@foo.com/t2_yy.ftl", "@foo.com/t2.ftl",
- "@foo.com/i2_yy.ftl", "@foo.com/i2.ftl", "@default/i2_yy.ftl", "@default/i2.ftl",
- "@foo.com/i3_yy.ftl", "@foo.com/i3.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("foo.com");
- final Template t = cfgNoLocLU.getTemplate("t2.ftl", locale, domain);
- assertOutputEquals(t2OtherLocaleExpectedOutput, t);
- assertEquals(
- ImmutableList.of(
- "@foo.com/t2.ftl",
- "@foo.com/i2.ftl", "@default/i2.ftl",
- "@foo.com/i3.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfgNoLocLU.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("foo.com");
- cfg.getTemplate("i3.ftl", locale, domain);
- assertEquals(
- ImmutableList.of("@foo.com/i3_xx.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- final Locale locale = new Locale("xx");
- final Domain domain = new Domain("bar.com");
- try {
- cfg.getTemplate("i3.ftl", locale, domain);
- } catch (TemplateNotFoundException e) {
- assertEquals("i3.ftl", e.getTemplateName());
- assertEquals(domain, e.getCustomLookupCondition());
- }
- assertEquals(
- ImmutableList.of(
- "@bar.com/i3_xx.ftl", "@bar.com/i3.ftl",
- "@default/i3_xx.ftl", "@default/i3.ftl"),
- tl.getLoadNames());
-
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- }
-
- public static class Domain implements Serializable {
- private final String name;
-
- public Domain(String name) {
- this.name = name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Domain domain = (Domain) o;
-
- return name != null ? name.equals(domain.name) : domain.name == null;
- }
-
- @Override
- public int hashCode() {
- return name != null ? name.hashCode() : 0;
- }
- }
-
- @Test
- public void testNonparsed() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("test.txt", "");
- tl.putTextTemplate("test_aa.txt", "");
-
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
-
- try {
- cfg.getTemplate("missing.txt", new Locale("aa", "BB"), null, false);
- fail();
- } catch (TemplateNotFoundException e) {
- assertEquals("missing.txt", e.getTemplateName());
- assertEquals(
- ImmutableList.of(
- "missing_aa_BB.txt",
- "missing_aa.txt",
- "missing.txt"),
- tl.getLoadNames());
- tl.clearEvents();
- cfg.clearTemplateCache();
- }
-
- {
- Template t = cfg.getTemplate("test.txt", new Locale("aa", "BB"), null, false);
- assertEquals("test.txt", t.getLookupName());
- assertEquals("test_aa.txt", t.getSourceName());
- assertEquals(
- ImmutableList.of(
- "test_aa_BB.txt",
- "test_aa.txt"),
- tl.getLoadNames());
- }
- }
-
- @Test
- public void testParseError() throws IOException {
- MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
- tl.putTextTemplate("test.ftl", "");
- tl.putTextTemplate("test_aa.ftl", "<#wrong>");
-
- Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(tl).build();
-
- try {
- cfg.getTemplate("test.ftl", new Locale("aa", "BB"));
- fail();
- } catch (ParseException e) {
- assertEquals("test_aa.ftl", e.getTemplateSourceName());
- assertEquals("test.ftl", e.getTemplateLookupName());
- }
- }
-
- private String toCanonicalFTL(String ftl, Configuration cfg) throws IOException {
- return new Template(null, ftl, cfg).toString();
- }
-
- private void assertOutputEquals(final String expectedContent, final Template t) throws TemplateException,
- IOException {
- StringWriter sw = new StringWriter();
- t.process(null, sw);
- assertEquals(expectedContent, sw.toString());
- }
-
- public static class MyTemplateLookupStrategy extends TemplateLookupStrategy {
-
- public static final MyTemplateLookupStrategy INSTANCE = new MyTemplateLookupStrategy();
-
- private MyTemplateLookupStrategy() { }
-
- @Override
- public <R extends TemplateLookupResult> R lookup(TemplateLookupContext<R> ctx) throws IOException {
- String lang = ctx.getTemplateLocale().getLanguage().toLowerCase();
- R lookupResult = ctx.lookupWithAcquisitionStrategy(lang + "/" + ctx.getTemplateName());
- if (lookupResult.isPositive()) {
- return lookupResult;
- }
-
- return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
- }
-
- }
-
- public static class DomainTemplateLookupStrategy extends TemplateLookupStrategy {
-
- public static final DomainTemplateLookupStrategy INSTANCE = new DomainTemplateLookupStrategy();
-
- @Override
- public <R extends TemplateLookupResult> R lookup(TemplateLookupContext<R> ctx) throws IOException {
- Domain domain = (Domain) ctx.getCustomLookupCondition();
- if (domain == null) {
- throw new NullPointerException("The domain wasn't specified");
- }
-
- final String templateName = ctx.getTemplateName();
-
- // Disallow addressing the domain roots directly:
- if (templateName.startsWith("@")) {
- return ctx.createNegativeLookupResult();
- }
-
- R lookupResult = ctx.lookupWithLocalizedThenAcquisitionStrategy(
- "@" + domain.name + "/" + templateName,
- ctx.getTemplateLocale());
- if (lookupResult.isPositive()) {
- return lookupResult;
- }
-
- return ctx.lookupWithLocalizedThenAcquisitionStrategy("@default/" + templateName, ctx.getTemplateLocale());
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
deleted file mode 100644
index 7c9a98f..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNameSpecialVariablesTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class TemplateNameSpecialVariablesTest extends TemplateTest {
-
- private static final String PRINT_ALL_FTL
- = "ct=${.currentTemplateName!'-'}, mt=${.mainTemplateName!'-'}";
-
- @Test
- public void testMainTemplateName() throws IOException, TemplateException {
- addTemplateNameTestTemplates(".mainTemplateName");
- assertOutputForNamed("main.ftl",
- "In main: main.ftl\n"
- + "In imp: main.ftl\n"
- + "In main: main.ftl\n"
- + "main.ftl\n"
- + "{main.ftl}\n"
- + "In imp call imp:\n"
- + "main.ftl\n"
- + "{main.ftl}\n"
- + "After: main.ftl\n"
- + "In main: main.ftl\n"
- + "In inc: main.ftl\n"
- + "In inc call imp:\n"
- + "main.ftl\n"
- + "{main.ftl}\n"
- + "In main: main.ftl\n"
- + "main.ftl\n"
- + "{main.ftl}\n"
- + "In inc call imp:\n"
- + "main.ftl\n"
- + "{main.ftl}\n"
- + "In main: main.ftl\n");
- }
-
- @Test
- public void testCurrentTemplateName() throws IOException, TemplateException {
- addTemplateNameTestTemplates(".currentTemplateName");
- assertOutputForNamed("main.ftl",
- "In main: main.ftl\n"
- + "In imp: imp.ftl\n"
- + "In main: main.ftl\n"
- + "imp.ftl\n"
- + "{main.ftl}\n"
- + "In imp call imp:\n"
- + "imp.ftl\n"
- + "{imp.ftl}\n"
- + "After: imp.ftl\n"
- + "In main: main.ftl\n"
- + "In inc: inc.ftl\n"
- + "In inc call imp:\n"
- + "imp.ftl\n"
- + "{inc.ftl}\n"
- + "In main: main.ftl\n"
- + "inc.ftl\n"
- + "{main.ftl}\n"
- + "In inc call imp:\n"
- + "imp.ftl\n"
- + "{inc.ftl}\n"
- + "In main: main.ftl\n");
- }
-
- private void addTemplateNameTestTemplates(String specVar) {
- addTemplate("main.ftl",
- "In main: ${" + specVar + "}\n"
- + "<#import 'imp.ftl' as i>"
- + "In imp: ${inImp}\n"
- + "In main: ${" + specVar + "}\n"
- + "<@i.impM>${" + specVar + "}</@>\n"
- + "<@i.impM2 />\n"
- + "In main: ${" + specVar + "}\n"
- + "<#include 'inc.ftl'>"
- + "In main: ${" + specVar + "}\n"
- + "<@incM>${" + specVar + "}</@>\n"
- + "<@incM2 />\n"
- + "In main: ${" + specVar + "}\n"
- );
- addTemplate("imp.ftl",
- "<#global inImp = " + specVar + ">"
- + "<#macro impM>"
- + "${" + specVar + "}\n"
- + "{<#nested>}"
- + "</#macro>"
- + "<#macro impM2>"
- + "In imp call imp:\n"
- + "<@impM>${" + specVar + "}</@>\n"
- + "After: ${" + specVar + "}"
- + "</#macro>"
- );
- addTemplate("inc.ftl",
- "In inc: ${" + specVar + "}\n"
- + "In inc call imp:\n"
- + "<@i.impM>${" + specVar + "}</@>\n"
- + "<#macro incM>"
- + "${" + specVar + "}\n"
- + "{<#nested>}"
- + "</#macro>"
- + "<#macro incM2>"
- + "In inc call imp:\n"
- + "<@i.impM>${" + specVar + "}</@>"
- + "</#macro>"
- );
- }
-
- @Test
- public void testInAdhocTemplate() throws TemplateException, IOException {
- addTemplate("inc.ftl", "Inc: " + PRINT_ALL_FTL);
-
- // In nameless templates, the deprecated .templateName is "", but the new variables are missing values.
- assertOutput(new Template(null, PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
- "ct=-, mt=-; Inc: ct=inc.ftl, mt=-");
-
- assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
- "ct=foo.ftl, mt=foo.ftl; Inc: ct=inc.ftl, mt=foo.ftl");
- }
-
- @Test
- public void testInInterpretTemplate() throws TemplateException, IOException {
- addToDataModel("t", PRINT_ALL_FTL);
- assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
- "ct=foo.ftl, mt=foo.ftl; "
- + "ct=foo.ftl->anonymous_interpreted, mt=foo.ftl");
- assertOutput(new Template(null, PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
- "ct=-, mt=-; "
- + "ct=nameless_template->anonymous_interpreted, mt=-");
- assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@[t,'bar']?interpret />", getConfiguration()),
- "ct=foo.ftl, mt=foo.ftl; "
- + "ct=foo.ftl->bar, mt=foo.ftl");
- }
-
- @Override
- protected Configuration createDefaultConfiguration() throws Exception {
- return new TestConfigurationBuilder().whitespaceStripping(false).build();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
deleted file mode 100644
index 66331ad..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TemplateNotFoundMessageTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.test.hamcerst.Matchers.*;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-
-import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
-import org.apache.freemarker.core.templateresolver.TemplateLoader;
-import org.apache.freemarker.core.templateresolver.TemplateLookupContext;
-import org.apache.freemarker.core.templateresolver.TemplateLookupResult;
-import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy;
-import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.FileTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.MultiTemplateLoader;
-import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader;
-import org.junit.Test;
-
-public class TemplateNotFoundMessageTest {
-
- @Test
- public void testFileTemplateLoader() throws IOException {
- final File baseDir = new File(System.getProperty("user.home"));
- final String errMsg = failWith(new FileTemplateLoader(baseDir));
- showErrorMessage(errMsg);
- assertThat(errMsg, containsString(baseDir.toString()));
- assertThat(errMsg, containsString("FileTemplateLoader"));
- }
-
- @Test
- public void testClassTemplateLoader() throws IOException {
- final String errMsg = failWith(new ClassTemplateLoader(getClass(), "foo/bar"));
- showErrorMessage(errMsg);
- assertThat(errMsg, containsString("ClassTemplateLoader"));
- assertThat(errMsg, containsString("foo/bar"));
- }
-
- @Test
- public void testStringTemplateLoader() throws IOException {
- StringTemplateLoader tl = new StringTemplateLoader();
- tl.putTemplate("aaa", "A");
- tl.putTemplate("bbb", "B");
- tl.putTemplate("ccc", "C");
- final String errMsg = failWith(tl);
- showErrorMessage(errMsg);
- assertThat(errMsg, containsString("StringTemplateLoader"));
- assertThat(errMsg, containsString("aaa"));
- assertThat(errMsg, containsString("bbb"));
- assertThat(errMsg, containsString("ccc"));
- }
-
- @Test
- public void testMultiTemplateLoader() throws IOException {
- final String errMsg = failWith(new MultiTemplateLoader(new TemplateLoader[] {
- new StringTemplateLoader(),
- new ClassTemplateLoader(getClass(), "foo/bar")
- }));
- showErrorMessage(errMsg);
- assertThat(errMsg, containsString("MultiTemplateLoader"));
- assertThat(errMsg, containsString("StringTemplateLoader"));
- assertThat(errMsg, containsString("ClassTemplateLoader"));
- assertThat(errMsg, containsString("foo/bar"));
- }
-
- @Test
- public void testDefaultTemplateLoader() throws IOException {
- String errMsg = failWith(null);
- showErrorMessage(errMsg);
- assertThat(errMsg, allOf(containsString("setTemplateLoader"), containsString("null")));
- }
-
- @Test
- public void testOtherMessageDetails() throws IOException {
- // Non-null TemplateLoader:
- StringTemplateLoader emptyLoader = new StringTemplateLoader();
- {
- String errMsg = failWith(emptyLoader, "../x");
- showErrorMessage(errMsg);
- assertThat(errMsg,
- allOf(
- containsStringIgnoringCase("Malformed template name"),
- containsStringIgnoringCase("root directory")));
- }
- {
- String errMsg = failWith(emptyLoader, "x\u0000y");
- showErrorMessage(errMsg);
- assertThat(errMsg,
- allOf(
- containsStringIgnoringCase("Malformed template name"),
- containsStringIgnoringCase("null character")));
- }
- {
- String errMsg = failWith(emptyLoader, "x\\y");
- showErrorMessage(errMsg);
- assertThat(errMsg,
- allOf(containsStringIgnoringCase("warning"), containsStringIgnoringCase("backslash")));
- }
- {
- String errMsg = failWith(emptyLoader, "x/./y");
- showErrorMessage(errMsg);
- assertThat(errMsg,
- allOf(containsStringIgnoringCase("normalized"), containsStringIgnoringCase("x/y")));
- }
- {
- String errMsg = failWith(emptyLoader, "/x/y");
- showErrorMessage(errMsg);
- assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
- }
- {
- String errMsg = failWith(emptyLoader, "x/y");
- showErrorMessage(errMsg);
- assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
- assertThat(errMsg, not(containsStringIgnoringCase("lookup strategy")));
- }
-
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0)
- .templateLoader(new StringTemplateLoader())
- .templateLookupStrategy(
- new TemplateLookupStrategy() {
- @Override
- public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
- return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
- }
- }
- );
- {
- String errMsg = failWith(emptyLoader, "x/y",
- new TemplateLookupStrategy() {
- @Override
- public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
- return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
- }
- }
- );
- showErrorMessage(errMsg);
- assertThat(errMsg, containsStringIgnoringCase("lookup strategy"));
- }
-
- try {
- cfgB.build().getTemplate("./missing", null, new DomainLookupCondition());
- fail();
- } catch (TemplateNotFoundException e) {
- showErrorMessage(e.getMessage());
- assertThat(e.getMessage(), containsStringIgnoringCase("example.com"));
- }
- }
-
- private void showErrorMessage(String errMsg) {
- // System.out.println(errMsg);
- }
-
- private String failWith(TemplateLoader tl, String name, TemplateLookupStrategy templateLookupStrategy) {
- try {
- Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0);
- cfgB.setTemplateLoader(tl);
- if (templateLookupStrategy != null) {
- cfgB.setTemplateLookupStrategy(templateLookupStrategy);
- }
- cfgB.build().getTemplate(name);
- fail();
- } catch (TemplateNotFoundException | MalformedTemplateNameException e) {
- return e.getMessage();
- } catch (IOException e) {
- fail("Unexpected exception: " + e);
- }
- return null;
- }
-
- private String failWith(TemplateLoader tl, String name) {
- return failWith(tl, name, null);
- }
-
- private String failWith(TemplateLoader tl) {
- return failWith(tl, "missing.ftl", null);
- }
-
- @SuppressWarnings("serial")
- private static final class DomainLookupCondition implements Serializable {
- @Override
- public String toString() {
- return "example.com";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
deleted file mode 100644
index a0174b3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.freemarker.core.ThreadInterruptionSupportTemplatePostProcessor.TemplateProcessingThreadInterruptedException;
-import org.apache.freemarker.core.model.TemplateDirectiveBody;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util._NullWriter;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TheadInterruptingSupportTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(TheadInterruptingSupportTest.class);
-
- private static final int TEMPLATE_INTERRUPTION_TIMEOUT = 5000;
- private final Configuration cfg = new TestConfigurationBuilder().build();
-
- @Test
- public void test() throws IOException, InterruptedException {
- assertCanBeInterrupted("<#list 1.. as x></#list>");
- assertCanBeInterrupted("<#list 1.. as x>${x}</#list>");
- assertCanBeInterrupted("<#list 1.. as x>t${x}</#list>");
- assertCanBeInterrupted("<#list 1.. as x><#list 1.. as y>${y}</#list></#list>");
- assertCanBeInterrupted("<#list 1.. as x>${x}<#else>nope</#list>");
- assertCanBeInterrupted("<#list 1..>[<#items as x>${x}</#items>]<#else>nope</#list>");
- assertCanBeInterrupted("<@customLoopDirective />");
- assertCanBeInterrupted("<@customLoopDirective>x</@>");
- assertCanBeInterrupted("<@customLoopDirective><#if true>x</#if></@>");
- assertCanBeInterrupted("<#macro selfCalling><@sleepDirective/><@selfCalling /></#macro><@selfCalling />");
- assertCanBeInterrupted("<#function selfCalling><@sleepDirective/>${selfCalling()}</#function>${selfCalling()}");
- assertCanBeInterrupted("<#list 1.. as _><#attempt><@sleepDirective/><#recover>suppress</#attempt></#list>");
- assertCanBeInterrupted("<#attempt><#list 1.. as _></#list><#recover>suppress</#attempt>");
- }
-
- private void assertCanBeInterrupted(final String templateSourceCode) throws IOException, InterruptedException {
- TemplateRunnerThread trt = new TemplateRunnerThread(templateSourceCode);
- trt.start();
- synchronized (trt) {
- while (!trt.isStarted()) {
- trt.wait();
- }
- }
- Thread.sleep(50); // Just to ensure (hope...) that the template execution reaches "deep" enough
- trt.interrupt();
- trt.join(TEMPLATE_INTERRUPTION_TIMEOUT);
- assertTrue(trt.isTemplateProcessingInterrupted());
- }
-
- public class TemplateRunnerThread extends Thread {
-
- private final Template template;
- private boolean started;
- private boolean templateProcessingInterrupted;
-
- public TemplateRunnerThread(String templateSourceCode) throws IOException {
- template = new Template(null, "<@startedDirective/>" + templateSourceCode, cfg);
- _CoreAPI.addThreadInterruptedChecks(template);
- }
-
- @Override
- public void run() {
- try {
- template.process(this, _NullWriter.INSTANCE);
- } catch (TemplateProcessingThreadInterruptedException e) {
- //LOG.debug("Template processing interrupted", e);
- synchronized (this) {
- templateProcessingInterrupted = true;
- }
- } catch (Throwable e) {
- LOG.error("Template processing failed", e);
- }
- }
-
- public synchronized boolean isTemplateProcessingInterrupted() {
- return templateProcessingInterrupted;
- }
-
- public synchronized boolean isStarted() {
- return started;
- }
-
- public TemplateDirectiveModel getStartedDirective() {
- return new StartedDirective();
- }
-
- public TemplateDirectiveModel getCustomLoopDirective() {
- return new CustomLoopDirective();
- }
-
- public TemplateDirectiveModel getSleepDirective() {
- return new SleepDirective();
- }
-
- public class StartedDirective implements TemplateDirectiveModel {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- synchronized (TemplateRunnerThread.this) {
- started = true;
- TemplateRunnerThread.this.notifyAll();
- }
- }
-
- }
-
- public class CustomLoopDirective implements TemplateDirectiveModel {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- // Deliberate infinite loop
- while (true) {
- body.render(_NullWriter.INSTANCE);
- }
- }
-
- }
-
- public class SleepDirective implements TemplateDirectiveModel {
-
- @Override
- public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
- throws TemplateException, IOException {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // Thread.sleep has reset the interrupted flag (because it has thrown InterruptedException).
- Thread.currentThread().interrupt();
- }
- }
-
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
deleted file mode 100644
index 749d057..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/TypeErrorMessagesTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.core;
-
-import java.io.StringReader;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-
-public class TypeErrorMessagesTest extends TemplateTest {
-
- static final Document doc;
- static {
- try {
- DocumentBuilder docBuilder;
- docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- doc = docBuilder.parse(new InputSource(new StringReader(
- "<a><b>123</b><c a='true'>1</c><c a='false'>2</c></a>")));
- } catch (Exception e) {
- throw new RuntimeException("Failed to build data-model", e);
- }
- }
-
- @Test
- public void testNumericalBinaryOperator() {
- assertErrorContains("${n - s}", "\"-\"", "right-hand", "number", "string");
- assertErrorContains("${s - n}", "\"-\"", "left-hand", "number", "string");
- }
-
- @Test
- public void testGetterMistake() {
- assertErrorContains("${bean.getX}", "${...}",
- "number", "string", "method", "obj.getSomething", "obj.something");
- assertErrorContains("${1 * bean.getX}", "right-hand",
- "number", "\\!string", "method", "obj.getSomething", "obj.something");
- assertErrorContains("<#if bean.isB></#if>", "condition",
- "boolean", "method", "obj.isSomething", "obj.something");
- assertErrorContains("<#if bean.isB></#if>", "condition",
- "boolean", "method", "obj.isSomething", "obj.something");
- assertErrorContains("${bean.voidM}",
- "string", "method", "\\!()");
- assertErrorContains("${bean.intM}",
- "string", "method", "obj.something()");
- assertErrorContains("${bean.intMP}",
- "string", "method", "obj.something(params)");
- }
-
- @Test
- public void testXMLTypeMismarches() throws Exception {
- assertErrorContains("${doc.a.c}",
- "used as string", "query result", "2", "multiple matches");
- assertErrorContains("${doc.a.c?boolean}",
- "used as string", "query result", "2", "multiple matches");
- assertErrorContains("${doc.a.d}",
- "used as string", "query result", "0", "no matches");
- assertErrorContains("${doc.a.d?boolean}",
- "used as string", "query result", "0", "no matches");
-
- assertErrorContains("${doc.a.c.@a}",
- "used as string", "query result", "2", "multiple matches");
- assertErrorContains("${doc.a.d.@b}",
- "used as string", "query result", "x", "no matches");
-
- assertErrorContains("${doc.a.b * 2}",
- "used as number", "text", "explicit conversion");
- assertErrorContains("<#if doc.a.b></#if>",
- "used as number", "text", "explicit conversion");
-
- assertErrorContains("${doc.a.d?nodeName}",
- "used as node", "query result", "0", "no matches");
- assertErrorContains("${doc.a.c?nodeName}",
- "used as node", "query result", "2", "multiple matches");
- }
-
- @Override
- protected Object createDataModel() {
- Map<String, Object> dataModel = createCommonTestValuesDataModel();
- dataModel.put("doc", doc);
- return dataModel;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
deleted file mode 100644
index 99bf5d3..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/UnclosedCommentTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.junit.Test;
-
-public class UnclosedCommentTest extends TemplateTest {
-
- @Test
- public void test() throws IOException, TemplateException {
- assertErrorContains("foo<#--", "end of file"); // Not too good...
- assertErrorContains("foo<#-- ", "Unclosed", "<#--");
- assertErrorContains("foo<#--bar", "Unclosed", "<#--");
- assertErrorContains("foo\n<#--\n", "Unclosed", "<#--");
- assertErrorContains("foo<#noparse>", "end of file"); // Not too good...
- assertErrorContains("foo<#noparse> ", "Unclosed", "#noparse");
- assertErrorContains("foo<#noparse>bar", "Unclosed", "#noparse");
- assertErrorContains("foo\n<#noparse>\n", "Unclosed", "#noparse");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/VersionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/VersionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/VersionTest.java
deleted file mode 100644
index 8c54df5..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/VersionTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.Assert.*;
-
-import java.sql.Date;
-
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class VersionTest {
-
- @Test
- public void testFromNumber() {
- Version v = new Version(1, 2, 3);
- assertEquals("1.2.3", v.toString());
- assertEquals(1002003, v.intValue());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- assertNull(v.getExtraInfo());
- assertNull(v.isGAECompliant());
- assertNull(v.getBuildDate());
- }
-
- @Test
- public void testFromNumber2() {
- Version v = new Version(1, 2, 3, "beta8", Boolean.TRUE, new Date(5000));
- assertEquals("1.2.3-beta8", v.toString());
- assertEquals("beta8", v.getExtraInfo());
- assertTrue(v.isGAECompliant().booleanValue());
- assertEquals(new Date(5000), v.getBuildDate());
- }
-
- @Test
- public void testFromNumber3() {
- Version v = new Version(new Version(1, 2, 3).intValue());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- }
-
- public void testFromNumberIncubating() {
- Version v = new Version(2, 3, 24, "rc01-incubating", Boolean.FALSE, new Date(5000));
- assertEquals("2.3.24-rc01-incubating", v.toString());
- assertEquals("rc01-incubating", v.getExtraInfo());
- assertFalse(v.isGAECompliant().booleanValue());
- assertEquals(new Date(5000), v.getBuildDate());
- }
-
- @Test
- public void testFromString() {
- Version v = new Version("1.2.3-beta2");
- assertEquals("1.2.3-beta2", v.toString());
- assertEquals(1002003, v.intValue());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- assertEquals("beta2", v.getExtraInfo());
- assertNull(v.isGAECompliant());
- assertNull(v.getBuildDate());
- }
-
- @Test
- public void testFromString2() {
- Version v = new Version("10.20.30", Boolean.TRUE, new Date(5000));
- assertEquals("10.20.30", v.toString());
- assertEquals(10020030, v.intValue());
- assertEquals(10, v.getMajor());
- assertEquals(20, v.getMinor());
- assertEquals(30, v.getMicro());
- assertNull(v.getExtraInfo());
- assertTrue(v.isGAECompliant().booleanValue());
- assertEquals(new Date(5000), v.getBuildDate());
- }
-
- @Test
- public void testFromString3() {
- Version v = new Version("01.002.0003-20130524");
- assertEquals("01.002.0003-20130524", v.toString());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- assertEquals("20130524", v.getExtraInfo());
-
- v = new Version("01.002.0003.4");
- assertEquals("01.002.0003.4", v.toString());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- assertEquals("4", v.getExtraInfo());
-
- v = new Version("1.2.3.FC");
- assertEquals("1.2.3.FC", v.toString());
- assertEquals("FC", v.getExtraInfo());
-
- v = new Version("1.2.3mod");
- assertEquals("1.2.3mod", v.toString());
- assertEquals(1, v.getMajor());
- assertEquals(2, v.getMinor());
- assertEquals(3, v.getMicro());
- assertEquals("mod", v.getExtraInfo());
-
- }
-
- @Test
- public void testFromStringIncubating() {
- Version v = new Version("2.3.24-rc01-incubating");
- assertEquals("2.3.24-rc01-incubating", v.toString());
- assertEquals(2, v.getMajor());
- assertEquals(3, v.getMinor());
- assertEquals(24, v.getMicro());
- assertEquals("rc01-incubating", v.getExtraInfo());
- }
-
- @Test
- public void testHashAndEquals() {
- Version v1 = new Version("1.2.3-beta2");
- Version v2 = new Version(1, 2, 3, "beta2", null, null);
- assertEquals(v1, v2);
- assertEquals(v1.hashCode(), v2.hashCode());
-
- v2 = new Version("1.2.3-beta3");
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version(1, 2, 3, "beta2", true, null);
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version(1, 2, 3, "beta2", null, new Date(5000));
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version("1.2.9-beta2");
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version("1.9.3-beta2");
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version("9.2.3-beta2");
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
-
- v2 = new Version("1.2.3");
- assertTrue(!v1.equals(v2));
- assertTrue(v1.hashCode() != v2.hashCode());
- }
-
- @Test
- public void testShortForms() {
- Version v = new Version("1.0.0-beta2");
- assertEquals(v, new Version("1.0-beta2"));
- assertEquals(v, new Version("1-beta2"));
-
- v = new Version("1.0.0");
- assertEquals(v, new Version("1.0"));
- assertEquals(v, new Version("1"));
- }
-
- @Test
- public void testMalformed() {
- try {
- new Version("1.2.");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- new Version("1.2.3.");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- new Version("1..3");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- new Version(".2");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- new Version("a");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- new Version("-a");
- fail();
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
deleted file mode 100644
index 8e5b52e..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/WhitespaceStrippingTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.core;
-
-import java.io.IOException;
-
-import org.apache.freemarker.test.TemplateTest;
-import org.apache.freemarker.test.TestConfigurationBuilder;
-import org.junit.Test;
-
-public class WhitespaceStrippingTest extends TemplateTest {
-
- @Test
- public void testBasics() throws Exception {
- assertOutput("<#assign x = 1>\n<#assign y = 2>\n${x}\n${y}", "1\n2", "\n\n1\n2");
- assertOutput(" <#assign x = 1> \n <#assign y = 2> \n${x}\n${y}", "1\n2", " \n \n1\n2");
- }
-
- @Test
- public void testFTLHeader() throws Exception {
- assertOutput("<#ftl>x", "x", "x");
- assertOutput(" <#ftl> x", " x", " x");
- assertOutput("\n<#ftl>\nx", "x", "x");
- assertOutput("\n<#ftl>\t \nx", "x", "x");
- assertOutput(" \n \n <#ftl> \n \n x", " \n x", " \n x");
- }
-
- @Test
- public void testComment() throws Exception {
- assertOutput(" a <#-- --> b ", " a b ", " a b ");
- assertOutput(" a \n<#-- -->\n b ", " a \n b ", " a \n\n b ");
- // These are wrong, but needed for 2.3.0 compatibility:
- assertOutput(" a \n <#-- --> \n b ", " a \n b ", " a \n \n b ");
- assertOutput(" a \n\t<#-- --> \n b ", " a \n\t b ", " a \n\t \n b ");
- }
-
- private void assertOutput(String ftl, String expectedOutStripped, String expectedOutNonStripped)
- throws IOException, TemplateException {
- setConfiguration(new TestConfigurationBuilder().build());
- assertOutput(ftl, expectedOutStripped);
-
- setConfiguration(new TestConfigurationBuilder().whitespaceStripping(false).build());
- assertOutput(ftl, expectedOutNonStripped);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
deleted file mode 100644
index 77951ed..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/XHTMLOutputFormatTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.core.outputformat.impl.XHTMLOutputFormat.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.junit.Test;
-
-public class XHTMLOutputFormatTest {
-
- @Test
- public void testOutputMO() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("a'b"), out);
- assertEquals("a'b", out.toString());
- }
-
- @Test
- public void testOutputString() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
- INSTANCE.output("a'b", out);
- assertEquals("a'b", out.toString());
- }
-
- @Test
- public void testEscaplePlainText() {
- assertEquals("", INSTANCE.escapePlainText(""));
- assertEquals("a", INSTANCE.escapePlainText("a"));
- assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
- assertEquals("<>", INSTANCE.escapePlainText("<>"));
- }
-
- @Test
- public void testGetMimeType() {
- assertEquals("application/xhtml+xml", INSTANCE.getMimeType());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
deleted file mode 100644
index 7e95e6d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/XMLOutputFormatTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.freemarker.core.outputformat.impl.XMLOutputFormat.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.junit.Test;
-
-public class XMLOutputFormatTest {
-
- @Test
- public void testOutputMO() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
- INSTANCE.output(INSTANCE.fromPlainTextByEscaping("a'b"), out);
- assertEquals("a'b", out.toString());
- }
-
- @Test
- public void testOutputString() throws TemplateModelException, IOException {
- StringWriter out = new StringWriter();
- INSTANCE.output("a'b", out);
- assertEquals("a'b", out.toString());
- }
-
- @Test
- public void testEscaplePlainText() {
- assertEquals("", INSTANCE.escapePlainText(""));
- assertEquals("a", INSTANCE.escapePlainText("a"));
- assertEquals("<a&b'c"d>", INSTANCE.escapePlainText("<a&b'c\"d>"));
- assertEquals("<>", INSTANCE.escapePlainText("<>"));
- }
-
- @Test
- public void testGetMimeType() {
- assertEquals("application/xml", INSTANCE.getMimeType());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
deleted file mode 100644
index bdb9a56..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-
-import junit.framework.TestCase;
-
-public abstract class AbstractParallelIntrospectionTest extends TestCase {
-
- private static final int NUM_THREADS = 8;
- private static final int NUM_ENTITYES = 8;
- private static final int NUM_MEMBERS = 8;
- private static final int ITERATIONS = 20000;
- private static final double CACHE_CLEARING_CHANCE = 0.01;
-
- private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
- .usePrivateCaches(true).build();
-
- public AbstractParallelIntrospectionTest(String name) {
- super(name);
- }
-
- public void testReliability() {
- testReliability(ITERATIONS);
- }
-
- public void testReliability(int iterations) {
- TestThread[] ts = new TestThread[NUM_THREADS];
- for (int i = 0; i < NUM_THREADS; i++) {
- ts[i] = new TestThread(iterations);
- ts[i].start();
- }
-
- for (int i = 0; i < NUM_THREADS; i++) {
- try {
- ts[i].join();
- if (ts[i].error != null) {
- throw new AssertionError(ts[i].error);
- }
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- protected abstract TemplateHashModel getWrappedEntity(int objIdx) throws TemplateModelException;
-
- protected final DefaultObjectWrapper getObjectWrapper() {
- return ow;
- }
-
- private class TestThread extends Thread {
-
- private final int iterations;
-
- private Throwable error;
-
- private TestThread(int iterations) {
- this.iterations = iterations;
- }
-
- @Override
- public void run() {
- try {
- for (int i = 0; i < iterations; i++) {
- if (Math.random() < CACHE_CLEARING_CHANCE) {
- ow.clearClassIntrospecitonCache();
- }
- int objIdx = (int) (Math.random() * NUM_ENTITYES);
- TemplateHashModel h = getWrappedEntity(objIdx);
- int mIdx = (int) (Math.random() * NUM_MEMBERS);
- testProperty(h, objIdx, mIdx);
- testMethod(h, objIdx, mIdx);
- }
- } catch (Throwable e) {
- error = e;
- }
- }
-
- private void testProperty(TemplateHashModel h, int objIdx, int mIdx)
- throws TemplateModelException, AssertionError {
- TemplateNumberModel pv = (TemplateNumberModel) h.get("p" + mIdx);
- final int expected = objIdx * 1000 + mIdx;
- final int got = pv.getAsNumber().intValue();
- if (got != expected) {
- throw new AssertionError("Property assertation failed; " +
- "expected " + expected + ", but got " + got);
- }
- }
-
- private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
- throws TemplateModelException, AssertionError {
- TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
- final int expected = objIdx * 1000 + mIdx;
- final int got = ((TemplateNumberModel) pv.exec(null)).getAsNumber().intValue();
- if (got != expected) {
- throw new AssertionError("Method assertation failed; " +
- "expected " + expected + ", but got " + got);
- }
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java b/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
deleted file mode 100644
index 149ad0d..0000000
--- a/freemarker-core/src/test/java/org/apache/freemarker/core/model/impl/AlphabeticalMethodSorter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.core.model.impl;
-
-import java.beans.MethodDescriptor;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-class AlphabeticalMethodSorter implements MethodSorter {
-
- private final boolean desc;
-
- public AlphabeticalMethodSorter(boolean desc) {
- this.desc = desc;
- }
-
- @Override
- public void sortMethodDescriptors(List<MethodDescriptor> methodDescriptors) {
- Collections.sort(methodDescriptors, new Comparator<MethodDescriptor>() {
- public int compare(MethodDescriptor o1, MethodDescriptor o2) {
- int res = o1.getMethod().toString().compareTo(o2.getMethod().toString());
- return desc ? -res : res;
- }
- });
- }
-
-}
\ No newline at end of file