InlineServiceDefinitionsPassTest.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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 Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
  13. use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass;
  14. use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
  15. use Symfony\Component\DependencyInjection\ContainerBuilder;
  16. use Symfony\Component\DependencyInjection\Definition;
  17. use Symfony\Component\DependencyInjection\Reference;
  18. use Symfony\Component\DependencyInjection\Scope;
  19. class InlineServiceDefinitionsPassTest extends TestCase
  20. {
  21. public function testProcess()
  22. {
  23. $container = new ContainerBuilder();
  24. $container
  25. ->register('inlinable.service')
  26. ->setPublic(false)
  27. ;
  28. $container
  29. ->register('service')
  30. ->setArguments(array(new Reference('inlinable.service')))
  31. ;
  32. $this->process($container);
  33. $arguments = $container->getDefinition('service')->getArguments();
  34. $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]);
  35. $this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
  36. }
  37. public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
  38. {
  39. $container = new ContainerBuilder();
  40. $container
  41. ->register('foo')
  42. ->setPublic(false)
  43. ;
  44. $container->setAlias('moo', 'foo');
  45. $container
  46. ->register('service')
  47. ->setArguments(array($ref = new Reference('foo')))
  48. ;
  49. $this->process($container);
  50. $arguments = $container->getDefinition('service')->getArguments();
  51. $this->assertSame($ref, $arguments[0]);
  52. }
  53. /**
  54. * @group legacy
  55. */
  56. public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope()
  57. {
  58. $container = new ContainerBuilder();
  59. $container
  60. ->register('foo')
  61. ->setPublic(false)
  62. ;
  63. $container->setAlias('moo', 'foo');
  64. $container
  65. ->register('service')
  66. ->setArguments(array($ref = new Reference('foo')))
  67. ;
  68. $this->process($container);
  69. $arguments = $container->getDefinition('service')->getArguments();
  70. $this->assertSame($ref, $arguments[0]);
  71. }
  72. public function testProcessDoesInlineNonSharedService()
  73. {
  74. $container = new ContainerBuilder();
  75. $container
  76. ->register('foo')
  77. ->setShared(false)
  78. ;
  79. $container
  80. ->register('bar')
  81. ->setPublic(false)
  82. ->setShared(false)
  83. ;
  84. $container->setAlias('moo', 'bar');
  85. $container
  86. ->register('service')
  87. ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
  88. ;
  89. $this->process($container);
  90. $arguments = $container->getDefinition('service')->getArguments();
  91. $this->assertEquals($container->getDefinition('foo'), $arguments[0]);
  92. $this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
  93. $this->assertSame($ref, $arguments[1]);
  94. $this->assertEquals($container->getDefinition('bar'), $arguments[2]);
  95. $this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
  96. }
  97. /**
  98. * @group legacy
  99. */
  100. public function testProcessDoesInlineServiceOfPrototypeScope()
  101. {
  102. $container = new ContainerBuilder();
  103. $container
  104. ->register('foo')
  105. ->setScope('prototype')
  106. ;
  107. $container
  108. ->register('bar')
  109. ->setPublic(false)
  110. ->setScope('prototype')
  111. ;
  112. $container->setAlias('moo', 'bar');
  113. $container
  114. ->register('service')
  115. ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
  116. ;
  117. $this->process($container);
  118. $arguments = $container->getDefinition('service')->getArguments();
  119. $this->assertEquals($container->getDefinition('foo'), $arguments[0]);
  120. $this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
  121. $this->assertSame($ref, $arguments[1]);
  122. $this->assertEquals($container->getDefinition('bar'), $arguments[2]);
  123. $this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
  124. }
  125. public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition()
  126. {
  127. $container = new ContainerBuilder();
  128. $a = $container->register('a')->setPublic(false);
  129. $b = $container
  130. ->register('b')
  131. ->addArgument(new Reference('a'))
  132. ->addArgument(new Definition(null, array(new Reference('a'))))
  133. ;
  134. $this->process($container);
  135. $arguments = $b->getArguments();
  136. $this->assertSame($a, $arguments[0]);
  137. $inlinedArguments = $arguments[1]->getArguments();
  138. $this->assertSame($a, $inlinedArguments[0]);
  139. }
  140. public function testProcessInlinesPrivateFactoryReference()
  141. {
  142. $container = new ContainerBuilder();
  143. $container->register('a')->setPublic(false);
  144. $b = $container
  145. ->register('b')
  146. ->setPublic(false)
  147. ->setFactory(array(new Reference('a'), 'a'))
  148. ;
  149. $container
  150. ->register('foo')
  151. ->setArguments(array(
  152. $ref = new Reference('b'),
  153. ));
  154. $this->process($container);
  155. $inlinedArguments = $container->getDefinition('foo')->getArguments();
  156. $this->assertSame($b, $inlinedArguments[0]);
  157. }
  158. public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition()
  159. {
  160. $container = new ContainerBuilder();
  161. $container
  162. ->register('a')
  163. ;
  164. $container
  165. ->register('b')
  166. ->setPublic(false)
  167. ->setFactory(array(new Reference('a'), 'a'))
  168. ;
  169. $container
  170. ->register('foo')
  171. ->setArguments(array(
  172. $ref1 = new Reference('b'),
  173. $ref2 = new Reference('b'),
  174. ))
  175. ;
  176. $this->process($container);
  177. $args = $container->getDefinition('foo')->getArguments();
  178. $this->assertSame($ref1, $args[0]);
  179. $this->assertSame($ref2, $args[1]);
  180. }
  181. public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory()
  182. {
  183. $container = new ContainerBuilder();
  184. $container
  185. ->register('a')
  186. ;
  187. $container
  188. ->register('b')
  189. ->setPublic(false)
  190. ->setFactory(array(new Reference('a'), 'a'))
  191. ;
  192. $inlineFactory = new Definition();
  193. $inlineFactory->setPublic(false);
  194. $inlineFactory->setFactory(array(new Reference('b'), 'b'));
  195. $container
  196. ->register('foo')
  197. ->setArguments(array(
  198. $ref = new Reference('b'),
  199. $inlineFactory,
  200. ))
  201. ;
  202. $this->process($container);
  203. $args = $container->getDefinition('foo')->getArguments();
  204. $this->assertSame($ref, $args[0]);
  205. }
  206. /**
  207. * @group legacy
  208. */
  209. public function testProcessInlinesOnlyIfSameScope()
  210. {
  211. $container = new ContainerBuilder();
  212. $container->addScope(new Scope('foo'));
  213. $a = $container->register('a')->setPublic(false)->setScope('foo');
  214. $b = $container->register('b')->addArgument(new Reference('a'));
  215. $this->process($container);
  216. $arguments = $b->getArguments();
  217. $this->assertEquals(new Reference('a'), $arguments[0]);
  218. $this->assertTrue($container->hasDefinition('a'));
  219. }
  220. public function testProcessDoesNotInlineWhenServiceIsPrivateButLazy()
  221. {
  222. $container = new ContainerBuilder();
  223. $container
  224. ->register('foo')
  225. ->setPublic(false)
  226. ->setLazy(true)
  227. ;
  228. $container
  229. ->register('service')
  230. ->setArguments(array($ref = new Reference('foo')))
  231. ;
  232. $this->process($container);
  233. $arguments = $container->getDefinition('service')->getArguments();
  234. $this->assertSame($ref, $arguments[0]);
  235. }
  236. public function testProcessDoesNotInlineWhenServiceReferencesItself()
  237. {
  238. $container = new ContainerBuilder();
  239. $container
  240. ->register('foo')
  241. ->setPublic(false)
  242. ->addMethodCall('foo', array($ref = new Reference('foo')))
  243. ;
  244. $this->process($container);
  245. $calls = $container->getDefinition('foo')->getMethodCalls();
  246. $this->assertSame($ref, $calls[0][1][0]);
  247. }
  248. protected function process(ContainerBuilder $container)
  249. {
  250. $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()));
  251. $repeatedPass->process($container);
  252. }
  253. }