From df378bff44058f2c7db17e3795f3ed473580c08a Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Mon, 12 Feb 2024 19:51:30 +0100 Subject: [PATCH] Update the validation engine of simple rules By "simple," I mean rules that have nothing in their constructor or that have simple templates. This change introduces two classes that will be the foundation for migrating all the rules to the newest validation engine: * Standard: this abstract rule contains only the accessors to define and retrieve names and templates, which means that the classes that extend it must implement the "evaluate()" method. * Simple: this abstract rule contains the "evaluate()" method, which relies on the "validate()" method, which means that the classes that extend it must implement that method. I expect many changes to the Simple abstract rule once all the rules get migrated to the newest validation engine. I've chosen to keep relying on the "validate()" method because it will make it easier to migrate everything. The "Standard" abstract rule uses a trait that triggers an "E_USER_DEPRECATED" error in every method from the old validation engine. That aims to support the migration because I can see clearly if any places still use the methods I would like to delete once I migrate everything. Signed-off-by: Henrique Moody --- .../Helpers/DeprecatedValidatableMethods.php | 70 +++++++++++++++++++ library/Rules/AlwaysInvalid.php | 2 +- library/Rules/AlwaysValid.php | 2 +- library/Rules/ArrayType.php | 2 +- library/Rules/ArrayVal.php | 2 +- library/Rules/Base64.php | 2 +- library/Rules/BoolType.php | 2 +- library/Rules/BoolVal.php | 2 +- library/Rules/Bsn.php | 2 +- library/Rules/CallableType.php | 2 +- library/Rules/Callback.php | 2 +- library/Rules/Cnh.php | 2 +- library/Rules/Cnpj.php | 2 +- library/Rules/Countable.php | 2 +- library/Rules/Cpf.php | 2 +- library/Rules/Directory.php | 2 +- library/Rules/Email.php | 2 +- library/Rules/Even.php | 2 +- library/Rules/Executable.php | 2 +- library/Rules/Exists.php | 2 +- library/Rules/FalseVal.php | 2 +- library/Rules/Fibonacci.php | 2 +- library/Rules/File.php | 2 +- library/Rules/Finite.php | 2 +- library/Rules/FloatType.php | 2 +- library/Rules/FloatVal.php | 2 +- library/Rules/Image.php | 2 +- library/Rules/Imei.php | 2 +- library/Rules/Infinite.php | 2 +- library/Rules/IntType.php | 2 +- library/Rules/IntVal.php | 2 +- library/Rules/Isbn.php | 2 +- library/Rules/IterableType.php | 2 +- library/Rules/Json.php | 2 +- library/Rules/LeapDate.php | 2 +- library/Rules/LeapYear.php | 2 +- library/Rules/Lowercase.php | 2 +- library/Rules/Luhn.php | 2 +- library/Rules/MacAddress.php | 2 +- library/Rules/Negative.php | 2 +- library/Rules/NfeAccessKey.php | 2 +- library/Rules/Nif.php | 2 +- library/Rules/Nip.php | 2 +- library/Rules/NoWhitespace.php | 2 +- library/Rules/NotEmoji.php | 2 +- library/Rules/NullType.php | 2 +- library/Rules/Number.php | 2 +- library/Rules/NumericVal.php | 2 +- library/Rules/ObjectType.php | 2 +- library/Rules/Odd.php | 2 +- library/Rules/PerfectSquare.php | 2 +- library/Rules/Pesel.php | 2 +- library/Rules/PhpLabel.php | 2 +- library/Rules/Pis.php | 2 +- library/Rules/PolishIdCard.php | 2 +- library/Rules/PortugueseNif.php | 2 +- library/Rules/Positive.php | 2 +- library/Rules/PrimeNumber.php | 2 +- library/Rules/PublicDomainSuffix.php | 2 +- library/Rules/Readable.php | 2 +- library/Rules/ResourceType.php | 2 +- library/Rules/ScalarVal.php | 2 +- library/Rules/Simple.php | 20 ++++++ library/Rules/Slug.php | 2 +- library/Rules/Standard.php | 46 ++++++++++++ library/Rules/StringType.php | 2 +- library/Rules/StringVal.php | 2 +- library/Rules/SymbolicLink.php | 2 +- library/Rules/Tld.php | 2 +- library/Rules/TrueVal.php | 2 +- library/Rules/Unique.php | 2 +- library/Rules/Uploaded.php | 2 +- library/Rules/Uppercase.php | 2 +- library/Rules/Version.php | 2 +- library/Rules/Writable.php | 2 +- library/Rules/Yes.php | 2 +- tests/library/Rules/ConcreteSimple.php | 20 ++++++ tests/library/Rules/ConcreteStandard.php | 21 ++++++ tests/unit/Rules/AlwaysInvalidTest.php | 2 +- tests/unit/Rules/AlwaysValidTest.php | 2 +- tests/unit/Rules/NotTest.php | 10 +-- tests/unit/Rules/SimpleTest.php | 46 ++++++++++++ tests/unit/Rules/StandardTest.php | 55 +++++++++++++++ 83 files changed, 356 insertions(+), 82 deletions(-) create mode 100644 library/Helpers/DeprecatedValidatableMethods.php create mode 100644 library/Rules/Simple.php create mode 100644 library/Rules/Standard.php create mode 100644 tests/library/Rules/ConcreteSimple.php create mode 100644 tests/library/Rules/ConcreteStandard.php create mode 100644 tests/unit/Rules/SimpleTest.php create mode 100644 tests/unit/Rules/StandardTest.php diff --git a/library/Helpers/DeprecatedValidatableMethods.php b/library/Helpers/DeprecatedValidatableMethods.php new file mode 100644 index 000000000..133af5429 --- /dev/null +++ b/library/Helpers/DeprecatedValidatableMethods.php @@ -0,0 +1,70 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Helpers; + +use Respect\Validation\Exceptions\ValidationException; +use Respect\Validation\Message\Parameter\Stringify; +use Respect\Validation\Message\TemplateRenderer; + +use function sprintf; +use function trigger_error; + +use const E_USER_DEPRECATED; + +trait DeprecatedValidatableMethods +{ + public function validate(mixed $input): bool + { + $this->triggerDeprecation(__METHOD__); + + return false; + } + + public function assert(mixed $input): void + { + $this->triggerDeprecation(__FUNCTION__); + } + + public function check(mixed $input): void + { + $this->triggerDeprecation(__FUNCTION__); + } + + /** @param array $extraParameters */ + public function reportError(mixed $input, array $extraParameters = []): ValidationException + { + $this->triggerDeprecation(__FUNCTION__); + + return new ValidationException( + input: $input, + id: 'id', + params: $extraParameters, + template: 'template', + templates: [], + formatter: new TemplateRenderer(static fn (string $message) => $message, new Stringify()), + ); + } + + /** @return array */ + public function getParams(): array + { + $this->triggerDeprecation(__FUNCTION__); + + return []; + } + + private function triggerDeprecation(string $function): void + { + trigger_error( + sprintf('The "%s" method is deprecated, please use the "Validator" class instead.', $function), + E_USER_DEPRECATED + ); + } +} diff --git a/library/Rules/AlwaysInvalid.php b/library/Rules/AlwaysInvalid.php index 48027f759..8f6443d16 100644 --- a/library/Rules/AlwaysInvalid.php +++ b/library/Rules/AlwaysInvalid.php @@ -21,7 +21,7 @@ '{{name}} is valid', self::TEMPLATE_SIMPLE, )] -final class AlwaysInvalid extends AbstractRule +final class AlwaysInvalid extends Simple { public const TEMPLATE_SIMPLE = '__simple__'; diff --git a/library/Rules/AlwaysValid.php b/library/Rules/AlwaysValid.php index b698272a8..48f87b923 100644 --- a/library/Rules/AlwaysValid.php +++ b/library/Rules/AlwaysValid.php @@ -15,7 +15,7 @@ '{{name}} is always valid', '{{name}} is always invalid', )] -final class AlwaysValid extends AbstractRule +final class AlwaysValid extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/ArrayType.php b/library/Rules/ArrayType.php index 5dca00fc9..6c6ad879d 100644 --- a/library/Rules/ArrayType.php +++ b/library/Rules/ArrayType.php @@ -17,7 +17,7 @@ '{{name}} must be of type array', '{{name}} must not be of type array', )] -final class ArrayType extends AbstractRule +final class ArrayType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/ArrayVal.php b/library/Rules/ArrayVal.php index afb3dd646..a21c49242 100644 --- a/library/Rules/ArrayVal.php +++ b/library/Rules/ArrayVal.php @@ -19,7 +19,7 @@ '{{name}} must be an array value', '{{name}} must not be an array value', )] -final class ArrayVal extends AbstractRule +final class ArrayVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Base64.php b/library/Rules/Base64.php index ab0b1499a..b453b90cd 100644 --- a/library/Rules/Base64.php +++ b/library/Rules/Base64.php @@ -19,7 +19,7 @@ '{{name}} must be Base64-encoded', '{{name}} must not be Base64-encoded', )] -final class Base64 extends AbstractRule +final class Base64 extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/BoolType.php b/library/Rules/BoolType.php index 550c316d9..ae33b07c8 100644 --- a/library/Rules/BoolType.php +++ b/library/Rules/BoolType.php @@ -17,7 +17,7 @@ '{{name}} must be of type boolean', '{{name}} must not be of type boolean', )] -final class BoolType extends AbstractRule +final class BoolType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/BoolVal.php b/library/Rules/BoolVal.php index 4af2137d0..e7313c290 100644 --- a/library/Rules/BoolVal.php +++ b/library/Rules/BoolVal.php @@ -21,7 +21,7 @@ '{{name}} must be a boolean value', '{{name}} must not be a boolean value', )] -final class BoolVal extends AbstractRule +final class BoolVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Bsn.php b/library/Rules/Bsn.php index 08c41fb94..1184063f1 100644 --- a/library/Rules/Bsn.php +++ b/library/Rules/Bsn.php @@ -24,7 +24,7 @@ '{{name}} must be a BSN', '{{name}} must not be a BSN', )] -final class Bsn extends AbstractRule +final class Bsn extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/CallableType.php b/library/Rules/CallableType.php index 701d92beb..8111f16eb 100644 --- a/library/Rules/CallableType.php +++ b/library/Rules/CallableType.php @@ -17,7 +17,7 @@ '{{name}} must be callable', '{{name}} must not be callable', )] -final class CallableType extends AbstractRule +final class CallableType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Callback.php b/library/Rules/Callback.php index 7ecda0da3..da8024771 100644 --- a/library/Rules/Callback.php +++ b/library/Rules/Callback.php @@ -19,7 +19,7 @@ '{{name}} must be valid', '{{name}} must not be valid', )] -final class Callback extends AbstractRule +final class Callback extends Simple { /** * @var callable diff --git a/library/Rules/Cnh.php b/library/Rules/Cnh.php index 7665f4928..2aeb58dd2 100644 --- a/library/Rules/Cnh.php +++ b/library/Rules/Cnh.php @@ -19,7 +19,7 @@ '{{name}} must be a valid CNH number', '{{name}} must not be a valid CNH number', )] -final class Cnh extends AbstractRule +final class Cnh extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Cnpj.php b/library/Rules/Cnpj.php index 3a58cac4a..8f5d5e85b 100644 --- a/library/Rules/Cnpj.php +++ b/library/Rules/Cnpj.php @@ -22,7 +22,7 @@ '{{name}} must be a valid CNPJ number', '{{name}} must not be a valid CNPJ number', )] -final class Cnpj extends AbstractRule +final class Cnpj extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Countable.php b/library/Rules/Countable.php index 8adf8fc90..687177d2a 100644 --- a/library/Rules/Countable.php +++ b/library/Rules/Countable.php @@ -18,7 +18,7 @@ '{{name}} must be countable', '{{name}} must not be countable', )] -final class Countable extends AbstractRule +final class Countable extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Cpf.php b/library/Rules/Cpf.php index 03629d9a3..4d1212d5d 100644 --- a/library/Rules/Cpf.php +++ b/library/Rules/Cpf.php @@ -20,7 +20,7 @@ '{{name}} must be a valid CPF number', '{{name}} must not be a valid CPF number', )] -final class Cpf extends AbstractRule +final class Cpf extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Directory.php b/library/Rules/Directory.php index e1d6bff38..66e610bfa 100644 --- a/library/Rules/Directory.php +++ b/library/Rules/Directory.php @@ -20,7 +20,7 @@ '{{name}} must be a directory', '{{name}} must not be a directory', )] -final class Directory extends AbstractRule +final class Directory extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Email.php b/library/Rules/Email.php index 4f91d8218..7047b395c 100644 --- a/library/Rules/Email.php +++ b/library/Rules/Email.php @@ -24,7 +24,7 @@ '{{name}} must be valid email', '{{name}} must not be an email', )] -final class Email extends AbstractRule +final class Email extends Simple { private readonly ?EmailValidator $validator; diff --git a/library/Rules/Even.php b/library/Rules/Even.php index 3bcef5a87..17a581871 100644 --- a/library/Rules/Even.php +++ b/library/Rules/Even.php @@ -19,7 +19,7 @@ '{{name}} must be an even number', '{{name}} must not be an even number', )] -final class Even extends AbstractRule +final class Even extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Executable.php b/library/Rules/Executable.php index b1abc1bd5..8c4f26ead 100644 --- a/library/Rules/Executable.php +++ b/library/Rules/Executable.php @@ -19,7 +19,7 @@ '{{name}} must be an executable file', '{{name}} must not be an executable file', )] -final class Executable extends AbstractRule +final class Executable extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Exists.php b/library/Rules/Exists.php index ee3b3b6fc..b9311fdb2 100644 --- a/library/Rules/Exists.php +++ b/library/Rules/Exists.php @@ -19,7 +19,7 @@ '{{name}} must exist', '{{name}} must not exist', )] -final class Exists extends AbstractRule +final class Exists extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/FalseVal.php b/library/Rules/FalseVal.php index b3d0bf2a7..d76c93243 100644 --- a/library/Rules/FalseVal.php +++ b/library/Rules/FalseVal.php @@ -20,7 +20,7 @@ '{{name}} must evaluate to `false`', '{{name}} must not evaluate to `false`', )] -final class FalseVal extends AbstractRule +final class FalseVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Fibonacci.php b/library/Rules/Fibonacci.php index 45081c08d..fbd71663b 100644 --- a/library/Rules/Fibonacci.php +++ b/library/Rules/Fibonacci.php @@ -17,7 +17,7 @@ '{{name}} must be a valid Fibonacci number', '{{name}} must not be a valid Fibonacci number', )] -final class Fibonacci extends AbstractRule +final class Fibonacci extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/File.php b/library/Rules/File.php index 332df9d89..203fc5ae1 100644 --- a/library/Rules/File.php +++ b/library/Rules/File.php @@ -19,7 +19,7 @@ '{{name}} must be a file', '{{name}} must not be a file', )] -final class File extends AbstractRule +final class File extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Finite.php b/library/Rules/Finite.php index fb230aa29..c96172dd0 100644 --- a/library/Rules/Finite.php +++ b/library/Rules/Finite.php @@ -18,7 +18,7 @@ '{{name}} must be a finite number', '{{name}} must not be a finite number', )] -final class Finite extends AbstractRule +final class Finite extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/FloatType.php b/library/Rules/FloatType.php index 4392dcf90..3f2385114 100644 --- a/library/Rules/FloatType.php +++ b/library/Rules/FloatType.php @@ -17,7 +17,7 @@ '{{name}} must be of type float', '{{name}} must not be of type float', )] -final class FloatType extends AbstractRule +final class FloatType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/FloatVal.php b/library/Rules/FloatVal.php index 017ef2cac..ebbea037e 100644 --- a/library/Rules/FloatVal.php +++ b/library/Rules/FloatVal.php @@ -20,7 +20,7 @@ '{{name}} must be a float number', '{{name}} must not be a float number', )] -final class FloatVal extends AbstractRule +final class FloatVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Image.php b/library/Rules/Image.php index 3b6c3c0a4..f0cc75144 100644 --- a/library/Rules/Image.php +++ b/library/Rules/Image.php @@ -23,7 +23,7 @@ '{{name}} must be a valid image', '{{name}} must not be a valid image', )] -final class Image extends AbstractRule +final class Image extends Simple { private readonly finfo $fileInfo; diff --git a/library/Rules/Imei.php b/library/Rules/Imei.php index fce836f4c..f8596b86a 100644 --- a/library/Rules/Imei.php +++ b/library/Rules/Imei.php @@ -19,7 +19,7 @@ '{{name}} must be a valid IMEI', '{{name}} must not be a valid IMEI', )] -final class Imei extends AbstractRule +final class Imei extends Simple { private const IMEI_SIZE = 15; diff --git a/library/Rules/Infinite.php b/library/Rules/Infinite.php index cb7daba5e..bd7e798c0 100644 --- a/library/Rules/Infinite.php +++ b/library/Rules/Infinite.php @@ -18,7 +18,7 @@ '{{name}} must be an infinite number', '{{name}} must not be an infinite number', )] -final class Infinite extends AbstractRule +final class Infinite extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/IntType.php b/library/Rules/IntType.php index 170e9dd52..f7d7ac7dc 100644 --- a/library/Rules/IntType.php +++ b/library/Rules/IntType.php @@ -17,7 +17,7 @@ '{{name}} must be of type integer', '{{name}} must not be of type integer', )] -final class IntType extends AbstractRule +final class IntType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/IntVal.php b/library/Rules/IntVal.php index 7ce3b6a63..42925a030 100644 --- a/library/Rules/IntVal.php +++ b/library/Rules/IntVal.php @@ -19,7 +19,7 @@ '{{name}} must be an integer number', '{{name}} must not be an integer number', )] -final class IntVal extends AbstractRule +final class IntVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Isbn.php b/library/Rules/Isbn.php index 0e3452779..f4d9ee6db 100644 --- a/library/Rules/Isbn.php +++ b/library/Rules/Isbn.php @@ -20,7 +20,7 @@ '{{name}} must be a ISBN', '{{name}} must not be a ISBN', )] -final class Isbn extends AbstractRule +final class Isbn extends Simple { /** * @see https://howtodoinjava.com/regex/java-regex-validate-international-standard-book-number-isbns diff --git a/library/Rules/IterableType.php b/library/Rules/IterableType.php index e863c8ce0..2ab40fed3 100644 --- a/library/Rules/IterableType.php +++ b/library/Rules/IterableType.php @@ -16,7 +16,7 @@ '{{name}} must be iterable', '{{name}} must not be iterable', )] -final class IterableType extends AbstractRule +final class IterableType extends Simple { use CanValidateIterable; diff --git a/library/Rules/Json.php b/library/Rules/Json.php index c87c6ff1e..6ca3a9f75 100644 --- a/library/Rules/Json.php +++ b/library/Rules/Json.php @@ -23,7 +23,7 @@ '{{name}} must be a valid JSON string', '{{name}} must not be a valid JSON string', )] -final class Json extends AbstractRule +final class Json extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/LeapDate.php b/library/Rules/LeapDate.php index 61321c426..aa8a96ef2 100644 --- a/library/Rules/LeapDate.php +++ b/library/Rules/LeapDate.php @@ -19,7 +19,7 @@ '{{name}} must be leap date', '{{name}} must not be leap date', )] -final class LeapDate extends AbstractRule +final class LeapDate extends Simple { public function __construct( private readonly string $format diff --git a/library/Rules/LeapYear.php b/library/Rules/LeapYear.php index 1da3a9408..3db40a5b7 100644 --- a/library/Rules/LeapYear.php +++ b/library/Rules/LeapYear.php @@ -22,7 +22,7 @@ '{{name}} must be a leap year', '{{name}} must not be a leap year', )] -final class LeapYear extends AbstractRule +final class LeapYear extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Lowercase.php b/library/Rules/Lowercase.php index a8ee9aee4..8e920d93b 100644 --- a/library/Rules/Lowercase.php +++ b/library/Rules/Lowercase.php @@ -18,7 +18,7 @@ '{{name}} must be lowercase', '{{name}} must not be lowercase', )] -final class Lowercase extends AbstractRule +final class Lowercase extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Luhn.php b/library/Rules/Luhn.php index b75258be2..4c66b65a0 100644 --- a/library/Rules/Luhn.php +++ b/library/Rules/Luhn.php @@ -22,7 +22,7 @@ '{{name}} must be a valid Luhn number', '{{name}} must not be a valid Luhn number', )] -final class Luhn extends AbstractRule +final class Luhn extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/MacAddress.php b/library/Rules/MacAddress.php index 1fabedb16..2c97515e1 100644 --- a/library/Rules/MacAddress.php +++ b/library/Rules/MacAddress.php @@ -18,7 +18,7 @@ '{{name}} must be a valid MAC address', '{{name}} must not be a valid MAC address', )] -final class MacAddress extends AbstractRule +final class MacAddress extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Negative.php b/library/Rules/Negative.php index 9b74bd316..ec030d33b 100644 --- a/library/Rules/Negative.php +++ b/library/Rules/Negative.php @@ -17,7 +17,7 @@ '{{name}} must be negative', '{{name}} must not be negative', )] -final class Negative extends AbstractRule +final class Negative extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/NfeAccessKey.php b/library/Rules/NfeAccessKey.php index d2411733a..d239984c3 100644 --- a/library/Rules/NfeAccessKey.php +++ b/library/Rules/NfeAccessKey.php @@ -23,7 +23,7 @@ '{{name}} must be a valid NFe access key', '{{name}} must not be a valid NFe access key', )] -final class NfeAccessKey extends AbstractRule +final class NfeAccessKey extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Nif.php b/library/Rules/Nif.php index 3419dea7e..6277148e1 100644 --- a/library/Rules/Nif.php +++ b/library/Rules/Nif.php @@ -26,7 +26,7 @@ '{{name}} must be a NIF', '{{name}} must not be a NIF', )] -final class Nif extends AbstractRule +final class Nif extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Nip.php b/library/Rules/Nip.php index 893aa50c5..d9c0c0245 100644 --- a/library/Rules/Nip.php +++ b/library/Rules/Nip.php @@ -23,7 +23,7 @@ '{{name}} must be a valid Polish VAT identification number', '{{name}} must not be a valid Polish VAT identification number', )] -final class Nip extends AbstractRule +final class Nip extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/NoWhitespace.php b/library/Rules/NoWhitespace.php index 318e5a35d..887d4b16e 100644 --- a/library/Rules/NoWhitespace.php +++ b/library/Rules/NoWhitespace.php @@ -19,7 +19,7 @@ '{{name}} must not contain whitespace', '{{name}} must contain whitespace', )] -final class NoWhitespace extends AbstractRule +final class NoWhitespace extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/NotEmoji.php b/library/Rules/NotEmoji.php index 72ebb7477..7402ee00c 100644 --- a/library/Rules/NotEmoji.php +++ b/library/Rules/NotEmoji.php @@ -19,7 +19,7 @@ '{{name}} must not contain an Emoji', '{{name}} must contain an Emoji', )] -final class NotEmoji extends AbstractRule +final class NotEmoji extends Simple { private const RANGES = [ '\x{0023}\x{FE0F}\x{20E3}', diff --git a/library/Rules/NullType.php b/library/Rules/NullType.php index 467a8a9b1..06539853b 100644 --- a/library/Rules/NullType.php +++ b/library/Rules/NullType.php @@ -17,7 +17,7 @@ '{{name}} must be null', '{{name}} must not be null', )] -final class NullType extends AbstractRule +final class NullType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Number.php b/library/Rules/Number.php index 295fad5f3..b72c673d9 100644 --- a/library/Rules/Number.php +++ b/library/Rules/Number.php @@ -18,7 +18,7 @@ '{{name}} must be a number', '{{name}} must not be a number', )] -final class Number extends AbstractRule +final class Number extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/NumericVal.php b/library/Rules/NumericVal.php index 83cd56ac2..dbc718c6b 100644 --- a/library/Rules/NumericVal.php +++ b/library/Rules/NumericVal.php @@ -17,7 +17,7 @@ '{{name}} must be numeric', '{{name}} must not be numeric', )] -final class NumericVal extends AbstractRule +final class NumericVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/ObjectType.php b/library/Rules/ObjectType.php index 107e9a3bd..2f9e6b2ce 100644 --- a/library/Rules/ObjectType.php +++ b/library/Rules/ObjectType.php @@ -17,7 +17,7 @@ '{{name}} must be of type object', '{{name}} must not be of type object', )] -final class ObjectType extends AbstractRule +final class ObjectType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Odd.php b/library/Rules/Odd.php index cdbb052e2..ab76d2700 100644 --- a/library/Rules/Odd.php +++ b/library/Rules/Odd.php @@ -20,7 +20,7 @@ '{{name}} must be an odd number', '{{name}} must not be an odd number', )] -final class Odd extends AbstractRule +final class Odd extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/PerfectSquare.php b/library/Rules/PerfectSquare.php index 08919c3d1..c0f237e3b 100644 --- a/library/Rules/PerfectSquare.php +++ b/library/Rules/PerfectSquare.php @@ -19,7 +19,7 @@ '{{name}} must be a valid perfect square', '{{name}} must not be a valid perfect square', )] -final class PerfectSquare extends AbstractRule +final class PerfectSquare extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Pesel.php b/library/Rules/Pesel.php index 87fbc5905..c004ae97c 100644 --- a/library/Rules/Pesel.php +++ b/library/Rules/Pesel.php @@ -18,7 +18,7 @@ '{{name}} must be a valid PESEL', '{{name}} must not be a valid PESEL', )] -final class Pesel extends AbstractRule +final class Pesel extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/PhpLabel.php b/library/Rules/PhpLabel.php index 1004b594e..16f0ac3fe 100644 --- a/library/Rules/PhpLabel.php +++ b/library/Rules/PhpLabel.php @@ -18,7 +18,7 @@ '{{name}} must be a valid PHP label', '{{name}} must not be a valid PHP label', )] -final class PhpLabel extends AbstractRule +final class PhpLabel extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Pis.php b/library/Rules/Pis.php index 0c86ca556..b35908701 100644 --- a/library/Rules/Pis.php +++ b/library/Rules/Pis.php @@ -20,7 +20,7 @@ '{{name}} must be a valid PIS number', '{{name}} must not be a valid PIS number', )] -final class Pis extends AbstractRule +final class Pis extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/PolishIdCard.php b/library/Rules/PolishIdCard.php index d05e39bf0..df3722aad 100644 --- a/library/Rules/PolishIdCard.php +++ b/library/Rules/PolishIdCard.php @@ -22,7 +22,7 @@ '{{name}} must be a valid Polish Identity Card number', '{{name}} must not be a valid Polish Identity Card number', )] -final class PolishIdCard extends AbstractRule +final class PolishIdCard extends Simple { private const ASCII_CODE_0 = 48; private const ASCII_CODE_7 = 55; diff --git a/library/Rules/PortugueseNif.php b/library/Rules/PortugueseNif.php index e0f00135c..240aebc97 100644 --- a/library/Rules/PortugueseNif.php +++ b/library/Rules/PortugueseNif.php @@ -28,7 +28,7 @@ '{{name}} must be a Portuguese NIF', '{{name}} must not be a Portuguese NIF', )] -final class PortugueseNif extends AbstractRule +final class PortugueseNif extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Positive.php b/library/Rules/Positive.php index d0ac76ba0..ec2aedf97 100644 --- a/library/Rules/Positive.php +++ b/library/Rules/Positive.php @@ -17,7 +17,7 @@ '{{name}} must be positive', '{{name}} must not be positive', )] -final class Positive extends AbstractRule +final class Positive extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/PrimeNumber.php b/library/Rules/PrimeNumber.php index a3adb5a74..8f38ff531 100644 --- a/library/Rules/PrimeNumber.php +++ b/library/Rules/PrimeNumber.php @@ -19,7 +19,7 @@ '{{name}} must be a valid prime number', '{{name}} must not be a valid prime number', )] -final class PrimeNumber extends AbstractRule +final class PrimeNumber extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/PublicDomainSuffix.php b/library/Rules/PublicDomainSuffix.php index d08ab108b..7b50dad03 100644 --- a/library/Rules/PublicDomainSuffix.php +++ b/library/Rules/PublicDomainSuffix.php @@ -23,7 +23,7 @@ '{{name}} must be a public domain suffix', '{{name}} must be a public domain suffix', )] -final class PublicDomainSuffix extends AbstractRule +final class PublicDomainSuffix extends Simple { use CanValidateUndefined; diff --git a/library/Rules/Readable.php b/library/Rules/Readable.php index b132b301d..86588c793 100644 --- a/library/Rules/Readable.php +++ b/library/Rules/Readable.php @@ -20,7 +20,7 @@ '{{name}} must be readable', '{{name}} must not be readable', )] -final class Readable extends AbstractRule +final class Readable extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/ResourceType.php b/library/Rules/ResourceType.php index 3a5947c7e..8ee1a01be 100644 --- a/library/Rules/ResourceType.php +++ b/library/Rules/ResourceType.php @@ -17,7 +17,7 @@ '{{name}} must be a resource', '{{name}} must not be a resource', )] -final class ResourceType extends AbstractRule +final class ResourceType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/ScalarVal.php b/library/Rules/ScalarVal.php index c0a4d3ad0..4bc087d5e 100644 --- a/library/Rules/ScalarVal.php +++ b/library/Rules/ScalarVal.php @@ -17,7 +17,7 @@ '{{name}} must be a scalar value', '{{name}} must not be a scalar value', )] -final class ScalarVal extends AbstractRule +final class ScalarVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Simple.php b/library/Rules/Simple.php new file mode 100644 index 000000000..cccf97b36 --- /dev/null +++ b/library/Rules/Simple.php @@ -0,0 +1,20 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Rules; + +use Respect\Validation\Result; + +abstract class Simple extends Standard +{ + public function evaluate(mixed $input): Result + { + return new Result($this->validate($input), $input, $this, self::TEMPLATE_STANDARD); + } +} diff --git a/library/Rules/Slug.php b/library/Rules/Slug.php index f172b53e9..4982bd55e 100644 --- a/library/Rules/Slug.php +++ b/library/Rules/Slug.php @@ -19,7 +19,7 @@ '{{name}} must be a valid slug', '{{name}} must not be a valid slug', )] -final class Slug extends AbstractRule +final class Slug extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Standard.php b/library/Rules/Standard.php new file mode 100644 index 000000000..5f458e13c --- /dev/null +++ b/library/Rules/Standard.php @@ -0,0 +1,46 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Rules; + +use Respect\Validation\Helpers\DeprecatedValidatableMethods; +use Respect\Validation\Validatable; + +abstract class Standard implements Validatable +{ + use DeprecatedValidatableMethods; + + private ?string $name = null; + + private ?string $template = null; + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function getTemplate(): ?string + { + return $this->template; + } + + public function setTemplate(string $template): static + { + $this->template = $template; + + return $this; + } +} diff --git a/library/Rules/StringType.php b/library/Rules/StringType.php index cb8e6f6c9..b81337648 100644 --- a/library/Rules/StringType.php +++ b/library/Rules/StringType.php @@ -17,7 +17,7 @@ '{{name}} must be of type string', '{{name}} must not be of type string', )] -final class StringType extends AbstractRule +final class StringType extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/StringVal.php b/library/Rules/StringVal.php index ac84b5070..a14e45421 100644 --- a/library/Rules/StringVal.php +++ b/library/Rules/StringVal.php @@ -19,7 +19,7 @@ '{{name}} must be a string', '{{name}} must not be string', )] -final class StringVal extends AbstractRule +final class StringVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/SymbolicLink.php b/library/Rules/SymbolicLink.php index 4ec4ee91a..e4b312df2 100644 --- a/library/Rules/SymbolicLink.php +++ b/library/Rules/SymbolicLink.php @@ -19,7 +19,7 @@ '{{name}} must be a symbolic link', '{{name}} must not be a symbolic link', )] -final class SymbolicLink extends AbstractRule +final class SymbolicLink extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Tld.php b/library/Rules/Tld.php index f51a6009b..2eba89be1 100644 --- a/library/Rules/Tld.php +++ b/library/Rules/Tld.php @@ -19,7 +19,7 @@ '{{name}} must be a valid top-level domain name', '{{name}} must not be a valid top-level domain name', )] -final class Tld extends AbstractRule +final class Tld extends Simple { // List extracted from https://data.iana.org/TLD/tlds-alpha-by-domain.txt private const TLD_LIST = [ diff --git a/library/Rules/TrueVal.php b/library/Rules/TrueVal.php index d10e93f6b..6c62222c6 100644 --- a/library/Rules/TrueVal.php +++ b/library/Rules/TrueVal.php @@ -20,7 +20,7 @@ '{{name}} must evaluate to `true`', '{{name}} must not evaluate to `true`', )] -final class TrueVal extends AbstractRule +final class TrueVal extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Unique.php b/library/Rules/Unique.php index 55232fc77..7dc89684a 100644 --- a/library/Rules/Unique.php +++ b/library/Rules/Unique.php @@ -20,7 +20,7 @@ '{{name}} must not contain duplicates', '{{name}} must contain duplicates', )] -final class Unique extends AbstractRule +final class Unique extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Uploaded.php b/library/Rules/Uploaded.php index 75c5d62f1..9423b0121 100644 --- a/library/Rules/Uploaded.php +++ b/library/Rules/Uploaded.php @@ -20,7 +20,7 @@ '{{name}} must be an uploaded file', '{{name}} must not be an uploaded file', )] -final class Uploaded extends AbstractRule +final class Uploaded extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Uppercase.php b/library/Rules/Uppercase.php index ef7346b98..03e4096d9 100644 --- a/library/Rules/Uppercase.php +++ b/library/Rules/Uppercase.php @@ -18,7 +18,7 @@ '{{name}} must be uppercase', '{{name}} must not be uppercase', )] -final class Uppercase extends AbstractRule +final class Uppercase extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Version.php b/library/Rules/Version.php index 1006742c9..91a4ce006 100644 --- a/library/Rules/Version.php +++ b/library/Rules/Version.php @@ -21,7 +21,7 @@ '{{name}} must be a version', '{{name}} must not be a version', )] -final class Version extends AbstractRule +final class Version extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Writable.php b/library/Rules/Writable.php index 20ed2e803..1ed760202 100644 --- a/library/Rules/Writable.php +++ b/library/Rules/Writable.php @@ -20,7 +20,7 @@ '{{name}} must be writable', '{{name}} must not be writable', )] -final class Writable extends AbstractRule +final class Writable extends Simple { public function validate(mixed $input): bool { diff --git a/library/Rules/Yes.php b/library/Rules/Yes.php index 09e4b97de..20825fc84 100644 --- a/library/Rules/Yes.php +++ b/library/Rules/Yes.php @@ -21,7 +21,7 @@ '{{name}} must be similar to "Yes"', '{{name}} must not be similar to "Yes"', )] -final class Yes extends AbstractRule +final class Yes extends Simple { public function __construct( private readonly bool $useLocale = false diff --git a/tests/library/Rules/ConcreteSimple.php b/tests/library/Rules/ConcreteSimple.php new file mode 100644 index 000000000..d8299a877 --- /dev/null +++ b/tests/library/Rules/ConcreteSimple.php @@ -0,0 +1,20 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Test\Rules; + +use Respect\Validation\Rules\Simple; + +final class ConcreteSimple extends Simple +{ + public function validate(mixed $input): bool + { + return true; + } +} diff --git a/tests/library/Rules/ConcreteStandard.php b/tests/library/Rules/ConcreteStandard.php new file mode 100644 index 000000000..415153e3e --- /dev/null +++ b/tests/library/Rules/ConcreteStandard.php @@ -0,0 +1,21 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Test\Rules; + +use Respect\Validation\Result; +use Respect\Validation\Rules\Standard; + +final class ConcreteStandard extends Standard +{ + public function evaluate(mixed $input): Result + { + return Result::passed($input, $this); + } +} diff --git a/tests/unit/Rules/AlwaysInvalidTest.php b/tests/unit/Rules/AlwaysInvalidTest.php index 0ec264bfc..8d2356f41 100644 --- a/tests/unit/Rules/AlwaysInvalidTest.php +++ b/tests/unit/Rules/AlwaysInvalidTest.php @@ -25,7 +25,7 @@ public function itShouldAlwaysBeInvalid(mixed $input): void { $rule = new AlwaysInvalid(); - self::assertFalse($rule->validate($input)); + self::assertFalse($rule->evaluate($input)->isValid); } /** diff --git a/tests/unit/Rules/AlwaysValidTest.php b/tests/unit/Rules/AlwaysValidTest.php index 73535334d..6deface66 100644 --- a/tests/unit/Rules/AlwaysValidTest.php +++ b/tests/unit/Rules/AlwaysValidTest.php @@ -25,7 +25,7 @@ public function itAlwaysBeValid(mixed $input): void { $rule = new AlwaysValid(); - self::assertTrue($rule->validate($input)); + self::assertTrue($rule->evaluate($input)->isValid); } /** diff --git a/tests/unit/Rules/NotTest.php b/tests/unit/Rules/NotTest.php index 4729a53f2..a8fcf90f7 100644 --- a/tests/unit/Rules/NotTest.php +++ b/tests/unit/Rules/NotTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; -use Respect\Validation\Exceptions\ValidationException; use Respect\Validation\Test\TestCase; use Respect\Validation\Validatable; use Respect\Validation\Validator; @@ -26,10 +25,9 @@ final class NotTest extends TestCase #[DataProvider('providerForValidNot')] public function not(Validatable $rule, mixed $input): void { - $this->expectNotToPerformAssertions(); - $not = new Not($rule); - $not->assert($input); + + self::assertTrue($not->evaluate($input)->isValid); } #[Test] @@ -38,9 +36,7 @@ public function notNotHaha(Validatable $rule, mixed $input): void { $not = new Not($rule); - $this->expectException(ValidationException::class); - - $not->assert($input); + self::assertFalse($not->evaluate($input)->isValid); } #[Test] diff --git a/tests/unit/Rules/SimpleTest.php b/tests/unit/Rules/SimpleTest.php new file mode 100644 index 000000000..6543ceff1 --- /dev/null +++ b/tests/unit/Rules/SimpleTest.php @@ -0,0 +1,46 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Rules; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use Respect\Validation\Rule; +use Respect\Validation\Test\Rules\ConcreteSimple; +use Respect\Validation\Test\TestCase; + +#[Group('core')] +#[CoversClass(Simple::class)] +final class SimpleTest extends TestCase +{ + #[Test] + public function itShouldEvaluateUsingTheValidateMethod(): void + { + $rule = new ConcreteSimple(); + + self::assertTrue($rule->evaluate('any')->isValid); + } + + #[Test] + public function itShouldEvaluateReturningTheCurrentRule(): void + { + $rule = new ConcreteSimple(); + + self::assertSame($rule, $rule->evaluate('any')->rule); + } + + #[Test] + public function itShouldEvaluateReturningTheStandardTemplate(): void + { + $rule = new ConcreteSimple(); + + self::assertSame(Rule::TEMPLATE_STANDARD, $rule->evaluate('any')->template); + } +} diff --git a/tests/unit/Rules/StandardTest.php b/tests/unit/Rules/StandardTest.php new file mode 100644 index 000000000..1471c205b --- /dev/null +++ b/tests/unit/Rules/StandardTest.php @@ -0,0 +1,55 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +namespace Respect\Validation\Rules; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; +use Respect\Validation\Test\Rules\ConcreteStandard; +use Respect\Validation\Test\TestCase; + +#[Group('core')] +#[CoversClass(Standard::class)] +final class StandardTest extends TestCase +{ + #[Test] + public function itShouldNotHaveAnyNameByDefault(): void + { + $rule = new ConcreteStandard(); + + self::assertNull($rule->getName()); + } + + #[Test] + public function itShouldBeAbleToSetName(): void + { + $rule = new ConcreteStandard(); + $rule->setName('foo'); + + self::assertEquals('foo', $rule->getName()); + } + + #[Test] + public function itShouldNotHaveAnyTemplateByDefault(): void + { + $rule = new ConcreteStandard(); + + self::assertNull($rule->getTemplate()); + } + + #[Test] + public function itShouldBeAbleToSetTemplate(): void + { + $rule = new ConcreteStandard(); + $rule->setTemplate('foo'); + + self::assertEquals('foo', $rule->getTemplate()); + } +}