From fa45a83406a01d2ed597ebe47d34b415b5d78b1a Mon Sep 17 00:00:00 2001 From: HypeMC Date: Tue, 28 Jun 2022 03:23:55 +0200 Subject: [PATCH] Fix compatibility with Monolog 3 --- composer.json | 2 +- phpstan.neon.dist | 4 +- phpunit-deprecation-baseline.json | 5 + src/Handler/ConsoleHandler.php | 59 +++++++++- .../AnnotationConfigurationProviderTest.php | 8 +- .../AttributeConfigurationProviderTest.php | 8 +- .../DummyLoggableOutputWithAnnotation.php | 4 +- .../DummyLoggableOutputWithAttribute.php | 4 +- .../MergedConfigurationProviderTest.php | 8 +- .../BizkitLoggableCommandExtensionTest.php | 49 +++++++-- .../Fixtures/DummyFormatter.php | 24 +++- .../Fixtures/DummyHandler.php | 26 ++++- tests/Handler/ConsoleHandlerTest.php | 103 ++++++++++-------- tests/HandlerFactory/HandlerFactoriesTest.php | 5 +- 14 files changed, 219 insertions(+), 90 deletions(-) diff --git a/composer.json b/composer.json index c3a42e6..a1289d9 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ ], "require": { "php": ">=7.2", - "monolog/monolog": "^1.25.1 || ^2", + "monolog/monolog": "^1.25.1 || ^2 || ^3", "symfony/config": "^4.4 || ^5.2 || ^6.0", "symfony/console": "^4.4 || ^5.2 || ^6.0", "symfony/dependency-injection": "^4.4 || ^5.2 || ^6.0", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 638aeab..04efb94 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -27,11 +27,11 @@ parameters: path: src/HandlerFactory/AbstractHandlerFactory.php - - message: '#^Parameter \#1 \$record of method Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler\:\:handle\(\) expects Monolog\\LogRecord, array\ given\.$#' + message: '#^Comparison operation "\>\=" between 3 and 3 is always true\.$#' count: 1 path: src/Handler/ConsoleHandler.php - - message: '#^Parameter \#1 \$record of method Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler\:\:isHandling\(\) expects Monolog\\LogRecord, array\ given\.$#' + message: '#^Else branch is unreachable because previous condition is always true\.$#' count: 1 path: src/Handler/ConsoleHandler.php diff --git a/phpunit-deprecation-baseline.json b/phpunit-deprecation-baseline.json index 6c684d4..16bb268 100644 --- a/phpunit-deprecation-baseline.json +++ b/phpunit-deprecation-baseline.json @@ -34,6 +34,11 @@ "message": "Function libxml_disable_entity_loader() is deprecated", "count": 4 }, + { + "location": "Bizkit\\LoggableCommandBundle\\Tests\\DependencyInjection\\BizkitLoggableCommandExtensionTest::testConsoleHandlerCanBeInstantiated", + "message": "Function libxml_disable_entity_loader() is deprecated", + "count": 8 + }, { "location": "Bizkit\\LoggableCommandBundle\\Tests\\DependencyInjection\\BizkitLoggableCommandExtensionTest::testAutoconfigurationIsRegistered", "message": "Function libxml_disable_entity_loader() is deprecated", diff --git a/src/Handler/ConsoleHandler.php b/src/Handler/ConsoleHandler.php index 946f912..64c0a19 100644 --- a/src/Handler/ConsoleHandler.php +++ b/src/Handler/ConsoleHandler.php @@ -9,7 +9,10 @@ use Monolog\Handler\FormattableHandlerInterface; use Monolog\Handler\HandlerInterface; use Monolog\Handler\ProcessableHandlerInterface; +use Monolog\Level; use Monolog\Logger; +use Monolog\LogRecord; +use Psr\Log\LogLevel; use Symfony\Bridge\Monolog\Handler\ConsoleHandler as BaseConsoleHandler; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; @@ -17,12 +20,52 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +if (Logger::API >= 3) { + trait CompatibilityHandlerTrait + { + public function handle(LogRecord $record): bool + { + return $this->doHandle($record); + } + + public function isHandling(LogRecord $record): bool + { + return $this->doIsHandling($record); + } + + public function getLevel(): Level + { + return $this->doGetLevel(); + } + } +} else { + trait CompatibilityHandlerTrait + { + public function handle(array $record): bool + { + return $this->doHandle($record); + } + + public function isHandling(array $record): bool + { + return $this->doIsHandling($record); + } + + public function getLevel(): int + { + return $this->doGetLevel(); + } + } +} + /** * Unlike Symfony's ConsoleHandler which sends everything to stderr if available, * this one sends to stdout or stderr depending on the {@see ConsoleHandler::$stdErrThreshold} setting. */ final class ConsoleHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface, EventSubscriberInterface { + use CompatibilityHandlerTrait; + /** * @var BaseConsoleHandler */ @@ -31,7 +74,7 @@ final class ConsoleHandler extends AbstractHandler implements ProcessableHandler /** * @var int */ - private $stdErrThreshold = Logger::WARNING; + private $stdErrThreshold; /** * @var OutputInterface|null @@ -46,11 +89,15 @@ final class ConsoleHandler extends AbstractHandler implements ProcessableHandler public function __construct(BaseConsoleHandler $innerHandler) { $this->innerHandler = $innerHandler; + $this->setStdErrThreshold(Logger::toMonologLevel(LogLevel::WARNING)); } - public function setStdErrThreshold(int $stdErrThreshold): void + /** + * @param int|Level $stdErrThreshold + */ + public function setStdErrThreshold($stdErrThreshold): void { - $this->stdErrThreshold = $stdErrThreshold; + $this->stdErrThreshold = $stdErrThreshold instanceof Level ? $stdErrThreshold->value : $stdErrThreshold; } public function setStandardOutput(OutputInterface $standardOutput): void @@ -96,7 +143,7 @@ public function onTerminate(ConsoleTerminateEvent $event): void $this->close(); } - public function handle(array $record): bool + private function doHandle($record): bool { $this->innerHandler->setOutput( $record['level'] < $this->stdErrThreshold ? $this->standardOutput : $this->errorOutput @@ -110,7 +157,7 @@ public static function getSubscribedEvents(): array return BaseConsoleHandler::getSubscribedEvents(); } - public function isHandling(array $record): bool + private function doIsHandling($record): bool { return $this->innerHandler->isHandling($record); } @@ -156,7 +203,7 @@ public function setLevel($level): AbstractHandler return $this; } - public function getLevel(): int + private function doGetLevel() { return $this->innerHandler->getLevel(); } diff --git a/tests/ConfigurationProvider/AnnotationConfigurationProviderTest.php b/tests/ConfigurationProvider/AnnotationConfigurationProviderTest.php index 43870f5..e49b9f5 100644 --- a/tests/ConfigurationProvider/AnnotationConfigurationProviderTest.php +++ b/tests/ConfigurationProvider/AnnotationConfigurationProviderTest.php @@ -15,7 +15,7 @@ use Doctrine\Common\Annotations\Annotation; use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\DocParser; -use Monolog\Logger; +use Psr\Log\LogLevel; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBag; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; @@ -34,7 +34,7 @@ protected function setUp(): void public function testProviderReturnsExpectedConfigWhenAnnotationIsFound(): void { - $handlerOptions = ['filename' => 'annotation-test', 'level' => Logger::CRITICAL, 'max_files' => 4]; + $handlerOptions = ['filename' => 'annotation-test', 'level' => LogLevel::CRITICAL, 'max_files' => 4]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) @@ -48,7 +48,7 @@ public function testProviderReturnsExpectedConfigWhenAnnotationIsFound(): void public function testProviderReturnsExpectedConfigWhenParentAndChildAnnotationsAreFound(): void { - $handlerOptions = ['filename' => 'child-annotation-test', 'level' => Logger::CRITICAL, 'max_files' => 4]; + $handlerOptions = ['filename' => 'child-annotation-test', 'level' => LogLevel::CRITICAL, 'max_files' => 4]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) @@ -62,7 +62,7 @@ public function testProviderReturnsExpectedConfigWhenParentAndChildAnnotationsAr public function testProviderReturnsExpectedConfigWhenParentAnnotationIsFound(): void { - $handlerOptions = ['filename' => 'annotation-test', 'level' => Logger::CRITICAL, 'max_files' => 4]; + $handlerOptions = ['filename' => 'annotation-test', 'level' => LogLevel::CRITICAL, 'max_files' => 4]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) diff --git a/tests/ConfigurationProvider/AttributeConfigurationProviderTest.php b/tests/ConfigurationProvider/AttributeConfigurationProviderTest.php index 4306126..12324cd 100644 --- a/tests/ConfigurationProvider/AttributeConfigurationProviderTest.php +++ b/tests/ConfigurationProvider/AttributeConfigurationProviderTest.php @@ -12,7 +12,7 @@ use Bizkit\LoggableCommandBundle\Tests\ConfigurationProvider\Fixtures\DummyLoggableOutputWithAttribute; use Bizkit\LoggableCommandBundle\Tests\ConfigurationProvider\Fixtures\DummyLoggableOutputWithAttributeAndParam; use Bizkit\LoggableCommandBundle\Tests\TestCase; -use Monolog\Logger; +use Psr\Log\LogLevel; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBag; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; @@ -26,7 +26,7 @@ final class AttributeConfigurationProviderTest extends TestCase { public function testProviderReturnsExpectedConfigWhenAttributeIsFound(): void { - $handlerOptions = ['filename' => 'attribute-test', 'level' => Logger::EMERGENCY, 'bubble' => true]; + $handlerOptions = ['filename' => 'attribute-test', 'level' => LogLevel::EMERGENCY, 'bubble' => true]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) @@ -40,7 +40,7 @@ public function testProviderReturnsExpectedConfigWhenAttributeIsFound(): void public function testProviderReturnsExpectedConfigWhenParentAndChildAttributesAreFound(): void { - $handlerOptions = ['filename' => 'child-attribute-test', 'level' => Logger::EMERGENCY, 'bubble' => true]; + $handlerOptions = ['filename' => 'child-attribute-test', 'level' => LogLevel::EMERGENCY, 'bubble' => true]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) @@ -54,7 +54,7 @@ public function testProviderReturnsExpectedConfigWhenParentAndChildAttributesAre public function testProviderReturnsExpectedConfigWhenParentAttributeIsFound(): void { - $handlerOptions = ['filename' => 'attribute-test', 'level' => Logger::EMERGENCY, 'bubble' => true]; + $handlerOptions = ['filename' => 'attribute-test', 'level' => LogLevel::EMERGENCY, 'bubble' => true]; $provider = $this->createConfigurationProvider( $this->createContainerBagWithResolveValueMethodCalled($handlerOptions) diff --git a/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAnnotation.php b/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAnnotation.php index 34f357c..2832d8d 100644 --- a/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAnnotation.php +++ b/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAnnotation.php @@ -7,10 +7,10 @@ use Bizkit\LoggableCommandBundle\ConfigurationProvider\Attribute\LoggableOutput; use Bizkit\LoggableCommandBundle\LoggableOutput\LoggableOutputInterface; use Bizkit\LoggableCommandBundle\LoggableOutput\LoggableOutputTrait; -use Monolog\Logger; +use Psr\Log\LogLevel; /** - * @LoggableOutput(filename="annotation-test", level=Logger::CRITICAL, maxFiles=4) + * @LoggableOutput(filename="annotation-test", level=LogLevel::CRITICAL, maxFiles=4) */ class DummyLoggableOutputWithAnnotation implements LoggableOutputInterface { diff --git a/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAttribute.php b/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAttribute.php index eaad2e7..036631f 100644 --- a/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAttribute.php +++ b/tests/ConfigurationProvider/Fixtures/DummyLoggableOutputWithAttribute.php @@ -7,9 +7,9 @@ use Bizkit\LoggableCommandBundle\ConfigurationProvider\Attribute\LoggableOutput; use Bizkit\LoggableCommandBundle\LoggableOutput\LoggableOutputInterface; use Bizkit\LoggableCommandBundle\LoggableOutput\LoggableOutputTrait; -use Monolog\Logger; +use Psr\Log\LogLevel; -#[LoggableOutput(filename: 'attribute-test', level: Logger::EMERGENCY, bubble: true)] +#[LoggableOutput(filename: 'attribute-test', level: LogLevel::EMERGENCY, bubble: true)] class DummyLoggableOutputWithAttribute implements LoggableOutputInterface { use LoggableOutputTrait; diff --git a/tests/ConfigurationProvider/MergedConfigurationProviderTest.php b/tests/ConfigurationProvider/MergedConfigurationProviderTest.php index 5620fe9..06fec9d 100644 --- a/tests/ConfigurationProvider/MergedConfigurationProviderTest.php +++ b/tests/ConfigurationProvider/MergedConfigurationProviderTest.php @@ -9,7 +9,7 @@ use Bizkit\LoggableCommandBundle\LoggableOutput\LoggableOutputInterface; use Bizkit\LoggableCommandBundle\Tests\ConfigurationProvider\Fixtures\DummyLoggableOutput; use Bizkit\LoggableCommandBundle\Tests\TestCase; -use Monolog\Logger; +use Psr\Log\LogLevel; /** * @covers \Bizkit\LoggableCommandBundle\ConfigurationProvider\MergedConfigurationProvider @@ -22,18 +22,18 @@ public function testConfigsAreMergedAsExpected(): void $provider = $this->createConfigurationProvider( $loggableOutput, - ['filename' => 'annotation-test', 'level' => Logger::CRITICAL, 'max_files' => 4, 'extra_options' => [ + ['filename' => 'annotation-test', 'level' => LogLevel::CRITICAL, 'max_files' => 4, 'extra_options' => [ 'foo' => 'one', 'bar' => 'two', ]], - ['filename' => 'attribute-test', 'level' => Logger::EMERGENCY, 'bubble' => true, 'extra_options' => [ + ['filename' => 'attribute-test', 'level' => LogLevel::EMERGENCY, 'bubble' => true, 'extra_options' => [ 'foo' => 'new one', 'baz' => 'three', ]] ); $this->assertSame( - ['filename' => 'annotation-test', 'level' => Logger::CRITICAL, 'max_files' => 4, 'bubble' => true, 'extra_options' => [ + ['filename' => 'annotation-test', 'level' => LogLevel::CRITICAL, 'max_files' => 4, 'bubble' => true, 'extra_options' => [ 'foo' => 'one', 'bar' => 'two', 'baz' => 'three', diff --git a/tests/DependencyInjection/BizkitLoggableCommandExtensionTest.php b/tests/DependencyInjection/BizkitLoggableCommandExtensionTest.php index e5d9244..e7e40b8 100644 --- a/tests/DependencyInjection/BizkitLoggableCommandExtensionTest.php +++ b/tests/DependencyInjection/BizkitLoggableCommandExtensionTest.php @@ -16,8 +16,10 @@ use Bizkit\LoggableCommandBundle\Tests\DependencyInjection\Fixtures\DummyLoggableOutput; use Bizkit\LoggableCommandBundle\Tests\TestCase; use Doctrine\Common\Annotations\Annotation; +use Monolog\Level; use Monolog\Logger; use Monolog\Processor\PsrLogMessageProcessor; +use Psr\Log\LogLevel; use Symfony\Bundle\MonologBundle\DependencyInjection\MonologExtension; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; @@ -180,19 +182,25 @@ public function testArgumentsAreReplacedAsExpected(): void $this->assertTrue($definition->hasMethodCall('setStdErrThreshold')); $methodCalls = array_column($definition->getMethodCalls(), 1, 0); - $this->assertSame([Logger::CRITICAL], $methodCalls['setStdErrThreshold']); + $this->assertSame([Logger::toMonologLevel(LogLevel::CRITICAL)], $methodCalls['setStdErrThreshold']); $definition = $container->getDefinition((string) $definition->getArgument(0)); $this->assertFalse($definition->getArgument(1)); - $this->assertSame([ - OutputInterface::VERBOSITY_NORMAL => Logger::INFO, - OutputInterface::VERBOSITY_VERBOSE => Logger::INFO, - OutputInterface::VERBOSITY_QUIET => Logger::ERROR, - OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO, - OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG, - ], $definition->getArgument(2)); + $expectedVerbosityLevels = array_map(static function (string $level): int { + /** @var int|Level $level */ + $level = Logger::toMonologLevel($level); + + return $level instanceof Level ? $level->value : $level; + }, [ + OutputInterface::VERBOSITY_NORMAL => LogLevel::INFO, + OutputInterface::VERBOSITY_VERBOSE => LogLevel::INFO, + OutputInterface::VERBOSITY_QUIET => LogLevel::ERROR, + OutputInterface::VERBOSITY_VERY_VERBOSE => LogLevel::INFO, + OutputInterface::VERBOSITY_DEBUG => LogLevel::DEBUG, + ]); + $this->assertSame($expectedVerbosityLevels, $definition->getArgument(2)); $this->assertSame([ 'format' => "[%%datetime%%] %%start_tag%%%%level_name%%%%end_tag%% %%message%%\n", @@ -209,6 +217,31 @@ public function testArgumentsAreReplacedAsExpected(): void $this->assertSame('monolog.logger.foo_channel', (string) $argument); } + public function testConsoleHandlerCanBeInstantiated(): void + { + $container = new ContainerBuilder(); + $container->setParameter('kernel.logs_dir', '/var/log'); + $container->registerExtension(new MonologExtension()); + $container->registerExtension($loggableCommandExtension = new BizkitLoggableCommandExtension()); + + $loggableCommandExtension->load([[ + 'channel_name' => 'foo_channel', + 'console_handler_options' => [ + 'bubble' => false, + 'stderr_threshold' => 'CRITICAL', + 'verbosity_levels' => [ + 'VERBOSITY_NORMAL' => 'INFO', + 'VERBOSITY_VERBOSE' => 'INFO', + ], + ], + ]], $container); + + $container->getDefinition(ConsoleHandler::class)->setPublic(true); + $container->compile(); + + $this->assertInstanceOf(ConsoleHandler::class, $container->get(ConsoleHandler::class)); + } + public function testAutoconfigurationIsRegistered(): void { $container = new ContainerBuilder(); diff --git a/tests/DependencyInjection/Fixtures/DummyFormatter.php b/tests/DependencyInjection/Fixtures/DummyFormatter.php index 313aac2..30dc683 100644 --- a/tests/DependencyInjection/Fixtures/DummyFormatter.php +++ b/tests/DependencyInjection/Fixtures/DummyFormatter.php @@ -5,13 +5,29 @@ namespace Bizkit\LoggableCommandBundle\Tests\DependencyInjection\Fixtures; use Monolog\Formatter\FormatterInterface; +use Monolog\LogRecord; -final class DummyFormatter implements FormatterInterface -{ - public function format(array $record) +if (class_exists(LogRecord::class)) { + trait CompatibilityFormatterTrait { - return null; + public function format(LogRecord $record) + { + return null; + } + } +} else { + trait CompatibilityFormatterTrait + { + public function format(array $record) + { + return null; + } } +} + +final class DummyFormatter implements FormatterInterface +{ + use CompatibilityFormatterTrait; public function formatBatch(array $records) { diff --git a/tests/DependencyInjection/Fixtures/DummyHandler.php b/tests/DependencyInjection/Fixtures/DummyHandler.php index 26dfe3a..60a5e53 100644 --- a/tests/DependencyInjection/Fixtures/DummyHandler.php +++ b/tests/DependencyInjection/Fixtures/DummyHandler.php @@ -5,9 +5,30 @@ namespace Bizkit\LoggableCommandBundle\Tests\DependencyInjection\Fixtures; use Monolog\Handler\AbstractHandler; +use Monolog\LogRecord; + +if (class_exists(LogRecord::class)) { + trait CompatibilityHandlerTrait + { + public function handle(LogRecord $record): bool + { + return true; + } + } +} else { + trait CompatibilityHandlerTrait + { + public function handle(array $record): bool + { + return true; + } + } +} final class DummyHandler extends AbstractHandler { + use CompatibilityHandlerTrait; + /** * @var array */ @@ -24,9 +45,4 @@ public function getHandlerOptions(): array { return $this->handlerOptions; } - - public function handle(array $record): bool - { - return true; - } } diff --git a/tests/Handler/ConsoleHandlerTest.php b/tests/Handler/ConsoleHandlerTest.php index c2a68ac..0530181 100644 --- a/tests/Handler/ConsoleHandlerTest.php +++ b/tests/Handler/ConsoleHandlerTest.php @@ -8,8 +8,10 @@ use Bizkit\LoggableCommandBundle\Tests\TestCase; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use Monolog\ResettableInterface; +use Psr\Log\LogLevel; use Symfony\Bridge\Monolog\Handler\ConsoleHandler as BaseConsoleHandler; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleCommandEvent; @@ -20,15 +22,13 @@ /** * @covers \Bizkit\LoggableCommandBundle\Handler\ConsoleHandler - * - * @phpstan-import-type Level from \Monolog\Logger */ final class ConsoleHandlerTest extends TestCase { public function testHandlerIsDecoratedAsExpected(): void { $innerConsoleHandler = new BaseConsoleHandler(null, true, [ - OutputInterface::VERBOSITY_NORMAL => Logger::WARNING, + OutputInterface::VERBOSITY_NORMAL => LogLevel::WARNING, ]); $consoleHandler = new ConsoleHandler($innerConsoleHandler); @@ -37,20 +37,12 @@ public function testHandlerIsDecoratedAsExpected(): void $consoleHandler->setOutput($output); $output->expects($this->once())->method('write'); - $consoleHandler->handleBatch([ - [ - 'datetime' => new \DateTimeImmutable('2021-01-31 13:50:02'), - 'channel' => 'foo', - 'message' => 'Lorem ipsum', - 'level' => Logger::WARNING, - 'level_name' => Logger::getLevelName(Logger::WARNING), - ], - ]); + $consoleHandler->handleBatch([$this->getRecord()]); - $this->assertFalse($innerConsoleHandler->isHandling(['level' => Logger::DEBUG])); - $this->assertFalse($consoleHandler->isHandling(['level' => Logger::DEBUG])); - $this->assertTrue($innerConsoleHandler->isHandling(['level' => Logger::ERROR])); - $this->assertTrue($consoleHandler->isHandling(['level' => Logger::ERROR])); + $this->assertFalse($innerConsoleHandler->isHandling($this->getRecord(LogLevel::DEBUG))); + $this->assertFalse($consoleHandler->isHandling($this->getRecord(LogLevel::DEBUG))); + $this->assertTrue($innerConsoleHandler->isHandling($this->getRecord(LogLevel::ERROR))); + $this->assertTrue($consoleHandler->isHandling($this->getRecord(LogLevel::ERROR))); $consoleHandler->setBubble(false); $this->assertFalse($innerConsoleHandler->getBubble()); @@ -59,18 +51,18 @@ public function testHandlerIsDecoratedAsExpected(): void $this->assertTrue($innerConsoleHandler->getBubble()); $this->assertTrue($consoleHandler->getBubble()); - $consoleHandler->setLevel(Logger::NOTICE); - $this->assertSame(Logger::NOTICE, $innerConsoleHandler->getLevel()); - $this->assertSame(Logger::NOTICE, $consoleHandler->getLevel()); - $consoleHandler->setLevel(Logger::WARNING); - $this->assertSame(Logger::WARNING, $innerConsoleHandler->getLevel()); - $this->assertSame(Logger::WARNING, $consoleHandler->getLevel()); + $consoleHandler->setLevel(LogLevel::NOTICE); + $this->assertSame(Logger::toMonologLevel(LogLevel::NOTICE), $innerConsoleHandler->getLevel()); + $this->assertSame(Logger::toMonologLevel(LogLevel::NOTICE), $consoleHandler->getLevel()); + $consoleHandler->setLevel(LogLevel::WARNING); + $this->assertSame(Logger::toMonologLevel(LogLevel::WARNING), $innerConsoleHandler->getLevel()); + $this->assertSame(Logger::toMonologLevel(LogLevel::WARNING), $consoleHandler->getLevel()); $consoleHandler->onTerminate(new ConsoleTerminateEvent( new Command(), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class), 0 )); - $this->assertFalse($innerConsoleHandler->isHandling(['level' => Logger::ERROR])); - $this->assertFalse($consoleHandler->isHandling(['level' => Logger::ERROR])); + $this->assertFalse($innerConsoleHandler->isHandling($this->getRecord(LogLevel::ERROR))); + $this->assertFalse($consoleHandler->isHandling($this->getRecord(LogLevel::ERROR))); $formatter = $this->createMock(FormatterInterface::class); $consoleHandler->setFormatter($formatter); @@ -95,9 +87,10 @@ public function testHandlerIsDecoratedAsExpected(): void /** * @dataProvider outputData * - * @phpstan-param Level $level + * @param LogLevel::* $stdErrThreshold + * @param LogLevel::* $level */ - public function testCorrectOutputIsUsed(string $expectedOutput, string $silentOutput, int $stdErrThreshold, int $level): void + public function testCorrectOutputIsUsed(string $expectedOutput, string $silentOutput, string $stdErrThreshold, string $level): void { $errorOutput = $this->createMock(OutputInterface::class); $errorOutput->method('getVerbosity')->willReturn(OutputInterface::VERBOSITY_DEBUG); @@ -120,17 +113,9 @@ public function testCorrectOutputIsUsed(string $expectedOutput, string $silentOu ->method('write') ; - $consoleHandler->setStdErrThreshold($stdErrThreshold); + $consoleHandler->setStdErrThreshold(Logger::toMonologLevel($stdErrThreshold)); - $consoleHandler->handle([ - 'datetime' => new \DateTimeImmutable('2021-01-31 13:50:02'), - 'channel' => 'foo', - 'message' => 'Lorem ipsum', - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'context' => [], - 'extra' => [], - ]); + $consoleHandler->handle($this->getRecord($level)); } public function outputData(): iterable @@ -138,33 +123,59 @@ public function outputData(): iterable yield 'NOTICE with threshold level WARNING' => [ 'standardOutput', 'errorOutput', - Logger::WARNING, - Logger::NOTICE, + LogLevel::WARNING, + LogLevel::NOTICE, ]; yield 'WARNING with threshold level WARNING' => [ 'errorOutput', 'standardOutput', - Logger::WARNING, - Logger::WARNING, + LogLevel::WARNING, + LogLevel::WARNING, ]; yield 'ERROR with threshold level WARNING' => [ 'errorOutput', 'standardOutput', - Logger::WARNING, - Logger::WARNING, + LogLevel::WARNING, + LogLevel::WARNING, ]; yield 'WARNING with threshold level ERROR' => [ 'standardOutput', 'errorOutput', - Logger::ERROR, - Logger::WARNING, + LogLevel::ERROR, + LogLevel::WARNING, ]; yield 'CRITICAL with threshold level ERROR' => [ 'errorOutput', 'standardOutput', - Logger::ERROR, - Logger::CRITICAL, + LogLevel::ERROR, + LogLevel::CRITICAL, + ]; + } + + /** + * @param LogLevel::* $level + * + * @return array|LogRecord + */ + private function getRecord(string $level = LogLevel::WARNING) + { + $record = [ + 'datetime' => new \DateTimeImmutable('2021-01-31 13:50:02'), + 'channel' => 'foo', + 'message' => 'Lorem ipsum', + 'level_name' => $level, + 'context' => [], + 'extra' => [], ]; + + $record['level'] = Logger::toMonologLevel($record['level_name']); + + if (class_exists(LogRecord::class)) { + unset($record['level_name']); + $record = new LogRecord(...$record); + } + + return $record; } } diff --git a/tests/HandlerFactory/HandlerFactoriesTest.php b/tests/HandlerFactory/HandlerFactoriesTest.php index d7bf819..a8fda71 100644 --- a/tests/HandlerFactory/HandlerFactoriesTest.php +++ b/tests/HandlerFactory/HandlerFactoriesTest.php @@ -9,6 +9,7 @@ use Bizkit\LoggableCommandBundle\Tests\TestCase; use Monolog\Handler\HandlerInterface; use Monolog\Logger; +use Psr\Log\LogLevel; /** * @covers \Bizkit\LoggableCommandBundle\HandlerFactory\RotatingFileHandlerFactory @@ -24,7 +25,7 @@ public function testRotatingFileHandlerIsConfiguredAsExpected(): void 'include_stacktraces' => false, 'path' => $path = __DIR__.'/foo', 'max_files' => $maxFiles = 3, - 'level' => $level = Logger::EMERGENCY, + 'level' => $level = Logger::toMonologLevel(LogLevel::EMERGENCY), 'bubble' => $bubble = false, 'file_permission' => $filePermission = 666, 'use_locking' => $useLocking = true, @@ -49,7 +50,7 @@ public function testStreamHandlerIsConfiguredAsExpected(): void $handler = $handlerFactory([ 'include_stacktraces' => false, 'path' => $path = __DIR__.'/foo', - 'level' => $level = Logger::EMERGENCY, + 'level' => $level = Logger::toMonologLevel(LogLevel::EMERGENCY), 'bubble' => $bubble = false, 'file_permission' => $filePermission = 666, 'use_locking' => $useLocking = true,