diff --git a/src/Mustache/Context.php b/src/Mustache/Context.php
index 6a2d57c..e7783b4 100644
--- a/src/Mustache/Context.php
+++ b/src/Mustache/Context.php
@@ -133,7 +133,7 @@ class Mustache_Context
private function findVariableInStack($id, array $stack)
{
for ($i = count($stack) - 1; $i >= 0; $i--) {
- if (is_object($stack[$i])) {
+ if (is_object($stack[$i]) && !$stack[$i] instanceof Closure) {
if (method_exists($stack[$i], $id)) {
return $stack[$i]->$id();
} elseif (isset($stack[$i]->$id)) {
diff --git a/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php b/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php
new file mode 100644
index 0000000..9f9f548
--- /dev/null
+++ b/test/Mustache/Test/FiveThree/Functional/ClosureQuirksTest.php
@@ -0,0 +1,30 @@
+mustache = new Mustache_Engine;
+ }
+
+ public function testClosuresDontLikeItWhenYouTouchTheirProperties()
+ {
+ $tpl = $this->mustache->loadTemplate('{{ foo.bar }}');
+ $this->assertEquals('', $tpl->render(array('foo' => function() { return 'FOO'; })));
+ }
+}
diff --git a/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php b/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php
index 8453c93..9862d06 100644
--- a/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php
+++ b/test/Mustache/Test/FiveThree/Functional/HigherOrderSectionsTest.php
@@ -15,57 +15,57 @@
*/
class Mustache_Test_FiveThree_Functional_HigherOrderSectionsTest extends PHPUnit_Framework_TestCase {
- private $mustache;
+ private $mustache;
- public function setUp() {
- $this->mustache = new Mustache_Engine;
- }
+ public function setUp() {
+ $this->mustache = new Mustache_Engine;
+ }
- public function testAnonymousFunctionSectionCallback() {
- $tpl = $this->mustache->loadTemplate('{{#wrapper}}{{name}}{{/wrapper}}');
+ public function testAnonymousFunctionSectionCallback() {
+ $tpl = $this->mustache->loadTemplate('{{#wrapper}}{{name}}{{/wrapper}}');
- $foo = new Mustache_Test_FiveThree_Functional_Foo;
- $foo->name = 'Mario';
- $foo->wrapper = function($text) {
- return sprintf('
%s
', $text);
- };
+ $foo = new Mustache_Test_FiveThree_Functional_Foo;
+ $foo->name = 'Mario';
+ $foo->wrapper = function($text) {
+ return sprintf('%s
', $text);
+ };
- $this->assertEquals(sprintf('%s
', $foo->name), $tpl->render($foo));
- }
+ $this->assertEquals(sprintf('%s
', $foo->name), $tpl->render($foo));
+ }
- public function testSectionCallback() {
- $one = $this->mustache->loadTemplate('{{name}}');
- $two = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+ public function testSectionCallback() {
+ $one = $this->mustache->loadTemplate('{{name}}');
+ $two = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
- $foo = new Mustache_Test_FiveThree_Functional_Foo;
- $foo->name = 'Luigi';
+ $foo = new Mustache_Test_FiveThree_Functional_Foo;
+ $foo->name = 'Luigi';
- $this->assertEquals($foo->name, $one->render($foo));
- $this->assertEquals(sprintf('%s', $foo->name), $two->render($foo));
- }
+ $this->assertEquals($foo->name, $one->render($foo));
+ $this->assertEquals(sprintf('%s', $foo->name), $two->render($foo));
+ }
- public function testViewArrayAnonymousSectionCallback() {
- $tpl = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
+ public function testViewArrayAnonymousSectionCallback() {
+ $tpl = $this->mustache->loadTemplate('{{#wrap}}{{name}}{{/wrap}}');
- $data = array(
- 'name' => 'Bob',
- 'wrap' => function($text) {
- return sprintf('[[%s]]', $text);
- }
- );
+ $data = array(
+ 'name' => 'Bob',
+ 'wrap' => function($text) {
+ return sprintf('[[%s]]', $text);
+ }
+ );
- $this->assertEquals(sprintf('[[%s]]', $data['name']), $tpl->render($data));
- }
+ $this->assertEquals(sprintf('[[%s]]', $data['name']), $tpl->render($data));
+ }
}
class Mustache_Test_FiveThree_Functional_Foo {
- public $name = 'Justin';
- public $lorem = 'Lorem ipsum dolor sit amet,';
- public $wrap;
+ public $name = 'Justin';
+ public $lorem = 'Lorem ipsum dolor sit amet,';
+ public $wrap;
- public function __construct() {
- $this->wrap = function($text) {
- return sprintf('%s', $text);
- };
- }
+ public function __construct() {
+ $this->wrap = function($text) {
+ return sprintf('%s', $text);
+ };
+ }
}
diff --git a/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php b/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php
index cf26ae1..86b8795 100644
--- a/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php
+++ b/test/Mustache/Test/FiveThree/Functional/MustacheSpecTest.php
@@ -17,98 +17,98 @@
*/
class Mustache_Test_FiveThree_Functional_MustacheSpecTest extends PHPUnit_Framework_TestCase {
- private static $mustache;
+ private static $mustache;
- public static function setUpBeforeClass() {
- self::$mustache = new Mustache_Engine;
- }
+ public static function setUpBeforeClass() {
+ self::$mustache = new Mustache_Engine;
+ }
- /**
- * For some reason data providers can't mark tests skipped, so this test exists
- * simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
- */
- public function testSpecInitialized() {
- if (!file_exists(dirname(__FILE__).'/../../../../../vendor/spec/specs/')) {
- $this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
- }
- }
+ /**
+ * For some reason data providers can't mark tests skipped, so this test exists
+ * simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
+ */
+ public function testSpecInitialized() {
+ if (!file_exists(dirname(__FILE__).'/../../../../../vendor/spec/specs/')) {
+ $this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
+ }
+ }
- /**
- * @group lambdas
- * @dataProvider loadLambdasSpec
- */
- public function testLambdasSpec($desc, $source, $partials, $data, $expected) {
- $template = self::loadTemplate($source, $partials);
- $this->assertEquals($expected, $template($this->prepareLambdasSpec($data)), $desc);
- }
+ /**
+ * @group lambdas
+ * @dataProvider loadLambdasSpec
+ */
+ public function testLambdasSpec($desc, $source, $partials, $data, $expected) {
+ $template = self::loadTemplate($source, $partials);
+ $this->assertEquals($expected, $template($this->prepareLambdasSpec($data)), $desc);
+ }
- public function loadLambdasSpec() {
- return $this->loadSpec('~lambdas');
- }
+ public function loadLambdasSpec() {
+ return $this->loadSpec('~lambdas');
+ }
- /**
- * Extract and lambdafy any 'lambda' values found in the $data array.
- */
- private function prepareLambdasSpec($data) {
- foreach ($data as $key => $val) {
- if ($key === 'lambda') {
- if (!isset($val['php'])) {
- $this->markTestSkipped(sprintf('PHP lambda test not implemented for this test.'));
- }
+ /**
+ * Extract and lambdafy any 'lambda' values found in the $data array.
+ */
+ private function prepareLambdasSpec($data) {
+ foreach ($data as $key => $val) {
+ if ($key === 'lambda') {
+ if (!isset($val['php'])) {
+ $this->markTestSkipped(sprintf('PHP lambda test not implemented for this test.'));
+ }
- $func = $val['php'];
- $data[$key] = function($text = null) use ($func) {
- return eval($func);
- };
- } else if (is_array($val)) {
- $data[$key] = $this->prepareLambdasSpec($val);
- }
- }
+ $func = $val['php'];
+ $data[$key] = function($text = null) use ($func) {
+ return eval($func);
+ };
+ } elseif (is_array($val)) {
+ $data[$key] = $this->prepareLambdasSpec($val);
+ }
+ }
- return $data;
- }
+ return $data;
+ }
- /**
- * Data provider for the mustache spec test.
- *
- * Loads YAML files from the spec and converts them to PHPisms.
- *
- * @access public
- * @return array
- */
- private function loadSpec($name) {
- $filename = dirname(__FILE__) . '/../../../../../vendor/spec/specs/' . $name . '.yml';
- if (!file_exists($filename)) {
- return array();
- }
+ /**
+ * Data provider for the mustache spec test.
+ *
+ * Loads YAML files from the spec and converts them to PHPisms.
+ *
+ * @access public
+ * @return array
+ */
+ private function loadSpec($name) {
+ $filename = dirname(__FILE__) . '/../../../../../vendor/spec/specs/' . $name . '.yml';
+ if (!file_exists($filename)) {
+ return array();
+ }
- $data = array();
- $yaml = new sfYamlParser;
- $file = file_get_contents($filename);
+ $data = array();
+ $yaml = new sfYamlParser;
+ $file = file_get_contents($filename);
- // @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
- if ($name === '~lambdas') {
- $file = str_replace(" !code\n", "\n", $file);
- }
+ // @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
+ if ($name === '~lambdas') {
+ $file = str_replace(" !code\n", "\n", $file);
+ }
- $spec = $yaml->parse($file);
+ $spec = $yaml->parse($file);
- foreach ($spec['tests'] as $test) {
- $data[] = array(
- $test['name'] . ': ' . $test['desc'],
- $test['template'],
- isset($test['partials']) ? $test['partials'] : array(),
- $test['data'],
- $test['expected'],
- );
- }
+ foreach ($spec['tests'] as $test) {
+ $data[] = array(
+ $test['name'] . ': ' . $test['desc'],
+ $test['template'],
+ isset($test['partials']) ? $test['partials'] : array(),
+ $test['data'],
+ $test['expected'],
+ );
+ }
- return $data;
- }
+ return $data;
+ }
- private static function loadTemplate($source, $partials) {
- self::$mustache->setPartials($partials);
+ private static function loadTemplate($source, $partials) {
+ self::$mustache->setPartials($partials);
- return self::$mustache->loadTemplate($source);
- }
+ return self::$mustache->loadTemplate($source);
+ }
}
diff --git a/test/fixtures/examples/partials/Partials.php b/test/fixtures/examples/partials/Partials.php
index f15d6b2..cfa110c 100644
--- a/test/fixtures/examples/partials/Partials.php
+++ b/test/fixtures/examples/partials/Partials.php
@@ -1,9 +1,9 @@
'Page Title',
- 'subtitle' => 'Page Subtitle',
- 'content' => 'Lorem ipsum dolor sit amet.',
- );
+ public $page = array(
+ 'title' => 'Page Title',
+ 'subtitle' => 'Page Subtitle',
+ 'content' => 'Lorem ipsum dolor sit amet.',
+ );
}