CheckCircularReferencesPassTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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\Argument\IteratorArgument;
  13. use Symfony\Component\DependencyInjection\Reference;
  14. use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
  15. use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
  16. use Symfony\Component\DependencyInjection\Compiler\Compiler;
  17. use Symfony\Component\DependencyInjection\ContainerBuilder;
  18. class CheckCircularReferencesPassTest extends TestCase
  19. {
  20. /**
  21. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  22. */
  23. public function testProcess()
  24. {
  25. $container = new ContainerBuilder();
  26. $container->register('a')->addArgument(new Reference('b'));
  27. $container->register('b')->addArgument(new Reference('a'));
  28. $this->process($container);
  29. }
  30. /**
  31. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  32. */
  33. public function testProcessWithAliases()
  34. {
  35. $container = new ContainerBuilder();
  36. $container->register('a')->addArgument(new Reference('b'));
  37. $container->setAlias('b', 'c');
  38. $container->setAlias('c', 'a');
  39. $this->process($container);
  40. }
  41. /**
  42. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  43. */
  44. public function testProcessWithFactory()
  45. {
  46. $container = new ContainerBuilder();
  47. $container
  48. ->register('a', 'stdClass')
  49. ->setFactory(array(new Reference('b'), 'getInstance'));
  50. $container
  51. ->register('b', 'stdClass')
  52. ->setFactory(array(new Reference('a'), 'getInstance'));
  53. $this->process($container);
  54. }
  55. /**
  56. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  57. */
  58. public function testProcessDetectsIndirectCircularReference()
  59. {
  60. $container = new ContainerBuilder();
  61. $container->register('a')->addArgument(new Reference('b'));
  62. $container->register('b')->addArgument(new Reference('c'));
  63. $container->register('c')->addArgument(new Reference('a'));
  64. $this->process($container);
  65. }
  66. /**
  67. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  68. */
  69. public function testProcessDetectsIndirectCircularReferenceWithFactory()
  70. {
  71. $container = new ContainerBuilder();
  72. $container->register('a')->addArgument(new Reference('b'));
  73. $container
  74. ->register('b', 'stdClass')
  75. ->setFactory(array(new Reference('c'), 'getInstance'));
  76. $container->register('c')->addArgument(new Reference('a'));
  77. $this->process($container);
  78. }
  79. /**
  80. * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
  81. */
  82. public function testDeepCircularReference()
  83. {
  84. $container = new ContainerBuilder();
  85. $container->register('a')->addArgument(new Reference('b'));
  86. $container->register('b')->addArgument(new Reference('c'));
  87. $container->register('c')->addArgument(new Reference('b'));
  88. $this->process($container);
  89. }
  90. public function testProcessIgnoresMethodCalls()
  91. {
  92. $container = new ContainerBuilder();
  93. $container->register('a')->addArgument(new Reference('b'));
  94. $container->register('b')->addMethodCall('setA', array(new Reference('a')));
  95. $this->process($container);
  96. $this->addToAssertionCount(1);
  97. }
  98. public function testProcessIgnoresLazyServices()
  99. {
  100. $container = new ContainerBuilder();
  101. $container->register('a')->setLazy(true)->addArgument(new Reference('b'));
  102. $container->register('b')->addArgument(new Reference('a'));
  103. $this->process($container);
  104. // just make sure that a lazily loaded service does not trigger a CircularReferenceException
  105. $this->addToAssertionCount(1);
  106. }
  107. public function testProcessIgnoresIteratorArguments()
  108. {
  109. $container = new ContainerBuilder();
  110. $container->register('a')->addArgument(new Reference('b'));
  111. $container->register('b')->addArgument(new IteratorArgument(array(new Reference('a'))));
  112. $this->process($container);
  113. // just make sure that an IteratorArgument does not trigger a CircularReferenceException
  114. $this->addToAssertionCount(1);
  115. }
  116. protected function process(ContainerBuilder $container)
  117. {
  118. $compiler = new Compiler();
  119. $passConfig = $compiler->getPassConfig();
  120. $passConfig->setOptimizationPasses(array(
  121. new AnalyzeServiceReferencesPass(true),
  122. new CheckCircularReferencesPass(),
  123. ));
  124. $passConfig->setRemovingPasses(array());
  125. $compiler->compile($container);
  126. }
  127. }