Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\Framework;
11
 
12
use function assert;
13
use function count;
14
use function get_class;
15
use function sprintf;
16
use function trim;
17
use PHPUnit\Util\Filter;
18
use PHPUnit\Util\InvalidDataSetException;
19
use PHPUnit\Util\Test as TestUtil;
20
use ReflectionClass;
21
use Throwable;
22
 
23
/**
24
 * @internal This class is not covered by the backward compatibility promise for PHPUnit
25
 */
26
final class TestBuilder
27
{
28
    public function build(ReflectionClass $theClass, string $methodName): Test
29
    {
30
        $className = $theClass->getName();
31
 
32
        if (!$theClass->isInstantiable()) {
33
            return new ErrorTestCase(
34
                sprintf('Cannot instantiate class "%s".', $className)
35
            );
36
        }
37
 
38
        $backupSettings = TestUtil::getBackupSettings(
39
            $className,
40
            $methodName
41
        );
42
 
43
        $preserveGlobalState = TestUtil::getPreserveGlobalStateSettings(
44
            $className,
45
            $methodName
46
        );
47
 
48
        $runTestInSeparateProcess = TestUtil::getProcessIsolationSettings(
49
            $className,
50
            $methodName
51
        );
52
 
53
        $runClassInSeparateProcess = TestUtil::getClassProcessIsolationSettings(
54
            $className,
55
            $methodName
56
        );
57
 
58
        $constructor = $theClass->getConstructor();
59
 
60
        if ($constructor === null) {
61
            throw new Exception('No valid test provided.');
62
        }
63
 
64
        $parameters = $constructor->getParameters();
65
 
66
        // TestCase() or TestCase($name)
67
        if (count($parameters) < 2) {
68
            $test = $this->buildTestWithoutData($className);
69
        } // TestCase($name, $data)
70
        else {
71
            try {
72
                $data = TestUtil::getProvidedData(
73
                    $className,
74
                    $methodName
75
                );
76
            } catch (IncompleteTestError $e) {
77
                $message = sprintf(
78
                    "Test for %s::%s marked incomplete by data provider\n%s",
79
                    $className,
80
                    $methodName,
81
                    $this->throwableToString($e)
82
                );
83
 
84
                $data = new IncompleteTestCase($className, $methodName, $message);
85
            } catch (SkippedTestError $e) {
86
                $message = sprintf(
87
                    "Test for %s::%s skipped by data provider\n%s",
88
                    $className,
89
                    $methodName,
90
                    $this->throwableToString($e)
91
                );
92
 
93
                $data = new SkippedTestCase($className, $methodName, $message);
94
            } catch (Throwable $t) {
95
                $message = sprintf(
96
                    "The data provider specified for %s::%s is invalid.\n%s",
97
                    $className,
98
                    $methodName,
99
                    $this->throwableToString($t)
100
                );
101
 
102
                $data = new ErrorTestCase($message);
103
            }
104
 
105
            // Test method with @dataProvider.
106
            if (isset($data)) {
107
                $test = $this->buildDataProviderTestSuite(
108
                    $methodName,
109
                    $className,
110
                    $data,
111
                    $runTestInSeparateProcess,
112
                    $preserveGlobalState,
113
                    $runClassInSeparateProcess,
114
                    $backupSettings
115
                );
116
            } else {
117
                $test = $this->buildTestWithoutData($className);
118
            }
119
        }
120
 
121
        if ($test instanceof TestCase) {
122
            $test->setName($methodName);
123
            $this->configureTestCase(
124
                $test,
125
                $runTestInSeparateProcess,
126
                $preserveGlobalState,
127
                $runClassInSeparateProcess,
128
                $backupSettings
129
            );
130
        }
131
 
132
        return $test;
133
    }
134
 
135
    /** @psalm-param class-string $className */
136
    private function buildTestWithoutData(string $className)
137
    {
138
        return new $className;
139
    }
140
 
141
    /** @psalm-param class-string $className */
142
    private function buildDataProviderTestSuite(
143
        string $methodName,
144
        string $className,
145
        $data,
146
        bool $runTestInSeparateProcess,
147
        ?bool $preserveGlobalState,
148
        bool $runClassInSeparateProcess,
149
        array $backupSettings
150
    ): DataProviderTestSuite {
151
        $dataProviderTestSuite = new DataProviderTestSuite(
152
            $className . '::' . $methodName
153
        );
154
 
155
        $groups = TestUtil::getGroups($className, $methodName);
156
 
157
        if ($data instanceof ErrorTestCase ||
158
            $data instanceof SkippedTestCase ||
159
            $data instanceof IncompleteTestCase) {
160
            $dataProviderTestSuite->addTest($data, $groups);
161
        } else {
162
            foreach ($data as $_dataName => $_data) {
163
                $_test = new $className($methodName, $_data, $_dataName);
164
 
165
                assert($_test instanceof TestCase);
166
 
167
                $this->configureTestCase(
168
                    $_test,
169
                    $runTestInSeparateProcess,
170
                    $preserveGlobalState,
171
                    $runClassInSeparateProcess,
172
                    $backupSettings
173
                );
174
 
175
                $dataProviderTestSuite->addTest($_test, $groups);
176
            }
177
        }
178
 
179
        return $dataProviderTestSuite;
180
    }
181
 
182
    private function configureTestCase(
183
        TestCase $test,
184
        bool $runTestInSeparateProcess,
185
        ?bool $preserveGlobalState,
186
        bool $runClassInSeparateProcess,
187
        array $backupSettings
188
    ): void {
189
        if ($runTestInSeparateProcess) {
190
            $test->setRunTestInSeparateProcess(true);
191
 
192
            if ($preserveGlobalState !== null) {
193
                $test->setPreserveGlobalState($preserveGlobalState);
194
            }
195
        }
196
 
197
        if ($runClassInSeparateProcess) {
198
            $test->setRunClassInSeparateProcess(true);
199
 
200
            if ($preserveGlobalState !== null) {
201
                $test->setPreserveGlobalState($preserveGlobalState);
202
            }
203
        }
204
 
205
        if ($backupSettings['backupGlobals'] !== null) {
206
            $test->setBackupGlobals($backupSettings['backupGlobals']);
207
        }
208
 
209
        if ($backupSettings['backupStaticAttributes'] !== null) {
210
            $test->setBackupStaticAttributes(
211
                $backupSettings['backupStaticAttributes']
212
            );
213
        }
214
    }
215
 
216
    private function throwableToString(Throwable $t): string
217
    {
218
        $message = $t->getMessage();
219
 
220
        if (empty(trim($message))) {
221
            $message = '<no message>';
222
        }
223
 
224
        if ($t instanceof InvalidDataSetException) {
225
            return sprintf(
226
                "%s\n%s",
227
                $message,
228
                Filter::getFilteredStacktrace($t)
229
            );
230
        }
231
 
232
        return sprintf(
233
            "%s: %s\n%s",
234
            get_class($t),
235
            $message,
236
            Filter::getFilteredStacktrace($t)
237
        );
238
    }
239
}