From 165054c78b22446a04d95d94c80ccaeeb6508dfd Mon Sep 17 00:00:00 2001 From: Mark Scherer Date: Thu, 6 Aug 2026 13:12:52 +0200 Subject: [PATCH] Add smoke tests for ten untested fixing sniffs The standard ships 86 sniffs against 38 test classes, and the gap is worst where it hurts most: sniffs that rewrite source. A fixer nobody exercises can break without anything noticing, which is exactly how VoidCast and PipeOperatorSpacing came to match nothing at all on PHP 8.5 from the day they were written. Covers the ten heaviest rewriters by fixable-error count: TernarySpacing, DocBlockTagGrouping, DocComment, ControlStructureSpacing, ConcatenationSpacing, Mock, MethodDeclaration, ImplicitCastSpacing, FunctionSpacing and DocBlockStructure. Each fixture triggers the distinct error codes its sniff can emit and also carries constructs the sniff has to leave alone, so an over-eager matcher fails the test rather than passing it quietly. No sniff behavior changes here. Where a fixture documents something that looks wrong, it asserts what the sniff does today rather than what it arguably should; those are followed up separately. 128 tests, up from 108. --- .../Classes/MethodDeclarationSniffTest.php | 30 +++++++ .../Commenting/DocBlockStructureSniffTest.php | 30 +++++++ .../DocBlockTagGroupingSniffTest.php | 30 +++++++ .../Sniffs/Commenting/DocCommentSniffTest.php | 30 +++++++ .../ControlStructureSpacingSniffTest.php | 30 +++++++ .../Sniffs/Testing/MockSniffTest.php | 53 +++++++++++++ .../ConcatenationSpacingSniffTest.php | 30 +++++++ .../WhiteSpace/FunctionSpacingSniffTest.php | 30 +++++++ .../ImplicitCastSpacingSniffTest.php | 30 +++++++ .../WhiteSpace/TernarySpacingSniffTest.php | 30 +++++++ tests/_data/ConcatenationSpacing/after.php | 22 ++++++ tests/_data/ConcatenationSpacing/before.php | 22 ++++++ tests/_data/ControlStructureSpacing/after.php | 29 +++++++ .../_data/ControlStructureSpacing/before.php | 32 ++++++++ tests/_data/DocBlockStructure/after.php | 31 ++++++++ tests/_data/DocBlockStructure/before.php | 30 +++++++ tests/_data/DocBlockTagGrouping/after.php | 78 +++++++++++++++++++ tests/_data/DocBlockTagGrouping/before.php | 77 ++++++++++++++++++ tests/_data/DocComment/after.php | 47 +++++++++++ tests/_data/DocComment/before.php | 47 +++++++++++ tests/_data/FunctionSpacing/after.php | 39 ++++++++++ tests/_data/FunctionSpacing/before.php | 37 +++++++++ tests/_data/ImplicitCastSpacing/after.php | 24 ++++++ tests/_data/ImplicitCastSpacing/before.php | 24 ++++++ tests/_data/MethodDeclaration/after.php | 26 +++++++ tests/_data/MethodDeclaration/before.php | 26 +++++++ tests/_data/Mock/after.php | 75 ++++++++++++++++++ tests/_data/Mock/before.php | 75 ++++++++++++++++++ tests/_data/TernarySpacing/after.php | 27 +++++++ tests/_data/TernarySpacing/before.php | 27 +++++++ 30 files changed, 1118 insertions(+) create mode 100644 tests/PhpCollective/Sniffs/Classes/MethodDeclarationSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/Commenting/DocBlockStructureSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/Commenting/DocBlockTagGroupingSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/Commenting/DocCommentSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/ControlStructures/ControlStructureSpacingSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/Testing/MockSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/WhiteSpace/ConcatenationSpacingSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/WhiteSpace/FunctionSpacingSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/WhiteSpace/ImplicitCastSpacingSniffTest.php create mode 100644 tests/PhpCollective/Sniffs/WhiteSpace/TernarySpacingSniffTest.php create mode 100644 tests/_data/ConcatenationSpacing/after.php create mode 100644 tests/_data/ConcatenationSpacing/before.php create mode 100644 tests/_data/ControlStructureSpacing/after.php create mode 100644 tests/_data/ControlStructureSpacing/before.php create mode 100644 tests/_data/DocBlockStructure/after.php create mode 100644 tests/_data/DocBlockStructure/before.php create mode 100644 tests/_data/DocBlockTagGrouping/after.php create mode 100644 tests/_data/DocBlockTagGrouping/before.php create mode 100644 tests/_data/DocComment/after.php create mode 100644 tests/_data/DocComment/before.php create mode 100644 tests/_data/FunctionSpacing/after.php create mode 100644 tests/_data/FunctionSpacing/before.php create mode 100644 tests/_data/ImplicitCastSpacing/after.php create mode 100644 tests/_data/ImplicitCastSpacing/before.php create mode 100644 tests/_data/MethodDeclaration/after.php create mode 100644 tests/_data/MethodDeclaration/before.php create mode 100644 tests/_data/Mock/after.php create mode 100644 tests/_data/Mock/before.php create mode 100644 tests/_data/TernarySpacing/after.php create mode 100644 tests/_data/TernarySpacing/before.php diff --git a/tests/PhpCollective/Sniffs/Classes/MethodDeclarationSniffTest.php b/tests/PhpCollective/Sniffs/Classes/MethodDeclarationSniffTest.php new file mode 100644 index 0000000..e21e882 --- /dev/null +++ b/tests/PhpCollective/Sniffs/Classes/MethodDeclarationSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new MethodDeclarationSniff(), 5, 4); + } + + /** + * @return void + */ + public function testMethodDeclarationFixer(): void + { + $this->assertSnifferCanFixErrors(new MethodDeclarationSniff(), 4); + } +} diff --git a/tests/PhpCollective/Sniffs/Commenting/DocBlockStructureSniffTest.php b/tests/PhpCollective/Sniffs/Commenting/DocBlockStructureSniffTest.php new file mode 100644 index 0000000..35ec887 --- /dev/null +++ b/tests/PhpCollective/Sniffs/Commenting/DocBlockStructureSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new DocBlockStructureSniff(), 3, 3); + } + + /** + * @return void + */ + public function testDocBlockStructureFixer(): void + { + $this->assertSnifferCanFixErrors(new DocBlockStructureSniff(), 3); + } +} diff --git a/tests/PhpCollective/Sniffs/Commenting/DocBlockTagGroupingSniffTest.php b/tests/PhpCollective/Sniffs/Commenting/DocBlockTagGroupingSniffTest.php new file mode 100644 index 0000000..b194fe7 --- /dev/null +++ b/tests/PhpCollective/Sniffs/Commenting/DocBlockTagGroupingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new DocBlockTagGroupingSniff(), 6, 6); + } + + /** + * @return void + */ + public function testDocBlockTagGroupingFixer(): void + { + $this->assertSnifferCanFixErrors(new DocBlockTagGroupingSniff(), 6); + } +} diff --git a/tests/PhpCollective/Sniffs/Commenting/DocCommentSniffTest.php b/tests/PhpCollective/Sniffs/Commenting/DocCommentSniffTest.php new file mode 100644 index 0000000..0e4f159 --- /dev/null +++ b/tests/PhpCollective/Sniffs/Commenting/DocCommentSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new DocCommentSniff(), 4, 4); + } + + /** + * @return void + */ + public function testDocCommentFixer(): void + { + $this->assertSnifferCanFixErrors(new DocCommentSniff(), 4); + } +} diff --git a/tests/PhpCollective/Sniffs/ControlStructures/ControlStructureSpacingSniffTest.php b/tests/PhpCollective/Sniffs/ControlStructures/ControlStructureSpacingSniffTest.php new file mode 100644 index 0000000..9e68192 --- /dev/null +++ b/tests/PhpCollective/Sniffs/ControlStructures/ControlStructureSpacingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new ControlStructureSpacingSniff(), 6, 6); + } + + /** + * @return void + */ + public function testControlStructureSpacingFixer(): void + { + $this->assertSnifferCanFixErrors(new ControlStructureSpacingSniff(), 6); + } +} diff --git a/tests/PhpCollective/Sniffs/Testing/MockSniffTest.php b/tests/PhpCollective/Sniffs/Testing/MockSniffTest.php new file mode 100644 index 0000000..4eb9ecc --- /dev/null +++ b/tests/PhpCollective/Sniffs/Testing/MockSniffTest.php @@ -0,0 +1,53 @@ +assertSnifferFindsFixableErrors(new MockSniff(), 6, 4); + } + + /** + * @return void + */ + public function testMockFixer(): void + { + $this->assertSnifferCanFixErrors(new MockSniff(), 4); + } + + /** + * @param \PHP_CodeSniffer\Sniffs\Sniff $sniffer + * + * @return string + */ + protected function getDummyFileBefore(Sniff $sniffer): string + { + $fixture = parent::getDummyFileBefore($sniffer); + $target = TMP . 'MockSniffFixtureTest.php'; + + if (!is_dir(TMP)) { + mkdir(TMP, 0770, true); + } + + $contents = file_get_contents($fixture); + $this->assertIsString($contents); + $result = file_put_contents($target, $contents); + $this->assertIsInt($result); + + return $target; + } +} diff --git a/tests/PhpCollective/Sniffs/WhiteSpace/ConcatenationSpacingSniffTest.php b/tests/PhpCollective/Sniffs/WhiteSpace/ConcatenationSpacingSniffTest.php new file mode 100644 index 0000000..4a9229e --- /dev/null +++ b/tests/PhpCollective/Sniffs/WhiteSpace/ConcatenationSpacingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new ConcatenationSpacingSniff(), 4, 4); + } + + /** + * @return void + */ + public function testConcatenationSpacingFixer(): void + { + $this->assertSnifferCanFixErrors(new ConcatenationSpacingSniff(), 4); + } +} diff --git a/tests/PhpCollective/Sniffs/WhiteSpace/FunctionSpacingSniffTest.php b/tests/PhpCollective/Sniffs/WhiteSpace/FunctionSpacingSniffTest.php new file mode 100644 index 0000000..ff4a0a4 --- /dev/null +++ b/tests/PhpCollective/Sniffs/WhiteSpace/FunctionSpacingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new FunctionSpacingSniff(), 2, 2); + } + + /** + * @return void + */ + public function testFunctionSpacingFixer(): void + { + $this->assertSnifferCanFixErrors(new FunctionSpacingSniff(), 2); + } +} diff --git a/tests/PhpCollective/Sniffs/WhiteSpace/ImplicitCastSpacingSniffTest.php b/tests/PhpCollective/Sniffs/WhiteSpace/ImplicitCastSpacingSniffTest.php new file mode 100644 index 0000000..0923db9 --- /dev/null +++ b/tests/PhpCollective/Sniffs/WhiteSpace/ImplicitCastSpacingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new ImplicitCastSpacingSniff(), 4, 4); + } + + /** + * @return void + */ + public function testImplicitCastSpacingFixer(): void + { + $this->assertSnifferCanFixErrors(new ImplicitCastSpacingSniff(), 4); + } +} diff --git a/tests/PhpCollective/Sniffs/WhiteSpace/TernarySpacingSniffTest.php b/tests/PhpCollective/Sniffs/WhiteSpace/TernarySpacingSniffTest.php new file mode 100644 index 0000000..35a872e --- /dev/null +++ b/tests/PhpCollective/Sniffs/WhiteSpace/TernarySpacingSniffTest.php @@ -0,0 +1,30 @@ +assertSnifferFindsFixableErrors(new TernarySpacingSniff(), 7, 7); + } + + /** + * @return void + */ + public function testTernarySpacingFixer(): void + { + $this->assertSnifferCanFixErrors(new TernarySpacingSniff(), 7); + } +} diff --git a/tests/_data/ConcatenationSpacing/after.php b/tests/_data/ConcatenationSpacing/after.php new file mode 100644 index 0000000..fe97e9b --- /dev/null +++ b/tests/_data/ConcatenationSpacing/after.php @@ -0,0 +1,22 @@ +createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function invalidTypehint() + { + return $this->createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function missingTypeHint(): Service + { + return $this->createMock(Service::class); + } + + /** + * @return Service|Repository|\PHPUnit\Framework\MockObject\MockObject + */ + public function complexMockMustNotHaveTypeHint(): Service + { + return $this->createMock(Service::class); + } + + /** + * @return \PHPUnit\Framework\MockObject\MockObject + */ + public function missingMockedClass() + { + return $this->createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function validMock(): Service + { + return $this->createMock(Service::class); + } + + /** + * @return RuntimeException + */ + public function nonMockReturnType(): RuntimeException + { + return new RuntimeException('valid'); + } +} + +class Service +{ +} + +class Repository +{ +} diff --git a/tests/_data/Mock/before.php b/tests/_data/Mock/before.php new file mode 100644 index 0000000..5d39eb7 --- /dev/null +++ b/tests/_data/Mock/before.php @@ -0,0 +1,75 @@ +createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function invalidTypehint(): MockObject + { + return $this->createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function missingTypeHint() + { + return $this->createMock(Service::class); + } + + /** + * @return Service|Repository|\PHPUnit\Framework\MockObject\MockObject + */ + public function complexMockMustNotHaveTypeHint(): Service + { + return $this->createMock(Service::class); + } + + /** + * @return \PHPUnit\Framework\MockObject\MockObject + */ + public function missingMockedClass() + { + return $this->createMock(Service::class); + } + + /** + * @return Service|\PHPUnit\Framework\MockObject\MockObject + */ + public function validMock(): Service + { + return $this->createMock(Service::class); + } + + /** + * @return RuntimeException + */ + public function nonMockReturnType(): RuntimeException + { + return new RuntimeException('valid'); + } +} + +class Service +{ +} + +class Repository +{ +} diff --git a/tests/_data/TernarySpacing/after.php b/tests/_data/TernarySpacing/after.php new file mode 100644 index 0000000..ce75cef --- /dev/null +++ b/tests/_data/TernarySpacing/after.php @@ -0,0 +1,27 @@ +