diff --git a/src/Expectation.php b/src/Expectation.php index 2e581802..89d86f53 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -221,15 +221,16 @@ final class Expectation } /** - * It skips the tests in the callback if the condition is not truthy. + * Apply the callback if the given "condition" is truthy. * - * @param Closure|bool|string $condition + * @param (callable(): bool)|bool $condition + * @param callable(Expectation): mixed $callback */ public function when($condition, callable $callback): Expectation { $condition = is_callable($condition) ? $condition - : function () use ($condition) { + : static function () use ($condition): mixed { return $condition; }; diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index be839bff..287ca7a9 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -78,6 +78,26 @@ final class TestCall return $this; } + /** + * Asserts that the test throws the given `$exceptionClass` when called if the given condition is true. + * + * @param (callable(): bool)|bool $condition + */ + public function throwsIf($condition, string $exception, string $exceptionMessage = null): TestCall + { + $condition = is_callable($condition) + ? $condition + : static function () use ($condition): mixed { + return $condition; + }; + + if ($condition()) { + return $this->throws($exception, $exceptionMessage); + } + + return $this; + } + /** * Runs the current test multiple times with * each item of the given `iterable`. diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 07f7c56a..2e201e93 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -107,6 +107,11 @@ ✓ it catch exceptions ✓ it catch exceptions and messages ✓ it can just define the message + ✓ it not catch exceptions if given condition is false + ✓ it catch exceptions if given condition is true + ✓ it catch exceptions and messages if given condition is true + ✓ it can just define the message if given condition is true + ✓ it can just define the message if given condition is 1 PASS Tests\Features\Expect\HigherOrder\methods ✓ it can access methods @@ -701,5 +706,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 9 skipped, 463 passed + Tests: 4 incompleted, 9 skipped, 459 passed \ No newline at end of file diff --git a/tests/Features/Exceptions.php b/tests/Features/Exceptions.php index 37eaaeb9..9970c2a9 100644 --- a/tests/Features/Exceptions.php +++ b/tests/Features/Exceptions.php @@ -17,3 +17,23 @@ it('catch exceptions and messages', function () { it('can just define the message', function () { throw new Exception('Something bad happened'); })->throws('Something bad happened'); + +it('not catch exceptions if given condition is false', function () { + $this->assertTrue(true); +})->throwsIf(false, Exception::class); + +it('catch exceptions if given condition is true', function () { + throw new Exception('Something bad happened'); +})->throwsIf(function () { return true; }, Exception::class); + +it('catch exceptions and messages if given condition is true', function () { + throw new Exception('Something bad happened'); +})->throwsIf(true, Exception::class, 'Something bad happened'); + +it('can just define the message if given condition is true', function () { + throw new Exception('Something bad happened'); +})->throwsIf(true, 'Something bad happened'); + +it('can just define the message if given condition is 1', function () { + throw new Exception('Something bad happened'); +})->throwsIf(1, 'Something bad happened');