TraceableEventDispatcherTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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\EventDispatcher\Tests\Debug;
  11. use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
  12. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\EventDispatcher\EventDispatcher;
  15. use Symfony\Component\EventDispatcher\Event;
  16. use Symfony\Component\Stopwatch\Stopwatch;
  17. class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
  18. {
  19. public function testAddRemoveListener()
  20. {
  21. $dispatcher = new EventDispatcher();
  22. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  23. $tdispatcher->addListener('foo', $listener = function () {; });
  24. $listeners = $dispatcher->getListeners('foo');
  25. $this->assertCount(1, $listeners);
  26. $this->assertSame($listener, $listeners[0]);
  27. $tdispatcher->removeListener('foo', $listener);
  28. $this->assertCount(0, $dispatcher->getListeners('foo'));
  29. }
  30. public function testGetListeners()
  31. {
  32. $dispatcher = new EventDispatcher();
  33. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  34. $tdispatcher->addListener('foo', $listener = function () {; });
  35. $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo'));
  36. }
  37. public function testHasListeners()
  38. {
  39. $dispatcher = new EventDispatcher();
  40. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  41. $this->assertFalse($dispatcher->hasListeners('foo'));
  42. $this->assertFalse($tdispatcher->hasListeners('foo'));
  43. $tdispatcher->addListener('foo', $listener = function () {; });
  44. $this->assertTrue($dispatcher->hasListeners('foo'));
  45. $this->assertTrue($tdispatcher->hasListeners('foo'));
  46. }
  47. public function testAddRemoveSubscriber()
  48. {
  49. $dispatcher = new EventDispatcher();
  50. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  51. $subscriber = new EventSubscriber();
  52. $tdispatcher->addSubscriber($subscriber);
  53. $listeners = $dispatcher->getListeners('foo');
  54. $this->assertCount(1, $listeners);
  55. $this->assertSame(array($subscriber, 'call'), $listeners[0]);
  56. $tdispatcher->removeSubscriber($subscriber);
  57. $this->assertCount(0, $dispatcher->getListeners('foo'));
  58. }
  59. public function testGetCalledListeners()
  60. {
  61. $dispatcher = new EventDispatcher();
  62. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  63. $tdispatcher->addListener('foo', $listener = function () {; });
  64. $this->assertEquals(array(), $tdispatcher->getCalledListeners());
  65. $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure')), $tdispatcher->getNotCalledListeners());
  66. $tdispatcher->dispatch('foo');
  67. $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure')), $tdispatcher->getCalledListeners());
  68. $this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
  69. }
  70. public function testGetCalledListenersNested()
  71. {
  72. $tdispatcher = null;
  73. $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
  74. $dispatcher->addListener('foo', function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) {
  75. $tdispatcher = $dispatcher;
  76. $dispatcher->dispatch('bar');
  77. });
  78. $dispatcher->addListener('bar', function (Event $event) {});
  79. $dispatcher->dispatch('foo');
  80. $this->assertSame($dispatcher, $tdispatcher);
  81. $this->assertCount(2, $dispatcher->getCalledListeners());
  82. }
  83. public function testLogger()
  84. {
  85. $logger = $this->getMock('Psr\Log\LoggerInterface');
  86. $dispatcher = new EventDispatcher();
  87. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
  88. $tdispatcher->addListener('foo', $listener1 = function () {; });
  89. $tdispatcher->addListener('foo', $listener2 = function () {; });
  90. $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".');
  91. $logger->expects($this->at(1))->method('debug')->with('Notified event "foo" to listener "closure".');
  92. $tdispatcher->dispatch('foo');
  93. }
  94. public function testLoggerWithStoppedEvent()
  95. {
  96. $logger = $this->getMock('Psr\Log\LoggerInterface');
  97. $dispatcher = new EventDispatcher();
  98. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
  99. $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); });
  100. $tdispatcher->addListener('foo', $listener2 = function () {; });
  101. $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".');
  102. $logger->expects($this->at(1))->method('debug')->with('Listener "closure" stopped propagation of the event "foo".');
  103. $logger->expects($this->at(2))->method('debug')->with('Listener "closure" was not called for event "foo".');
  104. $tdispatcher->dispatch('foo');
  105. }
  106. public function testDispatchCallListeners()
  107. {
  108. $called = array();
  109. $dispatcher = new EventDispatcher();
  110. $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
  111. $tdispatcher->addListener('foo', $listener1 = function () use (&$called) { $called[] = 'foo1'; });
  112. $tdispatcher->addListener('foo', $listener2 = function () use (&$called) { $called[] = 'foo2'; });
  113. $tdispatcher->dispatch('foo');
  114. $this->assertEquals(array('foo1', 'foo2'), $called);
  115. }
  116. public function testDispatchNested()
  117. {
  118. $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
  119. $loop = 1;
  120. $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) {
  121. ++$loop;
  122. if (2 == $loop) {
  123. $dispatcher->dispatch('foo');
  124. }
  125. });
  126. $dispatcher->dispatch('foo');
  127. }
  128. public function testDispatchReusedEventNested()
  129. {
  130. $nestedCall = false;
  131. $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
  132. $dispatcher->addListener('foo', function (Event $e) use ($dispatcher) {
  133. $dispatcher->dispatch('bar', $e);
  134. });
  135. $dispatcher->addListener('bar', function (Event $e) use (&$nestedCall) {
  136. $nestedCall = true;
  137. });
  138. $this->assertFalse($nestedCall);
  139. $dispatcher->dispatch('foo');
  140. $this->assertTrue($nestedCall);
  141. }
  142. public function testListenerCanRemoveItselfWhenExecuted()
  143. {
  144. $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
  145. $listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {
  146. $dispatcher->removeListener('foo', $listener1);
  147. };
  148. $eventDispatcher->addListener('foo', $listener1);
  149. $eventDispatcher->addListener('foo', function () {});
  150. $eventDispatcher->dispatch('foo');
  151. $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
  152. }
  153. }
  154. class EventSubscriber implements EventSubscriberInterface
  155. {
  156. public static function getSubscribedEvents()
  157. {
  158. return array('foo' => 'call');
  159. }
  160. }