Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace NunoMaduro\Collision\Adapters\Phpunit;
6
 
7
use NunoMaduro\Collision\Exceptions\ShouldNotHappen;
8
use NunoMaduro\Collision\Writer;
9
use PHPUnit\Framework\AssertionFailedError;
10
use PHPUnit\Framework\ExceptionWrapper;
11
use PHPUnit\Framework\ExpectationFailedException;
12
use Symfony\Component\Console\Output\ConsoleOutput;
13
use Symfony\Component\Console\Output\ConsoleOutputInterface;
14
use Throwable;
15
use Whoops\Exception\Inspector;
16
 
17
/**
18
 * @internal
19
 */
20
final class Style
21
{
22
    /**
23
     * @var ConsoleOutput
24
     */
25
    private $output;
26
 
27
    /**
28
     * Style constructor.
29
     */
30
    public function __construct(ConsoleOutputInterface $output)
31
    {
32
        if (! $output instanceof ConsoleOutput) {
33
            throw new ShouldNotHappen();
34
        }
35
 
36
        $this->output = $output;
37
    }
38
 
39
    /**
40
     * Prints the content.
41
     */
42
    public function write(string $content): void
43
    {
44
        $this->output->write($content);
45
    }
46
 
47
    /**
48
     * Prints the content similar too:.
49
     *
50
     * ```
51
     *    PASS  Unit\ExampleTest
52
     *    ✓ basic test
53
     * ```
54
     */
55
    public function writeCurrentTestCaseSummary(State $state): void
56
    {
57
        if ($state->testCaseTestsCount() === 0) {
58
            return;
59
        }
60
 
61
        if (! $state->headerPrinted) {
62
            $this->output->writeln($this->titleLineFrom(
63
                $state->getTestCaseTitle() === 'FAIL' ? 'white' : 'black',
64
                $state->getTestCaseTitleColor(),
65
                $state->getTestCaseTitle(),
66
                $state->testCaseName
67
            ));
68
            $state->headerPrinted = true;
69
        }
70
 
71
        $state->eachTestCaseTests(function (TestResult $testResult) {
72
            $this->output->writeln($this->testLineFrom(
73
                $testResult->color,
74
                $testResult->icon,
75
                $testResult->description,
76
                $testResult->warning
77
            ));
78
        });
79
    }
80
 
81
    /**
82
     * Prints the content similar too:.
83
     *
84
     * ```
85
     *    PASS  Unit\ExampleTest
86
     *    ✓ basic test
87
     * ```
88
     */
89
    public function writeErrorsSummary(State $state, bool $onFailure): void
90
    {
91
        $errors = array_filter($state->suiteTests, function (TestResult $testResult) {
92
            return $testResult->type === TestResult::FAIL;
93
        });
94
 
95
        if (! $onFailure) {
96
            $this->output->writeln(['', "  \e[2m---\e[22m", '']);
97
        }
98
 
99
        array_map(function (TestResult $testResult) use ($onFailure) {
100
            if (! $onFailure) {
101
                $this->output->write(sprintf(
102
                    '  <fg=red;options=bold>• %s </>> <fg=red;options=bold>%s</>',
103
                    $testResult->testCaseName,
104
                    $testResult->description
105
                ));
106
            }
107
 
108
            if (! $testResult->throwable instanceof Throwable) {
109
                throw new ShouldNotHappen();
110
            }
111
 
112
            $this->writeError($testResult->throwable);
113
        }, $errors);
114
    }
115
 
116
    /**
117
     * Writes the final recap.
118
     */
119
    public function writeRecap(State $state, Timer $timer = null): void
120
    {
121
        $types = [TestResult::FAIL, TestResult::WARN, TestResult::RISKY, TestResult::INCOMPLETE, TestResult::SKIPPED, TestResult::PASS];
122
        foreach ($types as $type) {
123
            if (($countTests = $state->countTestsInTestSuiteBy($type)) !== 0) {
124
                $color = TestResult::makeColor($type);
125
                $tests[] = "<fg=$color;options=bold>$countTests $type</>";
126
            }
127
        }
128
 
129
        $pending = $state->suiteTotalTests - $state->testSuiteTestsCount();
130
        if ($pending !== 0) {
131
            $tests[] = "\e[2m$pending pending\e[22m";
132
        }
133
 
134
        if (! empty($tests)) {
135
            $this->output->write([
136
                "\n",
137
                sprintf(
138
                    '  <fg=white;options=bold>Tests:  </><fg=default>%s</>',
139
                    implode(', ', $tests)
140
                ),
141
            ]);
142
        }
143
 
144
        if ($timer !== null) {
145
            $timeElapsed = number_format($timer->result(), 2, '.', '');
146
            $this->output->writeln([
147
                '',
148
                sprintf(
149
                    '  <fg=white;options=bold>Time:   </><fg=default>%ss</>',
150
                    $timeElapsed
151
                ),
152
            ]
153
            );
154
        }
155
 
156
        $this->output->writeln('');
157
    }
158
 
159
    /**
160
     * Displays a warning message.
161
     */
162
    public function writeWarning(string $message): void
163
    {
164
        $this->output->writeln($this->testLineFrom('yellow', $message, ''));
165
    }
166
 
167
    /**
168
     * Displays the error using Collision's writer
169
     * and terminates with exit code === 1.
170
     */
171
    public function writeError(Throwable $throwable): void
172
    {
173
        $writer = (new Writer())->setOutput($this->output);
174
 
175
        if ($throwable instanceof AssertionFailedError) {
176
            $writer->showTitle(false);
177
            $this->output->write('', true);
178
        }
179
 
180
        $writer->ignoreFilesIn([
181
            '/vendor\/bin\/pest/',
182
            '/bin\/pest/',
183
            '/vendor\/pestphp\/pest/',
184
            '/vendor\/phpspec\/prophecy-phpunit/',
185
            '/vendor\/phpspec\/prophecy/',
186
            '/vendor\/phpunit\/phpunit\/src/',
187
            '/vendor\/mockery\/mockery/',
188
            '/vendor\/laravel\/dusk/',
189
            '/vendor\/laravel\/framework\/src\/Illuminate\/Testing/',
190
            '/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Testing/',
191
            '/vendor\/symfony\/framework-bundle\/Test/',
192
            '/vendor\/symfony\/phpunit-bridge/',
193
            '/vendor\/symfony\/dom-crawler/',
194
            '/vendor\/symfony\/browser-kit/',
195
            '/vendor\/symfony\/css-selector/',
196
            '/vendor\/bin\/.phpunit/',
197
            '/bin\/.phpunit/',
198
            '/vendor\/bin\/simple-phpunit/',
199
            '/bin\/phpunit/',
200
            '/vendor\/coduo\/php-matcher\/src\/PHPUnit/',
201
            '/vendor\/sulu\/sulu\/src\/Sulu\/Bundle\/TestBundle\/Testing/',
202
            '/vendor\/webmozart\/assert/',
203
        ]);
204
 
205
        if ($throwable instanceof ExceptionWrapper && $throwable->getOriginalException() !== null) {
206
            $throwable = $throwable->getOriginalException();
207
        }
208
 
209
        $inspector = new Inspector($throwable);
210
 
211
        $writer->write($inspector);
212
 
213
        if ($throwable instanceof ExpectationFailedException && $comparisionFailure = $throwable->getComparisonFailure()) {
214
            $diff = $comparisionFailure->getDiff();
215
            $lines = explode(PHP_EOL, $diff);
216
            $diff = '';
217
            foreach ($lines as $line) {
218
                if (0 === strpos($line, '-')) {
219
                    $line = '<fg=red>'.$line.'</>';
220
                } elseif (0 === strpos($line, '+')) {
221
                    $line = '<fg=green>'.$line.'</>';
222
                }
223
 
224
                $diff .= $line.PHP_EOL;
225
            }
226
 
227
            $diff = trim((string) preg_replace("/\r|\n/", "\n  ", $diff));
228
 
229
            $this->output->write("  $diff");
230
        }
231
 
232
        $this->output->writeln('');
233
    }
234
 
235
    /**
236
     * Returns the title contents.
237
     */
238
    private function titleLineFrom(string $fg, string $bg, string $title, string $testCaseName): string
239
    {
240
        return sprintf(
241
            "\n  <fg=%s;bg=%s;options=bold> %s </><fg=default> %s</>",
242
            $fg,
243
            $bg,
244
            $title,
245
            $testCaseName
246
        );
247
    }
248
 
249
    /**
250
     * Returns the test contents.
251
     */
252
    private function testLineFrom(string $fg, string $icon, string $description, string $warning = null): string
253
    {
254
        if (! empty($warning)) {
255
            $warning = sprintf(
256
                ' → %s',
257
                $warning
258
            );
259
        }
260
 
261
        return sprintf(
262
            "  <fg=%s;options=bold>%s</><fg=default> \e[2m%s\e[22m</><fg=yellow>%s</>",
263
            $fg,
264
            $icon,
265
            $description,
266
            $warning
267
        );
268
    }
269
}