Skip to content

Commit

Permalink
Fix #161: Remove ResultSet (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Feb 9, 2022
1 parent 1d076d6 commit 54b5665
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 290 deletions.
2 changes: 1 addition & 1 deletion src/PostValidationHookInterface.php
Expand Up @@ -11,5 +11,5 @@
*/
interface PostValidationHookInterface extends DataSetInterface
{
public function processValidationResult(ResultSet $resultSet): void;
public function processValidationResult(Result $result): void;
}
67 changes: 67 additions & 0 deletions src/Result.php
Expand Up @@ -4,8 +4,12 @@

namespace Yiisoft\Validator;

use Closure;
use Yiisoft\Arrays\ArrayHelper;

use function array_slice;
use function implode;

final class Result
{
/**
Expand All @@ -18,6 +22,18 @@ public function isValid(): bool
return $this->errors === [];
}

public function isAttributeValid(string $attribute): bool
{
foreach ($this->errors as $error) {
$firstItem = $error->getValuePath()[0] ?? null;
if ($firstItem === $attribute) {
return false;
}
}

return true;
}

/**
* @return Error[]
*/
Expand All @@ -34,6 +50,9 @@ public function getErrors(): array
return ArrayHelper::getColumn($this->errors, static fn (Error $error) => $error->getMessage());
}

/**
* @psalm-return array<string, non-empty-list<string>>
*/
public function getErrorsIndexedByPath(string $separator = '.'): array
{
$errors = [];
Expand All @@ -45,6 +64,54 @@ public function getErrorsIndexedByPath(string $separator = '.'): array
return $errors;
}

/**
* @psalm-return array<string, Error[]>
*/
public function getAttributeErrorObjects(string $attribute): array
{
return $this->getAttributeErrorsMap($attribute, static fn (Error $error): Error => $error);
}

/**
* @psalm-return array<string, string[]>
*/
public function getAttributeErrors(string $attribute): array
{
return $this->getAttributeErrorsMap($attribute, static fn (Error $error): string => $error->getMessage());
}

private function getAttributeErrorsMap(string $attribute, Closure $getErrorClosure): array
{
$errors = [];
foreach ($this->errors as $error) {
$firstItem = $error->getValuePath()[0] ?? null;
if ($firstItem === $attribute) {
$errors[] = $getErrorClosure($error);
}
}

return $errors;
}

/**
* @psalm-return array<string, non-empty-list<string>>
*/
public function getAttributeErrorsIndexedByPath(string $attribute, string $separator = '.'): array
{
$errors = [];
foreach ($this->errors as $error) {
$firstItem = $error->getValuePath()[0] ?? null;
if ($firstItem !== $attribute) {
continue;
}

$valuePath = implode($separator, array_slice($error->getValuePath(), 1));
$errors[$valuePath][] = $error->getMessage();
}

return $errors;
}

/**
* @psalm-param array<int|string> $valuePath
*/
Expand Down
97 changes: 0 additions & 97 deletions src/ResultSet.php

This file was deleted.

22 changes: 13 additions & 9 deletions src/Validator.php
Expand Up @@ -25,33 +25,37 @@ public function __construct(?FormatterInterface $formatter = null)
* @param DataSetInterface|mixed|RulesProviderInterface $data
* @param Rule[][] $rules
* @psalm-param iterable<string, Rule[]> $rules
*
* @return ResultSet
*/
public function validate($data, iterable $rules = []): ResultSet
public function validate($data, iterable $rules = []): Result
{
$data = $this->normalizeDataSet($data);
if ($data instanceof RulesProviderInterface) {
$rules = $data->getRules();
}

$context = new ValidationContext($data);
$results = new ResultSet();
$result = new Result();

foreach ($rules as $attribute => $attributeRules) {
$ruleSet = new RuleSet($attributeRules);
if ($this->formatter !== null) {
$ruleSet = $ruleSet->withFormatter($this->formatter);
}
$results->addResult(
$attribute,
$ruleSet->validate($data->getAttributeValue($attribute), $context->withAttribute($attribute))

$tempResult = $ruleSet->validate(
$data->getAttributeValue($attribute),
$context->withAttribute($attribute)
);
foreach ($tempResult->getErrorObjects() as $error) {
$result->addError($error->getMessage(), [$attribute, ...$error->getValuePath()]);
}
}

if ($data instanceof PostValidationHookInterface) {
$data->processValidationResult($results);
$data->processValidationResult($result);
}
return $results;

return $result;
}

public function withFormatter(?FormatterInterface $formatter): self
Expand Down
4 changes: 1 addition & 3 deletions src/ValidatorInterface.php
Expand Up @@ -15,8 +15,6 @@ interface ValidatorInterface
* @param DataSetInterface|mixed|RulesProviderInterface $data Data set to validate.
* @param Rule[][] $rules Rules to apply.
* @psalm-param iterable<string, Rule[]> $rules
*
* @return ResultSet Validation results.
*/
public function validate($data, iterable $rules = []): ResultSet;
public function validate($data, iterable $rules = []): Result;
}
32 changes: 11 additions & 21 deletions tests/AbstractDataSetTest.php
Expand Up @@ -6,54 +6,44 @@

use PHPUnit\Framework\TestCase;
use Yiisoft\Validator\Result;
use Yiisoft\Validator\ResultSet;
use Yiisoft\Validator\Rule\Boolean;
use Yiisoft\Validator\Rule\Number;

abstract class AbstractDataSetTest extends TestCase
{
/**
* @dataProvider validationCasesDataProvider()
* @dataProvider validationCasesDataProvider
*
* @param array $dataSet
*/
final public function test(array $dataSet, array $rules): void
{
$resultSet = $this->validate($dataSet, $rules);

$this->assertTrue($resultSet->isValid());
$result = $this->validate($dataSet, $rules);
$this->assertTrue($result->isValid());
}

public function validationCasesDataProvider(): array
{
return [
[
[
'bool' => true,
'int' => 41,
],
[
'bool' => [Boolean::rule()],
'int' => [Number::rule()],
],
['bool' => true, 'int' => 41],
['bool' => [Boolean::rule()], 'int' => [Number::rule()]],
],
];
}

/**
* @dataProvider resultDataProvider()
* @dataProvider resultDataProvider
*
* @param array $dataSet
*/
public function testResult(array $dataSet, array $rules): void
{
$resultSet = $this->validate($dataSet, $rules);

$this->assertTrue($resultSet->getResult('bool')->isValid());
$result = $this->validate($dataSet, $rules);

$intResult = $resultSet->getResult('int');
$this->assertFalse($intResult->isValid());
$this->assertCount(1, $intResult->getErrors());
$this->assertTrue($result->isAttributeValid('bool'));
$this->assertFalse($result->isAttributeValid('int'));
$this->assertCount(1, $result->getAttributeErrors('int'));
}

public function resultDataProvider(): array
Expand Down Expand Up @@ -82,5 +72,5 @@ static function ($value): Result {
];
}

abstract protected function validate(array $dataSet, array $rules): ResultSet;
abstract protected function validate(array $dataSet, array $rules): Result;
}
5 changes: 2 additions & 3 deletions tests/DataSetTest.php
Expand Up @@ -4,16 +4,15 @@

namespace Yiisoft\Validator\Tests;

use Yiisoft\Validator\ResultSet;
use Yiisoft\Validator\Result;
use Yiisoft\Validator\Tests\Stub\DataSet;
use Yiisoft\Validator\Validator;

final class DataSetTest extends AbstractDataSetTest
{
protected function validate(array $dataSet, array $rules): ResultSet
protected function validate(array $dataSet, array $rules): Result
{
$dataObject = new DataSet($dataSet);

$validator = new Validator();

return $validator->validate($dataObject, $rules);
Expand Down

0 comments on commit 54b5665

Please sign in to comment.