Skip to content

Commit 10166e2

Browse files
committed
RuleTestCase - parse errors from files
1 parent 362f47a commit 10166e2

File tree

5 files changed

+37
-74
lines changed

5 files changed

+37
-74
lines changed

src/Testing/RuleTestCase.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Testing;
44

5+
use LogicException;
56
use PhpParser\Node;
67
use PHPStan\Analyser\Analyser;
78
use PHPStan\Analyser\AnalyserResultFinalizer;
@@ -40,7 +41,9 @@
4041
use function array_map;
4142
use function array_merge;
4243
use function count;
44+
use function file;
4345
use function implode;
46+
use function preg_match;
4447
use function sprintf;
4548
use function str_replace;
4649

@@ -142,10 +145,26 @@ private function getAnalyser(DirectRuleRegistry $ruleRegistry): Analyser
142145

143146
/**
144147
* @param string[] $files
145-
* @param list<array{0: string, 1: int, 2?: string|null}> $expectedErrors
148+
* @param ?list<array{0: string, 1: int, 2?: string|null}> $expectedErrors
146149
*/
147-
public function analyse(array $files, array $expectedErrors): void
150+
public function analyse(array $files, ?array $expectedErrors): void
148151
{
152+
if ($expectedErrors === null) {
153+
$expectedErrors = [];
154+
foreach ($files as $file) {
155+
$lines = file($file);
156+
if ($lines === false) {
157+
throw new LogicException('Error while reading data from ' . $file);
158+
}
159+
foreach ($lines as $n => $line) {
160+
if (preg_match('~// error: (.+?)(?:, tip: (.+))?$~m', $line, $match) !== 1) {
161+
continue;
162+
}
163+
$expectedErrors[] = [$match[1], $n + 1, $match[2] ?? null];
164+
}
165+
}
166+
}
167+
149168
[$actualErrors, $delayedErrors] = $this->gatherAnalyserErrorsWithDelayedErrors($files);
150169
$strictlyTypedSprintf = static function (int $line, string $message, ?string $tip): string {
151170
$message = sprintf('%02d: %s', $line, $message);

tests/PHPStan/Rules/Comparison/BooleanAndConstantConditionRuleTest.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,20 +346,14 @@ public function testBug5743(): void
346346
public static function dataBug4969(): iterable
347347
{
348348
yield [false, []];
349-
yield [true, [
350-
[
351-
'Result of && is always false.',
352-
15,
353-
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
354-
],
355-
]];
349+
yield [true, null];
356350
}
357351

358352
/**
359-
* @param list<array{0: string, 1: int, 2?: string}> $expectedErrors
353+
* @param ?list<array{0: string, 1: int, 2?: string}> $expectedErrors
360354
*/
361355
#[DataProvider('dataBug4969')]
362-
public function testBug4969(bool $treatPhpDocTypesAsCertain, array $expectedErrors): void
356+
public function testBug4969(bool $treatPhpDocTypesAsCertain, ?array $expectedErrors): void
363357
{
364358
$this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain;
365359
$this->analyse([__DIR__ . '/data/bug-4969.php'], $expectedErrors);

tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -37,57 +37,7 @@ protected function shouldTreatPhpDocTypesAsCertain(): bool
3737

3838
public function testRule(): void
3939
{
40-
$tipText = 'Remove remaining cases below this one and this error will disappear too.';
41-
$this->analyse([__DIR__ . '/data/match-expr.php'], [
42-
[
43-
'Match arm comparison between 1|2|3 and \'foo\' is always false.',
44-
14,
45-
],
46-
[
47-
'Match arm comparison between 1|2|3 and 0 is always false.',
48-
19,
49-
],
50-
[
51-
'Match arm comparison between 3 and 3 is always true.',
52-
28,
53-
$tipText,
54-
],
55-
[
56-
'Match arm comparison between 3 and 3 is always true.',
57-
35,
58-
$tipText,
59-
],
60-
[
61-
'Match arm comparison between 1 and 1 is always true.',
62-
40,
63-
$tipText,
64-
],
65-
[
66-
'Match arm comparison between 1 and 1 is always true.',
67-
46,
68-
$tipText,
69-
],
70-
[
71-
'Match expression does not handle remaining value: 3',
72-
50,
73-
],
74-
[
75-
'Match arm comparison between 1|2 and 3 is always false.',
76-
61,
77-
],
78-
[
79-
'Match expression does not handle remaining values: 1|2|3',
80-
78,
81-
],
82-
[
83-
'Match expression does not handle remaining value: true',
84-
90,
85-
],
86-
[
87-
'Match expression does not handle remaining values: int<min, 0>|int<2, max>',
88-
168,
89-
],
90-
]);
40+
$this->analyse([__DIR__ . '/data/match-expr.php'], null);
9141
}
9242

9343
public function testBug5161(): void

tests/PHPStan/Rules/Comparison/data/bug-4969.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function set(array $config): void
1212
if (!is_string($config['host'])) {
1313
throw new \InvalidArgumentException('error');
1414
}
15-
if (isset($config['port']) && !is_int($config['port'])) {
15+
if (isset($config['port']) && !is_int($config['port'])) { // error: Result of && is always false., tip: Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.
1616
throw new \InvalidArgumentException('error');
1717
}
1818
}

tests/PHPStan/Rules/Comparison/data/match-expr.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ class Foo
1111
public function doFoo(int $i): void
1212
{
1313
match ($i) {
14-
'foo' => null, // always false
14+
'foo' => null, // always false // error: Match arm comparison between 1|2|3 and 'foo' is always false.
1515
default => null,
1616
};
1717

1818
match ($i) {
19-
0 => null,
19+
0 => null, // error: Match arm comparison between 1|2|3 and 0 is always false.
2020
1 => null,
2121
2 => null,
2222
3 => null, // always true, but do not report (it's the last one)
@@ -25,29 +25,29 @@ public function doFoo(int $i): void
2525
match ($i) {
2626
1 => null,
2727
2 => null,
28-
3 => null, // always true - report with strict-rules
28+
3 => null, // always true - report with strict-rules // error: Match arm comparison between 3 and 3 is always true., tip: Remove remaining cases below this one and this error will disappear too.
2929
4 => null, // unreachable
3030
};
3131

3232
match ($i) {
3333
1 => null,
3434
2 => null,
35-
3 => null, // always true - report with strict-rules
35+
3 => null, // always true - report with strict-rules // error: Match arm comparison between 3 and 3 is always true., tip: Remove remaining cases below this one and this error will disappear too.
3636
default => null, // unreachable
3737
};
3838

3939
match (1) {
40-
1 => null, // always true - report with strict-rules
40+
1 => null, // always true - report with strict-rules // error: Match arm comparison between 1 and 1 is always true., tip: Remove remaining cases below this one and this error will disappear too.
4141
2 => null, // unreachable
4242
3 => null, // unreachable
4343
};
4444

4545
match (1) {
46-
1 => null, // always true - report with strict-rules
46+
1 => null, // always true - report with strict-rules // error: Match arm comparison between 1 and 1 is always true., tip: Remove remaining cases below this one and this error will disappear too.
4747
default => null, // unreachable
4848
};
4949

50-
match ($i) {
50+
match ($i) { // error: Match expression does not handle remaining value: 3
5151
1, 2 => null,
5252
// unhandled
5353
};
@@ -58,7 +58,7 @@ public function doFoo(int $i): void
5858
};
5959

6060
match ($i) {
61-
3, 3 => null, // second 3 is always false
61+
3, 3 => null, // second 3 is always false // error: Match arm comparison between 1|2 and 3 is always false.
6262
default => null,
6363
};
6464

@@ -75,7 +75,7 @@ public function doFoo(int $i): void
7575
1 => 2,
7676
};
7777

78-
match ($i) {
78+
match ($i) { // error: Match expression does not handle remaining values: 1|2|3
7979
// unhandled
8080
};
8181
}
@@ -87,7 +87,7 @@ public function doBar(\Exception $e): void
8787
default => null,
8888
};
8989

90-
match (true) {
90+
match (true) { // error: Match expression does not handle remaining value: true
9191
$e instanceof \InvalidArgumentException => true,
9292
$e instanceof \InvalidArgumentException => true, // reported by ImpossibleInstanceOfRule
9393
};
@@ -165,7 +165,7 @@ public function bar(int $bar): void
165165
*/
166166
public function baz(int $bar): void
167167
{
168-
$str = match($bar) {
168+
$str = match($bar) { // error: Match expression does not handle remaining values: int<min, 0>|int<2, max>
169169
1 => 'test'
170170
};
171171
}

0 commit comments

Comments
 (0)