-
Notifications
You must be signed in to change notification settings - Fork 472
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
49d8c4f
commit 6f6ea7e
Showing
7 changed files
with
319 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
tests/PHPStan/Analyser/traitsCachingIssue/TraitsCachingIssueIntegrationTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Analyser; | ||
|
||
use PHPStan\File\FileReader; | ||
use PHPStan\Testing\TestCase; | ||
use RecursiveDirectoryIterator; | ||
use RecursiveIteratorIterator; | ||
|
||
class TraitsCachingIssueIntegrationTest extends TestCase | ||
{ | ||
|
||
/** @var string|null */ | ||
private $originalTraitOneContents; | ||
|
||
/** @var string|null */ | ||
private $originalTraitTwoContents; | ||
|
||
public function tearDown(): void | ||
{ | ||
$this->deleteCache(); | ||
|
||
if ($this->originalTraitOneContents !== null) { | ||
$this->revertTrait(__DIR__ . '/data/TraitOne.php', $this->originalTraitOneContents); | ||
} | ||
|
||
if ($this->originalTraitTwoContents !== null) { | ||
$this->revertTrait(__DIR__ . '/data/TraitTwo.php', $this->originalTraitTwoContents); | ||
} | ||
} | ||
|
||
public function dataCachingIssue(): array | ||
{ | ||
return [ | ||
[ | ||
false, | ||
false, | ||
[], | ||
], | ||
[ | ||
false, | ||
true, | ||
[ | ||
'Method class@anonymous/TestClassUsingTrait.php:20::doBar() should return stdClass but returns Exception.', | ||
], | ||
], | ||
[ | ||
true, | ||
false, | ||
[ | ||
'Method TraitsCachingIssue\TestClassUsingTrait::doBar() should return stdClass but returns Exception.', | ||
], | ||
], | ||
[ | ||
true, | ||
true, | ||
[ | ||
'Method TraitsCachingIssue\TestClassUsingTrait::doBar() should return stdClass but returns Exception.', | ||
'Method class@anonymous/TestClassUsingTrait.php:20::doBar() should return stdClass but returns Exception.', | ||
], | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dataCachingIssue | ||
* @param bool $changeOne | ||
* @param bool $changeTwo | ||
* @param string[] $expectedErrors | ||
*/ | ||
public function testCachingIssue( | ||
bool $changeOne, | ||
bool $changeTwo, | ||
array $expectedErrors | ||
): void | ||
{ | ||
$this->deleteCache(); | ||
[$statusCode, $errors] = $this->runPhpStan(); | ||
$this->assertSame([], $errors); | ||
$this->assertSame(0, $statusCode); | ||
|
||
if ($changeOne) { | ||
$this->originalTraitOneContents = $this->changeTrait(__DIR__ . '/data/TraitOne.php'); | ||
} | ||
if ($changeTwo) { | ||
$this->originalTraitTwoContents = $this->changeTrait(__DIR__ . '/data/TraitTwo.php'); | ||
} | ||
|
||
$errorPath = __DIR__ . '/data/TestClassUsingTrait.php'; | ||
[$statusCode, $errors] = $this->runPhpStan(); | ||
|
||
if (count($expectedErrors) === 0) { | ||
$this->assertSame(0, $statusCode); | ||
$this->assertArrayNotHasKey($errorPath, $errors); | ||
return; | ||
} | ||
|
||
$this->assertSame(1, $statusCode); | ||
$this->assertArrayHasKey($errorPath, $errors); | ||
$this->assertSame(count($expectedErrors), $errors[$errorPath]['errors']); | ||
|
||
foreach ($errors[$errorPath]['messages'] as $i => $error) { | ||
$this->assertSame($expectedErrors[$i], $error['message']); | ||
} | ||
} | ||
|
||
/** | ||
* @return array{int, mixed[]} | ||
*/ | ||
private function runPhpStan(): array | ||
{ | ||
$phpstanBinPath = __DIR__ . '/../../../../bin/phpstan'; | ||
exec( | ||
sprintf( | ||
'%s %s analyse --no-progress --level 8 --configuration %s --error-format json %s', | ||
escapeshellarg(PHP_BINARY), | ||
$phpstanBinPath, | ||
escapeshellarg(__DIR__ . '/phpstan.neon'), | ||
escapeshellarg(__DIR__ . '/data') | ||
), | ||
$output, | ||
$statusCode | ||
); | ||
$stringOutput = implode("\n", $output); | ||
$json = \Nette\Utils\Json::decode($stringOutput, \Nette\Utils\Json::FORCE_ARRAY); | ||
|
||
return [$statusCode, $json['files']]; | ||
} | ||
|
||
private function deleteCache(): void | ||
{ | ||
$files = new RecursiveIteratorIterator( | ||
new RecursiveDirectoryIterator(__DIR__ . '/tmp/cache', RecursiveDirectoryIterator::SKIP_DOTS), | ||
RecursiveIteratorIterator::CHILD_FIRST | ||
); | ||
|
||
foreach ($files as $fileinfo) { | ||
if ($fileinfo->isDir()) { | ||
rmdir($fileinfo->getRealPath()); | ||
continue; | ||
} | ||
|
||
unlink($fileinfo->getRealPath()); | ||
} | ||
} | ||
|
||
private function changeTrait(string $traitPath): string | ||
{ | ||
$originalTraitContents = FileReader::read($traitPath); | ||
$traitContents = str_replace('use stdClass as Foo;', 'use Exception as Foo;', $originalTraitContents); | ||
$result = file_put_contents($traitPath, $traitContents); | ||
if ($result === false) { | ||
$this->fail(sprintf('Could not save file %s', $traitPath)); | ||
} | ||
|
||
return $originalTraitContents; | ||
} | ||
|
||
private function revertTrait(string $traitPath, string $originalTraitContents): void | ||
{ | ||
$result = file_put_contents($traitPath, $originalTraitContents); | ||
if ($result === false) { | ||
$this->fail(sprintf('Could not save file %s', $traitPath)); | ||
} | ||
} | ||
|
||
} |
34 changes: 34 additions & 0 deletions
34
tests/PHPStan/Analyser/traitsCachingIssue/data/TestClassUsingTrait.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace TraitsCachingIssue; | ||
|
||
class TestClassUsingTrait | ||
{ | ||
|
||
use TraitOne; | ||
|
||
/** | ||
* @return \stdClass | ||
*/ | ||
public function doBar() | ||
{ | ||
return $this->doFoo(); | ||
} | ||
|
||
public function doBaz(): void | ||
{ | ||
$class = new class() { | ||
|
||
use TraitTwo; | ||
|
||
/** | ||
* @return \stdClass | ||
*/ | ||
public function doBar() | ||
{ | ||
return $this->doFoo(); | ||
} | ||
}; | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
tests/PHPStan/Analyser/traitsCachingIssue/data/TraitOne.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace TraitsCachingIssue; | ||
|
||
use stdClass as Foo; | ||
|
||
trait TraitOne | ||
{ | ||
|
||
/** | ||
* @return Foo | ||
*/ | ||
public function doFoo() | ||
{ | ||
return new Foo(); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
tests/PHPStan/Analyser/traitsCachingIssue/data/TraitTwo.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace TraitsCachingIssue; | ||
|
||
use stdClass as Foo; | ||
|
||
trait TraitTwo | ||
{ | ||
|
||
/** | ||
* @return Foo | ||
*/ | ||
public function doFoo() | ||
{ | ||
return new Foo(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
parameters: | ||
tmpDir: tmp | ||
autoload_directories: | ||
- data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* | ||
!.gitignore |