From a7fe6f33b7a86c10cdd3d4f2f4825fe2cbbd5251 Mon Sep 17 00:00:00 2001 From: Jan Willem Kaper Date: Tue, 14 May 2024 15:18:08 +0200 Subject: [PATCH] Add ability to check for multiple Extends --- README.md | 2 ++ src/Expression/ForClasses/Extend.php | 19 ++++++++++++------- .../Expressions/ForClasses/ExtendTest.php | 19 +++++++++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 03eec96d..0bdba903 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,8 @@ $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new Extend('App\Controller\AbstractController')) ->because('we want to be sure that all controllers extend AbstractController'); + +You can add multiple parameters, the violation will happen when none of them match ``` ### Has an attribute (requires PHP >= 8.0) diff --git a/src/Expression/ForClasses/Extend.php b/src/Expression/ForClasses/Extend.php index b27947c5..c9434a08 100644 --- a/src/Expression/ForClasses/Extend.php +++ b/src/Expression/ForClasses/Extend.php @@ -13,25 +13,30 @@ class Extend implements Expression { - /** @var string */ - private $className; + /** @var string[] */ + private $classNames; - public function __construct(string $className) + public function __construct(string ...$classNames) { - $this->className = $className; + $this->classNames = $classNames; } public function describe(ClassDescription $theClass, string $because): Description { - return new Description("should extend {$this->className}", $because); + $desc = implode(', ', $this->classNames); + + return new Description("should extend one of these classes: {$desc}", $because); } public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void { $extends = $theClass->getExtends(); - if (null !== $extends && $extends->matches($this->className)) { - return; + /** @var string $className */ + foreach ($this->classNames as $className) { + if (null !== $extends && $extends->matches($className)) { + return; + } } $violation = Violation::create( diff --git a/tests/Unit/Expressions/ForClasses/ExtendTest.php b/tests/Unit/Expressions/ForClasses/ExtendTest.php index 749f305e..e73015d5 100644 --- a/tests/Unit/Expressions/ForClasses/ExtendTest.php +++ b/tests/Unit/Expressions/ForClasses/ExtendTest.php @@ -70,7 +70,7 @@ public function test_it_should_return_violation_error_when_class_not_extend(): v $extend->evaluate($classDescription, $violations, 'we want to add this rule for our software'); self::assertEquals(1, $violations->count()); - self::assertEquals('should extend My\BaseClass because we want to add this rule for our software', $violations->get(0)->getError()); + self::assertEquals('should extend one of these classes: My\BaseClass because we want to add this rule for our software', $violations->get(0)->getError()); } public function test_it_should_return_violation_error_if_extend_is_null(): void @@ -97,6 +97,21 @@ public function test_it_should_return_violation_error_if_extend_is_null(): void $extend->evaluate($classDescription, $violations, $because); self::assertEquals(1, $violations->count()); - self::assertEquals('should extend My\BaseClass because we want to add this rule for our software', $violationError); + self::assertEquals('should extend one of these classes: My\BaseClass because we want to add this rule for our software', $violationError); + } + + public function test_it_should_accept_multiple_extends(): void + { + $extend = new Extend('My\FirstExtend', 'My\SecondExtend'); + + $classDescription = (new ClassDescriptionBuilder()) + ->setClassName('My\Class') + ->setExtends('My\SecondExtend', 10) + ->build(); + + $violations = new Violations(); + $extend->evaluate($classDescription, $violations, 'because'); + + self::assertEquals(0, $violations->count()); } }