123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- <?php
- /**
- * @file
- * Contains \Drupal\Tests\Core\DependencyInjection\Compiler\TaggedHandlersPassTest.
- */
- namespace Drupal\Tests\Core\DependencyInjection\Compiler;
- use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
- use Drupal\Tests\UnitTestCase;
- use Symfony\Component\DependencyInjection\ContainerBuilder;
- use Symfony\Component\DependencyInjection\Exception\LogicException;
- use Symfony\Component\DependencyInjection\Reference;
- /**
- * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass
- * @group DependencyInjection
- */
- class TaggedHandlersPassTest extends UnitTestCase {
- protected function buildContainer($environment = 'dev') {
- $container = new ContainerBuilder();
- $container->setParameter('kernel.environment', $environment);
- return $container;
- }
- /**
- * Tests without any consumers.
- *
- * @covers ::process
- */
- public function testProcessNoConsumers() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer');
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $this->assertCount(2, $container->getDefinitions());
- $this->assertFalse($container->getDefinition('consumer_id')->hasMethodCall('addHandler'));
- }
- /**
- * Tests a required consumer with no handlers.
- *
- * @covers ::process
- */
- public function testProcessRequiredHandlers() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector', [
- 'required' => TRUE,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $this->expectException(LogicException::class);
- $this->expectExceptionMessage("At least one service tagged with 'consumer_id' is required.");
- $handler_pass->process($container);
- }
- /**
- * Tests a required consumer with no handlers.
- *
- * @covers ::process
- * @covers ::processServiceIdCollectorPass
- */
- public function testIdCollectorProcessRequiredHandlers() {
- $this->expectException(LogicException::class);
- $this->expectExceptionMessage("At least one service tagged with 'consumer_id' is required.");
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_id_collector', [
- 'required' => TRUE,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- }
- /**
- * Tests consumer with missing interface in non-production environment.
- *
- * @covers ::process
- */
- public function testProcessMissingInterface() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id0', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector');
- $container
- ->register('consumer_id1', __NAMESPACE__ . '\InvalidConsumer')
- ->addTag('service_collector');
- $handler_pass = new TaggedHandlersPass();
- $this->expectException(LogicException::class);
- $this->expectExceptionMessage("Service consumer 'consumer_id1' class method Drupal\Tests\Core\DependencyInjection\Compiler\InvalidConsumer::addHandler() has to type-hint an interface.");
- $handler_pass->process($container);
- }
- /**
- * Tests one consumer and two handlers.
- *
- * @covers ::process
- */
- public function testProcess() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(2, $method_calls);
- }
- /**
- * Tests one consumer and two handlers with service ID collection.
- *
- * @covers ::process
- */
- public function testserviceIdProcess() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_id_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $arguments = $container->getDefinition('consumer_id')->getArguments();
- $this->assertCount(1, $arguments);
- $this->assertCount(2, $arguments[0]);
- }
- /**
- * Tests handler priority sorting.
- *
- * @covers ::process
- */
- public function testProcessPriority() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 10,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(2, $method_calls);
- $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
- $this->assertEquals(10, $method_calls[0][1][1]);
- $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
- $this->assertEquals(0, $method_calls[1][1][1]);
- }
- /**
- * Tests handler priority sorting for service ID collection.
- *
- * @covers ::process
- */
- public function testserviceIdProcessPriority() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_id_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 20,
- ]);
- $container
- ->register('handler3', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 10,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $arguments = $container->getDefinition('consumer_id')->getArguments();
- $this->assertCount(1, $arguments);
- $this->assertSame(['handler2', 'handler3', 'handler1'], $arguments[0]);
- }
- /**
- * Tests consumer method without priority parameter.
- *
- * @covers ::process
- */
- public function testProcessNoPriorityParam() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector', [
- 'call' => 'addNoPriority',
- ]);
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 10,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(2, $method_calls);
- $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
- $this->assertCount(1, $method_calls[0][1]);
- $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
- $this->assertCount(1, $method_calls[0][1]);
- }
- /**
- * Tests consumer method with an ID parameter.
- *
- * @covers ::process
- */
- public function testProcessWithIdParameter() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector', [
- 'call' => 'addWithId',
- ]);
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 10,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(2, $method_calls);
- $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
- $this->assertEquals('handler2', $method_calls[0][1][1]);
- $this->assertEquals(10, $method_calls[0][1][2]);
- $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
- $this->assertEquals('handler1', $method_calls[1][1][1]);
- $this->assertEquals(0, $method_calls[1][1][2]);
- }
- /**
- * Tests interface validation in non-production environment.
- *
- * @covers ::process
- */
- public function testProcessInterfaceMismatch() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
- ->addTag('service_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\InvalidHandler')
- ->addTag('consumer_id');
- $container
- ->register('handler2', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 10,
- ]);
- $handler_pass = new TaggedHandlersPass();
- $this->expectException(LogicException::class);
- $handler_pass->process($container);
- }
- /**
- * Tests consumer method with extra parameters.
- *
- * @covers ::process
- */
- public function testProcessWithExtraArguments() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
- ->addTag('service_collector');
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'extra1' => 'extra1',
- 'extra2' => 'extra2',
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(4, $method_calls[0][1]);
- $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
- $this->assertEquals(0, $method_calls[0][1][1]);
- $this->assertEquals('extra1', $method_calls[0][1][2]);
- $this->assertEquals('extra2', $method_calls[0][1][3]);
- }
- /**
- * Tests consumer method with extra parameters and no priority.
- *
- * @covers ::process
- */
- public function testProcessNoPriorityAndExtraArguments() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
- ->addTag('service_collector', [
- 'call' => 'addNoPriority',
- ]);
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'extra' => 'extra',
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(2, $method_calls[0][1]);
- $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
- $this->assertEquals('extra', $method_calls[0][1][1]);
- }
- /**
- * Tests consumer method with priority, id and extra parameters.
- *
- * @covers ::process
- */
- public function testProcessWithIdAndExtraArguments() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
- ->addTag('service_collector', [
- 'call' => 'addWithId',
- ]);
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'extra1' => 'extra1',
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(5, $method_calls[0][1]);
- $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
- $this->assertEquals('handler1', $method_calls[0][1][1]);
- $this->assertEquals(0, $method_calls[0][1][2]);
- $this->assertEquals('extra1', $method_calls[0][1][3]);
- $this->assertNull($method_calls[0][1][4]);
- }
- /**
- * Tests consumer method with priority and extra parameters in different order.
- *
- * @covers ::process
- */
- public function testProcessWithDifferentArgumentsOrderAndDefaultValue() {
- $container = $this->buildContainer();
- $container
- ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
- ->addTag('service_collector', [
- 'call' => 'addWithDifferentOrder',
- ]);
- $container
- ->register('handler1', __NAMESPACE__ . '\ValidHandler')
- ->addTag('consumer_id', [
- 'priority' => 0,
- 'extra1' => 'extra1',
- 'extra3' => 'extra3',
- ]);
- $handler_pass = new TaggedHandlersPass();
- $handler_pass->process($container);
- $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
- $this->assertCount(5, $method_calls[0][1]);
- $expected = [new Reference('handler1'), 'extra1', 0, 'default2', 'extra3'];
- $this->assertEquals($expected, array_values($method_calls[0][1]));
- }
- }
- interface HandlerInterface {
- }
- class ValidConsumer {
- public function addHandler(HandlerInterface $instance, $priority = 0) {
- }
- public function addNoPriority(HandlerInterface $instance) {
- }
- public function addWithId(HandlerInterface $instance, $id, $priority = 0) {
- }
- }
- class InvalidConsumer {
- public function addHandler($instance, $priority = 0) {
- }
- }
- class ValidConsumerWithExtraArguments {
- public function addHandler(HandlerInterface $instance, $priority = 0, $extra1 = '', $extra2 = '') {
- }
- public function addNoPriority(HandlerInterface $instance, $extra) {
- }
- public function addWithId(HandlerInterface $instance, $id, $priority = 0, $extra1 = '', $extra2 = NULL) {
- }
- public function addWithDifferentOrder(HandlerInterface $instance, $extra1, $priority = 0, $extra2 = 'default2', $extra3 = 'default3') {
- }
- }
- class ValidHandler implements HandlerInterface {
- }
- class InvalidHandler {
- }
|