Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
74 / 74
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10pest()->group('integration');
11
12use Phexium\Plugin\Logger\Adapter\FileLogger;
13use Psr\Log\LogLevel;
14
15beforeEach(function (): void {
16    $this->tempFile = sys_get_temp_dir().'/test_'.uniqid().'/nested/test.log';
17    $this->logger = new FileLogger($this->tempFile, LogLevel::DEBUG);
18});
19
20afterEach(function (): void {
21    if (file_exists($this->tempFile)) {
22        unlink($this->tempFile);
23        rmdir(dirname($this->tempFile));
24        rmdir(dirname($this->tempFile, 2));
25    }
26});
27
28describe('Log output', function (): void {
29    it('writes all log levels', function (): void {
30        $levels = [
31            LogLevel::EMERGENCY => 'emergency',
32            LogLevel::ALERT => 'alert',
33            LogLevel::CRITICAL => 'critical',
34            LogLevel::ERROR => 'error',
35            LogLevel::WARNING => 'warning',
36            LogLevel::NOTICE => 'notice',
37            LogLevel::INFO => 'info',
38            LogLevel::DEBUG => 'debug',
39        ];
40
41        foreach ($levels as $method) {
42            $this->logger->{$method}(sprintf('Test %s message', $method));
43        }
44
45        $logContent = file_get_contents($this->tempFile);
46
47        foreach ($levels as $method) {
48            $ucMethod = strtoupper($method);
49            expect($logContent)->toContain('['.$ucMethod.']')
50                ->toContain(sprintf('Test %s message', $method))
51            ;
52        }
53    });
54
55    it('includes context data', function (): void {
56        $context = ['user_id' => 123];
57        $this->logger->info('User action', $context);
58
59        $logContent = file_get_contents($this->tempFile);
60
61        expect($logContent)->toContain('User action {"user_id":123}');
62    });
63
64    it('writes message without trailing content', function (): void {
65        $this->logger->info('Simple message');
66
67        $logContent = trim(file_get_contents($this->tempFile));
68
69        expect($logContent)->toEndWith('Simple message');
70    });
71
72    it('ends entries with newline', function (): void {
73        $this->logger->info('Message');
74
75        $logContent = file_get_contents($this->tempFile);
76
77        expect($logContent)->toContain('Message')
78            ->toEndWith("\n")
79        ;
80    });
81
82    it('handles Stringable message', function (): void {
83        $stringableMessage = new class implements Stringable {
84            public function __toString(): string
85            {
86                return 'Stringable message';
87            }
88        };
89
90        $this->logger->info($stringableMessage);
91
92        $logContent = file_get_contents($this->tempFile);
93
94        expect($logContent)->toContain('Stringable message');
95    });
96});
97
98describe('Log filtering', function (): void {
99    it('respects minimum log level', function (): void {
100        $logger = new FileLogger($this->tempFile, LogLevel::WARNING);
101
102        $logger->error('Error message');
103        $logger->warning('Warning message');
104        $logger->notice('Notice message');
105        $logger->log('UnknownLevel', 'UnknownLevel message');
106
107        $logContent = file_get_contents($this->tempFile);
108
109        expect($logContent)->toContain('Error message')
110            ->toContain('Warning message')
111            ->not->toContain('Notice message')
112            ->not->toContain('UnknownLevel message')
113        ;
114    });
115});