3
* This file is part of the PHP_CodeCoverage package.
5
* (c) Sebastian Bergmann <sebastian@phpunit.de>
7
* For the full copyright and license information, please view the LICENSE
8
* file that was distributed with this source code.
13
* @package CodeCoverage
14
* @author Arne Blankerts <arne@blankerts.de>
15
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
16
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
17
* @link http://github.com/sebastianbergmann/php-code-coverage
18
* @since Class available since Release 2.0.0
20
class PHP_CodeCoverage_Report_XML
28
* @var PHP_CodeCoverage_Report_XML_Project
32
public function process(PHP_CodeCoverage $coverage, $target)
34
if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
35
$target .= DIRECTORY_SEPARATOR;
38
$this->target = $target;
39
$this->initTargetDirectory($target);
41
$report = $coverage->getReport();
43
$this->project = new PHP_CodeCoverage_Report_XML_Project(
44
$coverage->getReport()->getName()
47
$this->processTests($coverage->getTests());
48
$this->processDirectory($report, $this->project);
50
$index = $this->project->asDom();
51
$index->formatOutput = true;
52
$index->preserveWhiteSpace = false;
53
$index->save($target . '/index.xml');
56
private function initTargetDirectory($dir)
58
if (file_exists($dir)) {
60
throw new PHP_CodeCoverage_Exception(
61
"'$dir' exists but is not a directory."
65
if (!is_writable($dir)) {
66
throw new PHP_CodeCoverage_Exception(
67
"'$dir' exists but is not writable."
70
} elseif (!@mkdir($dir, 0777, true)) {
71
throw new PHP_CodeCoverage_Exception(
72
"'$dir' could not be created."
77
private function processDirectory(PHP_CodeCoverage_Report_Node_Directory $directory, PHP_CodeCoverage_Report_XML_Node $context)
79
$dirObject = $context->addDirectory($directory->getName());
81
$this->setTotals($directory, $dirObject->getTotals());
83
foreach ($directory as $node) {
84
if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
85
$this->processDirectory($node, $dirObject);
89
if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
90
$this->processFile($node, $dirObject);
94
throw new PHP_CodeCoverage_Exception(
95
'Unknown node type for XML report'
100
private function processFile(PHP_CodeCoverage_Report_Node_File $file, PHP_CodeCoverage_Report_XML_Directory $context)
102
$fileObject = $context->addFile(
104
$file->getId() . '.xml'
107
$this->setTotals($file, $fileObject->getTotals());
109
$fileReport = new PHP_CodeCoverage_Report_XML_File_Report(
113
$this->setTotals($file, $fileReport->getTotals());
115
foreach ($file->getClassesAndTraits() as $unit) {
116
$this->processUnit($unit, $fileReport);
119
foreach ($file->getFunctions() as $function) {
120
$this->processFunction($function, $fileReport);
123
foreach ($file->getCoverageData() as $line => $tests) {
124
if (!is_array($tests) || count($tests) == 0) {
128
$coverage = $fileReport->getLineCoverage($line);
130
foreach ($tests as $test) {
131
$coverage->addTest($test);
134
$coverage->finalize();
137
$this->initTargetDirectory(
138
$this->target . dirname($file->getId()) . '/'
141
$fileDom = $fileReport->asDom();
142
$fileDom->formatOutput = true;
143
$fileDom->preserveWhiteSpace = false;
144
$fileDom->save($this->target . $file->getId() . '.xml');
147
private function processUnit($unit, PHP_CodeCoverage_Report_XML_File_Report $report)
149
if (isset($unit['className'])) {
150
$unitObject = $report->getClassObject($unit['className']);
152
$unitObject = $report->getTraitObject($unit['traitName']);
155
$unitObject->setLines(
157
$unit['executableLines'],
158
$unit['executedLines']
161
$unitObject->setCrap($unit['crap']);
163
$unitObject->setPackage(
164
$unit['package']['fullPackage'],
165
$unit['package']['package'],
166
$unit['package']['subpackage'],
167
$unit['package']['category']
170
$unitObject->setNamespace($unit['package']['namespace']);
172
foreach ($unit['methods'] as $method) {
173
$methodObject = $unitObject->addMethod($method['methodName']);
174
$methodObject->setSignature($method['signature']);
175
$methodObject->setLines($method['startLine'], $method['endLine']);
176
$methodObject->setCrap($method['crap']);
177
$methodObject->setTotals(
178
$method['executableLines'],
179
$method['executedLines'],
185
private function processFunction($function, PHP_CodeCoverage_Report_XML_File_Report $report)
187
$functionObject = $report->getFunctionObject($function['functionName']);
189
$functionObject->setSignature($function['signature']);
190
$functionObject->setLines($function['startLine']);
191
$functionObject->setCrap($function['crap']);
192
$functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
195
private function processTests(array $tests)
197
$testsObject = $this->project->getTests();
199
foreach ($tests as $test => $result) {
200
if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
204
$testsObject->addTest($test, $result);
208
private function setTotals(PHP_CodeCoverage_Report_Node $node, PHP_CodeCoverage_Report_XML_Totals $totals)
210
$loc = $node->getLinesOfCode();
212
$totals->setNumLines(
216
$node->getNumExecutableLines(),
217
$node->getNumExecutedLines()
220
$totals->setNumClasses(
221
$node->getNumClasses(),
222
$node->getNumTestedClasses()
225
$totals->setNumTraits(
226
$node->getNumTraits(),
227
$node->getNumTestedTraits()
230
$totals->setNumMethods(
231
$node->getNumMethods(),
232
$node->getNumTestedMethods()
235
$totals->setNumFunctions(
236
$node->getNumFunctions(),
237
$node->getNumTestedFunctions()