Skip to content

Commit 665641d

Browse files
committed
Import test classes from psr/log 1.1.4
Fix compatibility with PHPUnit and psr/log 3.0 Modernize code for PHP 8.0 Materialize magical methods from TestLogger::__call
1 parent 8e034d8 commit 665641d

File tree

8 files changed

+498
-11
lines changed

8 files changed

+498
-11
lines changed

.github/workflows/continuous-integration.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ jobs:
55
runs-on: ubuntu-latest
66
strategy:
77
matrix:
8-
# There is no code, we don't have to test old PHP versions
98
php-versions:
10-
- 7.4
119
- 8.0
1210
- 8.1
1311
dependency-levels:
1412
- 'highest'
1513
experimental:
1614
- false
1715
include:
18-
- php-versions: 7.4
16+
- php-versions: 8.0
1917
dependency-levels: 'lowest'
2018
experimental: false
2119
fail-fast: false
@@ -30,7 +28,7 @@ jobs:
3028
php-version: ${{ matrix.php-versions }}
3129

3230
- name: Validating PHP syntax
33-
run: find ./tests/ -type f -name '*.php' -print0 | xargs -0 -L 1 -P 4 -- php -l
31+
run: find ./{src,tests}/ -type f -name '*.php' -print0 | xargs -0 -L 1 -P 4 -- php -l
3432

3533
- name: Validate composer.json and composer.lock
3634
run: composer validate

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [1.1.0] - YYYY-MM-DD
8+
9+
- Import classes from [`psr/log`][] `v1.1.4`, for compatibility with `v2.0.0` and `v3.0.0`.
10+
711
## [1.0.0] - YYYY-MM-DD
812

913
- Initial release. This ports the test for and from [`psr/log` v1.1][], according to

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ If the project supports older versions of PHP:
4343
The version of `fig/log-test` that is installed after composer dependencies resolution varies with the version of `psr/log`.
4444

4545
| psr/log | fig/log-test | |
46-
|---------------|---------------|-------------------------------------------------|
47-
| `^1.1.14` | `1.0.*` | Empty package, classes a provided by `psr/log`. |
48-
| `^2.0\|^3.0` | `^1.1` | Imports test classes removed from `psr/log`. |
46+
|---------------|--------------|-------------------------------------------------|
47+
| `^1.1.14` | `1.0.*` | Empty package, classes a provided by `psr/log`. |
48+
| `^2.0\|^3.0` | `^1.1` | Imports test classes removed from `psr/log`. |
4949

5050
[`psr/log`]: https://packagist.org/packages/psr/log
5151
[PSR-3]: https://www.php-fig.org/psr/psr-3/

composer.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@
1010
}
1111
],
1212
"require": {
13-
"php": "^5.3 | ^7.0 | ^8.0",
14-
"psr/log": "^1.1.1"
13+
"php": "^8.0",
14+
"psr/log": "^2.0 | ^3.0"
1515
},
1616
"require-dev": {
1717
"phpunit/phpunit": "^8.0 | ^9.0",
1818
"squizlabs/php_codesniffer": "^3.6"
1919
},
20+
"autoload": {
21+
"psr-4": {
22+
"Psr\\Log\\": "src"
23+
}
24+
},
2025
"autoload-dev": {
2126
"psr-4": {
2227
"Fig\\Log\\Tests\\": "tests"

src/Test/DummyTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Psr\Log\Test;
4+
5+
/**
6+
* This class is internal and does not follow the BC promise.
7+
*
8+
* Do NOT use this class in any way.
9+
*
10+
* @internal
11+
*/
12+
class DummyTest
13+
{
14+
public function __toString()
15+
{
16+
return 'DummyTest';
17+
}
18+
}

src/Test/LoggerInterfaceTest.php

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?php
2+
3+
namespace Psr\Log\Test;
4+
5+
use Psr\Log\InvalidArgumentException;
6+
use Psr\Log\LoggerInterface;
7+
use Psr\Log\LogLevel;
8+
use PHPUnit\Framework\TestCase;
9+
10+
/**
11+
* Provides a base test class for ensuring compliance with the LoggerInterface.
12+
*
13+
* Implementors can extend the class and implement abstract methods to run this
14+
* as part of their test suite.
15+
*/
16+
abstract class LoggerInterfaceTest extends TestCase
17+
{
18+
/**
19+
* Return an instance of the logger to be tested.
20+
*
21+
* @return LoggerInterface
22+
*/
23+
abstract public function getLogger();
24+
25+
/**
26+
* This must return the log messages in order.
27+
*
28+
* The simple formatting of the messages is: "<LOG LEVEL> <MESSAGE>".
29+
*
30+
* Example ->error('Foo') would yield "error Foo".
31+
*
32+
* @return string[]
33+
*/
34+
abstract public function getLogs();
35+
36+
public function testImplements()
37+
{
38+
$this->assertInstanceOf(LoggerInterface::class, $this->getLogger());
39+
}
40+
41+
/**
42+
* @dataProvider provideLevelsAndMessages
43+
*/
44+
public function testLogsAtAllLevels($level, $message)
45+
{
46+
$logger = $this->getLogger();
47+
$logger->{$level}($message, ['user' => 'Bob']);
48+
$logger->log($level, $message, ['user' => 'Bob']);
49+
50+
$expected = [
51+
$level . ' message of level ' . $level . ' with context: Bob',
52+
$level . ' message of level ' . $level . ' with context: Bob',
53+
];
54+
$this->assertEquals($expected, $this->getLogs());
55+
}
56+
57+
public function provideLevelsAndMessages()
58+
{
59+
return [
60+
LogLevel::EMERGENCY => [LogLevel::EMERGENCY, 'message of level emergency with context: {user}'],
61+
LogLevel::ALERT => [LogLevel::ALERT, 'message of level alert with context: {user}'],
62+
LogLevel::CRITICAL => [LogLevel::CRITICAL, 'message of level critical with context: {user}'],
63+
LogLevel::ERROR => [LogLevel::ERROR, 'message of level error with context: {user}'],
64+
LogLevel::WARNING => [LogLevel::WARNING, 'message of level warning with context: {user}'],
65+
LogLevel::NOTICE => [LogLevel::NOTICE, 'message of level notice with context: {user}'],
66+
LogLevel::INFO => [LogLevel::INFO, 'message of level info with context: {user}'],
67+
LogLevel::DEBUG => [LogLevel::DEBUG, 'message of level debug with context: {user}'],
68+
];
69+
}
70+
71+
public function testThrowsOnInvalidLevel()
72+
{
73+
$this->expectException(InvalidArgumentException::class);
74+
$logger = $this->getLogger();
75+
$logger->log('invalid level', 'Foo');
76+
}
77+
78+
public function testContextReplacement()
79+
{
80+
$logger = $this->getLogger();
81+
$logger->info('{Message {nothing} {user} {foo.bar} a}', ['user' => 'Bob', 'foo.bar' => 'Bar']);
82+
83+
$expected = ['info {Message {nothing} Bob Bar a}'];
84+
$this->assertEquals($expected, $this->getLogs());
85+
}
86+
87+
public function testObjectCastToString()
88+
{
89+
$dummy = $this->createPartialMock(DummyTest::class, ['__toString']);
90+
$dummy->expects($this->once())
91+
->method('__toString')
92+
->will($this->returnValue('DUMMY'));
93+
94+
$this->getLogger()->warning($dummy);
95+
96+
$expected = ['warning DUMMY'];
97+
$this->assertEquals($expected, $this->getLogs());
98+
}
99+
100+
public function testContextCanContainAnything()
101+
{
102+
$closed = fopen('php://memory', 'r');
103+
fclose($closed);
104+
105+
$context = [
106+
'bool' => true,
107+
'null' => null,
108+
'string' => 'Foo',
109+
'int' => 0,
110+
'float' => 0.5,
111+
'nested' => ['with object' => new DummyTest()],
112+
'object' => new \DateTime(),
113+
'resource' => fopen('php://memory', 'r'),
114+
'closed' => $closed,
115+
];
116+
117+
$this->getLogger()->warning('Crazy context data', $context);
118+
119+
$expected = ['warning Crazy context data'];
120+
$this->assertEquals($expected, $this->getLogs());
121+
}
122+
123+
public function testContextExceptionKeyCanBeExceptionOrOtherValues()
124+
{
125+
$logger = $this->getLogger();
126+
$logger->warning('Random message', ['exception' => 'oops']);
127+
$logger->critical('Uncaught Exception!', ['exception' => new \LogicException('Fail')]);
128+
129+
$expected = [
130+
'warning Random message',
131+
'critical Uncaught Exception!'
132+
];
133+
$this->assertEquals($expected, $this->getLogs());
134+
}
135+
}

0 commit comments

Comments
 (0)