diff --git a/src/ControllerName.php b/src/ControllerName.php index d3181c8..f28e70a 100644 --- a/src/ControllerName.php +++ b/src/ControllerName.php @@ -15,22 +15,14 @@ use Chevere\Action\Interfaces\ControllerInterface; use Chevere\Action\Interfaces\ControllerNameInterface; -use InvalidArgumentException; +use Chevere\Action\Traits\ControllerNameTrait; final class ControllerName implements ControllerNameInterface { - public function __construct( - private string $name - ) { - if (is_subclass_of($this->name, ControllerInterface::class)) { - return; - } + use ControllerNameTrait; - throw new InvalidArgumentException(); - } - - public function __toString(): string + private function interface(): string { - return $this->name; + return ControllerInterface::class; } } diff --git a/src/Interfaces/ControllerNameInterface.php b/src/Interfaces/ControllerNameInterface.php index 3870911..e2144e3 100644 --- a/src/Interfaces/ControllerNameInterface.php +++ b/src/Interfaces/ControllerNameInterface.php @@ -20,4 +20,13 @@ */ interface ControllerNameInterface extends Stringable { + /** + * @return class-string ControllerInterface + */ + public function __toString(): string; + + /** + * Returns a boolean if the object has this class as one of its parents or implements it. + */ + public function isSubclassOf(string $class): bool; } diff --git a/src/Traits/ControllerNameTrait.php b/src/Traits/ControllerNameTrait.php new file mode 100644 index 0000000..2e11ea7 --- /dev/null +++ b/src/Traits/ControllerNameTrait.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Chevere\Action\Traits; + +use InvalidArgumentException; +use function Chevere\Message\message; + +trait ControllerNameTrait +{ + public function __construct( + /** @var class-string */ + private string $name + ) { + if ($this->isSubclassOf($this->interface())) { + return; + } + + throw new InvalidArgumentException( + (string) message( + "Controller `{{ name }}` doesn't implement `{{ interface }}`", + name: $this->name, + interface: $this->interface() + ) + ); + } + + public function __toString(): string + { + return $this->name; + } + + public function isSubclassOf(string $class): bool + { + return is_subclass_of($this->name, $class, true); + } + + abstract private function interface(): string; +} diff --git a/tests/ControllerNameTest.php b/tests/ControllerNameTest.php index 325699c..34a2a29 100644 --- a/tests/ControllerNameTest.php +++ b/tests/ControllerNameTest.php @@ -23,6 +23,11 @@ final class ControllerNameTest extends TestCase public function testWrongInterface(): void { $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage( + <<