Skip to content

Commit aeb8f51

Browse files
author
Niko Heikkilä
committed
Refactor and optimize code
- Guard against empty data (division by zero) - Refactor logic to functions and constants - Make 'only-percentage' option more canonical by prepending with two dashes - Update tests
1 parent a9b0c07 commit aeb8f51

File tree

5 files changed

+109
-34
lines changed

5 files changed

+109
-34
lines changed

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ This script can be used in your continuous deployment environment or for example
66

77
# Installation
88
The script can be installed using composer. Add this repository as a dependency to the composer.json file.
9+
910
```bash
1011
composer require --dev rregeer/phpunit-coverage-check
11-
composer install
1212
```
1313

1414
# Usage
@@ -17,17 +17,19 @@ The script has requires 2 parameters that are mandatory to return the code cover
1717
1. The location of the clover xml file, that's generated by phpunit.
1818
2. The coverage threshold that is acceptable. Min = 1, Max = 100
1919

20-
Generate the clover xml by using phpunit and run the coverage check script:
20+
Generate the `clover.xml` file by using phpunit and run the coverage check script:
2121
Run the script:
22+
2223
```bash
2324
vendor/bin/phpunit --coverage-clover clover.xml
2425
vendor/bin/coverage-check clover.xml 80
25-
vendor/bin/coverage-check clover.xml 80 only-percentage
26+
vendor/bin/coverage-check clover.xml 80 --only-percentage
2627
```
2728

28-
With the `only-percentage` enabled, the CLI command will only return the resulting coverage percentage.
29+
With the `--only-percentage` enabled, the CLI command will only return the resulting coverage percentage.
2930

3031
It's also possible to add the coverage report generation to the phpunit.xml.dist add to following line to the xml file:
32+
3133
```xml
3234
<logging>
3335
<log type="coverage-clover" target="clover.xml"/>

composer.lock

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coverage-check.php

+57-30
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,46 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
// Inspired by: https://ocramius.github.io/blog/automated-code-coverage-check-for-github-pull-requests-with-travis/
3-
if (!isset($argv[1]) || !file_exists($argv[1])) {
4-
echo 'Invalid input file provided' . PHP_EOL;
5-
exit(1);
6+
7+
const XPATH_METRICS = '//metrics';
8+
const STATUS_OK = 0;
9+
const STATUS_ERROR = 1;
10+
11+
function formatCoverage(float $number): string
12+
{
13+
return sprintf('%0.2f %%', $number);
614
}
715

8-
if (!isset($argv[2])) {
9-
echo 'An integer checked percentage must be given as second parameter'. PHP_EOL;
10-
exit(1);
16+
function loadMetrics(string $file): array
17+
{
18+
$xml = new SimpleXMLElement(file_get_contents($file));
19+
20+
return $xml->xpath(XPATH_METRICS);
1121
}
1222

13-
$onlyEchoPercentage = false;
23+
function printStatus(string $msg, int $exitCode = STATUS_OK)
24+
{
25+
echo $msg.PHP_EOL;
26+
exit($exitCode);
27+
}
1428

15-
if (isset($argv[3]) && $argv[3] === 'only-percentage') {
16-
$onlyEchoPercentage = true;
29+
if (! isset($argv[1]) || ! file_exists($argv[1])) {
30+
printStatus("Invalid input file {$argv[1]} provided.", STATUS_ERROR);
1731
}
1832

19-
$inputFile = $argv[1];
20-
$percentage = min(100, max(0, (float)$argv[2]));
33+
if (! isset($argv[2])) {
34+
printStatus(
35+
'An integer checked percentage must be given as second parameter.',
36+
STATUS_ERROR
37+
);
38+
}
39+
40+
$onlyEchoPercentage = isset($argv[3]) && $argv[3] === '--only-percentage';
2141

22-
$xml = new SimpleXMLElement(file_get_contents($inputFile));
23-
$metrics = $xml->xpath('//metrics');
42+
$inputFile = $argv[1];
43+
$percentage = min(100, max(0, (float) $argv[2]));
2444

2545
$elements = 0;
2646
$coveredElements = 0;
@@ -29,31 +49,38 @@
2949
$methods = 0;
3050
$coveredmethods = 0;
3151

32-
foreach ($metrics as $metric) {
33-
$elements += (int)$metric['elements'];
34-
$coveredElements += (int)$metric['coveredelements'];
35-
$statements += (int)$metric['statements'];
36-
$coveredstatements += (int)$metric['coveredstatements'];
37-
$methods += (int)$metric['methods'];
38-
$coveredmethods += (int)$metric['coveredmethods'];
52+
foreach (loadMetrics($inputFile) as $metric) {
53+
$elements += (int) $metric['elements'];
54+
$coveredElements += (int) $metric['coveredelements'];
55+
$statements += (int) $metric['statements'];
56+
$coveredstatements += (int) $metric['coveredstatements'];
57+
$methods += (int) $metric['methods'];
58+
$coveredmethods += (int) $metric['coveredmethods'];
3959
}
4060

4161
// See calculation: https://confluence.atlassian.com/pages/viewpage.action?pageId=79986990
42-
$TPC = ($coveredstatements + $coveredmethods + $coveredElements) / ($statements + $methods + $elements) * 100;
62+
$coveredMetrics = $coveredstatements + $coveredmethods + $coveredElements;
63+
$totalMetrics = $statements + $methods + $elements;
64+
65+
if ($totalMetrics === 0) {
66+
printStatus('Insufficient data for calculation. Please add more code.', STATUS_ERROR);
67+
}
68+
69+
$totalPercentageCoverage = $coveredMetrics / $totalMetrics * 100;
4370

44-
if ($TPC < $percentage && ! $onlyEchoPercentage) {
45-
echo 'Total code coverage is ' . sprintf('%0.2f', $TPC) . '%, which is below the accepted ' . $percentage . '%' . PHP_EOL;
46-
exit(1);
71+
if ($totalPercentageCoverage < $percentage && ! $onlyEchoPercentage) {
72+
printStatus(
73+
'Total code coverage is '.formatCoverage($totalPercentageCoverage).' which is below the accepted '.$percentage.'%',
74+
STATUS_ERROR
75+
);
4776
}
4877

49-
if ($TPC < $percentage && $onlyEchoPercentage) {
50-
echo sprintf('%0.2f', $TPC) . PHP_EOL;
51-
exit(1);
78+
if ($totalPercentageCoverage < $percentage && $onlyEchoPercentage) {
79+
printStatus(formatCoverage($totalPercentageCoverage), STATUS_ERROR);
5280
}
5381

5482
if ($onlyEchoPercentage) {
55-
echo sprintf('%0.2f', $TPC) . PHP_EOL;
56-
exit(0);
83+
printStatus(formatCoverage($totalPercentageCoverage));
5784
}
5885

59-
echo 'Total code coverage is ' . sprintf('%0.2f', $TPC) . '% - OK!' . PHP_EOL;
86+
printStatus('Total code coverage is '.formatCoverage($totalPercentageCoverage).' OK!');

test/empty.xml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<coverage generated="1002">
3+
<project timestamp="1002">
4+
<package name="Example">
5+
<file name="/tmp/Example/String.php">
6+
<class name="Example\String" namespace="Example">
7+
<metrics complexity="15" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
8+
</class>
9+
<metrics loc="1" ncloc="1" classes="1" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
10+
</file>
11+
<file name="/tmp/Example/StringList.php">
12+
<class name="Example\StringList" namespace="Example">
13+
<metrics complexity="0" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
14+
</class>
15+
<metrics loc="1" ncloc="1" classes="1" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
16+
</file>
17+
</package>
18+
<metrics files="1" loc="0" ncloc="0" classes="1" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
19+
</project>
20+
</coverage>

test/run

+7
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,12 @@ bin/coverage-check test/clover.xml 0
88
bin/coverage-check test/clover.xml 90
99

1010
# Expect fail
11+
! bin/coverage-check test/empty.xml 10
1112
! bin/coverage-check test/clover.xml 95
1213
! bin/coverage-check test/clover.xml 100
14+
15+
# Only percentage
16+
expected="90.32 %"
17+
actual=$(bin/coverage-check test/clover.xml 90 --only-percentage)
18+
19+
[[ "$expected" == "$actual" ]] || (echo "ERROR: Expected coverage $expected, got $actual" && exit 1)

0 commit comments

Comments
 (0)