From 6ffaf5ef4c83dc20a29315aa393adf891cf4786b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20Gersen?= Date: Thu, 11 Aug 2022 11:03:30 +0200 Subject: [PATCH] Use triggering class to generate baseline for deprecation messages from DebugClassLoader --- DeprecationErrorHandler/Configuration.php | 4 +- DeprecationErrorHandler/Deprecation.php | 25 ++++++++++ .../ConfigurationTest.php | 50 ++++++++++++++++--- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/DeprecationErrorHandler/Configuration.php b/DeprecationErrorHandler/Configuration.php index 6e9f0e4..e749c74 100644 --- a/DeprecationErrorHandler/Configuration.php +++ b/DeprecationErrorHandler/Configuration.php @@ -200,7 +200,9 @@ public function isBaselineDeprecation(Deprecation $deprecation) return false; } - if ($deprecation->originatesFromAnObject()) { + if ($deprecation->originatesFromDebugClassLoader()) { + $location = $deprecation->triggeringClass(); + } elseif ($deprecation->originatesFromAnObject()) { $location = $deprecation->originatingClass().'::'.$deprecation->originatingMethod(); } else { $location = 'procedural code'; diff --git a/DeprecationErrorHandler/Deprecation.php b/DeprecationErrorHandler/Deprecation.php index 5a5a0f6..95737f8 100644 --- a/DeprecationErrorHandler/Deprecation.php +++ b/DeprecationErrorHandler/Deprecation.php @@ -41,6 +41,7 @@ class Deprecation private $originClass; private $originMethod; private $triggeringFile; + private $triggeringClass; /** @var string[] Absolute paths to vendor directories */ private static $vendors; @@ -61,6 +62,10 @@ class Deprecation */ public function __construct($message, array $trace, $file, $languageDeprecation = false) { + if (isset($trace[2]['class']) && \in_array($trace[2]['class'], [DebugClassLoader::class, LegacyDebugClassLoader::class], true)) { + $this->triggeringClass = $trace[2]['args'][0]; + } + if (isset($trace[2]['function']) && 'trigger_deprecation' === $trace[2]['function']) { $file = $trace[2]['file']; array_splice($trace, 1, 1); @@ -158,6 +163,26 @@ private function lineShouldBeSkipped(array $line) return 'ReflectionMethod' === $class || 0 === strpos($class, 'PHPUnit\\'); } + /** + * @return bool + */ + public function originatesFromDebugClassLoader() + { + return isset($this->triggeringClass); + } + + /** + * @return string + */ + public function triggeringClass() + { + if (null === $this->triggeringClass) { + throw new \LogicException('Check with originatesFromDebugClassLoader() before calling this method.'); + } + + return $this->triggeringClass; + } + /** * @return bool */ diff --git a/Tests/DeprecationErrorHandler/ConfigurationTest.php b/Tests/DeprecationErrorHandler/ConfigurationTest.php index 9170605..6116fbe 100644 --- a/Tests/DeprecationErrorHandler/ConfigurationTest.php +++ b/Tests/DeprecationErrorHandler/ConfigurationTest.php @@ -15,6 +15,7 @@ use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup; +use Symfony\Component\ErrorHandler\DebugClassLoader; class ConfigurationTest extends TestCase { @@ -356,7 +357,7 @@ public function testBaselineGenerationEmptyFile() $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); $configuration->writeBaseline(); $this->assertEquals($filename, $configuration->getBaselineFile()); - $expected_baseline = [ + $expected = [ [ 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', 'message' => 'Test message 1', @@ -368,7 +369,7 @@ public function testBaselineGenerationEmptyFile() 'count' => 1, ], ]; - $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); } public function testBaselineGenerationNoFile() @@ -383,7 +384,7 @@ public function testBaselineGenerationNoFile() $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); $configuration->writeBaseline(); $this->assertEquals($filename, $configuration->getBaselineFile()); - $expected_baseline = [ + $expected = [ [ 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', 'message' => 'Test message 1', @@ -395,7 +396,7 @@ public function testBaselineGenerationNoFile() 'count' => 2, ], ]; - $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); } public function testExistingBaseline() @@ -447,7 +448,7 @@ public function testExistingBaselineAndGeneration() $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 3', $trace, ''))); $configuration->writeBaseline(); $this->assertEquals($filename, $configuration->getBaselineFile()); - $expected_baseline = [ + $expected = [ [ 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', 'message' => 'Test message 2', @@ -459,7 +460,44 @@ public function testExistingBaselineAndGeneration() 'count' => 1, ], ]; - $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + } + + public function testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader() + { + $filename = $this->createFile(); + $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename)); + + $trace = debug_backtrace(); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Regular deprecation', $trace, ''))); + + $trace[2] = [ + 'class' => DebugClassLoader::class, + 'function' => 'testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader', + 'args' => [self::class] + ]; + + $deprecation = new Deprecation('Deprecation by debug class loader', $trace, ''); + + $this->assertTrue($deprecation->originatesFromDebugClassLoader()); + + $this->assertTrue($configuration->isBaselineDeprecation($deprecation)); + + $configuration->writeBaseline(); + $this->assertEquals($filename, $configuration->getBaselineFile()); + $expected = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Regular deprecation', + 'count' => 1, + ], + [ + 'location' => self::class, + 'message' => 'Deprecation by debug class loader', + 'count' => 1, + ], + ]; + $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); } public function testBaselineArgumentException()