Yaffs site version 1.1
[yaffs-website] / vendor / twig / twig / test / Twig / Tests / ExpressionParserTest.php
1 <?php
2
3 /*
4  * This file is part of Twig.
5  *
6  * (c) Fabien Potencier
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
13 {
14     /**
15      * @expectedException Twig_Error_Syntax
16      * @dataProvider getFailingTestsForAssignment
17      */
18     public function testCanOnlyAssignToNames($template)
19     {
20         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
21         $parser = new Twig_Parser($env);
22
23         $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
24     }
25
26     public function getFailingTestsForAssignment()
27     {
28         return array(
29             array('{% set false = "foo" %}'),
30             array('{% set FALSE = "foo" %}'),
31             array('{% set true = "foo" %}'),
32             array('{% set TRUE = "foo" %}'),
33             array('{% set none = "foo" %}'),
34             array('{% set NONE = "foo" %}'),
35             array('{% set null = "foo" %}'),
36             array('{% set NULL = "foo" %}'),
37             array('{% set 3 = "foo" %}'),
38             array('{% set 1 + 2 = "foo" %}'),
39             array('{% set "bar" = "foo" %}'),
40             array('{% set %}{% endset %}'),
41         );
42     }
43
44     /**
45      * @dataProvider getTestsForArray
46      */
47     public function testArrayExpression($template, $expected)
48     {
49         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
50         $stream = $env->tokenize(new Twig_Source($template, ''));
51         $parser = new Twig_Parser($env);
52
53         $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
54     }
55
56     /**
57      * @expectedException Twig_Error_Syntax
58      * @dataProvider getFailingTestsForArray
59      */
60     public function testArraySyntaxError($template)
61     {
62         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
63         $parser = new Twig_Parser($env);
64
65         $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
66     }
67
68     public function getFailingTestsForArray()
69     {
70         return array(
71             array('{{ [1, "a": "b"] }}'),
72             array('{{ {"a": "b", 2} }}'),
73         );
74     }
75
76     public function getTestsForArray()
77     {
78         return array(
79             // simple array
80             array('{{ [1, 2] }}', new Twig_Node_Expression_Array(array(
81                   new Twig_Node_Expression_Constant(0, 1),
82                   new Twig_Node_Expression_Constant(1, 1),
83
84                   new Twig_Node_Expression_Constant(1, 1),
85                   new Twig_Node_Expression_Constant(2, 1),
86                 ), 1),
87             ),
88
89             // array with trailing ,
90             array('{{ [1, 2, ] }}', new Twig_Node_Expression_Array(array(
91                   new Twig_Node_Expression_Constant(0, 1),
92                   new Twig_Node_Expression_Constant(1, 1),
93
94                   new Twig_Node_Expression_Constant(1, 1),
95                   new Twig_Node_Expression_Constant(2, 1),
96                 ), 1),
97             ),
98
99             // simple hash
100             array('{{ {"a": "b", "b": "c"} }}', new Twig_Node_Expression_Array(array(
101                   new Twig_Node_Expression_Constant('a', 1),
102                   new Twig_Node_Expression_Constant('b', 1),
103
104                   new Twig_Node_Expression_Constant('b', 1),
105                   new Twig_Node_Expression_Constant('c', 1),
106                 ), 1),
107             ),
108
109             // hash with trailing ,
110             array('{{ {"a": "b", "b": "c", } }}', new Twig_Node_Expression_Array(array(
111                   new Twig_Node_Expression_Constant('a', 1),
112                   new Twig_Node_Expression_Constant('b', 1),
113
114                   new Twig_Node_Expression_Constant('b', 1),
115                   new Twig_Node_Expression_Constant('c', 1),
116                 ), 1),
117             ),
118
119             // hash in an array
120             array('{{ [1, {"a": "b", "b": "c"}] }}', new Twig_Node_Expression_Array(array(
121                   new Twig_Node_Expression_Constant(0, 1),
122                   new Twig_Node_Expression_Constant(1, 1),
123
124                   new Twig_Node_Expression_Constant(1, 1),
125                   new Twig_Node_Expression_Array(array(
126                         new Twig_Node_Expression_Constant('a', 1),
127                         new Twig_Node_Expression_Constant('b', 1),
128
129                         new Twig_Node_Expression_Constant('b', 1),
130                         new Twig_Node_Expression_Constant('c', 1),
131                       ), 1),
132                 ), 1),
133             ),
134
135             // array in a hash
136             array('{{ {"a": [1, 2], "b": "c"} }}', new Twig_Node_Expression_Array(array(
137                   new Twig_Node_Expression_Constant('a', 1),
138                   new Twig_Node_Expression_Array(array(
139                         new Twig_Node_Expression_Constant(0, 1),
140                         new Twig_Node_Expression_Constant(1, 1),
141
142                         new Twig_Node_Expression_Constant(1, 1),
143                         new Twig_Node_Expression_Constant(2, 1),
144                       ), 1),
145                   new Twig_Node_Expression_Constant('b', 1),
146                   new Twig_Node_Expression_Constant('c', 1),
147                 ), 1),
148             ),
149         );
150     }
151
152     /**
153      * @expectedException Twig_Error_Syntax
154      */
155     public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
156     {
157         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
158         $stream = $env->tokenize(new Twig_Source('{{ "a" "b" }}', 'index'));
159         $parser = new Twig_Parser($env);
160
161         $parser->parse($stream);
162     }
163
164     /**
165      * @dataProvider getTestsForString
166      */
167     public function testStringExpression($template, $expected)
168     {
169         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
170         $stream = $env->tokenize(new Twig_Source($template, ''));
171         $parser = new Twig_Parser($env);
172
173         $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
174     }
175
176     public function getTestsForString()
177     {
178         return array(
179             array(
180                 '{{ "foo" }}', new Twig_Node_Expression_Constant('foo', 1),
181             ),
182             array(
183                 '{{ "foo #{bar}" }}', new Twig_Node_Expression_Binary_Concat(
184                     new Twig_Node_Expression_Constant('foo ', 1),
185                     new Twig_Node_Expression_Name('bar', 1),
186                     1
187                 ),
188             ),
189             array(
190                 '{{ "foo #{bar} baz" }}', new Twig_Node_Expression_Binary_Concat(
191                     new Twig_Node_Expression_Binary_Concat(
192                         new Twig_Node_Expression_Constant('foo ', 1),
193                         new Twig_Node_Expression_Name('bar', 1),
194                         1
195                     ),
196                     new Twig_Node_Expression_Constant(' baz', 1),
197                     1
198                 ),
199             ),
200
201             array(
202                 '{{ "foo #{"foo #{bar} baz"} baz" }}', new Twig_Node_Expression_Binary_Concat(
203                     new Twig_Node_Expression_Binary_Concat(
204                         new Twig_Node_Expression_Constant('foo ', 1),
205                         new Twig_Node_Expression_Binary_Concat(
206                             new Twig_Node_Expression_Binary_Concat(
207                                 new Twig_Node_Expression_Constant('foo ', 1),
208                                 new Twig_Node_Expression_Name('bar', 1),
209                                 1
210                             ),
211                             new Twig_Node_Expression_Constant(' baz', 1),
212                             1
213                         ),
214                         1
215                     ),
216                     new Twig_Node_Expression_Constant(' baz', 1),
217                     1
218                 ),
219             ),
220         );
221     }
222
223     /**
224      * @expectedException Twig_Error_Syntax
225      */
226     public function testAttributeCallDoesNotSupportNamedArguments()
227     {
228         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
229         $parser = new Twig_Parser($env);
230
231         $parser->parse($env->tokenize(new Twig_Source('{{ foo.bar(name="Foo") }}', 'index')));
232     }
233
234     /**
235      * @expectedException Twig_Error_Syntax
236      */
237     public function testMacroCallDoesNotSupportNamedArguments()
238     {
239         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
240         $parser = new Twig_Parser($env);
241
242         $parser->parse($env->tokenize(new Twig_Source('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index')));
243     }
244
245     /**
246      * @expectedException        Twig_Error_Syntax
247      * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1.
248      */
249     public function testMacroDefinitionDoesNotSupportNonNameVariableName()
250     {
251         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
252         $parser = new Twig_Parser($env);
253
254         $parser->parse($env->tokenize(new Twig_Source('{% macro foo("a") %}{% endmacro %}', 'index')));
255     }
256
257     /**
258      * @expectedException        Twig_Error_Syntax
259      * @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
260      * @dataProvider             getMacroDefinitionDoesNotSupportNonConstantDefaultValues
261      */
262     public function testMacroDefinitionDoesNotSupportNonConstantDefaultValues($template)
263     {
264         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
265         $parser = new Twig_Parser($env);
266
267         $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
268     }
269
270     public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
271     {
272         return array(
273             array('{% macro foo(name = "a #{foo} a") %}{% endmacro %}'),
274             array('{% macro foo(name = [["b", "a #{foo} a"]]) %}{% endmacro %}'),
275         );
276     }
277
278     /**
279      * @dataProvider getMacroDefinitionSupportsConstantDefaultValues
280      */
281     public function testMacroDefinitionSupportsConstantDefaultValues($template)
282     {
283         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
284         $parser = new Twig_Parser($env);
285
286         $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
287
288         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
289         // can be executed without throwing any exceptions
290         $this->addToAssertionCount(1);
291     }
292
293     public function getMacroDefinitionSupportsConstantDefaultValues()
294     {
295         return array(
296             array('{% macro foo(name = "aa") %}{% endmacro %}'),
297             array('{% macro foo(name = 12) %}{% endmacro %}'),
298             array('{% macro foo(name = true) %}{% endmacro %}'),
299             array('{% macro foo(name = ["a"]) %}{% endmacro %}'),
300             array('{% macro foo(name = [["a"]]) %}{% endmacro %}'),
301             array('{% macro foo(name = {a: "a"}) %}{% endmacro %}'),
302             array('{% macro foo(name = {a: {b: "a"}}) %}{% endmacro %}'),
303         );
304     }
305
306     /**
307      * @expectedException        Twig_Error_Syntax
308      * @expectedExceptionMessage Unknown "cycl" function. Did you mean "cycle" in "index" at line 1?
309      */
310     public function testUnknownFunction()
311     {
312         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
313         $parser = new Twig_Parser($env);
314
315         $parser->parse($env->tokenize(new Twig_Source('{{ cycl() }}', 'index')));
316     }
317
318     /**
319      * @expectedException        Twig_Error_Syntax
320      * @expectedExceptionMessage Unknown "foobar" function in "index" at line 1.
321      */
322     public function testUnknownFunctionWithoutSuggestions()
323     {
324         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
325         $parser = new Twig_Parser($env);
326
327         $parser->parse($env->tokenize(new Twig_Source('{{ foobar() }}', 'index')));
328     }
329
330     /**
331      * @expectedException        Twig_Error_Syntax
332      * @expectedExceptionMessage Unknown "lowe" filter. Did you mean "lower" in "index" at line 1?
333      */
334     public function testUnknownFilter()
335     {
336         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
337         $parser = new Twig_Parser($env);
338
339         $parser->parse($env->tokenize(new Twig_Source('{{ 1|lowe }}', 'index')));
340     }
341
342     /**
343      * @expectedException        Twig_Error_Syntax
344      * @expectedExceptionMessage Unknown "foobar" filter in "index" at line 1.
345      */
346     public function testUnknownFilterWithoutSuggestions()
347     {
348         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
349         $parser = new Twig_Parser($env);
350
351         $parser->parse($env->tokenize(new Twig_Source('{{ 1|foobar }}', 'index')));
352     }
353
354     /**
355      * @expectedException        Twig_Error_Syntax
356      * @expectedExceptionMessage Unknown "nul" test. Did you mean "null" in "index" at line 1
357      */
358     public function testUnknownTest()
359     {
360         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
361         $parser = new Twig_Parser($env);
362         $stream = $env->tokenize(new Twig_Source('{{ 1 is nul }}', 'index'));
363         $parser->parse($stream);
364     }
365
366     /**
367      * @expectedException        Twig_Error_Syntax
368      * @expectedExceptionMessage Unknown "foobar" test in "index" at line 1.
369      */
370     public function testUnknownTestWithoutSuggestions()
371     {
372         $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
373         $parser = new Twig_Parser($env);
374
375         $parser->parse($env->tokenize(new Twig_Source('{{ 1 is foobar }}', 'index')));
376     }
377 }