annotate vendor/phpunit/php-code-coverage/src/Report/Clover.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@14 1 <?php
Chris@14 2 /*
Chris@14 3 * This file is part of the php-code-coverage package.
Chris@14 4 *
Chris@14 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@14 6 *
Chris@14 7 * For the full copyright and license information, please view the LICENSE
Chris@14 8 * file that was distributed with this source code.
Chris@14 9 */
Chris@14 10
Chris@14 11 namespace SebastianBergmann\CodeCoverage\Report;
Chris@14 12
Chris@14 13 use SebastianBergmann\CodeCoverage\CodeCoverage;
Chris@14 14 use SebastianBergmann\CodeCoverage\Node\File;
Chris@14 15 use SebastianBergmann\CodeCoverage\RuntimeException;
Chris@14 16
Chris@14 17 /**
Chris@14 18 * Generates a Clover XML logfile from a code coverage object.
Chris@14 19 */
Chris@14 20 class Clover
Chris@14 21 {
Chris@14 22 /**
Chris@14 23 * @param CodeCoverage $coverage
Chris@14 24 * @param string $target
Chris@14 25 * @param string $name
Chris@14 26 *
Chris@14 27 * @return string
Chris@14 28 *
Chris@14 29 * @throws \SebastianBergmann\CodeCoverage\RuntimeException
Chris@14 30 */
Chris@14 31 public function process(CodeCoverage $coverage, $target = null, $name = null)
Chris@14 32 {
Chris@14 33 $xmlDocument = new \DOMDocument('1.0', 'UTF-8');
Chris@14 34 $xmlDocument->formatOutput = true;
Chris@14 35
Chris@14 36 $xmlCoverage = $xmlDocument->createElement('coverage');
Chris@14 37 $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']);
Chris@14 38 $xmlDocument->appendChild($xmlCoverage);
Chris@14 39
Chris@14 40 $xmlProject = $xmlDocument->createElement('project');
Chris@14 41 $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']);
Chris@14 42
Chris@14 43 if (\is_string($name)) {
Chris@14 44 $xmlProject->setAttribute('name', $name);
Chris@14 45 }
Chris@14 46
Chris@14 47 $xmlCoverage->appendChild($xmlProject);
Chris@14 48
Chris@14 49 $packages = [];
Chris@14 50 $report = $coverage->getReport();
Chris@14 51 unset($coverage);
Chris@14 52
Chris@14 53 foreach ($report as $item) {
Chris@14 54 if (!$item instanceof File) {
Chris@14 55 continue;
Chris@14 56 }
Chris@14 57
Chris@14 58 /* @var File $item */
Chris@14 59
Chris@14 60 $xmlFile = $xmlDocument->createElement('file');
Chris@14 61 $xmlFile->setAttribute('name', $item->getPath());
Chris@14 62
Chris@14 63 $classes = $item->getClassesAndTraits();
Chris@14 64 $coverage = $item->getCoverageData();
Chris@14 65 $lines = [];
Chris@14 66 $namespace = 'global';
Chris@14 67
Chris@14 68 foreach ($classes as $className => $class) {
Chris@14 69 $classStatements = 0;
Chris@14 70 $coveredClassStatements = 0;
Chris@14 71 $coveredMethods = 0;
Chris@14 72 $classMethods = 0;
Chris@14 73
Chris@14 74 foreach ($class['methods'] as $methodName => $method) {
Chris@14 75 if ($method['executableLines'] == 0) {
Chris@14 76 continue;
Chris@14 77 }
Chris@14 78
Chris@14 79 $classMethods++;
Chris@14 80 $classStatements += $method['executableLines'];
Chris@14 81 $coveredClassStatements += $method['executedLines'];
Chris@14 82
Chris@14 83 if ($method['coverage'] == 100) {
Chris@14 84 $coveredMethods++;
Chris@14 85 }
Chris@14 86
Chris@14 87 $methodCount = 0;
Chris@14 88
Chris@14 89 foreach (\range($method['startLine'], $method['endLine']) as $line) {
Chris@14 90 if (isset($coverage[$line]) && ($coverage[$line] !== null)) {
Chris@14 91 $methodCount = \max($methodCount, \count($coverage[$line]));
Chris@14 92 }
Chris@14 93 }
Chris@14 94
Chris@14 95 $lines[$method['startLine']] = [
Chris@14 96 'ccn' => $method['ccn'],
Chris@14 97 'count' => $methodCount,
Chris@14 98 'crap' => $method['crap'],
Chris@14 99 'type' => 'method',
Chris@14 100 'visibility' => $method['visibility'],
Chris@14 101 'name' => $methodName
Chris@14 102 ];
Chris@14 103 }
Chris@14 104
Chris@14 105 if (!empty($class['package']['namespace'])) {
Chris@14 106 $namespace = $class['package']['namespace'];
Chris@14 107 }
Chris@14 108
Chris@14 109 $xmlClass = $xmlDocument->createElement('class');
Chris@14 110 $xmlClass->setAttribute('name', $className);
Chris@14 111 $xmlClass->setAttribute('namespace', $namespace);
Chris@14 112
Chris@14 113 if (!empty($class['package']['fullPackage'])) {
Chris@14 114 $xmlClass->setAttribute(
Chris@14 115 'fullPackage',
Chris@14 116 $class['package']['fullPackage']
Chris@14 117 );
Chris@14 118 }
Chris@14 119
Chris@14 120 if (!empty($class['package']['category'])) {
Chris@14 121 $xmlClass->setAttribute(
Chris@14 122 'category',
Chris@14 123 $class['package']['category']
Chris@14 124 );
Chris@14 125 }
Chris@14 126
Chris@14 127 if (!empty($class['package']['package'])) {
Chris@14 128 $xmlClass->setAttribute(
Chris@14 129 'package',
Chris@14 130 $class['package']['package']
Chris@14 131 );
Chris@14 132 }
Chris@14 133
Chris@14 134 if (!empty($class['package']['subpackage'])) {
Chris@14 135 $xmlClass->setAttribute(
Chris@14 136 'subpackage',
Chris@14 137 $class['package']['subpackage']
Chris@14 138 );
Chris@14 139 }
Chris@14 140
Chris@14 141 $xmlFile->appendChild($xmlClass);
Chris@14 142
Chris@14 143 $xmlMetrics = $xmlDocument->createElement('metrics');
Chris@14 144 $xmlMetrics->setAttribute('complexity', $class['ccn']);
Chris@14 145 $xmlMetrics->setAttribute('methods', $classMethods);
Chris@14 146 $xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
Chris@14 147 $xmlMetrics->setAttribute('conditionals', 0);
Chris@14 148 $xmlMetrics->setAttribute('coveredconditionals', 0);
Chris@14 149 $xmlMetrics->setAttribute('statements', $classStatements);
Chris@14 150 $xmlMetrics->setAttribute('coveredstatements', $coveredClassStatements);
Chris@14 151 $xmlMetrics->setAttribute('elements', $classMethods + $classStatements /* + conditionals */);
Chris@14 152 $xmlMetrics->setAttribute('coveredelements', $coveredMethods + $coveredClassStatements /* + coveredconditionals */);
Chris@14 153 $xmlClass->appendChild($xmlMetrics);
Chris@14 154 }
Chris@14 155
Chris@14 156 foreach ($coverage as $line => $data) {
Chris@14 157 if ($data === null || isset($lines[$line])) {
Chris@14 158 continue;
Chris@14 159 }
Chris@14 160
Chris@14 161 $lines[$line] = [
Chris@14 162 'count' => \count($data), 'type' => 'stmt'
Chris@14 163 ];
Chris@14 164 }
Chris@14 165
Chris@14 166 \ksort($lines);
Chris@14 167
Chris@14 168 foreach ($lines as $line => $data) {
Chris@14 169 $xmlLine = $xmlDocument->createElement('line');
Chris@14 170 $xmlLine->setAttribute('num', $line);
Chris@14 171 $xmlLine->setAttribute('type', $data['type']);
Chris@14 172
Chris@14 173 if (isset($data['name'])) {
Chris@14 174 $xmlLine->setAttribute('name', $data['name']);
Chris@14 175 }
Chris@14 176
Chris@14 177 if (isset($data['visibility'])) {
Chris@14 178 $xmlLine->setAttribute('visibility', $data['visibility']);
Chris@14 179 }
Chris@14 180
Chris@14 181 if (isset($data['ccn'])) {
Chris@14 182 $xmlLine->setAttribute('complexity', $data['ccn']);
Chris@14 183 }
Chris@14 184
Chris@14 185 if (isset($data['crap'])) {
Chris@14 186 $xmlLine->setAttribute('crap', $data['crap']);
Chris@14 187 }
Chris@14 188
Chris@14 189 $xmlLine->setAttribute('count', $data['count']);
Chris@14 190 $xmlFile->appendChild($xmlLine);
Chris@14 191 }
Chris@14 192
Chris@14 193 $linesOfCode = $item->getLinesOfCode();
Chris@14 194
Chris@14 195 $xmlMetrics = $xmlDocument->createElement('metrics');
Chris@14 196 $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
Chris@14 197 $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
Chris@14 198 $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits());
Chris@14 199 $xmlMetrics->setAttribute('methods', $item->getNumMethods());
Chris@14 200 $xmlMetrics->setAttribute('coveredmethods', $item->getNumTestedMethods());
Chris@14 201 $xmlMetrics->setAttribute('conditionals', 0);
Chris@14 202 $xmlMetrics->setAttribute('coveredconditionals', 0);
Chris@14 203 $xmlMetrics->setAttribute('statements', $item->getNumExecutableLines());
Chris@14 204 $xmlMetrics->setAttribute('coveredstatements', $item->getNumExecutedLines());
Chris@14 205 $xmlMetrics->setAttribute('elements', $item->getNumMethods() + $item->getNumExecutableLines() /* + conditionals */);
Chris@14 206 $xmlMetrics->setAttribute('coveredelements', $item->getNumTestedMethods() + $item->getNumExecutedLines() /* + coveredconditionals */);
Chris@14 207 $xmlFile->appendChild($xmlMetrics);
Chris@14 208
Chris@14 209 if ($namespace == 'global') {
Chris@14 210 $xmlProject->appendChild($xmlFile);
Chris@14 211 } else {
Chris@14 212 if (!isset($packages[$namespace])) {
Chris@14 213 $packages[$namespace] = $xmlDocument->createElement(
Chris@14 214 'package'
Chris@14 215 );
Chris@14 216
Chris@14 217 $packages[$namespace]->setAttribute('name', $namespace);
Chris@14 218 $xmlProject->appendChild($packages[$namespace]);
Chris@14 219 }
Chris@14 220
Chris@14 221 $packages[$namespace]->appendChild($xmlFile);
Chris@14 222 }
Chris@14 223 }
Chris@14 224
Chris@14 225 $linesOfCode = $report->getLinesOfCode();
Chris@14 226
Chris@14 227 $xmlMetrics = $xmlDocument->createElement('metrics');
Chris@14 228 $xmlMetrics->setAttribute('files', \count($report));
Chris@14 229 $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
Chris@14 230 $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
Chris@14 231 $xmlMetrics->setAttribute('classes', $report->getNumClassesAndTraits());
Chris@14 232 $xmlMetrics->setAttribute('methods', $report->getNumMethods());
Chris@14 233 $xmlMetrics->setAttribute('coveredmethods', $report->getNumTestedMethods());
Chris@14 234 $xmlMetrics->setAttribute('conditionals', 0);
Chris@14 235 $xmlMetrics->setAttribute('coveredconditionals', 0);
Chris@14 236 $xmlMetrics->setAttribute('statements', $report->getNumExecutableLines());
Chris@14 237 $xmlMetrics->setAttribute('coveredstatements', $report->getNumExecutedLines());
Chris@14 238 $xmlMetrics->setAttribute('elements', $report->getNumMethods() + $report->getNumExecutableLines() /* + conditionals */);
Chris@14 239 $xmlMetrics->setAttribute('coveredelements', $report->getNumTestedMethods() + $report->getNumExecutedLines() /* + coveredconditionals */);
Chris@14 240 $xmlProject->appendChild($xmlMetrics);
Chris@14 241
Chris@14 242 $buffer = $xmlDocument->saveXML();
Chris@14 243
Chris@14 244 if ($target !== null) {
Chris@14 245 if (!\is_dir(\dirname($target))) {
Chris@14 246 \mkdir(\dirname($target), 0777, true);
Chris@14 247 }
Chris@14 248
Chris@14 249 if (@\file_put_contents($target, $buffer) === false) {
Chris@14 250 throw new RuntimeException(
Chris@14 251 \sprintf(
Chris@14 252 'Could not write to "%s',
Chris@14 253 $target
Chris@14 254 )
Chris@14 255 );
Chris@14 256 }
Chris@14 257 }
Chris@14 258
Chris@14 259 return $buffer;
Chris@14 260 }
Chris@14 261 }