diff --git a/src/PendingCalls/TestCall.php b/src/PendingCalls/TestCall.php index ccf9b4f9b..c0e126a04 100644 --- a/src/PendingCalls/TestCall.php +++ b/src/PendingCalls/TestCall.php @@ -5,6 +5,7 @@ namespace Pest\PendingCalls; use Closure; +use Pest\Concerns\Extendable; use Pest\Concerns\Testable; use Pest\Exceptions\InvalidArgumentException; use Pest\Exceptions\TestDescriptionMissing; @@ -37,6 +38,11 @@ final class TestCall // @phpstan-ignore-line { use Describable; + /** @use Extendable */ + use Extendable { + extend as traitExtend; + } + /** * The list of test case factory attributes. * @@ -727,9 +733,25 @@ public function __get(string $name): self */ public function __call(string $name, array $arguments): self { + if (self::hasExtend($name)) { + $extend = self::$extends[$name]->bindTo($this, TestCall::class); + + if ($extend != false) { // @pest-arch-ignore-line + return $extend(...$arguments); + } + } + return $this->addChain(Backtrace::file(), Backtrace::line(), $name, $arguments); } + public function extend(string $name, Closure $extend): void + { + $this->traitExtend($name, $extend); + + $this->description = "extend: $name"; + $this->testCaseMethod->closure = fn (): null => null; + } + /** * Add a chain to the test case factory. Omitting the arguments will treat it as a property accessor. * diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 58dbeddf4..c3db34ad3 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -1492,6 +1492,10 @@ ✓ a test ✓ higher order message test + PASS Tests\Features\TestCallExtend + ✓ it uses fooBar extension with ('foo') + ✓ it uses fooBar extension with ('bar') + PASS Tests\Features\ThrowsNoExceptions ✓ it allows access to the underlying expectNotToPerformAssertions method ✓ it allows performing no expectations without being risky @@ -1938,4 +1942,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, 1329 passed (3010 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1331 passed (3012 assertions) \ No newline at end of file diff --git a/tests/Features/TestCallExtend.php b/tests/Features/TestCallExtend.php new file mode 100644 index 000000000..91f4a6f5a --- /dev/null +++ b/tests/Features/TestCallExtend.php @@ -0,0 +1,17 @@ +extend('fooBar', function () { + return $this->with([ + 'foo', + 'bar', + ]); +}); + +it('uses fooBar extension', function ($value) { + assertTrue(in_array($value, [ + 'foo', + 'bar', + ])); +})->fooBar(); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 1055526b2..55fbee7b6 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -24,13 +24,13 @@ $file = file_get_contents(__FILE__); $file = preg_replace( '/\$expected = \'.*?\';/', - "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1313 passed (2959 assertions)';", + "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1315 passed (2961 assertions)';", $file, ); file_put_contents(__FILE__, $file); } - $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1313 passed (2959 assertions)'; + $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1315 passed (2961 assertions)'; expect($output) ->toContain("Tests: {$expected}")