forked from rectorphp/rector-phpunit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConsecutiveIfsFactory.php
More file actions
130 lines (110 loc) · 5.32 KB
/
ConsecutiveIfsFactory.php
File metadata and controls
130 lines (110 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
declare(strict_types=1);
namespace Rector\PHPUnit\NodeFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\Int_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Exception\NotImplementedYetException;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\PHPUnit\CodeQuality\NodeFactory\NestedClosureAssertFactory;
use Rector\PHPUnit\Enum\ConsecutiveVariable;
final readonly class ConsecutiveIfsFactory
{
public function __construct(
private NodeNameResolver $nodeNameResolver,
private NestedClosureAssertFactory $nestedClosureAssertFactory
) {
}
/**
* @return Stmt[]
*/
public function createIfs(MethodCall $withConsecutiveMethodCall, MethodCall $numberOfInvocationsMethodCall): array
{
$ifs = [];
$parametersVariable = new Variable(ConsecutiveVariable::PARAMETERS);
foreach ($withConsecutiveMethodCall->getArgs() as $key => $withConsecutiveArg) {
$ifStmts = [];
if ($withConsecutiveArg->value instanceof Array_) {
$array = $withConsecutiveArg->value;
foreach ($array->items as $assertKey => $assertArrayItem) {
if (! $assertArrayItem instanceof ArrayItem) {
continue;
}
if (! $assertArrayItem->value instanceof MethodCall) {
$parametersDimFetch = new ArrayDimFetch(new Variable('parameters'), new Int_($assertKey));
$args = [new Arg($assertArrayItem->value), new Arg($parametersDimFetch)];
$ifStmts[] = new Expression(new MethodCall(new Variable('this'), 'assertSame', $args));
continue;
}
$assertMethodCall = $assertArrayItem->value;
if ($this->nodeNameResolver->isName($assertMethodCall->name, 'equalTo')) {
$ifStmts[] = $this->createAssertMethodCall($assertMethodCall, $parametersVariable, $assertKey);
} elseif ($this->nodeNameResolver->isName($assertMethodCall->name, 'callback')) {
$ifStmts = array_merge(
$ifStmts,
$this->nestedClosureAssertFactory->create($assertMethodCall, $assertKey)
);
} else {
$args = [
new Arg($assertMethodCall),
new Arg(new ArrayDimFetch(new Variable('parameters'), new Int_($assertKey))),
];
$assertSameMethodCall = new MethodCall(new Variable('this'), new Identifier(
'assertSame'
), $args);
$ifStmts[] = new Expression($assertSameMethodCall);
}
}
} elseif ($withConsecutiveArg->value instanceof MethodCall) {
$methodCall = $withConsecutiveArg->value;
if ($this->nodeNameResolver->isName($methodCall->name, 'callback')) {
// special callable case
$firstArg = $methodCall->getArgs()[0];
if ($firstArg->value instanceof ArrowFunction) {
$arrowFunction = $firstArg->value;
if ($arrowFunction->expr instanceof Identical) {
$identicalCompare = $arrowFunction->expr;
// @todo improve in time
if ($identicalCompare->left instanceof Variable) {
$parametersArrayDimFetch = new ArrayDimFetch(new Variable('parameters'), new Int_(
0
));
$assertSameMethodCall = new MethodCall(new Variable('this'), new Identifier(
'assertSame'
));
$assertSameMethodCall->args[] = new Arg($identicalCompare->right);
$assertSameMethodCall->args[] = new Arg($parametersArrayDimFetch);
return [new Expression($assertSameMethodCall)];
}
}
}
}
throw new NotImplementedYetException();
}
$ifs[] = new If_(new Identical($numberOfInvocationsMethodCall, new Int_($key + 1)), [
'stmts' => $ifStmts,
]);
}
return $ifs;
}
private function createAssertMethodCall(
MethodCall $assertMethodCall,
Variable $parametersVariable,
int $parameterPositionKey
): Expression {
$assertMethodCall->name = new Identifier('assertEquals');
$parametersArrayDimFetch = new ArrayDimFetch($parametersVariable, new Int_($parameterPositionKey));
$assertMethodCall->args[] = new Arg($parametersArrayDimFetch);
return new Expression($assertMethodCall);
}
}