From b97e206f7a2cb094d4adaba0ca554d49a3040446 Mon Sep 17 00:00:00 2001 From: luke Date: Thu, 8 Jul 2021 09:44:28 +0100 Subject: [PATCH] Closures passed to the `skip` method are now bound to the test case to allow for more complex logic. --- src/PendingObjects/TestCall.php | 8 +++---- src/Plugins/Coverage.php | 1 - src/Support/HigherOrderMessage.php | 23 +++++++++++++++++++- src/Support/HigherOrderMessageCollection.php | 10 +++++++++ tests/Features/Skip.php | 8 +++++++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 39486565..76df5dac 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -143,11 +143,9 @@ final class TestCall ? $conditionOrMessage : $message; - if ($condition() !== false) { - $this->testCaseFactory - ->chains - ->add(Backtrace::file(), Backtrace::line(), 'markTestSkipped', [$message]); - } + $this->testCaseFactory + ->chains + ->addWhen($condition, Backtrace::file(), Backtrace::line(), 'markTestSkipped', [$message]); return $this; } diff --git a/src/Plugins/Coverage.php b/src/Plugins/Coverage.php index cc03bd17..6d993717 100644 --- a/src/Plugins/Coverage.php +++ b/src/Plugins/Coverage.php @@ -81,7 +81,6 @@ final class Coverage implements AddsOutput, HandlesArguments } if ($input->getOption(self::MIN_OPTION) !== null) { - /* @phpstan-ignore-next-line */ $this->coverageMin = (float) $input->getOption(self::MIN_OPTION); } diff --git a/src/Support/HigherOrderMessage.php b/src/Support/HigherOrderMessage.php index 9f363b5a..4479b21d 100644 --- a/src/Support/HigherOrderMessage.php +++ b/src/Support/HigherOrderMessage.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Pest\Support; +use Closure; +use const PHP_MAJOR_VERSION; use ReflectionClass; use Throwable; @@ -50,6 +52,13 @@ final class HigherOrderMessage */ public $arguments; + /** + * An optional condition that will determine if the message will be executed. + * + * @var callable|null + */ + public $condition = null; + /** * Creates a new higher order message. * @@ -70,6 +79,11 @@ final class HigherOrderMessage */ public function call(object $target) { + /* @phpstan-ignore-next-line */ + if (is_callable($this->condition) && call_user_func(Closure::bind($this->condition, $target)) === false) { + return $target; + } + try { return Reflection::call($target, $this->methodName, $this->arguments); } catch (Throwable $throwable) { @@ -88,9 +102,16 @@ final class HigherOrderMessage } } + public function when(callable $condition): self + { + $this->condition = $condition; + + return $this; + } + private static function getUndefinedMethodMessage(object $target, string $methodName): string { - if (\PHP_MAJOR_VERSION >= 8) { + if (PHP_MAJOR_VERSION >= 8) { return sprintf(sprintf(self::UNDEFINED_METHOD, sprintf('%s::%s()', get_class($target), $methodName))); } diff --git a/src/Support/HigherOrderMessageCollection.php b/src/Support/HigherOrderMessageCollection.php index f16765e1..4c6e9cd2 100644 --- a/src/Support/HigherOrderMessageCollection.php +++ b/src/Support/HigherOrderMessageCollection.php @@ -24,6 +24,16 @@ final class HigherOrderMessageCollection $this->messages[] = new HigherOrderMessage($filename, $line, $methodName, $arguments); } + /** + * Adds a new higher order message to the collection if the callable condition is does not return false. + * + * @param array $arguments + */ + public function addWhen(callable $condition, string $filename, int $line, string $methodName, array $arguments): void + { + $this->messages[] = (new HigherOrderMessage($filename, $line, $methodName, $arguments))->when($condition); + } + /** * Proxy all the messages starting from the target. */ diff --git a/tests/Features/Skip.php b/tests/Features/Skip.php index 66d6fe62..9102673b 100644 --- a/tests/Features/Skip.php +++ b/tests/Features/Skip.php @@ -1,5 +1,9 @@ shouldSkip = true; +}); + it('do not skips') ->skip(false) ->assertTrue(true); @@ -31,3 +35,7 @@ it('skips with condition and message') it('skips when skip after assertion') ->assertTrue(true) ->skip(); + +it('can use something in the test case as a condition') + ->skip(function () { return $this->shouldSkip; }, 'This test was skipped') + ->assertTrue(false);