Passed
Pull Request — master (#1)
by Alex
07:28
created

EventDispatcherFactoryTest::testIsCallable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\LaminasEvent\Factory;
6
7
use Arp\EventDispatcher\EventDispatcher;
8
use Arp\EventDispatcher\Listener\AddableListenerProviderInterface;
9
use Arp\EventDispatcher\Listener\ListenerProvider;
10
use Arp\LaminasEvent\Factory\EventDispatcherFactory;
11
use Arp\LaminasFactory\FactoryInterface;
12
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
13
use Laminas\ServiceManager\ServiceLocatorInterface;
14
use PHPUnit\Framework\MockObject\MockObject;
15
use PHPUnit\Framework\TestCase;
16
use Psr\EventDispatcher\EventDispatcherInterface;
17
use Psr\EventDispatcher\ListenerProviderInterface;
18
19
/**
20
 * @covers  \Arp\LaminasEvent\Factory\EventDispatcherFactory
21
 * @covers  \Arp\LaminasEvent\Factory\AbstractEventDispatcherFactory
22
 *
23
 * @author  Alex Patterson <[email protected]>
24
 * @package ArpTest\LaminasEvent\Factory
25
 */
26
final class EventDispatcherFactoryTest extends TestCase
27
{
28
    /**
29
     * @var ServiceLocatorInterface&MockObject
30
     */
31
    private $container;
32
33
    /**
34
     * Prepare the test case dependencies
35
     */
36
    public function setUp(): void
37
    {
38
        $this->container = $this->createMock(ServiceLocatorInterface::class);
39
    }
40
41
    /**
42
     * Assert the factory is callable
43
     */
44
    public function testIsCallable(): void
45
    {
46
        $factory = new EventDispatcherFactory();
47
48
        $this->assertIsCallable($factory);
49
    }
50
51
    /**
52
     * Assert the class implement FactoryInterface
53
     */
54
    public function testImplementsFactoryInterface(): void
55
    {
56
        $factory = new EventDispatcherFactory();
57
58
        $this->assertInstanceOf(FactoryInterface::class, $factory);
59
    }
60
61
    /**
62
     * @throws ServiceNotCreatedException
63
     */
64
    public function testInvalidListenerProviderWillThrowServiceNotCreatedException(): void
65
    {
66
        $factory = new EventDispatcherFactory();
67
68
        $serviceName = EventDispatcherInterface::class;
69
        $options = [
70
            'listener_provider' => false,
71
        ];
72
73
        $this->expectException(ServiceNotCreatedException::class);
74
        $this->expectExceptionMessage(
75
            sprintf(
76
                'The listener provider must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
77
                ListenerProviderInterface::class,
78
                'boolean',
79
                $serviceName
80
            )
81
        );
82
83
        $factory($this->container, $serviceName, $options);
84
    }
85
86
    /**
87
     * Assert that if provided with a ListenerProvider configuration that does not implement
88
     * AddableListenerProviderInterface a ServiceNotCreatedException will be thrown
89
     *
90
     * @throws ServiceNotCreatedException
91
     */
92
    public function testNonAddableListenerProviderWillThrowServiceNotCreatedException(): void
93
    {
94
        $factory = new EventDispatcherFactory();
95
96
        $serviceName = EventDispatcherInterface::class;
97
        $listenerProviderName = ListenerProviderInterface::class;
98
        $options = [
99
            'listener_provider' => $listenerProviderName,
100
        ];
101
102
        $this->container->expects($this->once())
103
            ->method('has')
104
            ->with($listenerProviderName)
105
            ->willReturn(true);
106
107
        /** @var ListenerProviderInterface&MockObject $listenerProvider */
108
        $listenerProvider = $this->createMock(ListenerProviderInterface::class);
109
110
        $this->container->expects($this->once())
111
            ->method('get')
112
            ->with($listenerProviderName)
113
            ->willReturn($listenerProvider);
114
115
        $this->expectException(ServiceNotCreatedException::class);
116
        $this->expectExceptionMessage(
117
            sprintf(
118
                'The listener provider must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
119
                AddableListenerProviderInterface::class,
120
                get_class($listenerProvider),
121
                $serviceName
122
            )
123
        );
124
125
        $factory($this->container, $serviceName, $options);
126
    }
127
128
    /**
129
     * Assert that __invoke() will return a composed EventDispatcher instance
130
     *
131
     * @param mixed $listenerProviderConfig
132
     *
133
     * @dataProvider getEventDispatcherFactoryWillReturnConfiguredEventDispatcherData
134
     *
135
     * @throws ServiceNotCreatedException
136
     */
137
    public function testEventDispatcherFactoryWillReturnConfiguredEventDispatcher($listenerProviderConfig): void
138
    {
139
        $factory = new EventDispatcherFactory();
140
141
        $serviceName = EventDispatcherInterface::class;
142
        $options = [
143
            'listener_provider' => $listenerProviderConfig,
144
        ];
145
146
        /** @var AddableListenerProviderInterface&MockObject $listenerProvider */
147
        $listenerProvider = $this->createMock(AddableListenerProviderInterface::class);
148
149
        if (is_string($listenerProviderConfig)) {
150
            $this->container->expects($this->once())
151
                ->method('has')
152
                ->with($listenerProviderConfig)
153
                ->willReturn(true);
154
155
            $this->container->expects($this->once())
156
                ->method('get')
157
                ->with($listenerProviderConfig)
158
                ->willReturn($listenerProvider);
159
        } elseif (is_array($listenerProviderConfig)) {
160
            $this->container->expects($this->once())
161
                ->method('build')
162
                ->with(ListenerProviderInterface::class, $listenerProviderConfig)
163
                ->willReturn($listenerProvider);
164
        }
165
166
        $this->assertInstanceOf(EventDispatcher::class, $factory($this->container, $serviceName, $options));
167
    }
168
169
    /**
170
     * @return array<mixed>
171
     */
172
    public function getEventDispatcherFactoryWillReturnConfiguredEventDispatcherData(): array
173
    {
174
        return [
175
            [
176
                ListenerProvider::class,
177
            ],
178
179
            [
180
                [
181
                    'foo' => 'bar',
182
                    'test' => 'hello'
183
                ],
184
            ],
185
186
            [
187
                $this->createMock(AddableListenerProviderInterface::class),
188
            ]
189
        ];
190
    }
191
}
192