diff --git a/src/PHP_CodeSniffer/PhpCodeSnifferConvertToSubset.php b/src/PHP_CodeSniffer/PhpCodeSnifferConvertToSubset.php index 7424b10..d351191 100644 --- a/src/PHP_CodeSniffer/PhpCodeSnifferConvertToSubset.php +++ b/src/PHP_CodeSniffer/PhpCodeSnifferConvertToSubset.php @@ -23,6 +23,7 @@ public function convertToSubset(): void $filename, $node->line ), + 'severity' => $this->getSeverity($node->type), 'location' => [ 'path' => $filename, 'lines' => [ @@ -41,4 +42,10 @@ public function getToolName(): string { return 'PHP_CodeSniffer'; } + + private function getSeverity(string $type): string + { + // can be info, minor, major, critical, or blocker + return 'ERROR' === $type ? 'major' : 'minor'; + } } diff --git a/src/PHP_CodeSniffer/PhpCodeSnifferJsonValidator.php b/src/PHP_CodeSniffer/PhpCodeSnifferJsonValidator.php index d9f6d5c..2b49c65 100644 --- a/src/PHP_CodeSniffer/PhpCodeSnifferJsonValidator.php +++ b/src/PHP_CodeSniffer/PhpCodeSnifferJsonValidator.php @@ -28,6 +28,10 @@ public function validateJson(): void if (!property_exists($node, 'line')) { throw new InvalidJsonException('The [files.messages.line] is a required property'); } + + if (!property_exists($node, 'type')) { + throw new InvalidJsonException('The [files.messages.type] is a required property'); + } } } } diff --git a/src/Psalm/PsalmConvertToSubset.php b/src/Psalm/PsalmConvertToSubset.php index 0771fd7..9f7a8d0 100644 --- a/src/Psalm/PsalmConvertToSubset.php +++ b/src/Psalm/PsalmConvertToSubset.php @@ -22,6 +22,7 @@ public function convertToSubset(): void $node->file_name, $node->line_from ), + 'severity' => $this->getSeverity($node->severity), 'location' => [ 'path' => $node->file_name, 'lines' => [ @@ -40,4 +41,10 @@ public function getToolName(): string { return 'Psalm'; } + + private function getSeverity(string $severity): string + { + // can be info, minor, major, critical, or blocker + return 'error' === $severity ? 'major' : 'minor'; + } } diff --git a/src/Psalm/PsalmJsonValidator.php b/src/Psalm/PsalmJsonValidator.php index 6d55e6d..2cf58ab 100644 --- a/src/Psalm/PsalmJsonValidator.php +++ b/src/Psalm/PsalmJsonValidator.php @@ -27,6 +27,10 @@ public function validateJson(): void if (!property_exists($node, 'line_to')) { throw new InvalidJsonException('The [line_to] is a required property'); } + + if (!property_exists($node, 'severity')) { + throw new InvalidJsonException('The [severity] is a required property'); + } } } } diff --git a/tests/PHP_CodeSniffer/PhpCodeSnifferConverterTest.php b/tests/PHP_CodeSniffer/PhpCodeSnifferConverterTest.php index 5cdb22f..222ca51 100644 --- a/tests/PHP_CodeSniffer/PhpCodeSnifferConverterTest.php +++ b/tests/PHP_CodeSniffer/PhpCodeSnifferConverterTest.php @@ -7,6 +7,8 @@ use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ConverterFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ValidatorFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Tests\TestCase; +use function file_get_contents; +use function json_decode; /** * @internal @@ -40,6 +42,7 @@ public function testItCanConvertPhpCodeSnifferJsonToSubset(): void [ 'description' => '(PHP_CodeSniffer) Missing file doc comment', 'fingerprint' => 'fa33b2f8044e0f23de6b53f15d4d7bc9', + 'severity' => 'major', 'location' => [ 'path' => 'app/Class.php', 'lines' => [ diff --git a/tests/PHP_CodeSniffer/PhpCodeSnifferValidationTest.php b/tests/PHP_CodeSniffer/PhpCodeSnifferValidationTest.php index b588951..f141b7c 100644 --- a/tests/PHP_CodeSniffer/PhpCodeSnifferValidationTest.php +++ b/tests/PHP_CodeSniffer/PhpCodeSnifferValidationTest.php @@ -8,13 +8,15 @@ use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ConverterFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ValidatorFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Tests\TestCase; +use function file_get_contents; +use function json_decode; /** * @internal */ class PhpCodeSnifferValidationTest extends TestCase { - public function testItThrowsAnExceptionWhenFilesPropertyIsMissing() + public function testItThrowsAnExceptionWhenFilesPropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [files] is a required property'); @@ -39,7 +41,7 @@ public function testItThrowsAnExceptionWhenFilesPropertyIsMissing() $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenFilesMessagesPropertyIsMissing() + public function testItThrowsAnExceptionWhenFilesMessagesPropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [files.messages] is a required property'); @@ -64,7 +66,7 @@ public function testItThrowsAnExceptionWhenFilesMessagesPropertyIsMissing() $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenFilesMessagesMessagePropertyIsMissing() + public function testItThrowsAnExceptionWhenFilesMessagesMessagePropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [files.messages.message] is a required property'); @@ -89,7 +91,7 @@ public function testItThrowsAnExceptionWhenFilesMessagesMessagePropertyIsMissing $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenFilesMessagesLinePropertyIsMissing() + public function testItThrowsAnExceptionWhenFilesMessagesLinePropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [files.messages.line] is a required property'); @@ -113,4 +115,29 @@ public function testItThrowsAnExceptionWhenFilesMessagesLinePropertyIsMissing() // When $converterImplementation->convertToSubset(); } + + public function testItThrowsAnExceptionWhenFilesTypePropertyIsMissing(): void + { + $this->expectException(InvalidJsonException::class); + $this->expectErrorMessage('The [files.messages.type] is a required property'); + + // Given + $jsonInput = file_get_contents(__DIR__.'/fixtures/invalid-files-messages-type-input.json'); + $jsonDecodedInput = json_decode($jsonInput); + + $validatorFactory = new ValidatorFactory(); + + $validator = $validatorFactory->build('PHP_CodeSniffer', $jsonDecodedInput); + + $converterFactory = new ConverterFactory(); + + $converterImplementation = $converterFactory->build( + 'PHP_CodeSniffer', + $validator, + $jsonDecodedInput + ); + + // When + $converterImplementation->convertToSubset(); + } } diff --git a/tests/PHP_CodeSniffer/fixtures/invalid-files-messages-type-input.json b/tests/PHP_CodeSniffer/fixtures/invalid-files-messages-type-input.json new file mode 100644 index 0000000..cb0a824 --- /dev/null +++ b/tests/PHP_CodeSniffer/fixtures/invalid-files-messages-type-input.json @@ -0,0 +1,23 @@ +{ + "totals": { + "errors": 1, + "warnings": 0, + "fixable": 0 + }, + "files": { + "app\/Class.php": { + "errors": 1, + "warnings": 0, + "messages": [ + { + "message": "Missing file doc comment", + "source": "PEAR.Commenting.FileComment.Missing", + "severity": 5, + "fixable": false, + "line": 2, + "column": 1 + } + ] + } + } +} \ No newline at end of file diff --git a/tests/PHP_CodeSniffer/fixtures/output.json b/tests/PHP_CodeSniffer/fixtures/output.json index 85dd87a..86b9bfa 100644 --- a/tests/PHP_CodeSniffer/fixtures/output.json +++ b/tests/PHP_CodeSniffer/fixtures/output.json @@ -2,6 +2,7 @@ { "description": "(PHP_CodeSniffer) Missing file doc comment", "fingerprint": "fa33b2f8044e0f23de6b53f15d4d7bc9", + "severity": "major", "location": { "path": "app/Class.php", "lines": { diff --git a/tests/Psalm/PsalmConverterTest.php b/tests/Psalm/PsalmConverterTest.php index bb0797e..05f840c 100644 --- a/tests/Psalm/PsalmConverterTest.php +++ b/tests/Psalm/PsalmConverterTest.php @@ -7,6 +7,8 @@ use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ConverterFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ValidatorFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Tests\TestCase; +use function file_get_contents; +use function json_decode; /** * @internal @@ -40,6 +42,7 @@ public function testItCanConvertPsalmJsonToSubset(): void [ 'description' => '(Psalm) Property Illuminate\\Foundation\\Console\\Kernel::$artisan is not defined in constructor of App\\Console\\Kernel and in any methods called in the constructor', 'fingerprint' => '206df1cdb86fc7fc14b049a658832473', + 'severity' => 'minor', 'location' => [ 'path' => 'app/Class.php', 'lines' => [ diff --git a/tests/Psalm/PsalmValidationTest.php b/tests/Psalm/PsalmValidationTest.php index fef174e..9be87d0 100644 --- a/tests/Psalm/PsalmValidationTest.php +++ b/tests/Psalm/PsalmValidationTest.php @@ -8,13 +8,15 @@ use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ConverterFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Factories\ValidatorFactory; use BeechIt\JsonToCodeClimateSubsetConverter\Tests\TestCase; +use function file_get_contents; +use function json_decode; /** * @internal */ class PsalmValidationTest extends TestCase { - public function testItThrowsAnExceptionWhenDescriptionPropertyIsMissing() + public function testItThrowsAnExceptionWhenDescriptionPropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [message] is a required property'); @@ -39,7 +41,7 @@ public function testItThrowsAnExceptionWhenDescriptionPropertyIsMissing() $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenFileNamePropertyIsMissing() + public function testItThrowsAnExceptionWhenFileNamePropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [file_name] is a required property'); @@ -64,7 +66,7 @@ public function testItThrowsAnExceptionWhenFileNamePropertyIsMissing() $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenLineFromPropertyIsMissing() + public function testItThrowsAnExceptionWhenLineFromPropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [line_from] is a required property'); @@ -89,7 +91,7 @@ public function testItThrowsAnExceptionWhenLineFromPropertyIsMissing() $converterImplementation->convertToSubset(); } - public function testItThrowsAnExceptionWhenLineToPropertyIsMissing() + public function testItThrowsAnExceptionWhenLineToPropertyIsMissing(): void { $this->expectException(InvalidJsonException::class); $this->expectErrorMessage('The [line_to] is a required property'); @@ -113,4 +115,29 @@ public function testItThrowsAnExceptionWhenLineToPropertyIsMissing() // When $converterImplementation->convertToSubset(); } + + public function testItThrowsAnExceptionWhenSeverityPropertyIsMissing(): void + { + $this->expectException(InvalidJsonException::class); + $this->expectErrorMessage('The [severity] is a required property'); + + // Given + $jsonInput = file_get_contents(__DIR__.'/fixtures/invalid-severity-input.json'); + $jsonDecodedInput = json_decode($jsonInput); + + $validatorFactory = new ValidatorFactory(); + + $validator = $validatorFactory->build('Psalm', $jsonDecodedInput); + + $converterFactory = new ConverterFactory(); + + $converterImplementation = $converterFactory->build( + 'Psalm', + $validator, + $jsonDecodedInput + ); + + // When + $converterImplementation->convertToSubset(); + } } diff --git a/tests/Psalm/fixtures/invalid-severity-input.json b/tests/Psalm/fixtures/invalid-severity-input.json new file mode 100644 index 0000000..33892b9 --- /dev/null +++ b/tests/Psalm/fixtures/invalid-severity-input.json @@ -0,0 +1,18 @@ +[ + { + "line_from": 2, + "line_to": 2, + "type": "PropertyNotSetInConstructor", + "message": "Property Illuminate\\Foundation\\Console\\Kernel::$artisan is not defined in constructor of App\\Console\\Kernel and in any methods called in the constructor", + "file_name": "app\/Class.php", + "file_path": "\/var\/www\/html\/app\/Console\/Kernel.php", + "snippet": "class Kernel extends ConsoleKernel", + "selected_text": "Kernel", + "from": 141, + "to": 147, + "snippet_from": 135, + "snippet_to": 169, + "column_from": 7, + "column_to": 13 + } +] \ No newline at end of file diff --git a/tests/Psalm/fixtures/output.json b/tests/Psalm/fixtures/output.json index 53480c2..9f83c26 100644 --- a/tests/Psalm/fixtures/output.json +++ b/tests/Psalm/fixtures/output.json @@ -2,6 +2,7 @@ { "description": "(Psalm) Property Illuminate\\Foundation\\Console\\Kernel::$artisan is not defined in constructor of App\\Console\\Kernel and in any methods called in the constructor", "fingerprint": "206df1cdb86fc7fc14b049a658832473", + "severity": "minor", "location": { "path": "app/Class.php", "lines": { diff --git a/tests/TestCase.php b/tests/TestCase.php index bbc923d..51e236b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -52,6 +52,7 @@ public function multipleConvertersProvider(): array 'output' => [ 'description' => '(PHP_CodeSniffer) Missing file doc comment', 'fingerprint' => 'fa33b2f8044e0f23de6b53f15d4d7bc9', + 'severity' => 'major', 'location' => [ 'path' => 'app/Class.php', 'lines' => [ @@ -103,6 +104,7 @@ public function multipleConvertersProvider(): array 'output' => [ 'description' => '(Psalm) Property Illuminate\\Foundation\\Console\\Kernel::$artisan is not defined in constructor of App\\Console\\Kernel and in any methods called in the constructor', 'fingerprint' => '206df1cdb86fc7fc14b049a658832473', + 'severity' => 'minor', 'location' => [ 'path' => 'app/Class.php', 'lines' => [ diff --git a/tests/fixtures/output.json b/tests/fixtures/output.json index cd85bec..c0b7306 100644 --- a/tests/fixtures/output.json +++ b/tests/fixtures/output.json @@ -13,6 +13,7 @@ { "description": "(PHP_CodeSniffer) Missing file doc comment", "fingerprint": "fa33b2f8044e0f23de6b53f15d4d7bc9", + "severity": "major", "location": { "path": "app/Class.php", "lines": { @@ -43,6 +44,7 @@ { "description": "(Psalm) Property Illuminate\\Foundation\\Console\\Kernel::$artisan is not defined in constructor of App\\Console\\Kernel and in any methods called in the constructor", "fingerprint": "206df1cdb86fc7fc14b049a658832473", + "severity": "minor", "location": { "path": "app/Class.php", "lines": {