Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\EventDispatcher\Tests\Debug;
|
Chris@0
|
13
|
Chris@0
|
14 use PHPUnit\Framework\TestCase;
|
Chris@0
|
15 use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
|
Chris@0
|
16 use Symfony\Component\EventDispatcher\Debug\WrappedListener;
|
Chris@0
|
17 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
Chris@0
|
18 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
Chris@0
|
19 use Symfony\Component\EventDispatcher\EventDispatcher;
|
Chris@0
|
20 use Symfony\Component\EventDispatcher\Event;
|
Chris@0
|
21 use Symfony\Component\Stopwatch\Stopwatch;
|
Chris@0
|
22
|
Chris@0
|
23 class TraceableEventDispatcherTest extends TestCase
|
Chris@0
|
24 {
|
Chris@0
|
25 public function testAddRemoveListener()
|
Chris@0
|
26 {
|
Chris@0
|
27 $dispatcher = new EventDispatcher();
|
Chris@0
|
28 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
29
|
Chris@0
|
30 $tdispatcher->addListener('foo', $listener = function () {});
|
Chris@0
|
31 $listeners = $dispatcher->getListeners('foo');
|
Chris@0
|
32 $this->assertCount(1, $listeners);
|
Chris@0
|
33 $this->assertSame($listener, $listeners[0]);
|
Chris@0
|
34
|
Chris@0
|
35 $tdispatcher->removeListener('foo', $listener);
|
Chris@0
|
36 $this->assertCount(0, $dispatcher->getListeners('foo'));
|
Chris@0
|
37 }
|
Chris@0
|
38
|
Chris@0
|
39 public function testGetListeners()
|
Chris@0
|
40 {
|
Chris@0
|
41 $dispatcher = new EventDispatcher();
|
Chris@0
|
42 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
43
|
Chris@0
|
44 $tdispatcher->addListener('foo', $listener = function () {});
|
Chris@0
|
45 $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo'));
|
Chris@0
|
46 }
|
Chris@0
|
47
|
Chris@0
|
48 public function testHasListeners()
|
Chris@0
|
49 {
|
Chris@0
|
50 $dispatcher = new EventDispatcher();
|
Chris@0
|
51 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
52
|
Chris@0
|
53 $this->assertFalse($dispatcher->hasListeners('foo'));
|
Chris@0
|
54 $this->assertFalse($tdispatcher->hasListeners('foo'));
|
Chris@0
|
55
|
Chris@0
|
56 $tdispatcher->addListener('foo', $listener = function () {});
|
Chris@0
|
57 $this->assertTrue($dispatcher->hasListeners('foo'));
|
Chris@0
|
58 $this->assertTrue($tdispatcher->hasListeners('foo'));
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 public function testGetListenerPriority()
|
Chris@0
|
62 {
|
Chris@0
|
63 $dispatcher = new EventDispatcher();
|
Chris@0
|
64 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
65
|
Chris@0
|
66 $tdispatcher->addListener('foo', function () {}, 123);
|
Chris@0
|
67
|
Chris@0
|
68 $listeners = $dispatcher->getListeners('foo');
|
Chris@0
|
69 $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
|
Chris@0
|
70
|
Chris@0
|
71 // Verify that priority is preserved when listener is removed and re-added
|
Chris@0
|
72 // in preProcess() and postProcess().
|
Chris@0
|
73 $tdispatcher->dispatch('foo', new Event());
|
Chris@0
|
74 $listeners = $dispatcher->getListeners('foo');
|
Chris@0
|
75 $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
|
Chris@0
|
76 }
|
Chris@0
|
77
|
Chris@0
|
78 public function testGetListenerPriorityWhileDispatching()
|
Chris@0
|
79 {
|
Chris@0
|
80 $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
Chris@0
|
81 $priorityWhileDispatching = null;
|
Chris@0
|
82
|
Chris@0
|
83 $listener = function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) {
|
Chris@0
|
84 $priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener);
|
Chris@0
|
85 };
|
Chris@0
|
86
|
Chris@0
|
87 $tdispatcher->addListener('bar', $listener, 5);
|
Chris@0
|
88 $tdispatcher->dispatch('bar');
|
Chris@0
|
89 $this->assertSame(5, $priorityWhileDispatching);
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 public function testAddRemoveSubscriber()
|
Chris@0
|
93 {
|
Chris@0
|
94 $dispatcher = new EventDispatcher();
|
Chris@0
|
95 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
96
|
Chris@0
|
97 $subscriber = new EventSubscriber();
|
Chris@0
|
98
|
Chris@0
|
99 $tdispatcher->addSubscriber($subscriber);
|
Chris@0
|
100 $listeners = $dispatcher->getListeners('foo');
|
Chris@0
|
101 $this->assertCount(1, $listeners);
|
Chris@0
|
102 $this->assertSame(array($subscriber, 'call'), $listeners[0]);
|
Chris@0
|
103
|
Chris@0
|
104 $tdispatcher->removeSubscriber($subscriber);
|
Chris@0
|
105 $this->assertCount(0, $dispatcher->getListeners('foo'));
|
Chris@0
|
106 }
|
Chris@0
|
107
|
Chris@0
|
108 /**
|
Chris@0
|
109 * @dataProvider isWrappedDataProvider
|
Chris@0
|
110 *
|
Chris@0
|
111 * @param bool $isWrapped
|
Chris@0
|
112 */
|
Chris@0
|
113 public function testGetCalledListeners($isWrapped)
|
Chris@0
|
114 {
|
Chris@0
|
115 $dispatcher = new EventDispatcher();
|
Chris@0
|
116 $stopWatch = new Stopwatch();
|
Chris@0
|
117 $tdispatcher = new TraceableEventDispatcher($dispatcher, $stopWatch);
|
Chris@0
|
118
|
Chris@0
|
119 $listener = function () {};
|
Chris@0
|
120
|
Chris@0
|
121 $tdispatcher->addListener('foo', $listener, 5);
|
Chris@0
|
122
|
Chris@0
|
123 $listeners = $tdispatcher->getNotCalledListeners();
|
Chris@0
|
124 $this->assertArrayHasKey('data', $listeners['foo.closure']);
|
Chris@0
|
125 unset($listeners['foo.closure']['data']);
|
Chris@0
|
126 $this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
Chris@0
|
127 $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
Chris@0
|
128
|
Chris@0
|
129 $tdispatcher->dispatch('foo');
|
Chris@0
|
130
|
Chris@0
|
131 $listeners = $tdispatcher->getCalledListeners();
|
Chris@0
|
132 unset($listeners['foo.closure']['data']);
|
Chris@0
|
133 $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
Chris@0
|
134 $this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
Chris@0
|
135 }
|
Chris@0
|
136
|
Chris@0
|
137 public function isWrappedDataProvider()
|
Chris@0
|
138 {
|
Chris@0
|
139 return array(
|
Chris@0
|
140 array(false),
|
Chris@0
|
141 array(true),
|
Chris@0
|
142 );
|
Chris@0
|
143 }
|
Chris@0
|
144
|
Chris@0
|
145 public function testGetCalledListenersNested()
|
Chris@0
|
146 {
|
Chris@0
|
147 $tdispatcher = null;
|
Chris@0
|
148 $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
Chris@0
|
149 $dispatcher->addListener('foo', function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) {
|
Chris@0
|
150 $tdispatcher = $dispatcher;
|
Chris@0
|
151 $dispatcher->dispatch('bar');
|
Chris@0
|
152 });
|
Chris@0
|
153 $dispatcher->addListener('bar', function (Event $event) {});
|
Chris@0
|
154 $dispatcher->dispatch('foo');
|
Chris@0
|
155 $this->assertSame($dispatcher, $tdispatcher);
|
Chris@0
|
156 $this->assertCount(2, $dispatcher->getCalledListeners());
|
Chris@0
|
157 }
|
Chris@0
|
158
|
Chris@0
|
159 public function testLogger()
|
Chris@0
|
160 {
|
Chris@0
|
161 $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
Chris@0
|
162
|
Chris@0
|
163 $dispatcher = new EventDispatcher();
|
Chris@0
|
164 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
|
Chris@0
|
165 $tdispatcher->addListener('foo', $listener1 = function () {});
|
Chris@0
|
166 $tdispatcher->addListener('foo', $listener2 = function () {});
|
Chris@0
|
167
|
Chris@0
|
168 $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
|
Chris@0
|
169 $logger->expects($this->at(1))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
|
Chris@0
|
170
|
Chris@0
|
171 $tdispatcher->dispatch('foo');
|
Chris@0
|
172 }
|
Chris@0
|
173
|
Chris@0
|
174 public function testLoggerWithStoppedEvent()
|
Chris@0
|
175 {
|
Chris@0
|
176 $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
Chris@0
|
177
|
Chris@0
|
178 $dispatcher = new EventDispatcher();
|
Chris@0
|
179 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
|
Chris@0
|
180 $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); });
|
Chris@0
|
181 $tdispatcher->addListener('foo', $listener2 = function () {});
|
Chris@0
|
182
|
Chris@0
|
183 $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
|
Chris@0
|
184 $logger->expects($this->at(1))->method('debug')->with('Listener "{listener}" stopped propagation of the event "{event}".', array('event' => 'foo', 'listener' => 'closure'));
|
Chris@0
|
185 $logger->expects($this->at(2))->method('debug')->with('Listener "{listener}" was not called for event "{event}".', array('event' => 'foo', 'listener' => 'closure'));
|
Chris@0
|
186
|
Chris@0
|
187 $tdispatcher->dispatch('foo');
|
Chris@0
|
188 }
|
Chris@0
|
189
|
Chris@0
|
190 public function testDispatchCallListeners()
|
Chris@0
|
191 {
|
Chris@0
|
192 $called = array();
|
Chris@0
|
193
|
Chris@0
|
194 $dispatcher = new EventDispatcher();
|
Chris@0
|
195 $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
Chris@0
|
196 $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo1'; }, 10);
|
Chris@0
|
197 $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo2'; }, 20);
|
Chris@0
|
198
|
Chris@0
|
199 $tdispatcher->dispatch('foo');
|
Chris@0
|
200
|
Chris@0
|
201 $this->assertSame(array('foo2', 'foo1'), $called);
|
Chris@0
|
202 }
|
Chris@0
|
203
|
Chris@0
|
204 public function testDispatchNested()
|
Chris@0
|
205 {
|
Chris@0
|
206 $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
Chris@0
|
207 $loop = 1;
|
Chris@0
|
208 $dispatchedEvents = 0;
|
Chris@0
|
209 $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) {
|
Chris@0
|
210 ++$loop;
|
Chris@0
|
211 if (2 == $loop) {
|
Chris@0
|
212 $dispatcher->dispatch('foo');
|
Chris@0
|
213 }
|
Chris@0
|
214 });
|
Chris@0
|
215 $dispatcher->addListener('foo', function () use (&$dispatchedEvents) {
|
Chris@0
|
216 ++$dispatchedEvents;
|
Chris@0
|
217 });
|
Chris@0
|
218
|
Chris@0
|
219 $dispatcher->dispatch('foo');
|
Chris@0
|
220
|
Chris@0
|
221 $this->assertSame(2, $dispatchedEvents);
|
Chris@0
|
222 }
|
Chris@0
|
223
|
Chris@0
|
224 public function testDispatchReusedEventNested()
|
Chris@0
|
225 {
|
Chris@0
|
226 $nestedCall = false;
|
Chris@0
|
227 $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
Chris@0
|
228 $dispatcher->addListener('foo', function (Event $e) use ($dispatcher) {
|
Chris@0
|
229 $dispatcher->dispatch('bar', $e);
|
Chris@0
|
230 });
|
Chris@0
|
231 $dispatcher->addListener('bar', function (Event $e) use (&$nestedCall) {
|
Chris@0
|
232 $nestedCall = true;
|
Chris@0
|
233 });
|
Chris@0
|
234
|
Chris@0
|
235 $this->assertFalse($nestedCall);
|
Chris@0
|
236 $dispatcher->dispatch('foo');
|
Chris@0
|
237 $this->assertTrue($nestedCall);
|
Chris@0
|
238 }
|
Chris@0
|
239
|
Chris@0
|
240 public function testListenerCanRemoveItselfWhenExecuted()
|
Chris@0
|
241 {
|
Chris@0
|
242 $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
Chris@0
|
243 $listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {
|
Chris@0
|
244 $dispatcher->removeListener('foo', $listener1);
|
Chris@0
|
245 };
|
Chris@0
|
246 $eventDispatcher->addListener('foo', $listener1);
|
Chris@0
|
247 $eventDispatcher->addListener('foo', function () {});
|
Chris@0
|
248 $eventDispatcher->dispatch('foo');
|
Chris@0
|
249
|
Chris@0
|
250 $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
|
Chris@0
|
251 }
|
Chris@0
|
252 }
|
Chris@0
|
253
|
Chris@0
|
254 class EventSubscriber implements EventSubscriberInterface
|
Chris@0
|
255 {
|
Chris@0
|
256 public static function getSubscribedEvents()
|
Chris@0
|
257 {
|
Chris@0
|
258 return array('foo' => 'call');
|
Chris@0
|
259 }
|
Chris@0
|
260 }
|