class DebugDump
Drupal's extension for printing dump() output results.
@internal
Hierarchy
- class \Drupal\TestTools\Extension\Dump\DebugDump implements \PHPUnit\Runner\Extension\Extension
Expanded class hierarchy of DebugDump
6 files declare their use of DebugDump
- BrowserTestBase.php in core/
tests/ Drupal/ Tests/ BrowserTestBase.php - BrowserTestBaseTest.php in core/
tests/ Drupal/ FunctionalTests/ BrowserTestBaseTest.php - KernelTestBase.php in core/
tests/ Drupal/ KernelTests/ KernelTestBase.php - KernelTestBaseTest.php in core/
tests/ Drupal/ KernelTests/ KernelTestBaseTest.php - UnitTestCase.php in core/
tests/ Drupal/ Tests/ UnitTestCase.php
File
-
core/
tests/ Drupal/ TestTools/ Extension/ Dump/ DebugDump.php, line 21
Namespace
Drupal\TestTools\Extension\DumpView source
final class DebugDump implements Extension {
/**
* The path to the dump staging file.
*/
private static string $stagingFilePath;
/**
* Whether colors should be used for printing.
*/
private static bool $colors = FALSE;
/**
* Whether the caller of dump should be included in the report.
*/
private static bool $printCaller = FALSE;
/**
* {@inheritdoc}
*/
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters) : void {
// Determine staging file path.
self::$stagingFilePath = tempnam(sys_get_temp_dir(), 'dpd');
// Determine color output.
$colors = $parameters->has('colors') ? $parameters->get('colors') : FALSE;
self::$colors = filter_var($colors, \FILTER_VALIDATE_BOOLEAN);
// Print caller.
$printCaller = $parameters->has('printCaller') ? $parameters->get('printCaller') : FALSE;
self::$printCaller = filter_var($printCaller, \FILTER_VALIDATE_BOOLEAN);
// Set the environment variable with the configuration.
$config = json_encode([
'stagingFilePath' => self::$stagingFilePath,
'colors' => self::$colors,
'printCaller' => self::$printCaller,
]);
putenv('DRUPAL_PHPUNIT_DUMPER_CONFIG=' . $config);
$facade->registerSubscriber(new TestRunnerFinishedSubscriber($this));
}
/**
* Determines if the extension is enabled.
*
* @return bool
* TRUE if enabled, FALSE if disabled.
*/
public static function isEnabled() : bool {
return getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG') !== FALSE;
}
/**
* A CLI handler for \Symfony\Component\VarDumper\VarDumper.
*
* @param mixed $var
* The variable to be dumped.
*/
public static function cliHandler(mixed $var) : void {
if (!self::isEnabled()) {
return;
}
$config = (array) json_decode(getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG'));
$caller = self::getCaller();
$cloner = new VarCloner();
$dumper = new CliDumper();
$dumper->setColors($config['colors']);
$dump = [];
$dumper->dump($cloner->cloneVar($var), function ($line, $depth, $indent_pad) use (&$dump) {
// A negative depth means "end of dump".
if ($depth >= 0) {
// Adds a two spaces indentation to the line.
$dump[] = str_repeat($indent_pad, $depth) . $line;
}
});
file_put_contents($config['stagingFilePath'], self::encodeDump($caller['test']->id(), $caller['file'], $caller['line'], $dump) . "\n", FILE_APPEND);
}
/**
* Encodes the dump for storing.
*
* @param string $testId
* The id of the test from where the dump was called.
* @param string|null $file
* The path of the file from where the dump was called.
* @param int|null $line
* The line number from where the dump was called.
* @param array $dump
* The dump as an array of lines.
*
* @return string
* An encoded string.
*/
private static function encodeDump(string $testId, ?string $file, ?int $line, array $dump) : string {
$data = [
'test' => $testId,
'file' => $file,
'line' => $line,
'dump' => $dump,
];
$jsonData = json_encode($data);
return base64_encode($jsonData);
}
/**
* Decodes a dump retrieved from storage.
*
* @param string $encodedData
* An encoded string.
*
* @return array{test: string, file: string|null, line: int|null, dump: string[]}
* An encoded string.
*/
private static function decodeDump(string $encodedData) : array {
$jsonData = base64_decode($encodedData);
return (array) json_decode($jsonData);
}
/**
* Returns information about the caller of dump().
*
* @return array{test: \PHPUnit\Framework\Event\Code\TestMethod, file: string|null, line: int|null}
* Caller information.
*/
private static function getCaller() : array {
$backtrace = debug_backtrace();
while (!isset($backtrace[0]['function']) || $backtrace[0]['function'] !== 'dump') {
array_shift($backtrace);
}
$call['file'] = $backtrace[1]['file'] ?? NULL;
$call['line'] = $backtrace[1]['line'] ?? NULL;
while (!isset($backtrace[0]['object']) || !$backtrace[0]['object'] instanceof TestCase) {
array_shift($backtrace);
}
$call['test'] = $backtrace[0]['object']->valueObjectForEvents();
return $call;
}
/**
* Retrieves dumps from storage.
*
* @return array{string, array{file: string|null, line: int|null, dump: string[]}}
* Caller information.
*/
public static function getDumps() : array {
if (!self::isEnabled()) {
return [];
}
$config = (array) json_decode(getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG'));
$contents = rtrim(file_get_contents($config['stagingFilePath']));
if (empty($contents)) {
return [];
}
$encodedDumps = explode("\n", $contents);
$dumps = [];
foreach ($encodedDumps as $encodedDump) {
$dump = self::decodeDump($encodedDump);
$test = $dump['test'];
unset($dump['test']);
$dumps[$test][] = $dump;
}
return $dumps;
}
/**
* Prints the dumps generated during the test.
*/
public function testRunnerFinished(TestRunnerFinished $event) : void {
$dumps = self::getDumps();
// Cleanup.
unlink(self::$stagingFilePath);
putenv('DRUPAL_PHPUNIT_DUMPER_CONFIG');
if ($dumps === []) {
return;
}
print "\n\n";
print "dump() output\n";
print "-------------\n\n";
foreach ($dumps as $testId => $testDumps) {
if (self::$printCaller) {
print $testId . "\n";
}
foreach ($testDumps as $dump) {
if (self::$printCaller) {
print "in " . $dump['file'] . ", line " . $dump['line'] . ":\n";
}
foreach ($dump['dump'] as $line) {
print $line . "\n";
}
if (self::$printCaller) {
print "\n";
}
}
if (self::$printCaller) {
print "\n";
}
}
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
DebugDump::$colors | private static | property | Whether colors should be used for printing. |
DebugDump::$printCaller | private static | property | Whether the caller of dump should be included in the report. |
DebugDump::$stagingFilePath | private static | property | The path to the dump staging file. |
DebugDump::bootstrap | public | function | |
DebugDump::cliHandler | public static | function | A CLI handler for \Symfony\Component\VarDumper\VarDumper. |
DebugDump::decodeDump | private static | function | Decodes a dump retrieved from storage. |
DebugDump::encodeDump | private static | function | Encodes the dump for storing. |
DebugDump::getCaller | private static | function | Returns information about the caller of dump(). |
DebugDump::getDumps | public static | function | Retrieves dumps from storage. |
DebugDump::isEnabled | public static | function | Determines if the extension is enabled. |
DebugDump::testRunnerFinished | public | function | Prints the dumps generated during the test. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.