Skip to content

Commit

Permalink
Rewrote EventContextProviderTest to avoid using call_user_func()
Browse files Browse the repository at this point in the history
`call_user_func()` is automatically optimized away by PHP-SRC starting from
early PHP 7 releases, and therefore cannot be used to generate artificial
stack frames that are detected in PHP-SRC itself.

With this change, we use `array_map()` instead, which (for now) is not optimized
away (yet).
  • Loading branch information
Ocramius committed Dec 15, 2022
1 parent 3e22230 commit bfefcbc
Showing 1 changed file with 32 additions and 27 deletions.
59 changes: 32 additions & 27 deletions test/EventLogging/EventContextProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,43 @@
use Laminas\DeveloperTools\EventLogging\EventContextProvider;
use PHPUnit\Framework\TestCase;

use function array_map;

/** @covers \Laminas\DeveloperTools\EventLogging\EventContextProvider */
class EventContextProviderTest extends TestCase
{
public function testEventTriggerFileForInvokables()
public function testEventTriggerFileDetectsEmptyFileLocationWhenStackFrameIsInPhpItself(): void
{
$eventProviderClass = new class {
public function __invoke() {
return call_user_func([$this, 'get']);
}

private function get()
{
$eventProviderClass = new class {
public function __invoke($invokableClass, int $maxLevel, int $level = 0)
{
if ($level < $maxLevel) {
return $invokableClass($invokableClass, $maxLevel, ++$level);
}

return (new EventContextProvider())->getEventTriggerFile();
}
};

return $eventProviderClass($eventProviderClass, 3);
}
};

$eventTriggerFile = $eventProviderClass();

self::assertSame(
'',
$eventTriggerFile,
[
'stack frame on this file: EventLogging/EventContextProviderTest.php',
'stack frame in php core: ',
'stack frame on this file: EventLogging/EventContextProviderTest.php',
],
// Important: `array_map()` needed here, as it produces a stack frame without "file" location
array_map(
[$this, 'callEventContextProviderWithStackTraceNestingLevelAndName'],
[
'stack frame on this file',
'stack frame in php core',
'stack frame on this file',
],
[
3,
4,
5,
]
),
'trigger file should be empty because user function calls do not refer to a file'
);
}

private function callEventContextProviderWithStackTraceNestingLevelAndName(string $name, int $level): string
{
if ($level > 0) {
return $this->callEventContextProviderWithStackTraceNestingLevelAndName($name, $level - 1);
}

return $name . ': ' . (new EventContextProvider())->getEventTriggerFile();
}
}

0 comments on commit bfefcbc

Please sign in to comment.