diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 6b28f9a..8f62f5d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -17,8 +17,7 @@ jobs: strategy: matrix: php-version: - - "8.1" - - "8.2" + - "8.5" steps: - name: Checkout @@ -54,7 +53,7 @@ jobs: - name: Install PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.5 coverage: pcov - name: Install Dependencies @@ -78,7 +77,7 @@ jobs: - name: Install PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.5 coverage: none - name: Install dependencies diff --git a/composer.json b/composer.json index dc27c24..e1ba0ab 100644 --- a/composer.json +++ b/composer.json @@ -13,22 +13,19 @@ "psr-4": { "Respect\\Test\\Integration\\Assertion\\": "tests/integration", "Respect\\Test\\Unit\\Assertion\\": "tests/unit" - }, - "files": [ - "tests/documentation/lib/helpers.php" - ] + } }, "require": { - "php": "^8.1", - "respect/stringifier": "^0.2.0", - "respect/validation": "^2.2.4", + "php": "^8.5", + "respect/stringifier": "^3.0", + "respect/validation": "^3.0", "symfony/polyfill-mbstring": "^v1.27.0" }, "require-dev": { "malukenho/docheader": "^0.1.8", - "phpstan/phpstan": "^1.10.7", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.0.17", "respect/coding-standard": "^4.0.0", "squizlabs/php_codesniffer": "^3.7.2" diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 9ac6aa0..74ecc01 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -5,7 +5,7 @@ - + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index bdbe649..eb67c9d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,8 +3,8 @@ parameters: paths: - src/ - tests/ - fileExtensions: - - php - - phpt ignoreErrors: - '/Call to an undefined method Respect\\Assertion\\Mixin\\Chain\\Mixin::[a-zA-Z]+\(\)/' + - identifier: method.nonObject + paths: + - tests/integration/ diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3b151fa..3ef87a7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,9 +6,6 @@ - - tests/documentation - tests/integration/ diff --git a/src/Assertion.php b/src/Assertion.php index 9bba225..9ad31a6 100644 --- a/src/Assertion.php +++ b/src/Assertion.php @@ -13,21 +13,19 @@ namespace Respect\Assertion; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Validatable; +use Respect\Validation\Validator; +use Respect\Validation\ValidatorBuilder; use Throwable; -use function is_string; - final class Assertion { public function __construct( - private readonly Validatable $rule, + private readonly Validator $rule, private readonly null|string|Throwable $description = null ) { } - public function getRule(): Validatable + public function getRule(): Validator { return $this->rule; } @@ -39,18 +37,15 @@ public function getDescription(): null|string|Throwable public function assert(mixed $input): void { - try { - $this->rule->check($input); - } catch (ValidationException $exception) { - if ($this->description instanceof Throwable) { + if ($this->description instanceof Throwable) { + $result = $this->rule->evaluate($input); + if (!$result->hasPassed) { throw $this->description; } - if (is_string($this->description)) { - $exception->updateTemplate($this->description); - } - - throw $exception; + return; } + + ValidatorBuilder::init($this->rule)->assert($input, $this->description); } } diff --git a/src/Chain/SimpleChain.php b/src/Chain/SimpleChain.php index 927e784..167fd82 100644 --- a/src/Chain/SimpleChain.php +++ b/src/Chain/SimpleChain.php @@ -58,7 +58,7 @@ private function create(string $name, array $parameters): Assertion /** * @param array $arguments */ - public function __call(string $name, array $arguments): self + public function __call(string $name, array $arguments): static { $assertion = $this->create($name, $arguments); $assertion->assert($this->input); diff --git a/src/Creator/KeyCreator.php b/src/Creator/KeyCreator.php index 24a6eb0..05b8ed9 100644 --- a/src/Creator/KeyCreator.php +++ b/src/Creator/KeyCreator.php @@ -16,8 +16,9 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Rules\Key; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Key; +use Respect\Validation\Validators\KeyExists; +use Respect\Validation\Validators\Not; use Throwable; use function array_shift; @@ -52,11 +53,11 @@ public function create(string $name, array $parameters): Assertion } if ($name === 'keyPresent') { - return new Assertion(new Key($key), $this->getDescription($name, $parameters)); + return new Assertion(new KeyExists($key), $this->getDescription($name, $parameters)); } if ($name === 'keyNotPresent') { - return new Assertion(new Not(new Key($key)), $this->getDescription($name, $parameters)); + return new Assertion(new Not(new KeyExists($key)), $this->getDescription($name, $parameters)); } $assertion = $this->creator->create(lcfirst(substr($name, 3)), $parameters); diff --git a/src/Creator/NotCreator.php b/src/Creator/NotCreator.php index b9f91ad..f4c612a 100644 --- a/src/Creator/NotCreator.php +++ b/src/Creator/NotCreator.php @@ -16,7 +16,7 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Not; use function in_array; use function lcfirst; diff --git a/src/Creator/NullOrCreator.php b/src/Creator/NullOrCreator.php index 58ae9f9..29eb3f1 100644 --- a/src/Creator/NullOrCreator.php +++ b/src/Creator/NullOrCreator.php @@ -16,7 +16,7 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Rules\Nullable; +use Respect\Validation\Validators\NullOr; use function lcfirst; use function str_starts_with; @@ -40,6 +40,6 @@ public function create(string $name, array $parameters): Assertion $assertion = $this->creator->create(lcfirst(substr($name, 6)), $parameters); - return new Assertion(new Nullable($assertion->getRule()), $assertion->getDescription()); + return new Assertion(new NullOr($assertion->getRule()), $assertion->getDescription()); } } diff --git a/src/Creator/PrefixedCreator.php b/src/Creator/PrefixedCreator.php index c14fd85..b8a2412 100644 --- a/src/Creator/PrefixedCreator.php +++ b/src/Creator/PrefixedCreator.php @@ -17,7 +17,7 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Validatable; +use Respect\Validation\Validator; use function lcfirst; use function str_starts_with; @@ -27,7 +27,7 @@ final class PrefixedCreator implements Creator { /** - * @param class-string $className + * @param class-string $className */ public function __construct( private readonly string $prefix, diff --git a/src/Creator/PropertyCreator.php b/src/Creator/PropertyCreator.php index 888e3de..3f16a96 100644 --- a/src/Creator/PropertyCreator.php +++ b/src/Creator/PropertyCreator.php @@ -16,8 +16,9 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Rules\Attribute; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Not; +use Respect\Validation\Validators\Property; +use Respect\Validation\Validators\PropertyExists; use Throwable; use function array_shift; @@ -51,16 +52,16 @@ public function create(string $name, array $parameters): Assertion } if ($name === 'propertyPresent') { - return new Assertion(new Attribute($property), $this->getDescription($name, $parameters)); + return new Assertion(new PropertyExists($property), $this->getDescription($name, $parameters)); } if ($name === 'propertyNotPresent') { - return new Assertion(new Not(new Attribute($property)), $this->getDescription($name, $parameters)); + return new Assertion(new Not(new PropertyExists($property)), $this->getDescription($name, $parameters)); } $assertion = $this->creator->create(lcfirst(substr($name, 8)), $parameters); - return new Assertion(new Attribute($property, $assertion->getRule()), $assertion->getDescription()); + return new Assertion(new Property($property, $assertion->getRule()), $assertion->getDescription()); } /** diff --git a/src/Creator/StandardCreator.php b/src/Creator/StandardCreator.php index e853908..54487b4 100644 --- a/src/Creator/StandardCreator.php +++ b/src/Creator/StandardCreator.php @@ -17,7 +17,7 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Validatable; +use Respect\Validation\Validator; use Throwable; use function array_slice; @@ -45,18 +45,18 @@ public function create(string $name, array $parameters): Assertion $constructor === null ? 0 : count($constructor->getParameters()) ); - /** @var Validatable $rule */ + /** @var Validator $rule */ $rule = $reflection->newInstanceArgs($constructorParameters); return new Assertion($rule, $this->description($name, $parameters, $constructorParameters)); } /** - * @return ReflectionClass + * @return ReflectionClass */ private function ruleReflection(string $name): ReflectionClass { - $class = sprintf('Respect\\Validation\\Rules\\%s', ucfirst($name)); + $class = sprintf('Respect\\Validation\\Validators\\%s', ucfirst($name)); if (!class_exists($class)) { throw new CannotCreateAssertionException(sprintf('"%s" is not a valid assertion', $name)); @@ -67,7 +67,7 @@ private function ruleReflection(string $name): ReflectionClass throw new CannotCreateAssertionException(sprintf('Cannot create an instance of "%s"', $class)); } - if (!$reflection->isSubclassOf(Validatable::class)) { + if (!$reflection->isSubclassOf(Validator::class)) { throw new CannotCreateAssertionException(sprintf('Cannot create an instance of "%s"', $class)); } diff --git a/src/Rule/All.php b/src/Rule/All.php index 00f2a48..26526cf 100644 --- a/src/Rule/All.php +++ b/src/Rule/All.php @@ -13,34 +13,21 @@ namespace Respect\Assertion\Rule; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\Each; -use Respect\Validation\Rules\IterableType; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; +use Respect\Validation\Validators\All as ValidateAll; -use function Respect\Stringifier\stringify; - -final class All extends Rule +final class All implements Validator { - public function __construct(Validatable $rule) - { - parent::__construct( - new IterableType(), - new Each($rule), - ); - } + private readonly ValidateAll $validator; - protected function getFilteredInput(mixed $input): mixed + public function __construct(Validator $rule) { - return $input; + $this->validator = new ValidateAll($rule); } - protected function getCustomizedException(ValidationException $exception): ValidationException + public function evaluate(mixed $input): Result { - $params = $exception->getParams(); - $params['name'] = stringify($params['input']) . ' (like all items of the input)'; - $exception->updateParams($params); - - return $exception; + return $this->validator->evaluate($input); } } diff --git a/src/Rule/Envelope.php b/src/Rule/Envelope.php deleted file mode 100644 index adc043d..0000000 --- a/src/Rule/Envelope.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE file - * that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace Respect\Assertion\Rule; - -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AbstractEnvelope; -use Respect\Validation\Validatable; - -final class Envelope extends AbstractEnvelope -{ - public function __construct(Validatable $validatable, string $template) - { - parent::__construct($validatable, []); - $this->template = $template; - } - - /** - * {@inheritDoc} - */ - public function reportError($input, array $extraParameters = []): ValidationException - { - $exception = parent::reportError($input, $extraParameters); - $exception->updateTemplate((string) $this->template); - - return $exception; - } -} diff --git a/src/Rule/Length.php b/src/Rule/Length.php index 39ef3db..882fe40 100644 --- a/src/Rule/Length.php +++ b/src/Rule/Length.php @@ -13,52 +13,21 @@ namespace Respect\Assertion\Rule; -use Countable as PhpCountable; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AnyOf; -use Respect\Validation\Rules\Countable; -use Respect\Validation\Rules\StringType; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; +use Respect\Validation\Validators\Length as ValidateLength; -use function count; -use function is_array; -use function mb_strlen; - -final class Length extends Rule +final class Length implements Validator { - public function __construct(Validatable $rule) - { - parent::__construct( - new Envelope( - new AnyOf(new StringType(), new Countable()), - '{{input}} must be a string or a countable object' - ), - $rule - ); - } + private readonly ValidateLength $validator; - /** - * @param array|PhpCountable|string $input - */ - protected function getFilteredInput(mixed $input): int + public function __construct(Validator $rule) { - if (is_array($input)) { - return count($input); - } - - if ($input instanceof PhpCountable) { - return $input->count(); - } - - return mb_strlen($input); + $this->validator = new ValidateLength($rule); } - protected function getCustomizedException(ValidationException $exception): ValidationException + public function evaluate(mixed $input): Result { - $params = $exception->getParams(); - $params['name'] = $params['input'] . ' (the length of the input)'; - $exception->updateParams($params); - - return $exception; + return $this->validator->evaluate($input); } } diff --git a/src/Rule/Max.php b/src/Rule/Max.php index 46b5207..7b7d07f 100644 --- a/src/Rule/Max.php +++ b/src/Rule/Max.php @@ -13,54 +13,21 @@ namespace Respect\Assertion\Rule; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AllOf; -use Respect\Validation\Rules\AnyOf; -use Respect\Validation\Rules\ArrayType; -use Respect\Validation\Rules\Call; -use Respect\Validation\Rules\GreaterThan; -use Respect\Validation\Rules\IterableType; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; +use Respect\Validation\Validators\Max as ValidateMax; -use function is_array; -use function iterator_to_array; -use function max; -use function Respect\Stringifier\stringify; - -final class Max extends Rule +final class Max implements Validator { - public function __construct(Validatable $rule) - { - parent::__construct( - new Envelope( - new AllOf( - new AnyOf(new ArrayType(), new IterableType()), - new Call('count', new GreaterThan(0)), - ), - '{{input}} must be an non-empty array or iterable', - ), - $rule, - ); - } + private readonly ValidateMax $validator; - /** - * @param array|iterable $input - */ - protected function getFilteredInput(mixed $input): mixed + public function __construct(Validator $rule) { - if (is_array($input)) { - return max($input); - } - - return $this->getFilteredInput(iterator_to_array($input)); + $this->validator = new ValidateMax($rule); } - protected function getCustomizedException(ValidationException $exception): ValidationException + public function evaluate(mixed $input): Result { - $params = $exception->getParams(); - $params['name'] = stringify($params['input']) . ' (the maximum of the input)'; - $exception->updateParams($params); - - return $exception; + return $this->validator->evaluate($input); } } diff --git a/src/Rule/Min.php b/src/Rule/Min.php index 87eaf6f..108b015 100644 --- a/src/Rule/Min.php +++ b/src/Rule/Min.php @@ -13,54 +13,21 @@ namespace Respect\Assertion\Rule; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AllOf; -use Respect\Validation\Rules\AnyOf; -use Respect\Validation\Rules\ArrayType; -use Respect\Validation\Rules\Call; -use Respect\Validation\Rules\GreaterThan; -use Respect\Validation\Rules\IterableType; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; +use Respect\Validation\Validators\Min as ValidateMin; -use function is_array; -use function iterator_to_array; -use function min; -use function Respect\Stringifier\stringify; - -final class Min extends Rule +final class Min implements Validator { - public function __construct(Validatable $rule) - { - parent::__construct( - new Envelope( - new AllOf( - new AnyOf(new ArrayType(), new IterableType()), - new Call('count', new GreaterThan(0)), - ), - '{{input}} must be an non-empty array or iterable', - ), - $rule, - ); - } + private readonly ValidateMin $validator; - /** - * @param array|iterable $input - */ - protected function getFilteredInput(mixed $input): mixed + public function __construct(Validator $rule) { - if (is_array($input)) { - return min($input); - } - - return $this->getFilteredInput(iterator_to_array($input)); + $this->validator = new ValidateMin($rule); } - protected function getCustomizedException(ValidationException $exception): ValidationException + public function evaluate(mixed $input): Result { - $params = $exception->getParams(); - $params['name'] = stringify($params['input']) . ' (the minimum of the input)'; - $exception->updateParams($params); - - return $exception; + return $this->validator->evaluate($input); } } diff --git a/src/Rule/Rule.php b/src/Rule/Rule.php index ad50532..9bfbec3 100644 --- a/src/Rule/Rule.php +++ b/src/Rule/Rule.php @@ -13,41 +13,27 @@ namespace Respect\Assertion\Rule; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AbstractRule; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; -abstract class Rule extends AbstractRule +abstract class Rule implements Validator { abstract protected function getFilteredInput(mixed $input): mixed; - abstract protected function getCustomizedException(ValidationException $exception): ValidationException; - public function __construct( - private readonly Validatable $preconditionRule, - private readonly Validatable $rule, + private readonly Validator $preconditionRule, + private readonly Validator $rule, ) { } - /** - * {@inheritDoc} - */ - public function validate($input): bool + public function evaluate(mixed $input): Result { - return $this->preconditionRule->validate($input) && $this->rule->validate($this->getFilteredInput($input)); - } + $preconditionResult = $this->preconditionRule->evaluate($input); - /** - * {@inheritDoc} - */ - public function check($input): void - { - $this->preconditionRule->assert($input); - - try { - $this->rule->check($this->getFilteredInput($input)); - } catch (ValidationException $exception) { - throw $this->getCustomizedException($exception); + if (!$preconditionResult->hasPassed) { + return $preconditionResult; } + + return $this->rule->evaluate($this->getFilteredInput($input)); } } diff --git a/tests/documentation/lib/helpers.php b/tests/documentation/lib/helpers.php deleted file mode 100644 index 2994c94..0000000 --- a/tests/documentation/lib/helpers.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE file - * that was distributed with this source code. - */ - -declare(strict_types=1); - -function exceptionMessage(callable $callable): void -{ - try { - $callable(); - } catch (Throwable $exception) { - echo $exception->getMessage() . PHP_EOL; - } -} diff --git a/tests/documentation/prefixes-all.phpt b/tests/documentation/prefixes-all.phpt deleted file mode 100644 index d805fba..0000000 --- a/tests/documentation/prefixes-all.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---FILE-- - Assert::allIntType([1, 2, '3'])); -exceptionMessage( - static fn() => Assert::thatAll([1, 2, 2, 1, 3]) - ->intVal() - ->between(1, 2) -); -exceptionMessage( - static fn() => Assert::that([1, 2, 2, 1, 3]) - ->arrayType() - ->lengthLessThan(4) - ->all()->intVal()->between(1, 2) -); -?> ---EXPECT-- -"3" (like all items of the input) must be of type integer -3 (like all items of the input) must be between 1 and 2 -5 (the length of the input) must be less than 4 diff --git a/tests/documentation/prefixes-key.phpt b/tests/documentation/prefixes-key.phpt deleted file mode 100644 index 0487c0d..0000000 --- a/tests/documentation/prefixes-key.phpt +++ /dev/null @@ -1,39 +0,0 @@ ---FILE-- - Assert::keyPresent(['foo' => true], 'bar')); -exceptionMessage(static fn() => Assert::keyNotPresent(['bar' => 2], 'bar')); -exceptionMessage(static fn() => Assert::keyEquals(['foo' => 2], 'foo', 3)); -exceptionMessage(static fn() => Assert::keyNegative(['bar' => 2], 'bar')); -exceptionMessage(static fn() => Assert::keyNotIntType(['bar' => 2], 'bar')); -exceptionMessage(static fn() => Assert::keyNegative(['foo' => 2], 'baz')); -exceptionMessage(static fn() => Assert::keyExists(['foo' => '/path/to/file.txt'], 'foo')); -exceptionMessage( - static fn() => Assert::thatKey(['foo' => 'my-string'], 'foo') - ->stringType() - ->startsWith('my-') - ->lengthLessThan(4) -);exceptionMessage( - static fn() => Assert::that(['foo' => 'my-string', 'bar' => 42]) - ->arrayType() - ->key('foo')->stringType()->startsWith('my-') - ->key('bar')->intType()->positive()->lessThan(40) -); - -?> ---EXPECT-- -bar must be present -bar must not be present -foo must equal 3 -bar must be negative -bar must not be of type integer -baz must be present -foo must exists -9 (the length of the input) must be less than 4 -bar must be less than 40 \ No newline at end of file diff --git a/tests/documentation/prefixes-length.phpt b/tests/documentation/prefixes-length.phpt deleted file mode 100644 index 6963a30..0000000 --- a/tests/documentation/prefixes-length.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - Assert::lengthBetween('string', 10, 15)); -exceptionMessage(static fn() => Assert::lengthOdd([1, 2, 3, 4])); -exceptionMessage(static fn() => Assert::lengthEven(new ArrayObject([1, 2, 3]))); -exceptionMessage(static fn() => Assert::lengthNotMultiple([1, 2], 2)); -?> ---EXPECT-- -6 (the length of the input) must be between 10 and 15 -4 (the length of the input) must be an odd number -3 (the length of the input) must be an even number -2 (the length of the input) must not be multiple of 2 diff --git a/tests/documentation/prefixes-max.phpt b/tests/documentation/prefixes-max.phpt deleted file mode 100644 index 0d842c6..0000000 --- a/tests/documentation/prefixes-max.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - Assert::maxBetween([1, 2, 3], 5, 10)); -exceptionMessage(static fn() => Assert::maxEven([1, 2, 3])); -exceptionMessage(static fn() => Assert::maxPerfectSquare(new ArrayObject([45, 60, 20]))); -exceptionMessage(static fn() => Assert::maxNotPositive([23, 7, 20])); -?> ---EXPECT-- -3 (the maximum of the input) must be between 5 and 10 -3 (the maximum of the input) must be an even number -60 (the maximum of the input) must be a valid perfect square -23 (the maximum of the input) must not be positive diff --git a/tests/documentation/prefixes-min.phpt b/tests/documentation/prefixes-min.phpt deleted file mode 100644 index 975330b..0000000 --- a/tests/documentation/prefixes-min.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - Assert::minBetween([1, 2, 3], 5, 10)); -exceptionMessage(static fn() => Assert::minEven([1, 2, 3])); -exceptionMessage(static fn() => Assert::minPerfectSquare(new ArrayObject([45, 60, 20]))); -exceptionMessage(static fn() => Assert::minNotPositive([23, 7, 20])); -?> ---EXPECT-- -1 (the minimum of the input) must be between 5 and 10 -1 (the minimum of the input) must be an even number -20 (the minimum of the input) must be a valid perfect square -7 (the minimum of the input) must not be positive diff --git a/tests/documentation/prefixes-not.phpt b/tests/documentation/prefixes-not.phpt deleted file mode 100644 index 224caf3..0000000 --- a/tests/documentation/prefixes-not.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---FILE-- - Assert::notEven(2)); -exceptionMessage(static fn() => Assert::notIn(3, [1, 2, 3, 4])); -exceptionMessage( - static fn() => Assert::thatNot('1') - ->intType() - ->positive() - ->between(1, 3) -); -exceptionMessage( - static fn() => Assert::that('1') - ->not()->intType()->positive()->between(1, 3) -); -?> ---EXPECT-- -2 must not be an even number -3 must not be in `{ 1, 2, 3, 4 }` -"1" must not be positive -"1" must not be positive \ No newline at end of file diff --git a/tests/documentation/prefixes-nullOr.phpt b/tests/documentation/prefixes-nullOr.phpt deleted file mode 100644 index 5ebe04c..0000000 --- a/tests/documentation/prefixes-nullOr.phpt +++ /dev/null @@ -1,35 +0,0 @@ ---FILE-- - Assert::nullOrNegative(42)); -exceptionMessage(static fn() => Assert::nullOrNegative(null)); -exceptionMessage(static fn() => Assert::nullOrBetween(5, 1, 4)); -exceptionMessage(static fn() => Assert::nullOrBetween(null, 1, 4)); -exceptionMessage( - static fn() => Assert::thatNullOr(6) - ->positive() - ->between(1, 10) - ->primeNumber() -); -exceptionMessage( - static fn() => Assert::thatNullOr(null) - ->positive() - ->between(1, 10) - ->primeNumber() -); -exceptionMessage( - static fn() => Assert::that(6) - ->nullOr()->positive()->between(1, 10)->primeNumber() -); -?> ---EXPECT-- -42 must be negative -5 must be between 1 and 4 -6 must be a valid prime number -6 must be a valid prime number \ No newline at end of file diff --git a/tests/documentation/prefixes-property.phpt b/tests/documentation/prefixes-property.phpt deleted file mode 100644 index 61a8ac2..0000000 --- a/tests/documentation/prefixes-property.phpt +++ /dev/null @@ -1,41 +0,0 @@ ---FILE-- -foo = 1; - -exceptionMessage(static fn() => Assert::propertyPresent($input, 'bar')); -exceptionMessage(static fn() => Assert::propertyNotPresent($input, 'foo')); -exceptionMessage(static fn() => Assert::propertyEquals($input, 'foo', 3)); -exceptionMessage(static fn() => Assert::propertyNegative($input, 'foo')); -exceptionMessage(static fn() => Assert::propertyNotIntType($input, 'foo')); -exceptionMessage(static fn() => Assert::propertyNegative($input, 'baz')); -exceptionMessage(static fn() => Assert::propertyExists($input, 'foo')); -exceptionMessage( - static fn() => Assert::thatProperty($input, 'foo') - ->intType() - ->positive() - ->greaterThan(5) -); -exceptionMessage( - static fn() => Assert::that($input) - ->instance(stdClass::class) - ->property('foo')->intType()->positive()->greaterThan(5) -); -?> ---EXPECT-- -Attribute bar must be present -Attribute foo must not be present -foo must equal 3 -foo must be negative -foo must not be of type integer -Attribute baz must be present -foo must exists -foo must be greater than 5 -foo must be greater than 5 diff --git a/tests/documentation/usage-chained-assertions.phpt b/tests/documentation/usage-chained-assertions.phpt deleted file mode 100644 index d0dd966..0000000 --- a/tests/documentation/usage-chained-assertions.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---FILE-- - Assert::that(-1) - ->intVal('The number {{input}} must be an integer') - ->positive('I expected a positive number') - ->lessThan(4) -); -exceptionMessage( - static fn() => Assert::that(0, new DomainException('The number must be valid')) - ->positive() - ->greaterThan(5) -); -exceptionMessage( - static fn() => Assert::that(3, 'The number must be valid') - ->positive() - ->greaterThan(5, 'But it is not greater than 5, though') -); -exceptionMessage( - static fn() => Assert::that(['names' => ['Respect', 'Assertion'], 'options' => [1, 2, 3]]) - ->all()->arrayType() - ->key('names')->allStringType() - ->key('options')->lengthEquals(4) -); -?> ---EXPECT-- -I expected a positive number -The number must be valid -But it is not greater than 5, though -3 (the length of the input) must equal 4 diff --git a/tests/documentation/usage-custom-exceptions.phpt b/tests/documentation/usage-custom-exceptions.phpt deleted file mode 100644 index 351f39e..0000000 --- a/tests/documentation/usage-custom-exceptions.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---FILE-- - Assert::between(42, 1, 10, new DomainException('Something is not right'))); -?> ---EXPECT-- -Something is not right diff --git a/tests/documentation/usage-custom-messages.phpt b/tests/documentation/usage-custom-messages.phpt deleted file mode 100644 index 23f9217..0000000 --- a/tests/documentation/usage-custom-messages.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---FILE-- - Assert::equals(1, 5, 'I was expecting {{compareTo}}, but you gave be {{input}}')); -?> ---EXPECT-- -I was expecting 5, but you gave be 1 diff --git a/tests/documentation/usage.phpt b/tests/documentation/usage.phpt deleted file mode 100644 index 988ef83..0000000 --- a/tests/documentation/usage.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---FILE-- - Assert::equals(1, 5)); -exceptionMessage(static fn() => Assert::intType('string')); -exceptionMessage(static fn() => Assert::odd(5)); -?> ---EXPECT-- -1 must equal 5 -"string" must be of type integer diff --git a/tests/integration/AssertTest.php b/tests/integration/AssertTest.php index a5e405c..908c865 100644 --- a/tests/integration/AssertTest.php +++ b/tests/integration/AssertTest.php @@ -17,7 +17,6 @@ use Exception; use PHPUnit\Framework\TestCase; use Respect\Assertion\Assert; -use Respect\Validation\Exceptions\NegativeException; use Respect\Validation\Exceptions\ValidationException; use function array_merge; @@ -100,7 +99,7 @@ public function itShouldThrowCustomExceptionMessageWhenInvalid(string $name, arr */ public function itShouldThrowRespectValidationException(): void { - $this->expectException(NegativeException::class); + $this->expectException(ValidationException::class); Assert::that(2)->negative(); } @@ -110,10 +109,10 @@ public function itShouldThrowRespectValidationException(): void */ public function itShouldThrowRespectValidationExceptionWithCustomTemplate(): void { - $this->expectException(NegativeException::class); - $this->expectExceptionMessage('The input 2 that you are validating must be negative.'); + $this->expectException(ValidationException::class); + $this->expectExceptionMessage('2 must be a negative number'); - Assert::that(2)->negative('The input {{input}} that you are validating must be negative.'); + Assert::that(2)->negative('2 must be a negative number'); } /** @@ -164,7 +163,7 @@ public function itShouldThrowExceptionImmediatelyWhenRuleFails(): void */ public function itShouldPrefixSubAssertionsWithAllPrefix(): void { - $this->expectExceptionMessage('1 (like all items of the input) must equal 4'); + $this->expectExceptionMessage('Every item in `[1, 2, 3]` must be equal to 4'); Assert::thatAll([1, 2, 3])->equals(4); } @@ -176,7 +175,7 @@ public function itShouldPrefixSubAssertionsWithNullOrPrefix(): void { Assert::thatNullOr(null)->equals(4); - $this->expectExceptionMessage('3 must equal 4'); + $this->expectExceptionMessage('3 must be equal to 4 or must be null'); Assert::thatNullOr(3)->equals(4); } @@ -185,7 +184,7 @@ public function itShouldPrefixSubAssertionsWithNullOrPrefix(): void */ public function itShouldPrefixSubAssertionsWithNotPrefix(): void { - $this->expectExceptionMessage('3 must not equal 3'); + $this->expectExceptionMessage('3 must not be equal to 3'); Assert::thatNot(3)->equals(3); } @@ -195,7 +194,7 @@ public function itShouldPrefixSubAssertionsWithNotPrefix(): void */ public function itShouldPrefixSubAssertionsWithKeyPrefix(): void { - $this->expectExceptionMessage('foo must be of type string'); + $this->expectExceptionMessage('`.foo` must be a string'); Assert::thatKey(['foo' => true], 'foo')->stringType(); } @@ -205,7 +204,7 @@ public function itShouldPrefixSubAssertionsWithKeyPrefix(): void */ public function itShouldPrefixSubAssertionsWithPropertyPrefix(): void { - $this->expectExceptionMessage('bar must be of type array'); + $this->expectExceptionMessage('`.bar` must be an array'); Assert::thatProperty((object) ['bar' => true], 'bar')->arrayType(); } diff --git a/tests/integration/Documentation/AllPrefixTest.php b/tests/integration/Documentation/AllPrefixTest.php new file mode 100644 index 0000000..d78f851 --- /dev/null +++ b/tests/integration/Documentation/AllPrefixTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class AllPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowForStaticCallWhenAnyItemFails(): void + { + $this->expectExceptionMessage('Every item in `[1, 2, "3"]` must be an integer'); + + Assert::allIntType([1, 2, '3']); + } + + /** + * @test + */ + public function itShouldThrowForThatAllChainWhenAnyItemFails(): void + { + $this->expectExceptionMessage('Every item in `[1, 2, 2, 1, 3]` must be between 1 and 2'); + + Assert::thatAll([1, 2, 2, 1, 3]) + ->intVal() + ->between(1, 2); + } + + /** + * @test + */ + public function itShouldThrowForChainWithAllSegmentWhenEarlierAssertionFails(): void + { + $this->expectExceptionMessage('The length of `[1, 2, 2, 1, 3]` must be less than 4'); + + Assert::that([1, 2, 2, 1, 3]) + ->arrayType() + ->lengthLessThan(4) + ->all()->intVal()->between(1, 2); + } +} diff --git a/tests/integration/Documentation/ChainedAssertionsTest.php b/tests/integration/Documentation/ChainedAssertionsTest.php new file mode 100644 index 0000000..dfaf43d --- /dev/null +++ b/tests/integration/Documentation/ChainedAssertionsTest.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use DomainException; +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class ChainedAssertionsTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowFirstFailedRuleMessageFromChain(): void + { + $this->expectExceptionMessage('I expected a positive number'); + + Assert::that(-1) + ->intVal('The number {{subject}} must be an integer') + ->positive('I expected a positive number') + ->lessThan(4); + } + + /** + * @test + */ + public function itShouldThrowChainExceptionObjectWhenDescriptionIsException(): void + { + $this->expectException(DomainException::class); + $this->expectExceptionMessage('The number must be valid'); + + Assert::that(0, new DomainException('The number must be valid')) + ->positive() + ->greaterThan(5); + } + + /** + * @test + */ + public function itShouldThrowCustomMessageFromFailedRuleWhenOverridingChainMessage(): void + { + $this->expectExceptionMessage('But it is not greater than 5, though'); + + Assert::that(3, 'The number must be valid') + ->positive() + ->greaterThan(5, 'But it is not greater than 5, though'); + } + + /** + * @test + */ + public function itShouldPropagateKeyPrefixInNestedAllAndKeyChain(): void + { + $this->expectExceptionMessage('The length of `.options` must be equal to 4'); + + Assert::that(['names' => ['Respect', 'Assertion'], 'options' => [1, 2, 3]]) + ->all()->arrayType() + ->key('names')->allStringType() + ->key('options')->lengthEquals(4); + } +} diff --git a/tests/integration/Documentation/KeyPrefixTest.php b/tests/integration/Documentation/KeyPrefixTest.php new file mode 100644 index 0000000..d70e4c7 --- /dev/null +++ b/tests/integration/Documentation/KeyPrefixTest.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class KeyPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenKeyIsNotPresent(): void + { + $this->expectExceptionMessage('`.bar` must be present'); + + Assert::keyPresent(['foo' => true], 'bar'); + } + + /** + * @test + */ + public function itShouldThrowWhenKeyIsPresent(): void + { + $this->expectExceptionMessage('`.bar` must not be present'); + + Assert::keyNotPresent(['bar' => 2], 'bar'); + } + + /** + * @test + */ + public function itShouldThrowWhenKeyValueDoesNotMatch(): void + { + $this->expectExceptionMessage('`.foo` must be equal to 3'); + + Assert::keyEquals(['foo' => 2], 'foo', 3); + } + + /** + * @test + */ + public function itShouldThrowWhenKeyValueFailsAssertion(): void + { + $this->expectExceptionMessage('`.bar` must be a negative number'); + + Assert::keyNegative(['bar' => 2], 'bar'); + } + + /** + * @test + */ + public function itShouldThrowWhenKeyValueFailsNegatedAssertion(): void + { + $this->expectExceptionMessage('`.bar` must not be an integer'); + + Assert::keyNotIntType(['bar' => 2], 'bar'); + } + + /** + * @test + */ + public function itShouldThrowWhenReferencedKeyDoesNotExist(): void + { + $this->expectExceptionMessage('`.baz` must be present'); + + Assert::keyNegative(['foo' => 2], 'baz'); + } + + /** + * @test + */ + public function itShouldThrowWhenKeyValueFailsExistsAssertion(): void + { + $this->expectExceptionMessage('`.foo` must be an existing file'); + + Assert::keyExists(['foo' => '/path/to/file.txt'], 'foo'); + } + + /** + * @test + */ + public function itShouldThrowForThatKeyChainWhenAssertionFails(): void + { + $this->expectExceptionMessage('The length of `.foo` must be less than 4'); + + Assert::thatKey(['foo' => 'my-string'], 'foo') + ->stringType() + ->startsWith('my-') + ->lengthLessThan(4); + } + + /** + * @test + */ + public function itShouldThrowForChainWithKeySegmentWhenAssertionFails(): void + { + $this->expectExceptionMessage('`.bar` must be less than 40'); + + Assert::that(['foo' => 'my-string', 'bar' => 42]) + ->arrayType() + ->key('foo')->stringType()->startsWith('my-') + ->key('bar')->intType()->positive()->lessThan(40); + } +} diff --git a/tests/integration/Documentation/LengthPrefixTest.php b/tests/integration/Documentation/LengthPrefixTest.php new file mode 100644 index 0000000..2611126 --- /dev/null +++ b/tests/integration/Documentation/LengthPrefixTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use ArrayObject; +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class LengthPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenStringLengthFailsBetweenAssertion(): void + { + $this->expectExceptionMessage('The length of "string" must be between 10 and 15'); + + Assert::lengthBetween('string', 10, 15); + } + + /** + * @test + */ + public function itShouldThrowWhenArrayLengthFailsOddAssertion(): void + { + $this->expectExceptionMessage('The length of `[1, 2, 3, 4]` must be an odd number'); + + Assert::lengthOdd([1, 2, 3, 4]); + } + + /** + * @test + */ + public function itShouldThrowWhenArrayObjectLengthFailsEvenAssertion(): void + { + $this->expectExceptionMessage( + 'The length of `ArrayObject { getArrayCopy() => [1, 2, 3] }` must be an even number' + ); + + Assert::lengthEven(new ArrayObject([1, 2, 3])); + } + + /** + * @test + */ + public function itShouldThrowWhenArrayLengthFailsNotMultipleAssertion(): void + { + $this->expectExceptionMessage('The length of `[1, 2]` must not be a multiple of 2'); + + Assert::lengthNotMultiple([1, 2], 2); + } +} diff --git a/tests/integration/Documentation/MaxPrefixTest.php b/tests/integration/Documentation/MaxPrefixTest.php new file mode 100644 index 0000000..f258449 --- /dev/null +++ b/tests/integration/Documentation/MaxPrefixTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use ArrayObject; +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; +use Respect\Assertion\Exception\CannotCreateAssertionException; + +final class MaxPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenMaximumFailsBetweenAssertion(): void + { + $this->expectExceptionMessage('The maximum of `[1, 2, 3]` must be between 5 and 10'); + + Assert::maxBetween([1, 2, 3], 5, 10); + } + + /** + * @test + */ + public function itShouldThrowWhenMaximumFailsEvenAssertion(): void + { + $this->expectExceptionMessage('The maximum of `[1, 2, 3]` must be an even number'); + + Assert::maxEven([1, 2, 3]); + } + + /** + * @test + */ + public function itShouldThrowCannotCreateExceptionForUnsupportedRule(): void + { + $this->expectException(CannotCreateAssertionException::class); + $this->expectExceptionMessage('Cannot create assertion for "maxPerfectSquare"'); + + Assert::maxPerfectSquare(new ArrayObject([45, 60, 20])); + } + + /** + * @test + */ + public function itShouldThrowWhenMaximumFailsNotPositiveAssertion(): void + { + $this->expectExceptionMessage('The maximum of `[23, 7, 20]` must not be a positive number'); + + Assert::maxNotPositive([23, 7, 20]); + } +} diff --git a/tests/integration/Documentation/MinPrefixTest.php b/tests/integration/Documentation/MinPrefixTest.php new file mode 100644 index 0000000..a53b669 --- /dev/null +++ b/tests/integration/Documentation/MinPrefixTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use ArrayObject; +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; +use Respect\Assertion\Exception\CannotCreateAssertionException; + +final class MinPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenMinimumFailsBetweenAssertion(): void + { + $this->expectExceptionMessage('The minimum of `[1, 2, 3]` must be between 5 and 10'); + + Assert::minBetween([1, 2, 3], 5, 10); + } + + /** + * @test + */ + public function itShouldThrowWhenMinimumFailsEvenAssertion(): void + { + $this->expectExceptionMessage('The minimum of `[1, 2, 3]` must be an even number'); + + Assert::minEven([1, 2, 3]); + } + + /** + * @test + */ + public function itShouldThrowCannotCreateExceptionForUnsupportedRule(): void + { + $this->expectException(CannotCreateAssertionException::class); + $this->expectExceptionMessage('Cannot create assertion for "minPerfectSquare"'); + + Assert::minPerfectSquare(new ArrayObject([45, 60, 20])); + } + + /** + * @test + */ + public function itShouldThrowWhenMinimumFailsNotPositiveAssertion(): void + { + $this->expectExceptionMessage('The minimum of `[23, 7, 20]` must not be a positive number'); + + Assert::minNotPositive([23, 7, 20]); + } +} diff --git a/tests/integration/Documentation/NotPrefixTest.php b/tests/integration/Documentation/NotPrefixTest.php new file mode 100644 index 0000000..f5c9bb4 --- /dev/null +++ b/tests/integration/Documentation/NotPrefixTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class NotPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenStaticNotCallFails(): void + { + $this->expectExceptionMessage('2 must be an odd number'); + + Assert::notEven(2); + } + + /** + * @test + */ + public function itShouldThrowWhenStaticNotInCallFails(): void + { + $this->expectExceptionMessage('3 must not be in `[1, 2, 3, 4]`'); + + Assert::notIn(3, [1, 2, 3, 4]); + } + + /** + * @test + */ + public function itShouldThrowForThatNotChainWhenAssertionFails(): void + { + $this->expectExceptionMessage('"1" must not be a positive number'); + + Assert::thatNot('1') + ->intType() + ->positive() + ->between(1, 3); + } + + /** + * @test + */ + public function itShouldThrowForChainWithNotSegmentWhenAssertionFails(): void + { + $this->expectExceptionMessage('"1" must not be a positive number'); + + Assert::that('1') + ->not()->intType()->positive()->between(1, 3); + } +} diff --git a/tests/integration/Documentation/NullOrPrefixTest.php b/tests/integration/Documentation/NullOrPrefixTest.php new file mode 100644 index 0000000..8c78265 --- /dev/null +++ b/tests/integration/Documentation/NullOrPrefixTest.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; +use Respect\Assertion\Exception\CannotCreateAssertionException; + +final class NullOrPrefixTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowWhenNonNullValueFailsAssertion(): void + { + $this->expectExceptionMessage('42 must be a negative number or must be null'); + + Assert::nullOrNegative(42); + } + + /** + * @test + * + * @doesNotPerformAssertions + */ + public function itShouldNotThrowWhenValueIsNull(): void + { + Assert::nullOrNegative(null); + } + + /** + * @test + */ + public function itShouldThrowWhenNonNullValueFailsBetweenAssertion(): void + { + $this->expectExceptionMessage('5 must be between 1 and 4 or must be null'); + + Assert::nullOrBetween(5, 1, 4); + } + + /** + * @test + * + * @doesNotPerformAssertions + */ + public function itShouldNotThrowForBetweenWhenValueIsNull(): void + { + Assert::nullOrBetween(null, 1, 4); + } + + /** + * @test + */ + public function itShouldThrowCannotCreateExceptionForUnsupportedRuleInThatNullOrChain(): void + { + $this->expectException(CannotCreateAssertionException::class); + $this->expectExceptionMessage('Cannot create assertion for "nullOrPrimeNumber"'); + + Assert::thatNullOr(6) + ->positive() + ->between(1, 10) + ->primeNumber(); + } + + /** + * @test + */ + public function itShouldThrowCannotCreateExceptionEvenWhenValueIsNullInThatNullOrChain(): void + { + $this->expectException(CannotCreateAssertionException::class); + $this->expectExceptionMessage('Cannot create assertion for "nullOrPrimeNumber"'); + + Assert::thatNullOr(null) + ->positive() + ->between(1, 10) + ->primeNumber(); + } + + /** + * @test + */ + public function itShouldThrowCannotCreateExceptionForUnsupportedRuleInChainWithNullOrSegment(): void + { + $this->expectException(CannotCreateAssertionException::class); + $this->expectExceptionMessage('Cannot create assertion for "nullOrPrimeNumber"'); + + Assert::that(6) + ->nullOr()->positive()->between(1, 10)->primeNumber(); + } +} diff --git a/tests/integration/Documentation/PropertyPrefixTest.php b/tests/integration/Documentation/PropertyPrefixTest.php new file mode 100644 index 0000000..354839f --- /dev/null +++ b/tests/integration/Documentation/PropertyPrefixTest.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; +use stdClass; + +final class PropertyPrefixTest extends TestCase +{ + private stdClass $input; + + /** + * @test + */ + public function itShouldThrowWhenPropertyIsNotPresent(): void + { + $this->expectExceptionMessage('`.bar` must be present'); + + Assert::propertyPresent($this->input, 'bar'); + } + + /** + * @test + */ + public function itShouldThrowWhenPropertyIsPresent(): void + { + $this->expectExceptionMessage('`.foo` must not be present'); + + Assert::propertyNotPresent($this->input, 'foo'); + } + + /** + * @test + */ + public function itShouldThrowWhenPropertyValueDoesNotMatch(): void + { + $this->expectExceptionMessage('`.foo` must be equal to 3'); + + Assert::propertyEquals($this->input, 'foo', 3); + } + + /** + * @test + */ + public function itShouldThrowWhenPropertyValueFailsAssertion(): void + { + $this->expectExceptionMessage('`.foo` must be a negative number'); + + Assert::propertyNegative($this->input, 'foo'); + } + + /** + * @test + */ + public function itShouldThrowWhenPropertyValueFailsNegatedAssertion(): void + { + $this->expectExceptionMessage('`.foo` must not be an integer'); + + Assert::propertyNotIntType($this->input, 'foo'); + } + + /** + * @test + */ + public function itShouldThrowWhenReferencedPropertyDoesNotExist(): void + { + $this->expectExceptionMessage('`.baz` must be present'); + + Assert::propertyNegative($this->input, 'baz'); + } + + /** + * @test + */ + public function itShouldThrowWhenPropertyValueFailsExistsAssertion(): void + { + $this->expectExceptionMessage('`.foo` must be an existing file'); + + Assert::propertyExists($this->input, 'foo'); + } + + /** + * @test + */ + public function itShouldThrowForThatPropertyChainWhenAssertionFails(): void + { + $this->expectExceptionMessage('`.foo` must be greater than 5'); + + Assert::thatProperty($this->input, 'foo') + ->intType() + ->positive() + ->greaterThan(5); + } + + /** + * @test + */ + public function itShouldThrowForChainWithPropertySegmentWhenAssertionFails(): void + { + $this->expectExceptionMessage('`.foo` must be greater than 5'); + + Assert::that($this->input) + ->instance(stdClass::class) + ->property('foo')->intType()->positive()->greaterThan(5); + } + + protected function setUp(): void + { + $this->input = new stdClass(); + $this->input->foo = 1; + } +} diff --git a/tests/integration/Documentation/UsageTest.php b/tests/integration/Documentation/UsageTest.php new file mode 100644 index 0000000..b7a8f02 --- /dev/null +++ b/tests/integration/Documentation/UsageTest.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Respect\Test\Integration\Assertion\Documentation; + +use DomainException; +use PHPUnit\Framework\TestCase; +use Respect\Assertion\Assert; + +final class UsageTest extends TestCase +{ + /** + * @test + */ + public function itShouldThrowExceptionForFailedEqualsAssertion(): void + { + $this->expectExceptionMessage('1 must be equal to 5'); + + Assert::equals(1, 5); + } + + /** + * @test + */ + public function itShouldThrowExceptionForFailedIntTypeAssertion(): void + { + $this->expectExceptionMessage('"string" must be an integer'); + + Assert::intType('string'); + } + + /** + * @test + * + * @doesNotPerformAssertions + */ + public function itShouldNotThrowExceptionWhenAssertionPasses(): void + { + Assert::odd(5); + } + + /** + * @test + */ + public function itShouldThrowCustomExceptionObjectWhenAssertionFails(): void + { + $this->expectException(DomainException::class); + $this->expectExceptionMessage('Something is not right'); + + Assert::between(42, 1, 10, new DomainException('Something is not right')); + } + + /** + * @test + */ + public function itShouldThrowExceptionWithTemplatedCustomMessage(): void + { + $this->expectExceptionMessage('I was expecting 5, but you gave be 1'); + + Assert::equals(1, 5, 'I was expecting {{compareTo}}, but you gave be {{subject}}'); + } +} diff --git a/tests/unit/AssertionTest.php b/tests/unit/AssertionTest.php index 52411bb..00c8e42 100644 --- a/tests/unit/AssertionTest.php +++ b/tests/unit/AssertionTest.php @@ -13,14 +13,14 @@ namespace Respect\Test\Unit\Assertion; +use DomainException; use Exception; use PHPUnit\Framework\TestCase; use Respect\Assertion\Assertion; -use Respect\Validation\Exceptions\DomainException; use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Message\Formatter; -use Respect\Validation\Message\Stringifier\KeepOriginalStringName; -use Respect\Validation\Validatable; +use Respect\Validation\Result; +use Respect\Validation\Validator; +use Respect\Validation\Validators\AlwaysInvalid; /** * @covers \Respect\Assertion\Assertion @@ -32,7 +32,7 @@ final class AssertionTest extends TestCase */ public function isShouldCreateAssertion(): void { - $rule = $this->createMock(Validatable::class); + $rule = $this->createMock(Validator::class); $description = 'This is some template'; $sut = new Assertion($rule, $description); @@ -50,11 +50,12 @@ public function isShouldExecuteWhenSucceed(): void { $input = 'something'; - $rule = $this->createMock(Validatable::class); + $rule = $this->createMock(Validator::class); $rule ->expects($this->once()) - ->method('check') - ->with($input); + ->method('evaluate') + ->with($input) + ->willReturn(Result::of(true, $input, $rule)); $sut = new Assertion($rule); $sut->assert($input); @@ -69,16 +70,9 @@ public function isShouldExecuteIfFailsWhenThereIsNoDescription(): void { $input = 'something'; - $exception = new ValidationException('input', 'id', [], new Formatter('trim', new KeepOriginalStringName())); - - $rule = $this->createMock(Validatable::class); - $rule - ->expects($this->once()) - ->method('check') - ->with($input) - ->willThrowException($exception); + $rule = new AlwaysInvalid(); - $this->expectExceptionObject($exception); + $this->expectException(ValidationException::class); $sut = new Assertion($rule); $sut->assert($input); @@ -93,16 +87,8 @@ public function isShouldExecuteIfFailsWhenDescriptionIsAnException(): void { $input = 'something'; - $rule = $this->createMock(Validatable::class); - $rule - ->expects($this->once()) - ->method('check') - ->with($input) - ->willThrowException( - new ValidationException('input', 'id', [], new Formatter('trim', new KeepOriginalStringName())) - ); - - $description = new DomainException('input', 'id', [], new Formatter('trim', new KeepOriginalStringName())); + $description = new DomainException('custom error'); + $rule = new AlwaysInvalid(); $this->expectExceptionObject($description); @@ -120,20 +106,9 @@ public function isShouldExecuteIfFailsWhenDescriptionIsString(): void $input = 'something'; $description = 'Template for exception'; + $rule = new AlwaysInvalid(); - $exception = $this->createMock(ValidationException::class); - $exception - ->expects($this->once()) - ->method('updateTemplate'); - - $rule = $this->createMock(Validatable::class); - $rule - ->expects($this->once()) - ->method('check') - ->with($input) - ->willThrowException($exception); - - $this->expectExceptionObject($exception); + $this->expectException(ValidationException::class); $sut = new Assertion($rule, $description); $sut->assert($input); diff --git a/tests/unit/Creator/KeyCreatorTest.php b/tests/unit/Creator/KeyCreatorTest.php index 010d49f..95cc7c5 100644 --- a/tests/unit/Creator/KeyCreatorTest.php +++ b/tests/unit/Creator/KeyCreatorTest.php @@ -18,8 +18,9 @@ use Respect\Assertion\Creator\KeyCreator; use Respect\Assertion\Exception\CannotCreateAssertionException; use Respect\Test\Unit\Assertion\Double\FakeCreator; -use Respect\Validation\Rules\Key; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Key; +use Respect\Validation\Validators\KeyExists; +use Respect\Validation\Validators\Not; use stdClass; use function Respect\Stringifier\stringify; @@ -70,7 +71,7 @@ public function itShouldCreateKeyPresentAssertion(): void $sut = new KeyCreator(new FakeCreator()); $assertion = $sut->create('keyPresent', [$key]); - self::assertEquals(new Key('foo'), $assertion->getRule()); + self::assertEquals(new KeyExists('foo'), $assertion->getRule()); } /** @@ -97,7 +98,7 @@ public function itShouldCreateKeyNotPresentAssertion(): void $sut = new KeyCreator(new FakeCreator()); $assertion = $sut->create('keyNotPresent', [$key]); - self::assertEquals(new Not(new Key('foo')), $assertion->getRule()); + self::assertEquals(new Not(new KeyExists('foo')), $assertion->getRule()); } /** diff --git a/tests/unit/Creator/NotCreatorTest.php b/tests/unit/Creator/NotCreatorTest.php index 07923dd..d54e934 100644 --- a/tests/unit/Creator/NotCreatorTest.php +++ b/tests/unit/Creator/NotCreatorTest.php @@ -18,7 +18,7 @@ use Respect\Assertion\Creator\NotCreator; use Respect\Assertion\Exception\CannotCreateAssertionException; use Respect\Test\Unit\Assertion\Double\FakeCreator; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Not; use function ucfirst; diff --git a/tests/unit/Creator/NullOrCreatorTest.php b/tests/unit/Creator/NullOrCreatorTest.php index 4ebf22f..919e40b 100644 --- a/tests/unit/Creator/NullOrCreatorTest.php +++ b/tests/unit/Creator/NullOrCreatorTest.php @@ -18,7 +18,7 @@ use Respect\Assertion\Creator\NullOrCreator; use Respect\Assertion\Exception\CannotCreateAssertionException; use Respect\Test\Unit\Assertion\Double\FakeCreator; -use Respect\Validation\Rules\Nullable; +use Respect\Validation\Validators\NullOr; use function ucfirst; @@ -60,7 +60,7 @@ public function itShouldCreateNullOrAssertionWithExtraRule(): void self::assertEquals( new Assertion( - new Nullable($nextCreator->getLastCreatedRule()), + new NullOr($nextCreator->getLastCreatedRule()), $nextCreator->getLastCreatedDescription() ), $assertion diff --git a/tests/unit/Creator/PrefixedCreatorTest.php b/tests/unit/Creator/PrefixedCreatorTest.php index 37a1c42..6b7ab7e 100644 --- a/tests/unit/Creator/PrefixedCreatorTest.php +++ b/tests/unit/Creator/PrefixedCreatorTest.php @@ -19,7 +19,7 @@ use Respect\Assertion\Exception\CannotCreateAssertionException; use Respect\Assertion\Rule\Rule; use Respect\Test\Unit\Assertion\Double\FakeCreator; -use Respect\Validation\Rules\Optional; +use Respect\Validation\Validators\UndefOr; use function ucfirst; @@ -57,12 +57,12 @@ public function itShouldCreateAssertion(): void $nextCreator = new FakeCreator(); - $sut = new PrefixedCreator($prefix, Optional::class, $nextCreator); + $sut = new PrefixedCreator($prefix, UndefOr::class, $nextCreator); $assertion = $sut->create($name, $parameters); self::assertEquals( new Assertion( - new Optional($nextCreator->getLastCreatedRule()), + new UndefOr($nextCreator->getLastCreatedRule()), $nextCreator->getLastCreatedDescription(), ), $assertion diff --git a/tests/unit/Creator/PropertyCreatorTest.php b/tests/unit/Creator/PropertyCreatorTest.php index 58e5198..2e55e43 100644 --- a/tests/unit/Creator/PropertyCreatorTest.php +++ b/tests/unit/Creator/PropertyCreatorTest.php @@ -18,8 +18,9 @@ use Respect\Assertion\Creator\PropertyCreator; use Respect\Assertion\Exception\CannotCreateAssertionException; use Respect\Test\Unit\Assertion\Double\FakeCreator; -use Respect\Validation\Rules\Attribute; -use Respect\Validation\Rules\Not; +use Respect\Validation\Validators\Not; +use Respect\Validation\Validators\Property; +use Respect\Validation\Validators\PropertyExists; use stdClass; use function Respect\Stringifier\stringify; @@ -70,7 +71,7 @@ public function itShouldCreateSimplePropertyAssertionWhenPrefixCalledPropertyPre $sut = new PropertyCreator(new FakeCreator()); $assertion = $sut->create('propertyPresent', [$property]); - self::assertEquals(new Assertion(new Attribute($property)), $assertion); + self::assertEquals(new Assertion(new PropertyExists($property)), $assertion); } /** @@ -97,7 +98,7 @@ public function itShouldCreateSimplePropertyAssertionWhenPrefixCalledPropertyNot $sut = new PropertyCreator(new FakeCreator()); $assertion = $sut->create('propertyNotPresent', [$key]); - self::assertEquals(new Assertion(new Not(new Attribute('foo'))), $assertion); + self::assertEquals(new Assertion(new Not(new PropertyExists('foo'))), $assertion); } /** @@ -134,7 +135,7 @@ public function itShouldCreatePropertyAssertionWhenPrefixCalledProperty(): void self::assertEquals( new Assertion( - new Attribute($property, $nextCreator->getLastCreatedRule()), + new Property($property, $nextCreator->getLastCreatedRule()), $nextCreator->getLastCreatedDescription() ), $assertion diff --git a/tests/unit/Creator/StandardCreatorTest.php b/tests/unit/Creator/StandardCreatorTest.php index c5e61da..ec441bd 100644 --- a/tests/unit/Creator/StandardCreatorTest.php +++ b/tests/unit/Creator/StandardCreatorTest.php @@ -18,8 +18,8 @@ use Respect\Assertion\Assertion; use Respect\Assertion\Creator\StandardCreator; use Respect\Assertion\Exception\CannotCreateAssertionException; -use Respect\Validation\Rules\Equals; -use Respect\Validation\Rules\IntType; +use Respect\Validation\Validators\Equals; +use Respect\Validation\Validators\IntType; use stdClass; use function tmpfile; @@ -95,7 +95,7 @@ public function isShouldThrowAnExceptionWhenRuleIsNotInstantiable(): void { $this->expectException(CannotCreateAssertionException::class); - $this->getSut()->create('AbstractRule', []); + $this->getSut()->create('NonExistentValidator', []); } /** diff --git a/tests/unit/Double/FakeRule.php b/tests/unit/Double/FakeRule.php index 687b0ca..3afb6c9 100644 --- a/tests/unit/Double/FakeRule.php +++ b/tests/unit/Double/FakeRule.php @@ -13,29 +13,21 @@ namespace Respect\Test\Unit\Assertion\Double; -use Respect\Validation\Rules\AbstractRule; +use Respect\Validation\Result; +use Respect\Validation\Validator; -final class FakeRule extends AbstractRule +final class FakeRule implements Validator { /** * @var array */ private array $calledInputs = []; - /** - * {@inheritDoc} - */ - public function validate($input): bool - { - return true; - } - - /** - * {@inheritDoc} - */ - public function check($input): void + public function evaluate(mixed $input): Result { $this->calledInputs[] = $input; + + return Result::of(true, $input, $this); } /** diff --git a/tests/unit/Rule/AllTest.php b/tests/unit/Rule/AllTest.php index 20069e5..b1e8191 100644 --- a/tests/unit/Rule/AllTest.php +++ b/tests/unit/Rule/AllTest.php @@ -16,9 +16,9 @@ use PHPUnit\Framework\TestCase; use Respect\Assertion\Rule\All; use Respect\Test\Unit\Assertion\Double\FakeRule; -use Respect\Validation\Exceptions\AlwaysInvalidException; -use Respect\Validation\Exceptions\IterableTypeException; -use Respect\Validation\Rules\AlwaysInvalid; +use Respect\Validation\Exceptions\ValidationException; +use Respect\Validation\ValidatorBuilder; +use Respect\Validation\Validators\AlwaysInvalid; use function range; @@ -33,10 +33,10 @@ final class AllTest extends TestCase */ public function itShouldThrowAnExceptionWhenInputIsNotIterable(): void { - $this->expectException(IterableTypeException::class); + $this->expectException(ValidationException::class); $sut = new All(new AlwaysInvalid()); - $sut->check(42); + ValidatorBuilder::init($sut)->assert(42); } /** @@ -49,10 +49,10 @@ public function itShouldAssertEveryValueInTheInput(): void $rule = new FakeRule(); $sut = new All($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame($input, $rule->getCalledInputs()); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -62,10 +62,10 @@ public function itShouldModifyValidationExceptionsWhenAssertionFails(): void { $input = [1, 2, 3]; - $this->expectException(AlwaysInvalidException::class); - $this->expectExceptionMessage('1 (like all items of the input) is always invalid'); + $this->expectException(ValidationException::class); + $this->expectExceptionMessage('Every item in `[1, 2, 3]` must be valid'); $sut = new All(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } } diff --git a/tests/unit/Rule/EnvelopeTest.php b/tests/unit/Rule/EnvelopeTest.php deleted file mode 100644 index 70d2c55..0000000 --- a/tests/unit/Rule/EnvelopeTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE file - * that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace Respect\Test\Unit\Assertion\Rule; - -use PHPUnit\Framework\TestCase; -use Respect\Assertion\Rule\Envelope; -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AlwaysInvalid; - -use function Respect\Stringifier\stringify; - -/** - * @covers \Respect\Assertion\Rule\Envelope - */ -final class EnvelopeTest extends TestCase -{ - /** - * @test - */ - public function itShouldCustomizeExceptionTemplate(): void - { - $input = 'something'; - - $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify($input) . ' should be awesome'); - - $sut = new Envelope(new AlwaysInvalid(), '{{input}} should be awesome'); - $sut->check($input); - } -} diff --git a/tests/unit/Rule/LengthTest.php b/tests/unit/Rule/LengthTest.php index 2cd4951..f26de3a 100644 --- a/tests/unit/Rule/LengthTest.php +++ b/tests/unit/Rule/LengthTest.php @@ -17,9 +17,9 @@ use PHPUnit\Framework\TestCase; use Respect\Assertion\Rule\Length; use Respect\Test\Unit\Assertion\Double\FakeRule; -use Respect\Validation\Exceptions\AlwaysInvalidException; use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AlwaysInvalid; +use Respect\Validation\ValidatorBuilder; +use Respect\Validation\Validators\AlwaysInvalid; use stdClass; use function count; @@ -30,7 +30,6 @@ /** * @covers \Respect\Assertion\Rule\Length - * @covers \Respect\Assertion\Rule\Rule */ final class LengthTest extends TestCase { @@ -42,10 +41,10 @@ final class LengthTest extends TestCase public function itShouldThrowAnExceptionWhenInputIsNotStringOrCountable(mixed $input): void { $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify($input) . ' must be a string or a countable object'); + $this->expectExceptionMessage(stringify($input) . ' must be countable or a string'); $sut = new Length(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** @@ -58,7 +57,7 @@ public function itShouldAssertLengthOfStrings(): void $rule = new FakeRule(); $sut = new Length($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(mb_strlen($input), $rule->getCalledInputs()[0]); } @@ -73,10 +72,10 @@ public function itShouldAssertLengthOfArrays(): void $rule = new FakeRule(); $sut = new Length($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(count($input), $rule->getCalledInputs()[0]); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -89,7 +88,7 @@ public function itShouldAssertLengthOfCountable(): void $rule = new FakeRule(); $sut = new Length($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame($input->count(), $rule->getCalledInputs()[0]); } @@ -101,11 +100,11 @@ public function itShouldModifyValidationExceptionsWhenAssertionFails(): void { $input = [1, 2, 3]; - $this->expectException(AlwaysInvalidException::class); - $this->expectExceptionMessage('3 (the length of the input) is always invalid'); + $this->expectException(ValidationException::class); + $this->expectExceptionMessage('The length of `[1, 2, 3]` must be valid'); $sut = new Length(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** diff --git a/tests/unit/Rule/MaxTest.php b/tests/unit/Rule/MaxTest.php index f6a4d01..dc6b71f 100644 --- a/tests/unit/Rule/MaxTest.php +++ b/tests/unit/Rule/MaxTest.php @@ -18,7 +18,8 @@ use Respect\Assertion\Rule\Max; use Respect\Test\Unit\Assertion\Double\FakeRule; use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AlwaysInvalid; +use Respect\Validation\ValidatorBuilder; +use Respect\Validation\Validators\AlwaysInvalid; use stdClass; use function range; @@ -27,7 +28,6 @@ /** * @covers \Respect\Assertion\Rule\Max - * @covers \Respect\Assertion\Rule\Rule */ final class MaxTest extends TestCase { @@ -41,10 +41,10 @@ final class MaxTest extends TestCase public function itShouldThrowAnExceptionWhenInputIsNotStringOrCountable(mixed $input): void { $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify($input) . ' must be an non-empty array or iterable'); + $this->expectExceptionMessage(stringify($input) . ' must be iterable'); $sut = new Max(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** @@ -57,10 +57,10 @@ public function itShouldAssertTheMaxValueOfTheInputWhenItIsAnArray(): void $rule = new FakeRule(); $sut = new Max($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(self::MAXIMUM, $rule->getCalledInputs()[0]); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -73,10 +73,10 @@ public function itShouldAssertTheMaxValueOfTheInputWhenItIsAnIterableValue(): vo $rule = new FakeRule(); $sut = new Max($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(self::MAXIMUM, $rule->getCalledInputs()[0]); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -87,10 +87,10 @@ public function itShouldModifyValidationExceptionsWhenAssertionFails(): void $input = range(self::MAXIMUM - 5, self::MAXIMUM); $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify(self::MAXIMUM) . ' (the maximum of the input) is always invalid'); + $this->expectExceptionMessage('The maximum of `[95, 96, 97, 98, 99, ...]` must be valid'); $sut = new Max(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** @@ -100,8 +100,6 @@ public static function invalidInputProvider(): array { return [ [42], - [[]], - [new ArrayObject()], [new stdClass()], [tmpfile()], ]; diff --git a/tests/unit/Rule/MinTest.php b/tests/unit/Rule/MinTest.php index 8986cd2..155ab40 100644 --- a/tests/unit/Rule/MinTest.php +++ b/tests/unit/Rule/MinTest.php @@ -18,7 +18,8 @@ use Respect\Assertion\Rule\Min; use Respect\Test\Unit\Assertion\Double\FakeRule; use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rules\AlwaysInvalid; +use Respect\Validation\ValidatorBuilder; +use Respect\Validation\Validators\AlwaysInvalid; use stdClass; use function range; @@ -27,7 +28,6 @@ /** * @covers \Respect\Assertion\Rule\Min - * @covers \Respect\Assertion\Rule\Rule */ final class MinTest extends TestCase { @@ -41,10 +41,10 @@ final class MinTest extends TestCase public function itShouldThrowAnExceptionWhenInputIsNotStringOrCountable(mixed $input): void { $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify($input) . ' must be an non-empty array or iterable'); + $this->expectExceptionMessage(stringify($input) . ' must be iterable'); $sut = new Min(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** @@ -57,10 +57,10 @@ public function itShouldAssertTheMinValueOfTheInputWhenItIsAnArray(): void $rule = new FakeRule(); $sut = new Min($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(self::MINIMUM, $rule->getCalledInputs()[0]); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -73,10 +73,10 @@ public function itShouldAssertTheMinValueOfTheInputWhenItIsAnIterableValue(): vo $rule = new FakeRule(); $sut = new Min($rule); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); self::assertSame(self::MINIMUM, $rule->getCalledInputs()[0]); - self::assertTrue($sut->validate($input)); + self::assertTrue($sut->evaluate($input)->hasPassed); } /** @@ -87,10 +87,10 @@ public function itShouldModifyValidationExceptionsWhenAssertionFails(): void $input = range(self::MINIMUM, self::MINIMUM + 5); $this->expectException(ValidationException::class); - $this->expectExceptionMessage(stringify(self::MINIMUM) . ' (the minimum of the input) is always invalid'); + $this->expectExceptionMessage('The minimum of `[100, 101, 102, 103, 104, ...]` must be valid'); $sut = new Min(new AlwaysInvalid()); - $sut->check($input); + ValidatorBuilder::init($sut)->assert($input); } /** @@ -100,8 +100,6 @@ public static function invalidInputProvider(): array { return [ [42], - [[]], - [new ArrayObject()], [new stdClass()], [tmpfile()], ];