feature #28898 [Console] Add dumper (ro0NL)
This PR was squashed before being merged into the 4.3-dev branch (closes #28898).
Discussion
----------
[Console] Add dumper
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | no
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/issues/10502
This PR adds a new `Dumper` helper in the Console component. As there are 2 types of dumps
- debug purpose (e.g. `dd()`, `dump()`)
- output purpose (see #24208, #27684)
For the latter we cannot use the global system (debug) dumper, i.e. `VarDumper::dump()`, we need something tied to the current output and dependency free. Here it is:
```php
$io = new SymfonyStyle($input, $output);
$dumper = new Dumper($io);
$io->writeln($dumper([-0.5, 0, 1]));
$io->writeln($dumper(new \stdClass()));
$io->writeln($dumper(123));
$io->writeln($dumper('foo'));
$io->writeln($dumper(null));
$io->writeln($dumper(true));
```
With VarDumper comonent:
![image](https://user-images.githubusercontent.com/1047696/47069483-4cc26f80-d1ef-11e8-902e-2f9b0f040f25.png)
Without:
![image](https://user-images.githubusercontent.com/1047696/47069517-6663b700-d1ef-11e8-9328-ae1db0b83d7e.png)
> https://github.com/symfony/symfony/pull/27684#discussion_r224054237 var-dumper is not a mandatory dep of fwb, can we do without?
Now we can :)
Commits
-------
fc7465c02c
[Console] Add dumper
This commit is contained in:
commit
c52af28b0e
64
src/Symfony/Component/Console/Helper/Dumper.php
Normal file
64
src/Symfony/Component/Console/Helper/Dumper.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Helper;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
/**
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*/
|
||||
final class Dumper
|
||||
{
|
||||
private $output;
|
||||
private $dumper;
|
||||
private $cloner;
|
||||
private $handler;
|
||||
|
||||
public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
|
||||
{
|
||||
$this->output = $output;
|
||||
$this->dumper = $dumper;
|
||||
$this->cloner = $cloner;
|
||||
|
||||
if (class_exists(CliDumper::class)) {
|
||||
$this->handler = function ($var): string {
|
||||
$dumper = $this->dumper ?? $this->dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
|
||||
$dumper->setColors($this->output->isDecorated());
|
||||
|
||||
return rtrim($dumper->dump(($this->cloner ?? $this->cloner = new VarCloner())->cloneVar($var)->withRefHandles(false), true));
|
||||
};
|
||||
} else {
|
||||
$this->handler = function ($var): string {
|
||||
switch (true) {
|
||||
case null === $var:
|
||||
return 'null';
|
||||
case true === $var:
|
||||
return 'true';
|
||||
case false === $var:
|
||||
return 'false';
|
||||
case \is_string($var):
|
||||
return '"'.$var.'"';
|
||||
default:
|
||||
return rtrim(print_r($var, true));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function __invoke($var): string
|
||||
{
|
||||
return ($this->handler)($var);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Helper;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\PhpUnit\ClassExistsMock;
|
||||
use Symfony\Component\Console\Helper\Dumper;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
class DumperNativeFallbackTest extends TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
ClassExistsMock::register(Dumper::class);
|
||||
ClassExistsMock::withMockedClasses([
|
||||
CliDumper::class => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
ClassExistsMock::withMockedClasses([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideVariables
|
||||
*/
|
||||
public function testInvoke($variable, $primitiveString)
|
||||
{
|
||||
$dumper = new Dumper($this->getMockBuilder(OutputInterface::class)->getMock());
|
||||
|
||||
$this->assertSame($primitiveString, $dumper($variable));
|
||||
}
|
||||
|
||||
public function provideVariables()
|
||||
{
|
||||
return [
|
||||
[null, 'null'],
|
||||
[true, 'true'],
|
||||
[false, 'false'],
|
||||
[1, '1'],
|
||||
[-1.5, '-1.5'],
|
||||
['string', '"string"'],
|
||||
[[1, '2'], "Array\n(\n [0] => 1\n [1] => 2\n)"],
|
||||
[new \stdClass(), "stdClass Object\n(\n)"],
|
||||
];
|
||||
}
|
||||
}
|
58
src/Symfony/Component/Console/Tests/Helper/DumperTest.php
Normal file
58
src/Symfony/Component/Console/Tests/Helper/DumperTest.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Helper;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Helper\Dumper;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
|
||||
|
||||
class DumperTest extends TestCase
|
||||
{
|
||||
use VarDumperTestTrait;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
putenv('DUMP_LIGHT_ARRAY=1');
|
||||
putenv('DUMP_COMMA_SEPARATOR=1');
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
putenv('DUMP_LIGHT_ARRAY');
|
||||
putenv('DUMP_COMMA_SEPARATOR');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideVariables
|
||||
*/
|
||||
public function testInvoke($variable)
|
||||
{
|
||||
$dumper = new Dumper($this->getMockBuilder(OutputInterface::class)->getMock());
|
||||
|
||||
$this->assertDumpMatchesFormat($dumper($variable), $variable);
|
||||
}
|
||||
|
||||
public function provideVariables()
|
||||
{
|
||||
return [
|
||||
[null],
|
||||
[true],
|
||||
[false],
|
||||
[1],
|
||||
[-1.5],
|
||||
['string'],
|
||||
[[1, '2']],
|
||||
[new \stdClass()],
|
||||
];
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
"symfony/dependency-injection": "~3.4|~4.0",
|
||||
"symfony/lock": "~3.4|~4.0",
|
||||
"symfony/process": "~3.4|~4.0",
|
||||
"symfony/var-dumper": "^4.3",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"provide": {
|
||||
|
@ -33,6 +33,7 @@ trait VarDumperTestTrait
|
||||
{
|
||||
$flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0;
|
||||
$flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0;
|
||||
$flags |= getenv('DUMP_COMMA_SEPARATOR') ? CliDumper::DUMP_COMMA_SEPARATOR : 0;
|
||||
|
||||
$cloner = new VarCloner();
|
||||
$cloner->setMaxItems(-1);
|
||||
|
Reference in New Issue
Block a user