Skip to content

Commit 72d5655

Browse files
committed
report too many/too few with when provider re-used
1 parent 5cb8c63 commit 72d5655

File tree

3 files changed

+74
-15
lines changed

3 files changed

+74
-15
lines changed

src/Rules/PHPUnit/DataProviderDataRule.php

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
use PHPStan\Rules\Rule;
99
use PHPStan\ShouldNotHappenException;
1010
use PHPUnit\Framework\TestCase;
11+
use function array_slice;
1112
use function count;
13+
use function max;
14+
use function min;
1215

1316
/**
1417
* @implements Rule<Node>
@@ -95,23 +98,35 @@ public function processNode(Node $node, Scope $scope): array
9598
return [];
9699
}
97100

98-
foreach ($arrayExprs as $arrayExpr) {
99-
if (!$arrayExpr instanceof Node\Expr\Array_) {
100-
throw new ShouldNotHappenException();
101-
}
101+
$maxNumberOfParameters = 0;
102+
$trimArgs = count($testsWithProvider) > 1;
103+
foreach ($testsWithProvider as $testMethod) {
104+
$maxNumberOfParameters = max($maxNumberOfParameters, $testMethod->getNumberOfParameters());
105+
}
102106

103-
$args = $this->arrayItemsToArgs($arrayExpr);
104-
if ($args === null) {
105-
continue;
106-
}
107+
foreach ($testsWithProvider as $testMethod) {
108+
foreach ($arrayExprs as $arrayExpr) {
109+
if (!$arrayExpr instanceof Node\Expr\Array_) {
110+
throw new ShouldNotHappenException();
111+
}
107112

108-
$var = new Node\Expr\New_(new Node\Name($classReflection->getName()));
109-
$scope->invokeNodeCallback(new Node\Expr\MethodCall(
110-
$var,
111-
$testsWithProvider[0]->getName(),
112-
$args,
113-
['startLine' => $arrayExpr->getStartLine()],
114-
));
113+
$args = $this->arrayItemsToArgs($arrayExpr);
114+
if ($args === null) {
115+
continue;
116+
}
117+
118+
if ($trimArgs && $maxNumberOfParameters !== $testMethod->getNumberOfParameters()) {
119+
$args = array_slice($args, 0, min($testMethod->getNumberOfParameters(), $maxNumberOfParameters));
120+
}
121+
122+
$var = new Node\Expr\New_(new Node\Name($classReflection->getName()));
123+
$scope->invokeNodeCallback(new Node\Expr\MethodCall(
124+
$var,
125+
$testMethod->getName(),
126+
$args,
127+
['startLine' => $arrayExpr->getStartLine()],
128+
));
129+
}
115130
}
116131

117132
return [];

tests/Rules/PHPUnit/DataProviderDataRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ public function testRule(): void
9292
'Method DataProviderDataTest\DifferentArgumentCount::testFoo() invoked with 1 parameter, 2 required.',
9393
146,
9494
],
95+
[
96+
'Method DataProviderDataTest\DifferentArgumentCountWithReusedDataprovider::testFoo() invoked with 3 parameters, 2 required.',
97+
177,
98+
],
99+
[
100+
'Method DataProviderDataTest\DifferentArgumentCountWithReusedDataprovider::testFoo() invoked with 1 parameter, 2 required.',
101+
182,
102+
],
95103
]);
96104
}
97105

tests/Rules/PHPUnit/data/data-provider-data.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,39 @@ public function yieldProvider(): iterable
150150
}
151151
}
152152

153+
class DifferentArgumentCountWithReusedDataprovider extends TestCase
154+
{
155+
156+
/**
157+
* @dataProvider yieldProvider
158+
*/
159+
public function testFoo(string $expectedResult, string $input): void
160+
{
161+
}
162+
163+
/**
164+
* @dataProvider yieldProvider
165+
*/
166+
public function testBar(string $expectedResult): void
167+
{
168+
}
169+
170+
public function yieldProvider(): iterable
171+
{
172+
yield from [
173+
[
174+
'Hello World',
175+
" Hello World \n",
176+
],
177+
[
178+
'Hello World',
179+
'abc',
180+
123,
181+
],
182+
[
183+
'Hello World',
184+
]
185+
];
186+
}
187+
}
188+

0 commit comments

Comments
 (0)