Skip to content

Commit

Permalink
Refactor "AbstractComposite" class
Browse files Browse the repository at this point in the history
The class had too much complexity and some duplication on its children.

I started doing this because I'm refactoring the tests to upgrade
PHPUnit later, and then I made some improvements along the way.

Signed-off-by: Henrique Moody <[email protected]>
  • Loading branch information
henriquemoody committed Jan 28, 2024
1 parent e983e52 commit ae1620b
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 184 deletions.
5 changes: 5 additions & 0 deletions library/Exceptions/AllOfException.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ class AllOfException extends GroupedValidationException
self::SOME => 'These rules must not pass for {{name}}',
],
];

protected function chooseTemplate(): string
{
return self::SOME;
}
}
10 changes: 0 additions & 10 deletions library/Exceptions/GroupedValidationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

namespace Respect\Validation\Exceptions;

use function count;

class GroupedValidationException extends NestedValidationException
{
public const NONE = 'none';
Expand All @@ -29,12 +27,4 @@ class GroupedValidationException extends NestedValidationException
self::SOME => 'These rules must not pass for {{name}}',
],
];

protected function chooseTemplate(): string
{
$numRules = $this->getParam('passed');
$numFailed = count($this->getChildren());

return $numRules === $numFailed ? self::NONE : self::SOME;
}
}
47 changes: 27 additions & 20 deletions library/Rules/AbstractComposite.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Validatable;

use function array_filter;
use function array_map;

abstract class AbstractComposite extends AbstractRule
{
/**
Expand Down Expand Up @@ -62,27 +59,37 @@ public function getRules(): array
return $this->rules;
}

public function assert(mixed $input): void
{
$exceptions = $this->getAllThrownExceptions($input);
if (empty($exceptions)) {
return;
}

$exception = $this->reportError($input);
if ($exception instanceof NestedValidationException) {
$exception->addChildren($exceptions);
}

throw $exception;
}

/**
* @return ValidationException[]
*/
protected function getAllThrownExceptions(mixed $input): array
private function getAllThrownExceptions(mixed $input): array
{
return array_filter(
array_map(
function (Validatable $rule) use ($input): ?ValidationException {
try {
$rule->assert($input);
} catch (ValidationException $exception) {
$this->updateExceptionTemplate($exception);

return $exception;
}

return null;
},
$this->getRules()
)
);
$exceptions = [];
foreach ($this->getRules() as $rule) {
try {
$rule->assert($input);
} catch (ValidationException $exception) {
$this->updateExceptionTemplate($exception);
$exceptions[] = $exception;
}
}

return $exceptions;
}

private function shouldHaveNameOverwritten(Validatable $rule): bool
Expand Down
22 changes: 8 additions & 14 deletions library/Rules/AllOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,14 @@ class AllOf extends AbstractComposite
{
public function assert(mixed $input): void
{
$exceptions = $this->getAllThrownExceptions($input);
$numRules = count($this->getRules());
$numExceptions = count($exceptions);
$summary = [
'total' => $numRules,
'failed' => $numExceptions,
'passed' => $numRules - $numExceptions,
];
if (!empty($exceptions)) {
/** @var AllOfException $allOfException */
$allOfException = $this->reportError($input, $summary);
$allOfException->addChildren($exceptions);

throw $allOfException;
try {
parent::assert($input);
} catch (AllOfException $exception) {
if (count($exception->getChildren()) === count($this->getRules()) && !$exception->hasCustomTemplate()) {
$exception->updateTemplate(AllOfException::NONE);
}

throw $exception;
}
}

Expand Down
16 changes: 6 additions & 10 deletions library/Rules/AnyOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@ final class AnyOf extends AbstractComposite
{
public function assert(mixed $input): void
{
$validators = $this->getRules();
$exceptions = $this->getAllThrownExceptions($input);
$numRules = count($validators);
$numExceptions = count($exceptions);
if ($numExceptions === $numRules) {
/** @var AnyOfException $anyOfException */
$anyOfException = $this->reportError($input);
$anyOfException->addChildren($exceptions);

throw $anyOfException;
try {
parent::assert($input);
} catch (AnyOfException $exception) {
if (count($exception->getChildren()) === count($this->getRules())) {
throw $exception;
}
}
}

Expand Down
15 changes: 6 additions & 9 deletions library/Rules/NoneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ final class NoneOf extends AbstractComposite
{
public function assert(mixed $input): void
{
$exceptions = $this->getAllThrownExceptions($input);
$numRules = count($this->getRules());
$numExceptions = count($exceptions);
if ($numRules !== $numExceptions) {
/** @var NoneOfException $noneOfException */
$noneOfException = $this->reportError($input);
$noneOfException->addChildren($exceptions);

throw $noneOfException;
try {
parent::assert($input);
} catch (NoneOfException $exception) {
if (count($exception->getChildren()) !== count($this->getRules())) {
throw $exception;
}
}
}

Expand Down
16 changes: 6 additions & 10 deletions library/Rules/OneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,12 @@ final class OneOf extends AbstractComposite
{
public function assert(mixed $input): void
{
$validators = $this->getRules();
$exceptions = $this->getAllThrownExceptions($input);
$numRules = count($validators);
$numExceptions = count($exceptions);
if ($numExceptions !== $numRules - 1) {
/** @var OneOfException $oneOfException */
$oneOfException = $this->reportError($input);
$oneOfException->addChildren($exceptions);

throw $oneOfException;
try {
parent::assert($input);
} catch (OneOfException $exception) {
if (count($exception->getChildren()) !== count($this->getRules()) - 1) {
throw $exception;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/translator-assert.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Factory::setDefaultInstance(
=> '{{name}} deve ser do tipo string',
'{{name}} must have a length between {{minValue}} and {{maxValue}}'
=> '{{name}} deve possuir de {{minValue}} a {{maxValue}} caracteres',
][$message];
][$message] ?? $message;
})
);

Expand Down
16 changes: 16 additions & 0 deletions tests/library/Exceptions/CompositeStubException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/*
* Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
* SPDX-License-Identifier: MIT
*/

declare(strict_types=1);

namespace Respect\Validation\Test\Exceptions;

use Respect\Validation\Exceptions\NestedValidationException;

final class CompositeStubException extends NestedValidationException
{
}
36 changes: 36 additions & 0 deletions tests/library/Stubs/CompositeSub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
* SPDX-License-Identifier: MIT
*/

declare(strict_types=1);

namespace Respect\Validation\Test\Stubs;

use Respect\Validation\Message\Formatter;
use Respect\Validation\Message\Stringifier\KeepOriginalStringName;
use Respect\Validation\Rules\AbstractComposite;
use Respect\Validation\Test\Exceptions\CompositeStubException;

final class CompositeSub extends AbstractComposite
{
public function validate(mixed $input): bool
{
return true;
}

/**
* @param array<string, mixed> $extraParameters
*/
public function reportError(mixed $input, array $extraParameters = []): CompositeStubException
{
return new CompositeStubException(
input: $input,
id: 'CompositeStub',
params: $extraParameters,
formatter: new Formatter(static fn ($value) => $value, new KeepOriginalStringName())
);
}
}
Loading

0 comments on commit ae1620b

Please sign in to comment.