aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java')
-rw-r--r--velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java257
1 files changed, 257 insertions, 0 deletions
diff --git a/velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java b/velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java
new file mode 100644
index 00000000..5a6b6d17
--- /dev/null
+++ b/velocity-engine-core/src/test/java/org/apache/velocity/test/StrictReferenceTestCase.java
@@ -0,0 +1,257 @@
+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 org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.VelocityException;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+/**
+ * Test strict reference mode turned on by the velocity property
+ * runtime.references.strict
+ */
+public class StrictReferenceTestCase extends BaseTestCase
+{
+ public StrictReferenceTestCase(String name)
+ {
+ super(name);
+ }
+
+ // second engine to test WITH conversions
+ VelocityEngine engine2;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ /* first engine without conversions */
+ engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE);
+ engine.setProperty(RuntimeConstants.CONVERSION_HANDLER_CLASS, "none");
+
+ /* second engine with conversions */
+ engine2 = createEngine();
+ engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE);
+
+ context.put("NULL", null);
+ context.put("bar", null);
+ context.put("TRUE", Boolean.TRUE);
+ }
+
+ /**
+ * Test the modified behavior of #if in strict mode. Mainly, that
+ * single variables references in #if statements use non strict rules
+ */
+ public void testIfStatement()
+ {
+ Fargo fargo = new Fargo();
+ fargo.next = new Fargo();
+ context.put("fargo", fargo);
+ assertEvalEquals("", "#if($bogus)xxx#end");
+ assertEvalEquals("xxx", "#if($fargo)xxx#end");
+ assertEvalEquals("", "#if( ! $fargo)xxx#end");
+ assertEvalEquals("xxx", "#if($bogus || $fargo)xxx#end");
+ assertEvalEquals("", "#if($bogus && $fargo)xxx#end");
+ assertEvalEquals("", "#if($fargo != $NULL && $bogus)xxx#end");
+ assertEvalEquals("xxx", "#if($fargo == $NULL || ! $bogus)xxx#end");
+ assertEvalEquals("xxx", "#if(! $bogus1 && ! $bogus2)xxx#end");
+ assertEvalEquals("xxx", "#if($fargo.prop == \"propiness\" && ! $bogus && $bar == $NULL)xxx#end");
+ assertEvalEquals("", "#if($bogus && $bogus.foo)xxx#end");
+
+ assertMethodEx("#if($bogus.foo)#end");
+ assertMethodEx("#if(!$bogus.foo)#end");
+ }
+
+
+ /**
+ * We make sure that variables can actuall hold null
+ * values.
+ */
+ public void testAllowNullValues()
+ throws Exception
+ {
+ evaluate("$!bar");
+ assertEvalEquals("true", "#if($bar == $NULL)true#end");
+ assertEvalEquals("true", "#set($foobar = $NULL)#if($foobar == $NULL)true#end");
+ assertEvalEquals("13", "#set($list = [1, $NULL, 3])#foreach($item in $list)#if($item != $NULL)$item#end#end");
+ }
+
+ /**
+ * Test that variables references that have not been defined throw exceptions
+ */
+ public void testStrictVariableRef()
+ throws Exception
+ {
+ // We expect a Method exception on the following
+ assertMethodEx("$bogus");
+ assertMethodEx("#macro(test)$bogus#end #test()");
+
+ assertMethodEx("#set($bar = $bogus)");
+
+ assertMethodEx("#if($bogus == \"bar\") #end");
+ assertMethodEx("#if($bogus != \"bar\") #end");
+ assertMethodEx("#if(\"bar\" == $bogus) #end");
+ assertMethodEx("#if($bogus > 1) #end");
+ assertMethodEx("#foreach($item in $bogus)#end");
+
+ // make sure no exceptions are thrown here
+ evaluate("#set($foo = \"bar\") $foo");
+ evaluate("#macro(test1 $foo1) $foo1 #end #test1(\"junk\")");
+ evaluate("#macro(test2) #set($foo2 = \"bar\") $foo2 #end #test2()");
+ }
+
+ /**
+ * Test that exceptions are thrown when methods are called on
+ * references that contains objects that do not contains those
+ * methods.
+ */
+ public void testStrictMethodRef()
+ {
+ Fargo fargo = new Fargo();
+ fargo.next = new Fargo();
+ context.put("fargo", fargo);
+
+ // Mainly want to make sure no exceptions are thrown here
+ assertEvalEquals("propiness", "$fargo.prop");
+ assertEvalEquals("", "$!fargo.nullVal");
+ assertEvalEquals("propiness", "$fargo.next.prop");
+
+ assertMethodEx("$fargo.foobar");
+ assertMethodEx("$fargo.next.foobar");
+ assertMethodEx("$fargo.foobar()");
+ assertMethodEx("#set($fargo.next.prop = $TRUE)");
+ assertMethodEx("$fargo.next.setProp($TRUE)");
+ }
+
+ /**
+ * Make sure exceptions are thrown when when we attempt to call
+ * methods on null values.
+ */
+ public void testStrictMethodOnNull()
+ {
+ Fargo fargo = new Fargo();
+ fargo.next = new Fargo();
+ context.put("fargo", fargo);
+
+ assertVelocityEx("$NULL.bogus");
+ assertVelocityEx("$fargo.nullVal.bogus");
+ assertVelocityEx("$fargo.next.nullVal.bogus");
+ assertVelocityEx("#if (\"junk\" == $fargo.nullVal.bogus)#end");
+ assertVelocityEx("#if ($fargo.nullVal.bogus > 2)#end");
+ assertVelocityEx("#set($fargo.next.nullVal.bogus = \"junk\")");
+ assertVelocityEx("#set($foo = $NULL.bogus)");
+ assertVelocityEx("#foreach($item in $fargo.next.nullVal.bogus)#end");
+
+ evaluate("$fargo.prop.toString()");
+ assertVelocityEx("#set($fargo.prop = $NULL)$fargo.prop.next");
+
+ // make sure no exceptions are thrown here
+ evaluate("$!fargo.next.next");
+ evaluate("$!fargo.next.nullVal");
+ evaluate("#foreach($item in $fargo.nullVal)#end");
+ }
+
+ /**
+ * Make sure undefined macros throw exceptions
+ */
+ public void testMacros()
+ {
+ assertVelocityEx("#bogus()");
+ assertVelocityEx("#bogus ( )");
+ assertVelocityEx("#bogus( $a )");
+ assertVelocityEx("abc#bogus ( $a )a ");
+
+ assertEvalEquals(" true ", "#macro(test1) true #end#test1()");
+ assertEvalEquals(" true ", "#macro(test2 $a) $a #end#test2 ( \"true\")");
+ assertEvalEquals("#CCFFEE", "#CCFFEE");
+ assertEvalEquals("#F - ()", "#F - ()");
+ assertEvalEquals("#F{}", "#F{}");
+ }
+
+
+ public void testRenderingNull()
+ {
+ Fargo fargo = new Fargo();
+ fargo.next = new Fargo();
+ context.put("fargo", fargo);
+
+ assertVelocityEx("#set($foo = $NULL)$foo");
+ assertEvalEquals("", "#set($foo = $NULL)$!foo");
+ assertVelocityEx("$fargo.nullVal");
+ assertEvalEquals("", "$!fargo.nullVal");
+ assertVelocityEx("$fargo.next.next");
+ assertEvalEquals("", "$!fargo.next.next");
+ assertVelocityEx("$fargo.next.nullVal");
+ assertEvalEquals("", "$!fargo.next.nullVal");
+ }
+
+ /**
+ * Assert that we get a MethodInvocationException when calling evaluate
+ */
+ public void assertMethodEx(String template)
+ {
+ assertEvalException(template, MethodInvocationException.class);
+ }
+
+ /**
+ * Assert that we get a VelocityException when calling evaluate
+ */
+ public void assertVelocityEx(String template)
+ {
+ assertEvalException(template, VelocityException.class);
+ }
+
+ /**
+ * Assert that we get a MethodInvocationException when calling evaluate
+ */
+ public void assertParseEx(String template)
+ {
+ assertEvalException(template, ParseErrorException.class);
+ }
+
+
+ public static class Fargo
+ {
+ String prop = "propiness";
+ Fargo next = null;
+
+ public String getProp()
+ {
+ return prop;
+ }
+
+ public void setProp(String val)
+ {
+ this.prop = val;
+ }
+
+ public String getNullVal()
+ {
+ return null;
+ }
+
+ public Fargo getNext()
+ {
+ return next;
+ }
+ }
+}