comparison vendor/phpunit/php-code-coverage/src/Report/Crap4j.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents
children
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
1 <?php
2 /*
3 * This file is part of the php-code-coverage package.
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
11 namespace SebastianBergmann\CodeCoverage\Report;
12
13 use SebastianBergmann\CodeCoverage\CodeCoverage;
14 use SebastianBergmann\CodeCoverage\InvalidArgumentException;
15 use SebastianBergmann\CodeCoverage\Node\File;
16 use SebastianBergmann\CodeCoverage\RuntimeException;
17
18 class Crap4j
19 {
20 /**
21 * @var int
22 */
23 private $threshold;
24
25 /**
26 * @param int $threshold
27 */
28 public function __construct($threshold = 30)
29 {
30 if (!\is_int($threshold)) {
31 throw InvalidArgumentException::create(
32 1,
33 'integer'
34 );
35 }
36
37 $this->threshold = $threshold;
38 }
39
40 /**
41 * @param CodeCoverage $coverage
42 * @param string $target
43 * @param string $name
44 *
45 * @return string
46 *
47 * @throws \SebastianBergmann\CodeCoverage\RuntimeException
48 */
49 public function process(CodeCoverage $coverage, $target = null, $name = null)
50 {
51 $document = new \DOMDocument('1.0', 'UTF-8');
52 $document->formatOutput = true;
53
54 $root = $document->createElement('crap_result');
55 $document->appendChild($root);
56
57 $project = $document->createElement('project', \is_string($name) ? $name : '');
58 $root->appendChild($project);
59 $root->appendChild($document->createElement('timestamp', \date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
60
61 $stats = $document->createElement('stats');
62 $methodsNode = $document->createElement('methods');
63
64 $report = $coverage->getReport();
65 unset($coverage);
66
67 $fullMethodCount = 0;
68 $fullCrapMethodCount = 0;
69 $fullCrapLoad = 0;
70 $fullCrap = 0;
71
72 foreach ($report as $item) {
73 $namespace = 'global';
74
75 if (!$item instanceof File) {
76 continue;
77 }
78
79 $file = $document->createElement('file');
80 $file->setAttribute('name', $item->getPath());
81
82 $classes = $item->getClassesAndTraits();
83
84 foreach ($classes as $className => $class) {
85 foreach ($class['methods'] as $methodName => $method) {
86 $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
87
88 $fullCrap += $method['crap'];
89 $fullCrapLoad += $crapLoad;
90 $fullMethodCount++;
91
92 if ($method['crap'] >= $this->threshold) {
93 $fullCrapMethodCount++;
94 }
95
96 $methodNode = $document->createElement('method');
97
98 if (!empty($class['package']['namespace'])) {
99 $namespace = $class['package']['namespace'];
100 }
101
102 $methodNode->appendChild($document->createElement('package', $namespace));
103 $methodNode->appendChild($document->createElement('className', $className));
104 $methodNode->appendChild($document->createElement('methodName', $methodName));
105 $methodNode->appendChild($document->createElement('methodSignature', \htmlspecialchars($method['signature'])));
106 $methodNode->appendChild($document->createElement('fullMethod', \htmlspecialchars($method['signature'])));
107 $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
108 $methodNode->appendChild($document->createElement('complexity', $method['ccn']));
109 $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
110 $methodNode->appendChild($document->createElement('crapLoad', \round($crapLoad)));
111
112 $methodsNode->appendChild($methodNode);
113 }
114 }
115 }
116
117 $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
118 $stats->appendChild($document->createElement('methodCount', $fullMethodCount));
119 $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
120 $stats->appendChild($document->createElement('crapLoad', \round($fullCrapLoad)));
121 $stats->appendChild($document->createElement('totalCrap', $fullCrap));
122
123 if ($fullMethodCount > 0) {
124 $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
125 } else {
126 $crapMethodPercent = 0;
127 }
128
129 $stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent));
130
131 $root->appendChild($stats);
132 $root->appendChild($methodsNode);
133
134 $buffer = $document->saveXML();
135
136 if ($target !== null) {
137 if (!\is_dir(\dirname($target))) {
138 \mkdir(\dirname($target), 0777, true);
139 }
140
141 if (@\file_put_contents($target, $buffer) === false) {
142 throw new RuntimeException(
143 \sprintf(
144 'Could not write to "%s',
145 $target
146 )
147 );
148 }
149 }
150
151 return $buffer;
152 }
153
154 /**
155 * @param float $crapValue
156 * @param int $cyclomaticComplexity
157 * @param float $coveragePercent
158 *
159 * @return float
160 */
161 private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
162 {
163 $crapLoad = 0;
164
165 if ($crapValue >= $this->threshold) {
166 $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
167 $crapLoad += $cyclomaticComplexity / $this->threshold;
168 }
169
170 return $crapLoad;
171 }
172
173 /**
174 * @param float $value
175 *
176 * @return float
177 */
178 private function roundValue($value)
179 {
180 return \round($value, 2);
181 }
182 }