Skip to content

Commit 6bc77b7

Browse files
l-vogreg0ire
authored andcommitted
[PhpUnitBridge] Use serialized trace when using serialized deprecation
1 parent 179b76e commit 6bc77b7

File tree

3 files changed

+138
-18
lines changed

3 files changed

+138
-18
lines changed

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,19 @@ public static function collectDeprecations($outputFile)
106106
return \call_user_func(self::getPhpUnitErrorHandler(), $type, $msg, $file, $line, $context);
107107
}
108108

109-
$deprecations[] = [error_reporting(), $msg, $file];
109+
$trace = debug_backtrace();
110+
$filesStack = [];
111+
foreach ($trace as $line) {
112+
if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) {
113+
continue;
114+
}
115+
116+
if (isset($line['file'])) {
117+
$filesStack[] = $line['file'];
118+
}
119+
}
120+
121+
$deprecations[] = [error_reporting(), $msg, $file, $filesStack];
110122

111123
return null;
112124
});

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class Deprecation
4343
*/
4444
private static $internalPaths = [];
4545

46+
private $originalFilesStack;
47+
4648
/**
4749
* @param string $message
4850
* @param string $file
@@ -63,6 +65,7 @@ public function __construct($message, array $trace, $file)
6365
$this->message = $parsedMsg['deprecation'];
6466
$this->originClass = $parsedMsg['class'];
6567
$this->originMethod = $parsedMsg['method'];
68+
$this->originalFilesStack = $parsedMsg['files_stack'];
6669
// If the deprecation has been triggered via
6770
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
6871
// then we need to use the serialized information to determine
@@ -164,6 +167,24 @@ public function isMuted()
164167
return false !== strpos($this->triggeringFile, \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR.'phpunit'.\DIRECTORY_SEPARATOR);
165168
}
166169

170+
private function getOriginalFilesStack(): array
171+
{
172+
if (null === $this->originalFilesStack) {
173+
$this->originalFilesStack = [];
174+
foreach ($this->trace as $line) {
175+
if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) {
176+
continue;
177+
}
178+
if (!isset($line['file'])) {
179+
continue;
180+
}
181+
$this->originalFilesStack[] = $line['file'];
182+
}
183+
}
184+
185+
return $this->originalFilesStack;
186+
}
187+
167188
/**
168189
* Tells whether both the calling package and the called package are vendor
169190
* packages.
@@ -180,14 +201,8 @@ public function getType()
180201
return self::TYPE_UNDETERMINED;
181202
}
182203
$erroringFile = $erroringPackage = null;
183-
foreach ($this->trace as $line) {
184-
if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) {
185-
continue;
186-
}
187-
if (!isset($line['file'])) {
188-
continue;
189-
}
190-
$file = $line['file'];
204+
205+
foreach ($this->getOriginalFilesStack() as $file) {
191206
if ('-' === $file || 'Standard input code' === $file || !realpath($file)) {
192207
continue;
193208
}

src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,32 @@
1111

1212
namespace Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler;
1313

14+
use Composer\Autoload\ClassLoader;
1415
use PHPUnit\Framework\TestCase;
1516
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler;
1617
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation;
1718
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV5;
1819

1920
class DeprecationTest extends TestCase
2021
{
22+
public static function setUpBeforeClass(): void
23+
{
24+
$vendorDir = self::getVendorDir();
25+
26+
mkdir($vendorDir.'/myfakevendor/myfakepackage1', 0777, true);
27+
mkdir($vendorDir.'/myfakevendor/myfakepackage2');
28+
touch($vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile1.php');
29+
touch($vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile2.php');
30+
touch($vendorDir.'/myfakevendor/myfakepackage2/MyFakeFile.php');
31+
}
32+
33+
private static function getVendorDir(): string
34+
{
35+
$reflection = new \ReflectionClass(ClassLoader::class);
36+
37+
return \dirname($reflection->getFileName(), 2);
38+
}
39+
2140
public function testItCanDetermineTheClassWhereTheDeprecationHappened()
2241
{
2342
$deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__);
@@ -119,19 +138,19 @@ public function testItTakesMutesDeprecationFromPhpUnitFiles()
119138
$this->assertTrue($deprecation->isMuted());
120139
}
121140

122-
public function providerIsSelf(): array
141+
public function providerGetTypeDetectsSelf(): array
123142
{
124143
return [
125-
'not_from_vendors_file' => [true, '', 'MyClass1', ''],
126-
'nonexistent_file' => [false, '', 'MyClass1', 'dummy_vendor_path'],
144+
'not_from_vendors_file' => [Deprecation::TYPE_SELF, '', 'MyClass1', ''],
145+
'nonexistent_file' => [Deprecation::TYPE_UNDETERMINED, '', 'MyClass1', 'dummy_vendor_path'],
127146
'serialized_trace_without_triggering_file' => [
128-
true,
147+
Deprecation::TYPE_SELF,
129148
serialize(['class' => '', 'method' => '', 'deprecation' => '', 'files_stack' => []]),
130149
SymfonyTestsListenerForV5::class,
131150
'',
132151
],
133152
'serialized_trace_with_not_from_vendors_triggering_file' => [
134-
true,
153+
Deprecation::TYPE_SELF,
135154
serialize([
136155
'class' => '',
137156
'method' => '',
@@ -143,7 +162,7 @@ public function providerIsSelf(): array
143162
'',
144163
],
145164
'serialized_trace_with_nonexistent_triggering_file' => [
146-
false,
165+
Deprecation::TYPE_UNDETERMINED,
147166
serialize([
148167
'class' => '',
149168
'method' => '',
@@ -158,16 +177,72 @@ public function providerIsSelf(): array
158177
}
159178

160179
/**
161-
* @dataProvider providerIsSelf
180+
* @dataProvider providerGetTypeDetectsSelf
162181
*/
163-
public function testIsSelf(bool $expectedIsSelf, string $message, string $traceClass, string $file): void
182+
public function testGetTypeDetectsSelf(string $expectedType, string $message, string $traceClass, string $file): void
164183
{
165184
$trace = [
166185
['class' => 'MyClass1', 'function' => 'myMethod'],
167186
['class' => $traceClass, 'function' => 'myMethod'],
168187
];
169188
$deprecation = new Deprecation($message, $trace, $file);
170-
$this->assertEquals($expectedIsSelf, $deprecation->getType() === Deprecation::TYPE_SELF);
189+
$this->assertEquals($expectedType, $deprecation->getType());
190+
}
191+
192+
public function providerGetTypeUsesRightTrace(): array
193+
{
194+
$vendorDir = self::getVendorDir();
195+
196+
return [
197+
'no_file_in_stack' => [Deprecation::TYPE_DIRECT, '', [['function' => 'myfunc1'], ['function' => 'myfunc2']]],
198+
'files_in_stack_from_various_packages' => [
199+
Deprecation::TYPE_INDIRECT,
200+
'',
201+
[
202+
['function' => 'myfunc1', 'file' => $vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile1.php'],
203+
['function' => 'myfunc2', 'file' => $vendorDir.'/myfakevendor/myfakepackage2/MyFakeFile.php'],
204+
],
205+
],
206+
'serialized_stack_files_from_same_package' => [
207+
Deprecation::TYPE_DIRECT,
208+
serialize([
209+
'deprecation' => 'My deprecation message',
210+
'class' => 'MyClass',
211+
'method' => 'myMethod',
212+
'files_stack' => [
213+
$vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile1.php',
214+
$vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile2.php',
215+
],
216+
]),
217+
[['function' => 'myfunc1'], ['class' => SymfonyTestsListenerForV5::class, 'method' => 'mymethod']],
218+
],
219+
'serialized_stack_files_from_various_packages' => [
220+
Deprecation::TYPE_INDIRECT,
221+
serialize([
222+
'deprecation' => 'My deprecation message',
223+
'class' => 'MyClass',
224+
'method' => 'myMethod',
225+
'files_stack' => [
226+
$vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile1.php',
227+
$vendorDir.'/myfakevendor/myfakepackage2/MyFakeFile.php',
228+
],
229+
]),
230+
[['function' => 'myfunc1'], ['class' => SymfonyTestsListenerForV5::class, 'method' => 'mymethod']],
231+
],
232+
];
233+
}
234+
235+
/**
236+
* @dataProvider providerGetTypeUsesRightTrace
237+
*/
238+
public function testGetTypeUsesRightTrace(string $expectedType, string $message, array $trace): void
239+
{
240+
$deprecation = new Deprecation(
241+
$message,
242+
$trace,
243+
self::getVendorDir().'/myfakevendor/myfakepackage2/MyFakeFile.php'
244+
);
245+
$this->assertEquals($expectedType, $deprecation->getType());
171246
}
172247

173248
/**
@@ -178,4 +253,22 @@ public function debugBacktrace(): array
178253
{
179254
return debug_backtrace();
180255
}
256+
257+
private static function removeDir($dir): void
258+
{
259+
$files = glob($dir.'/*');
260+
foreach ($files as $file) {
261+
if (is_file($file)) {
262+
unlink($file);
263+
} else {
264+
self::removeDir($file);
265+
}
266+
}
267+
rmdir($dir);
268+
}
269+
270+
public static function tearDownAfterClass(): void
271+
{
272+
self::removeDir(self::getVendorDir().'/myfakevendor');
273+
}
181274
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy