ServiceValueResolverTest.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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\HttpKernel\Tests\Controller\ArgumentResolver;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\DependencyInjection\ContainerBuilder;
  13. use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  14. use Symfony\Component\DependencyInjection\ServiceLocator;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ServiceValueResolver;
  17. use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
  18. use Symfony\Component\HttpKernel\DependencyInjection\RegisterControllerArgumentLocatorsPass;
  19. class ServiceValueResolverTest extends TestCase
  20. {
  21. public function testDoNotSupportWhenControllerDoNotExists()
  22. {
  23. $resolver = new ServiceValueResolver(new ServiceLocator([]));
  24. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  25. $request = $this->requestWithAttributes(['_controller' => 'my_controller']);
  26. $this->assertFalse($resolver->supports($request, $argument));
  27. }
  28. public function testExistingController()
  29. {
  30. $resolver = new ServiceValueResolver(new ServiceLocator([
  31. 'App\\Controller\\Mine::method' => function () {
  32. return new ServiceLocator([
  33. 'dummy' => function () {
  34. return new DummyService();
  35. },
  36. ]);
  37. },
  38. ]));
  39. $request = $this->requestWithAttributes(['_controller' => 'App\\Controller\\Mine::method']);
  40. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  41. $this->assertTrue($resolver->supports($request, $argument));
  42. $this->assertYieldEquals([new DummyService()], $resolver->resolve($request, $argument));
  43. }
  44. public function testExistingControllerWithATrailingBackSlash()
  45. {
  46. $resolver = new ServiceValueResolver(new ServiceLocator([
  47. 'App\\Controller\\Mine::method' => function () {
  48. return new ServiceLocator([
  49. 'dummy' => function () {
  50. return new DummyService();
  51. },
  52. ]);
  53. },
  54. ]));
  55. $request = $this->requestWithAttributes(['_controller' => '\\App\\Controller\\Mine::method']);
  56. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  57. $this->assertTrue($resolver->supports($request, $argument));
  58. $this->assertYieldEquals([new DummyService()], $resolver->resolve($request, $argument));
  59. }
  60. public function testExistingControllerWithMethodNameStartUppercase()
  61. {
  62. $resolver = new ServiceValueResolver(new ServiceLocator([
  63. 'App\\Controller\\Mine::method' => function () {
  64. return new ServiceLocator([
  65. 'dummy' => function () {
  66. return new DummyService();
  67. },
  68. ]);
  69. },
  70. ]));
  71. $request = $this->requestWithAttributes(['_controller' => 'App\\Controller\\Mine::Method']);
  72. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  73. $this->assertTrue($resolver->supports($request, $argument));
  74. $this->assertYieldEquals([new DummyService()], $resolver->resolve($request, $argument));
  75. }
  76. public function testControllerNameIsAnArray()
  77. {
  78. $resolver = new ServiceValueResolver(new ServiceLocator([
  79. 'App\\Controller\\Mine::method' => function () {
  80. return new ServiceLocator([
  81. 'dummy' => function () {
  82. return new DummyService();
  83. },
  84. ]);
  85. },
  86. ]));
  87. $request = $this->requestWithAttributes(['_controller' => ['App\\Controller\\Mine', 'method']]);
  88. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  89. $this->assertTrue($resolver->supports($request, $argument));
  90. $this->assertYieldEquals([new DummyService()], $resolver->resolve($request, $argument));
  91. }
  92. public function testErrorIsTruncated()
  93. {
  94. $this->expectException(RuntimeException::class);
  95. $this->expectExceptionMessage('Cannot autowire argument $dummy of "Symfony\Component\HttpKernel\Tests\Controller\ArgumentResolver\DummyController::index()": it references class "Symfony\Component\HttpKernel\Tests\Controller\ArgumentResolver\DummyService" but no such service exists.');
  96. $container = new ContainerBuilder();
  97. $container->addCompilerPass(new RegisterControllerArgumentLocatorsPass());
  98. $container->register('argument_resolver.service', ServiceValueResolver::class)->addArgument(null)->setPublic(true);
  99. $container->register(DummyController::class)->addTag('controller.service_arguments')->setPublic(true);
  100. $container->compile();
  101. $request = $this->requestWithAttributes(['_controller' => [DummyController::class, 'index']]);
  102. $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
  103. $container->get('argument_resolver.service')->resolve($request, $argument)->current();
  104. }
  105. private function requestWithAttributes(array $attributes)
  106. {
  107. $request = Request::create('/');
  108. foreach ($attributes as $name => $value) {
  109. $request->attributes->set($name, $value);
  110. }
  111. return $request;
  112. }
  113. private function assertYieldEquals(array $expected, \Generator $generator)
  114. {
  115. $args = [];
  116. foreach ($generator as $arg) {
  117. $args[] = $arg;
  118. }
  119. $this->assertEquals($expected, $args);
  120. }
  121. }
  122. class DummyService
  123. {
  124. }
  125. class DummyController
  126. {
  127. public function index(DummyService $dummy)
  128. {
  129. }
  130. }