Skip to content

Commit 1a60bae

Browse files
authored
Merge pull request #39 from anne-gaelle123inkt/master
Add support for multiple coverage files passed as argument
2 parents cbd78c5 + 741c582 commit 1a60bae

22 files changed

+472
-243
lines changed

src/Lib/IO/MetricsFactory.php

+68-11
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,32 @@ class MetricsFactory
1919
*
2020
* @param DOMDocument[] $documents
2121
*
22-
* @return FileMetric[]
22+
* @return array<string, FileMetric>
2323
*/
2424
public static function getFilesMetrics(array $documents): array
2525
{
26+
/** @var array<string, FileMetric> $metrics */
2627
$metrics = [];
2728

2829
foreach ($documents as $document) {
2930
$foundMetrics = self::getFileMetrics($document);
3031
foreach ($foundMetrics as $metric) {
31-
if (isset($metrics[$metric->getFilepath()])) {
32-
$previousMetric = $metrics[$metric->getFilepath()];
33-
if ($previousMetric->getCoverage() > $metric->getCoverage()) {
34-
continue;
35-
}
32+
$existingMetric = $metrics[$metric->getFilepath()] ?? null;
33+
if ($existingMetric === null) {
34+
$metrics[$metric->getFilepath()] = $metric;
35+
continue;
3636
}
37-
$metrics[$metric->getFilepath()] = $metric;
37+
38+
if ($existingMetric->getCoverage() === 100.0) {
39+
continue;
40+
}
41+
42+
if ($metric->getCoverage() === 100.0) {
43+
$metrics[$metric->getFilepath()] = $metric;
44+
continue;
45+
}
46+
47+
self::mergeFileMetrics($existingMetric, $metric);
3848
}
3949
}
4050

@@ -44,7 +54,7 @@ public static function getFilesMetrics(array $documents): array
4454
/**
4555
* Get metrics information from coverage.xml file
4656
*
47-
* @return FileMetric[]
57+
* @return array<string, FileMetric>
4858
*/
4959
public static function getFileMetrics(DOMDocument $document): array
5060
{
@@ -72,14 +82,16 @@ public static function getFileMetrics(DOMDocument $document): array
7282
// gather metrics per method
7383
$methodMetrics = self::getMethodMetrics($xpath, $parentNode);
7484

75-
$metrics[] = new FileMetric($filename, $coveragePercentage, $methodMetrics);
85+
$coveredStatements = self::getCoveredStatements($xpath, $parentNode);
86+
87+
$metrics[$filename] = new FileMetric($filename, $statements, $coveragePercentage, $methodMetrics, $coveredStatements);
7688
}
7789

7890
return $metrics;
7991
}
8092

8193
/**
82-
* @return MethodMetric[]
94+
* @return array<string, MethodMetric>
8395
*/
8496
public static function getMethodMetrics(DOMXPath $xpath, DOMNode $fileNode): array
8597
{
@@ -95,9 +107,54 @@ public static function getMethodMetrics(DOMXPath $xpath, DOMNode $fileNode): arr
95107
$lineNumber = (int)XMLUtil::getAttribute($methodNode, 'num');
96108
$count = (int)XMLUtil::getAttribute($methodNode, 'count');
97109

98-
$metrics[] = new MethodMetric($methodName, $lineNumber, $count);
110+
$metrics[$methodName] = new MethodMetric($methodName, $lineNumber, $count);
99111
}
100112

101113
return $metrics;
102114
}
115+
116+
/**
117+
* @return int[]
118+
*/
119+
private static function getCoveredStatements(DOMXPath $xpath, DOMNode $fileNode): array
120+
{
121+
$statementNodes = $xpath->query('line[@type="stmt"]', $fileNode);
122+
if ($statementNodes === false || count($statementNodes) === 0) {
123+
return [];
124+
}
125+
126+
$coveredStatements = [];
127+
foreach ($statementNodes as $node) {
128+
$count = (int)XMLUtil::getAttribute($node, 'count');
129+
if ($count === 0) {
130+
continue;
131+
}
132+
$lineNumber = (int)XMLUtil::getAttribute($node, 'num');
133+
134+
$coveredStatements[] = $lineNumber;
135+
}
136+
137+
return $coveredStatements;
138+
}
139+
140+
private static function mergeFileMetrics(FileMetric $existingMetric, FileMetric $metric): void
141+
{
142+
$existingMetricMethods = $existingMetric->getMethods();
143+
$metricMethods = $metric->getMethods();
144+
foreach ($metricMethods as $methodName => $methodMetric) {
145+
if (isset($existingMetricMethods[$methodName]) === false || $existingMetricMethods[$methodName]->getCount() < $methodMetric->getCount()) {
146+
$existingMetricMethods[$methodName] = $methodMetric;
147+
}
148+
}
149+
150+
$existingCovered = $existingMetric->getCoveredStatements();
151+
$metricCovered = $metric->getCoveredStatements();
152+
$existingMetric->setCoveredStatements(array_merge($existingCovered, array_diff($metricCovered, $existingCovered)));
153+
$existingMetric->setMethods($existingMetricMethods);
154+
$coveragePercentage = round(
155+
count($existingMetric->getCoveredStatements()) / $existingMetric->getStatements() * 100,
156+
self::COVERAGE_PERCENTAGE_PRECISION
157+
);
158+
$existingMetric->setCoverage($coveragePercentage);
159+
}
103160
}

src/Model/Metric/FileMetric.php

+50-12
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,74 @@
55

66
class FileMetric
77
{
8-
private string $filepath;
9-
private float $coverage;
10-
/** @var MethodMetric[] */
11-
private array $methods;
12-
138
/**
14-
* @param MethodMetric[] $methods
9+
* @param array<string, MethodMetric> $methods
10+
* @param int[] $coveredStatements
1511
*/
16-
public function __construct(string $filepath, float $coverage, array $methods)
17-
{
18-
$this->filepath = $filepath;
19-
$this->coverage = $coverage;
20-
$this->methods = $methods;
12+
public function __construct(
13+
private readonly string $filepath,
14+
private readonly int $statements,
15+
private float $coverage,
16+
private array $methods,
17+
private array $coveredStatements
18+
) {
2119
}
2220

2321
public function getFilepath(): string
2422
{
2523
return $this->filepath;
2624
}
2725

26+
public function getStatements(): int
27+
{
28+
return $this->statements;
29+
}
30+
2831
public function getCoverage(): float
2932
{
3033
return $this->coverage;
3134
}
3235

36+
public function setCoverage(float $coverage): self
37+
{
38+
$this->coverage = $coverage;
39+
40+
return $this;
41+
}
42+
3343
/**
34-
* @return MethodMetric[]
44+
* @return array<string, MethodMetric>
3545
*/
3646
public function getMethods(): array
3747
{
3848
return $this->methods;
3949
}
50+
51+
/**
52+
* @param array<string, MethodMetric> $methods
53+
*/
54+
public function setMethods(array $methods): self
55+
{
56+
$this->methods = $methods;
57+
58+
return $this;
59+
}
60+
61+
/**
62+
* @return int[] $coveredStatements
63+
*/
64+
public function getCoveredStatements(): array
65+
{
66+
return $this->coveredStatements;
67+
}
68+
69+
/**
70+
* @param int[] $coveredStatements
71+
*/
72+
public function setCoveredStatements(array $coveredStatements): self
73+
{
74+
$this->coveredStatements = $coveredStatements;
75+
76+
return $this;
77+
}
4078
}

src/Model/Metric/MethodMetric.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
class MethodMetric
77
{
88
private string $methodName;
9-
private int $lineNumber;
10-
private int $count;
9+
private int $lineNumber;
10+
private int $count;
1111

1212
public function __construct(string $methodName, int $lineNumber, int $count)
1313
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<checkstyle version="3.5.5"/>

tests/Functional/Command/InspectCommand/Data/coverage-custom.xml

-97
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<coverage generated="1598702199">
3+
<project timestamp="1598702199">
4+
<!-- coverage test 1 90% -->
5+
<file name="/home/workspace/test\case/result-90.php">
6+
<line num="1" type="method" name="methodName" count="1"/>
7+
<line num="2" type="stmt" count="1"/>
8+
<line num="3" type="stmt" count="1"/>
9+
<line num="4" type="stmt" count="1"/>
10+
<line num="5" type="stmt" count="1"/>
11+
<line num="6" type="stmt" count="1"/>
12+
<line num="7" type="stmt" count="1"/>
13+
<line num="8" type="stmt" count="0"/>
14+
<line num="9" type="stmt" count="1"/>
15+
<line num="10" type="stmt" count="1"/>
16+
<metrics loc="11" ncloc="11" statements="10" coveredstatements="9"/>
17+
</file>
18+
<!-- coverage test 2 90% -->
19+
<file name="/home/workspace/test\case/result-100.php">
20+
<line num="1" type="method" name="methodName" count="1"/>
21+
<line num="2" type="stmt" count="1"/>
22+
<line num="3" type="stmt" count="1"/>
23+
<line num="4" type="stmt" count="1"/>
24+
<line num="5" type="stmt" count="1"/>
25+
<line num="6" type="stmt" count="1"/>
26+
<line num="7" type="stmt" count="1"/>
27+
<line num="8" type="stmt" count="0"/>
28+
<line num="9" type="stmt" count="1"/>
29+
<line num="10" type="stmt" count="1"/>
30+
<metrics loc="11" ncloc="11" statements="10" coveredstatements="9"/>
31+
</file>
32+
</project>
33+
</coverage>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<coverage generated="1598702199">
3+
<project timestamp="1598702199">
4+
<!-- coverage test 1 70% -->
5+
<file name="/home/workspace/test\case/result-90.php">
6+
<line num="1" type="method" name="methodName" count="1"/>
7+
<line num="2" type="stmt" count="1"/>
8+
<line num="3" type="stmt" count="1"/>
9+
<line num="4" type="stmt" count="0"/>
10+
<line num="5" type="stmt" count="0"/>
11+
<line num="6" type="stmt" count="1"/>
12+
<line num="7" type="stmt" count="1"/>
13+
<line num="8" type="stmt" count="0"/>
14+
<line num="9" type="stmt" count="1"/>
15+
<line num="10" type="stmt" count="1"/>
16+
<metrics loc="11" ncloc="11" statements="10" coveredstatements="7"/>
17+
</file>
18+
<!-- coverage test 2 90% -->
19+
<file name="/home/workspace/test\case/result-100.php">
20+
<line num="1" type="method" name="methodName" count="1"/>
21+
<line num="2" type="stmt" count="1"/>
22+
<line num="3" type="stmt" count="1"/>
23+
<line num="4" type="stmt" count="1"/>
24+
<line num="5" type="stmt" count="1"/>
25+
<line num="6" type="stmt" count="1"/>
26+
<line num="7" type="stmt" count="1"/>
27+
<line num="8" type="stmt" count="1"/>
28+
<line num="9" type="stmt" count="0"/>
29+
<line num="10" type="stmt" count="1"/>
30+
<metrics loc="11" ncloc="11" statements="10" coveredstatements="9"/>
31+
</file>
32+
</project>
33+
</coverage>

0 commit comments

Comments
 (0)