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 java.util.HashMap; | |
import org.apache.velocity.VelocityContext; | |
import org.apache.velocity.app.VelocityEngine; | |
import org.apache.velocity.runtime.RuntimeConstants; | |
import org.apache.velocity.runtime.directive.Scope; | |
/** | |
* This class tests the directive scope controls | |
*/ | |
public class ScopeTestCase extends BaseTestCase | |
{ | |
public ScopeTestCase(String name) | |
{ | |
super(name); | |
} | |
protected void setUpEngine(VelocityEngine engine) | |
{ | |
engine.setProperty("a.provide.scope.control", "true"); | |
engine.setProperty("define.provide.scope.control", "true"); | |
engine.setProperty("evaluate.provide.scope.control", "true"); | |
engine.setProperty("foo.provide.scope.control", "true"); | |
engine.setProperty("macro.provide.scope.control", "true"); | |
engine.setProperty("template.provide.scope.control", "true"); | |
engine.setProperty("vm.provide.scope.control", "true"); | |
} | |
public void testRootTemplateMergeScope() | |
{ | |
addTemplate("foo", "foo#break($template)bar"); | |
assertTmplEquals("foo", "foo"); | |
assertNull(context.get("template")); | |
} | |
public void testScopeGetLeakIntoInner() | |
{ | |
addTemplate("foo", "#foreach($i in [1..1])#set($foreach.a=$i)"+ | |
"#foreach($j in [2..2])$foreach.a#set($foreach.a=$j)"+ | |
"#foreach($k in [3..3])$foreach.a#end#end#end"); | |
assertTmplEquals("12", "foo"); | |
} | |
public void testScopeGetLeakDoesntHideNullset() | |
{ | |
addTemplate("a", "#macro(a)#set($macro.a='a')#b()$macro.a#end"+ | |
"#macro(b)$macro.a#set($macro.a=$null)$!macro.a#end"+ | |
"#a()"); | |
assertTmplEquals("aa", "a"); | |
} | |
public void testParseScope() | |
{ | |
addTemplate("test", "$template.depth"+ | |
"$!parse.parent.depth"+ | |
"#set( $template.foo = 'bar' )"+ | |
"$template.foo"+ | |
"#break($template)"+ | |
"woogie"); | |
assertEvalEquals("1bar", "#parse( 'test' )"); | |
assertNull(context.get("template")); | |
} | |
public void testNestedParseScope() | |
{ | |
HashMap grab = new HashMap(); | |
context.put("grab", grab); | |
addTemplate("inner", "Inner depth: $template.depth"+ | |
"#set( $template.foo = '?' )"+ | |
"$!grab.put('inner',$template)"+ | |
"#break($template)$template.foo"); | |
addTemplate("outer", "#set( $template.foo = '!' )"+ | |
"Outer depth: $template.depth "+ | |
"#parse('inner')"+ | |
"$!grab.put('outer', $template)"+ | |
"$template.foo"); | |
assertEvalEquals("Outer depth: 1 Inner depth: 2!", "#parse('outer')"); | |
// make extra sure that the outer control was restored after the stop | |
assertFalse(grab.get("inner") == grab.get("outer")); | |
// make sure the outer control was cleaned up | |
assertNull(context.get("template")); | |
addTemplate("3", "$template.topmost.foo#set( $template.topmost.foo = 'bar' )"); | |
addTemplate("2", "#parse( '3' )$!parse.foo"); | |
addTemplate("1", "#set( $template.foo = 'foo' )#parse('2')$template.foo"); | |
assertEvalEquals("foobar", "#parse('1')$!parse"); | |
// make sure the top control was cleaned up | |
assertNull(context.get("template")); | |
} | |
public void testForeachScope() | |
{ | |
String template = "#foreach( $i in [0..2] )"+ | |
"#if( $i > 1 )#break($foreach)#end"+ | |
"$foreach.index:$foreach.count:$foreach.hasNext,"+ | |
"#end"; | |
assertEvalEquals("0:1:true,1:2:true,", template); | |
assertNull(context.get("foreach")); | |
} | |
public void testNestedForeachScope() | |
{ | |
String template = "#foreach( $i in [1..5] )"+ | |
"#foreach( $j in [1..2] )"+ | |
"#if ( $i > $foreach.count + $foreach.index + $foreach.depth )#break($foreach.topmost)#end"+ | |
"#end"+ | |
"$i"+ | |
"#end"; | |
assertEvalEquals("123", template); | |
assertNull(context.get("foreach")); | |
} | |
public void testMacroScope() | |
{ | |
String template = "#macro( foo $i )"+ | |
"#if($i > 2 )#break($macro)#end"+ | |
"$i#end"+ | |
"#foo( 0 )#foo( 1 )#foo( 2 )"; | |
assertEvalEquals("012", template); | |
assertNull(context.get("macro")); | |
} | |
public void testRecursiveMacroScope() | |
{ | |
String template = "#macro( foo )$macro.depth"+ | |
"#if($macro.depth > 2 )#break($macro.topmost)#end"+ | |
"#foo()#end#foo()"; | |
assertEvalEquals("123", template); | |
assertNull(context.get("macro")); | |
} | |
public void testNestedMacroScope() | |
{ | |
String template = "#macro( a )$macro.depth#set($macro.c = 'a')$macro.c#end"+ | |
"#macro( b )#set($macro.c = 'b' )#a()$macro.c#end"+ | |
"#b()"; | |
assertEvalEquals("2ab", template); | |
assertNull(context.get("macro")); | |
} | |
public void testBodyMacroScope() | |
{ | |
String template = "#macro( foo $bar )$bodyContent$macro.bar#end"+ | |
"#@foo( 'bar' )#set( $macro.bar = 'foo'+$bar )"+ | |
"#set( $foo.d = $foo.depth )$foo.d #end"; | |
assertEvalEquals("1 foobar", template); | |
assertNull(context.get("foo")); | |
assertNull(context.get("macro")); | |
} | |
public void testRecursiveBodyMacroScope() | |
{ | |
engine.setProperty(RuntimeConstants.VM_MAX_DEPTH, "5"); | |
String template = "#macro( foo )$bodyContent$macro.i#end"+ | |
"#@foo()#set( $macro.i = \"$!macro.i$foo.depth,\" )"+ | |
"$!bodyContent#end"; | |
assertEvalEquals("1,2,3,4,5,", template); | |
assertNull(context.get("foo")); | |
assertNull(context.get("macro")); | |
} | |
public void testDefineScope() | |
{ | |
String template = "#define( $foo )#set( $define.bar = 'bar'+$define.depth )$define.bar#end$foo"; | |
assertEvalEquals("bar1", template); | |
assertNull(context.get("define")); | |
} | |
public void testNestedDefineScope() | |
{ | |
String template = "#define($a)$b c#end"+ | |
"#define($b)$define.depth#break($define.topmost)#end"+ | |
"$a"; | |
assertEvalEquals("2", template); | |
assertNull(context.get("define")); | |
} | |
public void testRecursiveDefineScope() | |
{ | |
engine.setProperty(RuntimeConstants.DEFINE_DIRECTIVE_MAXDEPTH, "10"); | |
String template = "#define($a)$define.depth"+ | |
"#if($define.depth == 5)#break($define)#end,$a#end$a"; | |
assertEvalEquals("1,2,3,4,5", template); | |
assertNull(context.get("define")); | |
} | |
public void testRootEvaluateScope() | |
{ | |
assertEvalEquals("1", "$evaluate.depth"); | |
assertEvalEquals("foo", "foo#break($evaluate)bar"); | |
assertNull(context.get("evaluate")); | |
} | |
public void testEvaluateScope() | |
{ | |
context.put("h", "#"); | |
context.put("d", "$"); | |
String template = "${h}set( ${d}evaluate.foo = 'bar' )"+ | |
"${d}evaluate.foo ${d}evaluate.depth"; | |
addTemplate("eval", "#evaluate(\""+template+"\")"); | |
assertTmplEquals("bar 1", "eval"); | |
assertNull(context.get("evaluate")); | |
assertNull(context.get("template")); | |
} | |
public void testNestedEvaluateScope() | |
{ | |
context.put("h", "#"); | |
context.put("d", "$"); | |
addTemplate("e", "#evaluate(\"${h}evaluate( '${d}evaluate.depth${h}stop(${d}evaluate) blah' )\")"); | |
assertTmplEquals("2", "e"); | |
assertNull(context.get("evaluate")); | |
assertNull(context.get("template")); | |
} | |
public void testTurningOffTemplateScope() | |
{ | |
engine.setProperty("template."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
// root | |
addTemplate("test", "$template.depth"); | |
assertTmplEquals("$template.depth", "test"); | |
// #parse | |
assertEvalEquals("$template.depth", "#parse('test')"); | |
} | |
public void testTurningOffEvaluateScope() | |
{ | |
engine.setProperty("evaluate."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
// root | |
assertSchmoo("$evaluate.depth"); | |
// #evaluate | |
assertEvalEquals("$evaluate.depth", "#evaluate( '$evaluate.depth' )"); | |
} | |
public void testTurningOffMacroScope() | |
{ | |
engine.setProperty("macro."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
engine.setProperty("foo."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
// macro definition | |
assertEvalEquals("$macro", "#macro(a)$macro#end#a()"); | |
// macro body | |
assertEvalEquals("$macro $foo", "#macro(foo)$bodyContent#end#@foo()$macro $foo#end"); | |
} | |
public void testTurningOffDefineScope() | |
{ | |
engine.setProperty("define."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
assertEvalEquals("$define", "#define($a)$define#end$a"); | |
} | |
public void testTurningOffForeachScope() | |
{ | |
engine.setProperty("foreach."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); | |
assertEvalEquals("$foreach$foreach", "#foreach($i in [0..1])$foreach#end"); | |
} | |
public void testTemplateReplaced() | |
{ | |
context.put("template", "foo"); | |
addTemplate("test", "$template.replaced"); | |
assertTmplEquals("foo", "test"); | |
assertEvalEquals("foo", "#parse('test')"); | |
assertContextValue("template", "foo"); | |
} | |
public void testEvaluateReplaced() | |
{ | |
context.put("evaluate","foo"); | |
assertEvalEquals("foo", "$evaluate.replaced"); | |
assertEvalEquals("foo", "#evaluate('$evaluate.replaced')"); | |
assertContextValue("evaluate", "foo"); | |
} | |
public void testMacroReplaced() | |
{ | |
context.put("macro", "foo"); | |
assertEvalEquals("foo foo foo", "$macro #macro(a)$macro.replaced#end#a() $macro"); | |
assertContextValue("macro", "foo"); | |
} | |
public void testForeachReplaced() | |
{ | |
context.put("foreach", "foo"); | |
assertEvalEquals("foofoofoo", "$foreach#foreach($i in [1..1])$foreach.replaced#end$foreach"); | |
assertEquals("foo", context.get("foreach")); | |
context.put("foreach", "a"); | |
assertEvalEquals("a", "#foreach($i in [1..1])#foreach($j in [1..1])$foreach.replaced#end#end"); | |
assertContextValue("foreach", "a"); | |
} | |
public void testDefineReplaced() | |
{ | |
context.put("define", "a"); | |
assertEvalEquals("a", "#define($a)$define.replaced#end$a"); | |
assertContextValue("define", "a"); | |
} | |
public void testBodyContentReplaced() | |
{ | |
context.put("vm", "a"); | |
assertEvalEquals("a", "#macro(vm)$bodyContent#end#@vm()$vm.replaced#end"); | |
assertContextValue("vm", "a"); | |
} | |
} |