From c93da15d1b557526d0bff0860031d8a540bc0b42 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 20 Jan 2026 15:29:23 +0100 Subject: [PATCH 1/3] bump to PHP 8.3 --- bin/behastan.php | 4 ++-- composer.json | 13 +++++++------ ...inerFactory.php => BehastanContainerFactory.php} | 2 +- tests/AbstractTestCase.php | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) rename src/DependencyInjection/{ContainerFactory.php => BehastanContainerFactory.php} (94%) diff --git a/bin/behastan.php b/bin/behastan.php index 95b95729a..39e69c401 100755 --- a/bin/behastan.php +++ b/bin/behastan.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use Rector\Behastan\DependencyInjection\ContainerFactory; +use Rector\Behastan\DependencyInjection\BehastanContainerFactory; $possibleAutoloadPaths = [ // dependency @@ -25,7 +25,7 @@ require_once $scoperAutoloadFilepath; } -$container = ContainerFactory::create(); +$container = BehastanContainerFactory::create(); $consoleApplication = $container->make(\Entropy\Console\ConsoleApplication::class); $exitCode = $consoleApplication->run($argv); diff --git a/composer.json b/composer.json index bc6dd026b..9bf539a48 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "bin/behastan" ], "require": { - "php": "^8.2", + "php": "^8.3", "nette/utils": "^4.0", "entropy/entropy": "dev-main", "nikic/php-parser": "^5.6", @@ -15,11 +15,12 @@ }, "require-dev": { "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^11.5", - "rector/rector": "^2.2", - "phpecs/phpecs": "^2.2", - "tomasvotruba/class-leak": "^2.0", + "phpstan/phpstan": "^2.1.34", + "phpunit/phpunit": "^12.5", + "rector/jack": "^0.5.1", + "rector/rector": "^2.3.2", + "symplify/easy-coding-standard": "^13.0", + "tomasvotruba/class-leak": "^2.1", "tracy/tracy": "^2.10" }, "autoload": { diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/BehastanContainerFactory.php similarity index 94% rename from src/DependencyInjection/ContainerFactory.php rename to src/DependencyInjection/BehastanContainerFactory.php index 35f59507b..333b5d2e6 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/BehastanContainerFactory.php @@ -8,7 +8,7 @@ use Rector\Behastan\Contract\RuleInterface; use Rector\Behastan\RulesRegistry; -final class ContainerFactory +final class BehastanContainerFactory { public static function create(): Container { diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php index 948eadf02..348878a08 100644 --- a/tests/AbstractTestCase.php +++ b/tests/AbstractTestCase.php @@ -6,7 +6,7 @@ use Entropy\Container\Container; use PHPUnit\Framework\TestCase; -use Rector\Behastan\DependencyInjection\ContainerFactory; +use Rector\Behastan\DependencyInjection\BehastanContainerFactory; abstract class AbstractTestCase extends TestCase { @@ -14,7 +14,7 @@ abstract class AbstractTestCase extends TestCase protected function setUp(): void { - $containerFactory = new ContainerFactory(); + $containerFactory = new BehastanContainerFactory(); $this->container = $containerFactory->create(); } From fdd2f795dfdeca73dfad7d73bd410925f956243a Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 20 Jan 2026 15:29:57 +0100 Subject: [PATCH 2/3] apply constant types and variable type naming --- rector.php | 1 + src/Analyzer/PatternAnalyzer.php | 5 +---- src/Analyzer/UnusedDefinitionsAnalyzer.php | 5 +---- src/Enum/RuleIdentifier.php | 15 +++------------ src/Resolver/ClassMethodPatternResolver.php | 5 +---- tests/AbstractTestCase.php | 4 ++-- 6 files changed, 9 insertions(+), 26 deletions(-) diff --git a/rector.php b/rector.php index be74166c8..27d9eba72 100644 --- a/rector.php +++ b/rector.php @@ -11,6 +11,7 @@ codeQuality: true, deadCode: true, typeDeclarations: true, + typeDeclarationDocblocks: true, privatization: true, earlyReturn: true, codingStyle: true, diff --git a/src/Analyzer/PatternAnalyzer.php b/src/Analyzer/PatternAnalyzer.php index 12a9cea29..e904fb517 100644 --- a/src/Analyzer/PatternAnalyzer.php +++ b/src/Analyzer/PatternAnalyzer.php @@ -6,10 +6,7 @@ final class PatternAnalyzer { - /** - * @var string - */ - private const PATTERN_REGEX = '#(\:[\W\w]+)#'; + private const string PATTERN_REGEX = '#(\:[\W\w]+)#'; public static function isRegex(string $rawPattern): bool { diff --git a/src/Analyzer/UnusedDefinitionsAnalyzer.php b/src/Analyzer/UnusedDefinitionsAnalyzer.php index 66955e05b..cac3e7d4a 100644 --- a/src/Analyzer/UnusedDefinitionsAnalyzer.php +++ b/src/Analyzer/UnusedDefinitionsAnalyzer.php @@ -21,10 +21,7 @@ */ final readonly class UnusedDefinitionsAnalyzer { - /** - * @var string - */ - private const PATTERN_VALUE_REGEX = '#(\:[\W\w]+)#'; + private const string PATTERN_VALUE_REGEX = '#(\:[\W\w]+)#'; public function __construct( private UsedInstructionResolver $usedInstructionResolver, diff --git a/src/Enum/RuleIdentifier.php b/src/Enum/RuleIdentifier.php index eb81579eb..e8f17766f 100644 --- a/src/Enum/RuleIdentifier.php +++ b/src/Enum/RuleIdentifier.php @@ -6,18 +6,9 @@ final class RuleIdentifier { - /** - * @var string - */ - public const DUPLICATED_CONTENTS = 'duplicated-contents'; + public const string DUPLICATED_CONTENTS = 'duplicated-contents'; - /** - * @var string - */ - public const DUPLICATED_PATTERNS = 'duplicated-patterns'; + public const string DUPLICATED_PATTERNS = 'duplicated-patterns'; - /** - * @var string - */ - public const UNUSED_DEFINITIONS = 'unused-definitions'; + public const string UNUSED_DEFINITIONS = 'unused-definitions'; } diff --git a/src/Resolver/ClassMethodPatternResolver.php b/src/Resolver/ClassMethodPatternResolver.php index 53a34ceb8..cf2c6bcb4 100644 --- a/src/Resolver/ClassMethodPatternResolver.php +++ b/src/Resolver/ClassMethodPatternResolver.php @@ -10,10 +10,7 @@ final class ClassMethodPatternResolver { - /** - * @var string - */ - private const INSTRUCTION_DOCBLOCK_REGEX = '#\@(Given|Then|When)\s+(?.*?)\n#m'; + private const string INSTRUCTION_DOCBLOCK_REGEX = '#\@(Given|Then|When)\s+(?.*?)\n#m'; /** * @return string[] diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php index 348878a08..c377570d1 100644 --- a/tests/AbstractTestCase.php +++ b/tests/AbstractTestCase.php @@ -14,8 +14,8 @@ abstract class AbstractTestCase extends TestCase protected function setUp(): void { - $containerFactory = new BehastanContainerFactory(); - $this->container = $containerFactory->create(); + $behastanContainerFactory = new BehastanContainerFactory(); + $this->container = $behastanContainerFactory->create(); } /** From 68cd7b0f1bff819c99b470a13e26ad25e995d32f Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 20 Jan 2026 15:33:15 +0100 Subject: [PATCH 3/3] move suffix check to particular services, avoid duplicated pattern collection use --- src/Analyzer/UnusedDefinitionsAnalyzer.php | 10 ---------- src/DefinitionPatternsExtractor.php | 5 +++++ src/UsedInstructionResolver.php | 5 +++++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Analyzer/UnusedDefinitionsAnalyzer.php b/src/Analyzer/UnusedDefinitionsAnalyzer.php index cac3e7d4a..44f61579a 100644 --- a/src/Analyzer/UnusedDefinitionsAnalyzer.php +++ b/src/Analyzer/UnusedDefinitionsAnalyzer.php @@ -5,7 +5,6 @@ namespace Rector\Behastan\Analyzer; use Nette\Utils\Strings; -use Rector\Behastan\DefinitionPatternsExtractor; use Rector\Behastan\UsedInstructionResolver; use Rector\Behastan\ValueObject\Pattern\AbstractPattern; use Rector\Behastan\ValueObject\Pattern\ExactPattern; @@ -25,7 +24,6 @@ public function __construct( private UsedInstructionResolver $usedInstructionResolver, - private DefinitionPatternsExtractor $definitionPatternsExtractor, ) { } @@ -37,18 +35,10 @@ public function __construct( */ public function analyse(array $contextFiles, array $featureFiles, PatternCollection $patternCollection): array { - Assert::allIsInstanceOf($contextFiles, SplFileInfo::class); - foreach ($contextFiles as $contextFile) { - Assert::endsWith($contextFile->getFilename(), '.php'); - } - - Assert::allIsInstanceOf($featureFiles, SplFileInfo::class); foreach ($featureFiles as $featureFile) { Assert::endsWith($featureFile->getFilename(), '.feature'); } - $patternCollection = $this->definitionPatternsExtractor->extract($contextFiles); - $featureInstructions = $this->usedInstructionResolver->resolveInstructionsFromFeatureFiles($featureFiles); $unusedPatterns = []; diff --git a/src/DefinitionPatternsExtractor.php b/src/DefinitionPatternsExtractor.php index d373b4daa..8fd384ff1 100644 --- a/src/DefinitionPatternsExtractor.php +++ b/src/DefinitionPatternsExtractor.php @@ -19,6 +19,7 @@ use Rector\Behastan\ValueObject\Pattern\SkippedPattern; use Rector\Behastan\ValueObject\PatternCollection; use SplFileInfo; +use Webmozart\Assert\Assert; #[RelatedTest(DefinitionPatternExtractorTest::class)] final readonly class DefinitionPatternsExtractor @@ -35,6 +36,10 @@ public function __construct( */ public function extract(array $contextFiles): PatternCollection { + foreach ($contextFiles as $contextFile) { + Assert::endsWith($contextFile->getFilename(), '.php'); + } + $patterns = []; $classMethodContextDefinitions = $this->resolvePatternsFromFiles($contextFiles); diff --git a/src/UsedInstructionResolver.php b/src/UsedInstructionResolver.php index 9b828635e..e2bb05ad7 100644 --- a/src/UsedInstructionResolver.php +++ b/src/UsedInstructionResolver.php @@ -7,6 +7,7 @@ use Nette\Utils\Strings; use RuntimeException; use Symfony\Component\Finder\SplFileInfo; +use Webmozart\Assert\Assert; /** * @see \Rector\Behastan\Tests\UsedInstructionResolver\UsedInstructionResolverTest @@ -19,6 +20,10 @@ final class UsedInstructionResolver */ public function resolveInstructionsFromFeatureFiles(array $featureFileInfos): array { + foreach ($featureFileInfos as $featureFileInfo) { + Assert::endsWith($featureFileInfo->getFilename(), '.feature'); + } + $instructions = []; foreach ($featureFileInfos as $featureFileInfo) {