|
17 | 17 | use Rector\PHPUnit\Enum\PHPUnitClassName; |
18 | 18 | use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; |
19 | 19 | use Rector\Rector\AbstractRector; |
| 20 | +use Rector\ValueObject\MethodName; |
20 | 21 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; |
21 | 22 | use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; |
22 | 23 |
|
@@ -44,30 +45,14 @@ public function getNodeTypes(): array |
44 | 45 | */ |
45 | 46 | public function refactor(Node $node): ?Class_ |
46 | 47 | { |
47 | | - if (! $this->testsNodeAnalyzer->isInTestClass($node)) { |
| 48 | + if ($this->shouldSkipClass($node)) { |
48 | 49 | return null; |
49 | 50 | } |
50 | 51 |
|
51 | | - // attribute must exist for the rule to work |
52 | | - if (! $this->reflectionProvider->hasClass(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)) { |
53 | | - return null; |
54 | | - } |
| 52 | + $mockObjectPropertyNames = $this->matchMockObjectPropertyNames($node); |
55 | 53 |
|
56 | | - // already filled |
57 | | - if ($this->attributeFinder->hasAttributeByClasses( |
58 | | - $node, |
59 | | - [PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS] |
60 | | - )) { |
61 | | - return null; |
62 | | - } |
63 | | - |
64 | | - // has mock objects properties and setUp() method? |
65 | | -
|
66 | | - if (! $node->getMethod('setUp') instanceof ClassMethod) { |
67 | | - return null; |
68 | | - } |
69 | | - |
70 | | - if (! $this->hasMockObjectProperty($node)) { |
| 54 | + // there are no mock object properties |
| 55 | + if ($mockObjectPropertyNames === []) { |
71 | 56 | return null; |
72 | 57 | } |
73 | 58 |
|
@@ -156,18 +141,50 @@ public function testTwo(): void |
156 | 141 |
|
157 | 142 | } |
158 | 143 |
|
159 | | - private function hasMockObjectProperty(Class_ $class): bool |
| 144 | + /** |
| 145 | + * @return string[] |
| 146 | + */ |
| 147 | + private function matchMockObjectPropertyNames(Class_ $class): array |
160 | 148 | { |
| 149 | + $propertyNames = []; |
| 150 | + |
161 | 151 | foreach ($class->getProperties() as $property) { |
162 | 152 | if (! $property->type instanceof Name) { |
163 | 153 | continue; |
164 | 154 | } |
165 | 155 |
|
166 | | - if ($this->isName($property->type, PHPUnitClassName::MOCK_OBJECT)) { |
167 | | - return true; |
| 156 | + if (! $this->isName($property->type, PHPUnitClassName::MOCK_OBJECT)) { |
| 157 | + continue; |
168 | 158 | } |
| 159 | + |
| 160 | + $propertyNames[] = $this->getName($property->props[0]); |
| 161 | + } |
| 162 | + |
| 163 | + return $propertyNames; |
| 164 | + } |
| 165 | + |
| 166 | + private function shouldSkipClass(Class_ $class): bool |
| 167 | + { |
| 168 | + if (! $this->testsNodeAnalyzer->isInTestClass($class)) { |
| 169 | + return true; |
169 | 170 | } |
170 | 171 |
|
171 | | - return false; |
| 172 | + // attribute must exist for the rule to work |
| 173 | + if (! $this->reflectionProvider->hasClass(PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS)) { |
| 174 | + return true; |
| 175 | + } |
| 176 | + |
| 177 | + // already filled |
| 178 | + if ($this->attributeFinder->hasAttributeByClasses( |
| 179 | + $class, |
| 180 | + [PHPUnitAttribute::ALLOW_MOCK_OBJECTS_WITHOUT_EXPECTATIONS] |
| 181 | + )) { |
| 182 | + return true; |
| 183 | + } |
| 184 | + |
| 185 | + // has mock objects properties and setUp() method? |
| 186 | +
|
| 187 | + $setupClassMethod = $class->getMethod(MethodName::SET_UP); |
| 188 | + return ! $setupClassMethod instanceof ClassMethod; |
172 | 189 | } |
173 | 190 | } |
0 commit comments