/
TestLogger.php
141 lines (118 loc) · 4.36 KB
/
TestLogger.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
/*
* CardDAV client library for PHP ("PHP-CardDavClient").
*
* Copyright (c) 2020-2021 Michael Stilkerich <ms@mike2k.de>
* Licensed under the MIT license. See COPYING file in the project root for details.
*/
declare(strict_types=1);
namespace MStilkerich\Tests\CardDavClient;
use Psr\Log\{AbstractLogger,LogLevel,LoggerInterface};
use PHPUnit\Framework\TestCase;
class TestLogger extends AbstractLogger
{
/**
* @var int[] Assigns each log level a numerical severity value.
*/
private const LOGLEVELS = [
LogLevel::DEBUG => 1,
LogLevel::INFO => 2,
LogLevel::NOTICE => 3,
LogLevel::WARNING => 4,
LogLevel::ERROR => 5,
LogLevel::CRITICAL => 6,
LogLevel::ALERT => 7,
LogLevel::EMERGENCY => 8
];
/**
* @var string[] Assigns each short name to each log level.
*/
private const LOGLEVELS_SHORT = [
LogLevel::DEBUG => "DBG",
LogLevel::INFO => "NFO",
LogLevel::NOTICE => "NTC",
LogLevel::WARNING => "WRN",
LogLevel::ERROR => "ERR",
LogLevel::CRITICAL => "CRT",
LogLevel::ALERT => "ALT",
LogLevel::EMERGENCY => "EMG"
];
/** @var resource $logh File handle to the log file */
private $logh;
/** @var string[][] In-Memory buffer of log messages to assert log messages */
private $logBuffer = [];
public function __construct(string $logFileName = 'test.log')
{
$logfile = "testreports/{$GLOBALS['TEST_TESTRUN']}/$logFileName";
$logh = fopen($logfile, 'w');
if ($logh === false) {
throw new \Exception("could not open log file: $logfile");
}
$this->logh = $logh;
}
/**
* At the time of destruction, there may be no unchecked log messages of warning or higher level.
*
* Tests should call reset() when done (in tearDown()), this is just a fallback to detect if a test did not and
* there were errors. When the error is raised from the destructor, the relation to the test function that triggered
* the leftover log messages is lost and PHPUnit may report the issue for an unrelated test function within the same
* test case.
*/
public function __destruct()
{
$this->reset();
fclose($this->logh);
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return void
*/
public function log($level, $message, array $context = array()): void
{
TestCase::assertIsString($level);
TestCase::assertNotNull(self::LOGLEVELS[$level]);
$levelNumeric = self::LOGLEVELS[$level];
$levelShort = self::LOGLEVELS_SHORT[$level];
// interpolation of context placeholders is not implemented
fprintf($this->logh, "[%s]: %s\n", date('Y-m-d H:i:s'), "[$levelNumeric $levelShort] $message");
// only warnings or more critical messages are interesting for testing
if (self::LOGLEVELS[$level] >= self::LOGLEVELS[LogLevel::WARNING]) {
$this->logBuffer[] = [ $level, $message, 'UNCHECKED' ];
}
}
/**
* Resets the in-memory buffer of critical log messages.
*/
public function reset(): void
{
$buffer = $this->logBuffer;
// reset before doing the assertions - if there is a failure, it won't affect the following tests
$this->logBuffer = [];
foreach ($buffer as $recMsg) {
[ $level, $msg, $checked ] = $recMsg;
TestCase::assertSame('CHECKED', $checked, "Unchecked log message of level $level: $msg");
}
}
/**
* Checks the in-memory buffer if a log message of the given log level was emitted.
*/
public function expectMessage(string $expLevel, string $expMsg): void
{
$found = false;
foreach ($this->logBuffer as &$recMsg) {
[ $level, $msg ] = $recMsg;
if (($level == $expLevel) && str_contains($msg, $expMsg) && $recMsg[2] == "UNCHECKED") {
$recMsg[2] = 'CHECKED';
$found = true;
break;
}
}
unset($recMsg);
TestCase::assertTrue($found, "The expected log entry containing '$expMsg' with level $expLevel was not found");
}
}
// vim: ts=4:sw=4:expandtab:fenc=utf8:ff=unix:tw=120:ft=php