Completed
Push — master ( 6cb3bb...ba31e6 )
by Frank
01:21 queued 18s
created

EventDispatcherTest   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 242
Duplicated Lines 16.53 %

Importance

Changes 0
Metric Value
wmc 2
dl 40
loc 242
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$0 ➔ getListenersForEvent() 0 4 1
A hp$1 ➔ subscribeListeners() 0 3 1
A hp$3 ➔ subscribeListeners() 0 9 1
A listening_to_a_plain_object_event() 11 11 1
A dispatching_returns_the_event_object() 0 9 1
A listening_to_a_named_event() 0 11 1
A listening_to_a_named_event_ignores_other_names() 0 10 1
A it_uses_a_provided_listener_provider() 12 12 1
A it_only_keeps_notifying_handlers_when_the_event_propagation_is_not_stopped() 17 17 1
A it_calls_one_time_listeners_one_time() 0 16 1
A subscribing_does_not_work_when_the_underlying_provider_does_not_allow_subscribing() 0 16 1
A dpScenariosCausingSubscribingFailure() 0 34 1
A listeners_are_prioritized() 0 20 1
A events_from_an_event_generator_can_be_dispatched() 0 18 1
A listeners_can_be_subscribed_through_a_subscriber() 0 20 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 View Code Duplication
    public function listening_to_a_plain_object_event(): void
0 ignored issues
show
Duplication introduced by Frank de Jonge
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...
17
    {
18
        $dispatcher = new EventDispatcher();
19
        $listenerSpy = new ListenerSpy();
20
        $event = new stdClass;
21
22
        $dispatcher->subscribeTo(stdClass::class, $listenerSpy);
23
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
24
25
        $this->assertTrue($listenerSpy->wasCalledWith($event));
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
26
    }
27
28
    /**
29
     * @test
30
     */
31
    public function dispatching_returns_the_event_object(): void
32
    {
33
        $event = new stdClass();
34
        $dispatcher = new  EventDispatcher();
35
36
        $returnedEvent = $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
37
38
        $this->assertSame($event, $returnedEvent);
39
    }
40
41
    /**
42
     * @test
43
     */
44
    public function listening_to_a_named_event(): void
45
    {
46
        $dispatcher = new EventDispatcher();
47
        $listenerSpy = new ListenerSpy();
48
        $event = new StubNamedEvent('event.name');
49
50
        $dispatcher->subscribeTo('event.name', $listenerSpy);
51
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubNamedEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
52
53
        $this->assertTrue($listenerSpy->wasCalledWith($event));
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubNamedEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
54
    }
55
56
    /**
57
     * @test
58
     */
59
    public function listening_to_a_named_event_ignores_other_names(): void
60
    {
61
        $dispatcher = new EventDispatcher();
62
        $listenerSpy = new ListenerSpy();
63
        $dispatcher->subscribeTo('event.name', $listenerSpy);
64
        $dispatcher->dispatch(new StubNamedEvent('event.name'));
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \League\Event\StubNamedEvent('event.name') is of type object<League\Event\StubNamedEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
65
        $dispatcher->dispatch(new StubNamedEvent('other.event.name'));
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \League\Event\StubNa...ent('other.event.name') is of type object<League\Event\StubNamedEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
66
67
        $this->assertEquals(1, $listenerSpy->numberOfTimeCalled());
68
    }
69
70
    /**
71
     * @test
72
     */
73 View Code Duplication
    public function it_uses_a_provided_listener_provider(): void
0 ignored issues
show
Duplication introduced by Frank de Jonge
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...
74
    {
75
        $listenerSpy = new ListenerSpy();
76
        $provider = new PrioritizedListenerCollection();
77
        $provider->subscribeTo(stdClass::class, $listenerSpy);
78
        $dispatcher = new EventDispatcher($provider);
79
        $event = new stdClass();
80
81
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
82
83
        $this->assertTrue($listenerSpy->wasCalledWith($event));
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
84
    }
85
86
    /**
87
     * @test
88
     */
89 View Code Duplication
    public function it_only_keeps_notifying_handlers_when_the_event_propagation_is_not_stopped(): void
0 ignored issues
show
Duplication introduced by Frank de Jonge
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...
90
    {
91
        $dispatcher = new EventDispatcher();
92
        $listenerSpy = new ListenerSpy();
93
        $event = new StubStoppableEvent();
94
95
        $dispatcher->subscribeTo(
96
            StubStoppableEvent::class,
97
            function (StubStoppableEvent $event) {
98
                $event->stopPropagation();
99
            }
100
        );
101
        $dispatcher->subscribeTo(StubStoppableEvent::class, $listenerSpy);
102
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubStoppableEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
103
104
        $this->assertFalse($listenerSpy->wasCalledWith($event));
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubStoppableEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
    }
106
107
    /**
108
     * @test
109
     */
110
    public function it_calls_one_time_listeners_one_time(): void
111
    {
112
        $normalListener = new ListenerSpy();
113
        $oneTimeListener = new ListenerSpy();
114
115
        $dispatcher = new EventDispatcher();
116
        $dispatcher->subscribeTo(stdClass::class, $normalListener);
117
        $dispatcher->subscribeOnceTo(stdClass::class, $oneTimeListener);
118
119
        $dispatcher->dispatch(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
120
        $dispatcher->dispatch(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
121
        $dispatcher->dispatch(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
122
123
        $this->assertEquals(1, $oneTimeListener->numberOfTimeCalled());
124
        $this->assertEquals(3, $normalListener->numberOfTimeCalled());
125
    }
126
127
    /**
128
     * @test
129
     * @dataProvider dpScenariosCausingSubscribingFailure
130
     */
131
    public function subscribing_does_not_work_when_the_underlying_provider_does_not_allow_subscribing(callable $scenario
132
    ): void {
133
        $provider = new class() implements ListenerProviderInterface {
134
            public function getListenersForEvent(object $event): iterable
135
            {
136
                return [];
137
            }
138
        };
139
        $dispatcher = new EventDispatcher($provider);
140
141
        $this->expectExceptionObject(
142
            UnableToSubscribeListener::becauseTheListenerProviderDoesNotAcceptListeners($provider)
143
        );
144
145
        $scenario($dispatcher);
146
    }
147
148
    public function dpScenariosCausingSubscribingFailure(): iterable
149
    {
150
        yield "subscribing" => [
151
            function (EventDispatcher $dispatcher) {
152
                $dispatcher->subscribeTo(
153
                    'event',
154
                    function () {
155
                    }
156
                );
157
            },
158
        ];
159
160
        yield "subscribing once" => [
161
            function (EventDispatcher $dispatcher) {
162
                $dispatcher->subscribeOnceTo(
163
                    'event',
164
                    function () {
165
                    }
166
                );
167
            },
168
        ];
169
170
        yield "subscribing from subscriber" => [
171
            function (EventDispatcher $dispatcher) {
172
                $dispatcher->subscribeListenersFrom(
173
                    new class () implements ListenerSubscriber {
174
                        public function subscribeListeners(ListenerAcceptor $acceptor): void
175
                        {
176
                        }
177
                    }
178
                );
179
            },
180
        ];
181
    }
182
183
    /**
184
     * @test
185
     */
186
    public function listeners_are_prioritized(): void
187
    {
188
        $dispatcher = new EventDispatcher();
189
        $event = new StubMutableEvent('Hi!');
190
        $append = static function (string $value) {
191
            return static function (StubMutableEvent $event) use ($value) {
192
                $event->append(' ' . $value);
193
            };
194
        };
195
        $appendHello = $append('Hello,');
196
        $appendWorld = $append('World!');
197
        $appendGoodBye = $append('Good bye!');
198
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendWorld, 0);
199
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendHello, 10);
200
        $dispatcher->subscribeTo(StubMutableEvent::class, $appendGoodBye, -10);
201
202
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubMutableEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
203
204
        $this->assertEquals('Hi! Hello, World! Good bye!', $event->value());
205
    }
206
207
    /**
208
     * @test
209
     */
210
    public function events_from_an_event_generator_can_be_dispatched(): void
211
    {
212
        $dispatcher = new EventDispatcher();
213
        $listener = new ListenerSpy();
214
        $dispatcher->subscribeTo(stdClass::class, $listener);
215
216
        $eventGenerator = new class () implements EventGenerator {
217
            use EventGeneratorBehavior {
218
                recordEvent as public;
219
            }
220
        };
221
        $eventGenerator->recordEvent(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
222
        $eventGenerator->recordEvent(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
223
        $eventGenerator->recordEvent(new stdClass());
0 ignored issues
show
Documentation introduced by Frank de Jonge
new \stdClass() is of type object<stdClass>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
224
        $dispatcher->dispatchGeneratedEvents($eventGenerator);
225
226
        $this->assertEquals(3, $listener->numberOfTimeCalled());
227
    }
228
229
    /**
230
     * @test
231
     */
232
    public function listeners_can_be_subscribed_through_a_subscriber(): void
233
    {
234
        $subscriber = new class () implements ListenerSubscriber {
235
            public function subscribeListeners(ListenerAcceptor $acceptor): void
236
            {
237
                $acceptor->subscribeTo(
238
                    StubMutableEvent::class,
239
                    function (StubMutableEvent $event) {
240
                        $event->append(' mutated');
241
                    }
242
                );
243
            }
244
        };
245
        $dispatcher = new EventDispatcher();
246
        $dispatcher->subscribeListenersFrom($subscriber);
247
        $event = new StubMutableEvent('this is');
248
        $dispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by Frank de Jonge
$event is of type object<League\Event\StubMutableEvent>, but the function expects a object<League\Event\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
249
250
        $this->assertEquals('this is mutated', $event->value());
251
    }
252
}
253