2253f716503bebf53116f128a2a7e2306747f7fd
[yaffs-website] / vendor / twig / twig / lib / Twig / Test / IntegrationTestCase.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
12 /**
13  * Integration test helper.
14  *
15  * @author Fabien Potencier <fabien@symfony.com>
16  * @author Karma Dordrak <drak@zikula.org>
17  */
18 abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
19 {
20     /**
21      * @return string
22      */
23     abstract protected function getFixturesDir();
24
25     /**
26      * @return Twig_ExtensionInterface[]
27      */
28     protected function getExtensions()
29     {
30         return array();
31     }
32
33     /**
34      * @return Twig_SimpleFilter[]
35      */
36     protected function getTwigFilters()
37     {
38         return array();
39     }
40
41     /**
42      * @return Twig_SimpleFunction[]
43      */
44     protected function getTwigFunctions()
45     {
46         return array();
47     }
48
49     /**
50      * @return Twig_SimpleTest[]
51      */
52     protected function getTwigTests()
53     {
54         return array();
55     }
56
57     /**
58      * @dataProvider getTests
59      */
60     public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
61     {
62         $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
63     }
64
65     /**
66      * @dataProvider getLegacyTests
67      * @group legacy
68      */
69     public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs)
70     {
71         $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
72     }
73
74     public function getTests($name, $legacyTests = false)
75     {
76         $fixturesDir = realpath($this->getFixturesDir());
77         $tests = array();
78
79         foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
80             if (!preg_match('/\.test$/', $file)) {
81                 continue;
82             }
83
84             if ($legacyTests xor false !== strpos($file->getRealpath(), '.legacy.test')) {
85                 continue;
86             }
87
88             $test = file_get_contents($file->getRealpath());
89
90             if (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
91                 $message = $match[1];
92                 $condition = $match[2];
93                 $templates = self::parseTemplates($match[3]);
94                 $exception = $match[5];
95                 $outputs = array(array(null, $match[4], null, ''));
96             } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
97                 $message = $match[1];
98                 $condition = $match[2];
99                 $templates = self::parseTemplates($match[3]);
100                 $exception = false;
101                 preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
102             } else {
103                 throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
104             }
105
106             $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
107         }
108
109         if ($legacyTests && empty($tests)) {
110             // add a dummy test to avoid a PHPUnit message
111             return array(array('not', '-', '', array(), '', array()));
112         }
113
114         return $tests;
115     }
116
117     public function getLegacyTests()
118     {
119         return $this->getTests('testLegacyIntegration', true);
120     }
121
122     protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
123     {
124         if (!$outputs) {
125             $this->markTestSkipped('no legacy tests to run');
126         }
127
128         if ($condition) {
129             eval('$ret = '.$condition.';');
130             if (!$ret) {
131                 $this->markTestSkipped($condition);
132             }
133         }
134
135         $loader = new Twig_Loader_Array($templates);
136
137         foreach ($outputs as $i => $match) {
138             $config = array_merge(array(
139                 'cache' => false,
140                 'strict_variables' => true,
141             ), $match[2] ? eval($match[2].';') : array());
142             $twig = new Twig_Environment($loader, $config);
143             $twig->addGlobal('global', 'global');
144             foreach ($this->getExtensions() as $extension) {
145                 $twig->addExtension($extension);
146             }
147
148             foreach ($this->getTwigFilters() as $filter) {
149                 $twig->addFilter($filter);
150             }
151
152             foreach ($this->getTwigTests() as $test) {
153                 $twig->addTest($test);
154             }
155
156             foreach ($this->getTwigFunctions() as $function) {
157                 $twig->addFunction($function);
158             }
159
160             // avoid using the same PHP class name for different cases
161             // only for PHP 5.2+
162             if (PHP_VERSION_ID >= 50300) {
163                 $p = new ReflectionProperty($twig, 'templateClassPrefix');
164                 $p->setAccessible(true);
165                 $p->setValue($twig, '__TwigTemplate_'.hash('sha256', uniqid(mt_rand(), true), false).'_');
166             }
167
168             try {
169                 $template = $twig->loadTemplate('index.twig');
170             } catch (Exception $e) {
171                 if (false !== $exception) {
172                     $message = $e->getMessage();
173                     $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
174                     $last = substr($message, strlen($message) - 1);
175                     $this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.');
176
177                     return;
178                 }
179
180                 throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
181             }
182
183             try {
184                 $output = trim($template->render(eval($match[1].';')), "\n ");
185             } catch (Exception $e) {
186                 if (false !== $exception) {
187                     $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
188
189                     return;
190                 }
191
192                 $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
193
194                 $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
195             }
196
197             if (false !== $exception) {
198                 list($class) = explode(':', $exception);
199                 $this->assertThat(null, new PHPUnit_Framework_Constraint_Exception($class));
200             }
201
202             $expected = trim($match[3], "\n ");
203
204             if ($expected !== $output) {
205                 printf("Compiled templates that failed on case %d:\n", $i + 1);
206
207                 foreach (array_keys($templates) as $name) {
208                     echo "Template: $name\n";
209                     $loader = $twig->getLoader();
210                     if (!$loader instanceof Twig_SourceContextLoaderInterface) {
211                         $source = new Twig_Source($loader->getSource($name), $name);
212                     } else {
213                         $source = $loader->getSourceContext($name);
214                     }
215                     echo $twig->compile($twig->parse($twig->tokenize($source)));
216                 }
217             }
218             $this->assertEquals($expected, $output, $message.' (in '.$file.')');
219         }
220     }
221
222     protected static function parseTemplates($test)
223     {
224         $templates = array();
225         preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER);
226         foreach ($matches as $match) {
227             $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
228         }
229
230         return $templates;
231     }
232 }