Passed
Pull Request — master (#18)
by Alex
06:24 queued 03:24
created

testLazyListenerWillCreateAndDispatchEvent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 10
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\EventDispatcher\Listener;
6
7
use Arp\EventDispatcher\Listener\Exception\EventListenerException;
8
use Arp\EventDispatcher\Listener\LazyListener;
9
use PHPUnit\Framework\ExpectationFailedException;
10
use PHPUnit\Framework\TestCase;
11
12
/**
13
 * @covers  \Arp\EventDispatcher\Listener\LazyListener
14
 *
15
 * @author  Alex Patterson <[email protected]>
16
 * @package ArpTest\EventDispatcher\Listener
17
 */
18
final class LazyListenerTest extends TestCase
19
{
20
    /**
21
     * testIsCallable
22
     */
23
    public function testIsCallable(): void
24
    {
25
        $listener = new LazyListener(
26
            static function () {
27
            }
28
        );
29
30
        $this->assertIsCallable($listener);
31
    }
32
33
    /**
34
     * Assert a EventListenerException is thrown from __construct if the provided $factory is invalid
35
     *
36
     * @param mixed $factory
37
     *
38
     * @dataProvider getConstructWillThrowEventListenerExceptionIfTheConfiguredFactoryIsNotCallableData
39
     */
40
    public function testConstructWillThrowEventListenerExceptionIfTheConfiguredFactoryIsNotCallable($factory): void
41
    {
42
        $this->expectException(EventListenerException::class);
43
        $this->expectExceptionMessage(
44
            sprintf(
45
                'The event listener factory must be of type \'callable\' or \'object\'; \'%s\' provided in \'%s\'',
46
                is_object($factory) ? get_class($factory) : gettype($factory),
47
                LazyListener::class
48
            )
49
        );
50
51
        new LazyListener($factory);
52
    }
53
54
    /**
55
     * @return array<mixed>
56
     */
57
    public function getConstructWillThrowEventListenerExceptionIfTheConfiguredFactoryIsNotCallableData(): array
58
    {
59
        return [
60
            ['hello'],
61
            [true],
62
            [123],
63
        ];
64
    }
65
66
    /**
67
     * Assert that non-callable factory methods will raise a EventListenerException in __invoke()
68
     *
69
     * @throws EventListenerException
70
     */
71
    public function testInvokeWillThrowEventListenerExceptionIfTheFactoryMethodIsNotCallable(): void
72
    {
73
        $event = new \stdClass();
74
        $factory = new \stdClass();
75
76
        $lazyListener = new LazyListener($factory);
77
78
        $this->expectException(EventListenerException::class);
79
        $this->expectExceptionMessage(
80
            sprintf(
81
                'The method \'%s\' is not callable for lazy load factory \'%s\'',
82
                '__invoke',
83
                'array'
84
            )
85
        );
86
87
        $lazyListener($event);
88
    }
89
90
    /**
91
     * Assert that a non-callable listener method will raise a EventListenerException in __invoke()
92
     *
93
     * @throws EventListenerException
94
     */
95
    public function testInvokeWillThrowEventListenerExceptionIfTheListenerMethodIsNotCallable(): void
96
    {
97
        $event = new \stdClass();
98
        $listener = new \stdClass();
99
        $factory = static fn () => $listener;
100
101
        $lazyListener = new LazyListener($factory);
102
103
        $this->expectException(EventListenerException::class);
104
        $this->expectExceptionMessage(
105
            sprintf(
106
                'The method \'%s\' is not callable for lazy load event listener \'%s\'',
107
                '__invoke',
108
                'array'
109
            )
110
        );
111
112
        $lazyListener($event);
113
    }
114
115
    /**
116
     * @param mixed       $expected
117
     * @param mixed       $factory
118
     * @param string|null $factoryMethod
119
     * @param string|null $listenerMethod
120
     *
121
     * @throws EventListenerException
122
     * @throws ExpectationFailedException
123
     *
124
     * @dataProvider getLazyListenerWillCreateAndDispatchEventData
125
     */
126
    public function testLazyListenerWillCreateAndDispatchEvent(
127
        $expected,
128
        $factory,
129
        ?string $factoryMethod = null,
130
        ?string $listenerMethod = null
131
    ): void {
132
        $event = new \stdClass();
133
        $lazyListener = new LazyListener($factory, $factoryMethod, $listenerMethod);
134
135
        $this->assertSame($expected, $lazyListener($event));
136
    }
137
138
    /**
139
     * @return array<mixed>
140
     */
141
    public function getLazyListenerWillCreateAndDispatchEventData(): array
142
    {
143
        $factory1 = new class () {
144
            public function create(): callable
145
            {
146
                return static fn () => 'hello123';
147
            }
148
        };
149
150
        $listener1 = new class () {
151
            public function doSomething(object $event): string
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

151
            public function doSomething(/** @scrutinizer ignore-unused */ object $event): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
152
            {
153
                return 'test123';
154
            }
155
        };
156
157
        $factory2 = new class ($listener1) {
158
            private object $listener;
159
160
            public function __construct(object $listener)
161
            {
162
                $this->listener = $listener;
163
            }
164
165
            public function create(): object
166
            {
167
                return $this->listener;
168
            }
169
        };
170
171
        return [
172
            [
173
                'hello123',
174
                static fn () => static fn () => 'hello123',
175
            ],
176
177
            [
178
                'hello123',
179
                $factory1,
180
                'create'
181
            ],
182
183
            [
184
                'test123',
185
                $factory2,
186
                'create',
187
                'doSomething',
188
            ]
189
        ];
190
    }
191
}
192