Skip to content

Commit 8871368

Browse files
znerolfabpot
authored andcommitted
Extract an AbstractEventDispatcherTest from EventDispatcherTest and also use it in ContainerAwareEventDispatcherTest
1 parent d55abb3 commit 8871368

File tree

3 files changed

+379
-350
lines changed

3 files changed

+379
-350
lines changed
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\EventDispatcher\Tests;
13+
14+
use Symfony\Component\EventDispatcher\Event;
15+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16+
17+
abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
18+
{
19+
/* Some pseudo events */
20+
const preFoo = 'pre.foo';
21+
const postFoo = 'post.foo';
22+
const preBar = 'pre.bar';
23+
const postBar = 'post.bar';
24+
25+
/**
26+
* @var EventDispatcher
27+
*/
28+
private $dispatcher;
29+
30+
private $listener;
31+
32+
protected function setUp()
33+
{
34+
$this->dispatcher = $this->createEventDispatcher();
35+
$this->listener = new TestEventListener();
36+
}
37+
38+
protected function tearDown()
39+
{
40+
$this->dispatcher = null;
41+
$this->listener = null;
42+
}
43+
44+
abstract protected function createEventDispatcher();
45+
46+
public function testInitialState()
47+
{
48+
$this->assertEquals(array(), $this->dispatcher->getListeners());
49+
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
50+
$this->assertFalse($this->dispatcher->hasListeners(self::postFoo));
51+
}
52+
53+
public function testAddListener()
54+
{
55+
$this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo'));
56+
$this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'));
57+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
58+
$this->assertTrue($this->dispatcher->hasListeners(self::postFoo));
59+
$this->assertCount(1, $this->dispatcher->getListeners(self::preFoo));
60+
$this->assertCount(1, $this->dispatcher->getListeners(self::postFoo));
61+
$this->assertCount(2, $this->dispatcher->getListeners());
62+
}
63+
64+
public function testGetListenersSortsByPriority()
65+
{
66+
$listener1 = new TestEventListener();
67+
$listener2 = new TestEventListener();
68+
$listener3 = new TestEventListener();
69+
$listener1->name = '1';
70+
$listener2->name = '2';
71+
$listener3->name = '3';
72+
73+
$this->dispatcher->addListener('pre.foo', array($listener1, 'preFoo'), -10);
74+
$this->dispatcher->addListener('pre.foo', array($listener2, 'preFoo'), 10);
75+
$this->dispatcher->addListener('pre.foo', array($listener3, 'preFoo'));
76+
77+
$expected = array(
78+
array($listener2, 'preFoo'),
79+
array($listener3, 'preFoo'),
80+
array($listener1, 'preFoo'),
81+
);
82+
83+
$this->assertSame($expected, $this->dispatcher->getListeners('pre.foo'));
84+
}
85+
86+
public function testGetAllListenersSortsByPriority()
87+
{
88+
$listener1 = new TestEventListener();
89+
$listener2 = new TestEventListener();
90+
$listener3 = new TestEventListener();
91+
$listener4 = new TestEventListener();
92+
$listener5 = new TestEventListener();
93+
$listener6 = new TestEventListener();
94+
95+
$this->dispatcher->addListener('pre.foo', $listener1, -10);
96+
$this->dispatcher->addListener('pre.foo', $listener2);
97+
$this->dispatcher->addListener('pre.foo', $listener3, 10);
98+
$this->dispatcher->addListener('post.foo', $listener4, -10);
99+
$this->dispatcher->addListener('post.foo', $listener5);
100+
$this->dispatcher->addListener('post.foo', $listener6, 10);
101+
102+
$expected = array(
103+
'pre.foo' => array($listener3, $listener2, $listener1),
104+
'post.foo' => array($listener6, $listener5, $listener4),
105+
);
106+
107+
$this->assertSame($expected, $this->dispatcher->getListeners());
108+
}
109+
110+
public function testDispatch()
111+
{
112+
$this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo'));
113+
$this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'));
114+
$this->dispatcher->dispatch(self::preFoo);
115+
$this->assertTrue($this->listener->preFooInvoked);
116+
$this->assertFalse($this->listener->postFooInvoked);
117+
$this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch('noevent'));
118+
$this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo));
119+
$event = new Event();
120+
$return = $this->dispatcher->dispatch(self::preFoo, $event);
121+
$this->assertEquals('pre.foo', $event->getName());
122+
$this->assertSame($event, $return);
123+
}
124+
125+
public function testDispatchForClosure()
126+
{
127+
$invoked = 0;
128+
$listener = function () use (&$invoked) {
129+
$invoked++;
130+
};
131+
$this->dispatcher->addListener('pre.foo', $listener);
132+
$this->dispatcher->addListener('post.foo', $listener);
133+
$this->dispatcher->dispatch(self::preFoo);
134+
$this->assertEquals(1, $invoked);
135+
}
136+
137+
public function testStopEventPropagation()
138+
{
139+
$otherListener = new TestEventListener();
140+
141+
// postFoo() stops the propagation, so only one listener should
142+
// be executed
143+
// Manually set priority to enforce $this->listener to be called first
144+
$this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'), 10);
145+
$this->dispatcher->addListener('post.foo', array($otherListener, 'preFoo'));
146+
$this->dispatcher->dispatch(self::postFoo);
147+
$this->assertTrue($this->listener->postFooInvoked);
148+
$this->assertFalse($otherListener->postFooInvoked);
149+
}
150+
151+
public function testDispatchByPriority()
152+
{
153+
$invoked = array();
154+
$listener1 = function () use (&$invoked) {
155+
$invoked[] = '1';
156+
};
157+
$listener2 = function () use (&$invoked) {
158+
$invoked[] = '2';
159+
};
160+
$listener3 = function () use (&$invoked) {
161+
$invoked[] = '3';
162+
};
163+
$this->dispatcher->addListener('pre.foo', $listener1, -10);
164+
$this->dispatcher->addListener('pre.foo', $listener2);
165+
$this->dispatcher->addListener('pre.foo', $listener3, 10);
166+
$this->dispatcher->dispatch(self::preFoo);
167+
$this->assertEquals(array('3', '2', '1'), $invoked);
168+
}
169+
170+
public function testRemoveListener()
171+
{
172+
$this->dispatcher->addListener('pre.bar', $this->listener);
173+
$this->assertTrue($this->dispatcher->hasListeners(self::preBar));
174+
$this->dispatcher->removeListener('pre.bar', $this->listener);
175+
$this->assertFalse($this->dispatcher->hasListeners(self::preBar));
176+
$this->dispatcher->removeListener('notExists', $this->listener);
177+
}
178+
179+
public function testAddSubscriber()
180+
{
181+
$eventSubscriber = new TestEventSubscriber();
182+
$this->dispatcher->addSubscriber($eventSubscriber);
183+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
184+
$this->assertTrue($this->dispatcher->hasListeners(self::postFoo));
185+
}
186+
187+
public function testAddSubscriberWithPriorities()
188+
{
189+
$eventSubscriber = new TestEventSubscriber();
190+
$this->dispatcher->addSubscriber($eventSubscriber);
191+
192+
$eventSubscriber = new TestEventSubscriberWithPriorities();
193+
$this->dispatcher->addSubscriber($eventSubscriber);
194+
195+
$listeners = $this->dispatcher->getListeners('pre.foo');
196+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
197+
$this->assertCount(2, $listeners);
198+
$this->assertInstanceOf('Symfony\Component\EventDispatcher\Tests\TestEventSubscriberWithPriorities', $listeners[0][0]);
199+
}
200+
201+
public function testAddSubscriberWithMultipleListeners()
202+
{
203+
$eventSubscriber = new TestEventSubscriberWithMultipleListeners();
204+
$this->dispatcher->addSubscriber($eventSubscriber);
205+
206+
$listeners = $this->dispatcher->getListeners('pre.foo');
207+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
208+
$this->assertCount(2, $listeners);
209+
$this->assertEquals('preFoo2', $listeners[0][1]);
210+
}
211+
212+
public function testRemoveSubscriber()
213+
{
214+
$eventSubscriber = new TestEventSubscriber();
215+
$this->dispatcher->addSubscriber($eventSubscriber);
216+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
217+
$this->assertTrue($this->dispatcher->hasListeners(self::postFoo));
218+
$this->dispatcher->removeSubscriber($eventSubscriber);
219+
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
220+
$this->assertFalse($this->dispatcher->hasListeners(self::postFoo));
221+
}
222+
223+
public function testRemoveSubscriberWithPriorities()
224+
{
225+
$eventSubscriber = new TestEventSubscriberWithPriorities();
226+
$this->dispatcher->addSubscriber($eventSubscriber);
227+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
228+
$this->dispatcher->removeSubscriber($eventSubscriber);
229+
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
230+
}
231+
232+
public function testRemoveSubscriberWithMultipleListeners()
233+
{
234+
$eventSubscriber = new TestEventSubscriberWithMultipleListeners();
235+
$this->dispatcher->addSubscriber($eventSubscriber);
236+
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
237+
$this->assertCount(2, $this->dispatcher->getListeners(self::preFoo));
238+
$this->dispatcher->removeSubscriber($eventSubscriber);
239+
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
240+
}
241+
242+
public function testEventReceivesTheDispatcherInstance()
243+
{
244+
$dispatcher = null;
245+
$this->dispatcher->addListener('test', function ($event) use (&$dispatcher) {
246+
$dispatcher = $event->getDispatcher();
247+
});
248+
$this->dispatcher->dispatch('test');
249+
$this->assertSame($this->dispatcher, $dispatcher);
250+
}
251+
252+
public function testEventReceivesTheDispatcherInstanceAsArgument()
253+
{
254+
$listener = new TestWithDispatcher();
255+
$this->dispatcher->addListener('test', array($listener, 'foo'));
256+
$this->assertNull($listener->name);
257+
$this->assertNull($listener->dispatcher);
258+
$this->dispatcher->dispatch('test');
259+
$this->assertEquals('test', $listener->name);
260+
$this->assertSame($this->dispatcher, $listener->dispatcher);
261+
}
262+
263+
/**
264+
* @see https://bugs.php.net/bug.php?id=62976
265+
*
266+
* This bug affects:
267+
* - The PHP 5.3 branch for versions < 5.3.18
268+
* - The PHP 5.4 branch for versions < 5.4.8
269+
* - The PHP 5.5 branch is not affected
270+
*/
271+
public function testWorkaroundForPhpBug62976()
272+
{
273+
$dispatcher = $this->createEventDispatcher();
274+
$dispatcher->addListener('bug.62976', new CallableClass());
275+
$dispatcher->removeListener('bug.62976', function () {});
276+
$this->assertTrue($dispatcher->hasListeners('bug.62976'));
277+
}
278+
279+
public function testHasListenersWhenAddedCallbackListenerIsRemoved()
280+
{
281+
$listener = function () {};
282+
$this->dispatcher->addListener('foo', $listener);
283+
$this->dispatcher->removeListener('foo', $listener);
284+
$this->assertFalse($this->dispatcher->hasListeners());
285+
}
286+
287+
public function testGetListenersWhenAddedCallbackListenerIsRemoved()
288+
{
289+
$listener = function () {};
290+
$this->dispatcher->addListener('foo', $listener);
291+
$this->dispatcher->removeListener('foo', $listener);
292+
$this->assertSame(array(), $this->dispatcher->getListeners());
293+
}
294+
295+
public function testHasListenersWithoutEventsReturnsFalseAfterHasListenersWithEventHasBeenCalled()
296+
{
297+
$this->assertFalse($this->dispatcher->hasListeners('foo'));
298+
$this->assertFalse($this->dispatcher->hasListeners());
299+
}
300+
}
301+
302+
class CallableClass
303+
{
304+
public function __invoke()
305+
{
306+
}
307+
}
308+
309+
class TestEventListener
310+
{
311+
public $preFooInvoked = false;
312+
public $postFooInvoked = false;
313+
314+
/* Listener methods */
315+
316+
public function preFoo(Event $e)
317+
{
318+
$this->preFooInvoked = true;
319+
}
320+
321+
public function postFoo(Event $e)
322+
{
323+
$this->postFooInvoked = true;
324+
325+
$e->stopPropagation();
326+
}
327+
}
328+
329+
class TestWithDispatcher
330+
{
331+
public $name;
332+
public $dispatcher;
333+
334+
public function foo(Event $e, $name, $dispatcher)
335+
{
336+
$this->name = $name;
337+
$this->dispatcher = $dispatcher;
338+
}
339+
}
340+
341+
class TestEventSubscriber implements EventSubscriberInterface
342+
{
343+
public static function getSubscribedEvents()
344+
{
345+
return array('pre.foo' => 'preFoo', 'post.foo' => 'postFoo');
346+
}
347+
}
348+
349+
class TestEventSubscriberWithPriorities implements EventSubscriberInterface
350+
{
351+
public static function getSubscribedEvents()
352+
{
353+
return array(
354+
'pre.foo' => array('preFoo', 10),
355+
'post.foo' => array('postFoo'),
356+
);
357+
}
358+
}
359+
360+
class TestEventSubscriberWithMultipleListeners implements EventSubscriberInterface
361+
{
362+
public static function getSubscribedEvents()
363+
{
364+
return array('pre.foo' => array(
365+
array('preFoo1'),
366+
array('preFoo2', 10),
367+
));
368+
}
369+
}

src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
use Symfony\Component\EventDispatcher\Event;
1818
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1919

20-
class ContainerAwareEventDispatcherTest extends \PHPUnit_Framework_TestCase
20+
class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
2121
{
22+
protected function createEventDispatcher()
23+
{
24+
$container = new Container();
25+
return new ContainerAwareEventDispatcher($container);
26+
}
27+
2228
public function testAddAListenerService()
2329
{
2430
$event = new Event();

0 commit comments

Comments
 (0)