diff --git a/config/sets/composer-based.php b/config/sets/composer-based.php index 2e90d7ca..422c719e 100644 --- a/config/sets/composer-based.php +++ b/config/sets/composer-based.php @@ -30,6 +30,7 @@ use Rector\PHPUnit\PHPUnit110\Rector\Class_\NamedArgumentForDataProviderRector; use Rector\PHPUnit\PHPUnit110\Rector\ClassMethod\ExpectsParamToMockObjectRector; use Rector\PHPUnit\PHPUnit110\Rector\ClassMethod\MockObjectArgCreateStubToCreateMockRector; +use Rector\PHPUnit\PHPUnit120\Rector\Assign\AnyMatcherToNewAnyInvokedCountRector; use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubInCoalesceArgRector; use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubOverCreateMockArgRector; use Rector\PHPUnit\PHPUnit120\Rector\Class_\AllowMockObjectsForDataProviderRector; @@ -106,6 +107,9 @@ // the TestCase::__construct() is final since PHPUnit 12.0.3 RemoveOverrideFinalConstructTestCaseRector::class, + // the any() matcher was deprecated in PHPUnit 12.5 + AnyMatcherToNewAnyInvokedCountRector::class, + // the AllowMockObjectsWithoutExpectations attribute exists since PHPUnit 12.5.2 AllowMockObjectsWhereParentClassRector::class, AllowMockObjectsForDataProviderRector::class, diff --git a/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/AnyMatcherToNewAnyInvokedCountRectorTest.php b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/AnyMatcherToNewAnyInvokedCountRectorTest.php new file mode 100644 index 00000000..6e5612c4 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/AnyMatcherToNewAnyInvokedCountRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/fixture.php.inc b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..f79ed6dd --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/fixture.php.inc @@ -0,0 +1,31 @@ +any(); + } +} + +?> +----- + diff --git a/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/skip_non_test_case.php.inc b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/skip_non_test_case.php.inc new file mode 100644 index 00000000..859a414b --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/Fixture/skip_non_test_case.php.inc @@ -0,0 +1,16 @@ +any(); + } + + public function any(): string + { + return 'any'; + } +} diff --git a/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/config/configured_rule.php b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/config/configured_rule.php new file mode 100644 index 00000000..9903bca7 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(AnyMatcherToNewAnyInvokedCountRector::class); +}; diff --git a/rules/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector.php b/rules/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector.php new file mode 100644 index 00000000..76c617de --- /dev/null +++ b/rules/PHPUnit120/Rector/Assign/AnyMatcherToNewAnyInvokedCountRector.php @@ -0,0 +1,113 @@ +=12.5'); + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Change deprecated `$this->any()` matcher assign to direct `new AnyInvokedCount()`', + [ + new CodeSample( + <<<'CODE_SAMPLE' +use PHPUnit\Framework\TestCase; + +final class SomeTest extends TestCase +{ + public function test(): void + { + $matcher = $this->any(); + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount; +use PHPUnit\Framework\TestCase; + +final class SomeTest extends TestCase +{ + public function test(): void + { + $matcher = new AnyInvokedCount(); + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [Assign::class]; + } + + /** + * @param Assign $node + */ + public function refactor(Node $node): ?Assign + { + if (! $node->expr instanceof MethodCall) { + return null; + } + + $methodCall = $node->expr; + if ($methodCall->isFirstClassCallable()) { + return null; + } + + if (! $this->isName($methodCall->name, 'any')) { + return null; + } + + if ($methodCall->getArgs() !== []) { + return null; + } + + if (! $this->testsNodeAnalyzer->isPHPUnitTestCaseCall($methodCall)) { + return null; + } + + $node->expr = new New_(new FullyQualified(self::ANY_INVOKED_COUNT_CLASS)); + + return $node; + } +}