diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index d38ddc7e6d88f..981823fd07f10 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -29,6 +29,7 @@ CHANGELOG * Added support for PHP files with translations in translation commands. * Added support for boolean container parameters within routes. * Added the `messenger:setup-transports` command to setup messenger transports + * Added a `InMemoryTransport` to Messenger. Use it with a DSN starting with `in-memory://`. 4.2.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml index 1720ea72e71aa..4f677d40918a8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml @@ -70,6 +70,11 @@ + + + + + diff --git a/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportFactoryTest.php b/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportFactoryTest.php new file mode 100644 index 0000000000000..856c865f1ea31 --- /dev/null +++ b/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportFactoryTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; +use Symfony\Component\Messenger\Transport\InMemoryTransport; +use Symfony\Component\Messenger\Transport\InMemoryTransportFactory; +use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface; + +/** + * @internal + * + * @author Gary PEGEOT + */ +class InMemoryTransportFactoryTest extends TestCase +{ + /** + * @var InMemoryTransportFactory + */ + private $factory; + + protected function setUp() + { + $this->factory = new InMemoryTransportFactory(); + } + + /** + * @param string $dsn + * @param bool $expected + * + * @dataProvider provideDSN + */ + public function testSupports(string $dsn, bool $expected = true) + { + $this->assertSame($expected, $this->factory->supports($dsn, []), 'InMemoryTransportFactory::supports returned unexpected result.'); + } + + public function testCreateTransport() + { + /** @var SerializerInterface $serializer */ + $serializer = $this->createMock(SerializerInterface::class); + + $this->assertInstanceOf(InMemoryTransport::class, $this->factory->createTransport('in-memory://', [], $serializer)); + } + + public function testResetCreatedTransports() + { + $transport = $this->factory->createTransport('in-memory://', [], $this->createMock(SerializerInterface::class)); + $transport->send(Envelope::wrap(new DummyMessage('Hello.'))); + + $this->assertCount(1, $transport->get()); + $this->factory->reset(); + $this->assertCount(0, $transport->get()); + } + + public function provideDSN(): array + { + return [ + 'Supported' => ['in-memory://foo'], + 'Unsupported' => ['amqp://bar', false], + ]; + } +} diff --git a/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportTest.php b/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportTest.php new file mode 100644 index 0000000000000..8b5634b3f616a --- /dev/null +++ b/src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Transport\InMemoryTransport; + +/** + * @internal + * + * @author Gary PEGEOT + */ +class InMemoryTransportTest extends TestCase +{ + /** + * @var InMemoryTransport + */ + private $transport; + + protected function setUp() + { + $this->transport = new InMemoryTransport(); + } + + public function testSend() + { + $envelope = new Envelope(new \stdClass()); + $this->transport->send($envelope); + $this->assertSame([$envelope], $this->transport->get()); + } + + public function testAck() + { + $envelope = new Envelope(new \stdClass()); + $this->transport->ack($envelope); + $this->assertSame([$envelope], $this->transport->getAcknowledged()); + } + + public function testReject() + { + $envelope = new Envelope(new \stdClass()); + $this->transport->reject($envelope); + $this->assertSame([$envelope], $this->transport->getRejected()); + } + + public function testReset() + { + $envelope = new Envelope(new \stdClass()); + $this->transport->send($envelope); + $this->transport->ack($envelope); + $this->transport->reject($envelope); + + $this->transport->reset(); + + $this->assertEmpty($this->transport->get(), 'Should be empty after reset'); + $this->assertEmpty($this->transport->getAcknowledged(), 'Should be empty after reset'); + $this->assertEmpty($this->transport->getRejected(), 'Should be empty after reset'); + } +} diff --git a/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php b/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php new file mode 100644 index 0000000000000..a21d67bd1982b --- /dev/null +++ b/src/Symfony/Component/Messenger/Transport/InMemoryTransport.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Transport; + +use Symfony\Component\Messenger\Envelope; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Transport that stay in memory. Useful for testing purpose. + * + * @author Gary PEGEOT + * + * @experimental in 4.3 + */ +class InMemoryTransport implements TransportInterface, ResetInterface +{ + /** + * @var Envelope[] + */ + private $sent = []; + + /** + * @var Envelope[] + */ + private $acknowledged = []; + + /** + * @var Envelope[] + */ + private $rejected = []; + + /** + * {@inheritdoc} + */ + public function get(): iterable + { + return $this->sent; + } + + /** + * {@inheritdoc} + */ + public function ack(Envelope $envelope): void + { + $this->acknowledged[] = $envelope; + } + + /** + * {@inheritdoc} + */ + public function reject(Envelope $envelope): void + { + $this->rejected[] = $envelope; + } + + /** + * {@inheritdoc} + */ + public function send(Envelope $envelope): Envelope + { + $this->sent[] = $envelope; + + return $envelope; + } + + public function reset() + { + $this->sent = $this->rejected = $this->acknowledged = []; + } + + /** + * @return Envelope[] + */ + public function getAcknowledged(): array + { + return $this->acknowledged; + } + + /** + * @return Envelope[] + */ + public function getRejected(): array + { + return $this->rejected; + } +} diff --git a/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php b/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php new file mode 100644 index 0000000000000..e7088e67052ca --- /dev/null +++ b/src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Transport; + +use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Gary PEGEOT + * + * @experimental in 4.3 + */ +class InMemoryTransportFactory implements TransportFactoryInterface, ResetInterface +{ + /** + * @var InMemoryTransport[] + */ + private $createdTransports = []; + + public function createTransport(string $dsn, array $options, SerializerInterface $serializer): TransportInterface + { + return $this->createdTransports[] = new InMemoryTransport(); + } + + public function supports(string $dsn, array $options): bool + { + return 0 === strpos($dsn, 'in-memory://'); + } + + public function reset() + { + foreach ($this->createdTransports as $transport) { + $transport->reset(); + } + } +}