bug #30660 [Bridge][Twig] DebugCommand - fix escaping and filter (SpacePossum)
This PR was squashed before being merged into the 3.4 branch (closes #30660).
Discussion
----------
[Bridge][Twig] DebugCommand - fix escaping and filter
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| License | MIT
The PR fixes:
- output escaping was not done for decorated consoles
- filter was not applied when using format json
+ added some tests for paths currently not tested
Commits
-------
7bdb06641d
[Bridge][Twig] DebugCommand - fix escaping and filter
This commit is contained in:
commit
6f0863020a
|
@ -12,6 +12,7 @@
|
||||||
namespace Symfony\Bridge\Twig\Command;
|
namespace Symfony\Bridge\Twig\Command;
|
||||||
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
@ -100,6 +101,7 @@ EOF
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
$decorated = $io->isDecorated();
|
||||||
|
|
||||||
// BC to be removed in 4.0
|
// BC to be removed in 4.0
|
||||||
if (__CLASS__ !== \get_class($this)) {
|
if (__CLASS__ !== \get_class($this)) {
|
||||||
|
@ -114,29 +116,35 @@ EOF
|
||||||
throw new \RuntimeException('The Twig environment needs to be set.');
|
throw new \RuntimeException('The Twig environment needs to be set.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$filter = $input->getArgument('filter');
|
||||||
$types = ['functions', 'filters', 'tests', 'globals'];
|
$types = ['functions', 'filters', 'tests', 'globals'];
|
||||||
|
|
||||||
if ('json' === $input->getOption('format')) {
|
if ('json' === $input->getOption('format')) {
|
||||||
$data = [];
|
$data = [];
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
|
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
|
||||||
$data[$type][$name] = $this->getMetadata($type, $entity);
|
if (!$filter || false !== strpos($name, $filter)) {
|
||||||
|
$data[$type][$name] = $this->getMetadata($type, $entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$data['tests'] = array_keys($data['tests']);
|
|
||||||
|
if (isset($data['tests'])) {
|
||||||
|
$data['tests'] = array_keys($data['tests']);
|
||||||
|
}
|
||||||
|
|
||||||
$data['loader_paths'] = $this->getLoaderPaths();
|
$data['loader_paths'] = $this->getLoaderPaths();
|
||||||
$io->writeln(json_encode($data));
|
$data = json_encode($data, JSON_PRETTY_PRINT);
|
||||||
|
$io->writeln($decorated ? OutputFormatter::escape($data) : $data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filter = $input->getArgument('filter');
|
|
||||||
|
|
||||||
foreach ($types as $index => $type) {
|
foreach ($types as $index => $type) {
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
|
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
|
||||||
if (!$filter || false !== strpos($name, $filter)) {
|
if (!$filter || false !== strpos($name, $filter)) {
|
||||||
$items[$name] = $name.$this->getPrettyMetadata($type, $entity);
|
$items[$name] = $name.$this->getPrettyMetadata($type, $entity, $decorated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +270,7 @@ EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPrettyMetadata($type, $entity)
|
private function getPrettyMetadata($type, $entity, $decorated)
|
||||||
{
|
{
|
||||||
if ('tests' === $type) {
|
if ('tests' === $type) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -274,7 +282,7 @@ EOF
|
||||||
return '(unknown?)';
|
return '(unknown?)';
|
||||||
}
|
}
|
||||||
} catch (\UnexpectedValueException $e) {
|
} catch (\UnexpectedValueException $e) {
|
||||||
return ' <error>'.$e->getMessage().'</error>';
|
return sprintf(' <error>%s</error>', $decorated ? OutputFormatter::escape($e->getMessage()) : $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('globals' === $type) {
|
if ('globals' === $type) {
|
||||||
|
@ -282,7 +290,9 @@ EOF
|
||||||
return ' = object('.\get_class($meta).')';
|
return ' = object('.\get_class($meta).')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ' = '.substr(@json_encode($meta), 0, 50);
|
$description = substr(@json_encode($meta), 0, 50);
|
||||||
|
|
||||||
|
return sprintf(' = %s', $decorated ? OutputFormatter::escape($description) : $description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('functions' === $type) {
|
if ('functions' === $type) {
|
||||||
|
|
|
@ -62,7 +62,45 @@ TXT;
|
||||||
$this->assertContains($loaderPaths, trim($tester->getDisplay(true)));
|
$this->assertContains($loaderPaths, trim($tester->getDisplay(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createCommandTester(array $paths = [])
|
public function testWithGlobals()
|
||||||
|
{
|
||||||
|
$message = '<error>foo</error>';
|
||||||
|
$tester = $this->createCommandTester([], ['message' => $message]);
|
||||||
|
$tester->execute([], ['decorated' => true]);
|
||||||
|
|
||||||
|
$display = $tester->getDisplay();
|
||||||
|
|
||||||
|
$this->assertContains(\json_encode($message), $display);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithGlobalsJson()
|
||||||
|
{
|
||||||
|
$globals = ['message' => '<error>foo</error>'];
|
||||||
|
|
||||||
|
$tester = $this->createCommandTester([], $globals);
|
||||||
|
$tester->execute(['--format' => 'json'], ['decorated' => true]);
|
||||||
|
|
||||||
|
$display = $tester->getDisplay();
|
||||||
|
$display = \json_decode($display, true);
|
||||||
|
|
||||||
|
$this->assertSame($globals, $display['globals']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithFilter()
|
||||||
|
{
|
||||||
|
$tester = $this->createCommandTester([]);
|
||||||
|
$tester->execute(['--format' => 'json'], ['decorated' => false]);
|
||||||
|
$display = $tester->getDisplay();
|
||||||
|
$display1 = \json_decode($display, true);
|
||||||
|
|
||||||
|
$tester->execute(['filter' => 'date', '--format' => 'json'], ['decorated' => false]);
|
||||||
|
$display = $tester->getDisplay();
|
||||||
|
$display2 = \json_decode($display, true);
|
||||||
|
|
||||||
|
$this->assertNotSame($display1, $display2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createCommandTester(array $paths = [], array $globals = [])
|
||||||
{
|
{
|
||||||
$filesystemLoader = new FilesystemLoader([], \dirname(__DIR__).'/Fixtures');
|
$filesystemLoader = new FilesystemLoader([], \dirname(__DIR__).'/Fixtures');
|
||||||
foreach ($paths as $namespace => $relDirs) {
|
foreach ($paths as $namespace => $relDirs) {
|
||||||
|
@ -70,7 +108,13 @@ TXT;
|
||||||
$filesystemLoader->addPath($relDir, $namespace);
|
$filesystemLoader->addPath($relDir, $namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$command = new DebugCommand(new Environment($filesystemLoader));
|
|
||||||
|
$environment = new Environment($filesystemLoader);
|
||||||
|
foreach ($globals as $name => $value) {
|
||||||
|
$environment->addGlobal($name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$command = new DebugCommand($environment);
|
||||||
|
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
$application->add($command);
|
$application->add($command);
|
||||||
|
|
|
@ -87,6 +87,10 @@ class CommandTester
|
||||||
*/
|
*/
|
||||||
public function getDisplay($normalize = false)
|
public function getDisplay($normalize = false)
|
||||||
{
|
{
|
||||||
|
if (null === $this->output) {
|
||||||
|
throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
|
||||||
|
}
|
||||||
|
|
||||||
rewind($this->output->getStream());
|
rewind($this->output->getStream());
|
||||||
|
|
||||||
$display = stream_get_contents($this->output->getStream());
|
$display = stream_get_contents($this->output->getStream());
|
||||||
|
|
Reference in New Issue