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\Util\TestDox;
11
 
12
use function array_filter;
13
use function get_class;
14
use function implode;
15
use function strpos;
16
use DOMDocument;
17
use DOMElement;
18
use PHPUnit\Framework\AssertionFailedError;
19
use PHPUnit\Framework\Exception;
20
use PHPUnit\Framework\Test;
21
use PHPUnit\Framework\TestCase;
22
use PHPUnit\Framework\TestListener;
23
use PHPUnit\Framework\TestSuite;
24
use PHPUnit\Framework\Warning;
25
use PHPUnit\Framework\WarningTestCase;
26
use PHPUnit\Util\Printer;
27
use PHPUnit\Util\Test as TestUtil;
28
use ReflectionClass;
29
use ReflectionException;
30
use Throwable;
31
 
32
/**
33
 * @internal This class is not covered by the backward compatibility promise for PHPUnit
34
 */
35
final class XmlResultPrinter extends Printer implements TestListener
36
{
37
    /**
38
     * @var DOMDocument
39
     */
40
    private $document;
41
 
42
    /**
43
     * @var DOMElement
44
     */
45
    private $root;
46
 
47
    /**
48
     * @var NamePrettifier
49
     */
50
    private $prettifier;
51
 
52
    /**
53
     * @var null|Throwable
54
     */
55
    private $exception;
56
 
57
    /**
58
     * @param resource|string $out
59
     *
60
     * @throws Exception
61
     */
62
    public function __construct($out = null)
63
    {
64
        $this->document               = new DOMDocument('1.0', 'UTF-8');
65
        $this->document->formatOutput = true;
66
 
67
        $this->root = $this->document->createElement('tests');
68
        $this->document->appendChild($this->root);
69
 
70
        $this->prettifier = new NamePrettifier;
71
 
72
        parent::__construct($out);
73
    }
74
 
75
    /**
76
     * Flush buffer and close output.
77
     */
78
    public function flush(): void
79
    {
80
        $this->write($this->document->saveXML());
81
 
82
        parent::flush();
83
    }
84
 
85
    /**
86
     * An error occurred.
87
     */
88
    public function addError(Test $test, Throwable $t, float $time): void
89
    {
90
        $this->exception = $t;
91
    }
92
 
93
    /**
94
     * A warning occurred.
95
     */
96
    public function addWarning(Test $test, Warning $e, float $time): void
97
    {
98
    }
99
 
100
    /**
101
     * A failure occurred.
102
     */
103
    public function addFailure(Test $test, AssertionFailedError $e, float $time): void
104
    {
105
        $this->exception = $e;
106
    }
107
 
108
    /**
109
     * Incomplete test.
110
     */
111
    public function addIncompleteTest(Test $test, Throwable $t, float $time): void
112
    {
113
    }
114
 
115
    /**
116
     * Risky test.
117
     */
118
    public function addRiskyTest(Test $test, Throwable $t, float $time): void
119
    {
120
    }
121
 
122
    /**
123
     * Skipped test.
124
     */
125
    public function addSkippedTest(Test $test, Throwable $t, float $time): void
126
    {
127
    }
128
 
129
    /**
130
     * A test suite started.
131
     */
132
    public function startTestSuite(TestSuite $suite): void
133
    {
134
    }
135
 
136
    /**
137
     * A test suite ended.
138
     */
139
    public function endTestSuite(TestSuite $suite): void
140
    {
141
    }
142
 
143
    /**
144
     * A test started.
145
     */
146
    public function startTest(Test $test): void
147
    {
148
        $this->exception = null;
149
    }
150
 
151
    /**
152
     * A test ended.
153
     *
154
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
155
     */
156
    public function endTest(Test $test, float $time): void
157
    {
158
        if (!$test instanceof TestCase || $test instanceof WarningTestCase) {
159
            return;
160
        }
161
 
162
        $groups = array_filter(
163
            $test->getGroups(),
164
            static function ($group)
165
            {
166
                return !($group === 'small' || $group === 'medium' || $group === 'large' || strpos($group, '__phpunit_') === 0);
167
            }
168
        );
169
 
170
        $testNode = $this->document->createElement('test');
171
 
172
        $testNode->setAttribute('className', get_class($test));
173
        $testNode->setAttribute('methodName', $test->getName());
174
        $testNode->setAttribute('prettifiedClassName', $this->prettifier->prettifyTestClass(get_class($test)));
175
        $testNode->setAttribute('prettifiedMethodName', $this->prettifier->prettifyTestCase($test));
176
        $testNode->setAttribute('status', (string) $test->getStatus());
177
        $testNode->setAttribute('time', (string) $time);
178
        $testNode->setAttribute('size', (string) $test->getSize());
179
        $testNode->setAttribute('groups', implode(',', $groups));
180
 
181
        foreach ($groups as $group) {
182
            $groupNode = $this->document->createElement('group');
183
 
184
            $groupNode->setAttribute('name', $group);
185
 
186
            $testNode->appendChild($groupNode);
187
        }
188
 
189
        $annotations = TestUtil::parseTestMethodAnnotations(
190
            get_class($test),
191
            $test->getName(false)
192
        );
193
 
194
        foreach (['class', 'method'] as $type) {
195
            foreach ($annotations[$type] as $annotation => $values) {
196
                if ($annotation !== 'covers' && $annotation !== 'uses') {
197
                    continue;
198
                }
199
 
200
                foreach ($values as $value) {
201
                    $coversNode = $this->document->createElement($annotation);
202
 
203
                    $coversNode->setAttribute('target', $value);
204
 
205
                    $testNode->appendChild($coversNode);
206
                }
207
            }
208
        }
209
 
210
        foreach ($test->doubledTypes() as $doubledType) {
211
            $testDoubleNode = $this->document->createElement('testDouble');
212
 
213
            $testDoubleNode->setAttribute('type', $doubledType);
214
 
215
            $testNode->appendChild($testDoubleNode);
216
        }
217
 
218
        $inlineAnnotations = \PHPUnit\Util\Test::getInlineAnnotations(get_class($test), $test->getName(false));
219
 
220
        if (isset($inlineAnnotations['given'], $inlineAnnotations['when'], $inlineAnnotations['then'])) {
221
            $testNode->setAttribute('given', $inlineAnnotations['given']['value']);
222
            $testNode->setAttribute('givenStartLine', (string) $inlineAnnotations['given']['line']);
223
            $testNode->setAttribute('when', $inlineAnnotations['when']['value']);
224
            $testNode->setAttribute('whenStartLine', (string) $inlineAnnotations['when']['line']);
225
            $testNode->setAttribute('then', $inlineAnnotations['then']['value']);
226
            $testNode->setAttribute('thenStartLine', (string) $inlineAnnotations['then']['line']);
227
        }
228
 
229
        if ($this->exception !== null) {
230
            if ($this->exception instanceof Exception) {
231
                $steps = $this->exception->getSerializableTrace();
232
            } else {
233
                $steps = $this->exception->getTrace();
234
            }
235
 
236
            try {
237
                $file = (new ReflectionClass($test))->getFileName();
238
                // @codeCoverageIgnoreStart
239
            } catch (ReflectionException $e) {
240
                throw new Exception(
241
                    $e->getMessage(),
242
                    $e->getCode(),
243
                    $e
244
                );
245
            }
246
            // @codeCoverageIgnoreEnd
247
 
248
            foreach ($steps as $step) {
249
                if (isset($step['file']) && $step['file'] === $file) {
250
                    $testNode->setAttribute('exceptionLine', (string) $step['line']);
251
 
252
                    break;
253
                }
254
            }
255
 
256
            $testNode->setAttribute('exceptionMessage', $this->exception->getMessage());
257
        }
258
 
259
        $this->root->appendChild($testNode);
260
    }
261
}