/* * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky * * 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. */ package freemarker.cache; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.junit.Test; import freemarker.core.TemplateConfigurer; import freemarker.template.Configuration; public class TemplateConfigurerFactoryTest { private Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); @Test public void testCondition1() throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer tc = newTemplateConfigurer(1); TemplateConfigurerFactory tcf = new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.ftlx"), tc); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertApplicable(tcf, "x.ftlx", tc); } @Test public void testCondition2() throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer tc = newTemplateConfigurer(1); TemplateConfigurerFactory tcf = new ConditionalTemplateConfigurerFactory( new FileNameGlobMatcher("*.ftlx"), new ConditionalTemplateConfigurerFactory( new FileNameGlobMatcher("x.*"), tc)); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertNotApplicable(tcf, "y.ftlx"); assertApplicable(tcf, "x.ftlx", tc); } @Test public void testMerging() throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer tc1 = newTemplateConfigurer(1); TemplateConfigurer tc2 = newTemplateConfigurer(2); TemplateConfigurer tc3 = newTemplateConfigurer(3); TemplateConfigurerFactory tcf = new MergingTemplateConfigurerFactory( new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.ftlx"), tc1), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*a*.*"), tc2), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*b*.*"), tc3)); tcf.setConfiguration(cfg); 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 MergingTemplateConfigurerFactory(), "x.ftl"); } @Test public void testFirstMatch() throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer tc1 = newTemplateConfigurer(1); TemplateConfigurer tc2 = newTemplateConfigurer(2); TemplateConfigurer tc3 = newTemplateConfigurer(3); FirstMatchTemplateConfigurerFactory tcf = new FirstMatchTemplateConfigurerFactory( new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.ftlx"), tc1), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*a*.*"), tc2), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*b*.*"), tc3)); tcf.setConfiguration(cfg); try { assertNotApplicable(tcf, "x.ftl"); } catch (TemplateConfigurerFactoryException e) { assertThat(e.getMessage(), containsString("x.ftl")); } tcf.setNoMatchErrorDetails("Test details"); try { assertNotApplicable(tcf, "x.ftl"); } catch (TemplateConfigurerFactoryException 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 FirstMatchTemplateConfigurerFactory().allowNoMatch(true), "x.ftl"); } @Test public void testComplex() throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer tcA = newTemplateConfigurer(1); TemplateConfigurer tcBSpec = newTemplateConfigurer(2); TemplateConfigurer tcBCommon = newTemplateConfigurer(3); TemplateConfigurer tcHH = newTemplateConfigurer(4); TemplateConfigurer tcHtml = newTemplateConfigurer(5); TemplateConfigurer tcXml = newTemplateConfigurer(6); TemplateConfigurer tcNWS = newTemplateConfigurer(7); TemplateConfigurerFactory tcf = new MergingTemplateConfigurerFactory( new FirstMatchTemplateConfigurerFactory( new ConditionalTemplateConfigurerFactory(new PathGlobMatcher("a/**"), tcA), new ConditionalTemplateConfigurerFactory(new PathGlobMatcher("b/**"), new MergingTemplateConfigurerFactory( new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*"), tcBCommon), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.s.*"), tcBSpec)))) .allowNoMatch(true), new FirstMatchTemplateConfigurerFactory( new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.hh"), tcHH), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.*h"), tcHtml), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.*x"), tcXml)) .allowNoMatch(true), new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*.nws.*"), tcNWS)); tcf.setConfiguration(cfg); 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); } @Test public void testSetConfiguration() { TemplateConfigurer tc = new TemplateConfigurer(); ConditionalTemplateConfigurerFactory tcf = new ConditionalTemplateConfigurerFactory(new FileNameGlobMatcher("*"), tc); assertNull(tcf.getConfiguration()); assertNull(tc.getParentConfiguration()); tcf.setConfiguration(cfg); assertEquals(cfg, tcf.getConfiguration()); assertEquals(cfg, tc.getParentConfiguration()); // Ignored: tcf.setConfiguration(cfg); try { tcf.setConfiguration(Configuration.getDefaultConfiguration()); fail(); } catch (IllegalStateException e) { assertThat(e.getMessage(), containsString("TemplateConfigurerFactory")); } } @SuppressWarnings("boxing") private TemplateConfigurer newTemplateConfigurer(int id) { TemplateConfigurer tc = new TemplateConfigurer(); tc.setCustomAttribute("id", id); tc.setCustomAttribute("contains" + id, true); return tc; } private void assertNotApplicable(TemplateConfigurerFactory tcf, String sourceName) throws IOException, TemplateConfigurerFactoryException { assertNull(tcf.get(sourceName, "dummy")); } private void assertApplicable(TemplateConfigurerFactory tcf, String sourceName, TemplateConfigurer... expectedTCs) throws IOException, TemplateConfigurerFactoryException { TemplateConfigurer mergedTC = tcf.get(sourceName, "dummy"); assertNotNull("TC should have its parents Configuration set", mergedTC.getParentConfiguration()); List<String> mergedTCAttNames = Arrays.asList(mergedTC.getCustomAttributeNames()); for (TemplateConfigurer expectedTC : expectedTCs) { Integer tcId = (Integer) expectedTC.getCustomAttribute("id"); if (tcId == null) { fail("TemplateConfigurer-s must be created with newTemplateConfigurer(id) in this test"); } if (!mergedTCAttNames.contains("contains" + tcId)) { fail("TemplateConfigurer with ID " + tcId + " is missing from the asserted value"); } } for (String attName: mergedTCAttNames) { if (!containsCustomAttr(attName, expectedTCs)) { fail("The asserted TemplateConfigurer contains an unexpected custom attribute: " + attName); } } assertEquals(expectedTCs[expectedTCs.length - 1].getCustomAttribute("id"), mergedTC.getCustomAttribute("id")); } private boolean containsCustomAttr(String attName, TemplateConfigurer... expectedTCs) { for (TemplateConfigurer expectedTC : expectedTCs) { if (expectedTC.getCustomAttribute(attName) != null) { return true; } } return false; } }