Passed
Push — master ( 61f3a0...6b4c98 )
by Alexander
01:39
created

TargetTest   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 111
dl 0
loc 165
rs 10
c 4
b 0
f 0
wmc 7
1
<?php
2
3
namespace Yiisoft\Log\Tests;
4
5
use Psr\Log\LogLevel;
6
use Yiisoft\Log\Logger;
7
use Yiisoft\Log\Target;
8
9
/**
10
 * @group log
11
 */
12
class TargetTest extends TestCase
13
{
14
    public static $messages;
15
16
    public function filters(): array
17
    {
18
        return [
19
            [[], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']],
20
            [['levels' => []], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']],
21
            [
22
                ['levels' => [LogLevel::INFO, LogLevel::WARNING, LogLevel::ERROR, LogLevel::DEBUG]],
23
                ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
24
            ],
25
            [['levels' => ['error']], ['B', 'G', 'H', 'I']],
26
            [['levels' => [LogLevel::ERROR]], ['B', 'G', 'H', 'I']],
27
            [['levels' => ['error', 'warning']], ['B', 'C', 'G', 'H', 'I']],
28
            [['levels' => [LogLevel::ERROR, LogLevel::WARNING]], ['B', 'C', 'G', 'H', 'I']],
29
30
            [['categories' => ['application']], ['A', 'B', 'C', 'D', 'E']],
31
            [['categories' => ['application*']], ['A', 'B', 'C', 'D', 'E', 'F']],
32
            [['categories' => ['application.*']], ['F']],
33
            [['categories' => ['application.components']], []],
34
            [['categories' => ['application.components.Test']], ['F']],
35
            [['categories' => ['application.components.*']], ['F']],
36
            [['categories' => ['application.*', 'Yiisoft.Db.*']], ['F', 'G', 'H']],
37
            [['categories' => ['application.*', 'Yiisoft.Db.*'], 'except' => ['Yiisoft.Db.Command.*', 'Yiisoft\Db\*']], ['F', 'G']],
38
            [['except' => ['Yiisoft\Db\*']], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']],
39
            [['categories' => ['Yiisoft*'], 'except' => ['Yiisoft\Db\*']], ['G', 'H']],
40
41
            [['categories' => ['application', 'Yiisoft.Db.*'], 'levels' => [LogLevel::ERROR]], ['B', 'G', 'H']],
42
            [['categories' => ['application'], 'levels' => [LogLevel::ERROR]], ['B']],
43
            [['categories' => ['application'], 'levels' => [LogLevel::ERROR, LogLevel::WARNING]], ['B', 'C']],
44
        ];
45
    }
46
47
    /**
48
     * @dataProvider filters
49
     * @param array $filter
50
     * @param array $expected
51
     */
52
    public function testFilter(array $filter, array $expected): void
53
    {
54
        static::$messages = [];
55
56
        $filter = array_merge($filter, ['logVars' => []]);
57
        $target = new TestTarget();
58
        foreach ($filter as $key => $value) {
59
            $target->{'set' . ucfirst($key)}($value);
60
        }
61
        $logger = new Logger(['test' => $target]);
62
63
        $logger->setFlushInterval(1);
64
        $logger->log(LogLevel::INFO, 'testA');
65
        $logger->log(LogLevel::ERROR, 'testB');
66
        $logger->log(LogLevel::WARNING, 'testC');
67
        $logger->log(LogLevel::DEBUG, 'testD');
68
        $logger->log(LogLevel::INFO, 'testE', ['category' => 'application']);
69
        $logger->log(LogLevel::INFO, 'testF', ['category' => 'application.components.Test']);
70
        $logger->log(LogLevel::ERROR, 'testG', ['category' => 'Yiisoft.Db.Command']);
71
        $logger->log(LogLevel::ERROR, 'testH', ['category' => 'Yiisoft.Db.Command.whatever']);
72
        $logger->log(LogLevel::ERROR, 'testI', ['category' => 'Yiisoft\Db\Command::query']);
73
74
        $this->assertCount(count($expected), static::$messages, 'Expected ' . implode(',', $expected) . ', got ' . implode(',', array_column(static::$messages, 0)));
75
        $i = 0;
76
        foreach ($expected as $e) {
77
            $this->assertEquals('test' . $e, static::$messages[$i++][1]);
78
        }
79
    }
80
81
    public function testGetContextMessage(): void
82
    {
83
        $target = new TestTarget();
84
        $target->setLogVars([
85
            'A', '!A.A_b', 'A.A_d',
86
            'B.B_a',
87
            'C', 'C.C_a',
88
        ]);
89
        $GLOBALS['A'] = [
90
            'A_a' => 1,
91
            'A_b' => 1,
92
            'A_c' => 1,
93
        ];
94
        $GLOBALS['B'] = [
95
            'B_a' => 1,
96
            'B_b' => 1,
97
            'B_c' => 1,
98
        ];
99
        $GLOBALS['C'] = [
100
            'C_a' => 1,
101
            'C_b' => 1,
102
            'C_c' => 1,
103
        ];
104
        $GLOBALS['E'] = [
105
            'C_a' => 1,
106
            'C_b' => 1,
107
            'C_c' => 1,
108
        ];
109
        $context = $target->getContextMessage();
110
        $this->assertStringContainsString('A_a', $context);
111
        $this->assertStringNotContainsString('A_b', $context);
112
        $this->assertStringContainsString('A_c', $context);
113
        $this->assertStringContainsString('B_a', $context);
114
        $this->assertStringNotContainsString('B_b', $context);
115
        $this->assertStringNotContainsString('B_c', $context);
116
        $this->assertStringContainsString('C_a', $context);
117
        $this->assertStringContainsString('C_b', $context);
118
        $this->assertStringContainsString('C_c', $context);
119
        $this->assertStringNotContainsString('D_a', $context);
120
        $this->assertStringNotContainsString('D_b', $context);
121
        $this->assertStringNotContainsString('D_c', $context);
122
        $this->assertStringNotContainsString('E_a', $context);
123
        $this->assertStringNotContainsString('E_b', $context);
124
        $this->assertStringNotContainsString('E_c', $context);
125
    }
126
127
    public function testGetEnabled(): void
128
    {
129
        /** @var Target $target */
130
        $target = $this->getMockForAbstractClass(Target::class);
131
132
        $target->enable();
133
        $this->assertTrue($target->isEnabled());
134
135
        $target->disable();
136
        $this->assertFalse($target->isEnabled());
137
138
        $target->setEnabled(static function ($target) {
139
            return empty($target->messages);
140
        });
141
        $this->assertTrue($target->isEnabled());
142
    }
143
144
    public function testFormatTimestamp(): void
145
    {
146
        /** @var Target $target */
147
        $target = $this->getMockForAbstractClass(Target::class);
148
149
        $text = 'message';
150
        $level = LogLevel::INFO;
151
        $category = 'application';
152
        $timestamp = 1508160390.6083;
153
154
        $target->setTimestampFormat('Y-m-d H:i:s');
155
156
        $expectedWithoutMicro = '2017-10-16 13:26:30 [info][application] message';
157
        $formatted = $target->formatMessage([$level, $text, ['category' => $category, 'time' => $timestamp]]);
158
        $this->assertSame($expectedWithoutMicro, $formatted);
159
160
        $target->setTimestampFormat('Y-m-d H:i:s.u');
161
162
        $expectedWithMicro = '2017-10-16 13:26:30.608300 [info][application] message';
163
        $formatted = $target->formatMessage([$level, $text, ['category' => $category, 'time' => $timestamp]]);
164
        $this->assertSame($expectedWithMicro, $formatted);
165
166
        $target->setTimestampFormat('Y-m-d H:i:s');
167
        $timestamp = 1508160390;
168
169
        $expectedWithoutMicro = '2017-10-16 13:26:30 [info][application] message';
170
        $formatted = $target->formatMessage([$level, $text, ['category' => $category, 'time' => $timestamp]]);
171
        $this->assertSame($expectedWithoutMicro, $formatted);
172
173
        $target->setTimestampFormat('D d F Y');
174
        $expectedCustom = 'Mon 16 October 2017 [info][application] message';
175
        $formatted = $target->formatMessage([$level, $text, ['category' => $category, 'time' => $timestamp]]);
176
        $this->assertSame($expectedCustom, $formatted);
177
    }
178
}
179
180
class TestTarget extends Target
181
{
182
    public function __construct()
183
    {
184
        $this->setExportInterval(1);
185
    }
186
187
    /**
188
     * Exports log [[messages]] to a specific destination.
189
     * Child classes must implement this method.
190
     */
191
    public function export(): void
192
    {
193
        TargetTest::$messages = array_merge(TargetTest::$messages, $this->getMessages());
194
        $this->setMessages([]);
195
    }
196
197
    public function getContextMessage(): string
198
    {
199
        return parent::getContextMessage();
200
    }
201
}
202