ParserTest.php 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
  11. {
  12. /**
  13. * @expectedException Twig_Error_Syntax
  14. */
  15. public function testSetMacroThrowsExceptionOnReservedMethods()
  16. {
  17. $parser = new Twig_Parser(new Twig_Environment());
  18. $parser->setMacro('display', $this->getMock('Twig_Node_Macro', array(), array(), '', null));
  19. }
  20. /**
  21. * @expectedException Twig_Error_Syntax
  22. * @expectedExceptionMessage Unknown tag name "foo". Did you mean "for" at line 0
  23. */
  24. public function testUnkownTag()
  25. {
  26. $stream = new Twig_TokenStream(array(
  27. new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0),
  28. new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 0),
  29. new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0),
  30. new Twig_Token(Twig_Token::EOF_TYPE, '', 0),
  31. ));
  32. $parser = new Twig_Parser(new Twig_Environment());
  33. $parser->parse($stream);
  34. }
  35. /**
  36. * @dataProvider getFilterBodyNodesData
  37. */
  38. public function testFilterBodyNodes($input, $expected)
  39. {
  40. $parser = $this->getParserForFilterBodyNodes();
  41. $this->assertEquals($expected, $parser->filterBodyNodes($input));
  42. }
  43. public function getFilterBodyNodesData()
  44. {
  45. return array(
  46. array(
  47. new Twig_Node(array(new Twig_Node_Text(' ', 0))),
  48. new Twig_Node(array()),
  49. ),
  50. array(
  51. $input = new Twig_Node(array(new Twig_Node_Set(false, new Twig_Node(), new Twig_Node(), 0))),
  52. $input,
  53. ),
  54. array(
  55. $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', 0))))), 0))),
  56. $input,
  57. ),
  58. );
  59. }
  60. /**
  61. * @dataProvider getFilterBodyNodesDataThrowsException
  62. * @expectedException Twig_Error_Syntax
  63. */
  64. public function testFilterBodyNodesThrowsException($input)
  65. {
  66. $parser = $this->getParserForFilterBodyNodes();
  67. $parser->filterBodyNodes($input);
  68. }
  69. public function getFilterBodyNodesDataThrowsException()
  70. {
  71. return array(
  72. array(new Twig_Node_Text('foo', 0)),
  73. array(new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 0)))))),
  74. );
  75. }
  76. /**
  77. * @expectedException Twig_Error_Syntax
  78. * @expectedExceptionMessage A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed at line 0.
  79. */
  80. public function testFilterBodyNodesWithBOM()
  81. {
  82. $parser = $this->getParserForFilterBodyNodes();
  83. $parser->filterBodyNodes(new Twig_Node_Text(chr(0xEF).chr(0xBB).chr(0xBF), 0));
  84. }
  85. public function testParseIsReentrant()
  86. {
  87. $twig = new Twig_Environment(null, array(
  88. 'autoescape' => false,
  89. 'optimizations' => 0,
  90. ));
  91. $twig->addTokenParser(new TestTokenParser());
  92. $parser = new Twig_Parser($twig);
  93. $parser->parse(new Twig_TokenStream(array(
  94. new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0),
  95. new Twig_Token(Twig_Token::NAME_TYPE, 'test', 0),
  96. new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0),
  97. new Twig_Token(Twig_Token::VAR_START_TYPE, '', 0),
  98. new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 0),
  99. new Twig_Token(Twig_Token::VAR_END_TYPE, '', 0),
  100. new Twig_Token(Twig_Token::EOF_TYPE, '', 0),
  101. )));
  102. $this->assertEquals(null, $parser->getParent());
  103. }
  104. protected function getParserForFilterBodyNodes()
  105. {
  106. $parser = new TestParser(new Twig_Environment());
  107. $parser->setParent(new Twig_Node());
  108. $parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
  109. return $parser;
  110. }
  111. }
  112. class TestParser extends Twig_Parser
  113. {
  114. public $stream;
  115. public function filterBodyNodes(Twig_NodeInterface $node)
  116. {
  117. return parent::filterBodyNodes($node);
  118. }
  119. }
  120. class TestTokenParser extends Twig_TokenParser
  121. {
  122. public function parse(Twig_Token $token)
  123. {
  124. // simulate the parsing of another template right in the middle of the parsing of the current template
  125. $this->parser->parse(new Twig_TokenStream(array(
  126. new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0),
  127. new Twig_Token(Twig_Token::NAME_TYPE, 'extends', 0),
  128. new Twig_Token(Twig_Token::STRING_TYPE, 'base', 0),
  129. new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0),
  130. new Twig_Token(Twig_Token::EOF_TYPE, '', 0),
  131. )));
  132. $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
  133. return new Twig_Node(array());
  134. }
  135. public function getTag()
  136. {
  137. return 'test';
  138. }
  139. }