diff --git a/composer.json b/composer.json
index ca9f405..afaa48a 100644
--- a/composer.json
+++ b/composer.json
@@ -24,7 +24,7 @@
"require-dev": {
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^8.5.14 || ^9.0",
- "squizlabs/php_codesniffer": "^3.3.1"
+ "squizlabs/php_codesniffer": "^3.5.0"
},
"autoload": {
"psr-4": {
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 0cf9d38..4d9ed81 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -15,4 +15,5 @@
src
tests
+ tests/_files/*
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index bb86c9e..7ff1558 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -4,5 +4,7 @@ parameters:
paths:
- src
- tests
+ excludePaths:
+ - tests/_files/
scanDirectories:
- vendor/squizlabs/php_codesniffer
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 6503d20..6c7186c 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -7,6 +7,12 @@
colors="true"
forceCoversAnnotation="true"
>
+
+
+
+
+
+
tests
diff --git a/src/Report/Gitlab.php b/src/Report/Gitlab.php
index 156ed8f..3a511fc 100644
--- a/src/Report/Gitlab.php
+++ b/src/Report/Gitlab.php
@@ -11,8 +11,11 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Reports\Report;
+use SplFileObject;
+use function is_string;
use function md5;
+use function preg_replace;
use function rtrim;
use function str_replace;
@@ -26,15 +29,25 @@ class Gitlab implements Report
public function generateFileReport($report, File $phpcsFile, $showSources = false, $width = 80)
{
$hasOutput = false;
+ $fingerprints = [];
foreach ($report['messages'] as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
+ $lineContent = $this->getContentOfLine($phpcsFile->getFilename(), $line);
+
+ foreach ($lineErrors as $colErrors) {
foreach ($colErrors as $error) {
+ $fingerprint = md5($report['filename'] . $lineContent . $error['source']);
+ if (isset($fingerprints[$fingerprint])) {
+ ++$fingerprints[$fingerprint];
+ } else {
+ $fingerprints[$fingerprint] = 1;
+ }
+
$issue = [
'type' => 'issue',
'categories' => ['Style'],
'check_name' => $error['source'],
- 'fingerprint' => md5($report['filename'] . $error['message'] . $line . $column),
+ 'fingerprint' => $fingerprint . '-' . $fingerprints[$fingerprint],
'severity' => $error['type'] === 'ERROR' ? 'major' : 'minor',
'description' => str_replace(["\n", "\r", "\t"], ['\n', '\r', '\t'], $error['message']),
'location' => [
@@ -68,4 +81,25 @@ public function generate(
) {
echo '[' . rtrim($cachedData, ',') . ']' . PHP_EOL;
}
+
+ /**
+ * @param string $filename
+ * @param int $line
+ * @return string
+ */
+ private function getContentOfLine($filename, $line)
+ {
+ $file = new SplFileObject($filename);
+
+ if (!$file->eof()) {
+ $file->seek($line - 1);
+ $contents = $file->current();
+
+ if (is_string($contents)) {
+ return (string) preg_replace('/\s+/', '', $contents);
+ }
+ }
+
+ return '';
+ }
}
diff --git a/tests/Fixtures/MixedViolations.php b/tests/Fixtures/MixedViolations.php
deleted file mode 100644
index ec307b0..0000000
--- a/tests/Fixtures/MixedViolations.php
+++ /dev/null
@@ -1,52 +0,0 @@
-
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD-3-Clause License
- */
-
-declare(strict_types=1);
-
-namespace MichehTest\PhpCodeSniffer\Fixtures;
-
-class MixedViolations implements ReportFixture
-{
- public function getReportData(): array
- {
- return [
- 'filename' => 'tests/Report/GitlabTest.php',
- 'errors' => 1,
- 'warnings' => 1,
- 'fixable' => 1,
- 'messages' => [
- 23 => [
- 32 => [
- 0 => [
- 'message' => 'There must be a single space between the colon and type in a return type declaration',
- 'source' => 'PSR12.Functions.ReturnTypeDeclaration.SpaceBeforeReturnType',
- 'severity' => 5,
- 'fixable' => true,
- 'type' => 'ERROR',
- ],
- ],
- ],
- 34 => [
- 9 => [
- 0 => [
- 'message' => 'Line exceeds 120 characters; contains 124 characters',
- 'source' => 'Generic.Files.LineLength.TooLong',
- 'severity' => 5,
- 'fixable' => false,
- 'type' => 'WARNING',
- ],
- ],
- ],
- ],
- ];
- }
-
- public function getExpectedOutput(): string
- {
- return '{"type":"issue","categories":["Style"],"check_name":"PSR12.Functions.ReturnTypeDeclaration.SpaceBeforeReturnType","fingerprint":"766bf1f7eff186fd667447bfb0291078","severity":"major","description":"There must be a single space between the colon and type in a return type declaration","location":{"path":"tests/Report/GitlabTest.php","lines":{"begin":23,"end":23}}},{"type":"issue","categories":["Style"],"check_name":"Generic.Files.LineLength.TooLong","fingerprint":"517eda4b85a33cd09fc933259f873191","severity":"minor","description":"Line exceeds 120 characters; contains 124 characters","location":{"path":"tests/Report/GitlabTest.php","lines":{"begin":34,"end":34}}},';
- }
-}
diff --git a/tests/Fixtures/ReportFixture.php b/tests/Fixtures/ReportFixture.php
deleted file mode 100644
index eba6ae6..0000000
--- a/tests/Fixtures/ReportFixture.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD-3-Clause License
- */
-
-declare(strict_types=1);
-
-namespace MichehTest\PhpCodeSniffer\Fixtures;
-
-interface ReportFixture
-{
- /**
- * @return array{filename: string, errors: int, warnings: int, fixable: int, messages: array}
- */
- public function getReportData(): array;
-
- public function getExpectedOutput(): string;
-}
diff --git a/tests/Fixtures/SingleViolation.php b/tests/Fixtures/SingleViolation.php
deleted file mode 100644
index 7768434..0000000
--- a/tests/Fixtures/SingleViolation.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD-3-Clause License
- */
-
-declare(strict_types=1);
-
-namespace MichehTest\PhpCodeSniffer\Fixtures;
-
-class SingleViolation implements ReportFixture
-{
- public function getReportData(): array
- {
- return [
- 'filename' => 'src/Report/Gitlab.php',
- 'errors' => 1,
- 'warnings' => 0,
- 'fixable' => 1,
- 'messages' => [
- 18 => [
- 25 => [
- 0 => [
- 'message' => 'Header blocks must not contain blank lines',
- 'source' => 'PSR12.Files.FileHeader.SpacingInsideBlock',
- 'severity' => 5,
- 'fixable' => true,
- 'type' => 'ERROR',
- ],
- ],
- ],
- ],
- ];
- }
-
- public function getExpectedOutput(): string
- {
- return '{"type":"issue","categories":["Style"],"check_name":"PSR12.Files.FileHeader.SpacingInsideBlock","fingerprint":"21f4cd5b7d88d9eb67402be5d56caa8b","severity":"major","description":"Header blocks must not contain blank lines","location":{"path":"src/Report/Gitlab.php","lines":{"begin":18,"end":18}}},';
- }
-}
diff --git a/tests/Report/GitlabTest.php b/tests/Report/GitlabTest.php
index a6e4663..ebe2e26 100644
--- a/tests/Report/GitlabTest.php
+++ b/tests/Report/GitlabTest.php
@@ -10,12 +10,16 @@
namespace MichehTest\PhpCodeSniffer\Report;
use Micheh\PhpCodeSniffer\Report\Gitlab;
-use MichehTest\PhpCodeSniffer\Fixtures\MixedViolations;
-use MichehTest\PhpCodeSniffer\Fixtures\ReportFixture;
-use MichehTest\PhpCodeSniffer\Fixtures\SingleViolation;
+use PHP_CodeSniffer\Config;
use PHP_CodeSniffer\Files\File;
+use PHP_CodeSniffer\Files\LocalFile;
+use PHP_CodeSniffer\Reporter;
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Runner;
use PHPUnit\Framework\TestCase;
+use function file_get_contents;
+
class GitlabTest extends TestCase
{
/**
@@ -23,6 +27,22 @@ class GitlabTest extends TestCase
*/
private $report;
+ /**
+ * @var Config
+ */
+ private static $config;
+
+
+ public static function setUpBeforeClass(): void
+ {
+ self::$config = new Config();
+ self::$config->basepath = __DIR__ . '/../';
+ self::$config->standards = ['PSR12'];
+
+ $runner = new Runner();
+ $runner->config = self::$config;
+ $runner->init();
+ }
protected function setUp(): void
{
@@ -48,27 +68,49 @@ public function testGenerateWithEmpty(): void
}
/**
- * @return array>>
+ * @return array>
*/
public function violations(): array
{
return [
- 'single' => [SingleViolation::class],
- 'mixed' => [MixedViolations::class],
+ 'single' => ['Single'],
+ 'mixed' => ['Mixed'],
+ 'multiple' => ['Multiple'],
];
}
/**
- * @param class-string $class
* @covers \Micheh\PhpCodeSniffer\Report\Gitlab::generateFileReport
* @dataProvider violations
*/
- public function testGenerateFileReport(string $class): void
+ public function testGenerateFileReport(string $fileName): void
{
- $fixture = new $class();
- self::assertInstanceOf(ReportFixture::class, $fixture);
+ $phpPath = __DIR__ . '/../_files/' . $fileName . '.php';
+ self::assertFileExists($phpPath);
+
+ $outputPath = __DIR__ . '/../_files/' . $fileName . '.json';
+ self::assertFileExists($outputPath);
+
+ $file = $this->createFile($phpPath);
- $this->expectOutputString($fixture->getExpectedOutput());
- $this->report->generateFileReport($fixture->getReportData(), $this->createMock(File::class));
+ $this->expectOutputString((string) file_get_contents($outputPath));
+ $this->report->generateFileReport($this->getReportData($file), $file);
+ }
+
+ private function createFile(string $path): File
+ {
+ $file = new LocalFile($path, new Ruleset(self::$config), self::$config);
+ $file->process();
+
+ return $file;
+ }
+
+ /**
+ * @return array{filename: string, errors: int, warnings: int, fixable: int, messages: array}
+ */
+ private function getReportData(File $file): array
+ {
+ $reporter = new Reporter(self::$config);
+ return $reporter->prepareFileReport($file); // @phpstan-ignore return.type
}
}
diff --git a/tests/_files/Mixed.json b/tests/_files/Mixed.json
new file mode 100644
index 0000000..4c17192
--- /dev/null
+++ b/tests/_files/Mixed.json
@@ -0,0 +1 @@
+{"type":"issue","categories":["Style"],"check_name":"Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine","fingerprint":"0da49d5a2f6b30f151e4abef2fccd4e2-1","severity":"major","description":"Opening brace should be on a new line","location":{"path":"_files/Mixed.php","lines":{"begin":7,"end":7}}},{"type":"issue","categories":["Style"],"check_name":"Generic.Files.LineLength.TooLong","fingerprint":"0be4b9620fcab36dcef7ba50bd3ac097-1","severity":"minor","description":"Line exceeds 120 characters; contains 143 characters","location":{"path":"_files/Mixed.php","lines":{"begin":8,"end":8}}},
\ No newline at end of file
diff --git a/tests/_files/Mixed.php b/tests/_files/Mixed.php
new file mode 100644
index 0000000..08338e4
--- /dev/null
+++ b/tests/_files/Mixed.php
@@ -0,0 +1,10 @@
+