Fixed the support of 2-word tests without a custom node class
authorChristophe Coevoet <stof@notk.org>
Tue, 14 Oct 2014 09:53:43 +0000 (11:53 +0200)
committerChristophe Coevoet <stof@notk.org>
Tue, 14 Oct 2014 10:50:18 +0000 (12:50 +0200)
CHANGELOG
lib/Twig/Extension/Core.php
test/Twig/Tests/Fixtures/regression/multi_word_tests.test [new file with mode: 0644]
test/Twig/Tests/IntegrationTest.php

index 9d136c1..01a6a60 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.16.2 (2014-XX-XX)
 
+ * fixed 2-words test names when a custom node class is not used
  * fixed macros when using an argument named like a PHP super global (like GET or POST)
  * fixed date_modify when working with DateTimeImmutable
  * optimized for loops
index 99d0fe3..a30527d 100644 (file)
@@ -298,8 +298,8 @@ class Twig_Extension_Core extends Twig_Extension
     public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
     {
         $stream = $parser->getStream();
-        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
-        $class = $this->getTestNodeClass($parser, $name, $node->getLine());
+        $name = $this->getTestName($parser, $node->getLine());
+        $class = $this->getTestNodeClass($parser, $name);
         $arguments = null;
         if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
             $arguments = $parser->getExpressionParser()->parseArguments(true);
@@ -308,33 +308,41 @@ class Twig_Extension_Core extends Twig_Extension
         return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
     }
 
-    protected function getTestNodeClass(Twig_Parser $parser, $name, $line)
+    protected function getTestName(Twig_Parser $parser, $line)
     {
+        $stream = $parser->getStream();
+        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
         $env = $parser->getEnvironment();
         $testMap = $env->getTests();
-        $testName = null;
+
         if (isset($testMap[$name])) {
-            $testName = $name;
-        } elseif ($parser->getStream()->test(Twig_Token::NAME_TYPE)) {
+            return $name;
+        }
+
+        if ($stream->test(Twig_Token::NAME_TYPE)) {
             // try 2-words tests
             $name = $name.' '.$parser->getCurrentToken()->getValue();
 
             if (isset($testMap[$name])) {
                 $parser->getStream()->next();
 
-                $testName = $name;
+                return $name;
             }
         }
 
-        if (null === $testName) {
-            $message = sprintf('The test "%s" does not exist', $name);
-            if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
-                $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
-            }
-
-            throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
+        $message = sprintf('The test "%s" does not exist', $name);
+        if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) {
+            $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
         }
 
+        throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
+    }
+
+    protected function getTestNodeClass(Twig_Parser $parser, $name)
+    {
+        $env = $parser->getEnvironment();
+        $testMap = $env->getTests();
+
         if ($testMap[$name] instanceof Twig_SimpleTest) {
             return $testMap[$name]->getNodeClass();
         }
diff --git a/test/Twig/Tests/Fixtures/regression/multi_word_tests.test b/test/Twig/Tests/Fixtures/regression/multi_word_tests.test
new file mode 100644 (file)
index 0000000..269a305
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Twig allows multi-word tests without a custom node class
+--TEMPLATE--
+{{ 'foo' is multi word ? 'yes' : 'no' }}
+{{ 'foo bar' is multi word ? 'yes' : 'no' }}
+--DATA--
+return array()
+--EXPECT--
+no
+yes
index ea00b02..70f9b80 100644 (file)
@@ -157,6 +157,13 @@ class TwigTestExtension extends Twig_Extension
         );
     }
 
+    public function getTests()
+    {
+        return array(
+            new Twig_SimpleTest('multi word', array($this, 'is_multi_word')),
+        );
+    }
+
     public function §Filter($value)
     {
         return "§{$value}§";
@@ -210,6 +217,11 @@ class TwigTestExtension extends Twig_Extension
         return '<br />';
     }
 
+    public function is_multi_word($value)
+    {
+        return false !== strpos($value, ' ');
+    }
+
     public function getName()
     {
         return 'integration_test';