Test Failed
Push — master ( 6a1530...bb1f7e )
by Justin
04:13
created

Twig_Test_IntegrationTestCase::parseTemplates()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
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
use PHPUnit\Framework\TestCase;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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