IntegrationTestCase.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) 2010 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. /**
  11. * Integration test helper
  12. *
  13. * @package twig
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. * @author Karma Dordrak <drak@zikula.org>
  16. */
  17. abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
  18. {
  19. abstract protected function getExtensions();
  20. abstract protected function getFixturesDir();
  21. /**
  22. * @dataProvider getTests
  23. */
  24. public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
  25. {
  26. $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
  27. }
  28. public function getTests()
  29. {
  30. $fixturesDir = realpath($this->getFixturesDir());
  31. $tests = array();
  32. foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
  33. if (!preg_match('/\.test$/', $file)) {
  34. continue;
  35. }
  36. $test = file_get_contents($file->getRealpath());
  37. if (preg_match('/
  38. --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
  39. $message = $match[1];
  40. $condition = $match[2];
  41. $templates = $this->parseTemplates($match[3]);
  42. $exception = $match[5];
  43. $outputs = array(array(null, $match[4], null, ''));
  44. } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
  45. $message = $match[1];
  46. $condition = $match[2];
  47. $templates = $this->parseTemplates($match[3]);
  48. $exception = false;
  49. preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
  50. } else {
  51. throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
  52. }
  53. $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
  54. }
  55. return $tests;
  56. }
  57. protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
  58. {
  59. if ($condition) {
  60. eval('$ret = '.$condition.';');
  61. if (!$ret) {
  62. $this->markTestSkipped($condition);
  63. }
  64. }
  65. $loader = new Twig_Loader_Array($templates);
  66. foreach ($outputs as $match) {
  67. $config = array_merge(array(
  68. 'cache' => false,
  69. 'strict_variables' => true,
  70. ), $match[2] ? eval($match[2].';') : array());
  71. $twig = new Twig_Environment($loader, $config);
  72. $twig->addGlobal('global', 'global');
  73. foreach ($this->getExtensions() as $extension) {
  74. $twig->addExtension($extension);
  75. }
  76. try {
  77. $template = $twig->loadTemplate('index.twig');
  78. } catch (Exception $e) {
  79. if (false !== $exception) {
  80. $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
  81. return;
  82. }
  83. if ($e instanceof Twig_Error_Syntax) {
  84. $e->setTemplateFile($file);
  85. throw $e;
  86. }
  87. throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
  88. }
  89. try {
  90. $output = trim($template->render(eval($match[1].';')), "\n ");
  91. } catch (Exception $e) {
  92. if (false !== $exception) {
  93. $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
  94. return;
  95. }
  96. if ($e instanceof Twig_Error_Syntax) {
  97. $e->setTemplateFile($file);
  98. } else {
  99. $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
  100. }
  101. $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
  102. }
  103. if (false !== $exception) {
  104. list($class, ) = explode(':', $exception);
  105. $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class));
  106. }
  107. $expected = trim($match[3], "\n ");
  108. if ($expected != $output) {
  109. echo 'Compiled template that failed:';
  110. foreach (array_keys($templates) as $name) {
  111. echo "Template: $name\n";
  112. $source = $loader->getSource($name);
  113. echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
  114. }
  115. }
  116. $this->assertEquals($expected, $output, $message.' (in '.$file.')');
  117. }
  118. }
  119. protected static function parseTemplates($test)
  120. {
  121. $templates = array();
  122. preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER);
  123. foreach ($matches as $match) {
  124. $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
  125. }
  126. return $templates;
  127. }
  128. }