Two phases. First phase, run everything through the parser, and freak out if

anything fails to parse. Second phase, actually merge the templates with a
populated context and compare the output to a golden file iff such a file
exists. Also accumulate any log output generated during that process and report
it if the test fails.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@1971 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2006-11-10 19:22:47 +00:00
parent f0183ce625
commit efd0c2dfe6
@@ -21,15 +21,18 @@
package com.samskivert.velocity;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
/**
* An abstract base class for easily testing Velocity templates.
@@ -41,16 +44,19 @@ public abstract class VelocityTestCase extends TestCase
super(name);
}
protected VelocityTestCase ()
{
this(VelocityTestCase.class.getName());
}
@Override // from TestCase
protected void setUp ()
{
try {
_engine = VelocityUtil.createEngine();
_engine = new VelocityEngine();
_engine.setProperty(VelocityEngine.VM_LIBRARY, "");
_engine.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath");
_engine.setProperty(
"classpath." + VelocityEngine.RESOURCE_LOADER + ".class",
ClasspathResourceLoader.class.getName());
_engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, _logger);
_engine.init();
} catch (Exception e) {
fail("Velocity initialization failed " + e);
}
@@ -59,16 +65,42 @@ public abstract class VelocityTestCase extends TestCase
@Override // from TestCase
protected void runTest ()
{
// first simply evaluate all of the templates
for (String template : getTemplates()) {
try {
runTest(template);
evaluateTemplate(template);
} catch (Exception e) {
fail("Failed to process " + template + ": " + e);
}
}
// then try to actually merge them with a context
for (String template : getTemplates()) {
try {
mergeTemplate(template);
} catch (Exception e) {
fail("Failed to process " + template + ": " + e);
}
}
}
protected void runTest (String template)
protected void evaluateTemplate (String template)
throws Exception
{
InputStream tempin =
getClass().getClassLoader().getResourceAsStream(template);
if (tempin == null) {
fail("Missing template '" + template + "'.");
}
// parse the template
if (!_engine.evaluate(new VelocityContext(), new StringWriter(),
template, tempin)) {
fail("Template parsing failed '" + template + "'.");
}
}
protected void mergeTemplate (String template)
throws Exception
{
// first load our golden output
@@ -76,21 +108,28 @@ public abstract class VelocityTestCase extends TestCase
InputStream goldin =
getClass().getClassLoader().getResourceAsStream(goldpath);
if (goldin == null) {
fail("Missing golden file for " + template +
" [path=" + goldpath + "].");
// if there is no golden template, we don't test this file
return;
}
String goldtext = IOUtils.toString(goldin);
// clear out any previous logging output
_logbuf.getBuffer().setLength(0);
// now generate the test output
VelocityContext context = new VelocityContext();
populateContext(template, context);
StringWriter writer = new StringWriter();
_engine.mergeTemplate(template, context, writer);
// and compare the two
assertEquals("Template output incorrect [template=" + template +
", golden=" + goldpath + "].",
goldtext, writer.toString());
// now compare the two
String output = "Template output incorrect [template=" + template +
", golden=" + goldpath + "].";
String logout = _logbuf.toString();
if (logout.length() > 0) {
output = output + "\n" + logout;
}
assertEquals(output, goldtext, writer.toString());
}
/**
@@ -118,5 +157,36 @@ public abstract class VelocityTestCase extends TestCase
return template + ".test";
}
/** Accumulates logging to a buffer for later reporting. */
protected LogChute _logger = new LogChute() {
public void init (RuntimeServices rs) throws Exception {
// nothing doing
}
public void log (int level, String message) {
switch (level) {
case ERROR_ID:
case WARN_ID:
_logout.println(message);
break;
default:
case INFO_ID:
case DEBUG_ID:
// velocity insists on sending info and debug messages even
// though isLevelEnabled() returns false
break;
}
}
public void log (int level, String message, Throwable t) {
log(level, message);
t.printStackTrace(_logout);
}
public boolean isLevelEnabled (int level) {
return (level == WARN_ID || level == ERROR_ID);
}
};
protected VelocityEngine _engine;
protected StringWriter _logbuf = new StringWriter();
protected PrintWriter _logout = new PrintWriter(_logbuf);
}