Update the validation engine of envelop-based rules

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2024-02-12 22:23:48 +01:00
parent 0e87d1fafd
commit e341fef5c0
No known key found for this signature in database
GPG key ID: 221E9281655813A6
17 changed files with 51 additions and 71 deletions

View file

@ -1,45 +0,0 @@
<?php
/*
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
* SPDX-License-Identifier: MIT
*/
declare(strict_types=1);
namespace Respect\Validation\Rules;
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Result;
use Respect\Validation\Validatable;
abstract class AbstractEnvelope extends AbstractRule
{
/**
* @param mixed[] $parameters
*/
public function __construct(
private readonly Validatable $validatable,
private readonly array $parameters = []
) {
}
public function validate(mixed $input): bool
{
return $this->validatable->validate($input);
}
public function evaluate(mixed $input): Result
{
return (new Result($this->validatable->evaluate($input)->isValid, $input, $this))
->withParameters($this->parameters);
}
/**
* @param mixed[] $extraParameters
*/
public function reportError(mixed $input, array $extraParameters = []): ValidationException
{
return parent::reportError($input, $extraParameters + $this->parameters);
}
}

View file

@ -17,7 +17,7 @@ use Respect\Validation\Message\Template;
'{{name}} must be between {{minValue}} and {{maxValue}}', '{{name}} must be between {{minValue}} and {{maxValue}}',
'{{name}} must not be between {{minValue}} and {{maxValue}}', '{{name}} must not be between {{minValue}} and {{maxValue}}',
)] )]
final class Between extends AbstractEnvelope final class Between extends Envelope
{ {
use CanCompareValues; use CanCompareValues;

View file

@ -17,7 +17,7 @@ use function array_map;
'{{name}} must contain at least one of the values {{needles}}', '{{name}} must contain at least one of the values {{needles}}',
'{{name}} must not contain any of the values {{needles}}', '{{name}} must not contain any of the values {{needles}}',
)] )]
final class ContainsAny extends AbstractEnvelope final class ContainsAny extends Envelope
{ {
/** /**
* @param mixed[] $needles At least one of the values provided must be found in input string or array * @param mixed[] $needles At least one of the values provided must be found in input string or array

View file

@ -0,0 +1,29 @@
<?php
/*
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
* SPDX-License-Identifier: MIT
*/
declare(strict_types=1);
namespace Respect\Validation\Rules;
use Respect\Validation\Result;
use Respect\Validation\Validatable;
abstract class Envelope extends Standard
{
/** @param array<string, mixed> $parameters */
public function __construct(
private readonly Validatable $rule,
private readonly array $parameters = []
) {
}
public function evaluate(mixed $input): Result
{
return (new Result($this->rule->evaluate($input)->isValid, $input, $this))
->withParameters($this->parameters);
}
}

View file

@ -30,7 +30,7 @@ use const FILTER_VALIDATE_URL;
'{{name}} must be valid', '{{name}} must be valid',
'{{name}} must not be valid', '{{name}} must not be valid',
)] )]
final class FilterVar extends AbstractEnvelope final class FilterVar extends Envelope
{ {
private const ALLOWED_FILTERS = [ private const ALLOWED_FILTERS = [
FILTER_VALIDATE_BOOLEAN => 'is_bool', FILTER_VALIDATE_BOOLEAN => 'is_bool',

View file

@ -15,7 +15,7 @@ use Respect\Validation\Message\Template;
'{{name}} must be a hex RGB color', '{{name}} must be a hex RGB color',
'{{name}} must not be a hex RGB color', '{{name}} must not be a hex RGB color',
)] )]
final class HexRgbColor extends AbstractEnvelope final class HexRgbColor extends Envelope
{ {
public function __construct() public function __construct()
{ {

View file

@ -21,7 +21,7 @@ use function sprintf;
'{{name}} must be a valid ISO 639 {{set|raw}} language code', '{{name}} must be a valid ISO 639 {{set|raw}} language code',
'{{name}} must not be a valid ISO 639 {{set|raw}} language code', '{{name}} must not be a valid ISO 639 {{set|raw}} language code',
)] )]
final class LanguageCode extends AbstractEnvelope final class LanguageCode extends Envelope
{ {
public const ALPHA2 = 'alpha-2'; public const ALPHA2 = 'alpha-2';
public const ALPHA3 = 'alpha-3'; public const ALPHA3 = 'alpha-3';

View file

@ -19,7 +19,7 @@ use const NOEXPR;
'{{name}} must be similar to "No"', '{{name}} must be similar to "No"',
'{{name}} must not be similar to "No"', '{{name}} must not be similar to "No"',
)] )]
final class No extends AbstractEnvelope final class No extends Envelope
{ {
public function __construct(bool $useLocale = false) public function __construct(bool $useLocale = false)
{ {

View file

@ -21,7 +21,7 @@ use function sprintf;
'{{name}} must be a valid postal code on {{countryCode}}', '{{name}} must be a valid postal code on {{countryCode}}',
'{{name}} must not be a valid postal code on {{countryCode}}', '{{name}} must not be a valid postal code on {{countryCode}}',
)] )]
final class PostalCode extends AbstractEnvelope final class PostalCode extends Envelope
{ {
private const DEFAULT_PATTERN = '/^$/'; private const DEFAULT_PATTERN = '/^$/';

View file

@ -15,7 +15,7 @@ use Respect\Validation\Message\Template;
'{{name}} must be a valid Roman numeral', '{{name}} must be a valid Roman numeral',
'{{name}} must not be a valid Roman numeral', '{{name}} must not be a valid Roman numeral',
)] )]
final class Roman extends AbstractEnvelope final class Roman extends Envelope
{ {
public function __construct() public function __construct()
{ {

View file

@ -17,7 +17,7 @@ use const FILTER_VALIDATE_URL;
'{{name}} must be a URL', '{{name}} must be a URL',
'{{name}} must not be a URL', '{{name}} must not be a URL',
)] )]
final class Url extends AbstractEnvelope final class Url extends Envelope
{ {
public function __construct() public function __construct()
{ {

View file

@ -9,8 +9,8 @@ declare(strict_types=1);
namespace Respect\Validation\Test\Rules; namespace Respect\Validation\Test\Rules;
use Respect\Validation\Rules\AbstractEnvelope; use Respect\Validation\Rules\Envelope;
final class Envelop extends AbstractEnvelope final class EnvelopStub extends Envelope
{ {
} }

View file

@ -18,7 +18,6 @@ use Respect\Validation\Test\RuleTestCase;
use Respect\Validation\Test\Stubs\CountableStub; use Respect\Validation\Test\Stubs\CountableStub;
#[Group('rule')] #[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(Between::class)] #[CoversClass(Between::class)]
final class BetweenTest extends RuleTestCase final class BetweenTest extends RuleTestCase
{ {

View file

@ -12,41 +12,41 @@ namespace Respect\Validation\Rules;
use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
use Respect\Validation\Test\Rules\Envelop; use Respect\Validation\Test\Rules\EnvelopStub;
use Respect\Validation\Test\Rules\Stub; use Respect\Validation\Test\Rules\Stub;
use Respect\Validation\Test\TestCase; use Respect\Validation\Test\TestCase;
use function array_intersect_key; use function array_intersect_key;
#[Group('core')] #[Group('core')]
#[CoversClass(AbstractEnvelope::class)] #[CoversClass(Envelope::class)]
final class AbstractEnvelopeTest extends TestCase final class EnvelopeTest extends TestCase
{ {
#[Test] #[Test]
public function itShouldValidateUsingTheInnerRule(): void public function itShouldValidateUsingTheInnerRule(): void
{ {
$rule = new Envelop(Stub::pass(1), []); $rule = new EnvelopStub(Stub::pass(1), []);
self::assertTrue($rule->validate('something')); self::assertTrue($rule->evaluate('something')->isValid);
} }
#[Test] #[Test]
public function itShouldInvalidateUsingTheInnerRule(): void public function itShouldInvalidateUsingTheInnerRule(): void
{ {
$rule = new Envelop(Stub::fail(1), []); $rule = new EnvelopStub(Stub::fail(1), []);
self::assertFalse($rule->validate('something')); self::assertFalse($rule->evaluate('something')->isValid);
} }
#[Test] #[Test]
public function itShouldReportErrorUsingProperties(): void public function itShouldEvaluatePassingTheGivenProperties(): void
{ {
$input = 'value'; $input = 'value';
$parameters = ['foo' => true, 'bar' => false, 'baz' => 42]; $parameters = ['foo' => true, 'bar' => false, 'baz' => 42];
$rule = new Envelop(Stub::fail(1), $parameters); $rule = new EnvelopStub(Stub::fail(1), $parameters);
$exception = $rule->reportError($input); $result = $rule->evaluate($input);
self::assertEquals($parameters, array_intersect_key($parameters, $exception->getParams())); self::assertEquals($parameters, array_intersect_key($parameters, $result->parameters));
} }
} }

View file

@ -26,7 +26,6 @@ use const FILTER_VALIDATE_INT;
use const FILTER_VALIDATE_URL; use const FILTER_VALIDATE_URL;
#[Group('rule')] #[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(FilterVar::class)] #[CoversClass(FilterVar::class)]
final class FilterVarTest extends RuleTestCase final class FilterVarTest extends RuleTestCase
{ {

View file

@ -16,7 +16,6 @@ use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
#[Group('rule')] #[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(LanguageCode::class)] #[CoversClass(LanguageCode::class)]
final class LanguageCodeTest extends RuleTestCase final class LanguageCodeTest extends RuleTestCase
{ {

View file

@ -14,7 +14,6 @@ use PHPUnit\Framework\Attributes\Group;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
#[Group('rule')] #[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(Url::class)] #[CoversClass(Url::class)]
final class UrlTest extends RuleTestCase final class UrlTest extends RuleTestCase
{ {