RegisterServiceSubscribersPassTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DependencyInjection\Tests\Compiler;
  11. use PHPUnit\Framework\TestCase;
  12. use Psr\Container\ContainerInterface as PsrContainerInterface;
  13. use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
  14. use Symfony\Component\DependencyInjection\Compiler\RegisterServiceSubscribersPass;
  15. use Symfony\Component\DependencyInjection\Compiler\ResolveServiceSubscribersPass;
  16. use Symfony\Component\DependencyInjection\ContainerBuilder;
  17. use Symfony\Component\DependencyInjection\ContainerInterface;
  18. use Symfony\Component\DependencyInjection\Reference;
  19. use Symfony\Component\DependencyInjection\ServiceLocator;
  20. use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
  21. use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
  22. use Symfony\Component\DependencyInjection\TypedReference;
  23. require_once __DIR__.'/../Fixtures/includes/classes.php';
  24. class RegisterServiceSubscribersPassTest extends TestCase
  25. {
  26. /**
  27. * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
  28. * @expectedExceptionMessage Service "foo" must implement interface "Symfony\Component\DependencyInjection\ServiceSubscriberInterface".
  29. */
  30. public function testInvalidClass()
  31. {
  32. $container = new ContainerBuilder();
  33. $container->register('foo', CustomDefinition::class)
  34. ->addTag('container.service_subscriber')
  35. ;
  36. (new RegisterServiceSubscribersPass())->process($container);
  37. (new ResolveServiceSubscribersPass())->process($container);
  38. }
  39. /**
  40. * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
  41. * @expectedExceptionMessage The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "bar" given for service "foo".
  42. */
  43. public function testInvalidAttributes()
  44. {
  45. $container = new ContainerBuilder();
  46. $container->register('foo', TestServiceSubscriber::class)
  47. ->addTag('container.service_subscriber', array('bar' => '123'))
  48. ;
  49. (new RegisterServiceSubscribersPass())->process($container);
  50. (new ResolveServiceSubscribersPass())->process($container);
  51. }
  52. public function testNoAttributes()
  53. {
  54. $container = new ContainerBuilder();
  55. $container->register('foo', TestServiceSubscriber::class)
  56. ->addArgument(new Reference(PsrContainerInterface::class))
  57. ->addTag('container.service_subscriber')
  58. ;
  59. (new RegisterServiceSubscribersPass())->process($container);
  60. (new ResolveServiceSubscribersPass())->process($container);
  61. $foo = $container->getDefinition('foo');
  62. $locator = $container->getDefinition((string) $foo->getArgument(0));
  63. $this->assertFalse($locator->isPublic());
  64. $this->assertSame(ServiceLocator::class, $locator->getClass());
  65. $expected = array(
  66. TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class, TestServiceSubscriber::class)),
  67. CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
  68. 'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class)),
  69. 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
  70. );
  71. $this->assertEquals($expected, $locator->getArgument(0));
  72. }
  73. public function testWithAttributes()
  74. {
  75. $container = new ContainerBuilder();
  76. $container->register('foo', TestServiceSubscriber::class)
  77. ->setAutowired(true)
  78. ->addArgument(new Reference(PsrContainerInterface::class))
  79. ->addTag('container.service_subscriber', array('key' => 'bar', 'id' => 'bar'))
  80. ->addTag('container.service_subscriber', array('key' => 'bar', 'id' => 'baz')) // should be ignored: the first wins
  81. ;
  82. (new RegisterServiceSubscribersPass())->process($container);
  83. (new ResolveServiceSubscribersPass())->process($container);
  84. $foo = $container->getDefinition('foo');
  85. $locator = $container->getDefinition((string) $foo->getArgument(0));
  86. $this->assertFalse($locator->isPublic());
  87. $this->assertSame(ServiceLocator::class, $locator->getClass());
  88. $expected = array(
  89. TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class, TestServiceSubscriber::class)),
  90. CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
  91. 'bar' => new ServiceClosureArgument(new TypedReference('bar', CustomDefinition::class, TestServiceSubscriber::class)),
  92. 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
  93. );
  94. $this->assertEquals($expected, $locator->getArgument(0));
  95. }
  96. /**
  97. * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
  98. * @expectedExceptionMessage Service key "test" does not exist in the map returned by "Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber::getSubscribedServices()" for service "foo_service".
  99. */
  100. public function testExtraServiceSubscriber()
  101. {
  102. $container = new ContainerBuilder();
  103. $container->register('foo_service', TestServiceSubscriber::class)
  104. ->setAutowired(true)
  105. ->addArgument(new Reference(PsrContainerInterface::class))
  106. ->addTag('container.service_subscriber', array(
  107. 'key' => 'test',
  108. 'id' => TestServiceSubscriber::class,
  109. ))
  110. ;
  111. $container->register(TestServiceSubscriber::class, TestServiceSubscriber::class);
  112. $container->compile();
  113. }
  114. }