Skip to content

Commit d8e02c9

Browse files
committed
Improve code coverage collection
1 parent f4fdc17 commit d8e02c9

File tree

4 files changed

+43
-39
lines changed

4 files changed

+43
-39
lines changed

CHANGELOG.md

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

55
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
66

7+
## [4.0.0] - 2024-02-20
8+
### Added
9+
* Add support for PHPUnit 11
10+
11+
### Changed
12+
* Simplify generating code coverage for CLI and API tests
13+
14+
### Deprecated
15+
* *Nothing*
16+
17+
### Removed
18+
* *Nothing*
19+
20+
### Fixed
21+
* *Nothing*
22+
23+
724
## [3.11.1] - 2024-02-18
825
### Added
926
* *Nothing*

composer.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
"require": {
1515
"php": "^8.2",
1616
"doctrine/data-fixtures": "^1.6",
17-
"doctrine/orm": "^3.0 | ^2.18",
17+
"doctrine/orm": "^3.0 || ^2.18",
1818
"fig/http-message-util": "^1.1",
1919
"guzzlehttp/guzzle": "^7.8",
20-
"phpunit/php-code-coverage": "^10.1",
21-
"phpunit/phpunit": "^10.5",
22-
"psr/container": "^2.0 | ^1.0",
20+
"phpunit/php-code-coverage": "^11.0 || ^10.1",
21+
"phpunit/phpunit": "^11.0 || ^10.5",
22+
"psr/container": "^2.0 || ^1.0",
2323
"psr/http-server-middleware": "^1.0",
2424
"shlinkio/shlink-json": "^1.0",
25-
"symfony/console": "^7.0 | ^6.4",
26-
"symfony/event-dispatcher": "^7.0 | ^6.4",
27-
"symfony/process": "^7.0 | ^6.4"
25+
"symfony/console": "^7.0 || ^6.4",
26+
"symfony/event-dispatcher": "^7.0 || ^6.4",
27+
"symfony/process": "^7.0 || ^6.4"
2828
},
2929
"require-dev": {
3030
"phpstan/phpstan": "^1.10",

src/CliTest/CliCoverageDelegator.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Shlinkio\Shlink\TestUtils\CliTest;
66

7-
use Closure;
87
use Psr\Container\ContainerInterface;
98
use SebastianBergmann\CodeCoverage\CodeCoverage;
109
use Symfony\Component\Console\Application;
@@ -16,7 +15,7 @@ class CliCoverageDelegator
1615
{
1716
public const COVERAGE_ID_ENV = 'COVERAGE_ID';
1817

19-
public function __construct(private readonly Closure $exportCoverage, private readonly ?CodeCoverage $coverage)
18+
public function __construct(private readonly ?CodeCoverage $coverage)
2019
{
2120
}
2221

@@ -26,7 +25,6 @@ public function __invoke(ContainerInterface $c, string $serviceName, callable $c
2625
$app = $callback();
2726
$wrappedEventDispatcher = new EventDispatcher();
2827
$coverage = $this->coverage;
29-
$exportCoverage = $this->exportCoverage;
3028

3129
// When the command starts, start collecting coverage
3230
$wrappedEventDispatcher->addListener(
@@ -42,11 +40,10 @@ static function () use (&$coverage): void {
4240
// When the command ends, stop collecting coverage and export it
4341
$wrappedEventDispatcher->addListener(
4442
'console.terminate',
45-
static function () use (&$coverage, $exportCoverage): void {
43+
static function () use (&$coverage): void {
4644
$id = getenv(self::COVERAGE_ID_ENV);
4745
if ($id && $coverage !== null) {
4846
$coverage->stop();
49-
$exportCoverage('cli');
5047
}
5148
},
5249
);

src/Helper/CoverageHelper.php

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@
55
namespace Shlinkio\Shlink\TestUtils\Helper;
66

77
use PHPUnit\Framework\Attributes\Test;
8-
use PHPUnit\Runner\Version;
98
use ReflectionMethod;
109
use SebastianBergmann\CodeCoverage\CodeCoverage;
1110
use SebastianBergmann\CodeCoverage\Driver\Selector;
1211
use SebastianBergmann\CodeCoverage\Filter;
13-
use SebastianBergmann\CodeCoverage\Report\Html\Facade as Html;
1412
use SebastianBergmann\CodeCoverage\Report\PHP;
15-
use SebastianBergmann\CodeCoverage\Report\Xml\Facade as Xml;
1613
use SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
1714

1815
use function debug_backtrace;
19-
use function file_exists;
16+
use function microtime;
17+
use function register_shutdown_function;
2018

2119
class CoverageHelper
2220
{
@@ -52,38 +50,30 @@ private static function resolveTestDataSet(string|int $dataName): string
5250
return ! empty($dataName) ? '#' . $dataName : '';
5351
}
5452

55-
public static function createCoverageForDirectories(array $dirs): CodeCoverage
56-
{
53+
/**
54+
* @param string|null $shutdownExportBasePath - If provided, it will export coverage to this location on shutdown
55+
*/
56+
public static function createCoverageForDirectories(
57+
array $dirs,
58+
?string $shutdownExportBasePath = null,
59+
): CodeCoverage {
5760
$filter = new Filter();
5861
foreach ($dirs as $dir) {
5962
foreach ((new FileIteratorFacade())->getFilesAsArray($dir) as $file) {
6063
$filter->includeFile($file);
6164
}
6265
}
6366

64-
return new CodeCoverage((new Selector())->forLineCoverage($filter), $filter);
65-
}
67+
$coverage = new CodeCoverage((new Selector())->forLineCoverage($filter), $filter);
6668

67-
public static function exportCoverage(
68-
?CodeCoverage $coverage,
69-
string $basePath,
70-
bool $pretty = false,
71-
bool $mergeWithExisting = false,
72-
): void {
73-
if ($coverage === null) {
74-
return;
69+
if ($shutdownExportBasePath !== null) {
70+
register_shutdown_function(function () use ($shutdownExportBasePath, $coverage): void {
71+
$id = (string) microtime(as_float: true);
72+
$covPath = $shutdownExportBasePath . '/' . $id . '.cov';
73+
(new PHP())->process($coverage, $covPath);
74+
});
7575
}
7676

77-
$covPath = $basePath . '.cov';
78-
if ($mergeWithExisting && file_exists($covPath)) {
79-
$coverage->merge(require $covPath);
80-
}
81-
82-
if ($pretty) {
83-
(new Html())->process($coverage, $basePath . '/coverage-html');
84-
} else {
85-
(new PHP())->process($coverage, $covPath);
86-
(new Xml(Version::getVersionString()))->process($coverage, $basePath . '/coverage-xml');
87-
}
77+
return $coverage;
8878
}
8979
}

0 commit comments

Comments
 (0)