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 not be between {{minValue}} and {{maxValue}}',
)]
final class Between extends AbstractEnvelope
final class Between extends Envelope
{
use CanCompareValues;

View file

@ -17,7 +17,7 @@ use function array_map;
'{{name}} must contain at least one 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

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 not be valid',
)]
final class FilterVar extends AbstractEnvelope
final class FilterVar extends Envelope
{
private const ALLOWED_FILTERS = [
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 not be a hex RGB color',
)]
final class HexRgbColor extends AbstractEnvelope
final class HexRgbColor extends Envelope
{
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 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 ALPHA3 = 'alpha-3';

View file

@ -19,7 +19,7 @@ use const NOEXPR;
'{{name}} must 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)
{

View file

@ -21,7 +21,7 @@ use function sprintf;
'{{name}} must 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 = '/^$/';

View file

@ -15,7 +15,7 @@ use Respect\Validation\Message\Template;
'{{name}} must 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()
{

View file

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

View file

@ -9,8 +9,8 @@ declare(strict_types=1);
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;
#[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(Between::class)]
final class BetweenTest extends RuleTestCase
{

View file

@ -12,41 +12,41 @@ namespace Respect\Validation\Rules;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
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\TestCase;
use function array_intersect_key;
#[Group('core')]
#[CoversClass(AbstractEnvelope::class)]
final class AbstractEnvelopeTest extends TestCase
#[CoversClass(Envelope::class)]
final class EnvelopeTest extends TestCase
{
#[Test]
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]
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]
public function itShouldReportErrorUsingProperties(): void
public function itShouldEvaluatePassingTheGivenProperties(): void
{
$input = 'value';
$parameters = ['foo' => true, 'bar' => false, 'baz' => 42];
$rule = new Envelop(Stub::fail(1), $parameters);
$exception = $rule->reportError($input);
$rule = new EnvelopStub(Stub::fail(1), $parameters);
$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;
#[Group('rule')]
#[CoversClass(AbstractEnvelope::class)]
#[CoversClass(FilterVar::class)]
final class FilterVarTest extends RuleTestCase
{

View file

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

View file

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