Skip to content

Commit 7e8bd12

Browse files
committed
add multi callbacks support
1 parent e2c5f39 commit 7e8bd12

File tree

6 files changed

+275
-137
lines changed

6 files changed

+275
-137
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WithCallbackIdenticalToStandaloneAssertsRector\Fixture;
6+
7+
use PHPUnit\Framework\TestCase;
8+
9+
final class IncludeNoArgs extends TestCase
10+
{
11+
public function test()
12+
{
13+
$someMock = $this->getMockBuilder('AnyType')->getMock();
14+
15+
$someMock->expects($this->any())
16+
->method('trans')
17+
->with($this->callback(function (): bool {
18+
$args= [1, 2, 3];
19+
return count($args) === 5 && $args[0] === 'some_value';
20+
}));
21+
}
22+
}
23+
24+
?>
25+
-----
26+
<?php
27+
28+
declare(strict_types=1);
29+
30+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WithCallbackIdenticalToStandaloneAssertsRector\Fixture;
31+
32+
use PHPUnit\Framework\TestCase;
33+
34+
final class IncludeNoArgs extends TestCase
35+
{
36+
public function test()
37+
{
38+
$someMock = $this->getMockBuilder('AnyType')->getMock();
39+
40+
$someMock->expects($this->any())
41+
->method('trans')
42+
->with($this->callback(function (): bool {
43+
$args= [1, 2, 3];
44+
$this->assertCount(5, $args);
45+
$this->assertSame('some_value', $args[0]);
46+
return true;
47+
}));
48+
}
49+
}
50+
51+
?>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WithCallbackIdenticalToStandaloneAssertsRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class MultiCallbacks extends TestCase
8+
{
9+
public function test()
10+
{
11+
$someMock = $this->getMockBuilder('AnyType')->getMock();
12+
13+
$someMock->expects($this->any())
14+
->method('trans')
15+
->with(
16+
$this->callback(fn (array $args) => array_key_exists(5, $args)),
17+
$this->callback(fn (array $args) => array_key_exists(50, $args)),
18+
);
19+
}
20+
}
21+
22+
?>
23+
-----
24+
<?php
25+
26+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WithCallbackIdenticalToStandaloneAssertsRector\Fixture;
27+
28+
use PHPUnit\Framework\TestCase;
29+
30+
final class MultiCallbacks extends TestCase
31+
{
32+
public function test()
33+
{
34+
$someMock = $this->getMockBuilder('AnyType')->getMock();
35+
36+
$someMock->expects($this->any())
37+
->method('trans')
38+
->with(
39+
$this->callback(function (array $args): bool {
40+
$this->assertArrayHasKey(5, $args);
41+
return true;
42+
}),
43+
$this->callback(function (array $args): bool {
44+
$this->assertArrayHasKey(50, $args);
45+
return true;
46+
}),
47+
);
48+
}
49+
}
50+
51+
?>

rules-tests/CodeQuality/Rector/MethodCall/WithCallbackIdenticalToStandaloneAssertsRector/Fixture/skip_no_args.php.inc

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\CodeQuality\NodeAnalyser;
6+
7+
use PhpParser\Node\ClosureUse;
8+
use PhpParser\Node\Expr\ArrowFunction;
9+
use PhpParser\Node\Expr\Variable;
10+
use Rector\NodeNameResolver\NodeNameResolver;
11+
use Rector\PhpParser\Node\BetterNodeFinder;
12+
13+
final readonly class ClosureUsesResolver
14+
{
15+
public function __construct(
16+
private BetterNodeFinder $betterNodeFinder,
17+
private NodeNameResolver $nodeNameResolver
18+
) {
19+
20+
}
21+
22+
/**
23+
* @return ClosureUse[]
24+
*/
25+
public function resolveFromArrowFunction(ArrowFunction $arrowFunction): array
26+
{
27+
// fill needed uses from arrow function to closure
28+
$arrowFunctionVariables = $this->betterNodeFinder->findInstancesOfScoped(
29+
$arrowFunction->getStmts(),
30+
Variable::class
31+
);
32+
33+
$paramNames = $this->resolveParamNames($arrowFunction);
34+
35+
$externalVariableNames = [];
36+
37+
foreach ($arrowFunctionVariables as $arrowFunctionVariable) {
38+
// skip those defined in params
39+
if ($this->nodeNameResolver->isNames($arrowFunctionVariable, $paramNames)) {
40+
continue;
41+
}
42+
43+
$variableName = $this->nodeNameResolver->getName($arrowFunctionVariable);
44+
if (! is_string($variableName)) {
45+
continue;
46+
}
47+
48+
$externalVariableNames[] = $variableName;
49+
}
50+
51+
$externalVariableNames = array_unique($externalVariableNames);
52+
$externalVariableNames = array_diff($externalVariableNames, ['this']);
53+
54+
$closureUses = [];
55+
foreach ($externalVariableNames as $externalVariableName) {
56+
$closureUses[] = new ClosureUse(new Variable($externalVariableName));
57+
}
58+
59+
return $closureUses;
60+
}
61+
62+
/**
63+
* @return string[]
64+
*/
65+
private function resolveParamNames(ArrowFunction $arrowFunction): array
66+
{
67+
$paramNames = [];
68+
foreach ($arrowFunction->getParams() as $param) {
69+
$paramNames[] = $this->nodeNameResolver->getName($param);
70+
}
71+
72+
return $paramNames;
73+
}
74+
}

rules/CodeQuality/NodeFactory/FromBinaryAndAssertExpressionsFactory.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public function __construct(
3030

3131
/**
3232
* @param Expr[] $exprs
33-
* @return Stmt[]|null
33+
* @return Stmt[]
3434
*/
35-
public function create(array $exprs): ?array
35+
public function create(array $exprs): array
3636
{
3737
$assertMethodCalls = [];
3838

@@ -62,7 +62,7 @@ public function create(array $exprs): ?array
6262
);
6363
} else {
6464
// not supported yet
65-
return null;
65+
return [];
6666
}
6767
}
6868

@@ -102,7 +102,7 @@ public function create(array $exprs): ?array
102102
}
103103

104104
// unclear, fallback to no change
105-
return null;
105+
return [];
106106
}
107107

108108
// create assertSame()
@@ -113,12 +113,12 @@ public function create(array $exprs): ?array
113113
);
114114
} else {
115115
// not supported expr
116-
return null;
116+
return [];
117117
}
118118
}
119119

120120
if ($assertMethodCalls === []) {
121-
return null;
121+
return [];
122122
}
123123

124124
// to keep order from binary

0 commit comments

Comments
 (0)