Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/Testing/RuleTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,20 @@ static function (Error $error) use ($strictlyTypedSprintf): string {
$actualErrors,
);

$assertionMessage = sprintf(
'Errors reported in %s do not match the expected errors.',
implode(', ', array_map([$this->getFileHelper(), 'normalizePath'], $files)),
);
$expectedErrorsString = implode("\n", $expectedErrors) . "\n";
$actualErrorsString = implode("\n", $actualErrors) . "\n";

if (count($delayedErrors) === 0) {
$this->assertSame($expectedErrorsString, $actualErrorsString);
$this->assertSame($expectedErrorsString, $actualErrorsString, $assertionMessage);
return;
}

if ($expectedErrorsString === $actualErrorsString) {
$this->assertSame($expectedErrorsString, $actualErrorsString);
$this->assertSame($expectedErrorsString, $actualErrorsString, $assertionMessage);
return;
}

Expand All @@ -244,7 +248,7 @@ static function (Error $error) use ($strictlyTypedSprintf): string {
$actualErrorsString .= sprintf("* %s\n", $delayedError->getMessage());
}

$this->assertSame($expectedErrorsString, $actualErrorsString);
$this->assertSame($expectedErrorsString, $actualErrorsString, $assertionMessage);
}

/**
Expand Down Expand Up @@ -308,8 +312,8 @@ public function fixOtherFile(string $file, string $fixedFile, string $expectedFi
}

$patchResult = $patcher->apply($contentsByFile, $diffGroups);
$this->assertGreaterThan(0, $patchResult['appliedCount'], 'Some fixes overlap and could not be applied together.');
$this->assertLessThan(self::FIX_ROUNDS_LIMIT, $round, sprintf('Fixing did not finish after %d rounds.', $round));
$this->assertGreaterThan(0, $patchResult['appliedCount'], sprintf('Some fixes in %s overlap and could not be applied together.', $fixedFile));
$this->assertLessThan(self::FIX_ROUNDS_LIMIT, $round, sprintf('Fixing %s did not finish after %d rounds.', $fixedFile, $round));
$contentsByFile = $patchResult['contents'];

// a new directory every round, so nothing cached for the contents of an earlier round is reused;
Expand All @@ -330,7 +334,11 @@ public function fixOtherFile(string $file, string $fixedFile, string $expectedFi

$fixedFileContents = FileReader::read($expectedFile);

$this->assertSame($this->normalizeLineEndings($fixedFileContents), $this->normalizeLineEndings($contentsByFile[$fixedFile]));
$this->assertSame(
$this->normalizeLineEndings($fixedFileContents),
$this->normalizeLineEndings($contentsByFile[$fixedFile]),
sprintf('Fixed contents of %s do not match the expected contents in %s.', $fixedFile, $fileHelper->normalizePath($expectedFile)),
);
}

private function normalizeLineEndings(string $string): string
Expand Down
76 changes: 76 additions & 0 deletions tests/PHPStan/Testing/RuleTestCaseFailureMessageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php declare(strict_types = 1);

namespace PHPStan\Testing;

use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPUnit\Framework\ExpectationFailedException;
use function realpath;

/**
* @extends RuleTestCase<Rule<String_>>
*/
final class RuleTestCaseFailureMessageTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new /** @implements Rule<String_> */ class implements Rule {

public function getNodeType(): string
{
return String_::class;
}

/**
* @param String_ $node
*/
public function processNode(Node $node, Scope $scope): array
{
if ($node->value !== 'foo') {
return [];
}

return [
RuleErrorBuilder::message('Foo string.')
->identifier('test.fooString')
->fixNode($node, static fn (String_ $node) => new String_('bar'))
->build(),
];
}

};
}

public function testFixFailureMentionsFiles(): void
{
$file = __DIR__ . '/data/rule-test-case-fix.php';
$expectedFile = __DIR__ . '/data/rule-test-case-fix.php.fixed';
try {
$this->fix($file, $expectedFile);
} catch (ExpectationFailedException $e) {
$this->assertStringContainsString((string) realpath($file), $e->getMessage());
$this->assertStringContainsString((string) realpath($expectedFile), $e->getMessage());
return;
}

$this->fail('fix() should have failed.');
}

public function testAnalyseFailureMentionsFiles(): void
{
$file = __DIR__ . '/data/rule-test-case-fix.php';
try {
$this->analyse([$file], []);
} catch (ExpectationFailedException $e) {
$this->assertStringContainsString((string) realpath($file), $e->getMessage());
return;
}

$this->fail('analyse() should have failed.');
}

}
5 changes: 5 additions & 0 deletions tests/PHPStan/Testing/data/rule-test-case-fix.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace RuleTestCaseFix;

echo 'foo';
5 changes: 5 additions & 0 deletions tests/PHPStan/Testing/data/rule-test-case-fix.php.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace RuleTestCaseFix;

echo 'baz';