From f066c50aced9b3aa389a0da9827ffd3bcfe3203b Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 23 Nov 2023 09:47:59 +0100 Subject: [PATCH] Rework --- composer-require-checker.json | 3 +- src/Report/Reporter/CheckstyleReporter.php | 51 ++++++++---- tests/Command/TwigCsFixerCommandTest.php | 4 +- .../Formatter/CheckstyleReporterTest.php | 82 +++++++++++++++++++ 4 files changed, 119 insertions(+), 21 deletions(-) create mode 100644 tests/Report/Formatter/CheckstyleReporterTest.php diff --git a/composer-require-checker.json b/composer-require-checker.json index 3e87a142..7878977e 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -8,7 +8,6 @@ "Symfony\\Bridge\\Twig\\TokenParser\\TransTokenParser", "Symfony\\UX\\TwigComponent\\Twig\\ComponentTokenParser", "Symfony\\UX\\TwigComponent\\Twig\\PropsTokenParser", - "Twig\\Extra\\Cache\\TokenParser\\CacheTokenParser", - "\\SimpleXMLElement" + "Twig\\Extra\\Cache\\TokenParser\\CacheTokenParser" ] } diff --git a/src/Report/Reporter/CheckstyleReporter.php b/src/Report/Reporter/CheckstyleReporter.php index 880b8dd8..f37f1219 100644 --- a/src/Report/Reporter/CheckstyleReporter.php +++ b/src/Report/Reporter/CheckstyleReporter.php @@ -8,35 +8,52 @@ use TwigCsFixer\Report\Report; use TwigCsFixer\Report\SniffViolation; -/** - * Human-readable output with context. - */ final class CheckstyleReporter implements ReporterInterface { public const NAME = 'checkstyle'; public function display(OutputInterface $output, Report $report, ?string $level = null): void { - $checkstyle = new \SimpleXMLElement(''); + $text = ''."\n"; + + $text .= ''."\n"; foreach ($report->getFiles() as $file) { $fileMessages = $report->getMessages($file, $level); - if (\count($fileMessages) > 0) { - /** @var \SimpleXMLElement $fileNode */ - $fileNode = $checkstyle->addChild('file'); - $fileNode->addAttribute('name', $file); - - foreach ($fileMessages as $message) { - /** @var \SimpleXMLElement $violation */ - $violation = $fileNode->addChild('violation'); - $violation->addAttribute('column', (string) $message->getLinePosition()); - $violation->addAttribute('severity', strtolower(SniffViolation::getLevelAsString($message->getLevel()))); - $violation->addAttribute('message', $message->getMessage()); - $violation->addAttribute('source', $message->getSniffName() ?? ''); + if (0 === \count($fileMessages)) { + continue; + } + + $text .= ' '."\n"; + foreach ($fileMessages as $message) { + $line = (string) $message->getLine(); + $linePosition = (string) $message->getLinePosition(); + $sniffName = $message->getSniffName(); + + $text .= ' getLevel())).'"'; + $text .= ' message="'.$this->xmlEncode($message->getMessage()).'"'; + if (null !== $sniffName) { + $text .= ' source="'.$sniffName.'"'; + } + $text .= '/>'."\n"; } + $text .= ' '."\n"; } - $output->writeln((string) $checkstyle->asXML()); + $text .= ''."\n"; + + $output->writeln($text); + } + + private function xmlEncode(string $data): string + { + return htmlspecialchars($data, \ENT_XML1 | \ENT_QUOTES); } } diff --git a/tests/Command/TwigCsFixerCommandTest.php b/tests/Command/TwigCsFixerCommandTest.php index 02c3981b..8c151d2b 100644 --- a/tests/Command/TwigCsFixerCommandTest.php +++ b/tests/Command/TwigCsFixerCommandTest.php @@ -116,9 +116,9 @@ public function testExecuteWithReportOption(): void $commandTester = new CommandTester($command); $commandTester->execute([ - 'paths' => [$this->getTmpPath(__DIR__.'/Fixtures/file.twig')], + 'paths' => [$this->getTmpPath(__DIR__.'/Fixtures')], '--no-cache' => true, // To avoid cache output - '--report' => 'null', + '--report' => 'checkstyle', ]); static::assertSame('', $commandTester->getDisplay()); diff --git a/tests/Report/Formatter/CheckstyleReporterTest.php b/tests/Report/Formatter/CheckstyleReporterTest.php new file mode 100644 index 00000000..1198030a --- /dev/null +++ b/tests/Report/Formatter/CheckstyleReporterTest.php @@ -0,0 +1,82 @@ +addMessage($violation0); + $violation1 = new SniffViolation(SniffViolation::LEVEL_WARNING, 'Warning', $file, 2, 22, 'WarningSniff'); + $report->addMessage($violation1); + $violation2 = new SniffViolation(SniffViolation::LEVEL_ERROR, 'Error', $file, 3, 33, 'ErrorSniff'); + $report->addMessage($violation2); + $violation3 = new SniffViolation(SniffViolation::LEVEL_FATAL, 'Fatal', $file); + $report->addMessage($violation3); + + $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true); + $textFormatter->display($output, $report, $level); + + $text = $output->fetch(); + static::assertStringContainsString($expected, $text); + } + + /** + * @return iterable + */ + public static function displayDataProvider(): iterable + { + yield [ + sprintf( + << + + + + + + + + + EOD, + __DIR__ + ), + null, + ]; + + yield [ + sprintf( + << + + + + + + + EOD, + __DIR__ + ), + Report::MESSAGE_TYPE_ERROR, + ]; + } +}