diff options
Diffstat (limited to 'velocity-engine-core/src/test/java/org/apache/velocity/test/ScopeTestCase.java')
-rwxr-xr-x | velocity-engine-core/src/test/java/org/apache/velocity/test/ScopeTestCase.java | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/velocity-engine-core/src/test/java/org/apache/velocity/test/ScopeTestCase.java b/velocity-engine-core/src/test/java/org/apache/velocity/test/ScopeTestCase.java new file mode 100755 index 00000000..21a6490d --- /dev/null +++ b/velocity-engine-core/src/test/java/org/apache/velocity/test/ScopeTestCase.java @@ -0,0 +1,369 @@ +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.runtime.RuntimeConstants; + +import java.util.HashMap; + +/** + * This class tests the directive scope controls + */ +public class ScopeTestCase extends BaseTestCase +{ + public ScopeTestCase(String name) + { + super(name); + } + + @Override + 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"); + engine.setProperty("space.gobbling", "bc"); + } + + 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$foreach.a#end"); + assertTmplEquals("121", "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 testRootTemplateMergeScope() + { + addTemplate("foo", "foo#break($template)bar"); + assertTmplEquals("foo", "foo"); + assertNull(context.get("template")); + } + + public void testParseScope() + { + addTemplate("test", "$template.info.depth"+ + "$!parse.parent.info.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.info.depth"+ + "#set( $template.foo = '?' )"+ + "$!grab.put('inner',$template)"+ + "#break($template)$template.foo"); + addTemplate("outer", "#set( $template.foo = '!' )"+ + "Outer depth: $template.info.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.info.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.info.depth"+ + "#if($macro.info.depth > 2 )#break($macro.topmost)#end"+ + "#foo()#end#foo()"; + assertEvalEquals("123", template); + assertNull(context.get("macro")); + } + + public void testNestedMacroScope() + { + String template = "#macro( a )$macro.info.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.info.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.info.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.info.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.info.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.info.depth"+ + "#if($define.info.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.info.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.info.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.info.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.info.depth"); + assertTmplEquals("$template.info.depth", "test"); + // #parse + assertEvalEquals("$template.info.depth", "#parse('test')"); + } + + public void testTurningOffEvaluateScope() + { + engine.setProperty("evaluate."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); + // root + assertSchmoo("$evaluate.info.depth"); + // #evaluate + assertEvalEquals("$evaluate.info.depth", "#evaluate( '$evaluate.info.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"); + } + + public void testInfoDepth() + { + String template = "#foreach($i in [1..1])"+ + "#foreach($j in [0..0])"+ + "$foreach.info.depth"+ + "#end"+ + "#end"; + assertEvalEquals("2", template); + } + + public void testInfoName() + { + String template = "#foreach($i in [1..1])"+ + "$foreach.info.name #evaluate('$evaluate.info.name')"+ + "#end"; + assertEvalEquals("foreach evaluate", template); + } + + public void testInfoType() + { + addTemplate("info", "#foreach($i in [1..1])"+ + "$foreach.info.type"+ + "#end "+ + "#evaluate('$evaluate.info.type') "+ + "$template.info.type"); + assertTmplEquals("block line utf-8", "info"); + } + + public void testInfoLineAndColumn() + { + String template = " #evaluate('$evaluate.info.line, $evaluate.info.column')"; + assertEvalEquals(" 1, 2", template); + assertEvalEquals("\n\n 3, 4", "\n\n "+template); + } + + public void testInfoTemplate() + { + addTemplate("test", "#evaluate('$evaluate.info.template')"); + assertTmplEquals("test", "test"); + assertEvalEquals("test", "#parse('test')"); + } + +} |