From 292071e72a710bf61ba8fa52f679db500e0abd46 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 28 Jan 2026 22:37:15 +0100 Subject: [PATCH] [phpunit 12] Add ExplicitMockExpectsCallRector --- ...th_annotation_and_attribute_exists.php.inc | 2 +- .../Fixture/on_self.php.inc | 2 +- .../Fixture/without_namespace.php.inc | 2 +- .../AssertIsTypeMethodCallRectorTest.php | 2 +- .../Fixture/fixture.php.inc | 4 +- .../Fixture/static_fixture.php.inc | 4 +- .../config/configured_rule.php | 0 .../ExplicitMockExpectsCallRectorTest.php | 28 +++++ .../Fixture/fixture.php.inc | 35 ++++++ .../config/configured_rule.php | 9 ++ .../Class_/AssertIsTypeMethodCallRector.php | 3 +- .../ExplicitMockExpectsCallRector.php | 101 ++++++++++++++++++ .../Fixture/some_test.php.inc | 1 + 13 files changed, 184 insertions(+), 9 deletions(-) rename rules-tests/PHPUnit120/Rector/{MethodCall => Class_}/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php (87%) rename rules-tests/PHPUnit120/Rector/{MethodCall => Class_}/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc (91%) rename rules-tests/PHPUnit120/Rector/{MethodCall => Class_}/AssertIsTypeMethodCallRector/Fixture/static_fixture.php.inc (91%) rename rules-tests/PHPUnit120/Rector/{MethodCall => Class_}/AssertIsTypeMethodCallRector/config/configured_rule.php (100%) create mode 100644 rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/ExplicitMockExpectsCallRectorTest.php create mode 100644 rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/Fixture/fixture.php.inc create mode 100644 rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/config/configured_rule.php create mode 100644 rules/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector.php diff --git a/rules-tests/AnnotationsToAttributes/Rector/ClassMethod/DataProviderAnnotationToAttributeRector/Fixture/both_annotation_and_attribute_exists.php.inc b/rules-tests/AnnotationsToAttributes/Rector/ClassMethod/DataProviderAnnotationToAttributeRector/Fixture/both_annotation_and_attribute_exists.php.inc index 106c6ba5..c8a1e04b 100644 --- a/rules-tests/AnnotationsToAttributes/Rector/ClassMethod/DataProviderAnnotationToAttributeRector/Fixture/both_annotation_and_attribute_exists.php.inc +++ b/rules-tests/AnnotationsToAttributes/Rector/ClassMethod/DataProviderAnnotationToAttributeRector/Fixture/both_annotation_and_attribute_exists.php.inc @@ -45,4 +45,4 @@ final class BothAnnotationAndAttributeExists extends TestCase } } -?> \ No newline at end of file +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/on_self.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/on_self.php.inc index c1456f0f..2be2c103 100644 --- a/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/on_self.php.inc +++ b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/on_self.php.inc @@ -44,4 +44,4 @@ final class OnSelf extends TestCase } } -?> \ No newline at end of file +?> diff --git a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/DeclareStrictTypesTestsRector/Fixture/without_namespace.php.inc b/rules-tests/CodeQuality/Rector/StmtsAwareInterface/DeclareStrictTypesTestsRector/Fixture/without_namespace.php.inc index 987f3e59..f248c9e7 100644 --- a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/DeclareStrictTypesTestsRector/Fixture/without_namespace.php.inc +++ b/rules-tests/CodeQuality/Rector/StmtsAwareInterface/DeclareStrictTypesTestsRector/Fixture/without_namespace.php.inc @@ -38,4 +38,4 @@ class WithoutNamespaceTest extends \PHPUnit\Framework\TestCase } } -?> \ No newline at end of file +?> diff --git a/rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php b/rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php similarity index 87% rename from rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php rename to rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php index 065b81c4..3fb2a1df 100644 --- a/rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php +++ b/rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/AssertIsTypeMethodCallRectorTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector; +namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector; use Iterator; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc b/rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc similarity index 91% rename from rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc rename to rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc index e27a9bab..108a959a 100644 --- a/rules-tests/PHPUnit120/Rector/MethodCall/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc +++ b/rules-tests/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector/Fixture/fixture.php.inc @@ -1,6 +1,6 @@ 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/MethodCall/ExplicitMockExpectsCallRector/Fixture/fixture.php.inc b/rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..68e7b2c1 --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/Fixture/fixture.php.inc @@ -0,0 +1,35 @@ +createMock(\stdClass::class); + + $someClass->method('some'); + } +} + +?> +----- +createMock(\stdClass::class); + + $someClass->expects($this->atLeastOnce())->method('some'); + } +} + +?> diff --git a/rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/config/configured_rule.php b/rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/config/configured_rule.php new file mode 100644 index 00000000..66ffadbb --- /dev/null +++ b/rules-tests/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector/config/configured_rule.php @@ -0,0 +1,9 @@ +withRules([ExplicitMockExpectsCallRector::class]); diff --git a/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php b/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php index 4c211615..7adca290 100644 --- a/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php +++ b/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php @@ -17,7 +17,8 @@ /** * @see https://github.com/sebastianbergmann/phpunit/issues/6053 * @see https://github.com/sebastianbergmann/phpunit/blob/12.0.0/ChangeLog-12.0.md - * @see \Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\AssertIsTypeMethodCallRectorTest + * + * @see \Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector\AssertIsTypeMethodCallRectorTest */ final class AssertIsTypeMethodCallRector extends AbstractRector { diff --git a/rules/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector.php b/rules/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector.php new file mode 100644 index 00000000..6133cf80 --- /dev/null +++ b/rules/PHPUnit120/Rector/MethodCall/ExplicitMockExpectsCallRector.php @@ -0,0 +1,101 @@ +createMock(\stdClass::class); + $someMock->method('some'); + } + } + CODE_SAMPLE + , + <<<'CODE_SAMPLE' + use PHPUnit\Framework\TestCase; + + final class SomeClass extends TestCase + { + public function testMe() + { + $someMock = $this->createMock(\stdClass::class); + $someMock->expects($this->atLeastOnce())->method('some'); + } + } + CODE_SAMPLE + , + ), + ], + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class]; + } + + /** + * @param MethodCall $node + */ + public function refactor(Node $node): Node|null + { + if (! $this->testsNodeAnalyzer->isInTestClass($node)) { + return null; + } + + if (! $node->var instanceof Variable && ! $node->var instanceof PropertyFetch) { + return null; + } + + if (! $this->isName($node->name, 'method')) { + return null; + } + + if (! $this->isObjectType($node->var, new ObjectType(PHPUnitClassName::MOCK_OBJECT))) { + return null; + } + + $node->var = new MethodCall($node->var, 'expects', [ + new Arg(new MethodCall(new Variable('this'), 'atLeastOnce')), + ]); + + return $node; + } +} diff --git a/tests/Issues/DoubleAnnotation/Fixture/some_test.php.inc b/tests/Issues/DoubleAnnotation/Fixture/some_test.php.inc index 75e6ae0c..4e842655 100644 --- a/tests/Issues/DoubleAnnotation/Fixture/some_test.php.inc +++ b/tests/Issues/DoubleAnnotation/Fixture/some_test.php.inc @@ -42,3 +42,4 @@ final class SomeTest extends TestCase { } } +