Skip to content

Commit 73c2fd4

Browse files
JanTvrdikclaude
andcommitted
Enhance RuleTestCase to support multiple errors on same line
Key improvements: - Update regex to properly parse multiple error comments using non-greedy matching - Simplify expected errors parsing by removing complex sorting logic - Add comprehensive test cases for multiple errors per line scenarios - Add dedicated test method demonstrating 2, 3, and 4 errors on single lines - Add test cases for mixed valid/invalid operations on same line The enhanced RuleTestCase now correctly handles the common scenario where multiple PHPStan rule violations occur on the same line of code, making it much more practical for testing complex rules. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent af5b783 commit 73c2fd4

File tree

4 files changed

+43
-16
lines changed

4 files changed

+43
-16
lines changed

src/RuleTestCase.php

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ protected function analyseFile(string $file, bool $autofix = false): void
3030
{
3131
$analyserErrors = $this->gatherAnalyserErrors([$file]);
3232

33-
if ($autofix === true) {
33+
if ($autofix) {
3434
$this->autofix($file, $analyserErrors);
35-
self::fail("File $file was autofixed. This setup should never remain in the codebase.");
35+
self::fail("File {$file} was autofixed. This setup should never remain in the codebase.");
3636
}
3737

3838
$actualErrors = $this->processActualErrors($analyserErrors);
@@ -74,27 +74,18 @@ private function parseExpectedErrors(string $file): array
7474
$expectedErrors = [];
7575

7676
foreach ($fileLines as $line => $row) {
77-
/** @var array{0: list<string>, 1: list<non-empty-string>} $matches */
78-
$matched = preg_match_all('#// error:(.+)#', $row, $matches);
77+
$matched = preg_match_all('#// error:(.*?)(?=// error:|$)#', $row, $matches);
7978

8079
if ($matched === false) {
8180
throw new LogicException('Error while matching errors');
8281
}
8382

84-
if ($matched === 0) {
85-
continue;
86-
}
87-
8883
foreach ($matches[1] as $error) {
89-
$actualLine = $line + 1;
90-
$key = sprintf('%04d', $actualLine) . '-' . uniqid();
91-
$expectedErrors[$key] = $this->formatErrorForAssert(trim($error), $actualLine);
84+
$expectedErrors[] = $this->formatErrorForAssert(trim($error), $line + 1);
9285
}
9386
}
9487

95-
ksort($expectedErrors);
96-
97-
return array_values($expectedErrors);
88+
return $expectedErrors;
9889
}
9990

10091
private function formatErrorForAssert(string $message, int $line): string

tests/Rule/Data/DisallowDivisionByLiteralZeroRule/code.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,13 @@ function testDivision(): void
1212

1313
$invalidDivision = $a / 0; // error: Division by literal zero is not allowed
1414
$anotherInvalidDivision = 5 / 0; // error: Division by literal zero is not allowed
15-
}
1615

16+
// Test multiple errors on same line - each gets detected separately
17+
$multipleErrors = ($a / 0) + (5 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
18+
19+
// Test three errors on one line
20+
$threeErrors = ($a / 0) + (5 / 0) + (10 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
21+
22+
// Test mixed valid/invalid on same line (should only have one error)
23+
$mixedLine = ($a / 2) + (5 / 0); // error: Division by literal zero is not allowed
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace DisallowDivisionByLiteralZeroRule;
4+
5+
function testMultipleErrorsPerLine(): void
6+
{
7+
$a = 10;
8+
9+
// Line with two errors
10+
$twoErrors = ($a / 0) + (5 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
11+
12+
// Line with three errors
13+
$threeErrors = ($a / 0) + (5 / 0) + (10 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
14+
15+
// Line with four errors
16+
$fourErrors = ($a / 0) + (5 / 0) + (10 / 0) + (15 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
17+
18+
// Mixed valid and invalid operations (only invalid ones should error)
19+
$mixed = ($a / 2) + (5 / 0) + ($a / 3) + (10 / 0); // error: Division by literal zero is not allowed // error: Division by literal zero is not allowed
20+
}
21+

tests/RuleTestCaseTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,12 @@ public function testRule(): void
2222
$this->analyseFile(__DIR__ . '/Rule/Data/DisallowDivisionByLiteralZeroRule/code.php');
2323
}
2424

25-
}
25+
public function testMultipleErrorsOnSameLine(): void
26+
{
27+
// Create a dedicated test file for multiple errors demonstration
28+
$testFile = __DIR__ . '/Rule/Data/DisallowDivisionByLiteralZeroRule/multiple-errors.php';
2629

30+
$this->analyseFile($testFile);
31+
}
32+
33+
}

0 commit comments

Comments
 (0)