From d3c43debdb07cd6caaf62c71331406b3bc458667 Mon Sep 17 00:00:00 2001 From: rekmixa Date: Sat, 24 Jan 2026 23:02:28 +0500 Subject: [PATCH 01/11] Improve mutation tests (#135) --- infection.json.dist | 5 +++- src/ContextProvider/SystemContextProvider.php | 11 +++++++- src/Logger.php | 18 ++---------- .../SystemContextProviderTest.php | 28 +++++++++++++++++++ tests/LoggerTest.php | 16 ++++++++++- 5 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 tests/ContextProvider/SystemContextProviderTest.php diff --git a/infection.json.dist b/infection.json.dist index 3776e223..52b04360 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -11,6 +11,9 @@ } }, "mutators": { - "@default": true + "@default": true, + "global-ignoreSourceCodeByRegex": [ + "register_shutdown_function" + ], } } diff --git a/src/ContextProvider/SystemContextProvider.php b/src/ContextProvider/SystemContextProvider.php index 0af3ee57..6be98ab2 100644 --- a/src/ContextProvider/SystemContextProvider.php +++ b/src/ContextProvider/SystemContextProvider.php @@ -28,6 +28,15 @@ public function __construct( private int $traceLevel = 0, array $excludedTracePaths = [], ) { + if ($this->traceLevel < 0) { + throw new InvalidArgumentException( + sprintf( + 'Trace level must be greater than or equal to zero, %s received.', + $this->traceLevel, + ) + ); + } + /** @psalm-suppress DeprecatedMethod `setExcludedTracePaths` will be private and not deprecated */ $this->setExcludedTracePaths($excludedTracePaths); } @@ -109,7 +118,7 @@ private function collectTrace(array $backtrace): array if (isset($trace['file'], $trace['line'])) { $excludedMatch = array_filter( $this->excludedTracePaths, - static fn($path) => str_contains($trace['file'], $path) + static fn(string $path): bool => str_contains($trace['file'], $path), ); if (empty($excludedMatch)) { diff --git a/src/Logger.php b/src/Logger.php index af5986f4..31c9e07b 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -11,9 +11,8 @@ use RuntimeException; use Stringable; use Throwable; -use Yiisoft\Log\ContextProvider\SystemContextProvider; use Yiisoft\Log\ContextProvider\ContextProviderInterface; - +use Yiisoft\Log\ContextProvider\SystemContextProvider; use function count; use function implode; use function in_array; @@ -109,20 +108,7 @@ public function __construct( */ public static function validateLevel(mixed $level): string { - if (!is_string($level)) { - throw new \Psr\Log\InvalidArgumentException(sprintf( - 'The log message level must be a string, %s provided.', - get_debug_type($level) - )); - } - - if (!in_array($level, self::LEVELS, true)) { - throw new \Psr\Log\InvalidArgumentException(sprintf( - 'Invalid log message level "%s" provided. The following values are supported: "%s".', - $level, - implode('", "', self::LEVELS) - )); - } + self::assertLevelIsValid($level); return $level; } diff --git a/tests/ContextProvider/SystemContextProviderTest.php b/tests/ContextProvider/SystemContextProviderTest.php new file mode 100644 index 00000000..8a53db94 --- /dev/null +++ b/tests/ContextProvider/SystemContextProviderTest.php @@ -0,0 +1,28 @@ +expectException(InvalidArgumentException::class); + new SystemContextProvider(-1); + } + + public function testContextHasNeededData(): void + { + $provider = new SystemContextProvider(); + + $this->assertArrayHasKey('time', $provider->getContext()); + $this->assertArrayHasKey('trace', $provider->getContext()); + $this->assertArrayHasKey('memory', $provider->getContext()); + $this->assertArrayHasKey('category', $provider->getContext()); + } +} diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index 46c9a038..b68fbc68 100644 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -54,11 +54,24 @@ public function testLog(): void $this->assertGreaterThanOrEqual($memory, $messages[1]->context('memory')); } + public function testLogWithWrongLevel(): void + { + $this->expectException(\Psr\Log\InvalidArgumentException::class); + $this->logger->log(123, 'test1'); + } + + public function testLogWithUnsupportedLevel(): void + { + $this->expectException(\Psr\Log\InvalidArgumentException::class); + $this->logger->log('unsupported-level', 'test1'); + } + public function testLogWithTraceLevel(): void { $memory = memory_get_usage(); $this->logger->setTraceLevel($traceLevel = 3); + $line = __LINE__; $this->logger->log(LogLevel::INFO, 'test3'); $messages = $this->getInaccessibleMessages($this->logger); @@ -68,7 +81,7 @@ public function testLogWithTraceLevel(): void $this->assertSame('application', $messages[0]->context('category')); $this->assertSame([ 'file' => __FILE__, - 'line' => 62, + 'line' => $line + 1, 'function' => 'log', 'class' => Logger::class, 'type' => '->', @@ -143,6 +156,7 @@ public function testSetExcludedTracePaths(): void $this->logger->info('info message'); $messages = $this->getInaccessibleMessages($this->logger); + $this->assertNotEmpty($messages[1]->context('trace')); foreach ($messages[1]->context('trace') as $trace) { $this->assertNotSame(__FILE__, $trace['file']); } From f3b4c1b9f81e1c5e9112782c083938c9735843f2 Mon Sep 17 00:00:00 2001 From: rekmixa Date: Sun, 25 Jan 2026 00:04:33 +0500 Subject: [PATCH 02/11] suppress psalm errors in Logger::validateLevel (#135) --- src/Logger.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Logger.php b/src/Logger.php index 31c9e07b..3c7ec13a 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -105,6 +105,8 @@ public function __construct( * * @return string The text display of the level. * @deprecated since 2.1, to be removed in 3.0. Use {@see LogLevel::assertLevelIsValid()} instead. + * @psalm-suppress MixedInferredReturnType + * @psalm-suppress MixedReturnStatement */ public static function validateLevel(mixed $level): string { From 601c705762c26726af5b899683dbb44115e241de Mon Sep 17 00:00:00 2001 From: rekmixa Date: Sun, 25 Jan 2026 00:08:04 +0500 Subject: [PATCH 03/11] Fix code style in Logger imports (#135) --- src/Logger.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Logger.php b/src/Logger.php index 3c7ec13a..f3faba57 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -13,6 +13,7 @@ use Throwable; use Yiisoft\Log\ContextProvider\ContextProviderInterface; use Yiisoft\Log\ContextProvider\SystemContextProvider; + use function count; use function implode; use function in_array; From 1767f670b772280aa30eb86962ccd682acde2979 Mon Sep 17 00:00:00 2001 From: rekmixa Date: Sun, 25 Jan 2026 00:13:35 +0500 Subject: [PATCH 04/11] fix infection.json.dist (#135) --- infection.json.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infection.json.dist b/infection.json.dist index 52b04360..46279901 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -14,6 +14,6 @@ "@default": true, "global-ignoreSourceCodeByRegex": [ "register_shutdown_function" - ], + ] } } From 673d40e51f3c1702b3a91defde6599cf5cfd3fd2 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 25 Jan 2026 14:43:46 +0300 Subject: [PATCH 05/11] Update src/Logger.php --- src/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Logger.php b/src/Logger.php index f3faba57..76f2186c 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -105,7 +105,7 @@ public function __construct( * @throws \Psr\Log\InvalidArgumentException for invalid log message level. * * @return string The text display of the level. - * @deprecated since 2.1, to be removed in 3.0. Use {@see LogLevel::assertLevelIsValid()} instead. + * @deprecated since 2.1, to be removed in 3.0. Use {@see Logger::assertLevelIsValid()} instead. * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ From dbc8fd7b432a1b7bf63f08bc990a0632743d6d3f Mon Sep 17 00:00:00 2001 From: rekmixa <49339132+rekmixa@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:14:10 +0500 Subject: [PATCH 06/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6439b25a..534a67a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) - Chg #130: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names and nested placeholders (@technicated) +- New #135: Added validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero ## 2.2.0 December 13, 2025 From f2aeb972615c267182f462488bd76036073dc96e Mon Sep 17 00:00:00 2001 From: michael19 <91liahim@gmail.com> Date: Mon, 26 Jan 2026 09:17:36 +0500 Subject: [PATCH 07/11] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 012e809a..be5e588a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) - Chg #130: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names and nested placeholders (@technicated) -- New #135: Added validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero - Chg #130, #133: Changed `Message::parse()` to conform to PSR-3 (@technicated, @vjik) +- New #135: Added validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero (@rekmixa) ## 2.2.0 December 13, 2025 From 0cb233ce7cc0127db2f779a75ba5d8f03a7c2a87 Mon Sep 17 00:00:00 2001 From: michael19 <91liahim@gmail.com> Date: Mon, 26 Jan 2026 09:21:37 +0500 Subject: [PATCH 08/11] update changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be5e588a..19446ca6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ ## 2.2.1 under development - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) -- Chg #130: Changed `Message::parse()` to conform to PSR-3, removing support for placeholders with arbitrary names and nested placeholders (@technicated) - Chg #130, #133: Changed `Message::parse()` to conform to PSR-3 (@technicated, @vjik) - New #135: Added validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero (@rekmixa) From 848d3213440f91191843698bd251a0348bf86e35 Mon Sep 17 00:00:00 2001 From: rekmixa <49339132+rekmixa@users.noreply.github.com> Date: Tue, 27 Jan 2026 19:08:29 +0500 Subject: [PATCH 09/11] Update tests/ContextProvider/SystemContextProviderTest.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/ContextProvider/SystemContextProviderTest.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/ContextProvider/SystemContextProviderTest.php b/tests/ContextProvider/SystemContextProviderTest.php index 8a53db94..2c0abaca 100644 --- a/tests/ContextProvider/SystemContextProviderTest.php +++ b/tests/ContextProvider/SystemContextProviderTest.php @@ -19,10 +19,11 @@ public function testWrongTraceLevel(): void public function testContextHasNeededData(): void { $provider = new SystemContextProvider(); + $context = $provider->getContext(); - $this->assertArrayHasKey('time', $provider->getContext()); - $this->assertArrayHasKey('trace', $provider->getContext()); - $this->assertArrayHasKey('memory', $provider->getContext()); - $this->assertArrayHasKey('category', $provider->getContext()); + $this->assertArrayHasKey('time', $context); + $this->assertArrayHasKey('trace', $context); + $this->assertArrayHasKey('memory', $context); + $this->assertArrayHasKey('category', $context); } } From 0fc663d8c37017c7b4625c349a3bf56b72ff6cd8 Mon Sep 17 00:00:00 2001 From: rekmixa Date: Tue, 27 Jan 2026 19:14:59 +0500 Subject: [PATCH 10/11] move traceLevel validation to assert assertTraceLevelIsValid method in SystemContextProvider (#135) --- src/ContextProvider/SystemContextProvider.php | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ContextProvider/SystemContextProvider.php b/src/ContextProvider/SystemContextProvider.php index 6be98ab2..cd66c5a6 100644 --- a/src/ContextProvider/SystemContextProvider.php +++ b/src/ContextProvider/SystemContextProvider.php @@ -28,15 +28,7 @@ public function __construct( private int $traceLevel = 0, array $excludedTracePaths = [], ) { - if ($this->traceLevel < 0) { - throw new InvalidArgumentException( - sprintf( - 'Trace level must be greater than or equal to zero, %s received.', - $this->traceLevel, - ) - ); - } - + $this->assertTraceLevelIsValid($this->traceLevel); /** @psalm-suppress DeprecatedMethod `setExcludedTracePaths` will be private and not deprecated */ $this->setExcludedTracePaths($excludedTracePaths); } @@ -65,7 +57,9 @@ public function getContext(): array */ public function setTraceLevel(int $traceLevel): self { + $this->assertTraceLevelIsValid($traceLevel); $this->traceLevel = $traceLevel; + return $this; } @@ -133,4 +127,23 @@ private function collectTrace(array $backtrace): array return $traces; } + + /** + * Validates $traceLevel property + * + * @param int $traceLevel The number of call stack information. + * + * @see self::$traceLevel + */ + private function assertTraceLevelIsValid(int $traceLevel): void + { + if ($traceLevel < 0) { + throw new InvalidArgumentException( + sprintf( + 'Trace level must be greater than or equal to zero, %s received.', + $traceLevel, + ), + ); + } + } } From 878e35813ce7ed42737bacde14cbe9f2070c0121 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 3 Feb 2026 13:44:36 +0300 Subject: [PATCH 11/11] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41d13e88..4ad62563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Enh #132: Add benchmarks, improve performance of `Message::parse()` (@samdark) - Bug #130: Updated `Message::parse()` to correctly support multiple placeholders (@technicated) - Chg #130, #133: Changed `Message::parse()` to conform to PSR-3 (@technicated, @vjik) -- New #135: Added validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero (@rekmixa) +- Enh #135: Add validation for `$traceLevel` in `SystemContextProvider` to ensure values are greater than or equal to zero (@rekmixa) - Enh #137: Explicitly import classes, functions, and constants in "use" section (@mspirkov) ## 2.2.0 December 13, 2025