diff --git a/src/Command/TwigCsFixerCommand.php b/src/Command/TwigCsFixerCommand.php index e3d90faa..fa5eb457 100644 --- a/src/Command/TwigCsFixerCommand.php +++ b/src/Command/TwigCsFixerCommand.php @@ -14,8 +14,9 @@ use TwigCsFixer\Config\ConfigResolver; use TwigCsFixer\Environment\StubbedEnvironment; use TwigCsFixer\Exception\CannotResolveConfigException; +use TwigCsFixer\Report\Reporter\TextReporter; use TwigCsFixer\Report\Report; -use TwigCsFixer\Report\TextFormatter; +use TwigCsFixer\Report\ReporterFactory; use TwigCsFixer\Runner\Fixer; use TwigCsFixer\Runner\Linter; use TwigCsFixer\Token\Tokenizer; @@ -50,6 +51,13 @@ protected function configure(): void InputOption::VALUE_REQUIRED, 'Path to a `.twig-cs-fixer.php` config file' ), + new InputOption( + 'report', + 'r', + InputOption::VALUE_REQUIRED, + 'Report format', + TextReporter::NAME + ), new InputOption( 'fix', 'f', @@ -119,8 +127,9 @@ private function runLinter(Config $config, InputInterface $input, OutputInterfac $input->getOption('fix') ? new Fixer($tokenizer) : null ); - $reporter = new TextFormatter($input, $output); - $reporter->display($report, $input->getOption('level')); + $reporterFactory = new ReporterFactory(); + $reporter = $reporterFactory->getReporter($input->getOption('report')); + $reporter->display($output, $report, $input->getOption('level')); return $report; } diff --git a/src/Report/Reporter/NullReporter.php b/src/Report/Reporter/NullReporter.php new file mode 100644 index 00000000..966305d5 --- /dev/null +++ b/src/Report/Reporter/NullReporter.php @@ -0,0 +1,18 @@ +>'; private const ERROR_LINE_FORMAT = '%-5s| %s'; private const ERROR_LINE_WIDTH = 120; - private SymfonyStyle $io; - - public function __construct(InputInterface $input, OutputInterface $output) + public function display(OutputInterface $output, Report $report, ?string $level = null): void { - $this->io = new SymfonyStyle($input, $output); - } + $io = new SymfonyStyle(new ArrayInput([]), $output); - public function display(Report $report, ?string $level = null): void - { if ( - $this->io->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE + $io->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE && [] !== $report->getFixedFiles() ) { - $this->io->text('Changed:'); - $this->io->listing($report->getFixedFiles()); + $io->text('Changed:'); + $io->listing($report->getFixedFiles()); } foreach ($report->getFiles() as $file) { $fileMessages = $report->getMessages($file, $level); if (\count($fileMessages) > 0) { - $this->io->text(sprintf('KO %s', $file)); + $io->text(sprintf('KO %s', $file)); } $content = @file_get_contents($file); @@ -77,7 +76,7 @@ public function display(Report $report, ?string $level = null): void } if (\count($rows) > 0) { - $this->io->table([], $rows); + $io->table([], $rows); } } @@ -90,11 +89,11 @@ public function display(Report $report, ?string $level = null): void ); if (0 < $report->getTotalErrors()) { - $this->io->error($summaryString); + $io->error($summaryString); } elseif (0 < $report->getTotalWarnings()) { - $this->io->warning($summaryString); + $io->warning($summaryString); } else { - $this->io->success($summaryString); + $io->success($summaryString); } } diff --git a/src/Report/ReporterFactory.php b/src/Report/ReporterFactory.php new file mode 100644 index 00000000..bd19de96 --- /dev/null +++ b/src/Report/ReporterFactory.php @@ -0,0 +1,24 @@ + new NullReporter(), + TextReporter::NAME => new TextReporter(), + default => throw new InvalidArgumentException( + sprintf('No reporter supports the format "%s".', $format) + ), + }; + } +} diff --git a/tests/Command/TwigCsFixerCommandTest.php b/tests/Command/TwigCsFixerCommandTest.php index 19d90048..02c3981b 100644 --- a/tests/Command/TwigCsFixerCommandTest.php +++ b/tests/Command/TwigCsFixerCommandTest.php @@ -110,6 +110,21 @@ public function testExecuteWithReportErrorsFixedVerbose(): void static::assertSame(Command::FAILURE, $commandTester->getStatusCode()); } + public function testExecuteWithReportOption(): void + { + $command = new TwigCsFixerCommand(); + + $commandTester = new CommandTester($command); + $commandTester->execute([ + 'paths' => [$this->getTmpPath(__DIR__.'/Fixtures/file.twig')], + '--no-cache' => true, // To avoid cache output + '--report' => 'null', + ]); + + static::assertSame('', $commandTester->getDisplay()); + static::assertSame(Command::SUCCESS, $commandTester->getStatusCode()); + } + public function testExecuteWithConfig(): void { $command = new TwigCsFixerCommand(); diff --git a/tests/Report/Fixtures/file.twig b/tests/Report/Formatter/Fixtures/file.twig similarity index 100% rename from tests/Report/Fixtures/file.twig rename to tests/Report/Formatter/Fixtures/file.twig diff --git a/tests/Report/Fixtures/file2.twig b/tests/Report/Formatter/Fixtures/file2.twig similarity index 100% rename from tests/Report/Fixtures/file2.twig rename to tests/Report/Formatter/Fixtures/file2.twig diff --git a/tests/Report/Formatter/NullReporterTest.php b/tests/Report/Formatter/NullReporterTest.php new file mode 100644 index 00000000..360a6e54 --- /dev/null +++ b/tests/Report/Formatter/NullReporterTest.php @@ -0,0 +1,54 @@ +addMessage($violation0); + $violation1 = new SniffViolation(SniffViolation::LEVEL_WARNING, 'Warning', $file, 2); + $report->addMessage($violation1); + $violation2 = new SniffViolation(SniffViolation::LEVEL_ERROR, 'Error', $file, 3); + $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::assertSame('', $text); + } + + /** + * @return iterable + */ + public static function displayDataProvider(): iterable + { + yield [null]; + yield [Report::MESSAGE_TYPE_NOTICE]; + yield [Report::MESSAGE_TYPE_WARNING]; + yield [Report::MESSAGE_TYPE_ERROR]; + yield [Report::MESSAGE_TYPE_FATAL]; + } +} diff --git a/tests/Report/TextFormatterTest.php b/tests/Report/Formatter/TextReporterTest.php similarity index 86% rename from tests/Report/TextFormatterTest.php rename to tests/Report/Formatter/TextReporterTest.php index db4404f2..74f63cff 100644 --- a/tests/Report/TextFormatterTest.php +++ b/tests/Report/Formatter/TextReporterTest.php @@ -2,27 +2,24 @@ declare(strict_types=1); -namespace TwigCsFixer\Tests\Report; +namespace TwigCsFixer\Tests\Report\Formatter; use PHPUnit\Framework\TestCase; use SplFileInfo; -use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; -use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Output\OutputInterface; +use TwigCsFixer\Report\Reporter\TextReporter; use TwigCsFixer\Report\Report; use TwigCsFixer\Report\SniffViolation; -use TwigCsFixer\Report\TextFormatter; -final class TextFormatterTest extends TestCase +final class TextReporterTest extends TestCase { /** * @dataProvider displayDataProvider */ public function testDisplayErrors(string $expected, ?string $level): void { - $input = new ArrayInput([]); - $output = new BufferedOutput(Output::VERBOSITY_NORMAL, true); - $textFormatter = new TextFormatter($input, $output); + $textFormatter = new TextReporter(); $file = __DIR__.'/Fixtures/file.twig'; $report = new Report([new SplFileInfo($file)]); @@ -36,7 +33,8 @@ public function testDisplayErrors(string $expected, ?string $level): void $violation3 = new SniffViolation(SniffViolation::LEVEL_FATAL, 'Fatal', $file); $report->addMessage($violation3); - $textFormatter->display($report, $level); + $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true); + $textFormatter->display($output, $report, $level); $text = $output->fetch(); static::assertStringContainsString($expected, $text); @@ -96,14 +94,13 @@ public static function displayDataProvider(): iterable public function testDisplaySuccess(): void { - $input = new ArrayInput([]); - $output = new BufferedOutput(); - $textFormatter = new TextFormatter($input, $output); + $textFormatter = new TextReporter(); $file = __DIR__.'/Fixtures/file.twig'; $report = new Report([new SplFileInfo($file)]); - $textFormatter->display($report); + $output = new BufferedOutput(); + $textFormatter->display($output, $report); $text = $output->fetch(); static::assertStringNotContainsString(sprintf('KO %s/Fixtures/file.twig', __DIR__), $text); @@ -112,9 +109,7 @@ public function testDisplaySuccess(): void public function testDisplayMultipleFiles(): void { - $input = new ArrayInput([]); - $output = new BufferedOutput(); - $textFormatter = new TextFormatter($input, $output); + $textFormatter = new TextReporter(); $file = __DIR__.'/Fixtures/file.twig'; $file2 = __DIR__.'/Fixtures/file2.twig'; @@ -123,7 +118,8 @@ public function testDisplayMultipleFiles(): void $violation = new SniffViolation(SniffViolation::LEVEL_ERROR, 'Error', $file, 3); $report->addMessage($violation); - $textFormatter->display($report); + $output = new BufferedOutput(); + $textFormatter->display($output, $report); static::assertStringContainsString( sprintf( @@ -146,9 +142,7 @@ public function testDisplayMultipleFiles(): void public function testDisplayNotFoundFile(): void { - $input = new ArrayInput([]); - $output = new BufferedOutput(); - $textFormatter = new TextFormatter($input, $output); + $textFormatter = new TextReporter(); $file = __DIR__.'/Fixtures/fileNotFound.twig'; @@ -156,7 +150,8 @@ public function testDisplayNotFoundFile(): void $violation = new SniffViolation(SniffViolation::LEVEL_ERROR, 'Error', $file, 1); $report->addMessage($violation); - $textFormatter->display($report); + $output = new BufferedOutput(); + $textFormatter->display($output, $report); static::assertStringContainsString( sprintf( @@ -177,9 +172,7 @@ public function testDisplayNotFoundFile(): void */ public function testDisplayBlock(string $expected, int $level): void { - $input = new ArrayInput([]); - $output = new BufferedOutput(Output::VERBOSITY_NORMAL, true); - $textFormatter = new TextFormatter($input, $output); + $textFormatter = new TextReporter(); $file = __DIR__.'/Fixtures/file.twig'; $report = new Report([new SplFileInfo($file)]); @@ -187,7 +180,8 @@ public function testDisplayBlock(string $expected, int $level): void $violation = new SniffViolation($level, 'Message', $file, 1); $report->addMessage($violation); - $textFormatter->display($report); + $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true); + $textFormatter->display($output, $report); $text = $output->fetch(); static::assertStringContainsString($expected, $text); diff --git a/tests/Report/ReporterFactoryTest.php b/tests/Report/ReporterFactoryTest.php new file mode 100644 index 00000000..a662dc85 --- /dev/null +++ b/tests/Report/ReporterFactoryTest.php @@ -0,0 +1,28 @@ +getReporter()); + static::assertInstanceOf(TextReporter::class, $reporterFactory->getReporter(TextReporter::NAME)); + static::assertInstanceOf(NullReporter::class, $reporterFactory->getReporter(NullReporter::NAME)); + } + + public function testGetMessageForAnotherFile(): void + { + $reporterFactory = new ReporterFactory(); + + $this->expectExceptionMessage('No reporter supports the format "foo".'); + $reporterFactory->getReporter('foo'); + } +}