4 * This file is part of Twig.
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 class Twig_Tests_ExpressionParserTest
extends PHPUnit_Framework_TestCase
15 * @expectedException Twig_Error_Syntax
16 * @dataProvider getFailingTestsForAssignment
18 public function testCanOnlyAssignToNames($template)
20 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
21 $parser = new Twig_Parser($env);
23 $parser->parse($env->tokenize($template, 'index'));
26 public function getFailingTestsForAssignment()
29 array('{% set false = "foo" %}'),
30 array('{% set true = "foo" %}'),
31 array('{% set none = "foo" %}'),
32 array('{% set 3 = "foo" %}'),
33 array('{% set 1 + 2 = "foo" %}'),
34 array('{% set "bar" = "foo" %}'),
35 array('{% set %}{% endset %}')
40 * @dataProvider getTestsForArray
42 public function testArrayExpression($template, $expected)
44 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
45 $stream = $env->tokenize($template, 'index');
46 $parser = new Twig_Parser($env);
48 $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
52 * @expectedException Twig_Error_Syntax
53 * @dataProvider getFailingTestsForArray
55 public function testArraySyntaxError($template)
57 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
58 $parser = new Twig_Parser($env);
60 $parser->parse($env->tokenize($template, 'index'));
63 public function getFailingTestsForArray()
66 array('{{ [1, "a": "b"] }}'),
67 array('{{ {"a": "b", 2} }}'),
71 public function getTestsForArray()
75 array('{{ [1, 2] }}', new Twig_Node_Expression_Array(array(
76 new Twig_Node_Expression_Constant(0, 1),
77 new Twig_Node_Expression_Constant(1, 1),
79 new Twig_Node_Expression_Constant(1, 1),
80 new Twig_Node_Expression_Constant(2, 1),
84 // array with trailing ,
85 array('{{ [1, 2, ] }}', new Twig_Node_Expression_Array(array(
86 new Twig_Node_Expression_Constant(0, 1),
87 new Twig_Node_Expression_Constant(1, 1),
89 new Twig_Node_Expression_Constant(1, 1),
90 new Twig_Node_Expression_Constant(2, 1),
95 array('{{ {"a": "b", "b": "c"} }}', new Twig_Node_Expression_Array(array(
96 new Twig_Node_Expression_Constant('a', 1),
97 new Twig_Node_Expression_Constant('b', 1),
99 new Twig_Node_Expression_Constant('b', 1),
100 new Twig_Node_Expression_Constant('c', 1),
104 // hash with trailing ,
105 array('{{ {"a": "b", "b": "c", } }}', new Twig_Node_Expression_Array(array(
106 new Twig_Node_Expression_Constant('a', 1),
107 new Twig_Node_Expression_Constant('b', 1),
109 new Twig_Node_Expression_Constant('b', 1),
110 new Twig_Node_Expression_Constant('c', 1),
115 array('{{ [1, {"a": "b", "b": "c"}] }}', new Twig_Node_Expression_Array(array(
116 new Twig_Node_Expression_Constant(0, 1),
117 new Twig_Node_Expression_Constant(1, 1),
119 new Twig_Node_Expression_Constant(1, 1),
120 new Twig_Node_Expression_Array(array(
121 new Twig_Node_Expression_Constant('a', 1),
122 new Twig_Node_Expression_Constant('b', 1),
124 new Twig_Node_Expression_Constant('b', 1),
125 new Twig_Node_Expression_Constant('c', 1),
131 array('{{ {"a": [1, 2], "b": "c"} }}', new Twig_Node_Expression_Array(array(
132 new Twig_Node_Expression_Constant('a', 1),
133 new Twig_Node_Expression_Array(array(
134 new Twig_Node_Expression_Constant(0, 1),
135 new Twig_Node_Expression_Constant(1, 1),
137 new Twig_Node_Expression_Constant(1, 1),
138 new Twig_Node_Expression_Constant(2, 1),
140 new Twig_Node_Expression_Constant('b', 1),
141 new Twig_Node_Expression_Constant('c', 1),
148 * @expectedException Twig_Error_Syntax
150 public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
152 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
153 $stream = $env->tokenize('{{ "a" "b" }}', 'index');
154 $parser = new Twig_Parser($env);
156 $parser->parse($stream);
160 * @dataProvider getTestsForString
162 public function testStringExpression($template, $expected)
164 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
165 $stream = $env->tokenize($template, 'index');
166 $parser = new Twig_Parser($env);
168 $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
171 public function getTestsForString()
175 '{{ "foo" }}', new Twig_Node_Expression_Constant('foo', 1),
178 '{{ "foo #{bar}" }}', new Twig_Node_Expression_Binary_Concat(
179 new Twig_Node_Expression_Constant('foo ', 1),
180 new Twig_Node_Expression_Name('bar', 1),
185 '{{ "foo #{bar} baz" }}', new Twig_Node_Expression_Binary_Concat(
186 new Twig_Node_Expression_Binary_Concat(
187 new Twig_Node_Expression_Constant('foo ', 1),
188 new Twig_Node_Expression_Name('bar', 1),
191 new Twig_Node_Expression_Constant(' baz', 1),
197 '{{ "foo #{"foo #{bar} baz"} baz" }}', new Twig_Node_Expression_Binary_Concat(
198 new Twig_Node_Expression_Binary_Concat(
199 new Twig_Node_Expression_Constant('foo ', 1),
200 new Twig_Node_Expression_Binary_Concat(
201 new Twig_Node_Expression_Binary_Concat(
202 new Twig_Node_Expression_Constant('foo ', 1),
203 new Twig_Node_Expression_Name('bar', 1),
206 new Twig_Node_Expression_Constant(' baz', 1),
211 new Twig_Node_Expression_Constant(' baz', 1),
219 * @expectedException Twig_Error_Syntax
221 public function testAttributeCallDoesNotSupportNamedArguments()
223 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
224 $parser = new Twig_Parser($env);
226 $parser->parse($env->tokenize('{{ foo.bar(name="Foo") }}', 'index'));
230 * @expectedException Twig_Error_Syntax
232 public function testMacroCallDoesNotSupportNamedArguments()
234 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
235 $parser = new Twig_Parser($env);
237 $parser->parse($env->tokenize('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index'));
241 * @expectedException Twig_Error_Syntax
242 * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1
244 public function testMacroDefinitionDoesNotSupportNonNameVariableName()
246 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
247 $parser = new Twig_Parser($env);
249 $parser->parse($env->tokenize('{% macro foo("a") %}{% endmacro %}', 'index'));
253 * @expectedException Twig_Error_Syntax
254 * @expectedExceptionMessage A default value for an argument must be a constant (a boolean, a string, a number, or an array) in "index" at line 1
255 * @dataProvider getMacroDefinitionDoesNotSupportNonConstantDefaultValues
257 public function testMacroDefinitionDoesNotSupportNonConstantDefaultValues($template)
259 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
260 $parser = new Twig_Parser($env);
262 $parser->parse($env->tokenize($template, 'index'));
265 public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
268 array('{% macro foo(name = "a #{foo} a") %}{% endmacro %}'),
269 array('{% macro foo(name = [["b", "a #{foo} a"]]) %}{% endmacro %}'),
274 * @dataProvider getMacroDefinitionSupportsConstantDefaultValues
276 public function testMacroDefinitionSupportsConstantDefaultValues($template)
278 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
279 $parser = new Twig_Parser($env);
281 $parser->parse($env->tokenize($template, 'index'));
284 public function getMacroDefinitionSupportsConstantDefaultValues()
287 array('{% macro foo(name = "aa") %}{% endmacro %}'),
288 array('{% macro foo(name = 12) %}{% endmacro %}'),
289 array('{% macro foo(name = true) %}{% endmacro %}'),
290 array('{% macro foo(name = ["a"]) %}{% endmacro %}'),
291 array('{% macro foo(name = [["a"]]) %}{% endmacro %}'),
292 array('{% macro foo(name = {a: "a"}) %}{% endmacro %}'),
293 array('{% macro foo(name = {a: {b: "a"}}) %}{% endmacro %}'),
298 * @expectedException Twig_Error_Syntax
299 * @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" in "index" at line 1
301 public function testUnknownFunction()
303 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
304 $parser = new Twig_Parser($env);
306 $parser->parse($env->tokenize('{{ cycl() }}', 'index'));
310 * @expectedException Twig_Error_Syntax
311 * @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" in "index" at line 1
313 public function testUnknownFilter()
315 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
316 $parser = new Twig_Parser($env);
318 $parser->parse($env->tokenize('{{ 1|lowe }}', 'index'));
322 * @expectedException Twig_Error_Syntax
323 * @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" in "index" at line 1
325 public function testUnknownTest()
327 $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
328 $parser = new Twig_Parser($env);
330 $parser->parse($env->tokenize('{{ 1 is nul }}', 'index'));