diff --git a/library/Rules/AllOf.php b/library/Rules/AllOf.php index 499f11656..94070d904 100644 --- a/library/Rules/AllOf.php +++ b/library/Rules/AllOf.php @@ -36,7 +36,7 @@ final class AllOf extends Composite public function evaluate(mixed $input): Result { - $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules()); + $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules); $valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry && $result->isValid, true); $failed = array_filter($children, static fn (Result $result): bool => !$result->isValid); $template = self::TEMPLATE_SOME; diff --git a/library/Rules/AnyOf.php b/library/Rules/AnyOf.php index 4cdab3fde..25117563d 100644 --- a/library/Rules/AnyOf.php +++ b/library/Rules/AnyOf.php @@ -25,7 +25,7 @@ final class AnyOf extends Composite { public function evaluate(mixed $input): Result { - $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules()); + $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules); $valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry || $result->isValid, false); return (new Result($valid, $input, $this))->withChildren(...$children); diff --git a/library/Rules/Core/Composite.php b/library/Rules/Core/Composite.php index 00206ffc0..a1eb82237 100644 --- a/library/Rules/Core/Composite.php +++ b/library/Rules/Core/Composite.php @@ -19,7 +19,7 @@ abstract class Composite implements Validatable use DeprecatedValidatableMethods; /** @var non-empty-array */ - private readonly array $rules; + protected readonly array $rules; private ?string $name = null; @@ -38,7 +38,7 @@ public function getRules(): array public function setName(string $name): static { - foreach ($this->getRules() as $rule) { + foreach ($this->rules as $rule) { if ($rule->getName() && $this->name !== $rule->getName()) { continue; } diff --git a/library/Rules/NoneOf.php b/library/Rules/NoneOf.php index 2937c4deb..c4e0b5298 100644 --- a/library/Rules/NoneOf.php +++ b/library/Rules/NoneOf.php @@ -25,7 +25,7 @@ final class NoneOf extends Composite { public function evaluate(mixed $input): Result { - $children = array_map(static fn (Rule $rule) => $rule->evaluate($input)->withInvertedMode(), $this->getRules()); + $children = array_map(static fn (Rule $rule) => $rule->evaluate($input)->withInvertedMode(), $this->rules); $valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry && $result->isValid, true); return (new Result($valid, $input, $this))->withChildren(...$children); diff --git a/library/Rules/OneOf.php b/library/Rules/OneOf.php index 62d6b87ff..f0442b8dd 100644 --- a/library/Rules/OneOf.php +++ b/library/Rules/OneOf.php @@ -25,9 +25,9 @@ final class OneOf extends Composite { public function evaluate(mixed $input): Result { - $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules()); - $count = array_reduce($children, static fn (int $carry, Result $result) => $carry + (int) $result->isValid, 0); + $children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules); + $valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry xor $result->isValid, false); - return (new Result($count === 1, $input, $this))->withChildren(...$children); + return (new Result($valid, $input, $this))->withChildren(...$children); } } diff --git a/tests/unit/Rules/AnyOfTest.php b/tests/unit/Rules/AnyOfTest.php index c29a14bc5..4b7fee3ec 100644 --- a/tests/unit/Rules/AnyOfTest.php +++ b/tests/unit/Rules/AnyOfTest.php @@ -22,8 +22,10 @@ final class AnyOfTest extends RuleTestCase public static function providerForValidInput(): iterable { yield 'fail, pass' => [new AnyOf(Stub::fail(1), Stub::pass(1)), []]; + yield 'pass, fail' => [new AnyOf(Stub::pass(1), Stub::fail(1)), []]; yield 'fail, fail, pass' => [new AnyOf(Stub::fail(1), Stub::fail(1), Stub::pass(1)), []]; yield 'fail, pass, fail' => [new AnyOf(Stub::fail(1), Stub::pass(1), Stub::fail(1)), []]; + yield 'pass, fail, fail' => [new AnyOf(Stub::pass(1), Stub::fail(1), Stub::fail(1)), []]; } /** @return iterable */