diff --git a/composer.json b/composer.json index 5b5ce2de..bdcdbcf7 100644 --- a/composer.json +++ b/composer.json @@ -19,18 +19,18 @@ "require": { "php": "^8.4", "brianium/paratest": "^7.23.0", - "nunomaduro/collision": "^8.9.4", + "nunomaduro/collision": "^8.9.5", "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^5.0.0", "pestphp/pest-plugin-arch": "^5.0.0", "pestphp/pest-plugin-mutate": "^5.0.0", "pestphp/pest-plugin-profanity": "^5.0.0", - "phpunit/phpunit": "^13.2.3", + "phpunit/phpunit": "^13.2.4", "symfony/process": "^8.1.0" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">13.2.3", + "phpunit/phpunit": ">13.2.4", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, diff --git a/rector.php b/rector.php index a5c426f5..1531a89d 100644 --- a/rector.php +++ b/rector.php @@ -6,6 +6,7 @@ use Rector\CodingStyle\Rector\ArrowFunction\ArrowFunctionDelegatingCallToFirstCl use Rector\Config\RectorConfig; use Rector\DeadCode\Rector\ClassMethod\RemoveDuplicatedReturnSelfDocblockRector; use Rector\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveReturnTagIncompatibleWithNativeTypeRector; use Rector\DeadCode\Rector\ClassMethod\RemoveUselessUnionReturnDocblockRector; use Rector\TypeDeclaration\Rector\ClassMethod\NarrowObjectReturnTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; @@ -22,6 +23,9 @@ return RectorConfig::configure() RemoveParentDelegatingConstructorRector::class, RemoveDuplicatedReturnSelfDocblockRector::class, RemoveUselessUnionReturnDocblockRector::class, + RemoveReturnTagIncompatibleWithNativeTypeRector::class => [ + __DIR__.'/src/Expectations/HigherOrderExpectation.php', + ], ]) ->withPreparedSets( deadCode: true, diff --git a/src/Exceptions/DatasetProviderError.php b/src/Exceptions/DatasetProviderError.php new file mode 100644 index 00000000..11630781 --- /dev/null +++ b/src/Exceptions/DatasetProviderError.php @@ -0,0 +1,19 @@ +getMessage(), (int) $previous->getCode(), $previous); + } +} diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index a3a343b1..50f6d12e 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -161,6 +161,7 @@ final class TestCaseFactory $classCode = <<getPrevious() ?? \$arguments[0]; + } + return \$this->__runTest( \$this->__test, ...\$arguments, @@ -261,7 +265,11 @@ final class TestCaseMethodFactory public static function $dataProviderName() { - return __PestDatasets::get(self::\$__filename, "$methodName"); + try { + return __PestDatasets::get(self::\$__filename, "$methodName"); + } catch (\Throwable \$throwable) { + return [[new __PestDatasetProviderError(\$throwable)]]; + } } EOF; diff --git a/src/Pest.php b/src/Pest.php index 0b512ea1..206952db 100644 --- a/src/Pest.php +++ b/src/Pest.php @@ -6,7 +6,7 @@ namespace Pest; function version(): string { - return '5.0.0-rc.12'; + return '5.0.0-beta.1'; } function testDirectory(string $file = ''): string diff --git a/tests/.pest/snapshots/Visual/Help/visual_snapshot_of_help_command_output.snap b/tests/.pest/snapshots/Visual/Help/visual_snapshot_of_help_command_output.snap index ebf1d8ec..5555c2b4 100644 --- a/tests/.pest/snapshots/Visual/Help/visual_snapshot_of_help_command_output.snap +++ b/tests/.pest/snapshots/Visual/Help/visual_snapshot_of_help_command_output.snap @@ -1,5 +1,5 @@ - Pest Testing Framework 5.0.0-rc.12. + Pest Testing Framework 5.0.0-beta.1. USAGE: pest [options] diff --git a/tests/.pest/snapshots/Visual/Version/visual_snapshot_of_help_command_output.snap b/tests/.pest/snapshots/Visual/Version/visual_snapshot_of_help_command_output.snap index 26f4d189..8ab8b170 100644 --- a/tests/.pest/snapshots/Visual/Version/visual_snapshot_of_help_command_output.snap +++ b/tests/.pest/snapshots/Visual/Version/visual_snapshot_of_help_command_output.snap @@ -1,3 +1,3 @@ - Pest Testing Framework 5.0.0-rc.12. + Pest Testing Framework 5.0.0-beta.1. diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index f739d0a0..bff081e3 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -136,6 +136,11 @@ ✓ describe()->with() preserves depends → first with (9) ✓ describe()->with() preserves depends → second with (9) + PASS Tests\Features\DatasetProviderErrors + ✓ reports missing datasets as errors for a single file run + ✓ reports missing datasets as errors alongside passing tests + ✓ reports dataset closure exceptions as errors + PASS Tests\Features\DatasetsTests - 1 todo ✓ it throws exception if dataset does not exist ✓ it throws exception if dataset already exist @@ -2068,4 +2073,4 @@ ✓ pass with dataset with ('my-datas-set-value') ✓ within describe → pass with dataset with ('my-datas-set-value') - Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1449 passed (3199 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1452 passed (3209 assertions) \ No newline at end of file diff --git a/tests/.tests/DatasetClosureThrows.php b/tests/.tests/DatasetClosureThrows.php new file mode 100644 index 00000000..2a8fc765 --- /dev/null +++ b/tests/.tests/DatasetClosureThrows.php @@ -0,0 +1,9 @@ +toBeTrue(); +})->with('throws'); diff --git a/tests/.tests/IssueOnly.php b/tests/.tests/IssueOnly.php new file mode 100644 index 00000000..1e0c8701 --- /dev/null +++ b/tests/.tests/IssueOnly.php @@ -0,0 +1,7 @@ +toBeTruthy(); +})->with('missing'); diff --git a/tests/.tests/IssueWithPassing.php b/tests/.tests/IssueWithPassing.php new file mode 100644 index 00000000..2cce0884 --- /dev/null +++ b/tests/.tests/IssueWithPassing.php @@ -0,0 +1,11 @@ +toBeTrue(); +}); + +it('references a missing dataset', function ($value) { + expect($value)->toBeTruthy(); +})->with('missing'); diff --git a/tests/Features/DatasetProviderErrors.php b/tests/Features/DatasetProviderErrors.php new file mode 100644 index 00000000..95fabb7d --- /dev/null +++ b/tests/Features/DatasetProviderErrors.php @@ -0,0 +1,49 @@ + 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true'], + ); + + $process->run(); + + return [ + 'output' => removeAnsiEscapeSequences($process->getOutput().$process->getErrorOutput()), + 'code' => $process->getExitCode(), + ]; +}; + +test('reports missing datasets as errors for a single file run', function () use ($run) { + $result = $run('tests/.tests/IssueOnly.php'); + + expect($result['output']) + ->toContain("A dataset with the name `missing` does not exist. You can create it using `dataset('missing', ['a', 'b']);`.") + ->toContain('FAILED') + ->toContain('Tests: 1 failed'); + + expect($result['code'])->not->toBe(0); +})->skipOnWindows(); + +test('reports missing datasets as errors alongside passing tests', function () use ($run) { + $result = $run('tests/.tests/IssueWithPassing.php'); + + expect($result['output']) + ->toContain("A dataset with the name `missing` does not exist. You can create it using `dataset('missing', ['a', 'b']);`.") + ->toContain('1 passed') + ->toContain('1 failed'); + + expect($result['code'])->not->toBe(0); +})->skipOnWindows(); + +test('reports dataset closure exceptions as errors', function () use ($run) { + $result = $run('tests/.tests/DatasetClosureThrows.php'); + + expect($result['output']) + ->toContain('boom from dataset'); + + expect($result['code'])->not->toBe(0); +})->skipOnWindows(); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 1e3c0d14..c5a76f60 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -24,13 +24,13 @@ test('parallel', function () use ($run) { $file = file_get_contents(__FILE__); $file = preg_replace( '/\$expected = \'.*?\';/', - "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1432 passed (3146 assertions)';", + "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1435 passed (3156 assertions)';", $file, ); file_put_contents(__FILE__, $file); } - $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1432 passed (3146 assertions)'; + $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1435 passed (3156 assertions)'; expect($output) ->toContain("Tests: {$expected}")