comparison vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2 /*
3 * This file is part of the PHP_CodeCoverage 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 /**
12 * @since Class available since Release 2.0.0
13 */
14 class PHP_CodeCoverage_Report_XML
15 {
16 /**
17 * @var string
18 */
19 private $target;
20
21 /**
22 * @var PHP_CodeCoverage_Report_XML_Project
23 */
24 private $project;
25
26 public function process(PHP_CodeCoverage $coverage, $target)
27 {
28 if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
29 $target .= DIRECTORY_SEPARATOR;
30 }
31
32 $this->target = $target;
33 $this->initTargetDirectory($target);
34
35 $report = $coverage->getReport();
36
37 $this->project = new PHP_CodeCoverage_Report_XML_Project(
38 $coverage->getReport()->getName()
39 );
40
41 $this->processTests($coverage->getTests());
42 $this->processDirectory($report, $this->project);
43
44 $index = $this->project->asDom();
45 $index->formatOutput = true;
46 $index->preserveWhiteSpace = false;
47 $index->save($target . '/index.xml');
48 }
49
50 private function initTargetDirectory($dir)
51 {
52 if (file_exists($dir)) {
53 if (!is_dir($dir)) {
54 throw new PHP_CodeCoverage_Exception(
55 "'$dir' exists but is not a directory."
56 );
57 }
58
59 if (!is_writable($dir)) {
60 throw new PHP_CodeCoverage_Exception(
61 "'$dir' exists but is not writable."
62 );
63 }
64 } elseif (!@mkdir($dir, 0777, true)) {
65 throw new PHP_CodeCoverage_Exception(
66 "'$dir' could not be created."
67 );
68 }
69 }
70
71 private function processDirectory(PHP_CodeCoverage_Report_Node_Directory $directory, PHP_CodeCoverage_Report_XML_Node $context)
72 {
73 $dirObject = $context->addDirectory($directory->getName());
74
75 $this->setTotals($directory, $dirObject->getTotals());
76
77 foreach ($directory as $node) {
78 if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
79 $this->processDirectory($node, $dirObject);
80 continue;
81 }
82
83 if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
84 $this->processFile($node, $dirObject);
85 continue;
86 }
87
88 throw new PHP_CodeCoverage_Exception(
89 'Unknown node type for XML report'
90 );
91 }
92 }
93
94 private function processFile(PHP_CodeCoverage_Report_Node_File $file, PHP_CodeCoverage_Report_XML_Directory $context)
95 {
96 $fileObject = $context->addFile(
97 $file->getName(),
98 $file->getId() . '.xml'
99 );
100
101 $this->setTotals($file, $fileObject->getTotals());
102
103 $fileReport = new PHP_CodeCoverage_Report_XML_File_Report(
104 $file->getName()
105 );
106
107 $this->setTotals($file, $fileReport->getTotals());
108
109 foreach ($file->getClassesAndTraits() as $unit) {
110 $this->processUnit($unit, $fileReport);
111 }
112
113 foreach ($file->getFunctions() as $function) {
114 $this->processFunction($function, $fileReport);
115 }
116
117 foreach ($file->getCoverageData() as $line => $tests) {
118 if (!is_array($tests) || count($tests) == 0) {
119 continue;
120 }
121
122 $coverage = $fileReport->getLineCoverage($line);
123
124 foreach ($tests as $test) {
125 $coverage->addTest($test);
126 }
127
128 $coverage->finalize();
129 }
130
131 $this->initTargetDirectory(
132 $this->target . dirname($file->getId()) . '/'
133 );
134
135 $fileDom = $fileReport->asDom();
136 $fileDom->formatOutput = true;
137 $fileDom->preserveWhiteSpace = false;
138 $fileDom->save($this->target . $file->getId() . '.xml');
139 }
140
141 private function processUnit($unit, PHP_CodeCoverage_Report_XML_File_Report $report)
142 {
143 if (isset($unit['className'])) {
144 $unitObject = $report->getClassObject($unit['className']);
145 } else {
146 $unitObject = $report->getTraitObject($unit['traitName']);
147 }
148
149 $unitObject->setLines(
150 $unit['startLine'],
151 $unit['executableLines'],
152 $unit['executedLines']
153 );
154
155 $unitObject->setCrap($unit['crap']);
156
157 $unitObject->setPackage(
158 $unit['package']['fullPackage'],
159 $unit['package']['package'],
160 $unit['package']['subpackage'],
161 $unit['package']['category']
162 );
163
164 $unitObject->setNamespace($unit['package']['namespace']);
165
166 foreach ($unit['methods'] as $method) {
167 $methodObject = $unitObject->addMethod($method['methodName']);
168 $methodObject->setSignature($method['signature']);
169 $methodObject->setLines($method['startLine'], $method['endLine']);
170 $methodObject->setCrap($method['crap']);
171 $methodObject->setTotals(
172 $method['executableLines'],
173 $method['executedLines'],
174 $method['coverage']
175 );
176 }
177 }
178
179 private function processFunction($function, PHP_CodeCoverage_Report_XML_File_Report $report)
180 {
181 $functionObject = $report->getFunctionObject($function['functionName']);
182
183 $functionObject->setSignature($function['signature']);
184 $functionObject->setLines($function['startLine']);
185 $functionObject->setCrap($function['crap']);
186 $functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
187 }
188
189 private function processTests(array $tests)
190 {
191 $testsObject = $this->project->getTests();
192
193 foreach ($tests as $test => $result) {
194 if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
195 continue;
196 }
197
198 $testsObject->addTest($test, $result);
199 }
200 }
201
202 private function setTotals(PHP_CodeCoverage_Report_Node $node, PHP_CodeCoverage_Report_XML_Totals $totals)
203 {
204 $loc = $node->getLinesOfCode();
205
206 $totals->setNumLines(
207 $loc['loc'],
208 $loc['cloc'],
209 $loc['ncloc'],
210 $node->getNumExecutableLines(),
211 $node->getNumExecutedLines()
212 );
213
214 $totals->setNumClasses(
215 $node->getNumClasses(),
216 $node->getNumTestedClasses()
217 );
218
219 $totals->setNumTraits(
220 $node->getNumTraits(),
221 $node->getNumTestedTraits()
222 );
223
224 $totals->setNumMethods(
225 $node->getNumMethods(),
226 $node->getNumTestedMethods()
227 );
228
229 $totals->setNumFunctions(
230 $node->getNumFunctions(),
231 $node->getNumTestedFunctions()
232 );
233 }
234 }