LoggerTest::setUp()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * This file is part of the php-gelf package.
6
 *
7
 * (c) Benjamin Zikarsky <http://benjamin-zikarsky.de>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Gelf\Test;
14
15
use Gelf\Logger;
16
use Gelf\MessageInterface;
17
use Gelf\PublisherInterface;
18
use PHPUnit\Framework\MockObject\MockObject;
19
use PHPUnit\Framework\TestCase;
20
use Psr\Log\LogLevel;
21
use Exception;
22
use Closure;
23
use Stringable;
24
25
class LoggerTest extends TestCase
26
{
27
    private MockObject|PublisherInterface $publisher;
28
    private Logger $logger;
29
30
    public function setUp(): void
31
    {
32
        $this->publisher = $this->createMock(PublisherInterface::class);
33
        $this->logger = new Logger($this->publisher);
34
    }
35
36
    public function testPublisher(): void
37
    {
38
        self::assertEquals($this->publisher, $this->logger->getPublisher());
39
40
        $newPublisher = $this->createMock(PublisherInterface::class);
41
        $this->logger->setPublisher($newPublisher);
42
        self::assertEquals($newPublisher, $this->logger->getPublisher());
43
    }
44
45
    public function testSimpleLog(): void
46
    {
47
        $this->validatePublish(
48
            function (MessageInterface $message) {
49
                self::assertEquals("test", $message->getShortMessage());
50
                self::assertEquals(LogLevel::ALERT, $message->getLevel());
51
            }
52
        );
53
54
        $this->logger->log(LogLevel::ALERT, "test");
55
    }
56
57
    public function testLogContext(): void
58
    {
59
        $additional = ['test' => 'bar', 'abc' => 'buz'];
60
        $this->validatePublish(
61
            function (MessageInterface $message) use ($additional) {
62
                self::assertEquals("foo bar", $message->getShortMessage());
63
                self::assertEquals($additional, $message->getAllAdditionals());
64
            }
65
        );
66
67
        $this->logger->log(LogLevel::NOTICE, "foo {test}", $additional);
68
    }
69
70
    /**
71
     * @see https://github.com/bzikarsky/gelf-php/issues/50
72
     * @dataProvider providerLogContextWithStructuralValues
73
     */
74
    public function testLogContextWithStructuralValues(mixed $contextValue, mixed $expected): void
75
    {
76
        $additional = ['context' => $contextValue];
77
        $this->validatePublish(
78
            function (MessageInterface $message) use ($expected) {
79
                // Use Message::toArray() as it filters invalid values
80
                $final = $message->toArray();
81
                if (!isset($final['_context'])) {
82
                    self::fail("Expected context key missing");
83
                }
84
                $actual = $final['_context'];
85
                // Only scalar values are allowed, with exception of boolean
86
                self::assertTrue(
87
                    is_scalar($actual) && !is_bool($actual),
88
                    'Unexpected context value of type: ' . gettype($actual)
89
                );
90
                self::assertSame($expected, $actual);
91
            }
92
        );
93
94
        // Log message length must exceed longest context key length + 2
95
        // to cause strtr() in Logger::interpolate() to throw notices for nested arrays
96
        $this->logger->log(LogLevel::NOTICE, 'test message', $additional);
97
    }
98
99
    public static function providerLogContextWithStructuralValues(): array
100
    {
101
        $stdClass = new \stdClass();
102
        $stdClass->prop1 = 'val1';
103
104
        $toString = new class implements Stringable {
105
            public function __toString(): string
106
            {
107
                return 'toString';
108
            }
109
        };
110
111
        return [
112
            'array'     => [['bar' => 'buz'], '{"bar":"buz"}'],
113
            'boolTrue'  => [true, 'true'],
114
            'boolFalse' => [false, 'false'],
115
            'integer'   => [123, 123],
116
            'float'     => [123.456, 123.456],
117
            'object'    => [$stdClass, '[object (stdClass)]'],
118
            'toString'  => [$toString, 'toString'],
119
            'resource'  => [fopen('php://memory', 'r'), '[resource]'],
120
            'null'      => [null, 'NULL']
121
        ];
122
    }
123
124
    public function testLogException(): void
125
    {
126
        // offset is the line-distance to the throw statement!
127
        $line = __LINE__ + 3;
128
129
        try {
130
            throw new Exception("test-message", 123);
131
        } catch (Exception $e) {
132
            $this->validatePublish(
133
                function (MessageInterface $message) use ($e, $line) {
134
                    self::assertStringContainsString(
135
                        $e->getMessage(),
136
                        $message->getFullMessage()
0 ignored issues
show
Bug introduced by
It seems like $message->getFullMessage() can also be of type null; however, parameter $haystack of PHPUnit\Framework\Assert...tStringContainsString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

136
                        /** @scrutinizer ignore-type */ $message->getFullMessage()
Loading history...
137
                    );
138
                    self::assertStringContainsString(
139
                        get_class($e),
140
                        $message->getFullMessage()
141
                    );
142
                    self::assertEquals($line, $message->getAdditional('line'));
143
                    self::assertEquals(__FILE__, $message->getAdditional('file'));
144
                }
145
            );
146
147
            $this->logger->log(
148
                LogLevel::ALERT,
149
                $e->getMessage(),
150
                context: ['exception' => $e]
151
            );
152
        }
153
    }
154
155
    // @see https://github.com/bzikarsky/gelf-php/issues/9
156
    public function testStringZeroMessage(): void
157
    {
158
        $this->validatePublish(
159
            function (MessageInterface $message) {
160
                self::assertEquals("0", $message->getShortMessage());
161
            }
162
        );
163
164
        $this->logger->info('0');
165
    }
166
167
    private function validatePublish(Closure $validator): void
168
    {
169
        $this->publisher->expects($this->once())->method('publish')->will(
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Gelf\PublisherInterface. ( Ignorable by Annotation )

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

169
        $this->publisher->/** @scrutinizer ignore-call */ 
170
                          expects($this->once())->method('publish')->will(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
170
            $this->returnCallback($validator)
171
        );
172
    }
173
174
    public function testDefaultContext(): void
175
    {
176
        $this->logger->setDefaultContext(['defaultFoo' => 'bar', 'defaultBar' => 'foo']);
177
        $this->validatePublish(
178
            function (MessageInterface $message) {
179
                self::assertEquals("bar", $message->getAdditional('defaultFoo'));
180
                self::assertEquals("baz", $message->getAdditional('defaultBar'));
181
            }
182
        );
183
184
        $this->logger->log(5, 'test', [
185
            'defaultBar' => 'baz'
186
        ]);
187
    }
188
}
189