diff --git a/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/assert_method_call_true.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/assert_method_call_true.php.inc new file mode 100644 index 00000000..5f81cbad --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/assert_method_call_true.php.inc @@ -0,0 +1,49 @@ +getMockBuilder('AnyType')->getMock(); + + $someMock->expects($this->any()) + ->method('trans') + ->with($this->callback(fn ($arg) => $arg instanceof SomeClassWithMethodCall && $arg->isReady())); + } +} + +?> +----- +getMockBuilder('AnyType')->getMock(); + + $someMock->expects($this->any()) + ->method('trans') + ->with($this->callback(function ($arg): bool { + $this->assertInstanceOf(\Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WithCallbackIdenticalToStandaloneAssertsRector\Source\SomeClassWithMethodCall::class, $arg); + $this->assertTrue($arg->isReady()); + return true; + })); + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Source/SomeClassWithMethodCall.php b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Source/SomeClassWithMethodCall.php new file mode 100644 index 00000000..4197dbce --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Source/SomeClassWithMethodCall.php @@ -0,0 +1,11 @@ +createClosureUses($externalVariableNames); } /** @@ -71,4 +66,18 @@ private function resolveParamNames(ArrowFunction $arrowFunction): array return $paramNames; } + + /** + * @param string[] $externalVariableNames + * @return ClosureUse[] + */ + private function createClosureUses(array $externalVariableNames): array + { + $closureUses = []; + foreach ($externalVariableNames as $externalVariableName) { + $closureUses[] = new ClosureUse(new Variable($externalVariableName)); + } + + return $closureUses; + } } diff --git a/rules/CodeQuality/NodeFactory/FromBinaryAndAssertExpressionsFactory.php b/rules/CodeQuality/NodeFactory/FromBinaryAndAssertExpressionsFactory.php index e8b880f8..b4c967d5 100644 --- a/rules/CodeQuality/NodeFactory/FromBinaryAndAssertExpressionsFactory.php +++ b/rules/CodeQuality/NodeFactory/FromBinaryAndAssertExpressionsFactory.php @@ -12,6 +12,7 @@ use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\Isset_; +use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Scalar\Int_; @@ -37,6 +38,13 @@ public function create(array $exprs): array $assertMethodCalls = []; foreach ($exprs as $expr) { + // implicit bool compare + if ($expr instanceof MethodCall) { + $assertMethodCalls[] = $this->nodeFactory->createMethodCall('this', 'assertTrue', [$expr]); + + continue; + } + if ($expr instanceof FuncCall && $this->nodeNameResolver->isName($expr, 'array_key_exists')) { $variableExpr = $expr->getArgs()[1] ->value; diff --git a/rules/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector.php b/rules/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector.php index dbab7cea..a7766975 100644 --- a/rules/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector.php +++ b/rules/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector.php @@ -125,34 +125,24 @@ public function refactor(Node $node): MethodCall|null continue; } - $assertExpressions = $this->fromBinaryAndAssertExpressionsFactory->create($joinedExprs); - if ($assertExpressions === []) { + $assertExprStmts = $this->fromBinaryAndAssertExpressionsFactory->create($joinedExprs); + if ($assertExprStmts === []) { continue; } $nonReturnCallbackStmts = $this->resolveNonReturnCallbackStmts($argAndFunctionLike); // last si return true; - $assertExpressions[] = new Return_($this->nodeFactory->createTrue()); - + $assertExprStmts[] = new Return_($this->nodeFactory->createTrue()); $innerFunctionLike = $argAndFunctionLike->getFunctionLike(); if ($innerFunctionLike instanceof Closure) { - $innerFunctionLike->stmts = array_merge($nonReturnCallbackStmts, $assertExpressions); + $innerFunctionLike->stmts = array_merge($nonReturnCallbackStmts, $assertExprStmts); } else { // arrow function -> flip to closure $functionLikeInArg = $argAndFunctionLike->getArg(); - $externalVariables = $this->closureUsesResolver->resolveFromArrowFunction($innerFunctionLike); - - $closure = new Closure([ - 'params' => $argAndFunctionLike->getFunctionLike() - ->params, - 'stmts' => $assertExpressions, - 'returnType' => new Identifier('bool'), - 'uses' => $externalVariables, - ]); - + $closure = $this->createClosure($innerFunctionLike, $argAndFunctionLike, $assertExprStmts); $functionLikeInArg->value = $closure; } @@ -273,4 +263,23 @@ private function resolveNonReturnCallbackStmts(ArgAndFunctionLike $argAndFunctio return []; } + + /** + * @param Stmt[] $assertExprStmts + */ + private function createClosure( + ArrowFunction $arrowFunction, + ArgAndFunctionLike $argAndFunctionLike, + array $assertExprStmts + ): Closure { + $externalVariables = $this->closureUsesResolver->resolveFromArrowFunction($arrowFunction); + + return new Closure([ + 'params' => $argAndFunctionLike->getFunctionLike() + ->params, + 'stmts' => $assertExprStmts, + 'returnType' => new Identifier('bool'), + 'uses' => $externalVariables, + ]); + } }