LoggerFactoryTest   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 13
eloc 68
c 4
b 0
f 0
dl 0
loc 143
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 3 1
A getLoggerWillCreateConfiguredHandlersData() 0 26 1
A testImplementsFactoryInterface() 0 5 1
B testLoggerWillCreateConfiguredHandlers() 0 53 9
A testInvokeWillThrowServiceNotCreatedExceptionIfProvidingInvalidHandlerConfiguration() 0 25 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\LaminasMonolog\Factory;
6
7
use Arp\LaminasFactory\FactoryInterface;
8
use Arp\LaminasMonolog\Factory\LoggerFactory;
9
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
10
use Laminas\ServiceManager\ServiceLocatorInterface;
11
use Monolog\Handler\HandlerInterface;
12
use Monolog\Handler\NoopHandler;
13
use Monolog\Handler\NullHandler;
14
use Monolog\Logger;
15
use PHPUnit\Framework\MockObject\MockObject;
16
use PHPUnit\Framework\TestCase;
17
18
/**
19
 * @covers \Arp\LaminasMonolog\Factory\LoggerFactory
20
 */
21
final class LoggerFactoryTest extends TestCase
22
{
23
    /**
24
     * @var ServiceLocatorInterface&MockObject
25
     */
26
    private $container;
27
28
    public function setUp(): void
29
    {
30
        $this->container = $this->createMock(ServiceLocatorInterface::class);
31
    }
32
33
    /**
34
     * Assert the class implements FactoryInterface
35
     */
36
    public function testImplementsFactoryInterface(): void
37
    {
38
        $factory = new LoggerFactory();
39
40
        $this->assertInstanceOf(FactoryInterface::class, $factory);
41
    }
42
43
    /**
44
     * Assert that a ServiceNotCreatedException is thrown from invoke() if a Handler is invalid
45
     */
46
    public function testInvokeWillThrowServiceNotCreatedExceptionIfProvidingInvalidHandlerConfiguration(): void
47
    {
48
        $logger = new LoggerFactory();
49
50
        $serviceName = Logger::class;
51
        $handler = new \stdClass();
52
        $options = [
53
            'handlers' => [
54
                $handler,
55
            ],
56
        ];
57
58
        $this->expectException(ServiceNotCreatedException::class);
59
        $this->expectExceptionMessage(
60
            sprintf(
61
                'The log handler \'%s\' must be an object of type \'%s\'; '
62
                . '\'%s\' provided for service \'%s\'',
63
                'object',
64
                HandlerInterface::class,
65
                get_class($handler),
66
                $serviceName,
67
            )
68
        );
69
70
        $logger($this->container, Logger::class, $options);
71
    }
72
73
    /**
74
     * @param array<mixed> $handlerConfigs
75
     *
76
     * @dataProvider getLoggerWillCreateConfiguredHandlersData
77
     *
78
     * @throws ServiceNotCreatedException
79
     */
80
    public function testLoggerWillCreateConfiguredHandlers(array $handlerConfigs = []): void
81
    {
82
        /** @var LoggerFactory&MockObject $factory */
83
        $factory = $this->getMockBuilder(LoggerFactory::class)
84
            ->onlyMethods(['getService', 'buildService'])
85
            ->getMock();
86
87
        $serviceName = 'FooLogger';
88
89
        $handlers = [];
90
        $getArgs = $buildArgs = [];
91
        $getReturns = $buildReturns = [];
92
        foreach ($handlerConfigs as $handlerName => $handler) {
93
            if (is_object($handler)) {
94
                $handlers[] = $handler;
95
                continue;
96
            }
97
            if (!is_array($handler) && !is_string($handler)) {
98
                continue;
99
            }
100
101
            /** @var HandlerInterface&MockObject $handlerObject */
102
            $handlerObject = $this->createMock(HandlerInterface::class);
103
104
            if (is_string($handler)) {
105
                $getArgs[] = [$this->container, $handler, $serviceName];
106
                $getReturns[] = $handlerObject;
107
            } elseif (is_array($handler)) {
108
                /** @var HandlerInterface&MockObject $handlerObject */
109
                $handlerObject = $this->createMock(HandlerInterface::class);
110
                $buildArgs[] = [$this->container, $handlerName, $handler, $serviceName];
111
                $buildReturns[] = $handlerObject;
112
            }
113
            $handlers[] = $handlerObject;
114
        }
115
116
        if (!empty($getArgs)) {
117
            $factory->expects($this->exactly(count($getArgs)))
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...cker::withConsecutive() has been deprecated. ( Ignorable by Annotation )

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

117
            /** @scrutinizer ignore-deprecated */ $factory->expects($this->exactly(count($getArgs)))
Loading history...
118
                ->method('getService')
119
                ->withConsecutive(...$getArgs)
120
                ->willReturnOnConsecutiveCalls(...$getReturns);
121
        }
122
123
        if (!empty($buildArgs)) {
124
            $factory->expects($this->exactly(count($buildArgs)))
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...cker::withConsecutive() has been deprecated. ( Ignorable by Annotation )

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

124
            /** @scrutinizer ignore-deprecated */ $factory->expects($this->exactly(count($buildArgs)))
Loading history...
125
                ->method('buildService')
126
                ->withConsecutive(...$buildArgs)
127
                ->willReturnOnConsecutiveCalls(...$buildReturns);
128
        }
129
130
        $logger = $factory($this->container, $serviceName, ['handlers' => $handlerConfigs]);
131
132
        $this->assertSame($handlers, $logger->getHandlers());
133
    }
134
135
    /**
136
     * @return array<mixed>
137
     */
138
    public function getLoggerWillCreateConfiguredHandlersData(): array
139
    {
140
        return [
141
            [
142
                [
143
                    'Foo\\Bar\\Service\\TestHandler',
144
                    HandlerInterface::class,
145
                    $this->createMock(HandlerInterface::class),
146
                ],
147
            ],
148
            [
149
                [
150
                    $this->createMock(HandlerInterface::class),
151
                    NoopHandler::class => [
152
                        'test' => 123,
153
                        'config' => 'data'
154
                    ],
155
                    NullHandler::class,
156
                ]
157
            ],
158
            [
159
                [
160
                    $this->createMock(HandlerInterface::class),
161
                    $this->createMock(HandlerInterface::class),
162
                    NoopHandler::class,
163
                    $this->createMock(HandlerInterface::class),
164
                ],
165
            ],
166
        ];
167
    }
168
}
169