/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/TaggedHandlersPassTest.php

https://gitlab.com/reasonat/test8 · PHP · 383 lines · 254 code · 56 blank · 73 comment · 0 complexity · b4e8b4b99718f9b54d9a230dc47de832 MD5 · raw file

  1. <?php
  2. /**
  3. * @file
  4. * Contains \Drupal\Tests\Core\DependencyInjection\Compiler\TaggedHandlersPassTest.
  5. */
  6. namespace Drupal\Tests\Core\DependencyInjection\Compiler;
  7. use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
  8. use Drupal\Tests\UnitTestCase;
  9. use Symfony\Component\DependencyInjection\ContainerBuilder;
  10. use Symfony\Component\DependencyInjection\Reference;
  11. /**
  12. * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass
  13. * @group DependencyInjection
  14. */
  15. class TaggedHandlersPassTest extends UnitTestCase {
  16. protected function buildContainer($environment = 'dev') {
  17. $container = new ContainerBuilder();
  18. $container->setParameter('kernel.environment', $environment);
  19. return $container;
  20. }
  21. /**
  22. * Tests without any consumers.
  23. *
  24. * @covers ::process
  25. */
  26. public function testProcessNoConsumers() {
  27. $container = $this->buildContainer();
  28. $container
  29. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer');
  30. $handler_pass = new TaggedHandlersPass();
  31. $handler_pass->process($container);
  32. $this->assertCount(1, $container->getDefinitions());
  33. $this->assertFalse($container->getDefinition('consumer_id')->hasMethodCall('addHandler'));
  34. }
  35. /**
  36. * Tests a required consumer with no handlers.
  37. *
  38. * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
  39. * @expectedExceptionMessage At least one service tagged with 'consumer_id' is required.
  40. * @covers ::process
  41. */
  42. public function testProcessRequiredHandlers() {
  43. $container = $this->buildContainer();
  44. $container
  45. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  46. ->addTag('service_collector', array(
  47. 'required' => TRUE,
  48. ));
  49. $handler_pass = new TaggedHandlersPass();
  50. $handler_pass->process($container);
  51. }
  52. /**
  53. * Tests consumer with missing interface in non-production environment.
  54. *
  55. * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
  56. * @expectedExceptionMessage Service consumer 'consumer_id' class method Drupal\Tests\Core\DependencyInjection\Compiler\InvalidConsumer::addHandler() has to type-hint an interface.
  57. * @covers ::process
  58. */
  59. public function testProcessMissingInterface() {
  60. $container = $this->buildContainer();
  61. $container
  62. ->register('consumer_id', __NAMESPACE__ . '\InvalidConsumer')
  63. ->addTag('service_collector');
  64. $handler_pass = new TaggedHandlersPass();
  65. $handler_pass->process($container);
  66. }
  67. /**
  68. * Tests one consumer and two handlers.
  69. *
  70. * @covers ::process
  71. */
  72. public function testProcess() {
  73. $container = $this->buildContainer();
  74. $container
  75. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  76. ->addTag('service_collector');
  77. $container
  78. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  79. ->addTag('consumer_id');
  80. $container
  81. ->register('handler2', __NAMESPACE__ . '\ValidHandler')
  82. ->addTag('consumer_id');
  83. $handler_pass = new TaggedHandlersPass();
  84. $handler_pass->process($container);
  85. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  86. $this->assertCount(2, $method_calls);
  87. }
  88. /**
  89. * Tests handler priority sorting.
  90. *
  91. * @covers ::process
  92. */
  93. public function testProcessPriority() {
  94. $container = $this->buildContainer();
  95. $container
  96. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  97. ->addTag('service_collector');
  98. $container
  99. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  100. ->addTag('consumer_id');
  101. $container
  102. ->register('handler2', __NAMESPACE__ . '\ValidHandler')
  103. ->addTag('consumer_id', array(
  104. 'priority' => 10,
  105. ));
  106. $handler_pass = new TaggedHandlersPass();
  107. $handler_pass->process($container);
  108. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  109. $this->assertCount(2, $method_calls);
  110. $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
  111. $this->assertEquals(10, $method_calls[0][1][1]);
  112. $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
  113. $this->assertEquals(0, $method_calls[1][1][1]);
  114. }
  115. /**
  116. * Tests consumer method without priority parameter.
  117. *
  118. * @covers ::process
  119. */
  120. public function testProcessNoPriorityParam() {
  121. $container = $this->buildContainer();
  122. $container
  123. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  124. ->addTag('service_collector', array(
  125. 'call' => 'addNoPriority',
  126. ));
  127. $container
  128. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  129. ->addTag('consumer_id');
  130. $container
  131. ->register('handler2', __NAMESPACE__ . '\ValidHandler')
  132. ->addTag('consumer_id', array(
  133. 'priority' => 10,
  134. ));
  135. $handler_pass = new TaggedHandlersPass();
  136. $handler_pass->process($container);
  137. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  138. $this->assertCount(2, $method_calls);
  139. $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
  140. $this->assertCount(1, $method_calls[0][1]);
  141. $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
  142. $this->assertCount(1, $method_calls[0][1]);
  143. }
  144. /**
  145. * Tests consumer method with an ID parameter.
  146. *
  147. * @covers ::process
  148. */
  149. public function testProcessWithIdParameter() {
  150. $container = $this->buildContainer();
  151. $container
  152. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  153. ->addTag('service_collector', array(
  154. 'call' => 'addWithId',
  155. ));
  156. $container
  157. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  158. ->addTag('consumer_id');
  159. $container
  160. ->register('handler2', __NAMESPACE__ . '\ValidHandler')
  161. ->addTag('consumer_id', array(
  162. 'priority' => 10,
  163. ));
  164. $handler_pass = new TaggedHandlersPass();
  165. $handler_pass->process($container);
  166. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  167. $this->assertCount(2, $method_calls);
  168. $this->assertEquals(new Reference('handler2'), $method_calls[0][1][0]);
  169. $this->assertEquals('handler2', $method_calls[0][1][1]);
  170. $this->assertEquals(10, $method_calls[0][1][2]);
  171. $this->assertEquals(new Reference('handler1'), $method_calls[1][1][0]);
  172. $this->assertEquals('handler1', $method_calls[1][1][1]);
  173. $this->assertEquals(0, $method_calls[1][1][2]);
  174. }
  175. /**
  176. * Tests interface validation in non-production environment.
  177. *
  178. * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
  179. * @covers ::process
  180. */
  181. public function testProcessInterfaceMismatch() {
  182. $container = $this->buildContainer();
  183. $container
  184. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumer')
  185. ->addTag('service_collector');
  186. $container
  187. ->register('handler1', __NAMESPACE__ . '\InvalidHandler')
  188. ->addTag('consumer_id');
  189. $container
  190. ->register('handler2', __NAMESPACE__ . '\ValidHandler')
  191. ->addTag('consumer_id', array(
  192. 'priority' => 10,
  193. ));
  194. $handler_pass = new TaggedHandlersPass();
  195. $handler_pass->process($container);
  196. }
  197. /**
  198. * Tests consumer method with extra parameters.
  199. *
  200. * @covers ::process
  201. */
  202. public function testProcessWithExtraArguments() {
  203. $container = $this->buildContainer();
  204. $container
  205. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
  206. ->addTag('service_collector');
  207. $container
  208. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  209. ->addTag('consumer_id', array(
  210. 'extra1' => 'extra1',
  211. 'extra2' => 'extra2',
  212. ));
  213. $handler_pass = new TaggedHandlersPass();
  214. $handler_pass->process($container);
  215. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  216. $this->assertCount(4, $method_calls[0][1]);
  217. $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
  218. $this->assertEquals(0, $method_calls[0][1][1]);
  219. $this->assertEquals('extra1', $method_calls[0][1][2]);
  220. $this->assertEquals('extra2', $method_calls[0][1][3]);
  221. }
  222. /**
  223. * Tests consumer method with extra parameters and no priority.
  224. *
  225. * @covers ::process
  226. */
  227. public function testProcessNoPriorityAndExtraArguments() {
  228. $container = $this->buildContainer();
  229. $container
  230. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
  231. ->addTag('service_collector', array(
  232. 'call' => 'addNoPriority'
  233. ));
  234. $container
  235. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  236. ->addTag('consumer_id', array(
  237. 'extra' => 'extra',
  238. ));
  239. $handler_pass = new TaggedHandlersPass();
  240. $handler_pass->process($container);
  241. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  242. $this->assertCount(2, $method_calls[0][1]);
  243. $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
  244. $this->assertEquals('extra', $method_calls[0][1][1]);
  245. }
  246. /**
  247. * Tests consumer method with priority, id and extra parameters.
  248. *
  249. * @covers ::process
  250. */
  251. public function testProcessWithIdAndExtraArguments() {
  252. $container = $this->buildContainer();
  253. $container
  254. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
  255. ->addTag('service_collector', array(
  256. 'call' => 'addWithId'
  257. ));
  258. $container
  259. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  260. ->addTag('consumer_id', array(
  261. 'extra1' => 'extra1',
  262. ));
  263. $handler_pass = new TaggedHandlersPass();
  264. $handler_pass->process($container);
  265. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  266. $this->assertCount(5, $method_calls[0][1]);
  267. $this->assertEquals(new Reference('handler1'), $method_calls[0][1][0]);
  268. $this->assertEquals('handler1', $method_calls[0][1][1]);
  269. $this->assertEquals(0, $method_calls[0][1][2]);
  270. $this->assertEquals('extra1', $method_calls[0][1][3]);
  271. $this->assertNull($method_calls[0][1][4]);
  272. }
  273. /**
  274. * Tests consumer method with priority and extra parameters in different order.
  275. *
  276. * @covers ::process
  277. */
  278. public function testProcessWithDifferentArgumentsOrderAndDefaultValue() {
  279. $container = $this->buildContainer();
  280. $container
  281. ->register('consumer_id', __NAMESPACE__ . '\ValidConsumerWithExtraArguments')
  282. ->addTag('service_collector', array(
  283. 'call' => 'addWithDifferentOrder'
  284. ));
  285. $container
  286. ->register('handler1', __NAMESPACE__ . '\ValidHandler')
  287. ->addTag('consumer_id', array(
  288. 'priority' => 0,
  289. 'extra1' => 'extra1',
  290. 'extra3' => 'extra3'
  291. ));
  292. $handler_pass = new TaggedHandlersPass();
  293. $handler_pass->process($container);
  294. $method_calls = $container->getDefinition('consumer_id')->getMethodCalls();
  295. $this->assertCount(5, $method_calls[0][1]);
  296. $expected = [new Reference('handler1'), 'extra1', 0, 'default2', 'extra3'];
  297. $this->assertEquals($expected, array_values($method_calls[0][1]));
  298. }
  299. }
  300. interface HandlerInterface {
  301. }
  302. class ValidConsumer {
  303. public function addHandler(HandlerInterface $instance, $priority = 0) {
  304. }
  305. public function addNoPriority(HandlerInterface $instance) {
  306. }
  307. public function addWithId(HandlerInterface $instance, $id, $priority = 0) {
  308. }
  309. }
  310. class InvalidConsumer {
  311. public function addHandler($instance, $priority = 0) {
  312. }
  313. }
  314. class ValidConsumerWithExtraArguments {
  315. public function addHandler(HandlerInterface $instance, $priority = 0, $extra1 = '', $extra2 = '') {
  316. }
  317. public function addNoPriority(HandlerInterface $instance, $extra) {
  318. }
  319. public function addWithId(HandlerInterface $instance, $id, $priority = 0, $extra1 = '', $extra2 = NULL) {
  320. }
  321. public function addWithDifferentOrder(HandlerInterface $instance, $extra1, $priority = 0, $extra2 = 'default2', $extra3 = 'default3') {
  322. }
  323. }
  324. class ValidHandler implements HandlerInterface {
  325. }
  326. class InvalidHandler {
  327. }