diff --git a/src/PendingCalls/TestCall.php b/src/PendingCalls/TestCall.php index a22ff11d6..43aeac319 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; @@ -31,6 +32,9 @@ final class TestCall // @phpstan-ignore-line { use Describable; + use Extendable { + extend as traitExtend; + } /** * The list of test case factory attributes. @@ -643,9 +647,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 90b1b0852..970a6cdc1 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -1324,6 +1324,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 @@ -1708,4 +1712,4 @@ WARN Tests\Visual\Version - visual snapshot of help command output - Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1152 passed (2744 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1154 passed (2746 assertions) 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 036f51d74..2b7635f62 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -16,7 +16,7 @@ test('parallel', function () use ($run) { expect($run('--exclude-group=integration')) - ->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1142 passed (2720 assertions)') + ->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1144 passed (2722 assertions)') ->toContain('Parallel: 3 processes'); })->skipOnWindows();