Ver código fonte

Fix ArrayAccess priority:

 * Methods brump properties and ArrayAccess
 * Properties beat ArrayAccess
 * ArrayAccess beats nothing at all
 * ArrayAccess also beats private properties

Add a test case to verify.

See #178
Justin Hileman 12 anos atrás
pai
commit
38b6b245b1
2 arquivos alterados com 60 adições e 11 exclusões
  1. 7 11
      src/Mustache/Context.php
  2. 53 0
      test/Mustache/Test/ContextTest.php

+ 7 - 11
src/Mustache/Context.php

@@ -133,17 +133,13 @@ class Mustache_Context
     private function findVariableInStack($id, array $stack)
     {
         for ($i = count($stack) - 1; $i >= 0; $i--) {
-            if (is_object($stack[$i])) {
-                if ($stack[$i] instanceof ArrayAccess) {
-                    if (isset($stack[$i][$id])) {
-                        return $stack[$i][$id];
-                    }
-                } elseif (!($stack[$i] instanceof Closure)) {
-                    if (method_exists($stack[$i], $id)) {
-                        return $stack[$i]->$id();
-                    } elseif (isset($stack[$i]->$id)) {
-                        return $stack[$i]->$id;
-                    }
+            if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
+                if (method_exists($stack[$i], $id)) {
+                    return $stack[$i]->$id();
+                } elseif (isset($stack[$i]->$id)) {
+                    return $stack[$i]->$id;
+                } elseif ($stack[$i] instanceof ArrayAccess && isset($stack[$i][$id])) {
+                    return $stack[$i][$id];
                 }
             } elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
                 return $stack[$i][$id];

+ 53 - 0
test/Mustache/Test/ContextTest.php

@@ -109,6 +109,16 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('see', $context->findDot('a.b.c'));
         $this->assertEquals(null, $context->findDot('a.b.c.d'));
     }
+
+    public function testAccessorPriority()
+    {
+        $context = new Mustache_Context(new Mustache_Test_AllTheThings);
+
+        $this->assertEquals('win', $context->find('foo'), 'method beats property');
+        $this->assertEquals('win', $context->find('bar'), 'property beats ArrayAccess');
+        $this->assertEquals('win', $context->find('baz'), 'ArrayAccess stands alone');
+        $this->assertEquals('win', $context->find('qux'), 'ArrayAccess beats private property');
+    }
 }
 
 class Mustache_Test_TestDummy
@@ -166,3 +176,46 @@ class Mustache_Test_TestArrayAccess implements ArrayAccess
         return isset($this->container[$offset]) ? $this->container[$offset] : null;
     }
 }
+
+class Mustache_Test_AllTheThings implements ArrayAccess
+{
+    public $foo  = 'fail';
+    public $bar  = 'win';
+    private $qux = 'fail';
+
+    public function foo()
+    {
+        return 'win';
+    }
+
+    public function offsetExists($offset)
+    {
+        return true;
+    }
+
+    public function offsetGet($offset)
+    {
+        switch ($offset) {
+            case 'foo':
+            case 'bar':
+                return 'fail';
+
+            case 'baz':
+            case 'qux':
+                return 'win';
+
+            default:
+                return 'lolwhut';
+        }
+    }
+
+    public function offsetSet($offset, $value)
+    {
+        // nada
+    }
+
+    public function offsetUnset($offset)
+    {
+        // nada
+    }
+}