Skip to content

Commit e8160d8

Browse files
committed
Cobertura report conform document definition and added metrics
1 parent 858b0f2 commit e8160d8

12 files changed

+811
-304
lines changed

src/Report/Cobertura.php

+2-267
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,11 @@
99
*/
1010
namespace SebastianBergmann\CodeCoverage\Report;
1111

12-
use function count;
1312
use function dirname;
1413
use function file_put_contents;
15-
use function range;
16-
use function time;
17-
use DOMImplementation;
1814
use SebastianBergmann\CodeCoverage\CodeCoverage;
1915
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
20-
use SebastianBergmann\CodeCoverage\Node\File;
16+
use SebastianBergmann\CodeCoverage\Report\Cobertura\CoberturaCoverage;
2117
use SebastianBergmann\CodeCoverage\Util\Filesystem;
2218

2319
final class Cobertura
@@ -27,268 +23,7 @@ final class Cobertura
2723
*/
2824
public function process(CodeCoverage $coverage, ?string $target = null): string
2925
{
30-
$time = (string) time();
31-
32-
$report = $coverage->getReport();
33-
34-
$implementation = new DOMImplementation;
35-
36-
$documentType = $implementation->createDocumentType(
37-
'coverage',
38-
'',
39-
'http://cobertura.sourceforge.net/xml/coverage-04.dtd'
40-
);
41-
42-
$document = $implementation->createDocument('', '', $documentType);
43-
$document->xmlVersion = '1.0';
44-
$document->encoding = 'UTF-8';
45-
$document->formatOutput = true;
46-
47-
$coverageElement = $document->createElement('coverage');
48-
49-
$linesValid = $report->numberOfExecutableLines();
50-
$linesCovered = $report->numberOfExecutedLines();
51-
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
52-
$coverageElement->setAttribute('line-rate', (string) $lineRate);
53-
54-
$branchesValid = $report->numberOfExecutableBranches();
55-
$branchesCovered = $report->numberOfExecutedBranches();
56-
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
57-
$coverageElement->setAttribute('branch-rate', (string) $branchRate);
58-
59-
$coverageElement->setAttribute('lines-covered', (string) $report->numberOfExecutedLines());
60-
$coverageElement->setAttribute('lines-valid', (string) $report->numberOfExecutableLines());
61-
$coverageElement->setAttribute('branches-covered', (string) $report->numberOfExecutedBranches());
62-
$coverageElement->setAttribute('branches-valid', (string) $report->numberOfExecutableBranches());
63-
$coverageElement->setAttribute('complexity', '');
64-
$coverageElement->setAttribute('version', '0.4');
65-
$coverageElement->setAttribute('timestamp', $time);
66-
67-
$document->appendChild($coverageElement);
68-
69-
$sourcesElement = $document->createElement('sources');
70-
$coverageElement->appendChild($sourcesElement);
71-
72-
$sourceElement = $document->createElement('source', $report->pathAsString());
73-
$sourcesElement->appendChild($sourceElement);
74-
75-
$packagesElement = $document->createElement('packages');
76-
$coverageElement->appendChild($packagesElement);
77-
78-
$complexity = 0;
79-
80-
foreach ($report as $item) {
81-
if (!$item instanceof File) {
82-
continue;
83-
}
84-
85-
$packageElement = $document->createElement('package');
86-
$packageComplexity = 0;
87-
88-
$packageElement->setAttribute('name', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
89-
90-
$linesValid = $item->numberOfExecutableLines();
91-
$linesCovered = $item->numberOfExecutedLines();
92-
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
93-
94-
$packageElement->setAttribute('line-rate', (string) $lineRate);
95-
96-
$branchesValid = $item->numberOfExecutableBranches();
97-
$branchesCovered = $item->numberOfExecutedBranches();
98-
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
99-
100-
$packageElement->setAttribute('branch-rate', (string) $branchRate);
101-
102-
$packageElement->setAttribute('complexity', '');
103-
$packagesElement->appendChild($packageElement);
104-
105-
$classesElement = $document->createElement('classes');
106-
107-
$packageElement->appendChild($classesElement);
108-
109-
$classes = $item->classesAndTraits();
110-
$coverageData = $item->lineCoverageData();
111-
112-
foreach ($classes as $className => $class) {
113-
$complexity += $class['ccn'];
114-
$packageComplexity += $class['ccn'];
115-
116-
if (!empty($class['package']['namespace'])) {
117-
$className = $class['package']['namespace'] . '\\' . $className;
118-
}
119-
120-
$linesValid = $class['executableLines'];
121-
$linesCovered = $class['executedLines'];
122-
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
123-
124-
$branchesValid = $class['executableBranches'];
125-
$branchesCovered = $class['executedBranches'];
126-
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
127-
128-
$classElement = $document->createElement('class');
129-
130-
$classElement->setAttribute('name', $className);
131-
$classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
132-
$classElement->setAttribute('line-rate', (string) $lineRate);
133-
$classElement->setAttribute('branch-rate', (string) $branchRate);
134-
$classElement->setAttribute('complexity', (string) $class['ccn']);
135-
136-
$classesElement->appendChild($classElement);
137-
138-
$methodsElement = $document->createElement('methods');
139-
140-
$classElement->appendChild($methodsElement);
141-
142-
$classLinesElement = $document->createElement('lines');
143-
144-
$classElement->appendChild($classLinesElement);
145-
146-
foreach ($class['methods'] as $methodName => $method) {
147-
if ($method['executableLines'] === 0) {
148-
continue;
149-
}
150-
151-
preg_match("/\((.*?)\)/", $method['signature'], $signature);
152-
153-
$linesValid = $method['executableLines'];
154-
$linesCovered = $method['executedLines'];
155-
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
156-
157-
$branchesValid = $method['executableBranches'];
158-
$branchesCovered = $method['executedBranches'];
159-
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
160-
161-
$methodElement = $document->createElement('method');
162-
163-
$methodElement->setAttribute('name', $methodName);
164-
$methodElement->setAttribute('signature', $signature[1]);
165-
$methodElement->setAttribute('line-rate', (string) $lineRate);
166-
$methodElement->setAttribute('branch-rate', (string) $branchRate);
167-
$methodElement->setAttribute('complexity', (string) $method['ccn']);
168-
169-
$methodLinesElement = $document->createElement('lines');
170-
171-
$methodElement->appendChild($methodLinesElement);
172-
173-
foreach (range($method['startLine'], $method['endLine']) as $line) {
174-
if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
175-
continue;
176-
}
177-
$methodLineElement = $document->createElement('line');
178-
179-
$methodLineElement->setAttribute('number', (string) $line);
180-
$methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
181-
182-
$methodLinesElement->appendChild($methodLineElement);
183-
184-
$classLineElement = $methodLineElement->cloneNode();
185-
186-
$classLinesElement->appendChild($classLineElement);
187-
}
188-
189-
$methodsElement->appendChild($methodElement);
190-
}
191-
}
192-
193-
if ($report->numberOfFunctions() === 0) {
194-
$packageElement->setAttribute('complexity', (string) $packageComplexity);
195-
196-
continue;
197-
}
198-
199-
$functionsComplexity = 0;
200-
$functionsLinesValid = 0;
201-
$functionsLinesCovered = 0;
202-
$functionsBranchesValid = 0;
203-
$functionsBranchesCovered = 0;
204-
205-
$classElement = $document->createElement('class');
206-
$classElement->setAttribute('name', basename($item->pathAsString()));
207-
$classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
208-
209-
$methodsElement = $document->createElement('methods');
210-
211-
$classElement->appendChild($methodsElement);
212-
213-
$classLinesElement = $document->createElement('lines');
214-
215-
$classElement->appendChild($classLinesElement);
216-
217-
$functions = $report->functions();
218-
219-
foreach ($functions as $functionName => $function) {
220-
if ($function['executableLines'] === 0) {
221-
continue;
222-
}
223-
224-
$complexity += $function['ccn'];
225-
$packageComplexity += $function['ccn'];
226-
$functionsComplexity += $function['ccn'];
227-
228-
$linesValid = $function['executableLines'];
229-
$linesCovered = $function['executedLines'];
230-
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
231-
232-
$functionsLinesValid += $linesValid;
233-
$functionsLinesCovered += $linesCovered;
234-
235-
$branchesValid = $function['executableBranches'];
236-
$branchesCovered = $function['executedBranches'];
237-
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
238-
239-
$functionsBranchesValid += $branchesValid;
240-
$functionsBranchesCovered += $branchesValid;
241-
242-
$methodElement = $document->createElement('method');
243-
244-
$methodElement->setAttribute('name', $functionName);
245-
$methodElement->setAttribute('signature', $function['signature']);
246-
$methodElement->setAttribute('line-rate', (string) $lineRate);
247-
$methodElement->setAttribute('branch-rate', (string) $branchRate);
248-
$methodElement->setAttribute('complexity', (string) $function['ccn']);
249-
250-
$methodLinesElement = $document->createElement('lines');
251-
252-
$methodElement->appendChild($methodLinesElement);
253-
254-
foreach (range($function['startLine'], $function['endLine']) as $line) {
255-
if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
256-
continue;
257-
}
258-
$methodLineElement = $document->createElement('line');
259-
260-
$methodLineElement->setAttribute('number', (string) $line);
261-
$methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
262-
263-
$methodLinesElement->appendChild($methodLineElement);
264-
265-
$classLineElement = $methodLineElement->cloneNode();
266-
267-
$classLinesElement->appendChild($classLineElement);
268-
}
269-
270-
$methodsElement->appendChild($methodElement);
271-
}
272-
273-
$packageElement->setAttribute('complexity', (string) $packageComplexity);
274-
275-
if ($functionsLinesValid === 0) {
276-
continue;
277-
}
278-
279-
$lineRate = $functionsLinesCovered / $functionsLinesValid;
280-
$branchRate = $functionsBranchesValid === 0 ? 0 : ($functionsBranchesCovered / $functionsBranchesValid);
281-
282-
$classElement->setAttribute('line-rate', (string) $lineRate);
283-
$classElement->setAttribute('branch-rate', (string) $branchRate);
284-
$classElement->setAttribute('complexity', (string) $functionsComplexity);
285-
286-
$classesElement->appendChild($classElement);
287-
}
288-
289-
$coverageElement->setAttribute('complexity', (string) $complexity);
290-
291-
$buffer = $document->saveXML();
26+
$buffer = CoberturaCoverage::create($coverage->getReport())->generateDocument()->saveXML();
29227

29328
if ($target !== null) {
29429
Filesystem::createDirectory(dirname($target));

0 commit comments

Comments
 (0)