Skip to content
This repository
Browse code

FIX Arguments to method calls reseting scope

  • Loading branch information...
commit ae3e3f3b44ce1c01832222b257ca2c26966027dc 1 parent 7349682
Hamish Friedlander authored June 25, 2013
69  tests/view/SSViewerTest.php
@@ -1074,7 +1074,7 @@ public function testRenderWithSourceFileComments() {
1074 1074
 		$origEnv = Config::inst()->get('Director', 'environment_type');
1075 1075
 		Config::inst()->update('Director', 'environment_type', 'dev');
1076 1076
 		Config::inst()->update('SSViewer', 'source_file_comments', true);
1077  
-	   $f = FRAMEWORK_PATH . '/tests/templates/SSViewerTestComments';
  1077
+		$f = FRAMEWORK_PATH . '/tests/templates/SSViewerTestComments';
1078 1078
 		$templates = array(
1079 1079
 			array(
1080 1080
 				'name' => 'SSViewerTestCommentsFullSource',
@@ -1090,7 +1090,8 @@ public function testRenderWithSourceFileComments() {
1090 1090
 			array(
1091 1091
 				'name' => 'SSViewerTestCommentsFullSourceHTML4Doctype',
1092 1092
 				'expected' => ""
1093  
-					. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"
  1093
+					. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML "
  1094
+					. "4.01//EN\"\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"
1094 1095
 					. "<!-- template $f/SSViewerTestCommentsFullSourceHTML4Doctype.ss -->"
1095 1096
 					. "<html>"
1096 1097
 					. "\t<head></head>"
@@ -1209,6 +1210,45 @@ public function testRequireCallInTemplateInclude() {
1209 1210
 			"tests/forms/RequirementsTest_a.js"
1210 1211
 		));
1211 1212
 	}
  1213
+
  1214
+	public function testCallsWithArguments() {
  1215
+		$data = new ArrayData(array(
  1216
+			'Set' => new ArrayList(array(
  1217
+				new SSViewerTest_Object("1"),
  1218
+				new SSViewerTest_Object("2"),
  1219
+				new SSViewerTest_Object("3"),
  1220
+				new SSViewerTest_Object("4"),
  1221
+				new SSViewerTest_Object("5"),
  1222
+			)),
  1223
+			'Level' => new SSViewerTest_LevelTest(1),
  1224
+			'Nest' => array(
  1225
+				'Level' => new SSViewerTest_LevelTest(2),
  1226
+			),
  1227
+		));
  1228
+
  1229
+		$tests = array(
  1230
+			'$Level.output(1)' => '1-1',
  1231
+			'$Nest.Level.output($Set.First.Number)' => '2-1',
  1232
+			'<% with $Set %>$Up.Level.output($First.Number)<% end_with %>' => '1-1',
  1233
+			'<% with $Set %>$Top.Nest.Level.output($First.Number)<% end_with %>' => '2-1',
  1234
+			'<% loop $Set %>$Up.Nest.Level.output($Number)<% end_loop %>' => '2-12-22-32-42-5',
  1235
+			'<% loop $Set %>$Top.Level.output($Number)<% end_loop %>' => '1-11-21-31-41-5',
  1236
+			'<% with $Nest %>$Level.output($Top.Set.First.Number)<% end_with %>' => '2-1',
  1237
+			'<% with $Level %>$output($Up.Set.Last.Number)<% end_with %>' => '1-5',
  1238
+			'<% with $Level.forWith($Set.Last.Number) %>$output("hi")<% end_with %>' => '5-hi',
  1239
+			'<% loop $Level.forLoop($Set.First.Number) %>$Number<% end_loop %>' => '!0',
  1240
+			'<% with $Nest %>
  1241
+				<% with $Level.forWith($Up.Set.First.Number) %>$output("hi")<% end_with %>
  1242
+			<% end_with %>' => '1-hi',
  1243
+			'<% with $Nest %>
  1244
+				<% loop $Level.forLoop($Top.Set.Last.Number) %>$Number<% end_loop %>
  1245
+			<% end_with %>' => '!0!1!2!3!4',
  1246
+		);
  1247
+
  1248
+		foreach($tests as $template => $expected) {
  1249
+			$this->assertEquals($expected, trim($this->render($template, $data)));
  1250
+		}
  1251
+	}
1212 1252
 }
1213 1253
 
1214 1254
 /**
@@ -1347,3 +1387,28 @@ public static function get_argmix() {
1347 1387
 	}
1348 1388
 
1349 1389
 }
  1390
+
  1391
+class SSViewerTest_LevelTest extends ViewableData implements TestOnly {
  1392
+	protected $depth;
  1393
+
  1394
+	public function __construct($depth = 1) {
  1395
+		$this->depth = $depth;
  1396
+	}
  1397
+
  1398
+	public function output($val) {
  1399
+		return "$this->depth-$val";
  1400
+	}
  1401
+
  1402
+	public function forLoop($number) {
  1403
+		$ret = array();
  1404
+		for($i = 0; $i < (int)$number; ++$i) {
  1405
+			$ret[] = new SSViewerTest_Object("!$i");
  1406
+		}
  1407
+		return new ArrayList($ret);
  1408
+	}
  1409
+
  1410
+	public function forWith($number) {
  1411
+		return new self($number);
  1412
+	}
  1413
+}
  1414
+
2  view/SSTemplateParser.php
@@ -615,7 +615,7 @@ function match_Lookup ($stack = array()) {
615 615
 
616 616
 	
617 617
 	function Lookup__construct(&$res) {
618  
-		$res['php'] = '$scope';
  618
+		$res['php'] = '$scope->locally()';
619 619
 		$res['LookupSteps'] = array();
620 620
 	}
621 621
 	
2  view/SSTemplateParser.php.inc
@@ -157,7 +157,7 @@ class SSTemplateParser extends Parser {
157 157
 	*/
158 158
 	
159 159
 	function Lookup__construct(&$res) {
160  
-		$res['php'] = '$scope';
  160
+		$res['php'] = '$scope->locally()';
161 161
 		$res['LookupSteps'] = array();
162 162
 	}
163 163
 	
24  view/SSViewer.php
@@ -49,18 +49,34 @@ class SSViewer_Scope {
49 49
 
50 50
 	public function __construct($item){
51 51
 		$this->item = $item;
52  
-		$this->localIndex=0;
  52
+		$this->localIndex = 0;
  53
+		$this->localStack = array();
53 54
 		$this->itemStack[] = array($this->item, null, 0, null, null, 0);
54 55
 	}
55 56
 	
56 57
 	public function getItem(){
57 58
 		return $this->itemIterator ? $this->itemIterator->current() : $this->item;
58 59
 	}
59  
-	
60  
-	public function resetLocalScope(){
  60
+
  61
+	/** Called at the start of every lookup chain by SSTemplateParser to indicate a new lookup from local scope */
  62
+	public function locally() {
61 63
 		list($this->item, $this->itemIterator, $this->itemIteratorTotal, $this->popIndex, $this->upIndex,
62 64
 			$this->currentIndex) = $this->itemStack[$this->localIndex];
63  
-		array_splice($this->itemStack, $this->localIndex+1);
  65
+
  66
+		// Remember any  un-completed (resetLocalScope hasn't been called) lookup chain. Even if there isn't an
  67
+		// un-completed chain we need to store an empty item, as resetLocalScope doesn't know the difference later
  68
+		$this->localStack[] = array_splice($this->itemStack, $this->localIndex+1);
  69
+
  70
+		return $this;
  71
+	}
  72
+
  73
+	public function resetLocalScope(){
  74
+		$previousLocalState = $this->localStack ? array_pop($this->localStack) : null;
  75
+
  76
+		array_splice($this->itemStack, $this->localIndex+1, count($this->itemStack), $previousLocalState);
  77
+
  78
+		list($this->item, $this->itemIterator, $this->itemIteratorTotal, $this->popIndex, $this->upIndex,
  79
+			$this->currentIndex) = end($this->itemStack);
64 80
 	}
65 81
 
66 82
 	public function getObj($name, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) {

0 notes on commit ae3e3f3

Please sign in to comment.
Something went wrong with that request. Please try again.