OptimizerTest.php 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
  11. {
  12. public function testRenderBlockOptimizer()
  13. {
  14. $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
  15. $env->addExtension(new Twig_Extension_Optimizer());
  16. $stream = $env->parse($env->tokenize('{{ block("foo") }}', 'index'));
  17. $node = $stream->getNode('body')->getNode(0);
  18. $this->assertInstanceOf('Twig_Node_Expression_BlockReference', $node);
  19. $this->assertTrue($node->getAttribute('output'));
  20. }
  21. public function testRenderParentBlockOptimizer()
  22. {
  23. $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
  24. $env->addExtension(new Twig_Extension_Optimizer());
  25. $stream = $env->parse($env->tokenize('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index'));
  26. $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body');
  27. $this->assertInstanceOf('Twig_Node_Expression_Parent', $node);
  28. $this->assertTrue($node->getAttribute('output'));
  29. }
  30. public function testRenderVariableBlockOptimizer()
  31. {
  32. if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
  33. return;
  34. }
  35. $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
  36. $env->addExtension(new Twig_Extension_Optimizer());
  37. $stream = $env->parse($env->tokenize('{{ block(name|lower) }}', 'index'));
  38. $node = $stream->getNode('body')->getNode(0)->getNode(1);
  39. $this->assertInstanceOf('Twig_Node_Expression_BlockReference', $node);
  40. $this->assertTrue($node->getAttribute('output'));
  41. }
  42. /**
  43. * @dataProvider getTestsForForOptimizer
  44. */
  45. public function testForOptimizer($template, $expected)
  46. {
  47. $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false));
  48. $env->addExtension(new Twig_Extension_Optimizer());
  49. $stream = $env->parse($env->tokenize($template, 'index'));
  50. foreach ($expected as $target => $withLoop) {
  51. $this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : ''));
  52. }
  53. }
  54. public function getTestsForForOptimizer()
  55. {
  56. return array(
  57. array('{% for i in foo %}{% endfor %}', array('i' => false)),
  58. array('{% for i in foo %}{{ loop.index }}{% endfor %}', array('i' => true)),
  59. array('{% for i in foo %}{% for j in foo %}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)),
  60. array('{% for i in foo %}{% include "foo" %}{% endfor %}', array('i' => true)),
  61. array('{% for i in foo %}{% include "foo" only %}{% endfor %}', array('i' => false)),
  62. array('{% for i in foo %}{% include "foo" with { "foo": "bar" } only %}{% endfor %}', array('i' => false)),
  63. array('{% for i in foo %}{% include "foo" with { "foo": loop.index } only %}{% endfor %}', array('i' => true)),
  64. array('{% for i in foo %}{% for j in foo %}{{ loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => true)),
  65. array('{% for i in foo %}{% for j in foo %}{{ loop.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)),
  66. array('{% for i in foo %}{% set l = loop %}{% for j in foo %}{{ l.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => false)),
  67. array('{% for i in foo %}{% for j in foo %}{{ foo.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)),
  68. array('{% for i in foo %}{% for j in foo %}{{ loop["parent"].loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)),
  69. );
  70. }
  71. public function checkForConfiguration(Twig_NodeInterface $node = null, $target, $withLoop)
  72. {
  73. if (null === $node) {
  74. return;
  75. }
  76. foreach ($node as $n) {
  77. if ($n instanceof Twig_Node_For) {
  78. if ($target === $n->getNode('value_target')->getAttribute('name')) {
  79. return $withLoop == $n->getAttribute('with_loop');
  80. }
  81. }
  82. $ret = $this->checkForConfiguration($n, $target, $withLoop);
  83. if (null !== $ret) {
  84. return $ret;
  85. }
  86. }
  87. }
  88. }