Skip to content

Commit

Permalink
RuleTestCase: ability to autofix errors (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal committed Dec 22, 2023
1 parent 3c286ce commit 6103ed1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
4 changes: 3 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@
</rule>
<rule ref="SlevomatCodingStandard.Commenting.EmptyComment"/>
<rule ref="SlevomatCodingStandard.Commenting.DisallowOneLinePropertyDocComment"/>
<rule ref="SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration"/>
<rule ref="SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration">
<exclude name="SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable"/>
</rule>
<rule ref="SlevomatCodingStandard.Commenting.UselessInheritDocComment"/>
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenComments">
<properties>
Expand Down
72 changes: 60 additions & 12 deletions tests/RuleTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
use PHPStan\Testing\RuleTestCase as OriginalRuleTestCase;
use function explode;
use function file_get_contents;
use function file_put_contents;
use function implode;
use function preg_match;
use function preg_match_all;
use function preg_replace;
use function sprintf;
use function trim;

Expand All @@ -20,9 +23,16 @@
abstract class RuleTestCase extends OriginalRuleTestCase
{

protected function analyseFile(string $file): void
protected function analyseFile(string $file, bool $autofix = false): void
{
$actualErrors = $this->processActualErrors($this->gatherAnalyserErrors([$file]));
$analyserErrors = $this->gatherAnalyserErrors([$file]);

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

$actualErrors = $this->processActualErrors($analyserErrors);
$expectedErrors = $this->parseExpectedErrors($file);

self::assertSame(
Expand Down Expand Up @@ -54,18 +64,10 @@ protected function processActualErrors(array $actualErrors): array
*/
private function parseExpectedErrors(string $file): array
{
$fileData = file_get_contents($file);

if ($fileData === false) {
throw new LogicException('Error while reading data from ' . $file);
}

$fileDataLines = explode("\n", $fileData);

$fileLines = $this->getFileLines($file);
$expectedErrors = [];

foreach ($fileDataLines as $line => $row) {
$matches = [];
foreach ($fileLines as $line => $row) {
/** @var array{0: list<string>, 1: list<string>} $matches */
$matched = preg_match_all('#// error:(.+)#', $row, $matches);

Expand All @@ -90,4 +92,50 @@ private function formatErrorForAssert(string $message, ?int $line): string
return sprintf('%02d: %s', $line ?? -1, $message);
}

/**
* @param list<Error> $analyserErrors
*/
private function autofix(string $file, array $analyserErrors): void
{
$errorsByLines = [];

foreach ($analyserErrors as $analyserError) {
$errorsByLines[$analyserError->getLine()] = $analyserError;
}

$fileLines = $this->getFileLines($file);

foreach ($fileLines as $line => &$row) {
if (!isset($errorsByLines[$line + 1])) {
continue;
}

$errorCommentPattern = '~ ?//.*$~';
$errorMessage = $errorsByLines[$line + 1]->getMessage();
$errorComment = ' // error: ' . $errorMessage;

if (preg_match($errorCommentPattern, $row) === 1) {
$row = preg_replace($errorCommentPattern, $errorComment, $row);
} else {
$row .= $errorComment;
}
}

file_put_contents($file, implode("\n", $fileLines));
}

/**
* @return list<string>
*/
private function getFileLines(string $file): array
{
$fileData = file_get_contents($file);

if ($fileData === false) {
throw new LogicException('Error while reading data from ' . $file);
}

return explode("\n", $fileData);
}

}

0 comments on commit 6103ed1

Please sign in to comment.