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/php-code-coverage.
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 SebastianBergmann\CodeCoverage\Report;
11
 
12
use function basename;
13
use function count;
14
use function dirname;
15
use function file_put_contents;
16
use function preg_match;
17
use function range;
18
use function str_replace;
19
use function time;
20
use DOMImplementation;
21
use SebastianBergmann\CodeCoverage\CodeCoverage;
22
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
23
use SebastianBergmann\CodeCoverage\Node\File;
24
use SebastianBergmann\CodeCoverage\Util\Filesystem;
25
 
26
final class Cobertura
27
{
28
    /**
29
     * @throws WriteOperationFailedException
30
     */
31
    public function process(CodeCoverage $coverage, ?string $target = null): string
32
    {
33
        $time = (string) time();
34
 
35
        $report = $coverage->getReport();
36
 
37
        $implementation = new DOMImplementation;
38
 
39
        $documentType = $implementation->createDocumentType(
40
            'coverage',
41
            '',
42
            'http://cobertura.sourceforge.net/xml/coverage-04.dtd'
43
        );
44
 
45
        $document               = $implementation->createDocument('', '', $documentType);
46
        $document->xmlVersion   = '1.0';
47
        $document->encoding     = 'UTF-8';
48
        $document->formatOutput = true;
49
 
50
        $coverageElement = $document->createElement('coverage');
51
 
52
        $linesValid   = $report->numberOfExecutableLines();
53
        $linesCovered = $report->numberOfExecutedLines();
54
        $lineRate     = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
55
        $coverageElement->setAttribute('line-rate', (string) $lineRate);
56
 
57
        $branchesValid   = $report->numberOfExecutableBranches();
58
        $branchesCovered = $report->numberOfExecutedBranches();
59
        $branchRate      = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
60
        $coverageElement->setAttribute('branch-rate', (string) $branchRate);
61
 
62
        $coverageElement->setAttribute('lines-covered', (string) $report->numberOfExecutedLines());
63
        $coverageElement->setAttribute('lines-valid', (string) $report->numberOfExecutableLines());
64
        $coverageElement->setAttribute('branches-covered', (string) $report->numberOfExecutedBranches());
65
        $coverageElement->setAttribute('branches-valid', (string) $report->numberOfExecutableBranches());
66
        $coverageElement->setAttribute('complexity', '');
67
        $coverageElement->setAttribute('version', '0.4');
68
        $coverageElement->setAttribute('timestamp', $time);
69
 
70
        $document->appendChild($coverageElement);
71
 
72
        $sourcesElement = $document->createElement('sources');
73
        $coverageElement->appendChild($sourcesElement);
74
 
75
        $sourceElement = $document->createElement('source', $report->pathAsString());
76
        $sourcesElement->appendChild($sourceElement);
77
 
78
        $packagesElement = $document->createElement('packages');
79
        $coverageElement->appendChild($packagesElement);
80
 
81
        $complexity = 0;
82
 
83
        foreach ($report as $item) {
84
            if (!$item instanceof File) {
85
                continue;
86
            }
87
 
88
            $packageElement    = $document->createElement('package');
89
            $packageComplexity = 0;
90
 
91
            $packageElement->setAttribute('name', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
92
 
93
            $linesValid   = $item->numberOfExecutableLines();
94
            $linesCovered = $item->numberOfExecutedLines();
95
            $lineRate     = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
96
 
97
            $packageElement->setAttribute('line-rate', (string) $lineRate);
98
 
99
            $branchesValid   = $item->numberOfExecutableBranches();
100
            $branchesCovered = $item->numberOfExecutedBranches();
101
            $branchRate      = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
102
 
103
            $packageElement->setAttribute('branch-rate', (string) $branchRate);
104
 
105
            $packageElement->setAttribute('complexity', '');
106
            $packagesElement->appendChild($packageElement);
107
 
108
            $classesElement = $document->createElement('classes');
109
 
110
            $packageElement->appendChild($classesElement);
111
 
112
            $classes      = $item->classesAndTraits();
113
            $coverageData = $item->lineCoverageData();
114
 
115
            foreach ($classes as $className => $class) {
116
                $complexity += $class['ccn'];
117
                $packageComplexity += $class['ccn'];
118
 
119
                if (!empty($class['package']['namespace'])) {
120
                    $className = $class['package']['namespace'] . '\\' . $className;
121
                }
122
 
123
                $linesValid   = $class['executableLines'];
124
                $linesCovered = $class['executedLines'];
125
                $lineRate     = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
126
 
127
                $branchesValid   = $class['executableBranches'];
128
                $branchesCovered = $class['executedBranches'];
129
                $branchRate      = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
130
 
131
                $classElement = $document->createElement('class');
132
 
133
                $classElement->setAttribute('name', $className);
134
                $classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
135
                $classElement->setAttribute('line-rate', (string) $lineRate);
136
                $classElement->setAttribute('branch-rate', (string) $branchRate);
137
                $classElement->setAttribute('complexity', (string) $class['ccn']);
138
 
139
                $classesElement->appendChild($classElement);
140
 
141
                $methodsElement = $document->createElement('methods');
142
 
143
                $classElement->appendChild($methodsElement);
144
 
145
                $classLinesElement = $document->createElement('lines');
146
 
147
                $classElement->appendChild($classLinesElement);
148
 
149
                foreach ($class['methods'] as $methodName => $method) {
150
                    if ($method['executableLines'] === 0) {
151
                        continue;
152
                    }
153
 
154
                    preg_match("/\((.*?)\)/", $method['signature'], $signature);
155
 
156
                    $linesValid   = $method['executableLines'];
157
                    $linesCovered = $method['executedLines'];
158
                    $lineRate     = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
159
 
160
                    $branchesValid   = $method['executableBranches'];
161
                    $branchesCovered = $method['executedBranches'];
162
                    $branchRate      = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
163
 
164
                    $methodElement = $document->createElement('method');
165
 
166
                    $methodElement->setAttribute('name', $methodName);
167
                    $methodElement->setAttribute('signature', $signature[1]);
168
                    $methodElement->setAttribute('line-rate', (string) $lineRate);
169
                    $methodElement->setAttribute('branch-rate', (string) $branchRate);
170
                    $methodElement->setAttribute('complexity', (string) $method['ccn']);
171
 
172
                    $methodLinesElement = $document->createElement('lines');
173
 
174
                    $methodElement->appendChild($methodLinesElement);
175
 
176
                    foreach (range($method['startLine'], $method['endLine']) as $line) {
177
                        if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
178
                            continue;
179
                        }
180
                        $methodLineElement = $document->createElement('line');
181
 
182
                        $methodLineElement->setAttribute('number', (string) $line);
183
                        $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
184
 
185
                        $methodLinesElement->appendChild($methodLineElement);
186
 
187
                        $classLineElement = $methodLineElement->cloneNode();
188
 
189
                        $classLinesElement->appendChild($classLineElement);
190
                    }
191
 
192
                    $methodsElement->appendChild($methodElement);
193
                }
194
            }
195
 
196
            if ($report->numberOfFunctions() === 0) {
197
                $packageElement->setAttribute('complexity', (string) $packageComplexity);
198
 
199
                continue;
200
            }
201
 
202
            $functionsComplexity      = 0;
203
            $functionsLinesValid      = 0;
204
            $functionsLinesCovered    = 0;
205
            $functionsBranchesValid   = 0;
206
            $functionsBranchesCovered = 0;
207
 
208
            $classElement = $document->createElement('class');
209
            $classElement->setAttribute('name', basename($item->pathAsString()));
210
            $classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
211
 
212
            $methodsElement = $document->createElement('methods');
213
 
214
            $classElement->appendChild($methodsElement);
215
 
216
            $classLinesElement = $document->createElement('lines');
217
 
218
            $classElement->appendChild($classLinesElement);
219
 
220
            $functions = $report->functions();
221
 
222
            foreach ($functions as $functionName => $function) {
223
                if ($function['executableLines'] === 0) {
224
                    continue;
225
                }
226
 
227
                $complexity += $function['ccn'];
228
                $packageComplexity += $function['ccn'];
229
                $functionsComplexity += $function['ccn'];
230
 
231
                $linesValid   = $function['executableLines'];
232
                $linesCovered = $function['executedLines'];
233
                $lineRate     = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
234
 
235
                $functionsLinesValid += $linesValid;
236
                $functionsLinesCovered += $linesCovered;
237
 
238
                $branchesValid   = $function['executableBranches'];
239
                $branchesCovered = $function['executedBranches'];
240
                $branchRate      = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
241
 
242
                $functionsBranchesValid += $branchesValid;
243
                $functionsBranchesCovered += $branchesValid;
244
 
245
                $methodElement = $document->createElement('method');
246
 
247
                $methodElement->setAttribute('name', $functionName);
248
                $methodElement->setAttribute('signature', $function['signature']);
249
                $methodElement->setAttribute('line-rate', (string) $lineRate);
250
                $methodElement->setAttribute('branch-rate', (string) $branchRate);
251
                $methodElement->setAttribute('complexity', (string) $function['ccn']);
252
 
253
                $methodLinesElement = $document->createElement('lines');
254
 
255
                $methodElement->appendChild($methodLinesElement);
256
 
257
                foreach (range($function['startLine'], $function['endLine']) as $line) {
258
                    if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
259
                        continue;
260
                    }
261
                    $methodLineElement = $document->createElement('line');
262
 
263
                    $methodLineElement->setAttribute('number', (string) $line);
264
                    $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
265
 
266
                    $methodLinesElement->appendChild($methodLineElement);
267
 
268
                    $classLineElement = $methodLineElement->cloneNode();
269
 
270
                    $classLinesElement->appendChild($classLineElement);
271
                }
272
 
273
                $methodsElement->appendChild($methodElement);
274
            }
275
 
276
            $packageElement->setAttribute('complexity', (string) $packageComplexity);
277
 
278
            if ($functionsLinesValid === 0) {
279
                continue;
280
            }
281
 
282
            $lineRate   = $functionsLinesCovered / $functionsLinesValid;
283
            $branchRate = $functionsBranchesValid === 0 ? 0 : ($functionsBranchesCovered / $functionsBranchesValid);
284
 
285
            $classElement->setAttribute('line-rate', (string) $lineRate);
286
            $classElement->setAttribute('branch-rate', (string) $branchRate);
287
            $classElement->setAttribute('complexity', (string) $functionsComplexity);
288
 
289
            $classesElement->appendChild($classElement);
290
        }
291
 
292
        $coverageElement->setAttribute('complexity', (string) $complexity);
293
 
294
        $buffer = $document->saveXML();
295
 
296
        if ($target !== null) {
297
            Filesystem::createDirectory(dirname($target));
298
 
299
            if (@file_put_contents($target, $buffer) === false) {
300
                throw new WriteOperationFailedException($target);
301
            }
302
        }
303
 
304
        return $buffer;
305
    }
306
}