From a2119316b4bef2706cb398d7a7e8fba53907d87c Mon Sep 17 00:00:00 2001 From: Zlatoslav Desyatnikov Date: Sun, 20 Oct 2024 19:08:37 +0400 Subject: [PATCH 1/3] feat: add validRegexPattern --- src/Assert.php | 20 +++++++++++++++++ src/Mixin.php | 53 ++++++++++++++++++++++++++++++++++++++++++++ tests/AssertTest.php | 6 +++++ 3 files changed, 79 insertions(+) diff --git a/src/Assert.php b/src/Assert.php index b962e3e..b115ab9 100644 --- a/src/Assert.php +++ b/src/Assert.php @@ -1227,6 +1227,26 @@ public static function notRegex($value, $pattern, $message = '') } } + /** + * @psalm-pure + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function validRegexPattern($value, $message = 'The value %s must be a valid regex pattern.') + { + static::string($value); + + if (@\preg_match($value, '') === false) { + static::reportInvalidArgument(\sprintf( + $message, + static::valueToString($value) + )); + } + } + /** * @psalm-pure * diff --git a/src/Mixin.php b/src/Mixin.php index fad0d47..e85b0d9 100644 --- a/src/Mixin.php +++ b/src/Mixin.php @@ -5207,4 +5207,57 @@ public static function allNullOrThrows($expression, $class = 'Exception', $messa null === $entry || static::throws($entry, $class, $message); } } + + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function nullOrValidRegexPattern($value, $message = '') + { + null === $value || static::validRegexPattern($value, $message); + } + + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function allValidRegexPattern($value, $message = '') + { + static::isIterable($value); + + foreach ($value as $entry) { + static::validRegexPattern($entry, $message); + } + } + + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function allNullOrValidRegexPattern($value, $message = '') + { + static::isIterable($value); + + foreach ($value as $entry) { + null === $entry || static::validRegexPattern($entry, $message); + } + } } diff --git a/tests/AssertTest.php b/tests/AssertTest.php index ef9b6be..b8b48ce 100644 --- a/tests/AssertTest.php +++ b/tests/AssertTest.php @@ -595,6 +595,12 @@ public function getTests() array('uniqueValues', array(array('qwerty', 'qwerty')), false), array('uniqueValues', array(array('asdfg', 'qwerty')), true), array('uniqueValues', array(array(123, '123')), false), + array('validRegexPattern', array('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/'), true), + array('validRegexPattern', array('/^\(\d{3}\) \d{3}-\d{4}$/'), true), + array('validRegexPattern', array('/^https?:\/\/[^\s/$.?#].[^\s]*$/i'), true), + array('validRegexPattern', array('/^(abc/'), false), // Unclosed parenthesis + array('validRegexPattern', array('/[a-z-]/'), false), // Improper character class + array('validRegexPattern', array('/(?:abc)\1/'), false), // Backreference to non-capturing group ); } From 471072b049f2d3b72b1f87b1ed4dcd8f535d0c8f Mon Sep 17 00:00:00 2001 From: Zlatoslav Desyatnikov Date: Sun, 20 Oct 2024 20:56:04 +0400 Subject: [PATCH 2/3] fix tests --- README.md | 1 + src/Assert.php | 2 +- src/Mixin.php | 106 +++++++++++++++++++++---------------------- tests/AssertTest.php | 4 +- 4 files changed, 57 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 766099c..85a9885 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ Method | Description `ipv6($value, $message = '')` | Check that a string is a valid IPv6 `email($value, $message = '')` | Check that a string is a valid e-mail address `notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character +`validRegexPattern($value, $message = '')` | Check that a string is a valid regular expression pattern ### File Assertions diff --git a/src/Assert.php b/src/Assert.php index b115ab9..05c1349 100644 --- a/src/Assert.php +++ b/src/Assert.php @@ -1242,7 +1242,7 @@ public static function validRegexPattern($value, $message = 'The value %s must b if (@\preg_match($value, '') === false) { static::reportInvalidArgument(\sprintf( $message, - static::valueToString($value) + $value )); } } diff --git a/src/Mixin.php b/src/Mixin.php index e85b0d9..9f1edd4 100644 --- a/src/Mixin.php +++ b/src/Mixin.php @@ -3200,6 +3200,59 @@ public static function allNullOrNotRegex($value, $pattern, $message = '') } } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function nullOrValidRegexPattern($value, $message = 'The value %s must be a valid regex pattern.') + { + null === $value || static::validRegexPattern($value, $message); + } + + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function allValidRegexPattern($value, $message = 'The value %s must be a valid regex pattern.') + { + static::isIterable($value); + + foreach ($value as $entry) { + static::validRegexPattern($entry, $message); + } + } + + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @return void + * + * @throws InvalidArgumentException + */ + public static function allNullOrValidRegexPattern($value, $message = 'The value %s must be a valid regex pattern.') + { + static::isIterable($value); + + foreach ($value as $entry) { + null === $entry || static::validRegexPattern($entry, $message); + } + } + /** * @psalm-pure * @@ -5207,57 +5260,4 @@ public static function allNullOrThrows($expression, $class = 'Exception', $messa null === $entry || static::throws($entry, $class, $message); } } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @return void - * - * @throws InvalidArgumentException - */ - public static function nullOrValidRegexPattern($value, $message = '') - { - null === $value || static::validRegexPattern($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @return void - * - * @throws InvalidArgumentException - */ - public static function allValidRegexPattern($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::validRegexPattern($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @return void - * - * @throws InvalidArgumentException - */ - public static function allNullOrValidRegexPattern($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::validRegexPattern($entry, $message); - } - } } diff --git a/tests/AssertTest.php b/tests/AssertTest.php index b8b48ce..26cc6ac 100644 --- a/tests/AssertTest.php +++ b/tests/AssertTest.php @@ -597,9 +597,9 @@ public function getTests() array('uniqueValues', array(array(123, '123')), false), array('validRegexPattern', array('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/'), true), array('validRegexPattern', array('/^\(\d{3}\) \d{3}-\d{4}$/'), true), - array('validRegexPattern', array('/^https?:\/\/[^\s/$.?#].[^\s]*$/i'), true), + array('validRegexPattern', array('/^https?:\/\/[^\s\/$.?#].[^\s]*$/i'), true), array('validRegexPattern', array('/^(abc/'), false), // Unclosed parenthesis - array('validRegexPattern', array('/[a-z-]/'), false), // Improper character class + array('validRegexPattern', array('/\p{Foo}/'), false), // Improper Unicode category array('validRegexPattern', array('/(?:abc)\1/'), false), // Backreference to non-capturing group ); } From 877070d7551a69199466a1af4340ead0ccd6149e Mon Sep 17 00:00:00 2001 From: Zlatoslav Desyatnikov Date: Mon, 21 Oct 2024 13:16:13 +0400 Subject: [PATCH 3/3] fix tests: drop non-stable test failing in php < 8.0 --- tests/AssertTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/AssertTest.php b/tests/AssertTest.php index 26cc6ac..d5734e8 100644 --- a/tests/AssertTest.php +++ b/tests/AssertTest.php @@ -599,7 +599,6 @@ public function getTests() array('validRegexPattern', array('/^\(\d{3}\) \d{3}-\d{4}$/'), true), array('validRegexPattern', array('/^https?:\/\/[^\s\/$.?#].[^\s]*$/i'), true), array('validRegexPattern', array('/^(abc/'), false), // Unclosed parenthesis - array('validRegexPattern', array('/\p{Foo}/'), false), // Improper Unicode category array('validRegexPattern', array('/(?:abc)\1/'), false), // Backreference to non-capturing group ); }