Passed
Push — master ( 755731...71ac2a )
by Dmitriy
02:36
created

createServiceCollector()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug\Tests\Unit\Collector;
6
7
use PHPUnit\Framework\TestCase;
8
use Psr\Container\ContainerExceptionInterface;
9
use Psr\Container\ContainerInterface;
10
use Psr\EventDispatcher\EventDispatcherInterface;
11
use Psr\EventDispatcher\ListenerProviderInterface;
12
use Psr\Log\LoggerInterface;
13
use Psr\Log\NullLogger;
14
use stdClass;
15
use Yiisoft\Di\Container;
16
use Yiisoft\Di\ContainerConfig;
17
use Yiisoft\EventDispatcher\Dispatcher\Dispatcher;
18
use Yiisoft\EventDispatcher\Provider\Provider;
19
use Yiisoft\Files\FileHelper;
20
use Yiisoft\Yii\Debug\Collector\CollectorInterface;
21
use Yiisoft\Yii\Debug\Collector\ContainerInterfaceProxy;
22
use Yiisoft\Yii\Debug\Collector\ContainerProxyConfig;
23
use Yiisoft\Yii\Debug\Collector\EventCollector;
24
use Yiisoft\Yii\Debug\Collector\EventDispatcherInterfaceProxy;
25
use Yiisoft\Yii\Debug\Collector\LogCollector;
26
use Yiisoft\Yii\Debug\Collector\LoggerInterfaceProxy;
27
use Yiisoft\Yii\Debug\Collector\ServiceCollector;
28
use Yiisoft\Yii\Debug\Collector\TimelineCollector;
29
30
class ContainerInterfaceProxyTest extends TestCase
31
{
32
    private string $path = 'tests/container-proxy';
33
34
    protected function tearDown(): void
35
    {
36
        parent::tearDown();
37
        FileHelper::removeDirectory($this->path);
38
    }
39
40
    public function testImmutability(): void
41
    {
42
        $containerProxy = new ContainerInterfaceProxy(new Container(ContainerConfig::create()), new ContainerProxyConfig());
43
44
        $this->assertNotSame(
45
            $containerProxy,
46
            $containerProxy->withDecoratedServices(
47
                [
48
                    LoggerInterface::class => [LoggerInterfaceProxy::class, LogCollector::class],
49
                ]
50
            )
51
        );
52
    }
53
54
    public function testGetAndHas(): void
55
    {
56
        $containerProxy = new ContainerInterfaceProxy($this->getContainer(), $this->getConfig());
57
58
        $this->assertTrue($containerProxy->isActive());
59
        $this->assertTrue($containerProxy->has(LoggerInterface::class));
60
        $this->assertInstanceOf(LoggerInterfaceProxy::class, $containerProxy->get(LoggerInterface::class));
61
    }
62
63
    public function testGetAndHasWithCallableServices(): void
64
    {
65
        $dispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
66
        $config = new ContainerProxyConfig(
67
            true,
68
            [
69
                LoggerInterface::class => fn (ContainerInterface $container) => $container->get(LoggerInterfaceProxy::class),
70
                EventDispatcherInterface::class => [
71
                    EventDispatcherInterfaceProxy::class,
72
                    EventCollector::class,
73
                ],
74
            ],
75
            $dispatcherMock,
76
            $this->createServiceCollector(),
77
            $this->path,
78
            1
79
        );
80
        $containerProxy = new ContainerInterfaceProxy($this->getContainer(), $config);
81
82
        $this->assertTrue($containerProxy->isActive());
83
        $this->assertTrue($containerProxy->has(LoggerInterface::class));
84
85
        $containerProxy->get(LogCollector::class)->startup();
86
        $containerProxy->get(LoggerInterface::class)->log('test', 'test message');
87
        $this->assertNotEmpty($containerProxy->get(LogCollector::class)->getCollected());
88
    }
89
90
    public function testGetWithArrayConfigWithStringKeys(): void
91
    {
92
        $dispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
93
        $serviceCollector = $this->createServiceCollector();
94
        $serviceCollector->startup(); // activate collector
95
96
        $config = new ContainerProxyConfig(
97
            true,
98
            [
99
                LoggerInterface::class => ['logger' => LoggerInterfaceProxy::class],
100
                EventDispatcherInterface::class => [
101
                    EventDispatcherInterfaceProxy::class,
102
                    EventCollector::class,
103
                ],
104
            ],
105
            $dispatcherMock,
106
            $serviceCollector,
107
            $this->path,
108
            1
109
        );
110
        $container = $this->getContainer();
111
        $containerProxy = new ContainerInterfaceProxy($container, $config);
112
113
        $this->assertTrue($containerProxy->isActive());
114
        $this->assertInstanceOf(LoggerInterface::class, $containerProxy->get(LoggerInterface::class));
115
116
        $containerProxy->get(LoggerInterface::class)->log('test', 'test message');
117
        $this->assertInstanceOf(LoggerInterface::class, $containerProxy->get(LoggerInterface::class));
118
        $this->assertNotEmpty($config->getCollector()->getCollected());
119
    }
120
121
    public function testGetWithoutConfig(): void
122
    {
123
        $dispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
124
        $config = new ContainerProxyConfig(
125
            true,
126
            [
127
                LoggerInterface::class => [LoggerInterfaceProxy::class, LogCollector::class],
128
                EventDispatcherInterface::class,
129
            ],
130
            $dispatcherMock,
131
            $this->createServiceCollector(),
132
            $this->path,
133
            1
134
        );
135
        $containerProxy = new ContainerInterfaceProxy($this->getContainer(), $config);
136
137
        $this->assertInstanceOf(EventDispatcherInterface::class, $containerProxy->get(EventDispatcherInterface::class));
138
        $this->assertInstanceOf(
139
            stdClass::class,
140
            $containerProxy->get(EventDispatcherInterface::class)->dispatch(new stdClass())
141
        );
142
    }
143
144
    public function testGetAndHasWithWrongId(): void
145
    {
146
        $this->expectException(ContainerExceptionInterface::class);
147
        $this->expectExceptionMessage(
148
            sprintf(
149
                'No definition or class found or resolvable for "%s" while building "%s".',
150
                CollectorInterface::class,
151
                CollectorInterface::class
152
            )
153
        );
154
155
        $containerProxy = new ContainerInterfaceProxy($this->getContainer(), $this->getConfig());
156
157
        $containerProxy->has(CollectorInterface::class);
158
        $containerProxy->get(CollectorInterface::class);
159
    }
160
161
    public function testGetAndHasWithNotService(): void
162
    {
163
        $containerProxy = new ContainerInterfaceProxy($this->getContainer(), $this->getConfig());
164
165
        $this->assertTrue($containerProxy->has(ListenerProviderInterface::class));
166
        $this->assertNotNull($containerProxy->get(ListenerProviderInterface::class));
167
        $this->assertInstanceOf(
168
            ListenerProviderInterface::class,
169
            $containerProxy->get(ListenerProviderInterface::class)
170
        );
171
    }
172
173
    private function getConfig(): ContainerProxyConfig
174
    {
175
        $dispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
176
177
        return new ContainerProxyConfig(
178
            true,
179
            [
180
                LoggerInterface::class => [LoggerInterfaceProxy::class, LogCollector::class],
181
                EventDispatcherInterface::class => [
182
                    EventDispatcherInterfaceProxy::class,
183
                    EventCollector::class,
184
                ],
185
            ],
186
            $dispatcherMock,
187
            $this->createServiceCollector(),
188
            $this->path,
189
            1
190
        );
191
    }
192
193
    private function getContainer(): Container
194
    {
195
        $config = ContainerConfig::create()
196
            ->withDefinitions([
197
                EventDispatcherInterface::class => Dispatcher::class,
198
                ListenerProviderInterface::class => Provider::class,
199
                LoggerInterface::class => NullLogger::class,
200
                LogCollector::class => LogCollector::class,
201
                EventCollector::class => EventCollector::class,
202
            ]);
203
        return new Container($config);
204
    }
205
206
    protected function createServiceCollector(): ServiceCollector
207
    {
208
        return new ServiceCollector(new TimelineCollector());
209
    }
210
}
211