Skip to content

Commit 20bcd55

Browse files
authored
Support psr/log version 2+3 (#66)
* Support psr/log version 2+3 * Support psr/log version 3 * Add mock logger to replace removed test logger
1 parent 0a2dd53 commit 20bcd55

5 files changed

Lines changed: 153 additions & 6 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"packaged/docblock": "~1.1",
3434
"packaged/i18n": "~1.2",
3535
"symfony/console": "~4.2||~5.0",
36-
"psr/log": "~1.1"
36+
"psr/log": "~1.1||^2.0||^3.0"
3737
},
3838
"suggest": {
3939
"ext-xdebug": "*"

src/Cubex.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public function getLogger()
171171
*
172172
* @return void
173173
*/
174-
public function setLogger(LoggerInterface $logger)
174+
public function setLogger(LoggerInterface $logger): void
175175
{
176176
$this->share(LoggerInterface::class, $logger);
177177
}

src/Logger/ErrorLogLogger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ErrorLogLogger extends AbstractLogger
2121
*
2222
* @throws \Exception
2323
*/
24-
public function log($level, $message, array $context = [])
24+
public function log($level, $message, array $context = []): void
2525
{
2626
$requestId = $this->hasContext() ? $this->getContext()->id() : Strings::randomString(10);
2727
$now = \DateTime::createFromFormat('U.u', sprintf("%.6F", microtime(true)));

tests/CubexTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Cubex\Events\ShutdownEvent;
1313
use Cubex\Logger\ErrorLogLogger;
1414
use Cubex\Routing\Router;
15+
use Cubex\Tests\Logger\MockLogger;
1516
use Cubex\Tests\Supporting\Console\TestExceptionCommand;
1617
use Cubex\Tests\Supporting\Http\TestResponse;
1718
use Exception;
@@ -23,7 +24,6 @@
2324
use Packaged\Routing\Handler\FuncHandler;
2425
use Packaged\Routing\Handler\Handler;
2526
use PHPUnit\Framework\TestCase;
26-
use Psr\Log\Test\TestLogger;
2727
use Symfony\Component\Console\Input\ArgvInput;
2828
use Symfony\Component\Console\Input\InputInterface;
2929
use Symfony\Component\Console\Output\BufferedOutput;
@@ -98,7 +98,7 @@ public function testHandle()
9898
public function testHandleCompleteException()
9999
{
100100
$cubex = $this->_cubex();
101-
$logger = new TestLogger();
101+
$logger = new MockLogger();
102102
$cubex->setLogger($logger);
103103
$router = new Router();
104104
$router->onPath(
@@ -244,7 +244,7 @@ public function _defaultShutdownProvider()
244244
public function testLog()
245245
{
246246
$cubex = new Cubex(__DIR__, null, true);
247-
$logger = new TestLogger();
247+
$logger = new MockLogger();
248248
$cubex->setLogger($logger);
249249
Cubex::log()->error("TEST");
250250
self::assertTrue($logger->hasError("TEST"));

tests/Logger/MockLogger.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
3+
namespace Cubex\Tests\Logger;
4+
5+
use Psr\Log\AbstractLogger;
6+
7+
/**
8+
* Used for testing purposes.
9+
*
10+
* It records all records and gives you access to them for verification.
11+
*
12+
* @method bool hasEmergency($record)
13+
* @method bool hasAlert($record)
14+
* @method bool hasCritical($record)
15+
* @method bool hasError($record)
16+
* @method bool hasWarning($record)
17+
* @method bool hasNotice($record)
18+
* @method bool hasInfo($record)
19+
* @method bool hasDebug($record)
20+
*
21+
* @method bool hasEmergencyRecords()
22+
* @method bool hasAlertRecords()
23+
* @method bool hasCriticalRecords()
24+
* @method bool hasErrorRecords()
25+
* @method bool hasWarningRecords()
26+
* @method bool hasNoticeRecords()
27+
* @method bool hasInfoRecords()
28+
* @method bool hasDebugRecords()
29+
*
30+
* @method bool hasEmergencyThatContains($message)
31+
* @method bool hasAlertThatContains($message)
32+
* @method bool hasCriticalThatContains($message)
33+
* @method bool hasErrorThatContains($message)
34+
* @method bool hasWarningThatContains($message)
35+
* @method bool hasNoticeThatContains($message)
36+
* @method bool hasInfoThatContains($message)
37+
* @method bool hasDebugThatContains($message)
38+
*
39+
* @method bool hasEmergencyThatMatches($message)
40+
* @method bool hasAlertThatMatches($message)
41+
* @method bool hasCriticalThatMatches($message)
42+
* @method bool hasErrorThatMatches($message)
43+
* @method bool hasWarningThatMatches($message)
44+
* @method bool hasNoticeThatMatches($message)
45+
* @method bool hasInfoThatMatches($message)
46+
* @method bool hasDebugThatMatches($message)
47+
*
48+
* @method bool hasEmergencyThatPasses($message)
49+
* @method bool hasAlertThatPasses($message)
50+
* @method bool hasCriticalThatPasses($message)
51+
* @method bool hasErrorThatPasses($message)
52+
* @method bool hasWarningThatPasses($message)
53+
* @method bool hasNoticeThatPasses($message)
54+
* @method bool hasInfoThatPasses($message)
55+
* @method bool hasDebugThatPasses($message)
56+
*/
57+
class MockLogger extends AbstractLogger
58+
{
59+
/**
60+
* @var array
61+
*/
62+
public $records = [];
63+
64+
public $recordsByLevel = [];
65+
66+
/**
67+
* @inheritdoc
68+
*/
69+
public function log($level, $message, array $context = []): void
70+
{
71+
$record = [
72+
'level' => $level,
73+
'message' => $message,
74+
'context' => $context,
75+
];
76+
77+
$this->recordsByLevel[$record['level']][] = $record;
78+
$this->records[] = $record;
79+
}
80+
81+
public function hasRecords($level)
82+
{
83+
return isset($this->recordsByLevel[$level]);
84+
}
85+
86+
public function hasRecord($record, $level)
87+
{
88+
if (is_string($record)) {
89+
$record = ['message' => $record];
90+
}
91+
return $this->hasRecordThatPasses(function ($rec) use ($record) {
92+
if ($rec['message'] !== $record['message']) {
93+
return false;
94+
}
95+
if (isset($record['context']) && $rec['context'] !== $record['context']) {
96+
return false;
97+
}
98+
return true;
99+
}, $level);
100+
}
101+
102+
public function hasRecordThatContains($message, $level)
103+
{
104+
return $this->hasRecordThatPasses(function ($rec) use ($message) {
105+
return strpos($rec['message'], $message) !== false;
106+
}, $level);
107+
}
108+
109+
public function hasRecordThatMatches($regex, $level)
110+
{
111+
return $this->hasRecordThatPasses(function ($rec) use ($regex) {
112+
return preg_match($regex, $rec['message']) > 0;
113+
}, $level);
114+
}
115+
116+
public function hasRecordThatPasses(callable $predicate, $level)
117+
{
118+
if (!isset($this->recordsByLevel[$level])) {
119+
return false;
120+
}
121+
foreach ($this->recordsByLevel[$level] as $i => $rec) {
122+
if (call_user_func($predicate, $rec, $i)) {
123+
return true;
124+
}
125+
}
126+
return false;
127+
}
128+
129+
public function __call($method, $args)
130+
{
131+
if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
132+
$genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
133+
$level = strtolower($matches[2]);
134+
if (method_exists($this, $genericMethod)) {
135+
$args[] = $level;
136+
return call_user_func_array([$this, $genericMethod], $args);
137+
}
138+
}
139+
throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()');
140+
}
141+
142+
public function reset()
143+
{
144+
$this->records = [];
145+
$this->recordsByLevel = [];
146+
}
147+
}

0 commit comments

Comments
 (0)