-
Notifications
You must be signed in to change notification settings - Fork 65
Expand file tree
/
Copy pathConsecutiveIfsFactory.php
More file actions
125 lines (106 loc) · 5.17 KB
/
ConsecutiveIfsFactory.php
File metadata and controls
125 lines (106 loc) · 5.17 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
<?php
declare(strict_types=1);
namespace Rector\PHPUnit\NodeFactory;
use PhpParser\Node\Arg;
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->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);
}
}