Version 1
[yaffs-website] / vendor / phpunit / php-code-coverage / src / CodeCoverage / Report / XML.php
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 }