Skip to content

Commit

Permalink
Add JUnit reporter (#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet authored Nov 25, 2023
1 parent 1c5555d commit cdfdccf
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 9 deletions.
19 changes: 19 additions & 0 deletions src/Report/Report.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,25 @@ public function getMessages(string $filename, ?string $level = null): array
);
}

/**
* @return list<SniffViolation>
*/
public function getAllMessages(?string $level = null): array
{
$messages = array_merge(...array_values($this->messagesByFiles));

if (null === $level) {
return $messages;
}

return array_values(
array_filter(
$messages,
static fn (SniffViolation $message): bool => $message->getLevel() >= SniffViolation::getLevelAsInt($level)
)
);
}

/**
* @return list<string>
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Report/Reporter/CheckstyleReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function display(OutputInterface $output, Report $report, ?string $level
continue;
}

$text .= ' <file name="'.$this->xmlEncode($file).'">'."\n";
$text .= sprintf(' <file name="%s">', $this->xmlEncode($file))."\n";
foreach ($fileMessages as $message) {
$line = (string) $message->getLine();
$linePosition = (string) $message->getLinePosition();
Expand Down
65 changes: 65 additions & 0 deletions src/Report/Reporter/JUnitReporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace TwigCsFixer\Report\Reporter;

use Symfony\Component\Console\Output\OutputInterface;
use TwigCsFixer\Report\Report;
use TwigCsFixer\Report\SniffViolation;

final class JUnitReporter implements ReporterInterface
{
public const NAME = 'junit';

public function display(OutputInterface $output, Report $report, ?string $level = null): void
{
$messages = $report->getAllMessages($level);
$totalErrors = \count($messages);

$text = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$text .= '<testsuites>'."\n";
$text .= ' '.sprintf(
'<testsuite name="Twig CS Fixer" tests="%d" failures="%d">',
max($totalErrors, 1),
$totalErrors
)."\n";

if ($totalErrors > 0) {
foreach ($messages as $message) {
$text .= $this->createTestCase(
sprintf('%s:%s', $message->getFilename(), $message->getLine() ?? 0),
strtolower(SniffViolation::getLevelAsString($message->getLevel())),
$message->getMessage()
);
}
} else {
$text .= $this->createTestCase('All OK');
}

$text .= ' </testsuite>'."\n";
$text .= '</testsuites>';

$output->writeln($text);
}

private function createTestCase(string $name, string $type = '', ?string $message = null): string
{
$result = ' '.sprintf('<testcase name="%s">', $this->xmlEncode($name))."\n";

if (null !== $message) {
$result .= ' '
.sprintf('<failure type="%s" message="%s" />', $this->xmlEncode($type), $this->xmlEncode($message))
."\n";
}

$result .= ' </testcase>'."\n";

return $result;
}

private function xmlEncode(string $data): string
{
return htmlspecialchars($data, \ENT_XML1 | \ENT_QUOTES);
}
}
2 changes: 2 additions & 0 deletions src/Report/ReporterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use InvalidArgumentException;
use TwigCsFixer\Report\Reporter\CheckstyleReporter;
use TwigCsFixer\Report\Reporter\JUnitReporter;
use TwigCsFixer\Report\Reporter\NullReporter;
use TwigCsFixer\Report\Reporter\ReporterInterface;
use TwigCsFixer\Report\Reporter\TextReporter;
Expand All @@ -18,6 +19,7 @@ public function getReporter(string $format = TextReporter::NAME): ReporterInterf
NullReporter::NAME => new NullReporter(),
TextReporter::NAME => new TextReporter(),
CheckstyleReporter::NAME => new CheckstyleReporter(),
JUnitReporter::NAME => new JUnitReporter(),
default => throw new InvalidArgumentException(
sprintf('No reporter supports the format "%s".', $format)
),
Expand Down
13 changes: 5 additions & 8 deletions tests/Report/Formatter/CheckstyleReporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,20 @@ public static function displayDataProvider(): iterable
<<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle>
<file name="%s/Fixtures/file.twig">
<file name="%1\$s/Fixtures/file.twig">
<error line="1" column="11" severity="notice" message="Notice" source="NoticeSniff"/>
<error line="2" column="22" severity="warning" message="Warning" source="WarningSniff"/>
<error line="3" column="33" severity="error" message="Error" source="ErrorSniff"/>
<error severity="fatal" message="Fatal"/>
</file>
<file name="%s/Fixtures/file2.twig">
<file name="%1\$s/Fixtures/file2.twig">
<error line="1" column="11" severity="notice" message="Notice2" source="Notice2Sniff"/>
</file>
<file name="%s/Fixtures/file3.twig">
<file name="%1\$s/Fixtures/file3.twig">
<error severity="fatal" message="&apos;&quot;&lt;&amp;&gt;&quot;&apos;"/>
</file>
</checkstyle>
EOD,
__DIR__,
__DIR__,
__DIR__
),
null,
Expand All @@ -84,16 +82,15 @@ public static function displayDataProvider(): iterable
<<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle>
<file name="%s/Fixtures/file.twig">
<file name="%1\$s/Fixtures/file.twig">
<error line="3" column="33" severity="error" message="Error" source="ErrorSniff"/>
<error severity="fatal" message="Fatal"/>
</file>
<file name="%s/Fixtures/file3.twig">
<file name="%1\$s/Fixtures/file3.twig">
<error severity="fatal" message="&apos;&quot;&lt;&amp;&gt;&quot;&apos;"/>
</file>
</checkstyle>
EOD,
__DIR__,
__DIR__
),
Report::MESSAGE_TYPE_ERROR,
Expand Down
114 changes: 114 additions & 0 deletions tests/Report/Formatter/JUnitReporterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

declare(strict_types=1);

namespace TwigCsFixer\Tests\Report\Formatter;

use PHPUnit\Framework\TestCase;
use SplFileInfo;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use TwigCsFixer\Report\Report;
use TwigCsFixer\Report\Reporter\JUnitReporter;
use TwigCsFixer\Report\SniffViolation;

final class JUnitReporterTest extends TestCase
{
/**
* @dataProvider displayDataProvider
*/
public function testDisplayErrors(string $expected, ?string $level): void
{
$textFormatter = new JUnitReporter();

$file = __DIR__.'/Fixtures/file.twig';
$file2 = __DIR__.'/Fixtures/file2.twig';
$file3 = __DIR__.'/Fixtures/file3.twig';
$report = new Report([new SplFileInfo($file), new SplFileInfo($file2), new SplFileInfo($file3)]);

$violation0 = new SniffViolation(SniffViolation::LEVEL_NOTICE, 'Notice', $file, 1, 11, 'NoticeSniff');
$report->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);

$violation4 = new SniffViolation(SniffViolation::LEVEL_NOTICE, 'Notice2', $file2, 1, 11, 'Notice2Sniff');
$report->addMessage($violation4);

$violation5 = new SniffViolation(SniffViolation::LEVEL_FATAL, '\'"<&>"\'', $file3);
$report->addMessage($violation5);

$output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true);
$textFormatter->display($output, $report, $level);

$text = $output->fetch();
static::assertStringContainsString($expected, $text);
}

/**
* @return iterable<array-key, array{string, string|null}>
*/
public static function displayDataProvider(): iterable
{
yield [
sprintf(
<<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="Twig CS Fixer" tests="6" failures="6">
<testcase name="%1\$s/Fixtures/file.twig:1">
<failure type="notice" message="Notice" />
</testcase>
<testcase name="%1\$s/Fixtures/file.twig:2">
<failure type="warning" message="Warning" />
</testcase>
<testcase name="%1\$s/Fixtures/file.twig:3">
<failure type="error" message="Error" />
</testcase>
<testcase name="%1\$s/Fixtures/file.twig:0">
<failure type="fatal" message="Fatal" />
</testcase>
<testcase name="%1\$s/Fixtures/file2.twig:1">
<failure type="notice" message="Notice2" />
</testcase>
<testcase name="%1\$s/Fixtures/file3.twig:0">
<failure type="fatal" message="&apos;&quot;&lt;&amp;&gt;&quot;&apos;" />
</testcase>
</testsuite>
</testsuites>
EOD,
__DIR__
),
null,
];
}

public function testDisplaySuccess(): void
{
$textFormatter = new JUnitReporter();

$file = __DIR__.'/Fixtures/file.twig';
$file2 = __DIR__.'/Fixtures/file2.twig';
$file3 = __DIR__.'/Fixtures/file3.twig';
$report = new Report([new SplFileInfo($file), new SplFileInfo($file2), new SplFileInfo($file3)]);

$output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true);
$textFormatter->display($output, $report);

$expected = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="Twig CS Fixer" tests="1" failures="0">
<testcase name="All OK">
</testcase>
</testsuite>
</testsuites>
EOD;

$text = $output->fetch();
static::assertStringContainsString($expected, $text);
}
}
22 changes: 22 additions & 0 deletions tests/Report/ReportTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ public function testReport(): void
$report->getMessages($file3)
);

static::assertSame(
[
$sniffViolation1,
$sniffViolation2,
$sniffViolation4,
$sniffViolation7,
$sniffViolation3,
$sniffViolation5,
$sniffViolation6,
],
$report->getAllMessages()
);

static::assertSame(
[$sniffViolation4, $sniffViolation7],
$report->getMessages($file, Report::MESSAGE_TYPE_ERROR)
Expand All @@ -81,6 +94,15 @@ public function testReport(): void
[$sniffViolation6],
$report->getMessages($file3, Report::MESSAGE_TYPE_ERROR)
);
static::assertSame(
[
$sniffViolation4,
$sniffViolation7,
$sniffViolation5,
$sniffViolation6,
],
$report->getAllMessages(Report::MESSAGE_TYPE_ERROR)
);
}

public function testAddMessageForAnotherFile(): void
Expand Down
2 changes: 2 additions & 0 deletions tests/Report/ReporterFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PHPUnit\Framework\TestCase;
use TwigCsFixer\Report\Reporter\CheckstyleReporter;
use TwigCsFixer\Report\Reporter\JUnitReporter;
use TwigCsFixer\Report\Reporter\NullReporter;
use TwigCsFixer\Report\Reporter\TextReporter;
use TwigCsFixer\Report\ReporterFactory;
Expand All @@ -20,6 +21,7 @@ public function testGetReporter(): void
static::assertInstanceOf(TextReporter::class, $reporterFactory->getReporter(TextReporter::NAME));
static::assertInstanceOf(NullReporter::class, $reporterFactory->getReporter(NullReporter::NAME));
static::assertInstanceOf(CheckstyleReporter::class, $reporterFactory->getReporter(CheckstyleReporter::NAME));
static::assertInstanceOf(JUnitReporter::class, $reporterFactory->getReporter(JUnitReporter::NAME));
}

public function testGetMessageForAnotherFile(): void
Expand Down

0 comments on commit cdfdccf

Please sign in to comment.