diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index f9457c937d531..e059fe2a9d995 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -128,6 +128,9 @@ public function handleError($type, $msg, $file, $line, $context = []) } $deprecation = new Deprecation($msg, debug_backtrace(), $file); + if ($deprecation->isMuted()) { + return; + } $group = 'other'; if ($deprecation->originatesFromAnObject()) { diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index ea84256663528..2d6aa29224cb5 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -48,9 +48,9 @@ class Deprecation private $originMethod; /** - * @var string one of the PATH_TYPE_* constants + * @var string */ - private $triggeringFilePathType; + private $triggeringFile; /** @var string[] absolute paths to vendor directories */ private static $vendors; @@ -76,7 +76,7 @@ public function __construct($message, array $trace, $file) // No-op } $line = $trace[$i]; - $this->triggeringFilePathType = $this->getPathType($file); + $this->triggeringFile = $file; if (isset($line['object']) || isset($line['class'])) { if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) { $parsedMsg = unserialize($this->message); @@ -88,7 +88,7 @@ public function __construct($message, array $trace, $file) // then we need to use the serialized information to determine // if the error has been triggered from vendor code. if (isset($parsedMsg['triggering_file'])) { - $this->triggeringFilePathType = $this->getPathType($parsedMsg['triggering_file']); + $this->triggeringFile = $parsedMsg['triggering_file']; } return; @@ -169,6 +169,21 @@ public function isLegacy($utilPrefix) || \in_array('legacy', $test::getGroups($class, $method), true); } + /** + * @return bool + */ + public function isMuted() + { + if ('Function ReflectionType::__toString() is deprecated' !== $this->message) { + return false; + } + if (isset($this->trace[1]['class'])) { + return 0 === strpos($this->trace[1]['class'], 'PHPUnit\\'); + } + + return false !== strpos($this->triggeringFile, \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR.'phpunit'.\DIRECTORY_SEPARATOR); + } + /** * Tells whether both the calling package and the called package are vendor * packages. @@ -177,10 +192,11 @@ public function isLegacy($utilPrefix) */ public function getType() { - if (self::PATH_TYPE_SELF === $this->triggeringFilePathType) { + $triggeringFilePathType = $this->getPathType($this->triggeringFile); + if (self::PATH_TYPE_SELF === $triggeringFilePathType) { return self::TYPE_SELF; } - if (self::PATH_TYPE_UNDETERMINED === $this->triggeringFilePathType) { + if (self::PATH_TYPE_UNDETERMINED === $triggeringFilePathType) { return self::TYPE_UNDETERMINED; } $erroringFile = $erroringPackage = null; diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 0c8708bb35f00..60b1efdfa2317 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation; class DeprecationTest extends TestCase @@ -55,6 +56,68 @@ public function testItRulesOutFilesOutsideVendorsAsIndirect() $this->assertNotSame(Deprecation::TYPE_INDIRECT, $deprecation->getType()); } + /** + * @dataProvider mutedProvider + */ + public function testItMutesOnlySpecificErrorMessagesWhenTheCallingCodeIsInPhpunit($muted, $callingClass, $message) + { + $trace = $this->debugBacktrace(); + array_unshift($trace, ['class' => $callingClass]); + array_unshift($trace, ['class' => DeprecationErrorHandler::class]); + $deprecation = new Deprecation($message, $trace, 'should_not_matter.php'); + $this->assertSame($muted, $deprecation->isMuted()); + } + + public function mutedProvider() + { + yield 'not from phpunit, and not a whitelisted message' => [ + false, + \My\Source\Code::class, + 'Self deprecating humor is deprecated by itself' + ]; + yield 'from phpunit, but not a whitelisted message' => [ + false, + \PHPUnit\Random\Piece\Of\Code::class, + 'Self deprecating humor is deprecated by itself' + ]; + yield 'whitelisted message, but not from phpunit' => [ + false, + \My\Source\Code::class, + 'Function ReflectionType::__toString() is deprecated', + ]; + yield 'from phpunit and whitelisted message' => [ + true, + \PHPUnit\Random\Piece\Of\Code::class, + 'Function ReflectionType::__toString() is deprecated', + ]; + } + + public function testNotMutedIfNotCalledFromAClassButARandomFile() + { + $deprecation = new Deprecation( + 'Function ReflectionType::__toString() is deprecated', + [ + ['file' => 'should_not_matter.php'], + ['file' => 'should_not_matter_either.php'], + ], + 'my-procedural-controller.php' + ); + $this->assertFalse($deprecation->isMuted()); + } + + public function testItTakesMutesDeprecationFromPhpUnitFiles() + { + $deprecation = new Deprecation( + 'Function ReflectionType::__toString() is deprecated', + [ + ['file' => 'should_not_matter.php'], + ['file' => 'should_not_matter_either.php'], + ], + 'random_path' . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'phpunit' . \DIRECTORY_SEPARATOR . 'whatever.php' + ); + $this->assertTrue($deprecation->isMuted()); + } + /** * This method is here to simulate the extra level from the piece of code * triggering an error to the error handler
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: