Skip to content

Commit e512024

Browse files
committed
tidy up AssertFuncCallToPHPUnitAssertRector
1 parent d22b617 commit e512024

File tree

2 files changed

+101
-102
lines changed

2 files changed

+101
-102
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\FuncCall\AssertFuncCallToPHPUnitAssertRector\Fixture;
4+
5+
final class SkipOutsideTestCase
6+
{
7+
public function some($response)
8+
{
9+
assert((bool) $response);
10+
}
11+
}

rules/CodeQuality/Rector/FuncCall/AssertFuncCallToPHPUnitAssertRector.php

Lines changed: 90 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
1313
use PhpParser\Node\Expr\Cast\Bool_;
1414
use PhpParser\Node\Expr\ClassConstFetch;
15-
use PhpParser\Node\Expr\Closure;
1615
use PhpParser\Node\Expr\FuncCall;
1716
use PhpParser\Node\Expr\Instanceof_;
1817
use PhpParser\Node\Expr\MethodCall;
1918
use PhpParser\Node\Expr\StaticCall;
2019
use PhpParser\Node\Expr\Variable;
2120
use PhpParser\Node\Name\FullyQualified;
22-
use PhpParser\Node\Stmt\ClassMethod;
23-
use PhpParser\NodeVisitor;
21+
use PhpParser\Node\Stmt\Class_;
2422
use PHPStan\Reflection\ClassReflection;
2523
use Rector\PhpParser\Node\Value\ValueResolver;
2624
use Rector\PHPStan\ScopeFetcher;
@@ -81,105 +79,111 @@ public function test()
8179
*/
8280
public function getNodeTypes(): array
8381
{
84-
return [ClassMethod::class, Closure::class, FuncCall::class];
82+
return [Class_::class];
8583
}
8684

8785
/**
88-
* @param ClassMethod|Closure|FuncCall $node
89-
* @return StaticCall|MethodCall|null|NodeVisitor::DONT_TRAVERSE_CHILDREN
86+
* @param Class_ $node
9087
*/
91-
public function refactor(Node $node): StaticCall|MethodCall|null|int
88+
public function refactor(Node $node): ?Class_
9289
{
93-
// @todo handle only in test classes!
94-
95-
// most liekly hook to ClassMethod :) + traverse then
96-
$this->testsNodeAnalyzer->isInTestClass($node);
97-
98-
// if ($node instanceof ClassMethod) {
99-
// if ($node->isStatic()) {
100-
// return NodeVisitor::DONT_TRAVERSE_CHILDREN;
101-
// }
102-
//
103-
// return null;
104-
// }
105-
106-
// if ($node instanceof Closure) {
107-
// if ($node->static) {
108-
// return NodeVisitor::DONT_TRAVERSE_CHILDREN;
109-
// }
110-
//
111-
// return null;
112-
// }
113-
114-
if ($node->isFirstClassCallable()) {
90+
if ($this->testsNodeAnalyzer->isInTestClass($node) && ! $this->isBehatContext($node)) {
11591
return null;
11692
}
11793

118-
if (! $this->isName($node, 'assert')) {
119-
return null;
120-
}
121-
122-
if (! $this->isTestFilePath($node) && ! $this->isBehatContext($node)) {
123-
return null;
124-
}
125-
126-
$comparedExpr = $node->getArgs()[0]
127-
->value;
94+
$hasChanged = false;
12895

129-
if ($comparedExpr instanceof Equal) {
130-
$methodName = AssertMethod::ASSERT_EQUALS;
131-
$exprs = [$comparedExpr->right, $comparedExpr->left];
132-
133-
} elseif ($comparedExpr instanceof Identical) {
134-
$methodName = AssertMethod::ASSERT_SAME;
135-
$exprs = [$comparedExpr->right, $comparedExpr->left];
136-
137-
} elseif ($comparedExpr instanceof NotIdentical) {
138-
if ($this->valueResolver->isNull($comparedExpr->right)) {
139-
$methodName = 'assertNotNull';
140-
$exprs = [$comparedExpr->left];
141-
} else {
142-
return null;
143-
}
144-
145-
} elseif ($comparedExpr instanceof Bool_) {
146-
$methodName = 'assertTrue';
147-
$exprs = [$comparedExpr];
148-
} elseif ($comparedExpr instanceof FuncCall) {
149-
if ($this->isName($comparedExpr, 'method_exists')) {
150-
$methodName = 'assertTrue';
151-
$exprs = [$comparedExpr];
152-
} else {
153-
return null;
154-
}
155-
} elseif ($comparedExpr instanceof Instanceof_) {
156-
// outside TestCase
157-
$methodName = 'assertInstanceOf';
158-
$exprs = [];
159-
160-
if ($comparedExpr->class instanceof FullyQualified) {
161-
$classConstFetch = new ClassConstFetch($comparedExpr->class, 'class');
162-
$exprs[] = $classConstFetch;
163-
} else {
164-
return null;
96+
foreach ($node->getMethods() as $classMethod) {
97+
if ($classMethod->stmts === null) {
98+
continue;
16599
}
166100

167-
$exprs[] = $comparedExpr->expr;
168-
} else {
169-
return null;
101+
$useStaticAssert = $classMethod->isStatic() ?: $this->isBehatContext($node);
102+
103+
$this->traverseNodesWithCallable($classMethod->stmts, function (\PhpParser\Node $node) use (
104+
$useStaticAssert,
105+
&$hasChanged
106+
) {
107+
if (! $node instanceof FuncCall) {
108+
return null;
109+
}
110+
111+
if ($node->isFirstClassCallable()) {
112+
return null;
113+
}
114+
115+
if (! $this->isName($node, 'assert')) {
116+
return null;
117+
}
118+
119+
$comparedExpr = $node->getArgs()[0]
120+
->value;
121+
122+
if ($comparedExpr instanceof Equal) {
123+
$methodName = AssertMethod::ASSERT_EQUALS;
124+
$exprs = [$comparedExpr->right, $comparedExpr->left];
125+
126+
} elseif ($comparedExpr instanceof Identical) {
127+
$methodName = AssertMethod::ASSERT_SAME;
128+
$exprs = [$comparedExpr->right, $comparedExpr->left];
129+
130+
} elseif ($comparedExpr instanceof NotIdentical) {
131+
if ($this->valueResolver->isNull($comparedExpr->right)) {
132+
$methodName = 'assertNotNull';
133+
$exprs = [$comparedExpr->left];
134+
} else {
135+
return null;
136+
}
137+
138+
} elseif ($comparedExpr instanceof Bool_) {
139+
$methodName = 'assertTrue';
140+
$exprs = [$comparedExpr];
141+
} elseif ($comparedExpr instanceof FuncCall) {
142+
if ($this->isName($comparedExpr, 'method_exists')) {
143+
$methodName = 'assertTrue';
144+
$exprs = [$comparedExpr];
145+
} else {
146+
return null;
147+
}
148+
} elseif ($comparedExpr instanceof Instanceof_) {
149+
// outside TestCase
150+
$methodName = 'assertInstanceOf';
151+
$exprs = [];
152+
153+
if ($comparedExpr->class instanceof FullyQualified) {
154+
$classConstFetch = new ClassConstFetch($comparedExpr->class, 'class');
155+
$exprs[] = $classConstFetch;
156+
} else {
157+
return null;
158+
}
159+
160+
$exprs[] = $comparedExpr->expr;
161+
} else {
162+
return null;
163+
}
164+
165+
// is there a comment message
166+
if (isset($node->getArgs()[1])) {
167+
$exprs[] = $node->getArgs()[1]->value;
168+
}
169+
170+
$hasChanged = true;
171+
172+
return $this->createAssertCall($methodName, $exprs, $useStaticAssert);
173+
174+
});
170175
}
171176

172-
// is there a comment message
173-
if (isset($node->getArgs()[1])) {
174-
$exprs[] = $node->getArgs()[1]->value;
177+
if (! $hasChanged) {
178+
return null;
175179
}
176180

177-
return $this->createCall($node, $methodName, $exprs);
181+
return $node;
178182
}
179183

180-
private function isBehatContext(FuncCall $funcCall): bool
184+
private function isBehatContext(Class_ $class): bool
181185
{
182-
$scope = ScopeFetcher::fetch($funcCall);
186+
$scope = ScopeFetcher::fetch($class);
183187
if (! $scope->getClassReflection() instanceof ClassReflection) {
184188
return false;
185189
}
@@ -191,33 +195,17 @@ private function isBehatContext(FuncCall $funcCall): bool
191195
return str_ends_with($className, 'Context');
192196
}
193197

194-
private function isTestFilePath(FuncCall $funcCall): bool
195-
{
196-
$scope = ScopeFetcher::fetch($funcCall);
197-
if (! $scope->getClassReflection() instanceof ClassReflection) {
198-
return false;
199-
}
200-
201-
$className = $scope->getClassReflection()
202-
->getName();
203-
if (str_ends_with($className, 'Test')) {
204-
return true;
205-
}
206-
207-
return str_ends_with($className, 'TestCase');
208-
}
209-
210198
/**
211199
* @param Expr[] $exprs
212200
*/
213-
private function createCall(FuncCall $funcCall, string $methodName, array $exprs): MethodCall|StaticCall
201+
private function createAssertCall(string $methodName, array $exprs, bool $useStaticAssert): MethodCall|StaticCall
214202
{
215203
$args = [];
216204
foreach ($exprs as $expr) {
217205
$args[] = new Arg($expr);
218206
}
219207

220-
if ($this->isBehatContext($funcCall)) {
208+
if ($useStaticAssert) {
221209
$assertFullyQualified = new FullyQualified(PHPUnitClassName::ASSERT);
222210
return new StaticCall($assertFullyQualified, $methodName, $args);
223211
}

0 commit comments

Comments
 (0)