From 97c89686b1896cddfcb10ee568bcbd816db87d6b Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 11 Jul 2019 17:24:38 -0400 Subject: [PATCH] [ErrorRenderer] Add DebugCommand for easy debugging and testing --- .../Resources/config/console.xml | 6 + .../ErrorRenderer/Command/DebugCommand.php | 123 ++++++++++++++++++ .../DependencyInjection/ErrorRendererPass.php | 8 +- .../Tests/Command/DebugCommandTest.php | 90 +++++++++++++ .../Component/ErrorRenderer/composer.json | 1 + 5 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/ErrorRenderer/Command/DebugCommand.php create mode 100644 src/Symfony/Component/ErrorRenderer/Tests/Command/DebugCommandTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml index ebd7d6ce46a6d..b87441fdfabdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml @@ -194,5 +194,11 @@ + + + + + + diff --git a/src/Symfony/Component/ErrorRenderer/Command/DebugCommand.php b/src/Symfony/Component/ErrorRenderer/Command/DebugCommand.php new file mode 100644 index 0000000000000..eac8f557e3b48 --- /dev/null +++ b/src/Symfony/Component/ErrorRenderer/Command/DebugCommand.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ErrorRenderer\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRendererInterface; +use Symfony\Component\ErrorRenderer\Exception\FlattenException; +use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; + +/** + * A console command for retrieving information about error renderers. + * + * @author Yonel Ceruto + * + * @internal + */ +class DebugCommand extends Command +{ + protected static $defaultName = 'debug:error-renderer'; + + private $renderers; + private $fileLinkFormatter; + + /** + * @param ErrorRendererInterface[] $renderers + */ + public function __construct(array $renderers, FileLinkFormatter $fileLinkFormatter = null) + { + $this->renderers = $renderers; + $this->fileLinkFormatter = $fileLinkFormatter; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure(): void + { + $this + ->addArgument('format', InputArgument::OPTIONAL, sprintf('Outputs a sample in a specific format (one of %s)', implode(', ', array_keys($this->renderers)))) + ->setDescription('Displays all available error renderers and their formats.') + ->setHelp(<<<'EOF' +The %command.name% command displays all available error renderers and +their formats: + + php %command.full_name% + +Or output a sample in a specific format: + + php %command.full_name% json + +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + $renderers = $this->renderers; + + if ($format = $input->getArgument('format')) { + if (!isset($renderers[$format])) { + throw new InvalidArgumentException(sprintf('No error renderer found for format "%s". Known format are %s.', $format, implode(', ', array_keys($this->renderers)))); + } + + $exception = FlattenException::createFromThrowable(new \Exception('This is a sample exception.'), 500, ['X-Debug' => false]); + $io->writeln($renderers[$format]->render($exception)); + } else { + $tableRows = []; + foreach ($renderers as $format => $renderer) { + $tableRows[] = [sprintf('%s', $format), $this->formatClassLink(\get_class($renderer))]; + } + + $io->title('Error Renderers'); + $io->text('The following error renderers are available:'); + $io->newLine(); + $io->table(['Format', 'Class'], $tableRows); + } + } + + private function formatClassLink(string $class): string + { + if ('' === $fileLink = $this->getFileLink($class)) { + return $class; + } + + return sprintf('%s', $fileLink, $class); + } + + private function getFileLink(string $class): string + { + if (null === $this->fileLinkFormatter) { + return ''; + } + + try { + $r = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + return ''; + } + + return $this->fileLinkFormatter->format($r->getFileName(), $r->getStartLine()); + } +} diff --git a/src/Symfony/Component/ErrorRenderer/DependencyInjection/ErrorRendererPass.php b/src/Symfony/Component/ErrorRenderer/DependencyInjection/ErrorRendererPass.php index 34c970adca6ac..1e297b7de13b3 100644 --- a/src/Symfony/Component/ErrorRenderer/DependencyInjection/ErrorRendererPass.php +++ b/src/Symfony/Component/ErrorRenderer/DependencyInjection/ErrorRendererPass.php @@ -24,11 +24,13 @@ class ErrorRendererPass implements CompilerPassInterface { private $rendererService; private $rendererTag; + private $debugCommandService; - public function __construct(string $rendererService = 'error_renderer', string $rendererTag = 'error_renderer.renderer') + public function __construct(string $rendererService = 'error_renderer', string $rendererTag = 'error_renderer.renderer', string $debugCommandService = 'console.command.error_renderer_debug') { $this->rendererService = $rendererService; $this->rendererTag = $rendererTag; + $this->debugCommandService = $debugCommandService; } /** @@ -61,5 +63,9 @@ public function process(ContainerBuilder $container) $definition = $container->getDefinition($this->rendererService); $definition->replaceArgument(0, ServiceLocatorTagPass::register($container, $renderers)); + + if ($container->hasDefinition($this->debugCommandService)) { + $container->getDefinition($this->debugCommandService)->replaceArgument(0, $renderers); + } } } diff --git a/src/Symfony/Component/ErrorRenderer/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/ErrorRenderer/Tests/Command/DebugCommandTest.php new file mode 100644 index 0000000000000..2a9174727dc99 --- /dev/null +++ b/src/Symfony/Component/ErrorRenderer/Tests/Command/DebugCommandTest.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ErrorRenderer\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\ErrorRenderer\Command\DebugCommand; +use Symfony\Component\ErrorRenderer\ErrorRenderer\JsonErrorRenderer; +use Symfony\Component\ErrorRenderer\ErrorRenderer\TxtErrorRenderer; +use Symfony\Component\ErrorRenderer\ErrorRenderer\XmlErrorRenderer; + +class DebugCommandTest extends TestCase +{ + public function testAvailableRenderers() + { + $tester = $this->createCommandTester(); + $ret = $tester->execute([], ['decorated' => false]); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertSame(<<getDisplay(true)); + } + + public function testFormatArgument() + { + $tester = $this->createCommandTester(); + $ret = $tester->execute(['format' => 'json'], ['decorated' => false]); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertSame(<<getDisplay(true)); + } + + private function createCommandTester() + { + $command = new DebugCommand([ + 'json' => new JsonErrorRenderer(false), + 'xml' => new XmlErrorRenderer(false), + 'txt' => new TxtErrorRenderer(false), + ]); + + $application = new Application(); + $application->add($command); + + return new CommandTester($application->find('debug:error-renderer')); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException + * @expectedExceptionMessage No error renderer found for format "foo". Known format are json, xml, txt. + */ + public function testInvalidFormat() + { + $tester = $this->createCommandTester(); + $tester->execute(['format' => 'foo'], ['decorated' => false]); + } +} diff --git a/src/Symfony/Component/ErrorRenderer/composer.json b/src/Symfony/Component/ErrorRenderer/composer.json index 4ce8a991f4280..31d15a79d99f0 100644 --- a/src/Symfony/Component/ErrorRenderer/composer.json +++ b/src/Symfony/Component/ErrorRenderer/composer.json @@ -20,6 +20,7 @@ "psr/log": "~1.0" }, "require-dev": { + "symfony/console": "^4.4", "symfony/dependency-injection": "^4.4", "symfony/http-kernel": "^4.4" }, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy