From 7a4dfaa682c9e3cf62f1adfade74d7f72bad4d07 Mon Sep 17 00:00:00 2001 From: Roel van Duijnhoven Date: Mon, 25 Jan 2021 16:45:58 +0100 Subject: [PATCH] Add implies as a logical assertion. This assertion can be used to easily assert stuff like: > Assert::implies($hasDog, $leashAttached); Which will assert that $leashAttached is true, if $hasDog is true. This is a shorthand for `Assert::true(!$hasDog || $leashAttached)`. --- README.md | 2 + src/Assert.php | 14 +++++++ src/Mixin.php | 22 +++++++++++ tests/AssertTest.php | 4 ++ tests/static-analysis/assert-implies.php | 50 ++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 tests/static-analysis/assert-implies.php diff --git a/README.md b/README.md index 9f53f8fa..71c53749 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ Method | Description `range($value, $min, $max, $message = '')` | Check that a value is within a range `inArray($value, array $values, $message = '')` | Check that a value is one of a list of values `oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values (alias of `inArray`) +`implies($p, $q, $message = '')` | Check that `$p` logically implies `$q` (i.e. _if_ `$p` is true, than `$q` must be true). + ### String Assertions diff --git a/src/Assert.php b/src/Assert.php index b28e1784..ffd4df96 100644 --- a/src/Assert.php +++ b/src/Assert.php @@ -658,6 +658,20 @@ public static function notFalse($value, $message = '') } } + /** + * @psalm-pure + * + * @param bool $p + * @param bool $q + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function implies($p, $q, $message = '') + { + self::true(!$p || $q, $message ?: 'Logical implication $p => $q did not hold.'); + } + /** * @param mixed $value * @param string $message diff --git a/src/Mixin.php b/src/Mixin.php index ccc43990..bdca658b 100644 --- a/src/Mixin.php +++ b/src/Mixin.php @@ -677,6 +677,28 @@ public static function nullOrNotFalse($value, $message = ''); */ public static function allNotFalse($value, $message = ''); + /** + * @psalm-pure + * + * @param bool|null $p + * @param bool $q + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function nullOrImplies($p, $q, $message = ''); + + /** + * @psalm-pure + * + * @param iterable $p + * @param bool $q + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function allImplies($p, $q, $message = ''); + /** * @param mixed $value * @param string $message diff --git a/tests/AssertTest.php b/tests/AssertTest.php index 2b90c67b..ea49f737 100644 --- a/tests/AssertTest.php +++ b/tests/AssertTest.php @@ -226,6 +226,10 @@ public function getTests() array('range', array(2, 1, 2), true), array('range', array(0, 1, 2), false), array('range', array(3, 1, 2), false), + array('implies', array(true, true), true), + array('implies', array(true, false), false), + array('implies', array(false, true), true), + array('implies', array(false, false), true), array('oneOf', array(1, array(1, 2, 3)), true), array('oneOf', array(1, array('1', '2', '3')), false), array('inArray', array(1, array(1, 2, 3)), true), diff --git a/tests/static-analysis/assert-implies.php b/tests/static-analysis/assert-implies.php new file mode 100644 index 00000000..87f13640 --- /dev/null +++ b/tests/static-analysis/assert-implies.php @@ -0,0 +1,50 @@ + $p + * @param bool $q + * + * @return iterable + */ +function allImplies(iterable $value, $p, $q): iterable +{ + Assert::allImplies($value, $p, $q); + + return $value; +}