From 0f319a435196bed6f512c47d6521b5a239b4825a Mon Sep 17 00:00:00 2001 From: Daniel Gimenes Date: Fri, 3 Nov 2017 16:35:56 -0200 Subject: [PATCH] Add query bus --- config/container.config.php | 5 ++ src/CommandBusInterface.php | 2 +- src/Container/SimpleQueryBusFactory.php | 26 ++++++++ src/MessageBusInterface.php | 16 +++++ src/QueryBusInterface.php | 16 +++++ src/SimpleQueryBus.php | 56 +++++++++++++++++ test/Asset/TestQuery.php | 10 +++ test/Asset/TestQueryHandler.php | 14 +++++ test/Container/SimpleQueryBusFactoryTest.php | 36 +++++++++++ test/SimpleQueryBusTest.php | 66 ++++++++++++++++++++ 10 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 src/Container/SimpleQueryBusFactory.php create mode 100644 src/MessageBusInterface.php create mode 100644 src/QueryBusInterface.php create mode 100644 src/SimpleQueryBus.php create mode 100644 test/Asset/TestQuery.php create mode 100644 test/Asset/TestQueryHandler.php create mode 100644 test/Container/SimpleQueryBusFactoryTest.php create mode 100644 test/SimpleQueryBusTest.php diff --git a/config/container.config.php b/config/container.config.php index 03b9819..38896fe 100644 --- a/config/container.config.php +++ b/config/container.config.php @@ -2,16 +2,21 @@ use ZfrCommandBus\CommandBusInterface; use ZfrCommandBus\Container\SimpleCommandBusFactory; +use ZfrCommandBus\Container\SimpleQueryBusFactory; +use ZfrCommandBus\QueryBusInterface; use ZfrCommandBus\SimpleCommandBus; +use ZfrCommandBus\SimpleQueryBus; return [ 'dependencies' => [ 'aliases' => [ CommandBusInterface::class => SimpleCommandBus::class, + QueryBusInterface::class => SimpleQueryBus::class, ], 'factories' => [ SimpleCommandBus::class => SimpleCommandBusFactory::class, + SimpleQueryBus::class => SimpleQueryBusFactory::class, ], ] ]; diff --git a/src/CommandBusInterface.php b/src/CommandBusInterface.php index 281ad0b..bf5b000 100644 --- a/src/CommandBusInterface.php +++ b/src/CommandBusInterface.php @@ -2,7 +2,7 @@ namespace ZfrCommandBus; -interface CommandBusInterface +interface CommandBusInterface extends MessageBusInterface { /** * @param object $command diff --git a/src/Container/SimpleQueryBusFactory.php b/src/Container/SimpleQueryBusFactory.php new file mode 100644 index 0000000..fb8c592 --- /dev/null +++ b/src/Container/SimpleQueryBusFactory.php @@ -0,0 +1,26 @@ +get('config'); + + return new SimpleQueryBus($container, $config['zfr_command_bus']['query_handlers'] ?? []); + } +} diff --git a/src/MessageBusInterface.php b/src/MessageBusInterface.php new file mode 100644 index 0000000..3dc57cc --- /dev/null +++ b/src/MessageBusInterface.php @@ -0,0 +1,16 @@ +container = $container; + $this->queryMap = $queryMap; + } + + /** + * {@inheritDoc} + * + * @throws RuntimeException + */ + public function dispatch($query): array + { + if (!is_object($query)) { + throw new InvalidArgumentException(sprintf( + '$query must be an object, %s given', + gettype($query) + )); + } + + $queryClass = get_class($query); + $queryHandlerName = $this->queryMap[$queryClass] ?? "{$queryClass}Handler"; + $queryHandler = $this->container->get($queryHandlerName); + + assert(is_callable($queryHandler), 'Make sure your query handler is callable'); + + return $queryHandler($query); + } +} diff --git a/test/Asset/TestQuery.php b/test/Asset/TestQuery.php new file mode 100644 index 0000000..24586d1 --- /dev/null +++ b/test/Asset/TestQuery.php @@ -0,0 +1,10 @@ + 'bar']; + } +} diff --git a/test/Container/SimpleQueryBusFactoryTest.php b/test/Container/SimpleQueryBusFactoryTest.php new file mode 100644 index 0000000..e5da113 --- /dev/null +++ b/test/Container/SimpleQueryBusFactoryTest.php @@ -0,0 +1,36 @@ +prophesize(ContainerInterface::class); + $factory = new SimpleQueryBusFactory(); + + $container->get('config')->shouldBeCalled()->willReturn([]); + + $factory($container->reveal()); + } + + public function testCreatesInstanceOfSimpleQueryBus() + { + $container = $this->prophesize(ContainerInterface::class); + $factory = new SimpleQueryBusFactory(); + + $container->get('config')->shouldBeCalled()->willReturn([ + 'zfr_command_bus' => [ + 'query_handlers' => [], + ], + ]); + + $factory($container->reveal()); + } +} diff --git a/test/SimpleQueryBusTest.php b/test/SimpleQueryBusTest.php new file mode 100644 index 0000000..8225ebf --- /dev/null +++ b/test/SimpleQueryBusTest.php @@ -0,0 +1,66 @@ +container = $this->prophesize(ContainerInterface::class); + $this->queryHandler = function (stdClass $query) { + return ['foo' => 'bar']; + }; + } + + public function testThrowsExceptionIfInvalidQueryType() + { + $queryBus = new SimpleQueryBus($this->container->reveal()); + + $this->setExpectedException(InvalidArgumentException::class); + + $queryBus->dispatch('string'); + } + + public function testDispatchesQueryToMappedQueryHandler() + { + $queryBus = new SimpleQueryBus($this->container->reveal(), [stdClass::class => 'My\TestQueryHandler']); + + $this->container->get('My\TestQueryHandler')->shouldBeCalled()->willReturn($this->queryHandler); + + $result = $queryBus->dispatch(new stdClass()); + + $this->assertSame(['foo' => 'bar'], $result); + } + + public function testTriesToGuessQueryHandlerNameWithSuffix() + { + $queryBus = new SimpleQueryBus($this->container->reveal()); + + $this->container->get(TestQueryHandler::class)->shouldBeCalled()->willReturn(new TestQueryHandler()); + + $result = $queryBus->dispatch(new TestQuery()); + + $this->assertSame(['foo' => 'bar'], $result); + } +}