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 PHPUnit\Framework\AssertionFailedError;
9
use PHPUnit\Framework\Test;
10
use PHPUnit\Framework\TestCase;
11
use PHPUnit\Framework\TestSuite;
12
use PHPUnit\Framework\Warning;
13
use ReflectionObject;
14
use Symfony\Component\Console\Input\ArgvInput;
15
use Symfony\Component\Console\Output\ConsoleOutput;
16
use Throwable;
17
 
18
/**
19
 * @internal
20
 */
21
final class Printer implements \PHPUnit\TextUI\ResultPrinter
22
{
23
    /**
24
     * Holds an instance of the style.
25
     *
26
     * Style is a class we use to interact with output.
27
     *
28
     * @var Style
29
     */
30
    private $style;
31
 
32
    /**
33
     * Holds the duration time of the test suite.
34
     *
35
     * @var Timer
36
     */
37
    private $timer;
38
 
39
    /**
40
     * Holds the state of the test
41
     * suite. The number of tests, etc.
42
     *
43
     * @var State
44
     */
45
    private $state;
46
 
47
    /**
48
     * If the test suite has failed.
49
     *
50
     * @var bool
51
     */
52
    private $failed = false;
53
 
54
    /**
55
     * Creates a new instance of the listener.
56
     *
57
     * @param  ConsoleOutput  $output
58
     *
59
     * @throws \ReflectionException
60
     */
61
    public function __construct(\Symfony\Component\Console\Output\ConsoleOutputInterface $output = null, bool $verbose = false, string $colors = 'always')
62
    {
63
        $this->timer = Timer::start();
64
 
65
        $decorated = $colors === 'always' || $colors === 'auto';
66
 
67
        $output = $output ?? new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $decorated);
68
 
69
        ConfigureIO::of(new ArgvInput(), $output);
70
 
71
        $this->style = new Style($output);
72
        $dummyTest = new class() extends TestCase
73
        {
74
        };
75
 
76
        $this->state = State::from($dummyTest);
77
    }
78
 
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function addError(Test $testCase, Throwable $throwable, float $time): void
83
    {
84
        $this->failed = true;
85
 
86
        $testCase = $this->testCaseFromTest($testCase);
87
 
88
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL, $throwable));
89
    }
90
 
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function addWarning(Test $testCase, Warning $warning, float $time): void
95
    {
96
        $testCase = $this->testCaseFromTest($testCase);
97
 
98
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::WARN, $warning));
99
    }
100
 
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function addFailure(Test $testCase, AssertionFailedError $error, float $time): void
105
    {
106
        $this->failed = true;
107
 
108
        $testCase = $this->testCaseFromTest($testCase);
109
 
110
        $reflector = new ReflectionObject($error);
111
 
112
        if ($reflector->hasProperty('message')) {
113
            $message = trim((string) preg_replace("/\r|\n/", "\n  ", $error->getMessage()));
114
            $property = $reflector->getProperty('message');
115
            $property->setAccessible(true);
116
            $property->setValue($error, $message);
117
        }
118
 
119
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL, $error));
120
    }
121
 
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function addIncompleteTest(Test $testCase, Throwable $throwable, float $time): void
126
    {
127
        $testCase = $this->testCaseFromTest($testCase);
128
 
129
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::INCOMPLETE, $throwable));
130
    }
131
 
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function addRiskyTest(Test $testCase, Throwable $throwable, float $time): void
136
    {
137
        $testCase = $this->testCaseFromTest($testCase);
138
 
139
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::RISKY, $throwable));
140
    }
141
 
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function addSkippedTest(Test $testCase, Throwable $throwable, float $time): void
146
    {
147
        $testCase = $this->testCaseFromTest($testCase);
148
 
149
        $this->state->add(TestResult::fromTestCase($testCase, TestResult::SKIPPED, $throwable));
150
    }
151
 
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function startTestSuite(TestSuite $suite): void
156
    {
157
        if ($this->state->suiteTotalTests === null) {
158
            $this->state->suiteTotalTests = $suite->count();
159
        }
160
    }
161
 
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function endTestSuite(TestSuite $suite): void
166
    {
167
        // ..
168
    }
169
 
170
    /**
171
     * {@inheritdoc}
172
     */
173
    public function startTest(Test $testCase): void
174
    {
175
        $testCase = $this->testCaseFromTest($testCase);
176
 
177
        // Let's check first if the testCase is over.
178
        if ($this->state->testCaseHasChanged($testCase)) {
179
            $this->style->writeCurrentTestCaseSummary($this->state);
180
 
181
            $this->state->moveTo($testCase);
182
        }
183
    }
184
 
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function endTest(Test $testCase, float $time): void
189
    {
190
        $testCase = $this->testCaseFromTest($testCase);
191
 
192
        if (! $this->state->existsInTestCase($testCase)) {
193
            $this->state->add(TestResult::fromTestCase($testCase, TestResult::PASS));
194
        }
195
 
196
        if ($testCase instanceof TestCase
197
            && $testCase->getTestResultObject() instanceof \PHPUnit\Framework\TestResult
198
            && ! $testCase->getTestResultObject()->isStrictAboutOutputDuringTests()
199
            && ! $testCase->hasExpectationOnOutput()) {
200
            $this->style->write($testCase->getActualOutput());
201
        }
202
    }
203
 
204
    /**
205
     * Intentionally left blank as we output things on events of the listener.
206
     */
207
    public function write(string $content): void
208
    {
209
        // ..
210
    }
211
 
212
    /**
213
     * Returns a test case from the given test.
214
     *
215
     * Note: This printer is do not work with normal Test classes - only
216
     * with Test Case classes. Please report an issue if you think
217
     * this should work any other way.
218
     */
219
    private function testCaseFromTest(Test $test): TestCase
220
    {
221
        if (! $test instanceof TestCase) {
222
            throw new ShouldNotHappen();
223
        }
224
 
225
        return $test;
226
    }
227
 
228
    /**
229
     * Intentionally left blank as we output things on events of the listener.
230
     */
231
    public function printResult(\PHPUnit\Framework\TestResult $result): void
232
    {
233
        if ($result->count() === 0) {
234
            $this->style->writeWarning('No tests executed!');
235
        }
236
 
237
        $this->style->writeCurrentTestCaseSummary($this->state);
238
 
239
        if ($this->failed) {
240
            $onFailure = $this->state->suiteTotalTests !== $this->state->testSuiteTestsCount();
241
            $this->style->writeErrorsSummary($this->state, $onFailure);
242
        }
243
 
244
        $this->style->writeRecap($this->state, $this->timer);
245
    }
246
}