From 601d9fbcad82ec825aeb7e520b439b550bedba52 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Wed, 13 Mar 2019 10:47:10 +0100 Subject: [PATCH] Add possibility to ignore deprecation messages and/or files that emit them. Add possibility to ignore deprecation messages and/or files that emit them. --- .gitignore | 1 + README.md | 39 ++++++++++++++ .../DeprecationErrorHandler/ignore_file.phpt | 24 +++++++++ .../ignore_file_and_message.phpt | 34 ++++++++++++ .../ignore_message.phpt | 34 ++++++++++++ .../DeprecationExtensionTest.php | 52 ++++++++++++++++++- behat.yml | 24 +++++++++ src/Error/Handler/DeprecationErrorHandler.php | 50 +++++++++++++++++- src/Resources/config/services.xml | 1 + src/ServiceContainer/DeprecationExtension.php | 20 +++++++ 10 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 Tests/Error/Handler/DeprecationErrorHandler/ignore_file.phpt create mode 100644 Tests/Error/Handler/DeprecationErrorHandler/ignore_file_and_message.phpt create mode 100644 Tests/Error/Handler/DeprecationErrorHandler/ignore_message.phpt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57872d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/README.md b/README.md index 318814e..87ae1e1 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,45 @@ Run Behat and enjoy :) - Remaining - Deprecation notices are all other (non-legacy) notices. +## Ignore some deprecation + +You can filter the file that did make the call to `trigger_error` like this: + +```yaml +default: + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { file: '#symfony#' } + - { file: '#my-app#' } +``` + +It will ignore every files that matches any of the listed regexps + +Or you can filter deprecation messages like this: + +```yaml +default: + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { message: '#symfony#' } + - { message: '#my-app#' } +``` + +It will ignore every deprecation message that matches any of the listed regexps + +You can use both filter types at the same time: + + +```yaml +default: + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { file: '#symfony#', message: '#symfony#' } +``` + ## Credits This library is developed by [Catalin Ciobanu](https://github.com/caciobanu). diff --git a/Tests/Error/Handler/DeprecationErrorHandler/ignore_file.phpt b/Tests/Error/Handler/DeprecationErrorHandler/ignore_file.phpt new file mode 100644 index 0000000..c7ab7b2 --- /dev/null +++ b/Tests/Error/Handler/DeprecationErrorHandler/ignore_file.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test DeprecationErrorHandler in weak mode +--FILE-- +/dev/null", $exitCode); + +if ($exitCode === 1) { + echo "Exit code: 1"; +} + +?> +--EXPECTF-- + +Exit code: 1 diff --git a/Tests/Error/Handler/DeprecationErrorHandler/ignore_file_and_message.phpt b/Tests/Error/Handler/DeprecationErrorHandler/ignore_file_and_message.phpt new file mode 100644 index 0000000..5921de8 --- /dev/null +++ b/Tests/Error/Handler/DeprecationErrorHandler/ignore_file_and_message.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test DeprecationErrorHandler in weak mode +--FILE-- +/dev/null", $exitCode); + +if ($exitCode === 1) { + echo "Exit code: 1"; +} + +?> +--EXPECTF-- + +Remaining deprecation notices (2) + +Method 'deprecatedMethodSilenced' is deprecated: 2x + 2x in DeprecatedCaller::callDeprecatedMethodSilenced from Caciobanu\Behat\DeprecationExtension\Tests\Deprecated + +Legacy deprecation notices (4) + +Method 'deprecatedMethodSilenced' is deprecated: 4x + 4x in DeprecatedCaller::callDeprecatedMethodSilenced from Caciobanu\Behat\DeprecationExtension\Tests\Deprecated + +Exit code: 1 diff --git a/Tests/Error/Handler/DeprecationErrorHandler/ignore_message.phpt b/Tests/Error/Handler/DeprecationErrorHandler/ignore_message.phpt new file mode 100644 index 0000000..649854c --- /dev/null +++ b/Tests/Error/Handler/DeprecationErrorHandler/ignore_message.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test DeprecationErrorHandler in weak mode +--FILE-- +/dev/null", $exitCode); + +if ($exitCode === 1) { + echo "Exit code: 1"; +} + +?> +--EXPECTF-- + +Remaining deprecation notices (2) + +Method 'deprecatedMethodSilenced' is deprecated: 2x + 2x in DeprecatedCaller::callDeprecatedMethodSilenced from Caciobanu\Behat\DeprecationExtension\Tests\Deprecated + +Legacy deprecation notices (4) + +Method 'deprecatedMethodSilenced' is deprecated: 4x + 4x in DeprecatedCaller::callDeprecatedMethodSilenced from Caciobanu\Behat\DeprecationExtension\Tests\Deprecated + +Exit code: 1 diff --git a/Tests/ServiceContainer/DeprecationExtensionTest.php b/Tests/ServiceContainer/DeprecationExtensionTest.php index cd2b030..b686fe0 100644 --- a/Tests/ServiceContainer/DeprecationExtensionTest.php +++ b/Tests/ServiceContainer/DeprecationExtensionTest.php @@ -42,6 +42,7 @@ public function testLoad() $this->assertEquals('Caciobanu\Behat\DeprecationExtension\Error\Handler\DeprecationErrorHandler' ,$definition->getClass()); $this->assertEquals('%caciobanu.deprecation_extension.mode%', (string) $definition->getArgument(0)); + $this->assertEquals('%caciobanu.deprecation_extension.ignore%', (string) $definition->getArgument(1)); } /** @@ -62,6 +63,25 @@ public function testConfigureInvalidValue() )); } + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testConfigureInvalidIgnoreValue() + { + $configurationTree = new ConfigurationTree(); + $tree = $configurationTree->getConfigTree(array(new DeprecationExtension())); + + $processor = new Processor(); + $processor->process($tree, array( + 'testwork' => array( + 'caciobanu_deprecation_extension' => array( + 'mode' => 'weak', + 'ignore' => array('hello'), + ), + ), + )); + } + /** * @dataProvider configValueProvider */ @@ -79,7 +99,28 @@ public function testConfigure($mode) ), )); - $this->assertEquals(array('caciobanu_deprecation_extension' => array('mode' => $mode)), $config); + $this->assertEquals(array('caciobanu_deprecation_extension' => array('mode' => $mode, 'ignore' => array())), $config); + } + + /** + * @dataProvider configIgnoreValueProvider + */ + public function testConfigureIgnore($ignore) + { + $configurationTree = new ConfigurationTree(); + $tree = $configurationTree->getConfigTree(array(new DeprecationExtension())); + + $processor = new Processor(); + $config = $processor->process($tree, array( + 'testwork' => array( + 'caciobanu_deprecation_extension' => array( + 'mode' => 'weak', + 'ignore' => $ignore + ), + ), + )); + + $this->assertEquals(array('caciobanu_deprecation_extension' => array('mode' => 'weak', 'ignore' => $ignore)), $config); } public function configValueProvider() @@ -92,4 +133,13 @@ public function configValueProvider() array(100), ); } + + public function configIgnoreValueProvider() + { + return array( + array(array(array('file' => 'file'))), + array(array(array('message' => 'message'))), + array(array(array('file' => 'file', 'message' => 'message'), array('file' => 'file', 'message' => 'message'))), + ); + } } diff --git a/behat.yml b/behat.yml index 712c6b4..b5fa220 100644 --- a/behat.yml +++ b/behat.yml @@ -18,6 +18,30 @@ integer: Caciobanu\Behat\DeprecationExtension: mode: 1 +ignore_file: + calls: + error_reporting: 32767 + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { file: '#DeprecatedClass#' } + +ignore_message: + calls: + error_reporting: 32767 + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { message: '#deprecatedMethodUnsilenced#' } + +ignore_file_and_message: + calls: + error_reporting: 32767 + extensions: + Caciobanu\Behat\DeprecationExtension: + ignore: + - { file: '#DeprecatedClass#', message: '#deprecatedMethodUnsilenced#' } + default_no_error_reporting: calls: error_reporting: 0 diff --git a/src/Error/Handler/DeprecationErrorHandler.php b/src/Error/Handler/DeprecationErrorHandler.php index 93e4f76..853a69a 100644 --- a/src/Error/Handler/DeprecationErrorHandler.php +++ b/src/Error/Handler/DeprecationErrorHandler.php @@ -46,12 +46,19 @@ class DeprecationErrorHandler */ private $mode; + /** + * @var array $ignore + */ + private $ignore; + /** * @param int|string|null $mode The reporting mode. + * @param array $ignore */ - public function __construct($mode = null) + public function __construct($mode = null, array $ignore = array()) { $this->mode = $mode; + $this->ignore = $ignore; } /** @@ -65,6 +72,10 @@ public function register(Call $call, $level, $message) return; } + if ($this->isIgnored($message)) { + return; + } + $trace = debug_backtrace(); $group = 'remaining'; @@ -205,4 +216,41 @@ private function hasColorSupport() return defined('STDOUT') && function_exists('posix_isatty') && @posix_isatty(STDOUT); } + + private function getCaller() + { + $backtrace = debug_backtrace(); + foreach ($backtrace as $item) { + if ('trigger_error' === $item['function']) { + return $item; + } + } + } + + /** + * @param string $message + * @return bool + */ + private function isIgnored($message) + { + if (empty($this->ignore)) { + return false; + } + + $callerItem = $this->getCaller(); + + foreach ($this->ignore as $ignore) { + if (isset($ignore['file'], $ignore['message'])) { + return preg_match($ignore['file'], $callerItem['file']) && preg_match($ignore['message'], $message); + } + if (isset($ignore['file']) && preg_match($ignore['file'], $callerItem['file'])) { + return true; + } + if (isset($ignore['message']) && preg_match($ignore['message'], $message)) { + return true; + } + } + + return false; + } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index b322173..da0d554 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -6,6 +6,7 @@ %caciobanu.deprecation_extension.mode% + %caciobanu.deprecation_extension.ignore% diff --git a/src/ServiceContainer/DeprecationExtension.php b/src/ServiceContainer/DeprecationExtension.php index 8d915c8..bd6aa85 100644 --- a/src/ServiceContainer/DeprecationExtension.php +++ b/src/ServiceContainer/DeprecationExtension.php @@ -59,6 +59,24 @@ public function configure(ArrayNodeDefinition $builder) { $builder ->children() + ->arrayNode('ignore') + ->arrayPrototype() + ->children() + ->scalarNode('file')->end() + ->scalarNode('message')->end() + ->end() + ->validate() + ->ifTrue(function ($value) { + if (!isset($value['file']) && !isset($value['message'])) { + return true; + } + + return false; + }) + ->thenInvalid('At least "file" or "message" must be set') + ->end() + ->end() + ->end() ->scalarNode('mode') ->defaultValue(null) ->validate() @@ -81,6 +99,8 @@ public function configure(ArrayNodeDefinition $builder) public function load(ContainerBuilder $container, array $config) { $container->setParameter('caciobanu.deprecation_extension.mode', $config['mode']); + $ignore = isset($config['ignore']) ? $config['ignore'] : array(); + $container->setParameter('caciobanu.deprecation_extension.ignore', $ignore); $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.xml');