Completed
Push — master ( 7b43ed...6cb3bb )
by Frank
01:43
created

src/EventDispatcherTest.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Event;
6
7
use PHPUnit\Framework\TestCase;
8
use Psr\EventDispatcher\ListenerProviderInterface;
9
use stdClass;
10
11
class EventDispatcherTest extends TestCase
12
{
13
    /**
14
     * @test
15
     */
16
    public function listening_to_a_plain_object_event(): void
17
    {
18
        $dispatcher = new EventDispatcher();
19
        $listenerSpy = new ListenerSpy();
20
        $event = new stdClass;
21
22
        $dispatcher->subscribeTo(stdClass::class, $listenerSpy);
23
        $dispatcher->dispatch($event);
24
25
        $this->assertTrue($listenerSpy->wasCalledWith($event));
26
    }
27
28
    /**
29
     * @test
30
     */
31
    public function listening_to_a_named_event(): void
32
    {
33
        $dispatcher = new EventDispatcher();
34
        $listenerSpy = new ListenerSpy();
35
        $event = new StubNamedEvent('event.name');
36
37
        $dispatcher->subscribeTo('event.name', $listenerSpy);
38
        $dispatcher->dispatch($event);
39
40
        $this->assertTrue($listenerSpy->wasCalledWith($event));
41
    }
42
43
    /**
44
     * @test
45
     */
46
    public function listening_to_a_named_event_ignores_other_names(): void
47
    {
48
        $dispatcher = new EventDispatcher();
49
        $listenerSpy = new ListenerSpy();
50
        $dispatcher->subscribeTo('event.name', $listenerSpy);
51
        $dispatcher->dispatch(new StubNamedEvent('event.name'));
52
        $dispatcher->dispatch(new StubNamedEvent('other.event.name'));
53
54
        $this->assertEquals(1, $listenerSpy->numberOfTimeCalled());
55
    }
56
57
    /**
58
     * @test
59
     */
60 View Code Duplication
    public function it_uses_a_provided_listener_provider(): void
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
61
    {
62
        $listenerSpy = new ListenerSpy();
63
        $provider = new PrioritizedListenerCollection();
64
        $provider->subscribeTo(stdClass::class, $listenerSpy);
65
        $dispatcher = new EventDispatcher($provider);
66
        $event = new stdClass();
67
68
        $dispatcher->dispatch($event);
69
70
        $this->assertTrue($listenerSpy->wasCalledWith($event));
71
    }
72
73
    /**
74
     * @test
75
     */
76 View Code Duplication
    public function it_only_keeps_notifying_handlers_when_the_event_propagation_is_not_stopped(): void
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
    {
78
        $dispatcher = new EventDispatcher();
79
        $listenerSpy = new ListenerSpy();
80
        $event = new StubStoppableEvent();
81
82
        $dispatcher->subscribeTo(
83
            StubStoppableEvent::class,
84
            function (StubStoppableEvent $event) {
85
                $event->stopPropagation();
86
            }
87
        );
88
        $dispatcher->subscribeTo(StubStoppableEvent::class, $listenerSpy);
89
        $dispatcher->dispatch($event);
90
91
        $this->assertFalse($listenerSpy->wasCalledWith($event));
92
    }
93
94
    /**
95
     * @test
96
     */
97
    public function it_calls_one_time_listeners_one_time(): void
98
    {
99
        $normalListener = new ListenerSpy();
100
        $oneTimeListener = new ListenerSpy();
101
102
        $dispatcher = new EventDispatcher();
103
        $dispatcher->subscribeTo(stdClass::class, $normalListener);
104
        $dispatcher->subscribeOnceTo(stdClass::class, $oneTimeListener);
105
106
        $dispatcher->dispatch(new stdClass());
107
        $dispatcher->dispatch(new stdClass());
108
        $dispatcher->dispatch(new stdClass());
109
110
        $this->assertEquals(1, $oneTimeListener->numberOfTimeCalled());
111
        $this->assertEquals(3, $normalListener->numberOfTimeCalled());
112
    }
113
114
    /**
115
     * @test
116
     * @dataProvider dpScenariosCausingSubscribingFailure
117
     */
118
    public function subscribing_does_not_work_when_the_underlying_provider_does_not_allow_subscribing(callable $scenario
119
    ): void {
120
        $provider = new class() implements ListenerProviderInterface {
121
            public function getListenersForEvent(object $event): iterable
122
            {
123
                return [];
124
            }
125
        };
126
        $dispatcher = new EventDispatcher($provider);
127
128
        $this->expectExceptionObject(
129
            UnableToSubscribeListener::becauseTheListenerProviderDoesNotAcceptListeners($provider)
130
        );
131
132
        $scenario($dispatcher);
133
    }
134
135
    public function dpScenariosCausingSubscribingFailure(): iterable
136
    {
137
        yield "subscribing" => [
138
            function (EventDispatcher $dispatcher) {
139
                $dispatcher->subscribeTo(
140
                    'event',
141
                    function () {
142
                    }
143
                );
144
            },
145
        ];
146
147
        yield "subscribing once" => [
148
            function (EventDispatcher $dispatcher) {
149
                $dispatcher->subscribeOnceTo(
150
                    'event',
151
                    function () {
152
                    }
153
                );
154
            },
155
        ];
156
157
        yield "subscribing from subscriber" => [
158
            function (EventDispatcher $dispatcher) {
159
                $dispatcher->subscribeListenersFrom(
160
                    new class () implements ListenerSubscriber {
161
                        public function subscribeListeners(ListenerAcceptor $acceptor): void
162
                        {
163
                        }
164
                    }
165
                );
166
            },
167
        ];
168
    }
169
170
    /**
171
     * @test
172
     */
173
    public function listeners_are_prioritized(): void
174
    {
175
        $dispatcher = new EventDispatcher();
176
        $event = new StubMutableEvent('Hi!');
177
        $append = static function (string $value) {
178
            return static function (StubMutableEvent $event) use ($value) {
179
                $event->append(' ' . $value);
180
            };
181
        };
182
        $appendHello = $append('Hello,');
183
        $appendWorld = $append('World!');
184
        $appendGoodBye = $append('Good bye!');
185
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendWorld, 0);
186
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendHello, 10);
187
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendGoodBye, -10);
188
189
        $dispatcher->dispatch($event);
190
191
        $this->assertEquals('Hi! Hello, World! Good bye!', $event->value());
192
    }
193
194
    /**
195
     * @test
196
     */
197
    public function events_from_an_event_generator_can_be_dispatched(): void
198
    {
199
        $dispatcher = new EventDispatcher();
200
        $listener = new ListenerSpy();
201
        $dispatcher->subscribeTo(stdClass::class, $listener);
202
203
        $eventGenerator = new class () implements EventGenerator {
204
            use EventGeneratorBehavior {
205
                recordEvent as public;
206
            }
207
        };
208
        $eventGenerator->recordEvent(new stdClass());
209
        $eventGenerator->recordEvent(new stdClass());
210
        $eventGenerator->recordEvent(new stdClass());
211
        $dispatcher->dispatchGeneratedEvents($eventGenerator);
212
213
        $this->assertEquals(3, $listener->numberOfTimeCalled());
214
    }
215
216
    /**
217
     * @test
218
     */
219
    public function listeners_can_be_subscribed_through_a_subscriber(): void
220
    {
221
        $subscriber = new class () implements ListenerSubscriber {
222
            public function subscribeListeners(ListenerAcceptor $acceptor): void
223
            {
224
                $acceptor->subscribeTo(
225
                    StubMutableEvent::class,
226
                    function (StubMutableEvent $event) {
227
                        $event->append(' mutated');
228
                    }
229
                );
230
            }
231
        };
232
        $dispatcher = new EventDispatcher();
233
        $dispatcher->subscribeListenersFrom($subscriber);
234
        $event = new StubMutableEvent('this is');
235
        $dispatcher->dispatch($event);
236
237
        $this->assertEquals('this is mutated', $event->value());
238
    }
239
}
240