Skip to content

Commit d9e99fd

Browse files
authored
Merge pull request #1 from permafrost-dev/feature-metric-flag
Feature: metric field name option
2 parents e675dca + cd9a848 commit d9e99fd

File tree

8 files changed

+83
-10
lines changed

8 files changed

+83
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to `coverage-check` will be documented in this file.
44

55
---
66

7+
## 1.1.0 - 2021-07-04
8+
9+
- add `--metric/-m` option flag
10+
711
## 1.0.0 - 2021-07-03
812

913
- initial release

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,22 @@ If you don't specify the `--require/-r` flag, only the percentage of code covera
3838
./vendor/bin/coverage-check clover.xml
3939
./vendor/bin/coverage-check clover.xml --require=50
4040
./vendor/bin/coverage-check clover.xml -r 80.5
41+
./vendor/bin/coverage-check clover.xml -m statement -r 75
4142
```
4243

4344
## Available Options
4445

4546
| Option | Description |
4647
| --- | --- |
47-
| `--require` or `-r` | Enforce a minimum code coverage value |
4848
| `--coverage-only` or `-C` | Only display the code coverage value |
49+
| `--metric` or `-m` `<name>` | Use the specified metric field for calculating coverage. Valid values are `element` _(default)_, `method`, or `statement` |
50+
| `--require` or `-r` `<value>` | Enforce a minimum code coverage value, where `<value>` is an integer or decimal value |
51+
52+
## Metric fields
53+
54+
The field that is used to calculate code coverage can be specified using the `--metric=<name>` or `-m <name>` option.
55+
56+
Valid field names are `element` _(the default)_, `statement`, and `method`.
4957

5058
## Generating clover-format coverage files
5159

src/Commands/CheckCoverageCommand.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ protected function configure(): void
2727
{
2828
$this->addArgument('filename')
2929
->addOption('require', 'r', InputOption::VALUE_REQUIRED, 'Require a minimum code coverage percentage', null)
30+
->addOption('metric', 'm', InputOption::VALUE_REQUIRED, 'Use a specific metric field (element, statement, or method)')
3031
->addOption('coverage-only', 'C', InputOption::VALUE_NONE, 'Display only the code coverage percentage')
3132
->setDescription('Checks a clover-format coverage file for a minimum coverage percentage and optionally enforces it.');
3233
}
@@ -52,7 +53,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
5253
return $result ? Command::SUCCESS : Command::FAILURE;
5354
}
5455

55-
$checker = new CoverageChecker($this->config->filename);
56+
$checker = new CoverageChecker($this->config->filename, $this->config);
5657
$coverage = $checker->getCoveragePercent();
5758

5859
$this->displayCoverageResults($coverage);
@@ -62,7 +63,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
6263

6364
protected function checkCoverage(string $filename, float $requiredPercentage): array
6465
{
65-
$checker = new CoverageChecker($filename);
66+
$checker = new CoverageChecker($filename, $this->config);
6667

6768
return [$checker->check($requiredPercentage), $checker->getCoveragePercent()];
6869
}

src/Configuration/Configuration.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,26 @@ class Configuration
1616
/** @var bool */
1717
public $displayCoverageOnly = false;
1818

19-
public function __construct(string $filename, bool $requireMode, $required, bool $displayCoverageOnly)
19+
/** @var string */
20+
public $metricField;
21+
22+
public function __construct(string $filename, bool $requireMode, $required, bool $displayCoverageOnly, string $metricField)
2023
{
2124
$this->filename = $filename;
2225
$this->required = $required;
2326
$this->requireMode = $requireMode;
2427
$this->displayCoverageOnly = $displayCoverageOnly;
28+
$this->metricField = rtrim(strtolower($metricField), 's');
2529
}
2630

2731
public function validate(): void
2832
{
2933
if (! file_exists($this->filename) || ! is_file($this->filename)) {
3034
throw new \InvalidArgumentException('Invalid input file provided.');
3135
}
36+
37+
if (! in_array($this->metricField, ['element', 'statement', 'method'])) {
38+
throw new \InvalidArgumentException('Invalid metric field name provided. Valid options are "element", "statement", "method".');
39+
}
3240
}
3341
}

src/Configuration/ConfigurationFactory.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ public static function create(InputInterface $input): Configuration
1212
$requireMode = $input->hasOption('require') && $input->getOption('require') !== null;
1313
$percentage = $requireMode ? (float)$input->getOption('require') : null;
1414
$displayCoverageOnly = $input->hasOption('coverage-only') && $input->getOption('coverage-only') === true;
15+
$metricField = 'element';
1516

16-
return new Configuration($filename, $requireMode, $percentage, $displayCoverageOnly);
17+
if ($input->hasOption('metric') && $input->getOption('metric') !== null) {
18+
$metricField = $input->getOption('metric');
19+
}
20+
21+
return new Configuration($filename, $requireMode, $percentage, $displayCoverageOnly, $metricField);
1722
}
1823
}

src/CoverageChecker.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
namespace Permafrost\CoverageCheck;
44

5+
use Permafrost\CoverageCheck\Configuration\Configuration;
56
use SimpleXMLElement;
67

78
class CoverageChecker
89
{
910
/** @var SimpleXMLElement */
1011
public $xml;
1112

12-
public function __construct(string $filename)
13+
/** @var Configuration */
14+
public $config;
15+
16+
public function __construct(string $filename, Configuration $config)
1317
{
18+
$this->config = $config;
1419
$this->xml = new SimpleXMLElement(file_get_contents($filename));
1520
}
1621

@@ -29,8 +34,10 @@ public function getCoveragePercent(): float
2934
{
3035
$metrics = $this->xml->xpath('//metrics');
3136

32-
$totalElements = $this->getMetricFieldSum($metrics, 'elements');
33-
$checkedElements = $this->getMetricFieldSum($metrics, 'coveredelements');
37+
[$totalName, $coveredName] = $this->getMetricFieldNames();
38+
39+
$totalElements = $this->getMetricFieldSum($metrics, $totalName);
40+
$checkedElements = $this->getMetricFieldSum($metrics, $coveredName);
3441

3542
return round(($checkedElements / $totalElements) * 100, 4);
3643
}
@@ -39,4 +46,9 @@ public function check(float $minPercentage): bool
3946
{
4047
return $this->getCoveragePercent() >= $minPercentage;
4148
}
49+
50+
protected function getMetricFieldNames(): array
51+
{
52+
return ["{$this->config->metricField}s", "covered{$this->config->metricField}s"];
53+
}
4254
}

tests/Configuration/ConfigurationFactoryTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ protected function createInput(array $input)
1616
$inputDefinition = new InputDefinition([
1717
new InputArgument('filename', InputArgument::REQUIRED),
1818
new InputOption('require', 'r', InputOption::VALUE_REQUIRED),
19+
new InputOption('metric', 'm', InputOption::VALUE_REQUIRED),
1920
new InputOption('coverage-only', 'C', InputOption::VALUE_NONE),
2021
]);
2122

@@ -67,4 +68,17 @@ public function it_does_not_throw_an_exception_when_validating_the_configuration
6768

6869
$this->assertFalse($hasException);
6970
}
71+
72+
/** @test */
73+
public function it_throws_an_exception_when_validating_the_metric_field_with_an_invalid_value()
74+
{
75+
$filename = realpath(__DIR__.'/../data/coverage-clover.xml');
76+
77+
$input = $this->createInput(['filename' => $filename, '--metric' => 'bad']);
78+
$config = ConfigurationFactory::create($input);
79+
80+
$this->expectException(\InvalidArgumentException::class);
81+
82+
$config->validate();
83+
}
7084
}

tests/CoverageCheckerTest.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Permafrost\CoverageCheck\Tests;
44

5+
use Permafrost\CoverageCheck\Configuration\Configuration;
56
use Permafrost\CoverageCheck\CoverageChecker;
67
use PHPUnit\Framework\TestCase;
78

@@ -10,17 +11,37 @@ class CoverageCheckerTest extends TestCase
1011
/** @test */
1112
public function it_gets_the_coverage_percentage()
1213
{
13-
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml');
14+
$config = new Configuration(__DIR__ . '/data/coverage-clover.xml', false, false, false, 'element');
15+
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml', $config);
1416

1517
$this->assertEquals(89.8765, round($checker->getCoveragePercent(), 4));
1618
}
1719

1820
/** @test */
1921
public function it_checks_for_a_minimum_coverage_percentage()
2022
{
21-
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml');
23+
$config = new Configuration(__DIR__ . '/data/coverage-clover.xml', false, false, false, 'element');
24+
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml', $config);
2225

2326
$this->assertTrue($checker->check(75));
2427
$this->assertFalse($checker->check(99));
2528
}
29+
30+
/** @test */
31+
public function it_gets_the_coverage_percentage_for_the_statement_metric()
32+
{
33+
$config = new Configuration(__DIR__ . '/data/coverage-clover.xml', false, false, false, 'statement');
34+
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml', $config);
35+
36+
$this->assertEquals(90.6279, round($checker->getCoveragePercent(), 4));
37+
}
38+
39+
/** @test */
40+
public function it_gets_the_coverage_percentage_for_the_method_metric()
41+
{
42+
$config = new Configuration(__DIR__ . '/data/coverage-clover.xml', false, false, false, 'method');
43+
$checker = new CoverageChecker(__DIR__ . '/data/coverage-clover.xml', $config);
44+
45+
$this->assertEquals(87.4439, $checker->getCoveragePercent());
46+
}
2647
}

0 commit comments

Comments
 (0)