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 date;
13
use function dirname;
14
use function file_put_contents;
15
use function htmlspecialchars;
16
use function is_string;
17
use function round;
18
use DOMDocument;
19
use SebastianBergmann\CodeCoverage\CodeCoverage;
20
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
21
use SebastianBergmann\CodeCoverage\Node\File;
22
use SebastianBergmann\CodeCoverage\Util\Filesystem;
23
 
24
final class Crap4j
25
{
26
    /**
27
     * @var int
28
     */
29
    private $threshold;
30
 
31
    public function __construct(int $threshold = 30)
32
    {
33
        $this->threshold = $threshold;
34
    }
35
 
36
    /**
37
     * @throws WriteOperationFailedException
38
     */
39
    public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
40
    {
41
        $document               = new DOMDocument('1.0', 'UTF-8');
42
        $document->formatOutput = true;
43
 
44
        $root = $document->createElement('crap_result');
45
        $document->appendChild($root);
46
 
47
        $project = $document->createElement('project', is_string($name) ? $name : '');
48
        $root->appendChild($project);
49
        $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s')));
50
 
51
        $stats       = $document->createElement('stats');
52
        $methodsNode = $document->createElement('methods');
53
 
54
        $report = $coverage->getReport();
55
        unset($coverage);
56
 
57
        $fullMethodCount     = 0;
58
        $fullCrapMethodCount = 0;
59
        $fullCrapLoad        = 0;
60
        $fullCrap            = 0;
61
 
62
        foreach ($report as $item) {
63
            $namespace = 'global';
64
 
65
            if (!$item instanceof File) {
66
                continue;
67
            }
68
 
69
            $file = $document->createElement('file');
70
            $file->setAttribute('name', $item->pathAsString());
71
 
72
            $classes = $item->classesAndTraits();
73
 
74
            foreach ($classes as $className => $class) {
75
                foreach ($class['methods'] as $methodName => $method) {
76
                    $crapLoad = $this->crapLoad((float) $method['crap'], $method['ccn'], $method['coverage']);
77
 
78
                    $fullCrap += $method['crap'];
79
                    $fullCrapLoad += $crapLoad;
80
                    $fullMethodCount++;
81
 
82
                    if ($method['crap'] >= $this->threshold) {
83
                        $fullCrapMethodCount++;
84
                    }
85
 
86
                    $methodNode = $document->createElement('method');
87
 
88
                    if (!empty($class['namespace'])) {
89
                        $namespace = $class['namespace'];
90
                    }
91
 
92
                    $methodNode->appendChild($document->createElement('package', $namespace));
93
                    $methodNode->appendChild($document->createElement('className', $className));
94
                    $methodNode->appendChild($document->createElement('methodName', $methodName));
95
                    $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
96
                    $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
97
                    $methodNode->appendChild($document->createElement('crap', (string) $this->roundValue((float) $method['crap'])));
98
                    $methodNode->appendChild($document->createElement('complexity', (string) $method['ccn']));
99
                    $methodNode->appendChild($document->createElement('coverage', (string) $this->roundValue($method['coverage'])));
100
                    $methodNode->appendChild($document->createElement('crapLoad', (string) round($crapLoad)));
101
 
102
                    $methodsNode->appendChild($methodNode);
103
                }
104
            }
105
        }
106
 
107
        $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
108
        $stats->appendChild($document->createElement('methodCount', (string) $fullMethodCount));
109
        $stats->appendChild($document->createElement('crapMethodCount', (string) $fullCrapMethodCount));
110
        $stats->appendChild($document->createElement('crapLoad', (string) round($fullCrapLoad)));
111
        $stats->appendChild($document->createElement('totalCrap', (string) $fullCrap));
112
 
113
        $crapMethodPercent = 0;
114
 
115
        if ($fullMethodCount > 0) {
116
            $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
117
        }
118
 
119
        $stats->appendChild($document->createElement('crapMethodPercent', (string) $crapMethodPercent));
120
 
121
        $root->appendChild($stats);
122
        $root->appendChild($methodsNode);
123
 
124
        $buffer = $document->saveXML();
125
 
126
        if ($target !== null) {
127
            Filesystem::createDirectory(dirname($target));
128
 
129
            if (@file_put_contents($target, $buffer) === false) {
130
                throw new WriteOperationFailedException($target);
131
            }
132
        }
133
 
134
        return $buffer;
135
    }
136
 
137
    private function crapLoad(float $crapValue, int $cyclomaticComplexity, float $coveragePercent): float
138
    {
139
        $crapLoad = 0;
140
 
141
        if ($crapValue >= $this->threshold) {
142
            $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
143
            $crapLoad += $cyclomaticComplexity / $this->threshold;
144
        }
145
 
146
        return $crapLoad;
147
    }
148
 
149
    private function roundValue(float $value): float
150
    {
151
        return round($value, 2);
152
    }
153
}