Passed
Push — master ( 7bc6a4...bace86 )
by Dmitriy
06:54 queued 04:27
created

testGetWithoutConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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