Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 033f690

Browse files
authored
PHPUnit 9.x/10.x does not at all support named arguments from data-providers
1 parent 758d343 commit 033f690

File tree

4 files changed

+144
-31
lines changed

4 files changed

+144
-31
lines changed

‎src/Rules/PHPUnit/DataProviderDataRule.php‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ class DataProviderDataRule implements Rule
2323

2424
private DataProviderHelper $dataProviderHelper;
2525

26+
private PHPUnitVersion $PHPUnitVersion;
27+
2628
public function __construct(
2729
TestMethodsHelper $testMethodsHelper,
28-
DataProviderHelper $dataProviderHelper
30+
DataProviderHelper $dataProviderHelper,
31+
PHPUnitVersion $PHPUnitVersion
2932
)
3033
{
3134
$this->testMethodsHelper = $testMethodsHelper;
3235
$this->dataProviderHelper = $dataProviderHelper;
36+
$this->PHPUnitVersion = $PHPUnitVersion;
3337
}
3438

3539
public function getNodeType(): string
@@ -153,11 +157,10 @@ private function arrayItemsToArgs(Type $array, int $numberOfParameters): ?array
153157
return null;
154158
}
155159

156-
if (count($key) === 0) {
160+
if (count($key) === 0 || !$this->PHPUnitVersion->supportsNamedArgumentsInDataProvider()->yes()) {
157161
$arg = new Node\Arg(new TypeExpr($valueType));
158162
$args[] = $arg;
159163
continue;
160-
161164
}
162165

163166
$arg = new Node\Arg(

‎src/Rules/PHPUnit/PHPUnitVersion.php‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ public function requiresStaticDataProviders(): TrinaryLogic
3838
return TrinaryLogic::createFromBoolean($this->majorVersion >= 10);
3939
}
4040

41+
public function supportsNamedArgumentsInDataProvider(): TrinaryLogic
42+
{
43+
if ($this->majorVersion === null) {
44+
return TrinaryLogic::createMaybe();
45+
}
46+
return TrinaryLogic::createFromBoolean($this->majorVersion >= 11);
47+
}
48+
4149
}

‎tests/Rules/PHPUnit/DataProviderDataRuleTest.php‎

Lines changed: 98 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,36 @@
88
use PHPStan\Rules\Rule;
99
use PHPStan\Testing\RuleTestCase;
1010
use PHPStan\Type\FileTypeMapper;
11+
use PHPUnit\Framework\Attributes\DataProvider;
12+
use PHPUnit\Framework\Attributes\TestWith;
13+
use const PHP_VERSION_ID;
1114

1215
/**
1316
* @extends RuleTestCase<CompositeRule>
1417
*/
1518
class DataProviderDataRuleTest extends RuleTestCase
1619
{
17-
private int $phpunitVersion;
20+
private ?int $phpunitVersion;
1821

1922
protected function getRule(): Rule
2023
{
2124
$reflectionProvider = $this->createReflectionProvider();
25+
$phpunitVersion = new PHPUnitVersion($this->phpunitVersion);
2226

2327
/** @var list<Rule<Node>> $rules */
2428
$rules = [
2529
new DataProviderDataRule(
2630
new TestMethodsHelper(
2731
self::getContainer()->getByType(FileTypeMapper::class),
28-
newPHPUnitVersion($this->phpunitVersion)
32+
$phpunitVersion
2933
),
3034
new DataProviderHelper(
3135
$reflectionProvider,
3236
self::getContainer()->getByType(FileTypeMapper::class),
3337
self::getContainer()->getService('defaultAnalysisParser'),
34-
newPHPUnitVersion($this->phpunitVersion)
38+
$phpunitVersion
3539
),
36-
40+
$phpunitVersion,
3741
),
3842
self::getContainer()->getByType(CallMethodsRule::class) /** @phpstan-ignore phpstanApi.classConstant */
3943
];
@@ -173,36 +177,64 @@ public function testRule(): void
173177
]);
174178
}
175179

176-
public function testRulePhp8(): void
180+
181+
/**
182+
* @dataProvider provideNamedArgumentPHPUnitVersions
183+
*/
184+
#[DataProvider('provideNamedArgumentPHPUnitVersions')]
185+
public function testRulePhp8(?int $phpunitVersion): void
177186
{
178187
if (PHP_VERSION_ID < 80000) {
179188
self::markTestSkipped();
180189
}
181190

182-
$this->phpunitVersion = 10;
191+
$this->phpunitVersion = $phpunitVersion;
183192

184-
$this->analyse([__DIR__ . '/data/data-provider-data-named.php'], [
185-
[
186-
'Parameter $input of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, int given.',
187-
44
188-
],
189-
[
190-
'Parameter $input of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, false given.',
191-
44
192-
],
193-
[
194-
'Unknown parameter $wrong in call to method DataProviderDataTestPhp8\TestWrongOffsetNameArrayShapeIterable::testBar().',
195-
58
196-
],
197-
[
198-
'Missing parameter $si (int) in call to method DataProviderDataTestPhp8\TestWrongOffsetNameArrayShapeIterable::testBar().',
199-
58
200-
],
201-
[
202-
'Parameter $si of method DataProviderDataTestPhp8\TestWrongTypeInArrayShapeIterable::testBar() expects int, string given.',
203-
79
204-
],
205-
]);
193+
if ($phpunitVersion >= 11) {
194+
$errors = [
195+
[
196+
'Parameter $input of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, int given.',
197+
44
198+
],
199+
[
200+
'Parameter $input of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, false given.',
201+
44
202+
],
203+
[
204+
'Unknown parameter $wrong in call to method DataProviderDataTestPhp8\TestWrongOffsetNameArrayShapeIterable::testBar().',
205+
58
206+
],
207+
[
208+
'Missing parameter $si (int) in call to method DataProviderDataTestPhp8\TestWrongOffsetNameArrayShapeIterable::testBar().',
209+
58
210+
],
211+
[
212+
'Parameter $si of method DataProviderDataTestPhp8\TestWrongTypeInArrayShapeIterable::testBar() expects int, string given.',
213+
79
214+
],
215+
];
216+
} else {
217+
$errors = [
218+
[
219+
'Parameter #1 $expectedResult of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, int given.',
220+
44
221+
],
222+
[
223+
'Parameter #1 $expectedResult of method DataProviderDataTestPhp8\NamedArgsInProvider::testFoo() expects string, false given.',
224+
44
225+
],
226+
[
227+
'Parameter #1 $si of method DataProviderDataTestPhp8\TestWrongOffsetNameArrayShapeIterable::testBar() expects int, string given.',
228+
58
229+
],
230+
[
231+
'Parameter #1 $si of method DataProviderDataTestPhp8\TestWrongTypeInArrayShapeIterable::testBar() expects int, string given.',
232+
79
233+
],
234+
];
235+
}
236+
237+
$this->analyse([__DIR__ . '/data/data-provider-data-named.php'], $errors);
206238
}
207239

208240

@@ -274,6 +306,44 @@ public function testTrimmingArgs(): void
274306
]);
275307
}
276308

309+
static public function provideNamedArgumentPHPUnitVersions(): iterable
310+
{
311+
yield [null]; // unknown phpunit version
312+
313+
if (PHP_VERSION_ID >= 80100) {
314+
yield [10]; // PHPUnit 10.x requires PHP 8.1+
315+
}
316+
if (PHP_VERSION_ID >= 80200) {
317+
yield [11]; // PHPUnit 11.x requires PHP 8.2+
318+
}
319+
}
320+
321+
/**
322+
* @dataProvider provideNamedArgumentPHPUnitVersions
323+
*/
324+
#[DataProvider('provideNamedArgumentPHPUnitVersions')]
325+
public function testNamedArgumentsInDataProviders(?int $phpunitVersion): void
326+
{
327+
$this->phpunitVersion = $phpunitVersion;
328+
329+
if ($phpunitVersion >= 11) {
330+
$errors = [];
331+
} else {
332+
$errors = [
333+
[
334+
'Parameter #1 $int of method DataProviderNamedArgs\FooTest::testFoo() expects int, string given.',
335+
26
336+
],
337+
[
338+
'Parameter #2 $string of method DataProviderNamedArgs\FooTest::testFoo() expects string, int given.',
339+
26
340+
],
341+
];
342+
}
343+
344+
$this->analyse([__DIR__ . '/data/data-provider-named-args.php'], $errors);
345+
}
346+
277347
/**
278348
* @return string[]
279349
*/
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace DataProviderNamedArgs;
4+
5+
class FooTest extends \PHPUnit\Framework\TestCase
6+
{
7+
8+
/**
9+
* @dataProvider dataProvider
10+
*/
11+
public function testFoo(
12+
int $int,
13+
string $string
14+
): void
15+
{
16+
$this->assertTrue(true);
17+
}
18+
19+
public static function dataProvider(): iterable
20+
{
21+
yield 'even' => [
22+
'int' => 50,
23+
'string' => 'abc',
24+
];
25+
26+
yield 'odd' => [
27+
'string' => 'def',
28+
'int' => 51,
29+
];
30+
}
31+
}
32+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /