Skip to content

Commit ab4fad0

Browse files
committed
Updated Rector to commit 4997962de1f53c449dadbef7025bffe5ca41e63c
rectorphp/rector-src@4997962 Bump PHPStan to 2.1.38 (#7879)
1 parent 55f9f3c commit ab4fad0

10 files changed

Lines changed: 175 additions & 12 deletions

File tree

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,7 @@
20522052
'Rector\\PHPUnit\\PHPUnit110\\Rector\\Class_\\NamedArgumentForDataProviderRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit110/Rector/Class_/NamedArgumentForDataProviderRector.php',
20532053
'Rector\\PHPUnit\\PHPUnit120\\Rector\\CallLike\\CreateStubOverCreateMockArgRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector.php',
20542054
'Rector\\PHPUnit\\PHPUnit120\\Rector\\ClassMethod\\ExpressionCreateMockToCreateStubRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/ClassMethod/ExpressionCreateMockToCreateStubRector.php',
2055+
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsForDataProviderRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsForDataProviderRector.php',
20552056
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsWhereParentClassRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsWhereParentClassRector.php',
20562057
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsWithoutExpectationsAttributeRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsWithoutExpectationsAttributeRector.php',
20572058
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AssertIsTypeMethodCallRector' => $vendorDir . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,7 @@ class ComposerStaticInit6374fd21a3f525a40760d79e3596b56b
23122312
'Rector\\PHPUnit\\PHPUnit110\\Rector\\Class_\\NamedArgumentForDataProviderRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit110/Rector/Class_/NamedArgumentForDataProviderRector.php',
23132313
'Rector\\PHPUnit\\PHPUnit120\\Rector\\CallLike\\CreateStubOverCreateMockArgRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/CallLike/CreateStubOverCreateMockArgRector.php',
23142314
'Rector\\PHPUnit\\PHPUnit120\\Rector\\ClassMethod\\ExpressionCreateMockToCreateStubRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/ClassMethod/ExpressionCreateMockToCreateStubRector.php',
2315+
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsForDataProviderRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsForDataProviderRector.php',
23152316
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsWhereParentClassRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsWhereParentClassRector.php',
23162317
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AllowMockObjectsWithoutExpectationsAttributeRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AllowMockObjectsWithoutExpectationsAttributeRector.php',
23172318
'Rector\\PHPUnit\\PHPUnit120\\Rector\\Class_\\AssertIsTypeMethodCallRector' => __DIR__ . '/..' . '/rector/rector-phpunit/rules/PHPUnit120/Rector/Class_/AssertIsTypeMethodCallRector.php',

vendor/composer/installed.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,12 +1818,12 @@
18181818
"source": {
18191819
"type": "git",
18201820
"url": "https:\/\/github.com\/rectorphp\/rector-phpunit.git",
1821-
"reference": "43e5326f462d78161a173844cf00403ed041fa8b"
1821+
"reference": "1993f6b70c1e8ee8241c56c3876a13f52facfb13"
18221822
},
18231823
"dist": {
18241824
"type": "zip",
1825-
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/43e5326f462d78161a173844cf00403ed041fa8b",
1826-
"reference": "43e5326f462d78161a173844cf00403ed041fa8b",
1825+
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/1993f6b70c1e8ee8241c56c3876a13f52facfb13",
1826+
"reference": "1993f6b70c1e8ee8241c56c3876a13f52facfb13",
18271827
"shasum": ""
18281828
},
18291829
"require": {
@@ -1850,7 +1850,7 @@
18501850
"tomasvotruba\/unused-public": "^2.2",
18511851
"tracy\/tracy": "^2.11"
18521852
},
1853-
"time": "2026-02-04T12:03:46+00:00",
1853+
"time": "2026-02-04T12:33:44+00:00",
18541854
"default-branch": true,
18551855
"type": "rector-extension",
18561856
"extra": {

vendor/composer/installed.php

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

vendor/rector/extension-installer/src/GeneratedConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
final class GeneratedConfig
1111
{
12-
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 46e4f77'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main a110e2f'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main 43e5326'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main eadb590'));
12+
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 46e4f77'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main a110e2f'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main 1993f6b'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main eadb590'));
1313
private function __construct()
1414
{
1515
}

vendor/rector/rector-phpunit/config/sets/phpunit120.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use Rector\Config\RectorConfig;
77
use Rector\PHPUnit\PHPUnit120\Rector\CallLike\CreateStubOverCreateMockArgRector;
8+
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AllowMockObjectsForDataProviderRector;
89
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AllowMockObjectsWhereParentClassRector;
910
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AllowMockObjectsWithoutExpectationsAttributeRector;
1011
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector;
@@ -20,6 +21,7 @@
2021
ExpressionCreateMockToCreateStubRector::class,
2122
PropertyCreateMockToCreateStubRector::class,
2223
AllowMockObjectsWhereParentClassRector::class,
24+
AllowMockObjectsForDataProviderRector::class,
2325
// experimental, from PHPUnit 12.5.2
2426
// @see https://github.com/sebastianbergmann/phpunit/commit/24c208d6a340c3071f28a9b5cce02b9377adfd43
2527
AllowMockObjectsWithoutExpectationsAttributeRector::class,

vendor/rector/rector-phpunit/rules/AnnotationsToAttributes/Rector/ClassMethod/DataProviderAnnotationToAttributeRector.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
1717
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
1818
use Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory;
19+
use Rector\PHPUnit\Enum\PHPUnitAttribute;
1920
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
2021
use Rector\Rector\AbstractRector;
2122
use Rector\Reflection\ReflectionResolver;
@@ -56,10 +57,6 @@ final class DataProviderAnnotationToAttributeRector extends AbstractRector imple
5657
* @readonly
5758
*/
5859
private ReflectionProvider $reflectionProvider;
59-
/**
60-
* @var string
61-
*/
62-
private const DATA_PROVIDER_CLASS = 'PHPUnit\Framework\Attributes\DataProvider';
6360
public function __construct(TestsNodeAnalyzer $testsNodeAnalyzer, PhpAttributeGroupFactory $phpAttributeGroupFactory, PhpDocTagRemover $phpDocTagRemover, ReflectionResolver $reflectionResolver, DocBlockUpdater $docBlockUpdater, PhpDocInfoFactory $phpDocInfoFactory, ReflectionProvider $reflectionProvider)
6461
{
6562
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
@@ -123,7 +120,7 @@ public function refactor(Node $node): ?Node
123120
if (!$this->testsNodeAnalyzer->isInTestClass($node)) {
124121
return null;
125122
}
126-
if (!$this->reflectionProvider->hasClass(self::DATA_PROVIDER_CLASS)) {
123+
if (!$this->reflectionProvider->hasClass(PHPUnitAttribute::DATA_PROVIDER)) {
127124
return null;
128125
}
129126
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
@@ -178,7 +175,7 @@ private function createAttributeGroup(ClassMethod $classMethod, string $original
178175
}
179176
$attributeGroup = $this->phpAttributeGroupFactory->createFromClassWithItems('PHPUnit\Framework\Attributes\DataProviderExternal', [$className . '::class', $methodName]);
180177
} else {
181-
$attributeGroup = $this->phpAttributeGroupFactory->createFromClassWithItems(self::DATA_PROVIDER_CLASS, [$methodName]);
178+
$attributeGroup = $this->phpAttributeGroupFactory->createFromClassWithItems(PHPUnitAttribute::DATA_PROVIDER, [$methodName]);
182179
}
183180
foreach ($classMethod->attrGroups as $existingAttributeGroup) {
184181
if ($this->nodeComparator->areNodesEqual($existingAttributeGroup, $attributeGroup)) {

vendor/rector/rector-phpunit/rules/CodeQuality/NodeAnalyser/MockObjectExprDetector.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ public function __construct(BetterNodeFinder $betterNodeFinder, NodeNameResolver
3232
$this->nodeNameResolver = $nodeNameResolver;
3333
$this->variableFinder = $variableFinder;
3434
}
35+
public function hasMethodCallWithoutExpects(ClassMethod $classMethod): bool
36+
{
37+
/** @var array<Expr\MethodCall> $methodCalls */
38+
$methodCalls = $this->betterNodeFinder->findInstancesOfScoped((array) $classMethod->stmts, [MethodCall::class]);
39+
foreach ($methodCalls as $methodCall) {
40+
if (!$this->nodeNameResolver->isName($methodCall->name, 'method')) {
41+
continue;
42+
}
43+
if ($methodCall->var instanceof MethodCall) {
44+
continue;
45+
}
46+
return \true;
47+
}
48+
return \false;
49+
}
3550
public function isUsedForMocking(Expr $expr, ClassMethod $classMethod): bool
3651
{
3752
if (!$expr instanceof Variable) {
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
declare (strict_types=1);
4+
namespace Rector\PHPUnit\PHPUnit120\Rector\Class_;
5+
6+
use PhpParser\Node;
7+
use PhpParser\Node\Attribute;
8+
use PhpParser\Node\AttributeGroup;
9+
use PhpParser\Node\Name\FullyQualified;
10+
use PhpParser\Node\Stmt\Class_;
11+
use PHPStan\Reflection\ReflectionProvider;
12+
use Rector\Doctrine\NodeAnalyzer\AttributeFinder;
13+
use Rector\PHPUnit\CodeQuality\NodeAnalyser\MockObjectExprDetector;
14+
use Rector\PHPUnit\Enum\PHPUnitAttribute;
15+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
16+
use Rector\Rector\AbstractRector;
17+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
18+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
19+
/**
20+
* @see \Rector\PHPUnit\Tests\PHPUnit120\Rector\Class_\AllowMockObjectsForDataProviderRector\AllowMockObjectsForDataProviderRectorTest
21+
*/
22+
final class AllowMockObjectsForDataProviderRector extends AbstractRector
23+
{
24+
/**
25+
* @readonly
26+
*/
27+
private TestsNodeAnalyzer $testsNodeAnalyzer;
28+
/**
29+
* @readonly
30+
*/
31+
private AttributeFinder $attributeFinder;
32+
/**
33+
* @readonly
34+
*/
35+
private ReflectionProvider $reflectionProvider;
36+
/**
37+
* @readonly
38+
*/
39+
private MockObjectExprDetector $mockObjectExprDetector;
40+
public function __construct(TestsNodeAnalyzer $testsNodeAnalyzer, AttributeFinder $attributeFinder, ReflectionProvider $reflectionProvider, MockObjectExprDetector $mockObjectExprDetector)
41+
{
42+
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
43+
$this->attributeFinder = $attributeFinder;
44+
$this->reflectionProvider = $reflectionProvider;
45+
$this->mockObjectExprDetector = $mockObjectExprDetector;
46+
}
47+
public function getNodeTypes(): array
48+
{
49+
return [Class_::class];
50+
}
51+
/**
52+
* @param Class_ $node
53+
*/
54+
public function refactor(Node $node): ?Class_
55+
{
56+
if ($this->shouldSkipClass($node)) {
57+
return null;
58+
}
59+
if (!$this->hasDataProviderMethodWithExpectLessMethodMock($node)) {
60+
return null;
61+
}
62+
// add attribute
63+
$node->attrGroups[] = new AttributeGroup([new Attribute(new FullyQualified(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS))]);
64+
return $node;
65+
}
66+
public function getRuleDefinition(): RuleDefinition
67+
{
68+
return new RuleDefinition('Add #[AllowMockObjectsWithoutExpectations] attribute to PHPUnit test classes that have methods with data providers and mock objects without expectations', [new CodeSample(<<<'CODE_SAMPLE'
69+
use PHPUnit\Framework\Attributes\DataProvider;
70+
use PHPUnit\Framework\TestCase;
71+
72+
final class SomeClass extends TestCase
73+
{
74+
#[DataProvider('someDataProvider')]
75+
public function test()
76+
{
77+
$someMock = $this->createMock(\stdClass::class);
78+
$someMock->expects('method')->willReturn(true);
79+
}
80+
81+
public static function someDataProvider(): iterable
82+
{
83+
yield [1];
84+
yield [2];
85+
yield [3];
86+
}
87+
}
88+
CODE_SAMPLE
89+
, <<<'CODE_SAMPLE'
90+
use PHPUnit\Framework\Attributes\DataProvider;
91+
use PHPUnit\Framework\TestCase;
92+
93+
#[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations]
94+
final class SomeClass extends TestCase
95+
{
96+
#[DataProvider('someDataProvider')]
97+
public function test()
98+
{
99+
$someMock = $this->createMock(\stdClass::class);
100+
$someMock->expects('method')->willReturn(true);
101+
}
102+
103+
public static function someDataProvider(): iterable
104+
{
105+
yield [1];
106+
yield [2];
107+
yield [3];
108+
}
109+
}
110+
CODE_SAMPLE
111+
)]);
112+
}
113+
private function shouldSkipClass(Class_ $class): bool
114+
{
115+
if (!$this->testsNodeAnalyzer->isInTestClass($class)) {
116+
return \true;
117+
}
118+
// attribute must exist for the rule to work
119+
if (!$this->reflectionProvider->hasClass(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)) {
120+
return \true;
121+
}
122+
// already filled
123+
return $this->attributeFinder->hasAttributeByClasses($class, [PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS]);
124+
}
125+
private function hasDataProviderMethodWithExpectLessMethodMock(Class_ $class): bool
126+
{
127+
// has a test method, that contains a ->method() call without expects()
128+
// and has a data provider attribute?
129+
foreach ($class->getMethods() as $classMethod) {
130+
if (!$this->testsNodeAnalyzer->isTestClassMethod($classMethod)) {
131+
continue;
132+
}
133+
if (!$this->attributeFinder->hasAttributeByClasses($classMethod, [PHPUnitAttribute::DATA_PROVIDER])) {
134+
continue;
135+
}
136+
// has expects-less mock objects
137+
if ($this->mockObjectExprDetector->hasMethodCallWithoutExpects($classMethod)) {
138+
return \true;
139+
}
140+
}
141+
return \false;
142+
}
143+
}

vendor/rector/rector-phpunit/src/Enum/PHPUnitAttribute.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ final class PHPUnitAttribute
4646
* @var string
4747
*/
4848
public const ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS = 'PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations';
49+
/**
50+
* @var string
51+
*/
52+
public const DATA_PROVIDER = 'PHPUnit\Framework\Attributes\DataProvider';
4953
}

0 commit comments

Comments
 (0)