Prefix IDs of wrapper rule results

Because some rules work more as a prefix, it makes sense to prefix their
result ID. That will allow for a more intuitive templating, especially
when using those rules as prefixes.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2024-03-26 00:16:09 +01:00
parent 8573bc5d45
commit eeaea466ac
No known key found for this signature in database
GPG key ID: 221E9281655813A6
20 changed files with 60 additions and 50 deletions

View file

@ -16,6 +16,7 @@ use function lcfirst;
use function preg_match;
use function strrchr;
use function substr;
use function ucfirst;
final class Result
{
@ -77,6 +78,15 @@ final class Result
return $this->clone(id: $id);
}
public function withPrefixedId(string $prefix): self
{
if ($this->id === $this->name) {
return $this;
}
return $this->clone(id: $prefix . ucfirst($this->id));
}
public function withChildren(Result ...$children): self
{
return $this->clone(children: $children);

View file

@ -18,6 +18,7 @@ use Respect\Validation\Rules\Core\Wrapper;
use function count;
use function is_string;
use function mb_strlen;
use function ucfirst;
#[Template('The length of', 'The length of')]
final class Length extends Wrapper
@ -28,12 +29,14 @@ final class Length extends Wrapper
{
$typeResult = $this->bindEvaluate(new OneOf(new StringType(), new Countable()), $this, $input);
if (!$typeResult->isValid) {
return Result::failed($input, $this)->withNextSibling($this->rule->evaluate($input));
$result = $this->rule->evaluate($input);
return Result::failed($input, $this)->withNextSibling($result)->withId('length' . ucfirst($result->id));
}
$result = $this->rule->evaluate($this->extractLength($input))->withInput($input);
$result = $this->rule->evaluate($this->extractLength($input))->withInput($input)->withPrefixedId('length');
return (new Result($result->isValid, $input, $this))->withNextSibling($result);
return (new Result($result->isValid, $input, $this, id: $result->id))->withNextSibling($result);
}
/** @param array<mixed>|PhpCountable|string $input */

View file

@ -24,9 +24,9 @@ final class Max extends FilteredNonEmptyArray
/** @param non-empty-array<mixed> $input */
protected function evaluateNonEmptyArray(array $input): Result
{
$result = $this->rule->evaluate(max($input));
$result = $this->rule->evaluate(max($input))->withPrefixedId('max');
$template = $this->getName() === null ? self::TEMPLATE_STANDARD : self::TEMPLATE_NAMED;
return (new Result($result->isValid, $input, $this, [], $template))->withNextSibling($result);
return (new Result($result->isValid, $input, $this, [], $template, id: $result->id))->withNextSibling($result);
}
}

View file

@ -24,9 +24,9 @@ final class Min extends FilteredNonEmptyArray
/** @param non-empty-array<mixed> $input */
protected function evaluateNonEmptyArray(array $input): Result
{
$result = $this->rule->evaluate(min($input));
$result = $this->rule->evaluate(min($input))->withPrefixedId('min');
$template = $this->getName() === null ? self::TEMPLATE_STANDARD : self::TEMPLATE_NAMED;
return (new Result($result->isValid, $input, $this, [], $template))->withNextSibling($result);
return (new Result($result->isValid, $input, $this, [], $template, id: $result->id))->withNextSibling($result);
}
}

View file

@ -16,6 +16,6 @@ final class Not extends Wrapper
{
public function evaluate(mixed $input): Result
{
return parent::evaluate($input)->withInvertedMode();
return $this->rule->evaluate($input)->withInvertedMode()->withPrefixedId('not');
}
}

View file

@ -24,5 +24,5 @@ exceptionMessages(
'__root__' => 'All of the required rules must pass for "really messed up screen#name"',
'alnum' => '"really messed up screen#name" must contain only letters and digits',
'noWhitespace' => '"really messed up screen#name" cannot contain spaces',
'length' => '"really messed up screen#name" must not have more than 15 chars',
]
'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15',
]

View file

@ -16,5 +16,5 @@ exceptionMessages(
'__root__' => 'All of the required rules must pass for "really messed up screen#name"',
'alnum' => '"really messed up screen#name" must contain only letters (a-z) and digits (0-9)',
'noWhitespace' => '"really messed up screen#name" must not contain whitespace',
'length' => 'The length of "really messed up screen#name" must be between 1 and 15',
'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15',
]

View file

@ -53,7 +53,7 @@ Wrapping "not"
4 must not be of type integer
- 4 must not be of type integer
[
'intType' => '4 must not be of type integer',
'notIntType' => '4 must not be of type integer',
]
With a single template
@ -75,4 +75,3 @@ Template for "stringType"
'stringType' => 'Template for "stringType"',
'uppercase' => 'Template for "uppercase"',
]

View file

@ -28,7 +28,7 @@ Negative
5 must not be greater than 1 and less than 10
- 5 must not be greater than 1 and less than 10
[
'betweenExclusive' => '5 must not be greater than 1 and less than 10',
'notBetweenExclusive' => '5 must not be greater than 1 and less than 10',
]
With template
@ -46,4 +46,3 @@ Range must be greater than 1 and less than 10
[
'betweenExclusive' => 'Range must be greater than 1 and less than 10',
]

View file

@ -67,7 +67,7 @@ Negative
`true` must not evaluate to `true`
- `true` must not evaluate to `true`
[
'trueVal' => '`true` must not evaluate to `true`',
'notTrueVal' => '`true` must not evaluate to `true`',
]
Default with inverted failing rule
@ -75,7 +75,7 @@ Default with inverted failing rule
`true` must not evaluate to `true`
- `true` must not evaluate to `true`
[
'trueVal' => '`true` must not evaluate to `true`',
'notTrueVal' => '`true` must not evaluate to `true`',
]
With wrapped name, default
@ -99,7 +99,7 @@ With the name set in the wrapped rule of an inverted failing rule
Wrapped must not evaluate to `true`
- Wrapped must not evaluate to `true`
[
'trueVal' => 'Wrapped must not evaluate to `true`',
'notTrueVal' => 'Wrapped must not evaluate to `true`',
]
With the name set in an inverted failing rule
@ -107,7 +107,7 @@ With the name set in an inverted failing rule
Not must not evaluate to `true`
- Not must not evaluate to `true`
[
'trueVal' => 'Not must not evaluate to `true`',
'notTrueVal' => 'Not must not evaluate to `true`',
]
With the name set in the "consecutive" that has an inverted failing rule
@ -115,7 +115,7 @@ With the name set in the "consecutive" that has an inverted failing rule
Wrapper must not evaluate to `true`
- Wrapper must not evaluate to `true`
[
'trueVal' => 'Wrapper must not evaluate to `true`',
'notTrueVal' => 'Wrapper must not evaluate to `true`',
]
With template
@ -141,4 +141,3 @@ subdivisionCode must be a subdivision code of Brazil
[
'subdivisionCode' => 'subdivisionCode must be a subdivision code of Brazil',
]

View file

@ -228,7 +228,7 @@ with template, negative
All items should not have been integers
- All items should not have been integers
[
'each' => 'All items should not have been integers',
'notEach' => 'All items should not have been integers',
]
With array template, default

View file

@ -28,7 +28,7 @@ Negative
"010106A9012" must not be a valid Finnish personal identity code
- "010106A9012" must not be a valid Finnish personal identity code
[
'hetu' => '"010106A9012" must not be a valid Finnish personal identity code',
'notHetu' => '"010106A9012" must not be a valid Finnish personal identity code',
]
With template

View file

@ -28,7 +28,7 @@ Negative
`[1, 2, 3]` must not of type iterable
- `[1, 2, 3]` must not of type iterable
[
'iterableType' => '`[1, 2, 3]` must not of type iterable',
'notIterableType' => '`[1, 2, 3]` must not of type iterable',
]
With template

View file

@ -51,7 +51,7 @@ Negative
2 must not be of type integer
- 2 must not be of type integer
[
'intType' => '2 must not be of type integer',
'notIntType' => '2 must not be of type integer',
]
With created name, default
@ -75,7 +75,7 @@ With created name, negative
Created must not be of type integer
- Created must not be of type integer
[
'intType' => 'Created must not be of type integer',
'notIntType' => 'Created must not be of type integer',
]
With wrapper name, negative
@ -83,7 +83,7 @@ With wrapper name, negative
Wrapped must not be of type integer
- Wrapped must not be of type integer
[
'intType' => 'Wrapped must not be of type integer',
'notIntType' => 'Wrapped must not be of type integer',
]
With not name, negative
@ -91,7 +91,7 @@ With not name, negative
Not must not be of type integer
- Not must not be of type integer
[
'intType' => 'Not must not be of type integer',
'notIntType' => 'Not must not be of type integer',
]
With template, default

View file

@ -21,7 +21,7 @@ Default
The length of "tulip" must equal 3
- The length of "tulip" must equal 3
[
'length' => 'The length of "tulip" must equal 3',
'lengthEquals' => 'The length of "tulip" must equal 3',
]
Negative wrapped
@ -29,7 +29,7 @@ Negative wrapped
The length of "rose" must not equal 4
- The length of "rose" must not equal 4
[
'length' => 'The length of "rose" must not equal 4',
'lengthNotEquals' => 'The length of "rose" must not equal 4',
]
Negative wrapper
@ -37,7 +37,7 @@ Negative wrapper
The length of "fern" must not equal 4
- The length of "fern" must not equal 4
[
'length' => 'The length of "fern" must not equal 4',
'notLengthEquals' => 'The length of "fern" must not equal 4',
]
With template
@ -45,7 +45,7 @@ With template
This is a template
- This is a template
[
'length' => 'This is a template',
'lengthEquals' => 'This is a template',
]
With wrapper name
@ -53,5 +53,5 @@ With wrapper name
The length of Cactus must equal 3
- The length of Cactus must equal 3
[
'length' => 'The length of Cactus must equal 3',
'lengthEquals' => 'The length of Cactus must equal 3',
]

View file

@ -48,7 +48,7 @@ Default
As the maximum of `[1, 2, 3]`, 3 must be negative
- As the maximum of `[1, 2, 3]`, 3 must be negative
[
'max' => 'As the maximum of `[1, 2, 3]`, 3 must be negative',
'maxNegative' => 'As the maximum of `[1, 2, 3]`, 3 must be negative',
]
Negative
@ -56,7 +56,7 @@ Negative
As the maximum of `[-3, -2, -1]`, -1 must not be negative
- As the maximum of `[-3, -2, -1]`, -1 must not be negative
[
'max' => 'As the maximum of `[-3, -2, -1]`, -1 must not be negative',
'notMaxNegative' => 'As the maximum of `[-3, -2, -1]`, -1 must not be negative',
]
With wrapped name, default
@ -64,7 +64,7 @@ With wrapped name, default
The maximum of Wrapped must be negative
- The maximum of Wrapped must be negative
[
'max' => 'The maximum of Wrapped must be negative',
'maxNegative' => 'The maximum of Wrapped must be negative',
]
With wrapper name, default
@ -72,7 +72,7 @@ With wrapper name, default
The maximum of Wrapper must be negative
- The maximum of Wrapper must be negative
[
'max' => 'The maximum of Wrapper must be negative',
'maxNegative' => 'The maximum of Wrapper must be negative',
]
With wrapped name, negative
@ -80,7 +80,7 @@ With wrapped name, negative
The maximum of Wrapped must not be negative
- The maximum of Wrapped must not be negative
[
'max' => 'The maximum of Wrapped must not be negative',
'notMaxNegative' => 'The maximum of Wrapped must not be negative',
]
With wrapper name, negative
@ -88,7 +88,7 @@ With wrapper name, negative
The maximum of Wrapper must not be negative
- The maximum of Wrapper must not be negative
[
'max' => 'The maximum of Wrapper must not be negative',
'notMaxNegative' => 'The maximum of Wrapper must not be negative',
]
With template, default
@ -96,5 +96,5 @@ With template, default
The maximum of the value is not what we expect
- The maximum of the value is not what we expect
[
'max' => 'The maximum of the value is not what we expect',
'maxNegative' => 'The maximum of the value is not what we expect',
]

View file

@ -20,7 +20,7 @@ Default
As the minimum from `[2, 3]`, 2 must equal 1
- As the minimum from `[2, 3]`, 2 must equal 1
[
'min' => 'As the minimum from `[2, 3]`, 2 must equal 1',
'minEquals' => 'As the minimum from `[2, 3]`, 2 must equal 1',
]
Negative
@ -28,7 +28,7 @@ Negative
As the minimum from `[1, 2, 3]`, 1 must not equal 1
- As the minimum from `[1, 2, 3]`, 1 must not equal 1
[
'min' => 'As the minimum from `[1, 2, 3]`, 1 must not equal 1',
'notMinEquals' => 'As the minimum from `[1, 2, 3]`, 1 must not equal 1',
]
With template
@ -36,7 +36,7 @@ With template
That did not go as planned
- That did not go as planned
[
'min' => 'That did not go as planned',
'minEquals' => 'That did not go as planned',
]
With name
@ -44,5 +44,5 @@ With name
The minimum from Options must equal 1
- The minimum from Options must equal 1
[
'min' => 'The minimum from Options must equal 1',
'minEquals' => 'The minimum from Options must equal 1',
]

View file

@ -37,7 +37,7 @@ Negative
"+55 11 91111 1111" must not be a valid telephone number
- "+55 11 91111 1111" must not be a valid telephone number
[
'phone' => '"+55 11 91111 1111" must not be a valid telephone number',
'notPhone' => '"+55 11 91111 1111" must not be a valid telephone number',
]
Default with name

View file

@ -33,7 +33,7 @@ length
The length of "foo" must be greater than 3
- The length of "foo" must be greater than 3
[
'length' => 'The length of "foo" must be greater than 3',
'lengthGreaterThan' => 'The length of "foo" must be greater than 3',
]
max
@ -41,7 +41,7 @@ max
As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number
- As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number
[
'max' => 'As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number',
'maxOdd' => 'As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number',
]
min
@ -49,7 +49,7 @@ min
As the minimum from `[1, 2, 3]`, 1 must be an even number
- As the minimum from `[1, 2, 3]`, 1 must be an even number
[
'min' => 'As the minimum from `[1, 2, 3]`, 1 must be an even number',
'minEven' => 'As the minimum from `[1, 2, 3]`, 1 must be an even number',
]
not
@ -57,7 +57,7 @@ not
2 must not be between 1 and 3
- 2 must not be between 1 and 3
[
'between' => '2 must not be between 1 and 3',
'notBetween' => '2 must not be between 1 and 3',
]
nullOr

View file

@ -28,7 +28,7 @@ final class NotTest extends RuleTestCase
self::assertEquals(
$rule->evaluate('input'),
$wrapped->evaluate('input')->withInvertedMode()
$wrapped->evaluate('input')->withPrefixedId('not')->withInvertedMode()
);
}