Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 953fa75

Browse files
committed
Incorporate feedback
- Updated EventManagerIntrospectionTrait: - Made methods private. - Added `getArrayOfListenersForEvent()`; casts to array before returning; used for counting listeners and/or traversal where priority isn't interesting. - Added `assertListenerAtPriority()` for simplifying assertions looking for specific listeners registered at specific priorities. - Added docblocks to all methods. - Updated tests per the above. - Various other small changes as suggested by @Ocramius.
1 parent 3bdb9f4 commit 953fa75

13 files changed

+196
-201
lines changed

src/Application.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ protected function completeRequest(MvcEvent $event)
365365

366366
$event->setName(MvcEvent::EVENT_FINISH);
367367
$events->triggerEvent($event);
368+
368369
return $this;
369370
}
370371
}

src/Controller/ControllerManager.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ public function injectControllerDependencies($controller, ServiceLocatorInterfac
7474
// is why the shared EM injection needs to happen; the conditional
7575
// will always pass.
7676
$events = $controller->getEventManager();
77-
if (! $events instanceof EventManagerInterface
78-
|| ! $events->getSharedManager() instanceof SharedEventManagerInterface
79-
) {
77+
if (! $events || ! $events->getSharedManager() instanceof SharedEventManagerInterface) {
8078
$controller->setEventManager($parentLocator->get('EventManager'));
8179
}
8280
}

src/DispatchListener.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ public function onDispatch(MvcEvent $e)
9999
$e->setControllerClass(get_class($controller));
100100
$e->setParam('exception', $ex);
101101

102-
$results = $events->triggerEvent($e);
103-
$return = $results->last();
102+
$return = $events->triggerEvent($e)->last();
104103
if (! $return) {
105104
$return = $e->getResult();
106105
}

test/ApplicationTest.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use stdClass;
1717
use Zend\Http\PhpEnvironment\Response;
1818
use Zend\ModuleManager\Listener\ConfigListener;
19+
use Zend\ModuleManager\ModuleEvent;
1920
use Zend\Mvc\Application;
2021
use Zend\Mvc\MvcEvent;
2122
use Zend\Mvc\Router;
@@ -74,17 +75,17 @@ public function setUp()
7475

7576
public function getConfigListener()
7677
{
77-
$manager = $this->serviceManager->get('ModuleManager');
78-
foreach ($this->getListenersForEvent('loadModule', $manager->getEventManager()) as $listener) {
79-
if (! is_array($listener)) {
80-
continue;
78+
$manager = $this->serviceManager->get('ModuleManager');
79+
$listeners = $this->getArrayOfListenersForEvent(ModuleEvent::EVENT_LOAD_MODULE, $manager->getEventManager());
80+
return array_reduce($listeners, function ($found, $listener) {
81+
if ($found || ! is_array($listener)) {
82+
return $found;
8183
}
82-
$object = array_shift($listener);
83-
if (! $object instanceof ConfigListener) {
84-
continue;
84+
$listener = array_shift($listener);
85+
if ($listener instanceof ConfigListener) {
86+
return $listener;
8587
}
86-
return $object;
87-
}
88+
});
8889
}
8990

9091
public function testRequestIsPopulatedFromServiceManager()
@@ -153,13 +154,8 @@ public function testBootstrapRegistersListeners($listenerServiceName, $event, $m
153154
$events = $this->application->getEventManager();
154155

155156
$foundListener = false;
156-
foreach ($this->getListenersForEvent($event, $events) as $listener) {
157-
$foundListener = $listener === [$listenerService, $method];
158-
if ($foundListener) {
159-
break;
160-
}
161-
}
162-
$this->assertTrue($foundListener);
157+
$listeners = $this->getArrayOfListenersForEvent($event, $events);
158+
$this->assertContains([$listenerService, $method], $listeners);
163159
}
164160

165161
public function bootstrapRegistersListenersProvider()

test/EventManagerIntrospectionTrait.php

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,39 @@
1717
*/
1818
trait EventManagerIntrospectionTrait
1919
{
20-
public function getEventsFromEventManager(EventManager $events)
20+
/**
21+
* Retrieve a list of event names from an event manager.
22+
*
23+
* @param EventManager $events
24+
* @return string[]
25+
*/
26+
private function getEventsFromEventManager(EventManager $events)
2127
{
2228
$r = new ReflectionProperty($events, 'events');
2329
$r->setAccessible(true);
2430
$listeners = $r->getValue($events);
2531
return array_keys($listeners);
2632
}
2733

28-
public function getListenersForEvent($event, EventManager $events, $withPriority = false)
34+
/**
35+
* Retrieve an interable list of listeners for an event.
36+
*
37+
* Given an event and an event manager, returns an iterator with the
38+
* listeners for that event, in priority order.
39+
*
40+
* If $withPriority is true, the key values will be the priority at which
41+
* the given listener is attached.
42+
*
43+
* Do not pass $withPriority if you want to cast the iterator to an array,
44+
* as many listeners will likely have the same priority, and thus casting
45+
* will collapse to the last added.
46+
*
47+
* @param string $event
48+
* @param EventManager $events
49+
* @param bool $withPriority
50+
* @return \Traversable
51+
*/
52+
private function getListenersForEvent($event, EventManager $events, $withPriority = false)
2953
{
3054
$r = new ReflectionProperty($events, 'events');
3155
$r->setAccessible(true);
@@ -38,6 +62,62 @@ public function getListenersForEvent($event, EventManager $events, $withPriority
3862
return $this->traverseListeners($listeners[$event], $withPriority);
3963
}
4064

65+
/**
66+
* Assert that a given listener exists at the specified priority.
67+
*
68+
* @param callable $expectedListener
69+
* @param int $expectedPriority
70+
* @param string $event
71+
* @param EventManager $events
72+
* @param string $message Failure message to use, if any.
73+
*/
74+
private function assertListenerAtPriority(
75+
callable $expectedListener,
76+
$expectedPriority,
77+
$event,
78+
EventManager $events,
79+
$message = ''
80+
) {
81+
$message = $message ?: sprintf(
82+
'Listener not found for event "%s" and priority %d',
83+
$event,
84+
$expectedPriority
85+
);
86+
$listeners = $this->getListenersForEvent($event, $events, true);
87+
$found = false;
88+
foreach ($listeners as $priority => $listener) {
89+
if ($listener === $expectedListener
90+
&& $priority === $expectedPriority
91+
) {
92+
$found = true;
93+
break;
94+
}
95+
}
96+
$this->assertTrue($found, $message);
97+
}
98+
99+
/**
100+
* Returns an indexed array of listeners for an event.
101+
*
102+
* Returns an indexed array of listeners for an event, in priority order.
103+
* Priority values will not be included; use this only for testing if
104+
* specific listeners are present, or for a count of listeners.
105+
*
106+
* @param string $event
107+
* @param EventManager $events
108+
* @return callable[]
109+
*/
110+
private function getArrayOfListenersForEvent($event, EventManager $events)
111+
{
112+
return iterator_to_array($this->getListenersForEvent($event, $events));
113+
}
114+
115+
/**
116+
* Generator for traversing listeners in priority order.
117+
*
118+
* @param array $listeners
119+
* @param bool $withPriority When true, yields priority as key.
120+
*/
41121
public function traverseListeners(array $queue, $withPriority = false)
42122
{
43123
krsort($queue, SORT_NUMERIC);

test/View/Console/DefaultRenderingStrategyTest.php

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class DefaultRenderingStrategyTest extends TestCase
2424
{
2525
use EventManagerIntrospectionTrait;
2626

27-
/* @var DefaultRenderingStrategy */
27+
/** @var DefaultRenderingStrategy */
2828
protected $strategy;
2929

3030
public function setUp()
@@ -36,34 +36,25 @@ public function testAttachesRendererAtExpectedPriority()
3636
{
3737
$events = new EventManager();
3838
$this->strategy->attach($events);
39-
$listeners = $this->getListenersForEvent(MvcEvent::EVENT_RENDER, $events, true);
40-
41-
$expectedListener = [$this->strategy, 'render'];
42-
$expectedPriority = -10000;
43-
$found = false;
44-
45-
/* @var \Zend\Stdlib\CallbackHandler $listener */
46-
foreach ($listeners as $priority => $listener) {
47-
if ($listener === $expectedListener
48-
&& $priority === $expectedPriority
49-
) {
50-
$found = true;
51-
break;
52-
}
53-
}
54-
$this->assertTrue($found, 'Renderer not found');
39+
$this->assertListenerAtPriority(
40+
[$this->strategy, 'render'],
41+
-10000,
42+
MvcEvent::EVENT_RENDER,
43+
$events,
44+
'Renderer listener not found'
45+
);
5546
}
5647

5748
public function testCanDetachListenersFromEventManager()
5849
{
5950
$events = new EventManager();
6051
$this->strategy->attach($events);
6152

62-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_RENDER, $events));
53+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events);
6354
$this->assertCount(1, $listeners);
6455

6556
$this->strategy->detach($events);
66-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_RENDER, $events));
57+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events);
6758
$this->assertCount(0, $listeners);
6859
}
6960

test/View/Console/ExceptionStrategyTest.php

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,21 @@ public function testEventListeners()
3333
$events = new EventManager();
3434
$this->strategy->attach($events);
3535

36-
$listeners = $this->getListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events, true);
37-
$expectedListener = [$this->strategy, 'prepareExceptionViewModel'];
38-
$expectedPriority = 1;
39-
$found = false;
40-
foreach ($listeners as $priority => $listener) {
41-
if ($listener === $expectedListener
42-
&& $priority === $expectedPriority
43-
) {
44-
$found = true;
45-
break;
46-
}
47-
}
48-
$this->assertTrue($found, 'MvcEvent::EVENT_DISPATCH_ERROR not found');
49-
50-
$listeners = $this->getListenersForEvent(MvcEvent::EVENT_RENDER_ERROR, $events, true);
51-
$expectedListener = [$this->strategy, 'prepareExceptionViewModel'];
52-
$expectedPriority = 1;
53-
$found = false;
54-
foreach ($listeners as $priority => $listener) {
55-
if ($listener === $expectedListener
56-
&& $priority === $expectedPriority
57-
) {
58-
$found = true;
59-
break;
60-
}
61-
}
62-
$this->assertTrue($found, 'MvcEvent::EVENT_RENDER_ERROR not found');
36+
$this->assertListenerAtPriority(
37+
[$this->strategy, 'prepareExceptionViewModel'],
38+
1,
39+
MvcEvent::EVENT_DISPATCH_ERROR,
40+
$events,
41+
'MvcEvent::EVENT_DISPATCH_ERROR listener not found'
42+
);
43+
44+
$this->assertListenerAtPriority(
45+
[$this->strategy, 'prepareExceptionViewModel'],
46+
1,
47+
MvcEvent::EVENT_RENDER_ERROR,
48+
$events,
49+
'MvcEvent::EVENT_RENDER_ERROR listener not found'
50+
);
6351
}
6452

6553
public function testDefaultDisplayExceptions()

test/View/CreateViewModelListenerTest.php

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -73,41 +73,31 @@ public function testAttachesListenersAtExpectedPriority()
7373
{
7474
$events = new EventManager();
7575
$this->listener->attach($events);
76-
$listeners = $this->getListenersForEvent(MvcEvent::EVENT_DISPATCH, $events, true);
77-
78-
$expectedArrayListener = [$this->listener, 'createViewModelFromArray'];
79-
$expectedNullListener = [$this->listener, 'createViewModelFromNull'];
80-
$expectedPriority = -80;
81-
$foundArray = false;
82-
$foundNull = false;
83-
foreach ($listeners as $priority => $listener) {
84-
if ($listener === $expectedArrayListener
85-
&& $priority === $expectedPriority
86-
) {
87-
$foundArray = true;
88-
continue;
89-
}
90-
91-
if ($listener === $expectedNullListener
92-
&& $priority === $expectedPriority
93-
) {
94-
$foundNull = true;
95-
continue;
96-
}
97-
}
98-
$this->assertTrue($foundArray, 'Listener FromArray not found');
99-
$this->assertTrue($foundNull, 'Listener FromNull not found');
76+
$this->assertListenerAtPriority(
77+
[$this->listener, 'createViewModelFromArray'],
78+
-80,
79+
MvcEvent::EVENT_DISPATCH,
80+
$events,
81+
'Did not find createViewModelFromArray listener in event list at expected priority'
82+
);
83+
$this->assertListenerAtPriority(
84+
[$this->listener, 'createViewModelFromNull'],
85+
-80,
86+
MvcEvent::EVENT_DISPATCH,
87+
$events,
88+
'Did not find createViewModelFromNull listener in event list at expected priority'
89+
);
10090
}
10191

10292
public function testDetachesListeners()
10393
{
10494
$events = new EventManager();
10595
$this->listener->attach($events);
106-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_DISPATCH, $events));
96+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events);
10797
$this->assertEquals(2, count($listeners));
10898

10999
$this->listener->detach($events);
110-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_DISPATCH, $events));
100+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events);
111101
$this->assertEquals(0, count($listeners));
112102
}
113103

test/View/DefaultRendereringStrategyTest.php

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,25 @@ public function testAttachesRendererAtExpectedPriority()
5757
$events = [MvcEvent::EVENT_RENDER, MvcEvent::EVENT_RENDER_ERROR];
5858

5959
foreach ($events as $event) {
60-
$listeners = $this->getListenersForEvent($event, $evm, true);
61-
62-
$expectedListener = [$this->strategy, 'render'];
63-
$expectedPriority = -10000;
64-
$found = false;
65-
foreach ($listeners as $priority => $listener) {
66-
if ($listener === $expectedListener
67-
&& $priority === $expectedPriority
68-
) {
69-
$found = true;
70-
break;
71-
}
72-
}
73-
$this->assertTrue($found, 'Renderer not found');
60+
$this->assertListenerAtPriority(
61+
[$this->strategy, 'render'],
62+
-10000,
63+
$event,
64+
$evm,
65+
'Renderer not found'
66+
);
7467
}
7568
}
7669

7770
public function testCanDetachListenersFromEventManager()
7871
{
7972
$events = new EventManager();
8073
$this->strategy->attach($events);
81-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_RENDER, $events));
74+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events);
8275
$this->assertCount(1, $listeners);
8376

8477
$this->strategy->detach($events);
85-
$listeners = iterator_to_array($this->getListenersForEvent(MvcEvent::EVENT_RENDER, $events));
78+
$listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events);
8679
$this->assertCount(0, $listeners);
8780
}
8881

0 commit comments

Comments
 (0)