Security update for Core, with self-updated composer
[yaffs-website] / vendor / twig / twig / test / Twig / Tests / LexerTest.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 class Twig_Tests_LexerTest extends \PHPUnit\Framework\TestCase
12 {
13     /**
14      * @group legacy
15      */
16     public function testLegacyConstructorSignature()
17     {
18         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
19         $stream = $lexer->tokenize('{{ foo }}', 'foo');
20         $this->assertEquals('foo', $stream->getFilename());
21         $this->assertEquals('{{ foo }}', $stream->getSource());
22     }
23
24     public function testNameLabelForTag()
25     {
26         $template = '{% § %}';
27
28         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
29         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
30
31         $stream->expect(Twig_Token::BLOCK_START_TYPE);
32         $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
33     }
34
35     public function testNameLabelForFunction()
36     {
37         $template = '{{ §() }}';
38
39         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
40         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
41
42         $stream->expect(Twig_Token::VAR_START_TYPE);
43         $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
44     }
45
46     public function testBracketsNesting()
47     {
48         $template = '{{ {"a":{"b":"c"}} }}';
49
50         $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '{'));
51         $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '}'));
52     }
53
54     protected function countToken($template, $type, $value = null)
55     {
56         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
57         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
58
59         $count = 0;
60         while (!$stream->isEOF()) {
61             $token = $stream->next();
62             if ($type === $token->getType()) {
63                 if (null === $value || $value === $token->getValue()) {
64                     ++$count;
65                 }
66             }
67         }
68
69         return $count;
70     }
71
72     public function testLineDirective()
73     {
74         $template = "foo\n"
75             ."bar\n"
76             ."{% line 10 %}\n"
77             ."{{\n"
78             ."baz\n"
79             ."}}\n";
80
81         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
82         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
83
84         // foo\nbar\n
85         $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
86         // \n (after {% line %})
87         $this->assertSame(10, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
88         // {{
89         $this->assertSame(11, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine());
90         // baz
91         $this->assertSame(12, $stream->expect(Twig_Token::NAME_TYPE)->getLine());
92     }
93
94     public function testLineDirectiveInline()
95     {
96         $template = "foo\n"
97             ."bar{% line 10 %}{{\n"
98             ."baz\n"
99             ."}}\n";
100
101         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
102         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
103
104         // foo\nbar
105         $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
106         // {{
107         $this->assertSame(10, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine());
108         // baz
109         $this->assertSame(11, $stream->expect(Twig_Token::NAME_TYPE)->getLine());
110     }
111
112     public function testLongComments()
113     {
114         $template = '{# '.str_repeat('*', 100000).' #}';
115
116         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
117         $lexer->tokenize(new Twig_Source($template, 'index'));
118
119         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
120         // can be executed without throwing any exceptions
121         $this->addToAssertionCount(1);
122     }
123
124     public function testLongVerbatim()
125     {
126         $template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
127
128         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
129         $lexer->tokenize(new Twig_Source($template, 'index'));
130
131         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
132         // can be executed without throwing any exceptions
133         $this->addToAssertionCount(1);
134     }
135
136     public function testLongVar()
137     {
138         $template = '{{ '.str_repeat('x', 100000).' }}';
139
140         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
141         $lexer->tokenize(new Twig_Source($template, 'index'));
142
143         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
144         // can be executed without throwing any exceptions
145         $this->addToAssertionCount(1);
146     }
147
148     public function testLongBlock()
149     {
150         $template = '{% '.str_repeat('x', 100000).' %}';
151
152         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
153         $lexer->tokenize(new Twig_Source($template, 'index'));
154
155         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
156         // can be executed without throwing any exceptions
157         $this->addToAssertionCount(1);
158     }
159
160     public function testBigNumbers()
161     {
162         $template = '{{ 922337203685477580700 }}';
163
164         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
165         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
166         $stream->next();
167         $node = $stream->next();
168         $this->assertEquals('922337203685477580700', $node->getValue());
169     }
170
171     public function testStringWithEscapedDelimiter()
172     {
173         $tests = array(
174             "{{ 'foo \' bar' }}" => 'foo \' bar',
175             '{{ "foo \" bar" }}' => 'foo " bar',
176         );
177         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
178         foreach ($tests as $template => $expected) {
179             $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
180             $stream->expect(Twig_Token::VAR_START_TYPE);
181             $stream->expect(Twig_Token::STRING_TYPE, $expected);
182
183             // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
184             // can be executed without throwing any exceptions
185             $this->addToAssertionCount(1);
186         }
187     }
188
189     public function testStringWithInterpolation()
190     {
191         $template = 'foo {{ "bar #{ baz + 1 }" }}';
192
193         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
194         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
195         $stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
196         $stream->expect(Twig_Token::VAR_START_TYPE);
197         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
198         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
199         $stream->expect(Twig_Token::NAME_TYPE, 'baz');
200         $stream->expect(Twig_Token::OPERATOR_TYPE, '+');
201         $stream->expect(Twig_Token::NUMBER_TYPE, '1');
202         $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
203         $stream->expect(Twig_Token::VAR_END_TYPE);
204
205         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
206         // can be executed without throwing any exceptions
207         $this->addToAssertionCount(1);
208     }
209
210     public function testStringWithEscapedInterpolation()
211     {
212         $template = '{{ "bar \#{baz+1}" }}';
213
214         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
215         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
216         $stream->expect(Twig_Token::VAR_START_TYPE);
217         $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
218         $stream->expect(Twig_Token::VAR_END_TYPE);
219
220         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
221         // can be executed without throwing any exceptions
222         $this->addToAssertionCount(1);
223     }
224
225     public function testStringWithHash()
226     {
227         $template = '{{ "bar # baz" }}';
228
229         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
230         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
231         $stream->expect(Twig_Token::VAR_START_TYPE);
232         $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
233         $stream->expect(Twig_Token::VAR_END_TYPE);
234
235         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
236         // can be executed without throwing any exceptions
237         $this->addToAssertionCount(1);
238     }
239
240     /**
241      * @expectedException Twig_Error_Syntax
242      * @expectedExceptionMessage Unclosed """
243      */
244     public function testStringWithUnterminatedInterpolation()
245     {
246         $template = '{{ "bar #{x" }}';
247
248         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
249         $lexer->tokenize(new Twig_Source($template, 'index'));
250     }
251
252     public function testStringWithNestedInterpolations()
253     {
254         $template = '{{ "bar #{ "foo#{bar}" }" }}';
255
256         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
257         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
258         $stream->expect(Twig_Token::VAR_START_TYPE);
259         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
260         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
261         $stream->expect(Twig_Token::STRING_TYPE, 'foo');
262         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
263         $stream->expect(Twig_Token::NAME_TYPE, 'bar');
264         $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
265         $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
266         $stream->expect(Twig_Token::VAR_END_TYPE);
267
268         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
269         // can be executed without throwing any exceptions
270         $this->addToAssertionCount(1);
271     }
272
273     public function testStringWithNestedInterpolationsInBlock()
274     {
275         $template = '{% foo "bar #{ "foo#{bar}" }" %}';
276
277         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
278         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
279         $stream->expect(Twig_Token::BLOCK_START_TYPE);
280         $stream->expect(Twig_Token::NAME_TYPE, 'foo');
281         $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
282         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
283         $stream->expect(Twig_Token::STRING_TYPE, 'foo');
284         $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
285         $stream->expect(Twig_Token::NAME_TYPE, 'bar');
286         $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
287         $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
288         $stream->expect(Twig_Token::BLOCK_END_TYPE);
289
290         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
291         // can be executed without throwing any exceptions
292         $this->addToAssertionCount(1);
293     }
294
295     public function testOperatorEndingWithALetterAtTheEndOfALine()
296     {
297         $template = "{{ 1 and\n0}}";
298
299         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
300         $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
301         $stream->expect(Twig_Token::VAR_START_TYPE);
302         $stream->expect(Twig_Token::NUMBER_TYPE, 1);
303         $stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
304
305         // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
306         // can be executed without throwing any exceptions
307         $this->addToAssertionCount(1);
308     }
309
310     /**
311      * @expectedException Twig_Error_Syntax
312      * @expectedExceptionMessage Unclosed "variable" in "index" at line 3
313      */
314     public function testUnterminatedVariable()
315     {
316         $template = '
317
318 {{
319
320 bar
321
322
323 ';
324
325         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
326         $lexer->tokenize(new Twig_Source($template, 'index'));
327     }
328
329     /**
330      * @expectedException Twig_Error_Syntax
331      * @expectedExceptionMessage Unclosed "block" in "index" at line 3
332      */
333     public function testUnterminatedBlock()
334     {
335         $template = '
336
337 {%
338
339 bar
340
341
342 ';
343
344         $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
345         $lexer->tokenize(new Twig_Source($template, 'index'));
346     }
347 }