Skip to content

Commit ee3e329

Browse files
authored
Merge pull request #6704 from paulbalandan/assert-logged-approx
feat: Check logs against parts of the message only
2 parents 6fe095a + 4894788 commit ee3e329

File tree

7 files changed

+124
-9
lines changed

7 files changed

+124
-9
lines changed

system/Test/CIUnitTestCase.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,6 @@ protected function mockSession()
349349
* @param string|null $expectedMessage
350350
*
351351
* @return bool
352-
*
353-
* @throws Exception
354352
*/
355353
public function assertLogged(string $level, $expectedMessage = null)
356354
{
@@ -365,6 +363,21 @@ public function assertLogged(string $level, $expectedMessage = null)
365363
return $result;
366364
}
367365

366+
/**
367+
* Asserts that there is a log record that contains `$logMessage` in the message.
368+
*/
369+
public function assertLogContains(string $level, string $logMessage, string $message = ''): void
370+
{
371+
$this->assertTrue(
372+
TestLogger::didLog($level, $logMessage, false),
373+
$message ?: sprintf(
374+
'Failed asserting that logs have a record of message containing "%s" with level "%s".',
375+
$logMessage,
376+
$level
377+
)
378+
);
379+
}
380+
368381
/**
369382
* Hooks into CodeIgniter's Events system to check if a specific
370383
* event was triggered or not.

system/Test/TestLogger.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,24 @@ public function log($level, $message, array $context = []): bool
5959
*
6060
* @return bool
6161
*/
62-
public static function didLog(string $level, $message)
62+
public static function didLog(string $level, $message, bool $useExactComparison = true)
6363
{
64+
$lowerLevel = strtolower($level);
65+
6466
foreach (self::$op_logs as $log) {
65-
if (strtolower($log['level']) === strtolower($level) && $message === $log['message']) {
67+
if (strtolower($log['level']) !== $lowerLevel) {
68+
continue;
69+
}
70+
71+
if ($useExactComparison) {
72+
if ($log['message'] === $message) {
73+
return true;
74+
}
75+
76+
continue;
77+
}
78+
79+
if (strpos($log['message'], $message) !== false) {
6680
return true;
6781
}
6882
}

tests/system/Test/TestCaseTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public function testLogging()
4545
$this->assertLogged('error', 'Some variable did not contain a value.');
4646
}
4747

48+
public function testAssertLogContains()
49+
{
50+
log_message('error', 'Some variable did not contain a value.');
51+
$this->assertLogContains('error', 'variable did not');
52+
}
53+
4854
public function testEventTriggering()
4955
{
5056
Events::on('foo', static function ($arg) use (&$result) {

tests/system/Test/TestLoggerTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Test;
13+
14+
use Config\Logger;
15+
16+
/**
17+
* @internal
18+
*/
19+
final class TestLoggerTest extends CIUnitTestCase
20+
{
21+
/**
22+
* @dataProvider provideDidLogCases
23+
*/
24+
public function testDidLogMethod(bool $expected, string $level, string $message, bool $exact): void
25+
{
26+
(new TestLogger(new Logger()))->log('error', 'Some variable did not contain a value.');
27+
28+
$this->assertSame(
29+
$expected,
30+
TestLogger::didLog($level, $message, $exact),
31+
);
32+
}
33+
34+
public function provideDidLogCases(): iterable
35+
{
36+
yield 'exact' => [
37+
true,
38+
'error',
39+
'Some variable did not contain a value.',
40+
true,
41+
];
42+
43+
yield 'wrong level' => [
44+
false,
45+
'warning',
46+
'Some variable did not contain a value.',
47+
true,
48+
];
49+
50+
yield 'wrong message' => [
51+
false,
52+
'error',
53+
'Some variables did not contain a value.',
54+
true,
55+
];
56+
57+
yield 'approximate' => [
58+
true,
59+
'error',
60+
'Some variable did not',
61+
false,
62+
];
63+
64+
yield 'approximate but wrong level' => [
65+
false,
66+
'warning',
67+
'Some variable did not',
68+
false,
69+
];
70+
}
71+
}

user_guide_src/source/changelogs/v4.3.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ Testing
128128
- The CITestStreamFilter filter class now implements methods for adding a filter to streams. See :ref:`testing-cli-output`.
129129
- Added the ``PhpStreamWrapper`` to make it easier to work with setting data to ``php://stdin``. See :ref:`testing-cli-input`.
130130
- Added method :ref:`benchmark-timer-record` to measure performance in a callable. Also enhanced common function ``timer()`` to accept optional callable.
131+
- A boolean third parameter ``$useExactComparison`` is added to ``TestLogger::didLog()`` which sets whether log messages are checked verbatim. This defaults to ``true``.
132+
- Added method ``CIUnitTestCase::assertLogContains()`` which compares log messages by parts instead of the whole of the message.
131133

132134
Database
133135
========

user_guide_src/source/testing/overview.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,12 @@ Additional Assertions
126126
assertLogged($level, $expectedMessage)
127127
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
128128

129-
Ensure that something you expected to be logged actually was:
129+
Ensure that something you expected to be logged was actually logged:
130+
131+
assertLogContains($level, $logMessage)
132+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
133+
134+
Ensure that there's a record in the logs which contains a message part.
130135

131136
.. literalinclude:: overview/007.php
132137

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
<?php
22

3-
$config = new LoggerConfig();
4-
$logger = new Logger($config);
3+
$config = new Config\Logger();
4+
$logger = new CodeIgniter\Log\Logger($config);
55

6-
// ... do something that you expect a log entry from
6+
// check verbatim the log message
77
$logger->log('error', "That's no moon");
8-
98
$this->assertLogged('error', "That's no moon");
9+
10+
// check that a portion of the message is found in the logs
11+
$exception = new RuntimeException('Hello world.');
12+
$logger->log('error', $exception->getTraceAsString());
13+
$this->assertLogContains('error', '{main}');

0 commit comments

Comments
 (0)