From cd2fea55713bb4d4aefdd27b1e7a19467600a7bd Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 31 May 2024 17:49:47 +0900 Subject: [PATCH] add test for ClassConstantResultAnalyser, fix regex message --- src/Command/PrivatizeConstantsCommand.php | 4 +- src/PHPStan/ClassConstantResultAnalyser.php | 14 +++++- src/ValueObject/ClassConstMatch.php | 3 ++ .../PublicAndProtectedClassConstants.php | 22 ++++----- .../ClassConstantResultAnalyserTest.php | 47 +++++++++++++++++++ 5 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 tests/PHPStan/ClassConstantResultAnalyserTest.php diff --git a/src/Command/PrivatizeConstantsCommand.php b/src/Command/PrivatizeConstantsCommand.php index 32390f632..1e84aacfb 100644 --- a/src/Command/PrivatizeConstantsCommand.php +++ b/src/Command/PrivatizeConstantsCommand.php @@ -85,11 +85,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int } // make public first, to avoid override to protected - foreach ($publicAndProtectedClassConstants->getPublicClassConstMatch() as $publicClassConstMatch) { + foreach ($publicAndProtectedClassConstants->getPublicClassConstMatches() as $publicClassConstMatch) { $this->replacePrivateConstWith($publicClassConstMatch, 'public const'); } - foreach ($publicAndProtectedClassConstants->getProtectedClassConstMatch() as $publicClassConstMatch) { + foreach ($publicAndProtectedClassConstants->getProtectedClassConstMatches() as $publicClassConstMatch) { $this->replacePrivateConstWith($publicClassConstMatch, 'protected const'); } diff --git a/src/PHPStan/ClassConstantResultAnalyser.php b/src/PHPStan/ClassConstantResultAnalyser.php index d1be11a2d..23c6bcda0 100644 --- a/src/PHPStan/ClassConstantResultAnalyser.php +++ b/src/PHPStan/ClassConstantResultAnalyser.php @@ -7,7 +7,11 @@ use Nette\Utils\Strings; use Rector\SwissKnife\ValueObject\ClassConstMatch; use Rector\SwissKnife\ValueObject\PublicAndProtectedClassConstants; +use Webmozart\Assert\Assert; +/** + * @see \Rector\SwissKnife\Tests\PHPStan\ClassConstantResultAnalyserTest + */ final class ClassConstantResultAnalyser { /** @@ -18,9 +22,9 @@ final class ClassConstantResultAnalyser /** * @var string - * @see https://regex101.com/r/pRzdnw/1 + * @see https://regex101.com/r/V1QOPN/1 */ - private const PROTECTED_CONSTANT_MESSAGE_REGEX = '#Access to undefined constant (?[\w\\\\]+)::(?.*?)#'; + private const PROTECTED_CONSTANT_MESSAGE_REGEX = '#Access to undefined constant (?[\w\\\\]+)::(?[\w\_]+)#'; /** * @param mixed[] $phpstanResult @@ -30,8 +34,14 @@ public function analyseResult(array $phpstanResult): PublicAndProtectedClassCons $publicClassConstMatches = []; $protectedClassConstMatches = []; + Assert::keyExists($phpstanResult, 'files'); + foreach ($phpstanResult['files'] as $fileDetail) { + Assert::keyExists($fileDetail, 'messages'); + foreach ($fileDetail['messages'] as $messageError) { + Assert::keyExists($messageError, 'message'); + $publicClassConstMatch = $this->matchPublicClassConstMatch($messageError['message']); if ($publicClassConstMatch instanceof ClassConstMatch) { $publicClassConstMatches[] = $publicClassConstMatch; diff --git a/src/ValueObject/ClassConstMatch.php b/src/ValueObject/ClassConstMatch.php index 1fe9a93f4..c287bb55e 100644 --- a/src/ValueObject/ClassConstMatch.php +++ b/src/ValueObject/ClassConstMatch.php @@ -6,6 +6,7 @@ use ReflectionClass; use Stringable; +use Webmozart\Assert\Assert; final readonly class ClassConstMatch implements Stringable { @@ -16,6 +17,8 @@ public function __construct( private string $className, private string $constantName ) { + Assert::notEmpty($constantName); + Assert::notEmpty($className); } /** diff --git a/src/ValueObject/PublicAndProtectedClassConstants.php b/src/ValueObject/PublicAndProtectedClassConstants.php index 08138770c..ce32be690 100644 --- a/src/ValueObject/PublicAndProtectedClassConstants.php +++ b/src/ValueObject/PublicAndProtectedClassConstants.php @@ -7,43 +7,43 @@ final readonly class PublicAndProtectedClassConstants { /** - * @param ClassConstMatch[] $publicClassConstMatch - * @param ClassConstMatch[] $protectedClassConstMatch + * @param ClassConstMatch[] $publicClassConstMatches + * @param ClassConstMatch[] $protectedClassConstMatches */ public function __construct( - private array $publicClassConstMatch, - private array $protectedClassConstMatch + private array $publicClassConstMatches, + private array $protectedClassConstMatches ) { } /** * @return ClassConstMatch[] */ - public function getPublicClassConstMatch(): array + public function getPublicClassConstMatches(): array { - return $this->publicClassConstMatch; + return $this->publicClassConstMatches; } /** * @return ClassConstMatch[] */ - public function getProtectedClassConstMatch(): array + public function getProtectedClassConstMatches(): array { - return $this->protectedClassConstMatch; + return $this->protectedClassConstMatches; } public function getProtectedCount(): int { - return count($this->protectedClassConstMatch); + return count($this->protectedClassConstMatches); } public function getPublicCount(): int { - return count($this->publicClassConstMatch); + return count($this->publicClassConstMatches); } public function isEmpty(): bool { - return $this->publicClassConstMatch === [] && $this->protectedClassConstMatch === []; + return $this->publicClassConstMatches === [] && $this->protectedClassConstMatches === []; } } diff --git a/tests/PHPStan/ClassConstantResultAnalyserTest.php b/tests/PHPStan/ClassConstantResultAnalyserTest.php new file mode 100644 index 000000000..839a7912b --- /dev/null +++ b/tests/PHPStan/ClassConstantResultAnalyserTest.php @@ -0,0 +1,47 @@ +classConstantResultAnalyser = new ClassConstantResultAnalyser(); + } + + public function test(): void + { + $phpstanResult = [ + 'files' => [ + 'some_file_path.php' => [ + 'messages' => [ + [ + 'line' => 10, + 'message' => 'Access to undefined constant App\\SomeClass::SOME_CONSTANT', + ], + ], + ], + ], + ]; + + $publicAndProtectedClassConstants = $this->classConstantResultAnalyser->analyseResult($phpstanResult); + + $this->assertFalse($publicAndProtectedClassConstants->isEmpty()); + $this->assertSame(0, $publicAndProtectedClassConstants->getPublicCount()); + $this->assertSame(1, $publicAndProtectedClassConstants->getProtectedCount()); + + $onlyProtectedClassConstMatch = $publicAndProtectedClassConstants->getProtectedClassConstMatches()[0]; + $this->assertInstanceOf(ClassConstMatch::class, $onlyProtectedClassConstMatch); + + // $this->assertSame('SOME_CONST', $onlyProtectedClassConstMatch->getConstantName()); + $this->assertSame('App\SomeClass', $onlyProtectedClassConstMatch->getClassName()); + } +}