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.
11 class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
14 * @expectedException Twig_Error_Syntax
16 public function testSetMacroThrowsExceptionOnReservedMethods()
18 $parser = $this->getParser();
19 $parser->setMacro('parent', $this->getMockBuilder('Twig_Node_Macro')->disableOriginalConstructor()->getMock());
23 * @expectedException Twig_Error_Syntax
24 * @expectedExceptionMessage Unknown "foo" tag. Did you mean "for" at line 1?
26 public function testUnknownTag()
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),
34 $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
35 $parser->parse($stream);
39 * @expectedException Twig_Error_Syntax
40 * @expectedExceptionMessage Unknown "foobar" tag at line 1.
42 public function testUnknownTagWithoutSuggestions()
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),
50 $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
51 $parser->parse($stream);
55 * @dataProvider getFilterBodyNodesData
57 public function testFilterBodyNodes($input, $expected)
59 $parser = $this->getParser();
61 $this->assertEquals($expected, $parser->filterBodyNodes($input));
64 public function getFilterBodyNodesData()
68 new Twig_Node(array(new Twig_Node_Text(' ', 1))),
69 new Twig_Node(array()),
72 $input = new Twig_Node(array(new Twig_Node_Set(false, new Twig_Node(), new Twig_Node(), 1))),
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))),
83 * @dataProvider getFilterBodyNodesDataThrowsException
84 * @expectedException Twig_Error_Syntax
86 public function testFilterBodyNodesThrowsException($input)
88 $parser = $this->getParser();
90 $parser->filterBodyNodes($input);
93 public function getFilterBodyNodesDataThrowsException()
96 array(new Twig_Node_Text('foo', 1)),
97 array(new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 1)))))),
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
105 public function testFilterBodyNodesWithBOM()
107 $parser = $this->getParser();
108 $parser->filterBodyNodes(new Twig_Node_Text(chr(0xEF).chr(0xBB).chr(0xBF), 1));
111 public function testParseIsReentrant()
113 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array(
114 'autoescape' => false,
115 'optimizations' => 0,
117 $twig->addTokenParser(new TestTokenParser());
119 $parser = new Twig_Parser($twig);
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),
131 $this->assertNull($parser->getParent());
134 public function testGetVarName()
136 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array(
137 'autoescape' => false,
138 'optimizations' => 0,
141 $twig->parse($twig->tokenize(new Twig_Source(<<<EOF
142 {% from _self import foo %}
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);
156 protected function getParser()
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());
166 class TestParser extends Twig_Parser
170 public function filterBodyNodes(Twig_NodeInterface $node)
172 return parent::filterBodyNodes($node);
176 class TestTokenParser extends Twig_TokenParser
178 public function parse(Twig_Token $token)
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),
189 $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
191 return new Twig_Node(array());
194 public function getTag()