diff --git a/docs/case-sensitiveness.md b/docs/case-sensitiveness.md new file mode 100644 index 00000000..6e5760a9 --- /dev/null +++ b/docs/case-sensitiveness.md @@ -0,0 +1,35 @@ + + +# Case Insensitive Validation + +For most simple cases, you can use `v::call` wrappers to perform +case normalization before comparison. + +For strings: + +```php +v::call(strtolower(...), v::contains('cde'))->assert('ABCDEF'); +// Validation passes successfully + +v::call(strtolower(...), v::contains('xxx'))->assert('ABCDEF'); +// → "abcdef" must contain "xxx" +``` + +For arrays: + +```php +v::call( + static fn ($i) => array_map(strtolower(...), $i), + v::contains('abc') +)->assert(['ABC', 'DEF']); +// Validation passes successfully + +v::call( + static fn ($i) => array_map(strtolower(...), $i), + v::contains('xxx') +)->assert(['ABC', 'DEF']); +// → `["abc", "def"]` must contain "xxx" +``` diff --git a/docs/migrating-from-v2-to-v3.md b/docs/migrating-from-v2-to-v3.md index d2b03667..f66f96f4 100644 --- a/docs/migrating-from-v2-to-v3.md +++ b/docs/migrating-from-v2-to-v3.md @@ -296,6 +296,42 @@ v::each(v::alwaysValid())->isValid([]); // false (empty) + v::intType()->assert($input); ``` +##### Call does not handle errors anymore + +`Call` now does not handle PHP errors inside the callback you provided. + +```php +v::call('strtolower', v::equals('foo'))->assert(123); // Error bubbles out +``` + +You can use anonymous functions to handle errors or perform type conversions +instead: + +```php +v::call(static fn ($i) => strtolower((string) $i), v::equals('123')); +``` + +##### `Contains`, `ContainsAny`, `In`, `EndsWith` and `StartsWith` strict by default. + +The parameter `$identical`, which controlled case-insensitivy and strict typing was +removed. Now these validators will always compare _case-sensitive_ and use +_strict typing_. + +```diff +- v::contains('needle', identical: true); +- v::containsAny(['needle1', 'needle2'], identical: true); +- v::in(['hay', 'stack'], compareIdentical: true); +- v::startsWith('needle', identical: true); +- v::endsWith('needle', identical: true); ++ v::contains('needle'); // always strict case and type ++ v::containsAny(['needle1', 'needle2']); // always strict case and type ++ v::in(['hay', 'stack']); // always strict case and type ++ v::startsWith('needle'); // always strict case and type ++ v::endsWith('needle'); // always strict case and type +``` + +For more information, refer to [case-sensitiveness.md](case-sensitiveness.md) + ##### New package dependencies Some validators now require additional packages: diff --git a/docs/validators/Call.md b/docs/validators/Call.md index c9308992..3e756946 100644 --- a/docs/validators/Call.md +++ b/docs/validators/Call.md @@ -52,22 +52,20 @@ v::call( // Validation passes successfully ``` -## Templates +Call does not handle possible errors (type mismatches). If you need to +ensure that your callback is of a certain type, use [Circuit](Circuit.md) or +handle it using a closure: -### `Call::TEMPLATE_STANDARD` +```php +v::call('strtolower', v::equals('ABC'))->assert(123); +// 𝙭 strtolower(): Argument #1 ($string) must be of type string, int given -| Mode | Template | -| ---------: | :--------------------------------------------------------- | -| `default` | {{input}} must be a suitable argument for {{callable}} | -| `inverted` | {{input}} must not be a suitable argument for {{callable}} | +v::circuit(v::stringType(), v::call('strtolower', v::equals('abc')))->assert(123); +// → 123 must be a string -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `callable` | | -| `input` | | -| `subject` | The validated input or the custom validator name (if specified). | +v::circuit(v::stringType(), v::call('strtolower', v::equals('abc')))->assert('ABC'); +// Validation passes successfully +``` ## Categorization @@ -77,9 +75,10 @@ v::call( ## Changelog -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | +| Version | Description | +| ------: | :---------------------------- | +| 3.0.0 | No longer sets error handlers | +| 0.3.9 | Created | ## See Also diff --git a/docs/validators/Contains.md b/docs/validators/Contains.md index ccb2c61f..c9b82da9 100644 --- a/docs/validators/Contains.md +++ b/docs/validators/Contains.md @@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT # Contains - `Contains(mixed $containsValue)` -- `Contains(mixed $containsValue, bool $identical)` Validates if the input contains some value. @@ -24,9 +23,6 @@ v::contains('ipsum')->assert(['ipsum', 'lorem']); // Validation passes successfully ``` -A second parameter may be passed for identical comparison instead -of equal comparison. - Message template for this validator includes `{{containsValue}}`. ## Templates @@ -52,9 +48,10 @@ Message template for this validator includes `{{containsValue}}`. ## Changelog -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | +| Version | Description | +| ------: | :---------------------------------- | +| 3.0.0 | Case-insensitive comparison removed | +| 0.3.9 | Created | ## See Also diff --git a/docs/validators/ContainsAny.md b/docs/validators/ContainsAny.md index 67c6e738..0d77db81 100644 --- a/docs/validators/ContainsAny.md +++ b/docs/validators/ContainsAny.md @@ -6,27 +6,23 @@ SPDX-License-Identifier: MIT # ContainsAny - `ContainsAny(non-empty-array $needles)` -- `ContainsAny(non-empty-array $needles, bool $identical)` Validates if the input contains at least one of defined values -For strings (comparing is case insensitive): +For strings: ```php v::containsAny(['lorem', 'dolor'])->assert('lorem ipsum'); // Validation passes successfully ``` -For arrays (comparing is case sensitive to respect "contains" behavior): +For arrays: ```php v::containsAny(['lorem', 'dolor'])->assert(['ipsum', 'lorem']); // Validation passes successfully ``` -A second parameter may be passed for identical comparison instead -of equal comparison for arrays. - Message template for this validator includes `{{needles}}`. ## Templates @@ -52,9 +48,10 @@ Message template for this validator includes `{{needles}}`. ## Changelog -| Version | Description | -| ------: | :---------- | -| 2.0.0 | Created | +| Version | Description | +| ------: | :---------------------------------- | +| 3.0.0 | Case-insensitive comparison removed | +| 2.0.0 | Created | ## See Also diff --git a/docs/validators/ContainsCount.md b/docs/validators/ContainsCount.md index 87ae6039..b13dc177 100644 --- a/docs/validators/ContainsCount.md +++ b/docs/validators/ContainsCount.md @@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT # ContainsCount - `ContainsCount(mixed $containsValue, int $count)` -- `ContainsCount(mixed $containsValue, int $count, bool $identical)` Validates if the input contains a value a specific number of times. @@ -24,16 +23,6 @@ v::containsCount('ipsum', 2)->assert(['ipsum', 'lorem', 'ipsum']); // Validation passes successfully ``` -A third parameter may be passed for identical comparison instead of equal comparison. - -```php -v::containsCount(1, 1, true)->assert([1, 2, 3]); -// Validation passes successfully - -v::containsCount('1', 1, true)->assert([1, 2, 3]); -// → `[1, 2, 3]` must contain "1" only once -``` - ## Templates ### `ContainsCount::TEMPLATE_TIMES` diff --git a/docs/validators/EndsWith.md b/docs/validators/EndsWith.md index 2c540ae2..3bdc31bd 100644 --- a/docs/validators/EndsWith.md +++ b/docs/validators/EndsWith.md @@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT # EndsWith - `EndsWith(mixed $endValue)` -- `EndsWith(mixed $endValue, bool $identical)` This validator is similar to `Contains()`, but validates only if the value is at the end of the input. @@ -25,9 +24,6 @@ v::endsWith('ipsum')->assert(['lorem', 'ipsum']); // Validation passes successfully ``` -A second parameter may be passed for identical comparison instead -of equal comparison. - Message template for this validator includes `{{endValue}}`. ## Templates @@ -53,9 +49,10 @@ Message template for this validator includes `{{endValue}}`. ## Changelog -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | +| Version | Description | +| ------: | :---------------------------------- | +| 3.0.0 | Case-insensitive comparison removed | +| 0.3.9 | Created | ## See Also diff --git a/docs/validators/In.md b/docs/validators/In.md index 3252461f..e3babe31 100644 --- a/docs/validators/In.md +++ b/docs/validators/In.md @@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT # In - `In(mixed $haystack)` -- `In(mixed $haystack, bool $compareIdentical)` Validates if the input is contained in a specific haystack. @@ -24,9 +23,6 @@ v::in(['lorem', 'ipsum'])->assert('lorem'); // Validation passes successfully ``` -A second parameter may be passed for identical comparison instead -of equal comparison. - Message template for this validator includes `{{haystack}}`. ## Templates @@ -53,9 +49,10 @@ Message template for this validator includes `{{haystack}}`. ## Changelog -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | +| Version | Description | +| ------: | :---------------------------------- | +| 3.0.0 | Case-insensitive comparison removed | +| 0.3.9 | Created | ## See Also diff --git a/docs/validators/StartsWith.md b/docs/validators/StartsWith.md index acaec37d..d6b9ea98 100644 --- a/docs/validators/StartsWith.md +++ b/docs/validators/StartsWith.md @@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT # StartsWith - `StartsWith(mixed $startValue)` -- `StartsWith(mixed $startValue, bool $identical)` Validates whether the input starts with a given value. @@ -27,9 +26,6 @@ v::startsWith('lorem')->assert(['lorem', 'ipsum']); // Validation passes successfully ``` -`true` may be passed as a parameter to indicate identical comparison -instead of equal. - Message template for this validator includes `{{startValue}}`. ## Templates @@ -55,9 +51,10 @@ Message template for this validator includes `{{startValue}}`. ## Changelog -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | +| Version | Description | +| ------: | :---------------------------------- | +| 3.0.0 | Case-insensitive comparison removed | +| 0.3.9 | Created | ## See Also diff --git a/src/Mixins/AllBuilder.php b/src/Mixins/AllBuilder.php index 6f8f4979..5bcfa901 100644 --- a/src/Mixins/AllBuilder.php +++ b/src/Mixins/AllBuilder.php @@ -64,12 +64,12 @@ interface AllBuilder public static function allConsonant(string ...$additionalChars): Chain; - public static function allContains(mixed $containsValue, bool $identical = false): Chain; + public static function allContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function allContainsAny(array $needles, bool $identical = false): Chain; + public static function allContainsAny(array $needles): Chain; - public static function allContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public static function allContainsCount(mixed $containsValue, int $count): Chain; public static function allControl(string ...$additionalChars): Chain; @@ -106,7 +106,7 @@ interface AllBuilder public static function allEmoji(): Chain; - public static function allEndsWith(mixed $endValue, bool $identical = false): Chain; + public static function allEndsWith(mixed $endValue): Chain; public static function allEquals(mixed $compareTo): Chain; @@ -150,7 +150,7 @@ interface AllBuilder public static function allImei(): Chain; - public static function allIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function allIn(mixed $haystack): Chain; public static function allInfinite(): Chain; @@ -266,7 +266,7 @@ interface AllBuilder public static function allSpaced(): Chain; - public static function allStartsWith(mixed $startValue, bool $identical = false): Chain; + public static function allStartsWith(mixed $startValue): Chain; public static function allStringType(): Chain; diff --git a/src/Mixins/AllChain.php b/src/Mixins/AllChain.php index ab51c72c..63b213a1 100644 --- a/src/Mixins/AllChain.php +++ b/src/Mixins/AllChain.php @@ -64,12 +64,12 @@ interface AllChain public function allConsonant(string ...$additionalChars): Chain; - public function allContains(mixed $containsValue, bool $identical = false): Chain; + public function allContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function allContainsAny(array $needles, bool $identical = false): Chain; + public function allContainsAny(array $needles): Chain; - public function allContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public function allContainsCount(mixed $containsValue, int $count): Chain; public function allControl(string ...$additionalChars): Chain; @@ -106,7 +106,7 @@ interface AllChain public function allEmoji(): Chain; - public function allEndsWith(mixed $endValue, bool $identical = false): Chain; + public function allEndsWith(mixed $endValue): Chain; public function allEquals(mixed $compareTo): Chain; @@ -150,7 +150,7 @@ interface AllChain public function allImei(): Chain; - public function allIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function allIn(mixed $haystack): Chain; public function allInfinite(): Chain; @@ -266,7 +266,7 @@ interface AllChain public function allSpaced(): Chain; - public function allStartsWith(mixed $startValue, bool $identical = false): Chain; + public function allStartsWith(mixed $startValue): Chain; public function allStringType(): Chain; diff --git a/src/Mixins/Builder.php b/src/Mixins/Builder.php index 64c70bf8..b93e3af8 100644 --- a/src/Mixins/Builder.php +++ b/src/Mixins/Builder.php @@ -69,12 +69,12 @@ interface Builder extends AllBuilder, KeyBuilder, LengthBuilder, MaxBuilder, Min public static function consonant(string ...$additionalChars): Chain; - public static function contains(mixed $containsValue, bool $identical = false): Chain; + public static function contains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function containsAny(array $needles, bool $identical = false): Chain; + public static function containsAny(array $needles): Chain; - public static function containsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public static function containsCount(mixed $containsValue, int $count): Chain; public static function control(string ...$additionalChars): Chain; @@ -111,7 +111,7 @@ interface Builder extends AllBuilder, KeyBuilder, LengthBuilder, MaxBuilder, Min public static function emoji(): Chain; - public static function endsWith(mixed $endValue, bool $identical = false): Chain; + public static function endsWith(mixed $endValue): Chain; public static function equals(mixed $compareTo): Chain; @@ -157,7 +157,7 @@ interface Builder extends AllBuilder, KeyBuilder, LengthBuilder, MaxBuilder, Min public static function imei(): Chain; - public static function in(mixed $haystack, bool $compareIdentical = false): Chain; + public static function in(mixed $haystack): Chain; public static function infinite(): Chain; @@ -291,7 +291,7 @@ interface Builder extends AllBuilder, KeyBuilder, LengthBuilder, MaxBuilder, Min public static function spaced(): Chain; - public static function startsWith(mixed $startValue, bool $identical = false): Chain; + public static function startsWith(mixed $startValue): Chain; public static function stringType(): Chain; diff --git a/src/Mixins/Chain.php b/src/Mixins/Chain.php index b8ef56be..432aa52b 100644 --- a/src/Mixins/Chain.php +++ b/src/Mixins/Chain.php @@ -71,12 +71,12 @@ interface Chain extends Validator, AllChain, KeyChain, LengthChain, MaxChain, Mi public function consonant(string ...$additionalChars): Chain; - public function contains(mixed $containsValue, bool $identical = false): Chain; + public function contains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function containsAny(array $needles, bool $identical = false): Chain; + public function containsAny(array $needles): Chain; - public function containsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public function containsCount(mixed $containsValue, int $count): Chain; public function control(string ...$additionalChars): Chain; @@ -113,7 +113,7 @@ interface Chain extends Validator, AllChain, KeyChain, LengthChain, MaxChain, Mi public function emoji(): Chain; - public function endsWith(mixed $endValue, bool $identical = false): Chain; + public function endsWith(mixed $endValue): Chain; public function equals(mixed $compareTo): Chain; @@ -159,7 +159,7 @@ interface Chain extends Validator, AllChain, KeyChain, LengthChain, MaxChain, Mi public function imei(): Chain; - public function in(mixed $haystack, bool $compareIdentical = false): Chain; + public function in(mixed $haystack): Chain; public function infinite(): Chain; @@ -293,7 +293,7 @@ interface Chain extends Validator, AllChain, KeyChain, LengthChain, MaxChain, Mi public function spaced(): Chain; - public function startsWith(mixed $startValue, bool $identical = false): Chain; + public function startsWith(mixed $startValue): Chain; public function stringType(): Chain; diff --git a/src/Mixins/KeyBuilder.php b/src/Mixins/KeyBuilder.php index ab2b1625..ee78982e 100644 --- a/src/Mixins/KeyBuilder.php +++ b/src/Mixins/KeyBuilder.php @@ -66,12 +66,12 @@ interface KeyBuilder public static function keyConsonant(int|string $key, string ...$additionalChars): Chain; - public static function keyContains(int|string $key, mixed $containsValue, bool $identical = false): Chain; + public static function keyContains(int|string $key, mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function keyContainsAny(int|string $key, array $needles, bool $identical = false): Chain; + public static function keyContainsAny(int|string $key, array $needles): Chain; - public static function keyContainsCount(int|string $key, mixed $containsValue, int $count, bool $identical = false): Chain; + public static function keyContainsCount(int|string $key, mixed $containsValue, int $count): Chain; public static function keyControl(int|string $key, string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface KeyBuilder public static function keyEmoji(int|string $key): Chain; - public static function keyEndsWith(int|string $key, mixed $endValue, bool $identical = false): Chain; + public static function keyEndsWith(int|string $key, mixed $endValue): Chain; public static function keyEquals(int|string $key, mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface KeyBuilder public static function keyImei(int|string $key): Chain; - public static function keyIn(int|string $key, mixed $haystack, bool $compareIdentical = false): Chain; + public static function keyIn(int|string $key, mixed $haystack): Chain; public static function keyInfinite(int|string $key): Chain; @@ -268,7 +268,7 @@ interface KeyBuilder public static function keySpaced(int|string $key): Chain; - public static function keyStartsWith(int|string $key, mixed $startValue, bool $identical = false): Chain; + public static function keyStartsWith(int|string $key, mixed $startValue): Chain; public static function keyStringType(int|string $key): Chain; diff --git a/src/Mixins/KeyChain.php b/src/Mixins/KeyChain.php index fba445aa..d038f9c6 100644 --- a/src/Mixins/KeyChain.php +++ b/src/Mixins/KeyChain.php @@ -66,12 +66,12 @@ interface KeyChain public function keyConsonant(int|string $key, string ...$additionalChars): Chain; - public function keyContains(int|string $key, mixed $containsValue, bool $identical = false): Chain; + public function keyContains(int|string $key, mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function keyContainsAny(int|string $key, array $needles, bool $identical = false): Chain; + public function keyContainsAny(int|string $key, array $needles): Chain; - public function keyContainsCount(int|string $key, mixed $containsValue, int $count, bool $identical = false): Chain; + public function keyContainsCount(int|string $key, mixed $containsValue, int $count): Chain; public function keyControl(int|string $key, string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface KeyChain public function keyEmoji(int|string $key): Chain; - public function keyEndsWith(int|string $key, mixed $endValue, bool $identical = false): Chain; + public function keyEndsWith(int|string $key, mixed $endValue): Chain; public function keyEquals(int|string $key, mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface KeyChain public function keyImei(int|string $key): Chain; - public function keyIn(int|string $key, mixed $haystack, bool $compareIdentical = false): Chain; + public function keyIn(int|string $key, mixed $haystack): Chain; public function keyInfinite(int|string $key): Chain; @@ -268,7 +268,7 @@ interface KeyChain public function keySpaced(int|string $key): Chain; - public function keyStartsWith(int|string $key, mixed $startValue, bool $identical = false): Chain; + public function keyStartsWith(int|string $key, mixed $startValue): Chain; public function keyStringType(int|string $key): Chain; diff --git a/src/Mixins/LengthBuilder.php b/src/Mixins/LengthBuilder.php index f03ecfe1..229cef3d 100644 --- a/src/Mixins/LengthBuilder.php +++ b/src/Mixins/LengthBuilder.php @@ -32,7 +32,7 @@ interface LengthBuilder public static function lengthIdentical(mixed $compareTo): Chain; - public static function lengthIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function lengthIn(mixed $haystack): Chain; public static function lengthInfinite(): Chain; diff --git a/src/Mixins/LengthChain.php b/src/Mixins/LengthChain.php index 8b21c3b3..d455b378 100644 --- a/src/Mixins/LengthChain.php +++ b/src/Mixins/LengthChain.php @@ -32,7 +32,7 @@ interface LengthChain public function lengthIdentical(mixed $compareTo): Chain; - public function lengthIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function lengthIn(mixed $haystack): Chain; public function lengthInfinite(): Chain; diff --git a/src/Mixins/MaxBuilder.php b/src/Mixins/MaxBuilder.php index a3daefe7..1f480354 100644 --- a/src/Mixins/MaxBuilder.php +++ b/src/Mixins/MaxBuilder.php @@ -32,7 +32,7 @@ interface MaxBuilder public static function maxIdentical(mixed $compareTo): Chain; - public static function maxIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function maxIn(mixed $haystack): Chain; public static function maxInfinite(): Chain; diff --git a/src/Mixins/MaxChain.php b/src/Mixins/MaxChain.php index 485785de..42f2cd15 100644 --- a/src/Mixins/MaxChain.php +++ b/src/Mixins/MaxChain.php @@ -32,7 +32,7 @@ interface MaxChain public function maxIdentical(mixed $compareTo): Chain; - public function maxIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function maxIn(mixed $haystack): Chain; public function maxInfinite(): Chain; diff --git a/src/Mixins/MinBuilder.php b/src/Mixins/MinBuilder.php index 115aebbe..21c45dcf 100644 --- a/src/Mixins/MinBuilder.php +++ b/src/Mixins/MinBuilder.php @@ -32,7 +32,7 @@ interface MinBuilder public static function minIdentical(mixed $compareTo): Chain; - public static function minIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function minIn(mixed $haystack): Chain; public static function minInfinite(): Chain; diff --git a/src/Mixins/MinChain.php b/src/Mixins/MinChain.php index 8aa73e0b..7af8663c 100644 --- a/src/Mixins/MinChain.php +++ b/src/Mixins/MinChain.php @@ -32,7 +32,7 @@ interface MinChain public function minIdentical(mixed $compareTo): Chain; - public function minIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function minIn(mixed $haystack): Chain; public function minInfinite(): Chain; diff --git a/src/Mixins/NotBuilder.php b/src/Mixins/NotBuilder.php index 680ddeba..b07b0c76 100644 --- a/src/Mixins/NotBuilder.php +++ b/src/Mixins/NotBuilder.php @@ -66,12 +66,12 @@ interface NotBuilder public static function notConsonant(string ...$additionalChars): Chain; - public static function notContains(mixed $containsValue, bool $identical = false): Chain; + public static function notContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function notContainsAny(array $needles, bool $identical = false): Chain; + public static function notContainsAny(array $needles): Chain; - public static function notContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public static function notContainsCount(mixed $containsValue, int $count): Chain; public static function notControl(string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface NotBuilder public static function notEmoji(): Chain; - public static function notEndsWith(mixed $endValue, bool $identical = false): Chain; + public static function notEndsWith(mixed $endValue): Chain; public static function notEquals(mixed $compareTo): Chain; @@ -154,7 +154,7 @@ interface NotBuilder public static function notImei(): Chain; - public static function notIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function notIn(mixed $haystack): Chain; public static function notInfinite(): Chain; @@ -282,7 +282,7 @@ interface NotBuilder public static function notSpaced(): Chain; - public static function notStartsWith(mixed $startValue, bool $identical = false): Chain; + public static function notStartsWith(mixed $startValue): Chain; public static function notStringType(): Chain; diff --git a/src/Mixins/NotChain.php b/src/Mixins/NotChain.php index 7437b414..d75fb6c4 100644 --- a/src/Mixins/NotChain.php +++ b/src/Mixins/NotChain.php @@ -66,12 +66,12 @@ interface NotChain public function notConsonant(string ...$additionalChars): Chain; - public function notContains(mixed $containsValue, bool $identical = false): Chain; + public function notContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function notContainsAny(array $needles, bool $identical = false): Chain; + public function notContainsAny(array $needles): Chain; - public function notContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public function notContainsCount(mixed $containsValue, int $count): Chain; public function notControl(string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface NotChain public function notEmoji(): Chain; - public function notEndsWith(mixed $endValue, bool $identical = false): Chain; + public function notEndsWith(mixed $endValue): Chain; public function notEquals(mixed $compareTo): Chain; @@ -154,7 +154,7 @@ interface NotChain public function notImei(): Chain; - public function notIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function notIn(mixed $haystack): Chain; public function notInfinite(): Chain; @@ -282,7 +282,7 @@ interface NotChain public function notSpaced(): Chain; - public function notStartsWith(mixed $startValue, bool $identical = false): Chain; + public function notStartsWith(mixed $startValue): Chain; public function notStringType(): Chain; diff --git a/src/Mixins/NullOrBuilder.php b/src/Mixins/NullOrBuilder.php index a276b756..d1d12340 100644 --- a/src/Mixins/NullOrBuilder.php +++ b/src/Mixins/NullOrBuilder.php @@ -66,12 +66,12 @@ interface NullOrBuilder public static function nullOrConsonant(string ...$additionalChars): Chain; - public static function nullOrContains(mixed $containsValue, bool $identical = false): Chain; + public static function nullOrContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function nullOrContainsAny(array $needles, bool $identical = false): Chain; + public static function nullOrContainsAny(array $needles): Chain; - public static function nullOrContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public static function nullOrContainsCount(mixed $containsValue, int $count): Chain; public static function nullOrControl(string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface NullOrBuilder public static function nullOrEmoji(): Chain; - public static function nullOrEndsWith(mixed $endValue, bool $identical = false): Chain; + public static function nullOrEndsWith(mixed $endValue): Chain; public static function nullOrEquals(mixed $compareTo): Chain; @@ -154,7 +154,7 @@ interface NullOrBuilder public static function nullOrImei(): Chain; - public static function nullOrIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function nullOrIn(mixed $haystack): Chain; public static function nullOrInfinite(): Chain; @@ -284,7 +284,7 @@ interface NullOrBuilder public static function nullOrSpaced(): Chain; - public static function nullOrStartsWith(mixed $startValue, bool $identical = false): Chain; + public static function nullOrStartsWith(mixed $startValue): Chain; public static function nullOrStringType(): Chain; diff --git a/src/Mixins/NullOrChain.php b/src/Mixins/NullOrChain.php index 6753eb70..0d6664a7 100644 --- a/src/Mixins/NullOrChain.php +++ b/src/Mixins/NullOrChain.php @@ -66,12 +66,12 @@ interface NullOrChain public function nullOrConsonant(string ...$additionalChars): Chain; - public function nullOrContains(mixed $containsValue, bool $identical = false): Chain; + public function nullOrContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function nullOrContainsAny(array $needles, bool $identical = false): Chain; + public function nullOrContainsAny(array $needles): Chain; - public function nullOrContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public function nullOrContainsCount(mixed $containsValue, int $count): Chain; public function nullOrControl(string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface NullOrChain public function nullOrEmoji(): Chain; - public function nullOrEndsWith(mixed $endValue, bool $identical = false): Chain; + public function nullOrEndsWith(mixed $endValue): Chain; public function nullOrEquals(mixed $compareTo): Chain; @@ -154,7 +154,7 @@ interface NullOrChain public function nullOrImei(): Chain; - public function nullOrIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function nullOrIn(mixed $haystack): Chain; public function nullOrInfinite(): Chain; @@ -284,7 +284,7 @@ interface NullOrChain public function nullOrSpaced(): Chain; - public function nullOrStartsWith(mixed $startValue, bool $identical = false): Chain; + public function nullOrStartsWith(mixed $startValue): Chain; public function nullOrStringType(): Chain; diff --git a/src/Mixins/PropertyBuilder.php b/src/Mixins/PropertyBuilder.php index f5a59c89..6712d07a 100644 --- a/src/Mixins/PropertyBuilder.php +++ b/src/Mixins/PropertyBuilder.php @@ -66,12 +66,12 @@ interface PropertyBuilder public static function propertyConsonant(string $propertyName, string ...$additionalChars): Chain; - public static function propertyContains(string $propertyName, mixed $containsValue, bool $identical = false): Chain; + public static function propertyContains(string $propertyName, mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function propertyContainsAny(string $propertyName, array $needles, bool $identical = false): Chain; + public static function propertyContainsAny(string $propertyName, array $needles): Chain; - public static function propertyContainsCount(string $propertyName, mixed $containsValue, int $count, bool $identical = false): Chain; + public static function propertyContainsCount(string $propertyName, mixed $containsValue, int $count): Chain; public static function propertyControl(string $propertyName, string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface PropertyBuilder public static function propertyEmoji(string $propertyName): Chain; - public static function propertyEndsWith(string $propertyName, mixed $endValue, bool $identical = false): Chain; + public static function propertyEndsWith(string $propertyName, mixed $endValue): Chain; public static function propertyEquals(string $propertyName, mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface PropertyBuilder public static function propertyImei(string $propertyName): Chain; - public static function propertyIn(string $propertyName, mixed $haystack, bool $compareIdentical = false): Chain; + public static function propertyIn(string $propertyName, mixed $haystack): Chain; public static function propertyInfinite(string $propertyName): Chain; @@ -268,7 +268,7 @@ interface PropertyBuilder public static function propertySpaced(string $propertyName): Chain; - public static function propertyStartsWith(string $propertyName, mixed $startValue, bool $identical = false): Chain; + public static function propertyStartsWith(string $propertyName, mixed $startValue): Chain; public static function propertyStringType(string $propertyName): Chain; diff --git a/src/Mixins/PropertyChain.php b/src/Mixins/PropertyChain.php index 68c0e1db..668fa7c8 100644 --- a/src/Mixins/PropertyChain.php +++ b/src/Mixins/PropertyChain.php @@ -66,12 +66,12 @@ interface PropertyChain public function propertyConsonant(string $propertyName, string ...$additionalChars): Chain; - public function propertyContains(string $propertyName, mixed $containsValue, bool $identical = false): Chain; + public function propertyContains(string $propertyName, mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function propertyContainsAny(string $propertyName, array $needles, bool $identical = false): Chain; + public function propertyContainsAny(string $propertyName, array $needles): Chain; - public function propertyContainsCount(string $propertyName, mixed $containsValue, int $count, bool $identical = false): Chain; + public function propertyContainsCount(string $propertyName, mixed $containsValue, int $count): Chain; public function propertyControl(string $propertyName, string ...$additionalChars): Chain; @@ -108,7 +108,7 @@ interface PropertyChain public function propertyEmoji(string $propertyName): Chain; - public function propertyEndsWith(string $propertyName, mixed $endValue, bool $identical = false): Chain; + public function propertyEndsWith(string $propertyName, mixed $endValue): Chain; public function propertyEquals(string $propertyName, mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface PropertyChain public function propertyImei(string $propertyName): Chain; - public function propertyIn(string $propertyName, mixed $haystack, bool $compareIdentical = false): Chain; + public function propertyIn(string $propertyName, mixed $haystack): Chain; public function propertyInfinite(string $propertyName): Chain; @@ -268,7 +268,7 @@ interface PropertyChain public function propertySpaced(string $propertyName): Chain; - public function propertyStartsWith(string $propertyName, mixed $startValue, bool $identical = false): Chain; + public function propertyStartsWith(string $propertyName, mixed $startValue): Chain; public function propertyStringType(string $propertyName): Chain; diff --git a/src/Mixins/UndefOrBuilder.php b/src/Mixins/UndefOrBuilder.php index 52c63309..6c0b046e 100644 --- a/src/Mixins/UndefOrBuilder.php +++ b/src/Mixins/UndefOrBuilder.php @@ -64,12 +64,12 @@ interface UndefOrBuilder public static function undefOrConsonant(string ...$additionalChars): Chain; - public static function undefOrContains(mixed $containsValue, bool $identical = false): Chain; + public static function undefOrContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public static function undefOrContainsAny(array $needles, bool $identical = false): Chain; + public static function undefOrContainsAny(array $needles): Chain; - public static function undefOrContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public static function undefOrContainsCount(mixed $containsValue, int $count): Chain; public static function undefOrControl(string ...$additionalChars): Chain; @@ -106,7 +106,7 @@ interface UndefOrBuilder public static function undefOrEmoji(): Chain; - public static function undefOrEndsWith(mixed $endValue, bool $identical = false): Chain; + public static function undefOrEndsWith(mixed $endValue): Chain; public static function undefOrEquals(mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface UndefOrBuilder public static function undefOrImei(): Chain; - public static function undefOrIn(mixed $haystack, bool $compareIdentical = false): Chain; + public static function undefOrIn(mixed $haystack): Chain; public static function undefOrInfinite(): Chain; @@ -282,7 +282,7 @@ interface UndefOrBuilder public static function undefOrSpaced(): Chain; - public static function undefOrStartsWith(mixed $startValue, bool $identical = false): Chain; + public static function undefOrStartsWith(mixed $startValue): Chain; public static function undefOrStringType(): Chain; diff --git a/src/Mixins/UndefOrChain.php b/src/Mixins/UndefOrChain.php index 92e263be..adb8f85f 100644 --- a/src/Mixins/UndefOrChain.php +++ b/src/Mixins/UndefOrChain.php @@ -64,12 +64,12 @@ interface UndefOrChain public function undefOrConsonant(string ...$additionalChars): Chain; - public function undefOrContains(mixed $containsValue, bool $identical = false): Chain; + public function undefOrContains(mixed $containsValue): Chain; /** @param non-empty-array $needles */ - public function undefOrContainsAny(array $needles, bool $identical = false): Chain; + public function undefOrContainsAny(array $needles): Chain; - public function undefOrContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain; + public function undefOrContainsCount(mixed $containsValue, int $count): Chain; public function undefOrControl(string ...$additionalChars): Chain; @@ -106,7 +106,7 @@ interface UndefOrChain public function undefOrEmoji(): Chain; - public function undefOrEndsWith(mixed $endValue, bool $identical = false): Chain; + public function undefOrEndsWith(mixed $endValue): Chain; public function undefOrEquals(mixed $compareTo): Chain; @@ -152,7 +152,7 @@ interface UndefOrChain public function undefOrImei(): Chain; - public function undefOrIn(mixed $haystack, bool $compareIdentical = false): Chain; + public function undefOrIn(mixed $haystack): Chain; public function undefOrInfinite(): Chain; @@ -282,7 +282,7 @@ interface UndefOrChain public function undefOrSpaced(): Chain; - public function undefOrStartsWith(mixed $startValue, bool $identical = false): Chain; + public function undefOrStartsWith(mixed $startValue): Chain; public function undefOrStringType(): Chain; diff --git a/src/Validators/Call.php b/src/Validators/Call.php index 0f0131a3..b978534c 100644 --- a/src/Validators/Call.php +++ b/src/Validators/Call.php @@ -17,21 +17,12 @@ declare(strict_types=1); namespace Respect\Validation\Validators; use Attribute; -use ErrorException; -use Respect\Validation\Message\Template; use Respect\Validation\Result; use Respect\Validation\Validator; -use Throwable; use function call_user_func; -use function restore_error_handler; -use function set_error_handler; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] -#[Template( - '{{input}} must be a suitable argument for {{callable}}', - '{{input}} must not be a suitable argument for {{callable}}', -)] final class Call implements Validator { /** @var callable */ @@ -46,18 +37,6 @@ final class Call implements Validator public function evaluate(mixed $input): Result { - set_error_handler(static function (int $severity, string $message, string|null $filename, int $line): void { - throw new ErrorException($message, 0, $severity, $filename, $line); - }); - - try { - $result = $this->validator->evaluate(call_user_func($this->callable, $input)); - } catch (Throwable) { - $result = Result::failed($input, $this, ['callable' => $this->callable]); - } - - restore_error_handler(); - - return $result; + return $this->validator->evaluate(call_user_func($this->callable, $input)); } } diff --git a/src/Validators/Contains.php b/src/Validators/Contains.php index f403be2e..893be994 100644 --- a/src/Validators/Contains.php +++ b/src/Validators/Contains.php @@ -23,7 +23,6 @@ use Respect\Validation\Validator; use function in_array; use function is_array; use function is_scalar; -use function mb_stripos; use function mb_strpos; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] @@ -33,17 +32,15 @@ use function mb_strpos; )] final readonly class Contains implements Validator { - public function __construct( - private mixed $containsValue, - private bool $identical = false, - ) { + public function __construct(private mixed $containsValue) + { } public function evaluate(mixed $input): Result { $parameters = ['containsValue' => $this->containsValue]; if (is_array($input)) { - return Result::of(in_array($this->containsValue, $input, $this->identical), $input, $this, $parameters); + return Result::of(in_array($this->containsValue, $input, strict: true), $input, $this, $parameters); } if (!is_scalar($input) || !is_scalar($this->containsValue)) { @@ -64,10 +61,6 @@ final readonly class Contains implements Validator return false; } - if ($this->identical) { - return mb_strpos($haystack, $needle) !== false; - } - - return mb_stripos($haystack, $needle) !== false; + return mb_strpos($haystack, $needle) !== false; } } diff --git a/src/Validators/ContainsAny.php b/src/Validators/ContainsAny.php index be3a8833..df18e511 100644 --- a/src/Validators/ContainsAny.php +++ b/src/Validators/ContainsAny.php @@ -28,13 +28,13 @@ use function count; final class ContainsAny extends Envelope { /** @param non-empty-array $needles */ - public function __construct(array $needles, bool $identical = false) + public function __construct(array $needles) { if (empty($needles)) { throw new InvalidValidatorException('At least one value must be provided'); } - $validators = $this->getValidators($needles, $identical); + $validators = $this->getValidators($needles); parent::__construct( count($validators) === 1 ? $validators[0] : new AnyOf(...$validators), @@ -47,12 +47,10 @@ final class ContainsAny extends Envelope * * @return Contains[] */ - private function getValidators(array $needles, bool $identical): array + private function getValidators(array $needles): array { return array_map( - static function ($needle) use ($identical): Contains { - return new Contains($needle, $identical); - }, + static fn($needle): Contains => new Contains($needle), $needles, ); } diff --git a/src/Validators/ContainsCount.php b/src/Validators/ContainsCount.php index 6e2ec17f..ba401df5 100644 --- a/src/Validators/ContainsCount.php +++ b/src/Validators/ContainsCount.php @@ -18,7 +18,6 @@ use Respect\Validation\Validator; use function array_reduce; use function is_array; use function is_scalar; -use function mb_strtolower; use function mb_substr_count; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] @@ -40,7 +39,6 @@ final readonly class ContainsCount implements Validator public function __construct( private mixed $containsValue, private int $count, - private bool $identical = false, ) { } @@ -74,7 +72,7 @@ final readonly class ContainsCount implements Validator } return Result::of( - $this->countStringOccurrences((string) $input, $needle) === $this->count, + mb_substr_count((string) $input, $needle) === $this->count, $input, $this, $parameters, @@ -87,21 +85,10 @@ final readonly class ContainsCount implements Validator { return array_reduce( $input, - $this->identical ? function (int $carry, mixed $item): int { + function (int $carry, mixed $item): int { return $carry + ($item === $this->containsValue ? 1 : 0); - } : function (int $carry, mixed $item): int { - return $carry + ($item == $this->containsValue ? 1 : 0); }, 0, ); } - - private function countStringOccurrences(string $haystack, string $needle): int - { - if ($this->identical) { - return mb_substr_count($haystack, $needle); - } - - return mb_substr_count(mb_strtolower($haystack), mb_strtolower($needle)); - } } diff --git a/src/Validators/EndsWith.php b/src/Validators/EndsWith.php index f86d3f3e..5a5279e6 100644 --- a/src/Validators/EndsWith.php +++ b/src/Validators/EndsWith.php @@ -23,7 +23,6 @@ use Respect\Validation\Validator; use function end; use function is_array; use function mb_strlen; -use function mb_strripos; use function mb_strrpos; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] @@ -35,27 +34,14 @@ final readonly class EndsWith implements Validator { public function __construct( private mixed $endValue, - private bool $identical = false, ) { } public function evaluate(mixed $input): Result { $parameters = ['endValue' => $this->endValue]; - if ($this->identical) { - return Result::of($this->validateIdentical($input), $input, $this, $parameters); - } - return Result::of($this->validateEquals($input), $input, $this, $parameters); - } - - private function validateEquals(mixed $input): bool - { - if (is_array($input)) { - return end($input) == $this->endValue; - } - - return mb_strripos($input, $this->endValue) === mb_strlen($input) - mb_strlen($this->endValue); + return Result::of($this->validateIdentical($input), $input, $this, $parameters); } private function validateIdentical(mixed $input): bool diff --git a/src/Validators/In.php b/src/Validators/In.php index 16fe0804..ce07b303 100644 --- a/src/Validators/In.php +++ b/src/Validators/In.php @@ -22,7 +22,6 @@ use Respect\Validation\Validator; use function in_array; use function is_array; -use function mb_stripos; use function mb_strpos; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] @@ -34,37 +33,20 @@ final readonly class In implements Validator { public function __construct( private mixed $haystack, - private bool $compareIdentical = false, ) { } public function evaluate(mixed $input): Result { $parameters = ['haystack' => $this->haystack]; - if ($this->compareIdentical) { - return Result::of($this->validateIdentical($input), $input, $this, $parameters); - } - return Result::of($this->validateEquals($input), $input, $this, $parameters); + return Result::of($this->validate($input), $input, $this, $parameters); } - private function validateEquals(mixed $input): bool + private function validate(mixed $input): bool { if (is_array($this->haystack)) { - return in_array($input, $this->haystack); - } - - if ($input === null || $input === '') { - return $input == $this->haystack; - } - - return mb_stripos($this->haystack, (string) $input) !== false; - } - - private function validateIdentical(mixed $input): bool - { - if (is_array($this->haystack)) { - return in_array($input, $this->haystack, true); + return in_array($input, $this->haystack, strict: true); } if ($input === null || $input === '') { diff --git a/src/Validators/StartsWith.php b/src/Validators/StartsWith.php index b0beaf9e..a9548148 100644 --- a/src/Validators/StartsWith.php +++ b/src/Validators/StartsWith.php @@ -22,7 +22,6 @@ use Respect\Validation\Validator; use function is_array; use function is_string; -use function mb_stripos; use function mb_strpos; use function reset; @@ -35,31 +34,14 @@ final readonly class StartsWith implements Validator { public function __construct( private mixed $startValue, - private bool $identical = false, ) { } public function evaluate(mixed $input): Result { $parameters = ['startValue' => $this->startValue]; - if ($this->identical) { - return Result::of($this->validateIdentical($input), $input, $this, $parameters); - } - return Result::of($this->validateEquals($input), $input, $this, $parameters); - } - - protected function validateEquals(mixed $input): bool - { - if (is_array($input)) { - return reset($input) == $this->startValue; - } - - if (is_string($input) && is_string($this->startValue)) { - return mb_stripos($input, $this->startValue) === 0; - } - - return false; + return Result::of($this->validateIdentical($input), $input, $this, $parameters); } protected function validateIdentical(mixed $input): bool diff --git a/src/Validators/Tld.php b/src/Validators/Tld.php index 490bdb09..b76c201e 100644 --- a/src/Validators/Tld.php +++ b/src/Validators/Tld.php @@ -23,6 +23,9 @@ final class Tld extends Envelope { public function __construct() { - parent::__construct(new Call('mb_strtoupper', new In(DataLoader::load('domain/tld.php')))); + parent::__construct(new Circuit( + new StringType(), + new Call('mb_strtoupper', new In(DataLoader::load('domain/tld.php'))), + )); } } diff --git a/tests/feature/Validators/CallTest.php b/tests/feature/Validators/CallTest.php index a2e4d612..3d448f17 100644 --- a/tests/feature/Validators/CallTest.php +++ b/tests/feature/Validators/CallTest.php @@ -18,22 +18,12 @@ test('Scenario #2', catchMessage( fn(string $message) => expect($message)->toBe('" something " must not be a string'), )); -test('Scenario #3', catchMessage( - fn() => v::call('stripslashes', v::alwaysValid())->assert([]), - fn(string $message) => expect($message)->toBe('`[]` must be a suitable argument for "stripslashes"'), -)); - -test('Scenario #4', catchFullMessage( +test('Scenario #3', catchFullMessage( fn() => v::call('strval', v::intType())->assert(1234), fn(string $fullMessage) => expect($fullMessage)->toBe('- "1234" must be an integer'), )); -test('Scenario #5', catchFullMessage( +test('Scenario #4', catchFullMessage( fn() => v::not(v::call('is_float', v::boolType()))->assert(1.2), fn(string $fullMessage) => expect($fullMessage)->toBe('- `true` must not be a boolean'), )); - -test('Scenario #6', catchFullMessage( - fn() => v::call('array_shift', v::alwaysValid())->assert(INF), - fn(string $fullMessage) => expect($fullMessage)->toBe('- `INF` must be a suitable argument for "array_shift"'), -)); diff --git a/tests/feature/Validators/ContainsAnyTest.php b/tests/feature/Validators/ContainsAnyTest.php index fe5d6f42..351bea23 100644 --- a/tests/feature/Validators/ContainsAnyTest.php +++ b/tests/feature/Validators/ContainsAnyTest.php @@ -24,6 +24,6 @@ test('Scenario #3', catchFullMessage( )); test('Scenario #4', catchFullMessage( - fn() => v::not(v::containsAny(['foo', 'bar'], true))->assert(['bar', 'foo']), + fn() => v::not(v::containsAny(['foo', 'bar']))->assert(['bar', 'foo']), fn(string $fullMessage) => expect($fullMessage)->toBe('- `["bar", "foo"]` must not contain any value from `["foo", "bar"]`'), )); diff --git a/tests/feature/Validators/ContainsCountTest.php b/tests/feature/Validators/ContainsCountTest.php index 352de83e..bfd52536 100644 --- a/tests/feature/Validators/ContainsCountTest.php +++ b/tests/feature/Validators/ContainsCountTest.php @@ -24,11 +24,11 @@ test('Scenario #3', catchFullMessage( )); test('Scenario #4', catchFullMessage( - fn() => v::not(v::containsCount('foo', 1, true))->assert(['foo', 'bar']), + fn() => v::not(v::containsCount('foo', 1))->assert(['foo', 'bar']), fn(string $fullMessage) => expect($fullMessage)->toBe('- `["foo", "bar"]` must not contain "foo" only once'), )); test('Scenario #5', catchFullMessage( - fn() => v::containsCount('foo', 1, true)->assert(['foo', 'foo']), + fn() => v::containsCount('foo', 1)->assert(['foo', 'foo']), fn(string $fullMessage) => expect($fullMessage)->toBe('- `["foo", "foo"]` must contain "foo" only once'), )); diff --git a/tests/feature/Validators/ContainsTest.php b/tests/feature/Validators/ContainsTest.php index 0970e647..e0fda2bb 100644 --- a/tests/feature/Validators/ContainsTest.php +++ b/tests/feature/Validators/ContainsTest.php @@ -24,6 +24,6 @@ test('Scenario #3', catchFullMessage( )); test('Scenario #4', catchFullMessage( - fn() => v::not(v::contains('foo', true))->assert(['bar', 'foo']), + fn() => v::not(v::contains('foo'))->assert(['bar', 'foo']), fn(string $fullMessage) => expect($fullMessage)->toBe('- `["bar", "foo"]` must not contain "foo"'), )); diff --git a/tests/feature/Validators/InTest.php b/tests/feature/Validators/InTest.php index 93acc3d1..6d868f34 100644 --- a/tests/feature/Validators/InTest.php +++ b/tests/feature/Validators/InTest.php @@ -19,11 +19,11 @@ test('Scenario #2', catchMessage( )); test('Scenario #3', catchFullMessage( - fn() => v::in([2, '1', 3], true)->assert('2'), + fn() => v::in([2, '1', 3])->assert('2'), fn(string $fullMessage) => expect($fullMessage)->toBe('- "2" must be in `[2, "1", 3]`'), )); test('Scenario #4', catchFullMessage( - fn() => v::not(v::in([2, '1', 3], true))->assert('1'), + fn() => v::not(v::in([2, '1', 3]))->assert('1'), fn(string $fullMessage) => expect($fullMessage)->toBe('- "1" must not be in `[2, "1", 3]`'), )); diff --git a/tests/feature/Validators/StartsWithTest.php b/tests/feature/Validators/StartsWithTest.php index de402579..2870a287 100644 --- a/tests/feature/Validators/StartsWithTest.php +++ b/tests/feature/Validators/StartsWithTest.php @@ -19,7 +19,7 @@ test('Scenario #2', catchMessage( )); test('Scenario #3', catchFullMessage( - fn() => v::startsWith('3.3', true)->assert([3.3, 4.4]), + fn() => v::startsWith('3.3')->assert([3.3, 4.4]), fn(string $fullMessage) => expect($fullMessage)->toBe('- `[3.3, 4.4]` must start with "3.3"'), )); diff --git a/tests/unit/Validators/CallTest.php b/tests/unit/Validators/CallTest.php index 8c8780dd..62904865 100644 --- a/tests/unit/Validators/CallTest.php +++ b/tests/unit/Validators/CallTest.php @@ -14,11 +14,11 @@ declare(strict_types=1); namespace Respect\Validation\Validators; -use Exception; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use Respect\Validation\Test\RuleTestCase; -use Respect\Validation\Test\Validators\Stub; +use TypeError; #[Group('validator')] #[CoversClass(Call::class)] @@ -28,7 +28,7 @@ final class CallTest extends RuleTestCase public static function providerForValidInput(): iterable { return [ - 'valid rule and valid callable' => [new Call('trim', Stub::pass(1)), ' input '], + 'callback true' => [new Call('strtolower', new Equals('abc')), 'ABC'], ]; } @@ -36,8 +36,16 @@ final class CallTest extends RuleTestCase public static function providerForInvalidInput(): iterable { return [ - 'PHP error' => [new Call('trim', Stub::pass(1)), []], - 'exception' => [new Call(static fn() => throw new Exception(), Stub::pass(1)), []], + 'callback false' => [new Call('strtolower', new Equals('abc')), 'DEF'], ]; } + + #[Test] + public function shouldLetErrorsEmittedByTheChosenProvidedCallbackToBubbleUp(): void + { + $this->expectException(TypeError::class); + $this->expectExceptionMessage('strtolower(): Argument #1 ($string) must be of type string, int given'); + $validator = new Call('strtolower', new Equals('abc')); + $validator->evaluate(123); + } } diff --git a/tests/unit/Validators/ContainsAnyTest.php b/tests/unit/Validators/ContainsAnyTest.php index ec88b8eb..36728152 100644 --- a/tests/unit/Validators/ContainsAnyTest.php +++ b/tests/unit/Validators/ContainsAnyTest.php @@ -36,14 +36,8 @@ final class ContainsAnyTest extends RuleTestCase public static function providerForValidInput(): iterable { return [ - [new ContainsAny(['Something', 'Else']), 'something else'], - [new ContainsAny([true]), [1, 2, 3]], - [new ContainsAny([true], true), [true]], - [new ContainsAny(['1']), [1, 2, 3]], - [new ContainsAny([1], true), [1, 2, 3]], - [new ContainsAny(['word', '@', '/']), 'lorem ipsum @ word'], - [new ContainsAny(['foo', 'qux']), 'foobarbaz'], - [new ContainsAny(['1']), ['foo', 1]], + [new ContainsAny([true]), [true]], + [new ContainsAny([1]), [1, 2, 3]], [new ContainsAny(['foo', true]), ['foo', 'bar']], ]; } @@ -55,13 +49,8 @@ final class ContainsAnyTest extends RuleTestCase [new ContainsAny(['foo']), ['bar', 'baz']], [new ContainsAny(['foo', 'bar']), ['baz', 'qux']], [new ContainsAny(['foo', 'bar']), ['FOO', 'BAR']], - [new ContainsAny(['foo'], true), ['bar', 'baz']], - [new ContainsAny(['foo', 'bar'], true), ['FOO', 'BAR']], - [new ContainsAny(['whatever']), ''], - [new ContainsAny(['']), 'whatever'], - [new ContainsAny([false]), ''], [new ContainsAny(['foo', 'qux']), 'barbaz'], - [new ContainsAny([1, 2, 3], true), ['1', '2', '3']], + [new ContainsAny([1, 2, 3]), ['1', '2', '3']], [new ContainsAny(['word', '@', '/']), 'lorem ipsum'], ]; } diff --git a/tests/unit/Validators/ContainsCountTest.php b/tests/unit/Validators/ContainsCountTest.php index 9ebce52f..3011b6c4 100644 --- a/tests/unit/Validators/ContainsCountTest.php +++ b/tests/unit/Validators/ContainsCountTest.php @@ -27,16 +27,10 @@ final class ContainsCountTest extends RuleTestCase [new ContainsCount('foo', 1), 'foo bar'], [new ContainsCount('foo', 2), 'foo bar foo'], [new ContainsCount('a', 3), 'banana'], - - [new ContainsCount('1', 1, true), ['1', 2, 3]], - [new ContainsCount(1, 1, true), [1, 2, 3]], - - [new ContainsCount('A', 3), 'banana'], - [new ContainsCount('foo', 2), 'FOO bar foo'], - - [new ContainsCount('A', 0, true), 'banana'], - [new ContainsCount('a', 3, true), 'banana'], - + [new ContainsCount('1', 1), ['1', 2, 3]], + [new ContainsCount(1, 1), [1, 2, 3]], + [new ContainsCount('A', 0), 'banana'], + [new ContainsCount('a', 3), 'banana'], [new ContainsCount('foo', 0), 'bar'], ]; } @@ -48,16 +42,12 @@ final class ContainsCountTest extends RuleTestCase [new ContainsCount('foo', 2), ['foo', 'bar']], [new ContainsCount('foo', 2), 'foo bar'], [new ContainsCount('a', 2), 'banana'], - - [new ContainsCount('1', 1, true), [1, 2, 3]], - + [new ContainsCount('1', 1), [1, 2, 3]], [new ContainsCount('A', 2), 'banana'], - - [new ContainsCount('A', 3, true), 'banana'], - + [new ContainsCount('A', 3), 'banana'], + [new ContainsCount('foo', 2), 'FOO bar foo'], [new ContainsCount('foo', 1), null], [new ContainsCount('foo', 1), new stdClass()], - [new ContainsCount('', 1), ''], ]; } diff --git a/tests/unit/Validators/ContainsTest.php b/tests/unit/Validators/ContainsTest.php index 2df77e65..bd05bf43 100644 --- a/tests/unit/Validators/ContainsTest.php +++ b/tests/unit/Validators/ContainsTest.php @@ -30,15 +30,12 @@ final class ContainsTest extends RuleTestCase public static function providerForValidInput(): iterable { return [ - [new Contains('foo', false), ['bar', 'foo']], - [new Contains('foo', false), 'barbazFOO'], - [new Contains('foo', false), 'barbazfoo'], - [new Contains('foo', false), 'foobazfoO'], - [new Contains('1', false), [2, 3, 1]], - [new Contains('1', false), [2, 3, '1']], + [new Contains('foo'), ['bar', 'foo']], [new Contains('foo'), ['fool', 'foo']], + [new Contains('foo'), 'foobazfoO'], [new Contains('foo'), 'barbazfoo'], [new Contains('foo'), 'foobazfoo'], + [new Contains('1'), [2, 3, '1']], [new Contains('1'), [2, 3, (string) 1]], [new Contains('1'), [2, 3, '1']], [new Contains(1), [2, 3, 1]], @@ -49,24 +46,19 @@ final class ContainsTest extends RuleTestCase public static function providerForInvalidInput(): iterable { return [ - [new Contains('', false), 'abc'], - [new Contains(null, false), null], - [new Contains(null, false), []], - [new Contains(new stdClass(), false), new stdClass()], - [new Contains('foo', false), ''], - [new Contains('bat', false), ['bar', 'foo']], - [new Contains('foo', false), 'barfaabaz'], - [new Contains('foo', false), 'faabarbaz'], - [new Contains(null, true), null], - [new Contains(null, true), []], - [new Contains(new stdClass(), true), new stdClass()], - [new Contains('foo', true), ''], - [new Contains('bat', true), ['BAT', 'foo']], - [new Contains('bat', true), ['BaT', 'Batata']], - [new Contains('foo', true), 'barfaabaz'], - [new Contains('foo', true), 'barbazFOO'], - [new Contains('foo', true), 'faabarbaz'], - [new Contains(1, true), ['1', 2, 3]], + [new Contains('foo'), 'barbazFOO'], + [new Contains('1'), [2, 3, 1]], + [new Contains(''), 'abc'], + [new Contains(null), null], + [new Contains(null), []], + [new Contains(new stdClass()), new stdClass()], + [new Contains('foo'), ''], + [new Contains('bat'), ['bar', 'foo']], + [new Contains('foo'), 'barfaabaz'], + [new Contains('foo'), 'faabarbaz'], + [new Contains('bat'), ['BAT', 'foo']], + [new Contains('bat'), ['BaT', 'Batata']], + [new Contains(1), ['1', 2, 3]], ]; } } diff --git a/tests/unit/Validators/EndsWithTest.php b/tests/unit/Validators/EndsWithTest.php index d043997a..3c0d1dc0 100644 --- a/tests/unit/Validators/EndsWithTest.php +++ b/tests/unit/Validators/EndsWithTest.php @@ -28,12 +28,10 @@ final class EndsWithTest extends RuleTestCase { return [ [new EndsWith('foo'), ['bar', 'foo']], - [new EndsWith('foo'), 'barbazFOO'], [new EndsWith('foo'), 'barbazfoo'], [new EndsWith('foo'), 'foobazfoo'], - [new EndsWith('1'), [2, 3, 1]], [new EndsWith(1), [2, 3, 1]], - [new EndsWith('1', true), [2, 3, '1']], + [new EndsWith('1'), [2, 3, '1']], ]; } @@ -44,11 +42,12 @@ final class EndsWithTest extends RuleTestCase [new EndsWith('foo'), ''], [new EndsWith('bat'), ['bar', 'foo']], [new EndsWith('foo'), 'barfaabaz'], - [new EndsWith('foo', true), 'barbazFOO'], + [new EndsWith('foo'), 'barbazFOO'], [new EndsWith('foo'), 'faabarbaz'], [new EndsWith('foo'), 'baabazfaa'], [new EndsWith('foo'), 'baafoofaa'], - [new EndsWith('1', true), [1, '1', 3]], + [new EndsWith('1'), [1, '1', 3]], + [new EndsWith('1'), [2, 3, 1]], ]; } } diff --git a/tests/unit/Validators/InTest.php b/tests/unit/Validators/InTest.php index a191507a..ef4d041a 100644 --- a/tests/unit/Validators/InTest.php +++ b/tests/unit/Validators/InTest.php @@ -36,8 +36,7 @@ final class InTest extends RuleTestCase [new In('barfoobaz'), 'foo'], [new In('foobarbaz'), 'foo'], [new In('barbazfoo'), 'foo'], - [new In([1, 2, 3]), '1'], - [new In(['1', 2, 3], true), '1'], + [new In(['1', 2, 3]), '1'], ]; } @@ -45,11 +44,11 @@ final class InTest extends RuleTestCase public static function providerForInvalidInput(): iterable { return [ - [new In('0', true), 'abc'], + [new In('0'), 'abc'], [new In('0'), null], - [new In(0, true), null], - [new In('', true), null], - [new In([], true), null], + [new In(0), null], + [new In(''), null], + [new In([]), null], [new In('barfoobaz'), ''], [new In('barfoobaz'), null], [new In('barfoobaz'), 0], @@ -58,7 +57,7 @@ final class InTest extends RuleTestCase [new In('barfaabaz'), 'foo'], [new In('faabarbaz'), 'foo'], [new In('baabazfaa'), 'foo'], - [new In([1, 2, 3], true), '1'], + [new In([1, 2, 3]), '1'], ]; } } diff --git a/tests/unit/Validators/StartsWithTest.php b/tests/unit/Validators/StartsWithTest.php index 489c7adf..7af038d9 100644 --- a/tests/unit/Validators/StartsWithTest.php +++ b/tests/unit/Validators/StartsWithTest.php @@ -27,11 +27,9 @@ final class StartsWithTest extends RuleTestCase { return [ [new StartsWith('foo'), ['foo', 'bar']], - [new StartsWith('foo') ,'FOObarbaz'], - [new StartsWith('foo') , 'foobarbaz'], - [new StartsWith('foo') ,'foobazfoo'], - [new StartsWith('1'), [1, 2, 3]], - [new StartsWith('1', true), ['1', 2, 3]], + [new StartsWith('foo'), 'foobarbaz'], + [new StartsWith('foo'), 'foobazfoo'], + [new StartsWith('1'), ['1', 2, 3]], ]; } @@ -40,15 +38,15 @@ final class StartsWithTest extends RuleTestCase { return [ [new StartsWith(123), 123], - [new StartsWith(123, true), 123], [new StartsWith('foo'), ''], [new StartsWith('bat'), ['foo', 'bar']], [new StartsWith('foo'), 'barfaabaz'], - [new StartsWith('foo', true), 'FOObarbaz'], + [new StartsWith('foo'), 'FOObarbaz'], [new StartsWith('foo'), 'faabarbaz'], [new StartsWith('foo'), 'baabazfaa'], [new StartsWith('foo'), 'baafoofaa'], - [new StartsWith('1', true), [1, '1', 3]], + [new StartsWith('1'), [1, '1', 3]], + [new StartsWith('1'), [1, 2, 3]], ]; } }