-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathcoverage-summary.php
More file actions
128 lines (103 loc) · 4.37 KB
/
Copy pathcoverage-summary.php
File metadata and controls
128 lines (103 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
declare(strict_types=1);
$cloverPath = 'coverage/clover.xml';
$failUnder = null;
foreach (array_slice($argv, 1) as $arg) {
if (str_starts_with($arg, '--fail-under=')) {
$failUnder = (float) substr($arg, strlen('--fail-under='));
continue;
}
if ($arg !== '') {
$cloverPath = $arg;
}
}
if (!is_file($cloverPath)) {
fwrite(STDERR, "Coverage file not found: {$cloverPath}\n");
fwrite(STDERR, "Run `composer test:coverage:clover` first.\n");
exit(1);
}
$xml = simplexml_load_file($cloverPath);
if (!$xml) {
fwrite(STDERR, "Unable to parse Clover coverage file: {$cloverPath}\n");
exit(1);
}
function coveragePercent(int $covered, int $total): float
{
return $total === 0 ? 0.0 : round(($covered / $total) * 100, 2);
}
function intMetric(SimpleXMLElement $node, string $name): int
{
return (int) ($node->metrics[$name] ?? 0);
}
$project = $xml->project;
$metrics = $project->metrics;
$statements = (int) ($metrics['statements'] ?? 0);
$coveredStatements = (int) ($metrics['coveredstatements'] ?? 0);
$methods = (int) ($metrics['methods'] ?? 0);
$coveredMethods = (int) ($metrics['coveredmethods'] ?? 0);
$classes = (int) ($metrics['classes'] ?? 0);
$coveredClasses = (int) ($metrics['coveredclasses'] ?? 0);
$files = [];
$directories = [];
foreach ($project->xpath('.//file') ?: [] as $file) {
$path = (string) $file['name'];
$fileStatements = intMetric($file, 'statements');
$coveredFileLines = intMetric($file, 'coveredstatements');
$fileMethods = intMetric($file, 'methods');
$coveredFileMethod = intMetric($file, 'coveredmethods');
if ($fileStatements === 0) {
continue;
}
$files[] = [
'path' => $path,
'covered' => $coveredFileLines,
'statements' => $fileStatements,
'methods' => $fileMethods,
'covered_methods' => $coveredFileMethod,
'percent' => coveragePercent($coveredFileLines, $fileStatements),
];
$relativePath = preg_replace('#^' . preg_quote(getcwd(), '#') . '/?#', '', $path);
$parts = explode('/', $relativePath ?: $path);
$directory = count($parts) > 2 ? $parts[0] . '/' . $parts[1] : dirname($relativePath ?: $path);
if (!isset($directories[$directory])) {
$directories[$directory] = [
'covered' => 0,
'statements' => 0,
];
}
$directories[$directory]['covered'] += $coveredFileLines;
$directories[$directory]['statements'] += $fileStatements;
}
usort($files, function (array $a, array $b): int {
return $a['percent'] <=> $b['percent']
?: $b['statements'] <=> $a['statements'];
});
$directoryRows = [];
foreach ($directories as $directory => $directoryMetrics) {
$directoryRows[] = [
'directory' => $directory,
'covered' => $directoryMetrics['covered'],
'statements' => $directoryMetrics['statements'],
'percent' => coveragePercent($directoryMetrics['covered'], $directoryMetrics['statements']),
];
}
usort($directoryRows, function (array $a, array $b): int {
return $a['percent'] <=> $b['percent']
?: $b['statements'] <=> $a['statements'];
});
printf("Line coverage: %.2f%% (%d/%d statements)\n", coveragePercent($coveredStatements, $statements), $coveredStatements, $statements);
printf("Method coverage: %.2f%% (%d/%d methods)\n", coveragePercent($coveredMethods, $methods), $coveredMethods, $methods);
printf("Class coverage: %.2f%% (%d/%d classes)\n", coveragePercent($coveredClasses, $classes), $coveredClasses, $classes);
echo "\nLowest covered directories:\n";
foreach (array_slice($directoryRows, 0, 10) as $row) {
printf(" %6.2f%% %5d/%-5d %s\n", $row['percent'], $row['covered'], $row['statements'], $row['directory']);
}
echo "\nLowest covered files:\n";
foreach (array_slice($files, 0, 20) as $file) {
$relativePath = preg_replace('#^' . preg_quote(getcwd(), '#') . '/?#', '', $file['path']);
printf(" %6.2f%% %5d/%-5d %s\n", $file['percent'], $file['covered'], $file['statements'], $relativePath ?: $file['path']);
}
if ($failUnder !== null && coveragePercent($coveredStatements, $statements) < $failUnder) {
fwrite(STDERR, sprintf("\nCoverage %.2f%% is below the required %.2f%% line threshold.\n", coveragePercent($coveredStatements, $statements), $failUnder));
exit(1);
}