Security update for Core, with self-updated composer
[yaffs-website] / vendor / twig / twig / test / Twig / Tests / ParserTest.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_ParserTest extends \PHPUnit\Framework\TestCase
12 {
13     /**
14      * @expectedException Twig_Error_Syntax
15      */
16     public function testSetMacroThrowsExceptionOnReservedMethods()
17     {
18         $parser = $this->getParser();
19         $parser->setMacro('parent', $this->getMockBuilder('Twig_Node_Macro')->disableOriginalConstructor()->getMock());
20     }
21
22     /**
23      * @expectedException        Twig_Error_Syntax
24      * @expectedExceptionMessage Unknown "foo" tag. Did you mean "for" at line 1?
25      */
26     public function testUnknownTag()
27     {
28         $stream = new Twig_TokenStream(array(
29             new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1),
30             new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 1),
31             new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1),
32             new Twig_Token(Twig_Token::EOF_TYPE, '', 1),
33         ));
34         $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
35         $parser->parse($stream);
36     }
37
38     /**
39      * @expectedException        Twig_Error_Syntax
40      * @expectedExceptionMessage Unknown "foobar" tag at line 1.
41      */
42     public function testUnknownTagWithoutSuggestions()
43     {
44         $stream = new Twig_TokenStream(array(
45             new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1),
46             new Twig_Token(Twig_Token::NAME_TYPE, 'foobar', 1),
47             new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1),
48             new Twig_Token(Twig_Token::EOF_TYPE, '', 1),
49         ));
50         $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
51         $parser->parse($stream);
52     }
53
54     /**
55      * @dataProvider getFilterBodyNodesData
56      */
57     public function testFilterBodyNodes($input, $expected)
58     {
59         $parser = $this->getParser();
60
61         $this->assertEquals($expected, $parser->filterBodyNodes($input));
62     }
63
64     public function getFilterBodyNodesData()
65     {
66         return array(
67             array(
68                 new Twig_Node(array(new Twig_Node_Text('   ', 1))),
69                 new Twig_Node(array()),
70             ),
71             array(
72                 $input = new Twig_Node(array(new Twig_Node_Set(false, new Twig_Node(), new Twig_Node(), 1))),
73                 $input,
74             ),
75             array(
76                 $input = new Twig_Node(array(new Twig_Node_Set(true, new Twig_Node(), new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 1))))), 1))),
77                 $input,
78             ),
79         );
80     }
81
82     /**
83      * @dataProvider getFilterBodyNodesDataThrowsException
84      * @expectedException Twig_Error_Syntax
85      */
86     public function testFilterBodyNodesThrowsException($input)
87     {
88         $parser = $this->getParser();
89
90         $parser->filterBodyNodes($input);
91     }
92
93     public function getFilterBodyNodesDataThrowsException()
94     {
95         return array(
96             array(new Twig_Node_Text('foo', 1)),
97             array(new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 1)))))),
98         );
99     }
100
101     /**
102      * @expectedException Twig_Error_Syntax
103      * @expectedExceptionMessage A template that extends another one cannot start with a byte order mark (BOM); it must be removed at line 1
104      */
105     public function testFilterBodyNodesWithBOM()
106     {
107         $parser = $this->getParser();
108         $parser->filterBodyNodes(new Twig_Node_Text(chr(0xEF).chr(0xBB).chr(0xBF), 1));
109     }
110
111     public function testParseIsReentrant()
112     {
113         $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array(
114             'autoescape' => false,
115             'optimizations' => 0,
116         ));
117         $twig->addTokenParser(new TestTokenParser());
118
119         $parser = new Twig_Parser($twig);
120
121         $parser->parse(new Twig_TokenStream(array(
122             new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1),
123             new Twig_Token(Twig_Token::NAME_TYPE, 'test', 1),
124             new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1),
125             new Twig_Token(Twig_Token::VAR_START_TYPE, '', 1),
126             new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 1),
127             new Twig_Token(Twig_Token::VAR_END_TYPE, '', 1),
128             new Twig_Token(Twig_Token::EOF_TYPE, '', 1),
129         )));
130
131         $this->assertNull($parser->getParent());
132     }
133
134     public function testGetVarName()
135     {
136         $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array(
137             'autoescape' => false,
138             'optimizations' => 0,
139         ));
140
141         $twig->parse($twig->tokenize(new Twig_Source(<<<EOF
142 {% from _self import foo %}
143
144 {% macro foo() %}
145     {{ foo }}
146 {% endmacro %}
147 EOF
148         , 'index')));
149
150         // The getVarName() must not depend on the template loaders,
151         // If this test does not throw any exception, that's good.
152         // see https://github.com/symfony/symfony/issues/4218
153         $this->addToAssertionCount(1);
154     }
155
156     protected function getParser()
157     {
158         $parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
159         $parser->setParent(new Twig_Node());
160         $parser->stream = new Twig_TokenStream(array());
161
162         return $parser;
163     }
164 }
165
166 class TestParser extends Twig_Parser
167 {
168     public $stream;
169
170     public function filterBodyNodes(Twig_NodeInterface $node)
171     {
172         return parent::filterBodyNodes($node);
173     }
174 }
175
176 class TestTokenParser extends Twig_TokenParser
177 {
178     public function parse(Twig_Token $token)
179     {
180         // simulate the parsing of another template right in the middle of the parsing of the current template
181         $this->parser->parse(new Twig_TokenStream(array(
182             new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1),
183             new Twig_Token(Twig_Token::NAME_TYPE, 'extends', 1),
184             new Twig_Token(Twig_Token::STRING_TYPE, 'base', 1),
185             new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1),
186             new Twig_Token(Twig_Token::EOF_TYPE, '', 1),
187         )));
188
189         $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
190
191         return new Twig_Node(array());
192     }
193
194     public function getTag()
195     {
196         return 'test';
197     }
198 }