blob: 3a9a3bacc9688e858daa50f5c259f93232056d1a [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 org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.exception.ParseErrorException;
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);
}
public void setUp() throws Exception
{
super.setUp();
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 = prop;
}
public String getNullVal()
{
return null;
}
public Fargo getNext()
{
return next;
}
}
}