aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java')
-rw-r--r--velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java515
1 files changed, 515 insertions, 0 deletions
diff --git a/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java b/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java
new file mode 100644
index 00000000..c6456dff
--- /dev/null
+++ b/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java
@@ -0,0 +1,515 @@
+package org.apache.velocity.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.
+ */
+
+import junit.framework.TestCase;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
+import org.apache.velocity.runtime.resource.util.StringResourceRepository;
+import org.apache.velocity.test.misc.TestLogger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Locale;
+
+/**
+ * Base test case that provides utility methods for
+ * the rest of the tests.
+ *
+ * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ * @author Nathan Bubna
+ * @version $Id$
+ */
+public abstract class BaseTestCase extends TestCase implements TemplateTestBase
+{
+ protected VelocityEngine engine;
+ protected VelocityContext context;
+ protected boolean DEBUG = Boolean.getBoolean("test.debug");
+ protected TestLogger log;
+ protected String stringRepoName = "string.repo";
+
+ public BaseTestCase(String name)
+ {
+ super(name);
+
+ // if we're just running one case, then have DEBUG
+ // automatically set to true
+ String test = System.getProperty("test");
+ if (test != null)
+ {
+ DEBUG = test.equals(getClass().getSimpleName());
+ }
+ }
+
+ protected VelocityEngine createEngine()
+ {
+ VelocityEngine ret = new VelocityEngine();
+ ret.setProperty(RuntimeConstants.RUNTIME_LOG_INSTANCE, log);
+
+ // use string resource loader by default, instead of file
+ ret.setProperty(RuntimeConstants.RESOURCE_LOADERS, "file,string");
+ ret.addProperty("string.resource.loader.class", StringResourceLoader.class.getName());
+ ret.addProperty("string.resource.loader.repository.name", stringRepoName);
+ ret.addProperty("string.resource.loader.repository.static", "false");
+
+ setUpEngine(ret);
+ return ret;
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ //by default, make the engine's log output go to the test-report
+ log = new TestLogger(false, false);
+ engine = createEngine();
+ context = new VelocityContext();
+ setUpContext(context);
+ }
+
+ protected void setUpEngine(VelocityEngine engine)
+ {
+ // extension hook
+ }
+
+ protected void setUpContext(VelocityContext context)
+ {
+ // extension hook
+ }
+
+ protected StringResourceRepository getStringRepository()
+ {
+ StringResourceRepository repo =
+ (StringResourceRepository)engine.getApplicationAttribute(stringRepoName);
+ if (repo == null)
+ {
+ engine.init();
+ repo =
+ (StringResourceRepository)engine.getApplicationAttribute(stringRepoName);
+ }
+ return repo;
+ }
+
+ protected void addTemplate(String name, String template)
+ {
+ info("Template '"+name+"': "+template);
+ getStringRepository().putStringResource(name, template);
+ }
+
+ protected void removeTemplate(String name)
+ {
+ info("Removed: '"+name+"'");
+ getStringRepository().removeStringResource(name);
+ }
+
+ @Override
+ public void tearDown()
+ {
+ engine = null;
+ context = null;
+ }
+
+ protected void info(String msg)
+ {
+ info(msg, null);
+ }
+
+ protected void info(String msg, Throwable t)
+ {
+ if (DEBUG)
+ {
+ try
+ {
+ if (engine == null)
+ {
+ Velocity.getLog().info(msg, t);
+ }
+ else
+ {
+ engine.getLog().info(msg, t);
+ }
+ }
+ catch (Throwable t2)
+ {
+ System.out.println("Failed to log: "+msg+(t!=null?" - "+t: ""));
+ System.out.println("Cause: "+t2);
+ t2.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Compare an expected string with the given loaded template
+ */
+ protected void assertTmplEquals(String expected, String template)
+ {
+ info("Expected: " + expected + " from '" + template + "'");
+
+ StringWriter writer = new StringWriter();
+ try
+ {
+ engine.mergeTemplate(template, "utf-8", context, writer);
+ }
+ catch (RuntimeException re)
+ {
+ info("RuntimeException!", re);
+ throw re;
+ }
+ catch (Exception e)
+ {
+ info("Exception!", e);
+ throw new RuntimeException(e);
+ }
+
+ info("Result: " + writer.toString());
+ assertEquals(expected, writer.toString());
+ }
+
+ /**
+ * Ensure that a context value is as expected.
+ */
+ protected void assertContextValue(String key, Object expected)
+ {
+ info("Expected value of '"+key+"': "+expected);
+ Object value = context.get(key);
+ info("Result: "+value);
+ assertEquals(expected, value);
+ }
+
+ /**
+ * Ensure that a template renders as expected.
+ */
+ protected void assertEvalEquals(String expected, String template)
+ {
+ info("Expectation: "+expected);
+ assertEquals(expected, evaluate(template));
+ }
+
+ /**
+ * Ensure that the given string renders as itself when evaluated.
+ */
+ protected void assertSchmoo(String templateIsExpected)
+ {
+ assertEvalEquals(templateIsExpected, templateIsExpected);
+ }
+
+ /**
+ * Ensure that an exception occurs when the string is evaluated.
+ */
+ protected Exception assertEvalException(String evil)
+ {
+ return assertEvalException(evil, null);
+ }
+
+ /**
+ * Ensure that a specified type of exception occurs when evaluating the string.
+ */
+ protected Exception assertEvalException(String evil, Class<?> exceptionType)
+ {
+ try
+ {
+ if (!DEBUG)
+ {
+ log.off();
+ }
+ if (exceptionType != null)
+ {
+ info("Expectation: "+exceptionType.getName());
+ }
+ else
+ {
+ info("Expectation: "+Exception.class.getName());
+ }
+ evaluate(evil);
+ String msg = "Template '"+evil+"' should have thrown an exception.";
+ info("Fail: "+msg);
+ fail(msg);
+ }
+ catch (Exception e)
+ {
+ if (exceptionType != null && !exceptionType.isAssignableFrom(e.getClass()))
+ {
+ String msg = "Was expecting template '"+evil+"' to throw "+exceptionType+" not "+e;
+ info("Fail: "+msg);
+ fail(msg);
+ }
+ return e;
+ }
+ finally
+ {
+ if (!DEBUG)
+ {
+ log.on();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Ensure that the error message of the expected exception has the proper location info.
+ */
+ protected Exception assertEvalExceptionAt(String evil, String template,
+ int line, int col)
+ {
+ String loc = template+"[line "+line+", column "+col+"]";
+ info("Expectation: Exception at "+loc);
+ Exception e = assertEvalException(evil);
+
+ info("Result: "+e.getClass().getName()+" - "+e.getMessage());
+ if (e.getMessage().indexOf(loc) < 1)
+ {
+ fail("Was expecting exception at "+loc+" instead of "+e.getMessage());
+ }
+ return e;
+ }
+
+ /**
+ * Only ensure that the error message of the expected exception
+ * has the proper line and column info.
+ */
+ protected Exception assertEvalExceptionAt(String evil, int line, int col)
+ {
+ return assertEvalExceptionAt(evil, "", line, col);
+ }
+
+ /**
+ * Evaluate the specified String as a template and return the result as a String.
+ */
+ protected String evaluate(String template)
+ {
+ StringWriter writer = new StringWriter();
+ try
+ {
+ info("Template: "+template);
+
+ // use template as its own name, since our templates are short
+ // unless it's not that short, then shorten it...
+ String name = (template.length() <= 15) ? template : template.substring(0,15);
+ engine.evaluate(context, writer, name, template);
+
+ String result = writer.toString();
+ info("Result: "+result);
+ return result;
+ }
+ catch (RuntimeException re)
+ {
+ info("RuntimeException!", re);
+ throw re;
+ }
+ catch (Exception e)
+ {
+ info("Exception!", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Concatenates the file name parts together appropriately.
+ *
+ * @return The full path to the file.
+ */
+ protected String getFileName(final String dir, final String base, final String ext)
+ {
+ return getFileName(dir, base, ext, false);
+ }
+
+ protected String getFileName(final String dir, final String base, final String ext, final boolean mustExist)
+ {
+ StringBuilder buf = new StringBuilder();
+ try
+ {
+ File baseFile = new File(base);
+ if (dir != null)
+ {
+ if (!baseFile.isAbsolute())
+ {
+ baseFile = new File(dir, base);
+ }
+
+ buf.append(baseFile.getCanonicalPath());
+ }
+ else
+ {
+ buf.append(baseFile.getPath());
+ }
+
+ if (org.apache.commons.lang3.StringUtils.isNotEmpty(ext))
+ {
+ buf.append('.').append(ext);
+ }
+
+ if (mustExist)
+ {
+ File testFile = new File(buf.toString());
+
+ if (!testFile.exists())
+ {
+ String msg = "getFileName() result " + testFile.getPath() + " does not exist!";
+ info(msg);
+ fail(msg);
+ }
+
+ if (!testFile.isFile())
+ {
+ String msg = "getFileName() result " + testFile.getPath() + " is not a file!";
+ info(msg);
+ fail(msg);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ fail("IO Exception while running getFileName(" + dir + ", " + base + ", "+ ext + ", " + mustExist + "): " + e.getMessage());
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Assures that the results directory exists. If the results directory
+ * cannot be created, fails the test.
+ */
+ protected void assureResultsDirectoryExists(String resultsDirectory)
+ {
+ File dir = new File(resultsDirectory);
+ if (!dir.exists())
+ {
+ info("Template results directory ("+resultsDirectory+") does not exist");
+ if (dir.mkdirs())
+ {
+ info("Created template results directory");
+ if (DEBUG)
+ {
+ info("Created template results directory: "+resultsDirectory);
+ }
+ }
+ else
+ {
+ String errMsg = "Unable to create '"+resultsDirectory+"'";
+ info(errMsg);
+ fail(errMsg);
+ }
+ }
+ }
+
+
+ /**
+ * Normalizes lines to account for platform differences. Macs use
+ * a single \r, DOS derived operating systems use \r\n, and Unix
+ * uses \n. Replace each with a single \n.
+ *
+ * @return source with all line terminations changed to Unix style
+ */
+ protected String normalizeNewlines (String source)
+ {
+ return source.replaceAll("\r\n?", "\n");
+ }
+
+ /**
+ * Returns whether the processed template matches the
+ * content of the provided comparison file.
+ *
+ * @return Whether the output matches the contents
+ * of the comparison file.
+ *
+ * @exception Exception Test failure condition.
+ */
+ protected boolean isMatch (String resultsDir,
+ String compareDir,
+ String baseFileName,
+ String resultExt,
+ String compareExt) throws Exception
+ {
+ if (DEBUG)
+ {
+ info("Result: "+resultsDir+'/'+baseFileName+'.'+resultExt);
+ }
+ String result = getFileContents(resultsDir, baseFileName, resultExt);
+ return isMatch(result,compareDir,baseFileName,compareExt);
+ }
+
+
+ protected String getFileContents(String dir, String baseFileName, String ext)
+ {
+ String fileName = getFileName(dir, baseFileName, ext, true);
+ return getFileContents(fileName);
+ }
+
+ protected String getFileContents(String file)
+ {
+ String contents = null;
+
+ try
+ {
+ contents = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return contents;
+ }
+
+ /**
+ * Returns whether the processed template matches the
+ * content of the provided comparison file.
+ *
+ * @return Whether the output matches the contents
+ * of the comparison file.
+ *
+ * @exception Exception Test failure condition.
+ */
+ protected boolean isMatch (String result,
+ String compareDir,
+ String baseFileName,
+ String compareExt) throws Exception
+ {
+ String compare = getFileContents(compareDir, baseFileName, compareExt);
+
+ // normalize each wrt newline
+ result = normalizeNewlines(result);
+ compare = normalizeNewlines(compare);
+ if (DEBUG)
+ {
+ info("Expection: "+compareDir+'/'+baseFileName+'.'+compareExt);
+ }
+ return result.equals(compare);
+ }
+
+ /**
+ * Turns a base file name into a test case name.
+ *
+ * @param s The base file name.
+ * @return The test case name.
+ */
+ protected static String getTestCaseName(String s)
+ {
+ StringBuilder name = new StringBuilder();
+ name.append(Character.toTitleCase(s.charAt(0)));
+ name.append(s.substring(1, s.length()).toLowerCase(Locale.ROOT));
+ return name.toString();
+ }
+}