diff --git a/.gitignore b/.gitignore index 8c612a2a..0a4259fd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ .idea/* .env .phpunit.result.cache +.phpunit.cache/ /composer.lock -.php_cs.cache \ No newline at end of file +.php_cs.cache diff --git a/composer.json b/composer.json index 034bb647..02a57389 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "psr/simple-cache": "^1.0|^2.0|^3.0", "sebastian/diff": "^4.0|^5.0", "slevomat/coding-standard": "^7.0.8|^8.0", - "squizlabs/php_codesniffer": "^3.5", + "squizlabs/php_codesniffer": "^3.7", "symfony/cache": "^4.4|^5.0|^6.0", "symfony/console": "^4.2.12|^5.0|^6.0", "symfony/finder": "^4.2.12|^5.0|^6.0", diff --git a/phpunit.xml b/phpunit.xml index 1600bcd4..6c7af36e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,13 +1,14 @@ - - - - ./src - - + + ./tests + + + ./src + + diff --git a/src/Domain/Analyser.php b/src/Domain/Analyser.php index 32e2123e..9b5a38f5 100644 --- a/src/Domain/Analyser.php +++ b/src/Domain/Analyser.php @@ -177,9 +177,9 @@ private function analyseFile(Collector $collector, string $filename): void $collector->incrementInterfaces(); } elseif (isset($tokens[$i - 2]) && \is_array($tokens[$i - 2])) { - if ($tokens[$i - 2][0] === \T_ABSTRACT) { + if ($tokens[$i - 2][0] === \T_ABSTRACT || $tokens[$i - 2][0] === \T_READONLY && $tokens[$i - 4][0] === \T_ABSTRACT) { $collector->addAbstractClass($filename); - } elseif ($tokens[$i - 2][0] === \T_FINAL) { + } elseif ($tokens[$i - 2][0] === \T_FINAL || $tokens[$i - 2][0] === \T_READONLY && $tokens[$i - 4][0] === \T_FINAL) { $collector->addConcreteFinalClass($filename); } else { $collector->addConcreteNonFinalClass($filename); diff --git a/tests/Domain/Insights/Fixtures/ReadonlyClass.php b/tests/Domain/Insights/Fixtures/ReadonlyClass.php new file mode 100644 index 00000000..bad034c1 --- /dev/null +++ b/tests/Domain/Insights/Fixtures/ReadonlyClass.php @@ -0,0 +1,14 @@ +analyse([__DIR__ . '/Fixtures/'], $files, PathShortener::extractCommonPath($files)); + $insight = new ForbiddenNormalClasses($collector, []); + + self::assertTrue($insight->hasIssue()); + self::assertIsArray($insight->getDetails()); + self::assertNotEmpty($insight->getDetails()); + } + + public function testSkipFile(): void + { + $fileLocation = __DIR__ . '/Fixtures/ReadonlyClass.php'; + + $collection = $this->runAnalyserOnConfig( + [ + 'add' => [ + Classes::class => [ + ForbiddenNormalClasses::class, + ], + ], + 'config' => [ + ForbiddenNormalClasses::class => [ + 'exclude' => [$fileLocation], + ], + ], + ], + [$fileLocation] + ); + + $classErrors = 0; + + foreach ($collection->allFrom(new Classes()) as $insight) { + if ($insight->hasIssue() && $insight->getInsightClass() === ForbiddenNormalClasses::class) { + $classErrors++; + } + } + + self::assertEquals(0, $classErrors); + } +} diff --git a/tests/Domain/Insights/SyntaxCheckTest.php b/tests/Domain/Insights/SyntaxCheckTest.php index 44496330..abd02a16 100644 --- a/tests/Domain/Insights/SyntaxCheckTest.php +++ b/tests/Domain/Insights/SyntaxCheckTest.php @@ -49,10 +49,10 @@ public function testHasIssueOnDirectory(): void usort($details, static fn (Details $a, Details $b): int => $a->getFile() <=> $b->getFile()); self::assertTrue($insight->hasIssue()); - if (PHP_MAJOR_VERSION === 7) { - self::assertCount(2, $details); - } else { + if (PHP_MAJOR_VERSION === 7 || PHP_VERSION_ID >= 80200) { self::assertCount(3, $details); + } else { + self::assertCount(4, $details); } /** @var \NunoMaduro\PhpInsights\Domain\Details $detail */