Compare commits

...

7 Commits

Author SHA1 Message Date
9688b83a3d release: 3.7.0 2024-12-10 11:54:49 +00:00
675372c794 chore: fixes types 2024-12-10 11:54:42 +00:00
c18636b3d5 chore: adds phpunit 11.5.0 support 2024-12-10 11:53:59 +00:00
145294a4a3 chore: style 2024-12-01 23:55:15 +00:00
c2cabaeae6 chore: fixes test suite 2024-12-01 23:16:34 +00:00
918a8fc169 release: 3.6.0 2024-12-01 22:46:00 +00:00
5d32dd0641 feat: option to coverage 2024-12-01 22:45:31 +00:00
12 changed files with 87 additions and 16 deletions

View File

@ -18,17 +18,17 @@
],
"require": {
"php": "^8.2.0",
"brianium/paratest": "^7.6.0",
"brianium/paratest": "^7.6.2",
"nunomaduro/collision": "^8.5.0",
"nunomaduro/termwind": "^2.3.0",
"pestphp/pest-plugin": "^3.0.0",
"pestphp/pest-plugin-arch": "^3.0.0",
"pestphp/pest-plugin-mutate": "^3.0.5",
"phpunit/phpunit": "^11.4.4"
"phpunit/phpunit": "^11.5.0"
},
"conflict": {
"filp/whoops": "<2.16.0",
"phpunit/phpunit": ">11.4.4",
"phpunit/phpunit": ">11.5.0",
"sebastian/exporter": "<6.0.0",
"webmozart/assert": "<1.11.0"
},
@ -55,7 +55,7 @@
"require-dev": {
"pestphp/pest-dev-tools": "^3.3.0",
"pestphp/pest-plugin-type-coverage": "^3.2.0",
"symfony/process": "^7.1.8"
"symfony/process": "^7.2.0"
},
"minimum-stability": "dev",
"prefer-stable": true,

View File

@ -68,7 +68,7 @@ final readonly class ThrowableBuilder
$previous = self::from($previous);
}
$trace = Filter::getFilteredStacktrace($t);
$trace = Filter::stackTraceFromThrowableAsString($t);
if ($t instanceof RenderableOnCollisionEditor && $frame = $t->toCollisionEditor()) {
$file = $frame->getFile();

View File

@ -24,7 +24,7 @@ final class BootOverrides implements Bootstrapper
'3bb609b0d3bf6dee8df8d6cd62a3c8ece823c4bb941eaaae39e3cb267171b9d2' => 'TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
'8abdad6413329c6fe0d7d44a8b9926e390af32c0b3123f3720bb9c5bbc6fbb7e' => 'TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
'b4250fc3ffad5954624cb5e682fd940b874e8d3422fa1ee298bd7225e1aa5fc2' => 'TextUI/TestSuiteFilterProcessor.php',
'357d5cd7007f8559b26e1b8cdf43bb6fb15b51b79db981779da6f31b7ec39dad' => 'Event/Value/ThrowableBuilder.php',
'8cfcb4999af79463eca51a42058e502ea4ddc776cba5677bf2f8eb6093e21a5c' => 'Event/Value/ThrowableBuilder.php',
'ede161507d4c9c27805f55a05a32c3bb528e53b6e1fc092bfafdb8207e0019e9' => 'Logging/JUnit/JunitXmlLogger.php',
];

View File

@ -56,7 +56,7 @@ final class AfterEachCall
$afterEachTestCase = ChainableClosure::boundWhen(
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
ChainableClosure::bound(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
ChainableClosure::bound(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class),
)->bindTo($this, self::class);
assert($afterEachTestCase instanceof Closure);

View File

@ -79,7 +79,7 @@ final class BeforeEachCall
$beforeEachTestCase = ChainableClosure::boundWhen(
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
ChainableClosure::bound(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
ChainableClosure::bound(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class),
)->bindTo($this, self::class);
assert($beforeEachTestCase instanceof Closure);

View File

@ -6,7 +6,7 @@ namespace Pest;
function version(): string
{
return '3.5.2';
return '3.7.0';
}
function testDirectory(string $file = ''): string

View File

@ -27,6 +27,11 @@ final class Coverage implements AddsOutput, HandlesArguments
*/
private const MIN_OPTION = 'min';
/**
* @var string
*/
private const EXACTLY_OPTION = 'exactly';
/**
* Whether it should show the coverage or not.
*/
@ -37,6 +42,11 @@ final class Coverage implements AddsOutput, HandlesArguments
*/
public float $coverageMin = 0.0;
/**
* The exactly coverage.
*/
public ?float $coverageExactly = null;
/**
* Creates a new Plugin instance.
*/
@ -51,7 +61,7 @@ final class Coverage implements AddsOutput, HandlesArguments
public function handleArguments(array $originals): array
{
$arguments = [...[''], ...array_values(array_filter($originals, function (string $original): bool {
foreach ([self::COVERAGE_OPTION, self::MIN_OPTION] as $option) {
foreach ([self::COVERAGE_OPTION, self::MIN_OPTION, self::EXACTLY_OPTION] as $option) {
if ($original === sprintf('--%s', $option)) {
return true;
}
@ -73,6 +83,7 @@ final class Coverage implements AddsOutput, HandlesArguments
$inputs = [];
$inputs[] = new InputOption(self::COVERAGE_OPTION, null, InputOption::VALUE_NONE);
$inputs[] = new InputOption(self::MIN_OPTION, null, InputOption::VALUE_REQUIRED);
$inputs[] = new InputOption(self::EXACTLY_OPTION, null, InputOption::VALUE_REQUIRED);
$input = new ArgvInput($arguments, new InputDefinition($inputs));
if ((bool) $input->getOption(self::COVERAGE_OPTION)) {
@ -106,6 +117,13 @@ final class Coverage implements AddsOutput, HandlesArguments
$this->coverageMin = (float) $minOption;
}
if ($input->getOption(self::EXACTLY_OPTION) !== null) {
/** @var int|float $exactlyOption */
$exactlyOption = $input->getOption(self::EXACTLY_OPTION);
$this->coverageExactly = (float) $exactlyOption;
}
return $originals;
}
@ -127,10 +145,22 @@ final class Coverage implements AddsOutput, HandlesArguments
}
$coverage = \Pest\Support\Coverage::report($this->output);
$exitCode = (int) ($coverage < $this->coverageMin);
if ($exitCode === 1) {
if ($exitCode === 0 && $this->coverageExactly !== null) {
$comparableCoverage = $this->computeComparableCoverage($coverage);
$comparableCoverageExactly = $this->computeComparableCoverage($this->coverageExactly);
$exitCode = $comparableCoverage === $comparableCoverageExactly ? 0 : 1;
if ($exitCode === 1) {
$this->output->writeln(sprintf(
"\n <fg=white;bg=red;options=bold> FAIL </> Code coverage not exactly <fg=white;options=bold> %s %%</>, currently <fg=red;options=bold> %s %%</>.",
number_format($this->coverageExactly, 1),
number_format(floor($coverage * 10) / 10, 1),
));
}
} elseif ($exitCode === 1) {
$this->output->writeln(sprintf(
"\n <fg=white;bg=red;options=bold> FAIL </> Code coverage below expected <fg=white;options=bold> %s %%</>, currently <fg=red;options=bold> %s %%</>.",
number_format($this->coverageMin, 1),
@ -143,4 +173,12 @@ final class Coverage implements AddsOutput, HandlesArguments
return $exitCode;
}
/**
* Computes the comparable coverage to a percentage with one decimal.
*/
private function computeComparableCoverage(float $coverage): float
{
return floor($coverage * 10) / 10;
}
}

View File

@ -1,5 +1,5 @@
Pest Testing Framework 3.5.2.
Pest Testing Framework 3.7.0.
USAGE: pest <file> [options]

View File

@ -1,3 +1,3 @@
Pest Testing Framework 3.5.2.
Pest Testing Framework 3.7.0.

View File

@ -1491,6 +1491,16 @@
PASS Tests\Playground
✓ basic
PASS Tests\Plugins\Coverage
✓ compute comparable coverage with (0, 0)
✓ compute comparable coverage with (0.5, 0.5)
✓ compute comparable coverage with (1.0, 1.0)
✓ compute comparable coverage with (32.51, 32.5)
✓ compute comparable coverage with (32.12312321312312, 32.1)
✓ compute comparable coverage with (32.53333333333333, 32.5)
✓ compute comparable coverage with (32.57777771232132, 32.5)
✓ compute comparable coverage with (100.0, 100.0)
PASS Tests\Plugins\Traits
✓ it allows global uses
✓ it allows multiple global uses registered in the same path
@ -1698,4 +1708,4 @@
WARN Tests\Visual\Version
- visual snapshot of help command output
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1144 passed (2736 assertions)
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1152 passed (2744 assertions)

View File

@ -0,0 +1,23 @@
<?php
use Pest\Plugins\Coverage;
use Symfony\Component\Console\Output\NullOutput;
test('compute comparable coverage', function (float $givenValue, float $expectedValue) {
$output = new NullOutput;
$plugin = new Coverage($output);
$comparableCoverage = (fn () => $this->computeComparableCoverage($givenValue))->call($plugin);
expect($comparableCoverage)->toBe($expectedValue);
})->with([
[0, 0],
[0.5, 0.5],
[1.0, 1.0],
[32.51, 32.5],
[32.12312321312312, 32.1],
[32.53333333333333, 32.5],
[32.57777771232132, 32.5],
[100.0, 100.0],
]);

View File

@ -16,7 +16,7 @@ $run = function () {
test('parallel', function () use ($run) {
expect($run('--exclude-group=integration'))
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1134 passed (2712 assertions)')
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1142 passed (2720 assertions)')
->toContain('Parallel: 3 processes');
})->skipOnWindows();