5
5
namespace Rector \TypeDeclaration \Rector \Class_ ;
6
6
7
7
use PhpParser \Node ;
8
+ use PhpParser \Node \IntersectionType ;
8
9
use PhpParser \Node \NullableType ;
9
10
use PhpParser \Node \Stmt \Class_ ;
11
+ use PhpParser \Node \Stmt \Property ;
10
12
use PHPStan \Type \ObjectType ;
11
13
use PHPStan \Type \Type ;
12
14
use Rector \Enum \ClassName ;
@@ -34,7 +36,9 @@ public function __construct(
34
36
35
37
public function getRuleDefinition (): RuleDefinition
36
38
{
37
- return new RuleDefinition ('Add typed property from assigned mock ' , [
39
+ return new RuleDefinition (
40
+ 'Add "PHPUnit\Framework\MockObject\MockObject" typed property from assigned mock to clearly separate from real objects ' ,
41
+ [
38
42
new CodeSample (
39
43
<<<'CODE_SAMPLE'
40
44
use PHPUnit\Framework\TestCase;
@@ -52,10 +56,11 @@ protected function setUp(): void
52
56
,
53
57
<<<'CODE_SAMPLE'
54
58
use PHPUnit\Framework\TestCase;
59
+ use PHPUnit\Framework\MockObject\MockObject;
55
60
56
61
final class SomeTest extends TestCase
57
62
{
58
- private \PHPUnit\Framework\MockObject\ MockObject $someProperty;
63
+ private MockObject $someProperty;
59
64
60
65
protected function setUp(): void
61
66
{
@@ -64,6 +69,7 @@ protected function setUp(): void
64
69
}
65
70
CODE_SAMPLE
66
71
),
72
+
67
73
]);
68
74
}
69
75
@@ -84,15 +90,12 @@ public function refactor(Node $node): ?Node
84
90
$ hasChanged = false ;
85
91
86
92
foreach ($ node ->getProperties () as $ property ) {
87
- // already use PHPUnit\Framework\MockObject\MockObject type
88
- if ($ property ->type instanceof Node && $ this ->isObjectType (
89
- $ property ->type ,
90
- new ObjectType (ClassName::MOCK_OBJECT )
91
- )) {
93
+ if (count ($ property ->props ) !== 1 ) {
92
94
continue ;
93
95
}
94
96
95
- if (count ($ property ->props ) !== 1 ) {
97
+ // already use PHPUnit\Framework\MockObject\MockObject type
98
+ if ($ this ->isAlreadyTypedWithMockObject ($ property )) {
96
99
continue ;
97
100
}
98
101
@@ -135,4 +138,18 @@ public function provideMinPhpVersion(): int
135
138
{
136
139
return PhpVersionFeature::TYPED_PROPERTIES ;
137
140
}
141
+
142
+ private function isAlreadyTypedWithMockObject (Property $ property ): bool
143
+ {
144
+ if (! $ property ->type instanceof Node) {
145
+ return false ;
146
+ }
147
+
148
+ // complex type, used on purpose
149
+ if ($ property ->type instanceof IntersectionType) {
150
+ return true ;
151
+ }
152
+
153
+ return $ this ->isObjectType ($ property ->type , new ObjectType (ClassName::MOCK_OBJECT ));
154
+ }
138
155
}
0 commit comments