Skip to content

Commit 83bf3ab

Browse files
authored
Optimize NodeScopeResolverTest
1 parent 92a951f commit 83bf3ab

File tree

2 files changed

+173
-105
lines changed

2 files changed

+173
-105
lines changed

src/Testing/TypeInferenceTestCase.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,25 +278,38 @@ public static function gatherAssertTypes(string $file): array
278278
* @return array<string, mixed[]>
279279
*/
280280
public static function gatherAssertTypesFromDirectory(string $directory): array
281+
{
282+
$asserts = [];
283+
foreach (self::findTestDataFilesFromDirectory($directory) as $path) {
284+
foreach (self::gatherAssertTypes($path) as $key => $assert) {
285+
$asserts[$key] = $assert;
286+
}
287+
}
288+
289+
return $asserts;
290+
}
291+
292+
/**
293+
* @return list<string>
294+
*/
295+
public static function findTestDataFilesFromDirectory(string $directory): array
281296
{
282297
if (!is_dir($directory)) {
283298
self::fail(sprintf('Directory %s does not exist.', $directory));
284299
}
285300

286301
$finder = new Finder();
287302
$finder->followLinks();
288-
$asserts = [];
303+
$files = [];
289304
foreach ($finder->files()->name('*.php')->in($directory) as $fileInfo) {
290305
$path = $fileInfo->getPathname();
291306
if (self::isFileLintSkipped($path)) {
292307
continue;
293308
}
294-
foreach (self::gatherAssertTypes($path) as $key => $assert) {
295-
$asserts[$key] = $assert;
296-
}
309+
$files[] = $path;
297310
}
298311

299-
return $asserts;
312+
return $files;
300313
}
301314

302315
/**

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 155 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,75 +5,87 @@
55
use EnumTypeAssertions\Foo;
66
use PHPStan\Testing\TypeInferenceTestCase;
77
use stdClass;
8+
use function array_shift;
89
use function define;
10+
use function dirname;
11+
use function implode;
12+
use function sprintf;
13+
use function str_starts_with;
14+
use function strlen;
15+
use function substr;
916
use const PHP_INT_SIZE;
1017
use const PHP_VERSION_ID;
1118

1219
class NodeScopeResolverTest extends TypeInferenceTestCase
1320
{
1421

15-
public function dataFileAsserts(): iterable
22+
/**
23+
* @return iterable<string>
24+
*/
25+
private static function findTestFiles(): iterable
1626
{
17-
yield from $this->gatherAssertTypesFromDirectory(__DIR__ . '/nsrt');
27+
foreach (self::findTestDataFilesFromDirectory(__DIR__ . '/nsrt') as $testFile) {
28+
yield $testFile;
29+
}
1830

1931
if (PHP_VERSION_ID < 80200 && PHP_VERSION_ID >= 80100) {
20-
yield from $this->gatherAssertTypes(__DIR__ . '/data/enum-reflection-php81.php');
32+
yield __DIR__ . '/data/enum-reflection-php81.php';
2133
}
2234

2335
if (PHP_VERSION_ID < 80000 && PHP_VERSION_ID >= 70400) {
24-
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4902.php');
36+
yield __DIR__ . '/data/bug-4902.php';
2537
}
2638

2739
if (PHP_VERSION_ID < 80300) {
2840
if (PHP_VERSION_ID >= 80200) {
29-
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php82.php');
41+
yield __DIR__ . '/data/mb-strlen-php82.php';
3042
} elseif (PHP_VERSION_ID >= 80000) {
31-
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php8.php');
43+
yield __DIR__ . '/data/mb-strlen-php8.php';
3244
} elseif (PHP_VERSION_ID < 70300) {
33-
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php72.php');
45+
yield __DIR__ . '/data/mb-strlen-php72.php';
3446
} else {
35-
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php73.php');
47+
yield __DIR__ . '/data/mb-strlen-php73.php';
3648
}
3749
}
3850

39-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-6856.php');
51+
yield __DIR__ . '/../Rules/Methods/data/bug-6856.php';
4052

4153
if (PHP_VERSION_ID >= 80000) {
42-
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/unionTypes.php');
43-
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/mixedType.php');
44-
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/staticReturnType.php');
54+
yield __DIR__ . '/../Reflection/data/unionTypes.php';
55+
yield __DIR__ . '/../Reflection/data/mixedType.php';
56+
yield __DIR__ . '/../Reflection/data/staticReturnType.php';
4557
}
4658

4759
if (PHP_INT_SIZE === 8) {
48-
yield from $this->gatherAssertTypes(__DIR__ . '/data/predefined-constants-64bit.php');
60+
yield __DIR__ . '/data/predefined-constants-64bit.php';
4961
} else {
50-
yield from $this->gatherAssertTypes(__DIR__ . '/data/predefined-constants-32bit.php');
62+
yield __DIR__ . '/data/predefined-constants-32bit.php';
5163
}
5264

53-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-10577.php');
54-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-10610.php');
55-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-2550.php');
56-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/bug-3777.php');
57-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-4552.php');
58-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/infer-array-key.php');
59-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Generics/data/bug-3769.php');
60-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Generics/data/bug-6301.php');
61-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-4643.php');
65+
yield __DIR__ . '/../Rules/Variables/data/bug-10577.php';
66+
yield __DIR__ . '/../Rules/Variables/data/bug-10610.php';
67+
yield __DIR__ . '/../Rules/Comparison/data/bug-2550.php';
68+
yield __DIR__ . '/../Rules/Properties/data/bug-3777.php';
69+
yield __DIR__ . '/../Rules/Methods/data/bug-4552.php';
70+
yield __DIR__ . '/../Rules/Methods/data/infer-array-key.php';
71+
yield __DIR__ . '/../Rules/Generics/data/bug-3769.php';
72+
yield __DIR__ . '/../Rules/Generics/data/bug-6301.php';
73+
yield __DIR__ . '/../Rules/PhpDoc/data/bug-4643.php';
6274

6375
if (PHP_VERSION_ID >= 80000) {
64-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-4857.php');
76+
yield __DIR__ . '/../Rules/Comparison/data/bug-4857.php';
6577
}
6678

67-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5089.php');
68-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/unable-to-resolve-callback-parameter-type.php');
79+
yield __DIR__ . '/../Rules/Methods/data/bug-5089.php';
80+
yield __DIR__ . '/../Rules/Methods/data/unable-to-resolve-callback-parameter-type.php';
6981

70-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/varying-acceptor.php');
71-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-4415.php');
82+
yield __DIR__ . '/../Rules/Functions/data/varying-acceptor.php';
83+
yield __DIR__ . '/../Rules/Methods/data/bug-4415.php';
7284
if (PHP_VERSION_ID >= 70400) {
73-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5372.php');
85+
yield __DIR__ . '/../Rules/Methods/data/bug-5372.php';
7486
}
75-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5372_2.php');
76-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5562.php');
87+
yield __DIR__ . '/../Rules/Arrays/data/bug-5372_2.php';
88+
yield __DIR__ . '/../Rules/Methods/data/bug-5562.php';
7789

7890
if (PHP_VERSION_ID >= 80100) {
7991
define('TEST_OBJECT_CONSTANT', new stdClass());
@@ -82,124 +94,167 @@ public function dataFileAsserts(): iterable
8294
define('TEST_FALSE_CONSTANT', false);
8395
define('TEST_ARRAY_CONSTANT', [true, false, null]);
8496
define('TEST_ENUM_CONSTANT', Foo::ONE);
85-
yield from $this->gatherAssertTypes(__DIR__ . '/data/new-in-initializers-runtime.php');
97+
yield __DIR__ . '/data/new-in-initializers-runtime.php';
8698
}
8799

88100
if (PHP_VERSION_ID >= 70400) {
89-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-6473.php');
101+
yield __DIR__ . '/../Rules/Comparison/data/bug-6473.php';
90102
}
91103

92-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/filter-iterator-child-class.php');
104+
yield __DIR__ . '/../Rules/Methods/data/filter-iterator-child-class.php';
93105

94-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5749.php');
95-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5757.php');
106+
yield __DIR__ . '/../Rules/Methods/data/bug-5749.php';
107+
yield __DIR__ . '/../Rules/Methods/data/bug-5757.php';
96108

97109
if (PHP_VERSION_ID >= 80000) {
98-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-6635.php');
110+
yield __DIR__ . '/../Rules/Methods/data/bug-6635.php';
99111
}
100112

101113
if (PHP_VERSION_ID >= 80300) {
102-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Constants/data/bug-10212.php');
114+
yield __DIR__ . '/../Rules/Constants/data/bug-10212.php';
103115
}
104116

105-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-3284.php');
117+
yield __DIR__ . '/../Rules/Methods/data/bug-3284.php';
106118

107119
if (PHP_VERSION_ID >= 80300) {
108-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/return-type-class-constant.php');
120+
yield __DIR__ . '/../Rules/Methods/data/return-type-class-constant.php';
109121
}
110122

111123
//define('ALREADY_DEFINED_CONSTANT', true);
112124
//yield from $this->gatherAssertTypes(__DIR__ . '/data/already-defined-constant.php');
113125

114-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/conditional-complex-templates.php');
126+
yield __DIR__ . '/../Rules/Methods/data/conditional-complex-templates.php';
115127

116-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-7511.php');
117-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/trait-mixin.php');
118-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/trait-mixin.php');
119-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-4708.php');
120-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-7156.php');
121-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6364.php');
122-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5758.php');
123-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-3931.php');
124-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-7417.php');
125-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-7469.php');
126-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-3391.php');
128+
yield __DIR__ . '/../Rules/Methods/data/bug-7511.php';
129+
yield __DIR__ . '/../Rules/Properties/data/trait-mixin.php';
130+
yield __DIR__ . '/../Rules/Methods/data/trait-mixin.php';
131+
yield __DIR__ . '/../Rules/Comparison/data/bug-4708.php';
132+
yield __DIR__ . '/../Rules/Functions/data/bug-7156.php';
133+
yield __DIR__ . '/../Rules/Arrays/data/bug-6364.php';
134+
yield __DIR__ . '/../Rules/Arrays/data/bug-5758.php';
135+
yield __DIR__ . '/../Rules/Functions/data/bug-3931.php';
136+
yield __DIR__ . '/../Rules/Variables/data/bug-7417.php';
137+
yield __DIR__ . '/../Rules/Arrays/data/bug-7469.php';
138+
yield __DIR__ . '/../Rules/Variables/data/bug-3391.php';
127139

128140
if (PHP_VERSION_ID >= 70400) {
129-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-anonymous-function-method-constant.php');
141+
yield __DIR__ . '/../Rules/Functions/data/bug-anonymous-function-method-constant.php';
130142
}
131143

132144
if (PHP_VERSION_ID >= 80200) {
133-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/true-typehint.php');
145+
yield __DIR__ . '/../Rules/Methods/data/true-typehint.php';
134146
}
135-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6000.php');
147+
yield __DIR__ . '/../Rules/Arrays/data/bug-6000.php';
136148

137-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/slevomat-foreach-unset-bug.php');
138-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/slevomat-foreach-array-key-exists-bug.php');
149+
yield __DIR__ . '/../Rules/Arrays/data/slevomat-foreach-unset-bug.php';
150+
yield __DIR__ . '/../Rules/Arrays/data/slevomat-foreach-array-key-exists-bug.php';
139151

140152
if (PHP_VERSION_ID >= 80000) {
141-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-7898.php');
153+
yield __DIR__ . '/../Rules/Comparison/data/bug-7898.php';
142154
}
143155

144156
if (PHP_VERSION_ID >= 80000) {
145-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-7823.php');
146-
}
147-
148-
yield from $this->gatherAssertTypes(__DIR__ . '/../Analyser/data/is-resource-specified.php');
149-
150-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-7954.php');
151-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/docblock-assert-equality.php');
152-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/bug-7839.php');
153-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-5333.php');
154-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-8174.php');
155-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8169.php');
156-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-8280.php');
157-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8277.php');
158-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-8113.php');
159-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-8389.php');
160-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-8467a.php');
157+
yield __DIR__ . '/../Rules/Functions/data/bug-7823.php';
158+
}
159+
160+
yield __DIR__ . '/../Analyser/data/is-resource-specified.php';
161+
162+
yield __DIR__ . '/../Rules/Arrays/data/bug-7954.php';
163+
yield __DIR__ . '/../Rules/Comparison/data/docblock-assert-equality.php';
164+
yield __DIR__ . '/../Rules/Properties/data/bug-7839.php';
165+
yield __DIR__ . '/../Rules/Classes/data/bug-5333.php';
166+
yield __DIR__ . '/../Rules/Methods/data/bug-8174.php';
167+
yield __DIR__ . '/../Rules/Comparison/data/bug-8169.php';
168+
yield __DIR__ . '/../Rules/Functions/data/bug-8280.php';
169+
yield __DIR__ . '/../Rules/Comparison/data/bug-8277.php';
170+
yield __DIR__ . '/../Rules/Variables/data/bug-8113.php';
171+
yield __DIR__ . '/../Rules/Functions/data/bug-8389.php';
172+
yield __DIR__ . '/../Rules/Arrays/data/bug-8467a.php';
161173
if (PHP_VERSION_ID >= 80100) {
162-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8485.php');
174+
yield __DIR__ . '/../Rules/Comparison/data/bug-8485.php';
163175
}
164176

165177
if (PHP_VERSION_ID >= 80100) {
166-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-9007.php');
178+
yield __DIR__ . '/../Rules/Comparison/data/bug-9007.php';
167179
}
168180

169-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/DeadCode/data/bug-8620.php');
181+
yield __DIR__ . '/../Rules/DeadCode/data/bug-8620.php';
170182

171183
if (PHP_VERSION_ID >= 80200) {
172-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Constants/data/bug-8957.php');
184+
yield __DIR__ . '/../Rules/Constants/data/bug-8957.php';
173185
}
174186

175187
if (PHP_VERSION_ID >= 80100) {
176-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-9499.php');
177-
}
178-
179-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-8609-function.php');
180-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-5365.php');
181-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-6551.php');
182-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-9403.php');
183-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-9542.php');
184-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-9803.php');
185-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-10594.php');
186-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591.php');
187-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591-method-tag.php');
188-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591-property-tag.php');
189-
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/mixin-trait-use.php');
188+
yield __DIR__ . '/../Rules/Comparison/data/bug-9499.php';
189+
}
190+
191+
yield __DIR__ . '/../Rules/PhpDoc/data/bug-8609-function.php';
192+
yield __DIR__ . '/../Rules/Comparison/data/bug-5365.php';
193+
yield __DIR__ . '/../Rules/Comparison/data/bug-6551.php';
194+
yield __DIR__ . '/../Rules/Variables/data/bug-9403.php';
195+
yield __DIR__ . '/../Rules/Methods/data/bug-9542.php';
196+
yield __DIR__ . '/../Rules/Functions/data/bug-9803.php';
197+
yield __DIR__ . '/../Rules/PhpDoc/data/bug-10594.php';
198+
yield __DIR__ . '/../Rules/Classes/data/bug-11591.php';
199+
yield __DIR__ . '/../Rules/Classes/data/bug-11591-method-tag.php';
200+
yield __DIR__ . '/../Rules/Classes/data/bug-11591-property-tag.php';
201+
yield __DIR__ . '/../Rules/Classes/data/mixin-trait-use.php';
190202
}
191203

192204
/**
193-
* @dataProvider dataFileAsserts
194-
* @param mixed ...$args
205+
* @return iterable<string, array{string}>
195206
*/
196-
public function testFileAsserts(
197-
string $assertType,
198-
string $file,
199-
...$args,
200-
): void
207+
public static function dataFile(): iterable
201208
{
202-
$this->assertFileAsserts($assertType, $file, ...$args);
209+
$base = dirname(__DIR__, 3) . '/';
210+
$baseLength = strlen($base);
211+
212+
foreach (self::findTestFiles() as $file) {
213+
$testName = $file;
214+
if (str_starts_with($file, $base)) {
215+
$testName = substr($file, $baseLength);
216+
}
217+
218+
yield $testName => [$file];
219+
}
220+
}
221+
222+
/**
223+
* @dataProvider dataFile
224+
*/
225+
public function testFile(string $file): void
226+
{
227+
$asserts = $this->gatherAssertTypes($file);
228+
$this->assertNotCount(0, $asserts, sprintf('File %s has no asserts.', $file));
229+
$failures = [];
230+
231+
foreach ($asserts as $args) {
232+
$assertType = array_shift($args);
233+
$file = array_shift($args);
234+
235+
if ($assertType === 'type') {
236+
$expected = $args[0];
237+
$actual = $args[1];
238+
239+
if ($expected !== $actual) {
240+
$failures[] = sprintf("Line %d:\nExpected: %s\nActual: %s\n", $args[2], $expected, $actual);
241+
}
242+
} elseif ($assertType === 'variableCertainty') {
243+
$expectedCertainty = $args[0];
244+
$actualCertainty = $args[1];
245+
$variableName = $args[2];
246+
247+
if ($expectedCertainty->equals($actualCertainty) !== true) {
248+
$failures[] = sprintf("Certainty of variable \$%s on line %d:\nExpected: %s\nActual: %s\n", $variableName, $args[3], $expectedCertainty->describe(), $actualCertainty->describe());
249+
}
250+
}
251+
}
252+
253+
if ($failures === []) {
254+
return;
255+
}
256+
257+
self::fail(sprintf("Failed assertions in %s:\n\n%s", $file, implode("\n", $failures)));
203258
}
204259

205260
public static function getAdditionalConfigFiles(): array

0 commit comments

Comments
 (0)