PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Tests/Unit/SignalSlot/DispatcherTest.php

https://github.com/christianjul/FLOW3-Composer
PHP | 212 lines | 114 code | 40 blank | 58 comment | 0 complexity | a22b614e68659b5819855bf590d1985d MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0
  1. <?php
  2. namespace TYPO3\FLOW3\Tests\Unit\SignalSlot;
  3. /* *
  4. * This script belongs to the FLOW3 framework. *
  5. * *
  6. * It is free software; you can redistribute it and/or modify it under *
  7. * the terms of the GNU Lesser General Public License, either version 3 *
  8. * of the License, or (at your option) any later version. *
  9. * *
  10. * The TYPO3 project - inspiring people to share! *
  11. * */
  12. /**
  13. * Testcase for the Signal Dispatcher Class
  14. *
  15. */
  16. class DispatcherTest extends \TYPO3\FLOW3\Tests\UnitTestCase {
  17. /**
  18. * @test
  19. */
  20. public function connectAllowsForConnectingASlotWithASignal() {
  21. $mockSignal = $this->getMock('ClassA', array('emitSomeSignal'));
  22. $mockSlot = $this->getMock('ClassB', array('someSlotMethod'));
  23. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  24. $dispatcher->connect(get_class($mockSignal), 'someSignal', get_class($mockSlot), 'someSlotMethod', FALSE);
  25. $expectedSlots = array(
  26. array('class' => get_class($mockSlot), 'method' => 'someSlotMethod', 'object' => NULL, 'passSignalInformation' => FALSE)
  27. );
  28. $this->assertSame($expectedSlots, $dispatcher->getSlots(get_class($mockSignal), 'someSignal'));
  29. }
  30. /**
  31. * @test
  32. */
  33. public function connectAlsoAcceptsObjectsInPlaceOfTheClassName() {
  34. $mockSignal = $this->getMock('ClassA', array('emitSomeSignal'));
  35. $mockSlot = $this->getMock('ClassB', array('someSlotMethod'));
  36. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  37. $dispatcher->connect(get_class($mockSignal), 'someSignal', $mockSlot, 'someSlotMethod', FALSE);
  38. $expectedSlots = array(
  39. array('class' => NULL, 'method' => 'someSlotMethod', 'object' => $mockSlot, 'passSignalInformation' => FALSE)
  40. );
  41. $this->assertSame($expectedSlots, $dispatcher->getSlots(get_class($mockSignal), 'someSignal'));
  42. }
  43. /**
  44. * @test
  45. */
  46. public function connectAlsoAcceptsClosuresActingAsASlot() {
  47. $mockSignal = $this->getMock('ClassA', array('emitSomeSignal'));
  48. $mockSlot = function() { };
  49. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  50. $dispatcher->connect(get_class($mockSignal), 'someSignal', $mockSlot, 'foo', FALSE);
  51. $expectedSlots = array(
  52. array('class' => NULL, 'method' => '__invoke', 'object' => $mockSlot, 'passSignalInformation' => FALSE)
  53. );
  54. $this->assertSame($expectedSlots, $dispatcher->getSlots(get_class($mockSignal), 'someSignal'));
  55. }
  56. /**
  57. * @test
  58. */
  59. public function dispatchPassesTheSignalArgumentsToTheSlotMethod() {
  60. $arguments = array();
  61. $mockSlot = function() use (&$arguments) { $arguments = func_get_args(); };
  62. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  63. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  64. $dispatcher->connect('Foo', 'bar', $mockSlot, NULL, FALSE);
  65. $dispatcher->injectObjectManager($mockObjectManager);
  66. $dispatcher->dispatch('Foo', 'bar', array('foo' => 'bar', 'baz' => 'quux'));
  67. $this->assertSame(array('bar', 'quux'), $arguments);
  68. }
  69. /**
  70. * @test
  71. */
  72. public function dispatchPassesTheSignalArgumentsToTheStaticSlotMethod() {
  73. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  74. $mockObjectManager->expects($this->any())->method('getClassNameByObjectName')->with('TYPO3\FLOW3\Tests\Unit\SignalSlot\DispatcherTest')->will($this->returnValue('TYPO3\FLOW3\Tests\Unit\SignalSlot\DispatcherTest'));
  75. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  76. $dispatcher->connect('Foo', 'bar', get_class($this), '::staticSlot', FALSE);
  77. $dispatcher->injectObjectManager($mockObjectManager);
  78. $dispatcher->dispatch('Foo', 'bar', array('foo' => 'bar', 'baz' => 'quux'));
  79. $this->assertSame(array('bar', 'quux'), self::$arguments);
  80. }
  81. /**
  82. * @test
  83. */
  84. public function dispatchPassesTheSignalArgumentsToTheStaticSlotMethodIfNoObjectmanagerIsAvailable() {
  85. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  86. $dispatcher->connect('Foo', 'bar', get_class($this), '::staticSlot', FALSE);
  87. $dispatcher->dispatch('Foo', 'bar', array('no' => 'object', 'manager' => 'exists'));
  88. $this->assertSame(array('object', 'exists'), self::$arguments);
  89. }
  90. /**
  91. * A variable used in the above two tests.
  92. * @var array
  93. */
  94. static protected $arguments = array();
  95. /**
  96. * A slot used in the above two tests.
  97. *
  98. * @return void
  99. */
  100. static public function staticSlot() {
  101. self::$arguments = func_get_args();
  102. }
  103. /**
  104. * @test
  105. */
  106. public function dispatchRetrievesSlotInstanceFromTheObjectManagerIfOnlyAClassNameWasSpecified() {
  107. $slotClassName = 'Mock_' . md5(uniqid(mt_rand(), TRUE));
  108. eval ('class ' . $slotClassName . ' { function slot($foo, $baz) { $this->arguments = array($foo, $baz); } }');
  109. $mockSlot = new $slotClassName();
  110. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  111. $mockObjectManager->expects($this->once())->method('isRegistered')->with($slotClassName)->will($this->returnValue(TRUE));
  112. $mockObjectManager->expects($this->once())->method('get')->with($slotClassName)->will($this->returnValue($mockSlot));
  113. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  114. $dispatcher->injectObjectManager($mockObjectManager);
  115. $dispatcher->connect('Foo', 'bar', $slotClassName, 'slot', FALSE);
  116. $dispatcher->dispatch('Foo', 'bar', array('foo' => 'bar', 'baz' => 'quux'));
  117. $this->assertSame($mockSlot->arguments, array('bar', 'quux'));
  118. }
  119. /**
  120. * @test
  121. * @expectedException \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException
  122. */
  123. public function dispatchThrowsAnExceptionIfTheSpecifiedClassOfASlotIsUnknown() {
  124. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  125. $mockObjectManager->expects($this->once())->method('isRegistered')->with('NonExistingClassName')->will($this->returnValue(FALSE));
  126. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  127. $dispatcher->injectObjectManager($mockObjectManager);
  128. $dispatcher->connect('Foo', 'bar', 'NonExistingClassName', 'slot', FALSE);
  129. $dispatcher->dispatch('Foo', 'bar', array());
  130. }
  131. /**
  132. * @test
  133. * @expectedException \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException
  134. */
  135. public function dispatchThrowsAnExceptionIfTheSpecifiedSlotMethodDoesNotExist() {
  136. $slotClassName = 'Mock_' . md5(uniqid(mt_rand(), TRUE));
  137. eval ('class ' . $slotClassName . ' { function slot($foo, $baz) { $this->arguments = array($foo, $baz); } }');
  138. $mockSlot = new $slotClassName();
  139. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  140. $mockObjectManager->expects($this->once())->method('isRegistered')->with($slotClassName)->will($this->returnValue(TRUE));
  141. $mockObjectManager->expects($this->once())->method('get')->with($slotClassName)->will($this->returnValue($mockSlot));
  142. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  143. $dispatcher->injectObjectManager($mockObjectManager);
  144. $dispatcher->connect('Foo', 'bar', $slotClassName, 'unknownMethodName', TRUE);
  145. $dispatcher->dispatch('Foo', 'bar', array('foo' => 'bar', 'baz' => 'quux'));
  146. $this->assertSame($mockSlot->arguments, array('bar', 'quux'));
  147. }
  148. /**
  149. * @test
  150. */
  151. public function dispatchPassesArgumentContainingSlotInformationLastIfTheConnectionStatesSo() {
  152. $arguments = array();
  153. $mockSlot = function() use (&$arguments) { $arguments = func_get_args(); };
  154. $mockObjectManager = $this->getMock('TYPO3\FLOW3\Object\ObjectManagerInterface');
  155. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  156. $dispatcher->connect('SignalClassName', 'methodName', $mockSlot, NULL, TRUE);
  157. $dispatcher->injectObjectManager($mockObjectManager);
  158. $dispatcher->dispatch('SignalClassName', 'methodName', array('foo' => 'bar', 'baz' => 'quux'));
  159. $this->assertSame(array('bar', 'quux', 'SignalClassName::methodName'), $arguments);
  160. }
  161. /**
  162. * @test
  163. * @expectedException \InvalidArgumentException
  164. */
  165. public function connectWithSignalNameStartingWithEmitShouldNotBeAllowed() {
  166. $mockSignal = $this->getMock('ClassA', array('emitSomeSignal'));
  167. $mockSlot = $this->getMock('ClassB', array('someSlotMethod'));
  168. $dispatcher = new \TYPO3\FLOW3\SignalSlot\Dispatcher();
  169. $dispatcher->connect(get_class($mockSignal), 'emitSomeSignal', get_class($mockSlot), 'someSlotMethod', FALSE);
  170. }
  171. }
  172. ?>