diff --git a/README.md b/README.md index 7b014a4..b8c84a1 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,7 @@ require './vendor/autoload.php'; ```php use Gears\CQRS\Tactician\CommandBus; use Gears\CQRS\Tactician\CommandHandlerMiddleware; -use Gears\CQRS\Tactician\CommandInflector; use League\Tactician\CommandBus as TacticianBus; -use League\Tactician\Handler\CommandHandlerMiddleware as TacticianHandlerMiddleware; use League\Tactician\Handler\Locator\InMemoryLocator; use League\Tactician\Plugins\LockingMiddleware; @@ -59,9 +57,7 @@ $commandBus->handle($command); ```php use Gears\CQRS\Tactician\QueryBus; use Gears\CQRS\Tactician\QueryHandlerMiddleware; -use Gears\CQRS\Tactician\QueryInflector; use League\Tactician\CommandBus as TacticianBus; -use League\Tactician\Handler\CommandHandlerMiddleware as TacticianHandlerMiddleware; use League\Tactician\Handler\Locator\InMemoryLocator; use League\Tactician\Plugins\LockingMiddleware; diff --git a/composer.json b/composer.json index 723d715..cb5744e 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "require": { "php": "^7.1", "league/tactician": "^1.0", - "phpgears/cqrs": "~0.3" + "phpgears/cqrs": "~0.3.1" }, "require-dev": { "brainmaestro/composer-git-hooks": "^2.1", diff --git a/src/CommandExtractor.php b/src/CommandExtractor.php new file mode 100644 index 0000000..16ec166 --- /dev/null +++ b/src/CommandExtractor.php @@ -0,0 +1,43 @@ + + */ + +declare(strict_types=1); + +namespace Gears\CQRS\Tactician; + +use Gears\CQRS\Command; +use Gears\CQRS\Exception\InvalidCommandException; +use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor; + +final class CommandExtractor implements CommandNameExtractor +{ + /** + * Extract the name from a command. + * + * @param mixed $command + * + * @throws InvalidCommandException + * + * @return string + */ + public function extract($command) + { + if (!$command instanceof Command) { + throw new InvalidCommandException(\sprintf( + 'Command must implement "%s" interface, "%s" given', + Command::class, + \is_object($command) ? \get_class($command) : \gettype($command) + )); + } + + return $command->getCommandType(); + } +} diff --git a/src/CommandHandlerMiddleware.php b/src/CommandHandlerMiddleware.php index e884077..7f67a86 100644 --- a/src/CommandHandlerMiddleware.php +++ b/src/CommandHandlerMiddleware.php @@ -14,7 +14,6 @@ namespace Gears\CQRS\Tactician; use League\Tactician\Handler\CommandHandlerMiddleware as TacticianHandlerMiddleware; -use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor; use League\Tactician\Handler\Locator\HandlerLocator; final class CommandHandlerMiddleware extends TacticianHandlerMiddleware @@ -27,7 +26,7 @@ final class CommandHandlerMiddleware extends TacticianHandlerMiddleware public function __construct(HandlerLocator $handlerLocator) { parent::__construct( - new ClassNameExtractor(), + new CommandExtractor(), $handlerLocator, new CommandInflector() ); diff --git a/src/CommandInflector.php b/src/CommandInflector.php index 62b0482..3f03add 100644 --- a/src/CommandInflector.php +++ b/src/CommandInflector.php @@ -34,7 +34,7 @@ public function inflect($command, $handler): string { if (!$command instanceof Command) { throw new InvalidCommandException(\sprintf( - 'Command must implement %s interface, %s given', + 'Command must implement "%s" interface, "%s" given', Command::class, \is_object($command) ? \get_class($command) : \gettype($command) )); @@ -42,7 +42,7 @@ public function inflect($command, $handler): string if (!$handler instanceof CommandHandler) { throw new InvalidCommandHandlerException(\sprintf( - 'Command handler must implement %s interface, %s given', + 'Command handler must implement "%s" interface, "%s" given', CommandHandler::class, \is_object($handler) ? \get_class($handler) : \gettype($handler) )); diff --git a/src/QueryExtractor.php b/src/QueryExtractor.php new file mode 100644 index 0000000..d46cdef --- /dev/null +++ b/src/QueryExtractor.php @@ -0,0 +1,43 @@ + + */ + +declare(strict_types=1); + +namespace Gears\CQRS\Tactician; + +use Gears\CQRS\Exception\InvalidQueryException; +use Gears\CQRS\Query; +use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor; + +final class QueryExtractor implements CommandNameExtractor +{ + /** + * Extract the name from a query. + * + * @param mixed $query + * + * @throws InvalidQueryException + * + * @return string + */ + public function extract($query) + { + if (!$query instanceof Query) { + throw new InvalidQueryException(\sprintf( + 'Query must implement "%s" interface, "%s" given', + Query::class, + \is_object($query) ? \get_class($query) : \gettype($query) + )); + } + + return $query->getQueryType(); + } +} diff --git a/src/QueryHandlerMiddleware.php b/src/QueryHandlerMiddleware.php index a2908d2..22456a6 100644 --- a/src/QueryHandlerMiddleware.php +++ b/src/QueryHandlerMiddleware.php @@ -14,7 +14,6 @@ namespace Gears\CQRS\Tactician; use League\Tactician\Handler\CommandHandlerMiddleware as TacticianHandlerMiddleware; -use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor; use League\Tactician\Handler\Locator\HandlerLocator; final class QueryHandlerMiddleware extends TacticianHandlerMiddleware @@ -27,7 +26,7 @@ final class QueryHandlerMiddleware extends TacticianHandlerMiddleware public function __construct(HandlerLocator $handlerLocator) { parent::__construct( - new ClassNameExtractor(), + new QueryExtractor(), $handlerLocator, new QueryInflector() ); diff --git a/src/QueryInflector.php b/src/QueryInflector.php index 7d5493a..c37e780 100644 --- a/src/QueryInflector.php +++ b/src/QueryInflector.php @@ -34,7 +34,7 @@ public function inflect($command, $handler): string { if (!$command instanceof Query) { throw new InvalidQueryException(\sprintf( - 'Query must implement %s interface, %s given', + 'Query must implement "%s" interface, "%s" given', Query::class, \is_object($command) ? \get_class($command) : \gettype($command) )); @@ -42,7 +42,7 @@ public function inflect($command, $handler): string if (!$handler instanceof QueryHandler) { throw new InvalidQueryHandlerException(\sprintf( - 'Query handler must implement %s interface, %s given', + 'Query handler must implement "%s" interface, "%s" given', QueryHandler::class, \is_object($handler) ? \get_class($handler) : \gettype($handler) )); diff --git a/tests/Tactician/CommandExtractorTest.php b/tests/Tactician/CommandExtractorTest.php new file mode 100644 index 0000000..2824371 --- /dev/null +++ b/tests/Tactician/CommandExtractorTest.php @@ -0,0 +1,40 @@ + + */ + +declare(strict_types=1); + +namespace Gears\CQRS\Tactician\Tests; + +use Gears\CQRS\Exception\InvalidCommandException; +use Gears\CQRS\Tactician\CommandExtractor; +use Gears\CQRS\Tactician\Tests\Stub\CommandStub; +use PHPUnit\Framework\TestCase; + +/** + * Command extractor test. + */ +class CommandExtractorTest extends TestCase +{ + public function testInvalidCommand(): void + { + $this->expectException(InvalidCommandException::class); + $this->expectExceptionMessage('Command must implement "Gears\CQRS\Command" interface, "stdClass" given'); + + (new CommandExtractor())->extract(new \stdClass()); + } + + public function testExtract(): void + { + $type = (new CommandExtractor())->extract(CommandStub::instance()); + + static::assertSame(CommandStub::class, $type); + } +} diff --git a/tests/Tactician/CommandInflectorTest.php b/tests/Tactician/CommandInflectorTest.php index 681715b..db76f85 100644 --- a/tests/Tactician/CommandInflectorTest.php +++ b/tests/Tactician/CommandInflectorTest.php @@ -28,7 +28,7 @@ class CommandInflectorTest extends TestCase public function testInvalidCommand(): void { $this->expectException(InvalidCommandException::class); - $this->expectExceptionMessage('Command must implement Gears\CQRS\Command interface, string given'); + $this->expectExceptionMessage('Command must implement "Gears\CQRS\Command" interface, "string" given'); (new CommandInflector())->inflect('', ''); } @@ -37,7 +37,7 @@ public function testInvalidCommandHandler(): void { $this->expectException(InvalidCommandHandlerException::class); $this->expectExceptionMessage( - 'Command handler must implement Gears\CQRS\CommandHandler interface, string given' + 'Command handler must implement "Gears\CQRS\CommandHandler" interface, "string" given' ); (new CommandInflector())->inflect(CommandStub::instance(), ''); diff --git a/tests/Tactician/QueryExtractorTest.php b/tests/Tactician/QueryExtractorTest.php new file mode 100644 index 0000000..3e6bec5 --- /dev/null +++ b/tests/Tactician/QueryExtractorTest.php @@ -0,0 +1,40 @@ + + */ + +declare(strict_types=1); + +namespace Gears\CQRS\Tactician\Tests; + +use Gears\CQRS\Exception\InvalidQueryException; +use Gears\CQRS\Tactician\QueryExtractor; +use Gears\CQRS\Tactician\Tests\Stub\QueryStub; +use PHPUnit\Framework\TestCase; + +/** + * Query extractor test. + */ +class QueryExtractorTest extends TestCase +{ + public function testInvalidQuery(): void + { + $this->expectException(InvalidQueryException::class); + $this->expectExceptionMessage('Query must implement "Gears\CQRS\Query" interface, "stdClass" given'); + + (new QueryExtractor())->extract(new \stdClass()); + } + + public function testExtract(): void + { + $type = (new QueryExtractor())->extract(QueryStub::instance()); + + static::assertSame(QueryStub::class, $type); + } +} diff --git a/tests/Tactician/QueryInflectorTest.php b/tests/Tactician/QueryInflectorTest.php index 8f1bca3..1f43992 100644 --- a/tests/Tactician/QueryInflectorTest.php +++ b/tests/Tactician/QueryInflectorTest.php @@ -28,7 +28,7 @@ class QueryInflectorTest extends TestCase public function testInvalidCommand(): void { $this->expectException(InvalidQueryException::class); - $this->expectExceptionMessage('Query must implement Gears\CQRS\Query interface, string given'); + $this->expectExceptionMessage('Query must implement "Gears\CQRS\Query" interface, "string" given'); (new QueryInflector())->inflect('', ''); } @@ -36,7 +36,9 @@ public function testInvalidCommand(): void public function testInvalidCommandHandler(): void { $this->expectException(InvalidQueryHandlerException::class); - $this->expectExceptionMessage('Query handler must implement Gears\CQRS\QueryHandler interface, string given'); + $this->expectExceptionMessage( + 'Query handler must implement "Gears\CQRS\QueryHandler" interface, "string" given' + ); (new QueryInflector())->inflect(QueryStub::instance(), ''); }