mirror of
https://github.com/maximebf/php-debugbar.git
synced 2025-07-28 04:00:43 +02:00
The Symfony VarDumper component includes an HtmlDumper that dumps variables in a rich HTML format that allows for expanding and collapsing individual tree nodes in the dumped variable. This makes it much more practical to navigate large/deep variables that have been dumped. DebugBarVarDumper provides a Debug Bar-friendly wrapper around the VarDumper component. It’s intended as a better alternative to DataFormatter::formatVar. It provides for: * Debug Bar-friendly styles for the VarDumper HTML. * Implements AssetProvider for returning VarDumper static assets (requires users of JavascriptRenderer to support inline assets). * Simplifies VarCloner and HtmlDumper function calls for cloning and dumping variables in a Debug Bar environment. VarDumper was originally written/targeted to be a replacement for var_dump, so the default behavior of HtmlDumper echoing static assets and variable dumps directly to the page output isn’t really appropriate. Furthermore, we must contend with several different Symfony versions going back to v2.6.0. This class provides a friendly wrapper. I have tested this with these Symfony versions: * v2.6.0 * v2.7.0 * v2.8.0 * v3.0.0 * v3.1.0 * v3.2.0 * v3.3.0 All seem to work fine, with graceful degradation as needed. Furthermore, the class is ready to take advantage of new features that I added and are upcoming in Symfony v3.4: * setMinDepth: https://github.com/symfony/symfony/pull/23515 This feature will be valuable for the upcoming BacktraceCollector.
254 lines
8.9 KiB
PHP
254 lines
8.9 KiB
PHP
<?php
|
|
|
|
namespace DebugBar\Tests\DataFormatter;
|
|
|
|
use DebugBar\DataFormatter\DebugBarVarDumper;
|
|
use DebugBar\Tests\DebugBarTestCase;
|
|
|
|
class DebugBarVarDumperTest extends DebugBarTestCase
|
|
{
|
|
const STYLE_STRING = 'SpecialStyleString';
|
|
|
|
private $testStyles = array(
|
|
'default' => self::STYLE_STRING,
|
|
);
|
|
|
|
public function testBasicFunctionality()
|
|
{
|
|
// Test that we can render a simple variable without dump headers
|
|
$d = new DebugBarVarDumper();
|
|
$d->mergeDumperOptions(array('styles' => $this->testStyles));
|
|
$out = $d->renderVar('magic');
|
|
|
|
$this->assertContains('magic', $out);
|
|
$this->assertNotContains(self::STYLE_STRING, $out); // make sure there's no dump header
|
|
|
|
// Test that we can capture a variable without rendering into a Data-type variable
|
|
$data = $d->captureVar('hello');
|
|
$this->assertContains('hello', $data);
|
|
$deserialized = unserialize($data);
|
|
$this->assertInstanceOf('Symfony\Component\VarDumper\Cloner\Data', $deserialized);
|
|
|
|
// Test that we can render the captured variable at a later time
|
|
$out = $d->renderCapturedVar($data);
|
|
$this->assertContains('hello', $out);
|
|
$this->assertNotContains(self::STYLE_STRING, $out); // make sure there's no dump header
|
|
}
|
|
|
|
public function testSeeking()
|
|
{
|
|
$testData = array(
|
|
'one',
|
|
array('two'),
|
|
'three',
|
|
);
|
|
$d = new DebugBarVarDumper();
|
|
$data = $d->captureVar($testData);
|
|
|
|
// seek depth of 1
|
|
$out = $d->renderCapturedVar($data, array(1));
|
|
$this->assertNotContains('one', $out);
|
|
$this->assertContains('array', $out);
|
|
$this->assertContains('two', $out);
|
|
$this->assertNotContains('three', $out);
|
|
|
|
// seek depth of 2
|
|
$out = $d->renderCapturedVar($data, array(1, 0));
|
|
$this->assertNotContains('one', $out);
|
|
$this->assertNotContains('array', $out);
|
|
$this->assertContains('two', $out);
|
|
$this->assertNotContains('three', $out);
|
|
}
|
|
|
|
public function testAssetProvider()
|
|
{
|
|
$d = new DebugBarVarDumper();
|
|
$d->mergeDumperOptions(array('styles' => $this->testStyles));
|
|
$assets = $d->getAssets();
|
|
$this->assertArrayHasKey('inline_head', $assets);
|
|
$this->assertCount(1, $assets);
|
|
|
|
$inlineHead = $assets['inline_head'];
|
|
$this->assertArrayHasKey('html_var_dumper', $inlineHead);
|
|
$this->assertCount(1, $inlineHead);
|
|
|
|
$assetText = $inlineHead['html_var_dumper'];
|
|
$this->assertContains(self::STYLE_STRING, $assetText);
|
|
}
|
|
|
|
public function testBasicOptionOperations()
|
|
{
|
|
// Test basic get/merge/reset functionality for cloner
|
|
$d = new DebugBarVarDumper();
|
|
$options = $d->getClonerOptions();
|
|
$this->assertEmpty($options);
|
|
|
|
$d->mergeClonerOptions(array(
|
|
'max_items' => 5,
|
|
));
|
|
$d->mergeClonerOptions(array(
|
|
'max_string' => 4,
|
|
));
|
|
$d->mergeClonerOptions(array(
|
|
'max_items' => 3,
|
|
));
|
|
$options = $d->getClonerOptions();
|
|
$this->assertEquals(array(
|
|
'max_items' => 3,
|
|
'max_string' => 4,
|
|
), $options);
|
|
|
|
$d->resetClonerOptions(array(
|
|
'min_depth' => 2,
|
|
));
|
|
$options = $d->getClonerOptions();
|
|
$this->assertEquals(array(
|
|
'min_depth' => 2,
|
|
), $options);
|
|
|
|
// Test basic get/merge/reset functionality for dumper
|
|
$options = $d->getDumperOptions();
|
|
$this->assertContains('styles', $options);
|
|
$this->assertArrayHasKey('const', $options['styles']);
|
|
$this->assertContains('expanded_depth', $options);
|
|
$this->assertEquals(0, $options['expanded_depth']);
|
|
$this->assertCount(2, $options);
|
|
|
|
$d->mergeDumperOptions(array(
|
|
'styles' => $this->testStyles,
|
|
));
|
|
$d->mergeDumperOptions(array(
|
|
'max_string' => 7,
|
|
));
|
|
$options = $d->getDumperOptions();
|
|
$this->assertEquals(array(
|
|
'max_string' => 7,
|
|
'styles' => $this->testStyles,
|
|
'expanded_depth' => 0,
|
|
), $options);
|
|
|
|
$d->resetDumperOptions(array(
|
|
'styles' => $this->testStyles,
|
|
));
|
|
$options = $d->getDumperOptions();
|
|
$this->assertEquals(array(
|
|
'styles' => $this->testStyles,
|
|
'expanded_depth' => 0,
|
|
), $options);
|
|
}
|
|
|
|
public function testClonerOptions()
|
|
{
|
|
// Test the actual operation of the cloner options
|
|
$d = new DebugBarVarDumper();
|
|
|
|
// Test that the 'casters' option can remove default casters
|
|
$testData = function() {};
|
|
$d->resetClonerOptions();
|
|
$this->assertContains('DebugBarVarDumperTest.php', $d->renderVar($testData));
|
|
|
|
$d->resetClonerOptions(array(
|
|
'casters' => array(),
|
|
));
|
|
$this->assertNotContains('DebugBarVarDumperTest.php', $d->renderVar($testData));
|
|
|
|
// Test that the 'additional_casters' option can add new casters
|
|
$testData = function() {};
|
|
$d->resetClonerOptions();
|
|
$this->assertContains('DebugBarVarDumperTest.php', $d->renderVar($testData));
|
|
|
|
$d->resetClonerOptions(array(
|
|
'casters' => array(),
|
|
'additional_casters' => array('Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure'),
|
|
));
|
|
$this->assertContains('DebugBarVarDumperTest.php', $d->renderVar($testData));
|
|
|
|
// Test 'max_items'
|
|
$testData = array(array('one', 'two', 'three', 'four', 'five'));
|
|
$d->resetClonerOptions();
|
|
$out = $d->renderVar($testData);
|
|
foreach ($testData[0] as $search) {
|
|
$this->assertContains($search, $out);
|
|
}
|
|
|
|
$d->resetClonerOptions(array(
|
|
'max_items' => 3,
|
|
));
|
|
$out = $d->renderVar($testData);
|
|
$this->assertContains('one', $out);
|
|
$this->assertContains('two', $out);
|
|
$this->assertContains('three', $out);
|
|
$this->assertNotContains('four', $out);
|
|
$this->assertNotContains('five', $out);
|
|
|
|
// Test 'max_string'
|
|
$testData = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
$d->resetClonerOptions();
|
|
$this->assertContains($testData, $d->renderVar($testData));
|
|
|
|
$d->resetClonerOptions(array(
|
|
'max_string' => 10,
|
|
));
|
|
$out = $d->renderVar($testData);
|
|
$this->assertContains('ABCDEFGHIJ', $out);
|
|
$this->assertNotContains('ABCDEFGHIJK', $out);
|
|
|
|
// Test 'min_depth' if we are on a Symfony version that supports it
|
|
if (method_exists('Symfony\Component\VarDumper\Cloner\AbstractCloner', 'setMinDepth')) {
|
|
$testData = array('one', 'two', 'three', 'four', 'five');
|
|
$d->resetClonerOptions(array(
|
|
'max_items' => 3,
|
|
));
|
|
$out = $d->renderVar($testData);
|
|
foreach ($testData as $search) {
|
|
$this->assertContains($search, $out);
|
|
}
|
|
|
|
$d->resetClonerOptions(array(
|
|
'min_depth' => 0,
|
|
'max_items' => 3,
|
|
));
|
|
$out = $d->renderVar($testData);
|
|
$this->assertContains('one', $out);
|
|
$this->assertContains('two', $out);
|
|
$this->assertContains('three', $out);
|
|
$this->assertNotContains('four', $out);
|
|
$this->assertNotContains('five', $out);
|
|
}
|
|
}
|
|
|
|
public function testDumperOptions()
|
|
{
|
|
// Test the actual operation of the dumper options
|
|
$d = new DebugBarVarDumper();
|
|
|
|
// Test that the 'styles' option affects assets
|
|
$d->resetDumperOptions();
|
|
$assets = $d->getAssets();
|
|
$this->assertNotContains(self::STYLE_STRING, $assets['inline_head']['html_var_dumper']);
|
|
|
|
$d->resetDumperOptions(array('styles' => $this->testStyles));
|
|
$assets = $d->getAssets();
|
|
$this->assertContains(self::STYLE_STRING, $assets['inline_head']['html_var_dumper']);
|
|
|
|
// The next tests require changes in Symfony 3.2:
|
|
$dumpMethod = new \ReflectionMethod('Symfony\Component\VarDumper\Dumper\HtmlDumper', 'dump');
|
|
if ($dumpMethod->getNumberOfParameters() >= 3) {
|
|
// Test that the 'expanded_depth' option affects output
|
|
$d->resetDumperOptions(array('expanded_depth' => 123321));
|
|
$out = $d->renderVar(true);
|
|
$this->assertContains('123321', $out);
|
|
|
|
// Test that the 'max_string' option affects output
|
|
$d->resetDumperOptions(array('max_string' => 321123));
|
|
$out = $d->renderVar(true);
|
|
$this->assertContains('321123', $out);
|
|
|
|
// Test that the 'file_link_format' option affects output
|
|
$d->resetDumperOptions(array('file_link_format' => 'fmt%ftest'));
|
|
$out = $d->renderVar(function() {});
|
|
$this->assertContains('DebugBarVarDumperTest.phptest', $out);
|
|
}
|
|
}
|
|
}
|