Skip to content

Commit

Permalink
FIX Arguments to method calls reseting scope
Browse files Browse the repository at this point in the history
  • Loading branch information
Hamish Friedlander committed Jun 25, 2013
1 parent 7349682 commit ae3e3f3
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
69 changes: 67 additions & 2 deletions tests/view/SSViewerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ public function testRenderWithSourceFileComments() {
$origEnv = Config::inst()->get('Director', 'environment_type');
Config::inst()->update('Director', 'environment_type', 'dev');
Config::inst()->update('SSViewer', 'source_file_comments', true);
$f = FRAMEWORK_PATH . '/tests/templates/SSViewerTestComments';
$f = FRAMEWORK_PATH . '/tests/templates/SSViewerTestComments';
$templates = array(
array(
'name' => 'SSViewerTestCommentsFullSource',
Expand All @@ -1090,7 +1090,8 @@ public function testRenderWithSourceFileComments() {
array(
'name' => 'SSViewerTestCommentsFullSourceHTML4Doctype',
'expected' => ""
. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"
. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML "
. "4.01//EN\"\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"
. "<!-- template $f/SSViewerTestCommentsFullSourceHTML4Doctype.ss -->"
. "<html>"
. "\t<head></head>"
Expand Down Expand Up @@ -1209,6 +1210,45 @@ public function testRequireCallInTemplateInclude() {
"tests/forms/RequirementsTest_a.js"
));
}

public function testCallsWithArguments() {
$data = new ArrayData(array(
'Set' => new ArrayList(array(
new SSViewerTest_Object("1"),
new SSViewerTest_Object("2"),
new SSViewerTest_Object("3"),
new SSViewerTest_Object("4"),
new SSViewerTest_Object("5"),
)),
'Level' => new SSViewerTest_LevelTest(1),
'Nest' => array(
'Level' => new SSViewerTest_LevelTest(2),
),
));

$tests = array(
'$Level.output(1)' => '1-1',
'$Nest.Level.output($Set.First.Number)' => '2-1',
'<% with $Set %>$Up.Level.output($First.Number)<% end_with %>' => '1-1',
'<% with $Set %>$Top.Nest.Level.output($First.Number)<% end_with %>' => '2-1',
'<% loop $Set %>$Up.Nest.Level.output($Number)<% end_loop %>' => '2-12-22-32-42-5',
'<% loop $Set %>$Top.Level.output($Number)<% end_loop %>' => '1-11-21-31-41-5',
'<% with $Nest %>$Level.output($Top.Set.First.Number)<% end_with %>' => '2-1',
'<% with $Level %>$output($Up.Set.Last.Number)<% end_with %>' => '1-5',
'<% with $Level.forWith($Set.Last.Number) %>$output("hi")<% end_with %>' => '5-hi',
'<% loop $Level.forLoop($Set.First.Number) %>$Number<% end_loop %>' => '!0',
'<% with $Nest %>
<% with $Level.forWith($Up.Set.First.Number) %>$output("hi")<% end_with %>
<% end_with %>' => '1-hi',
'<% with $Nest %>
<% loop $Level.forLoop($Top.Set.Last.Number) %>$Number<% end_loop %>
<% end_with %>' => '!0!1!2!3!4',
);

foreach($tests as $template => $expected) {
$this->assertEquals($expected, trim($this->render($template, $data)));
}
}
}

/**
Expand Down Expand Up @@ -1347,3 +1387,28 @@ public static function get_argmix() {
}

}

class SSViewerTest_LevelTest extends ViewableData implements TestOnly {
protected $depth;

public function __construct($depth = 1) {
$this->depth = $depth;
}

public function output($val) {
return "$this->depth-$val";
}

public function forLoop($number) {
$ret = array();
for($i = 0; $i < (int)$number; ++$i) {
$ret[] = new SSViewerTest_Object("!$i");
}
return new ArrayList($ret);
}

public function forWith($number) {
return new self($number);
}
}

2 changes: 1 addition & 1 deletion view/SSTemplateParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ function match_Lookup ($stack = array()) {


function Lookup__construct(&$res) {
$res['php'] = '$scope';
$res['php'] = '$scope->locally()';
$res['LookupSteps'] = array();
}

Expand Down
2 changes: 1 addition & 1 deletion view/SSTemplateParser.php.inc
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class SSTemplateParser extends Parser {
*/

function Lookup__construct(&$res) {
$res['php'] = '$scope';
$res['php'] = '$scope->locally()';
$res['LookupSteps'] = array();
}

Expand Down
24 changes: 20 additions & 4 deletions view/SSViewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,34 @@ class SSViewer_Scope {

public function __construct($item){
$this->item = $item;
$this->localIndex=0;
$this->localIndex = 0;
$this->localStack = array();
$this->itemStack[] = array($this->item, null, 0, null, null, 0);
}

public function getItem(){
return $this->itemIterator ? $this->itemIterator->current() : $this->item;
}

public function resetLocalScope(){

/** Called at the start of every lookup chain by SSTemplateParser to indicate a new lookup from local scope */
public function locally() {
list($this->item, $this->itemIterator, $this->itemIteratorTotal, $this->popIndex, $this->upIndex,
$this->currentIndex) = $this->itemStack[$this->localIndex];
array_splice($this->itemStack, $this->localIndex+1);

// Remember any un-completed (resetLocalScope hasn't been called) lookup chain. Even if there isn't an
// un-completed chain we need to store an empty item, as resetLocalScope doesn't know the difference later
$this->localStack[] = array_splice($this->itemStack, $this->localIndex+1);

return $this;
}

public function resetLocalScope(){
$previousLocalState = $this->localStack ? array_pop($this->localStack) : null;

array_splice($this->itemStack, $this->localIndex+1, count($this->itemStack), $previousLocalState);

list($this->item, $this->itemIterator, $this->itemIteratorTotal, $this->popIndex, $this->upIndex,
$this->currentIndex) = end($this->itemStack);
}

public function getObj($name, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) {
Expand Down

0 comments on commit ae3e3f3

Please sign in to comment.