mirror of
https://github.com/Respect/Validation.git
synced 2024-06-08 00:32:16 +02:00
Report all errors when asserting with "Each" rule
The intention of the "assert()" method is to show all the errors that a given input may have. The implementation of the "assert()" method in the "Each" rule, on the other hand, only reports the first error of each element of the input. This commit makes "Each" show all the validation failures of each element of the input. Also, the implementation of "AbstractRule::check()" is simply a proxy for the "assert()" method, and since the "Each" rule extends that class, this commit creates a custom implementation of the "check()" method. Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
parent
7154e90522
commit
3501192293
|
@ -55,7 +55,7 @@ final class Each extends AbstractRule
|
|||
$exceptions = [];
|
||||
foreach ($input as $value) {
|
||||
try {
|
||||
$this->rule->check($value);
|
||||
$this->rule->assert($value);
|
||||
} catch (ValidationException $exception) {
|
||||
$exceptions[] = $exception;
|
||||
}
|
||||
|
@ -70,13 +70,27 @@ final class Each extends AbstractRule
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function check($input): void
|
||||
{
|
||||
if (!$this->isIterable($input)) {
|
||||
throw $this->reportError($input);
|
||||
}
|
||||
|
||||
foreach ($input as $value) {
|
||||
$this->rule->check($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function validate($input): bool
|
||||
{
|
||||
try {
|
||||
$this->assert($input);
|
||||
$this->check($input);
|
||||
} catch (ValidationException $exception) {
|
||||
return false;
|
||||
}
|
||||
|
|
76
tests/integration/issue-1289.phpt
Normal file
76
tests/integration/issue-1289.phpt
Normal file
|
@ -0,0 +1,76 @@
|
|||
--CREDITS--
|
||||
Henrique Moody <henriquemoody@gmail.com>
|
||||
--DESCRIPTION--
|
||||
The previous output was:
|
||||
|
||||
default must be of type string
|
||||
- default must be of type string
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Exceptions\ValidationException;
|
||||
use Respect\Validation\Rules\ArrayType;
|
||||
use Respect\Validation\Rules\BoolType;
|
||||
use Respect\Validation\Rules\Each;
|
||||
use Respect\Validation\Rules\Key;
|
||||
use Respect\Validation\Rules\OneOf;
|
||||
use Respect\Validation\Rules\StringType;
|
||||
use Respect\Validation\Rules\StringVal;
|
||||
use Respect\Validation\Validator;
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
$validator = new Validator(
|
||||
new Each(
|
||||
new Validator(
|
||||
new Key(
|
||||
'default',
|
||||
new OneOf(
|
||||
new StringType(),
|
||||
new BoolType()
|
||||
),
|
||||
false
|
||||
),
|
||||
new Key(
|
||||
'description',
|
||||
new StringVal(),
|
||||
false
|
||||
),
|
||||
new Key(
|
||||
'children',
|
||||
new ArrayType(),
|
||||
false
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$input = [
|
||||
[
|
||||
'default' => 2,
|
||||
'description' => [],
|
||||
'children' => ['nope'],
|
||||
],
|
||||
];
|
||||
try {
|
||||
$validator->check($input);
|
||||
} catch (ValidationException $exception) {
|
||||
echo $exception->getMessage().PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
$validator->assert($input);
|
||||
} catch (NestedValidationException $exception) {
|
||||
echo $exception->getFullMessage();
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
default must be of type string
|
||||
- These rules must pass for `{ "default": 2, "description": { }, "children": { "nope" } }`
|
||||
- Only one of these rules must pass for default
|
||||
- default must be of type string
|
||||
- default must be of type boolean
|
||||
- description must be a string
|
|
@ -17,6 +17,8 @@ use Respect\Validation\Test\RuleTestCase;
|
|||
use Respect\Validation\Validatable;
|
||||
use SplStack;
|
||||
use stdClass;
|
||||
use Traversable;
|
||||
use function range;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
|
@ -40,6 +42,8 @@ final class EachTest extends RuleTestCase
|
|||
return [
|
||||
[$rule, []],
|
||||
[$rule, [1, 2, 3, 4, 5]],
|
||||
[$rule, $this->createTraversableInput(1, 5)],
|
||||
[$rule, $this->createStdClassInput(1, 5)],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -57,43 +61,39 @@ final class EachTest extends RuleTestCase
|
|||
[$rule, false],
|
||||
[$rule, ['', 2, 3, 4, 5]],
|
||||
[$rule, ['a', 2, 3, 4, 5]],
|
||||
[$rule, $this->createTraversableInput(1, 5)],
|
||||
[$rule, $this->createStdClassInput(1, 5)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function itShouldValidateTraversable(): void
|
||||
public function itShouldAssertEachValue(): void
|
||||
{
|
||||
$validatable = $this->createMock(Validatable::class);
|
||||
|
||||
$validatable
|
||||
->expects(self::at(0))
|
||||
->method('check')
|
||||
->with('A');
|
||||
->method('assert')
|
||||
->with(1);
|
||||
$validatable
|
||||
->expects(self::at(1))
|
||||
->method('check')
|
||||
->with('B');
|
||||
->method('assert')
|
||||
->with(2);
|
||||
$validatable
|
||||
->expects(self::at(2))
|
||||
->method('check')
|
||||
->with('C');
|
||||
->method('assert')
|
||||
->with(3);
|
||||
|
||||
$rule = new Each($validatable);
|
||||
|
||||
$input = new SplStack();
|
||||
$input->push('C');
|
||||
$input->push('B');
|
||||
$input->push('A');
|
||||
|
||||
self::assertValidInput($rule, $input);
|
||||
$rule->assert(range(1, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function itShouldValidateStdClass(): void
|
||||
public function itShouldCheckEachValue(): void
|
||||
{
|
||||
$validatable = $this->createMock(Validatable::class);
|
||||
|
||||
|
@ -111,12 +111,26 @@ final class EachTest extends RuleTestCase
|
|||
->with(3);
|
||||
|
||||
$rule = new Each($validatable);
|
||||
$rule->check(range(1, 3));
|
||||
}
|
||||
|
||||
$input = new stdClass();
|
||||
$input->foo = 1;
|
||||
$input->bar = 2;
|
||||
$input->baz = 3;
|
||||
private function createTraversableInput(int $firstValue, int $lastValue): Traversable
|
||||
{
|
||||
$input = new SplStack();
|
||||
foreach (range($firstValue, $lastValue) as $value) {
|
||||
$input->push($value);
|
||||
}
|
||||
|
||||
self::assertValidInput($rule, $input);
|
||||
return $input;
|
||||
}
|
||||
|
||||
private function createStdClassInput(int $firstValue, int $lastValue): stdClass
|
||||
{
|
||||
$input = [];
|
||||
foreach (range($firstValue, $lastValue) as $value) {
|
||||
$input[] = $value;
|
||||
}
|
||||
|
||||
return (object) $input;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue