blob: ad9464189309f91267a64e2dfd28d4b21e9938fd [file] [log] [blame]
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.Test;
import junit.framework.TestSuite;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.implement.EscapeHtmlReference;
import org.apache.velocity.app.event.implement.EscapeJavaScriptReference;
import org.apache.velocity.app.event.implement.EscapeReference;
import org.apache.velocity.app.event.implement.EscapeSqlReference;
import org.apache.velocity.app.event.implement.EscapeXmlReference;
import org.apache.velocity.app.event.implement.InvalidReferenceInfo;
import org.apache.velocity.app.event.implement.ReportInvalidReferences;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
/**
* Tests the operation of the built in event handlers.
*
* @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
* @version $Id$
*/
public class BuiltInEventHandlerTestCase extends BaseTestCase {
protected boolean DEBUG = false;
/**
* VTL file extension.
*/
private static final String TMPL_FILE_EXT = "vm";
/**
* Comparison file extension.
*/
private static final String CMP_FILE_EXT = "cmp";
/**
* Comparison file extension.
*/
private static final String RESULT_FILE_EXT = "res";
/**
* Path for templates. This property will override the
* value in the default velocity properties file.
*/
private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/includeevent";
/**
* Results relative to the build directory.
*/
private static final String RESULTS_DIR = TEST_RESULT_DIR + "/includeevent";
/**
* Results relative to the build directory.
*/
private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/includeevent/compare";
/**
* Default constructor.
*/
public BuiltInEventHandlerTestCase(String name)
{
super(name);
}
public void setUp() throws Exception
{
assureResultsDirectoryExists(RESULTS_DIR);
super.setUp();
}
public static Test suite()
{
return new TestSuite(BuiltInEventHandlerTestCase.class);
}
protected void log(String out)
{
if (DEBUG)
{
System.out.println (out);
}
}
/**
* Test reporting of invalid syntax
* @throws Exception
*/
public void testReportInvalidReferences1() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
context.put("n1", null);
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar() $!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(2,errors.size());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference());
assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference());
log("Caught invalid references (local configuration).");
}
public void testReportInvalidReferences2() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty("event_handler.invalid_references.exception","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 no problem");
try {
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()");
fail ("Expected exception.");
} catch (RuntimeException E) {}
log("Caught invalid references (global configuration).");
}
/**
* Test reporting of invalid syntax
* @throws Exception
*/
public void testReportQuietInvalidReferences() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty("event_handler.invalid_references.quiet","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
context.put("n1", null);
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar() $!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(3,errors.size());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference());
assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(2)).getInvalidReference());
log("Caught invalid references (local configuration).");
}
/**
* Test reporting of invalid syntax
* @throws Exception
*/
public void testReportNullInvalidReferences() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty("event_handler.invalid_references.null","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
context.put("n1", null);
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar() $!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(3,errors.size());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference());
assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference());
assertEquals("$n1",((InvalidReferenceInfo) errors.get(2)).getInvalidReference());
log("Caught invalid references (local configuration).");
}
/**
* Test reporting of invalid syntax
* @throws Exception
*/
public void testReportNullQuietInvalidReferences() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty("event_handler.invalid_references.quiet","true");
ve.setProperty("event_handler.invalid_references.null","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
context.put("n1", null);
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar() $!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(5,errors.size());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference());
assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(2)).getInvalidReference());
assertEquals("$n1",((InvalidReferenceInfo) errors.get(3)).getInvalidReference());
assertEquals("$n1",((InvalidReferenceInfo) errors.get(4)).getInvalidReference());
log("Caught invalid references (local configuration).");
}
/**
* Test reporting of invalid syntax
* @throws Exception
*/
public void testReportTestedInvalidReferences() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty("event_handler.invalid_references.tested","true");
ReportInvalidReferences reporter = new ReportInvalidReferences();
ve.init();
VelocityContext context = new VelocityContext();
EventCartridge ec = new EventCartridge();
ec.addEventHandler(reporter);
ec.attachToContext(context);
context.put("a1","test");
context.put("b1","test");
context.put("n1", null);
Writer writer = new StringWriter();
ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar() $!c1 $n1 $!n1 #if($c1) nop #end");
List errors = reporter.getInvalidReferences();
assertEquals(3,errors.size());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference());
assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference());
assertEquals("$c1",((InvalidReferenceInfo) errors.get(2)).getInvalidReference());
log("Caught invalid references (local configuration).");
}
/**
* Test escaping
* @throws Exception
*/
public void testEscapeHtml() throws Exception
{
EscapeReference esc = new EscapeHtmlReference();
assertEquals("test string&amp;another&lt;b&gt;bold&lt;/b&gt;test",esc.referenceInsert(null,"","test string&another<b>bold</b>test"));
assertEquals("&lt;&quot;&gt;",esc.referenceInsert(null,"","<\">"));
assertEquals("test string",esc.referenceInsert(null,"","test string"));
log("Correctly escaped HTML");
}
/**
* Test escaping
* @throws Exception
*/
public void testEscapeXml() throws Exception
{
EscapeReference esc = new EscapeXmlReference();
assertEquals("test string&amp;another&lt;b&gt;bold&lt;/b&gt;test",esc.referenceInsert(null,"","test string&another<b>bold</b>test"));
assertEquals("&lt;&quot;&gt;",esc.referenceInsert(null,"","<\">"));
assertEquals("&apos;",esc.referenceInsert(null,"","'"));
assertEquals("test string",esc.referenceInsert(null,"","test string"));
log("Correctly escaped XML");
}
/**
* Test escaping
* @throws Exception
*/
public void testEscapeSql() throws Exception
{
EscapeReference esc = new EscapeSqlReference();
assertEquals("Jimmy''s Pizza",esc.referenceInsert(null,"","Jimmy's Pizza"));
assertEquals("test string",esc.referenceInsert(null,"","test string"));
log("Correctly escaped SQL");
}
/**
* Test escaping
* @throws Exception
*/
public void testEscapeJavaScript() throws Exception
{
EscapeReference esc = new EscapeJavaScriptReference();
assertEquals("Jimmy\\'s Pizza",esc.referenceInsert(null,"","Jimmy's Pizza"));
assertEquals("test string",esc.referenceInsert(null,"","test string"));
log("Correctly escaped Javascript");
}
/**
* test that escape reference handler works with no match restrictions
* @throws Exception
*/
public void testEscapeReferenceMatchAll() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, "org.apache.velocity.app.event.implement.EscapeHtmlReference");
ve.init();
Context context;
Writer writer;
// test normal reference
context = new VelocityContext();
writer = new StringWriter();
context.put("bold","<b>");
ve.evaluate(context,writer,"test","$bold test & test");
assertEquals("&lt;b&gt; test & test",writer.toString());
// test method reference
context = new VelocityContext();
writer = new StringWriter();
context.put("bold","<b>");
ve.evaluate(context,writer,"test","$bold.substring(0,1)");
assertEquals("&lt;",writer.toString());
log("Escape matched all references (global configuration)");
}
/**
* test that escape reference handler works with match restrictions
* @throws Exception
*/
public void testEscapeReferenceMatch() throws Exception
{
// set up HTML match on everything, JavaScript match on _js*
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, "org.apache.velocity.app.event.implement.EscapeHtmlReference,org.apache.velocity.app.event.implement.EscapeJavaScriptReference");
ve.setProperty("eventhandler.escape.javascript.match", "/.*_js.*/");
ve.init();
Writer writer;
// Html no JavaScript
writer = new StringWriter();
ve.evaluate(newEscapeContext(),writer,"test","$test1");
assertEquals("Jimmy's &lt;b&gt;pizza&lt;/b&gt;",writer.toString());
// comment out bad test -- requires latest commons-lang
/**
// JavaScript and HTML
writer = new StringWriter();
ve.evaluate(newEscapeContext(),writer,"test","$test1_js");
assertEquals("Jimmy\\'s &lt;b&gt;pizza&lt;/b&gt;",writer.toString());
// JavaScript and HTML
writer = new StringWriter();
ve.evaluate(newEscapeContext(),writer,"test","$test1_js_test");
assertEquals("Jimmy\\'s &lt;b&gt;pizza&lt;/b&gt;",writer.toString());
// JavaScript and HTML (method call)
writer = new StringWriter();
ve.evaluate(newEscapeContext(),writer,"test","$test1_js.substring(0,7)");
assertEquals("Jimmy\\'s",writer.toString());
**/
log("Escape selected references (global configuration)");
}
private Context newEscapeContext()
{
Context context = new VelocityContext();
context.put("test1","Jimmy's <b>pizza</b>");
context.put("test1_js","Jimmy's <b>pizza</b>");
context.put("test1_js_test","Jimmy's <b>pizza</b>");
return context;
}
public void testPrintExceptionHandler() throws Exception
{
VelocityEngine ve1 = new VelocityEngine();
ve1.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions");
ve1.init();
VelocityEngine ve2 = new VelocityEngine();
ve2.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions");
ve2.setProperty("eventhandler.methodexception.templateinfo","true");
ve2.init();
VelocityEngine ve3 = new VelocityEngine();
ve3.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions");
ve3.setProperty("eventhandler.methodexception.stacktrace","true");
ve3.init();
Context context;
StringWriter writer;
context = new VelocityContext();
context.put("list",new ArrayList());
// exception and message only
writer = new StringWriter();
ve1.evaluate(context, writer, "test", "$list.get(0)");
String result = writer.toString();
assertTrue(result.contains("IndexOutOfBoundsException"));
assertTrue(result.contains("Index: 0, Size: 0"));
assertTrue(!result.contains("at test (line 1, column 7)"));
assertTrue(!result.contains("rangeCheck"));
// exception, message and template info
writer = new StringWriter();
ve2.evaluate(context,writer,"test","$list.get(0)");
result = writer.toString();
assertTrue(result.contains("IndexOutOfBoundsException"));
assertTrue(result.contains("Index: 0, Size: 0"));
assertTrue(result.contains("at test (line 1, column 7)"));
assertTrue(!result.contains("rangeCheck"));
// exception, message and stack trace
writer = new StringWriter();
ve3.evaluate(context,writer,"test","$list.get(0)");
result = writer.toString();
assertTrue(result.contains("IndexOutOfBoundsException"));
assertTrue(result.contains("Index: 0, Size: 0"));
assertTrue(!result.contains("at test (line 1, column 7)"));
assertTrue(result.contains("rangeCheck"));
log("PrintException handler successful.");
}
public void testIncludeNotFound() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeNotFound");
ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH);
ve.init();
Template template;
FileOutputStream fos;
Writer fwriter;
Context context;
template = ve.getTemplate( getFileName(null, "test6", TMPL_FILE_EXT) );
fos = new FileOutputStream (
getFileName(RESULTS_DIR, "test6", RESULT_FILE_EXT));
fwriter = new BufferedWriter( new OutputStreamWriter(fos) );
context = new VelocityContext();
template.merge(context, fwriter);
fwriter.flush();
fwriter.close();
if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test6", RESULT_FILE_EXT, CMP_FILE_EXT))
{
fail("Output incorrect.");
}
log("IncludeNotFound handler successful.");
}
public void testIncludeNotFoundMissingResourceName() throws Exception
{
// uses base test support
engine.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeNotFound");
addTemplate("notfound.vm", "$missingResource");
assertEvalEquals("foo", "#parse('foo')");
}
public void testIncludeRelativePath() throws Exception
{
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeRelativePath");
ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH);
ve.init();
Template template;
FileOutputStream fos;
Writer fwriter;
Context context;
template = ve.getTemplate( getFileName(null, "subdir/test2", TMPL_FILE_EXT) );
fos = new FileOutputStream (
getFileName(RESULTS_DIR, "test2", RESULT_FILE_EXT));
fwriter = new BufferedWriter( new OutputStreamWriter(fos) );
context = new VelocityContext();
template.merge(context, fwriter);
fwriter.flush();
fwriter.close();
if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test2", RESULT_FILE_EXT, CMP_FILE_EXT))
{
fail("Output incorrect.");
}
log("IncludeRelativePath handler successful.");
}
}