changed name regex to allow more characters (the same as PHP - works for blocks,...
authorFabien Potencier <fabien.potencier@gmail.com>
Sun, 7 Aug 2011 08:07:35 +0000 (10:07 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Sun, 7 Aug 2011 08:07:35 +0000 (10:07 +0200)
CHANGELOG
lib/Twig/Lexer.php
test/Twig/Tests/Fixtures/filters/special_chars.test [new file with mode: 0644]
test/Twig/Tests/Fixtures/functions/special_chars.test [new file with mode: 0644]
test/Twig/Tests/Fixtures/tags/block/special_chars.test [new file with mode: 0644]
test/Twig/Tests/Fixtures/tags/macro/special_chars.test [new file with mode: 0644]
test/Twig/Tests/Fixtures/tags/special_chars.test [new file with mode: 0644]
test/Twig/Tests/LexerTest.php
test/Twig/Tests/integrationTest.php

index 401bd1f..742eb4b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.2.0
 
+ * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
  * removed the possibility to use the "extends" tag from a block
  * added "if" modifier support to "for" loops
 
index 5a2489a..868a814 100644 (file)
@@ -35,7 +35,7 @@ class Twig_Lexer implements Twig_LexerInterface
     const STATE_BLOCK = 1;
     const STATE_VAR   = 2;
 
-    const REGEX_NAME   = '/[A-Za-z_][A-Za-z0-9_]*/A';
+    const REGEX_NAME   = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
     const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
     const REGEX_STRING = '/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
     const PUNCTUATION  = '()[]{}?:.,|';
diff --git a/test/Twig/Tests/Fixtures/filters/special_chars.test b/test/Twig/Tests/Fixtures/filters/special_chars.test
new file mode 100644 (file)
index 0000000..cc91900
--- /dev/null
@@ -0,0 +1,8 @@
+--TEST--
+"☃" custom filter
+--TEMPLATE--
+{{ 'foo'|☃ }}
+--DATA--
+return array()
+--EXPECT--
+☃foo☃
diff --git a/test/Twig/Tests/Fixtures/functions/special_chars.test b/test/Twig/Tests/Fixtures/functions/special_chars.test
new file mode 100644 (file)
index 0000000..f602b0d
--- /dev/null
@@ -0,0 +1,8 @@
+--TEST--
+"☃" custom function
+--TEMPLATE--
+{{ ☃('foo') }}
+--DATA--
+return array()
+--EXPECT--
+☃foo☃
diff --git a/test/Twig/Tests/Fixtures/tags/block/special_chars.test b/test/Twig/Tests/Fixtures/tags/block/special_chars.test
new file mode 100644 (file)
index 0000000..441570c
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+"☃" special chars in a block name
+--TEMPLATE--
+{% block ☃ %}
+☃
+{% endblock ☃ %}
+--DATA--
+return array()
+--EXPECT--
+☃
diff --git a/test/Twig/Tests/Fixtures/tags/macro/special_chars.test b/test/Twig/Tests/Fixtures/tags/macro/special_chars.test
new file mode 100644 (file)
index 0000000..e61716e
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+"☃" as a macro name
+--TEMPLATE--
+{{ _self.☃('foo') }}
+
+{% macro ☃(foo) %}
+  ☃{{ foo }}☃
+{% endmacro %}
+--DATA--
+return array()
+--EXPECT--
+☃foo☃
diff --git a/test/Twig/Tests/Fixtures/tags/special_chars.test b/test/Twig/Tests/Fixtures/tags/special_chars.test
new file mode 100644 (file)
index 0000000..d584d9e
--- /dev/null
@@ -0,0 +1,8 @@
+--TEST--
+"☃" custom tag
+--TEMPLATE--
+{% ☃ %}
+--DATA--
+return array()
+--EXPECT--
+☃
index f3df09b..7594041 100644 (file)
  */
 class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
 {
+    public function testNameLabelForTag()
+    {
+        $template = '{% ☃ %}';
+
+        $lexer = new Twig_Lexer(new Twig_Environment());
+        $stream = $lexer->tokenize($template);
+
+        $stream->expect(Twig_Token::BLOCK_START_TYPE);
+        $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
+    }
+
+    public function testNameLabelForFunction()
+    {
+        $template = '{{ ☃() }}';
+
+        $lexer = new Twig_Lexer(new Twig_Environment());
+        $stream = $lexer->tokenize($template);
+
+        $stream->expect(Twig_Token::VAR_START_TYPE);
+        $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
+    }
+
     public function testBracketsNesting()
     {
         $template = '{{ {"a":{"b":"c"}} }}';
index 3c26cfa..ef682f6 100644 (file)
@@ -149,11 +149,34 @@ class Foo
     }
 }
 
+class TestTokenParser_☃ extends Twig_TokenParser
+{
+    public function parse(Twig_Token $token)
+    {
+        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+        return new Twig_Node_Print(new Twig_Node_Expression_Constant('☃', -1), -1);
+    }
+
+    public function getTag()
+    {
+        return '☃';
+    }
+}
+
 class TestExtension extends Twig_Extension
 {
+    public function getTokenParsers()
+    {
+        return array(
+            new TestTokenParser_☃(),
+        );
+    }
+
     public function getFilters()
     {
         return array(
+            '☃' => new Twig_Filter_Method($this, '☃Filter'),
             'escape_and_nl2br' => new Twig_Filter_Method($this, 'escape_and_nl2br', array('needs_environment' => true, 'is_safe' => array('html'))),
             'nl2br' => new Twig_Filter_Method($this, 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),
             'escape_something' => new Twig_Filter_Method($this, 'escape_something', array('is_safe' => array('something'))),
@@ -163,11 +186,22 @@ class TestExtension extends Twig_Extension
     public function getFunctions()
     {
         return array(
+            '☃' => new Twig_Function_Method($this, '☃Function'),
             'safe_br' => new Twig_Function_Method($this, 'br', array('is_safe' => array('html'))),
             'unsafe_br' => new Twig_Function_Method($this, 'br'),
         );
     }
 
+    public function ☃Filter($value)
+    {
+        return "☃{$value}☃";
+    }
+
+    public function ☃Function($value)
+    {
+        return "☃{$value}☃";
+    }
+
     /**
      * nl2br which also escapes, for testing escaper filters
      */