Skip to content

Commit

Permalink
Optimize NodeScopeResolverTest
Browse files Browse the repository at this point in the history
  • Loading branch information
schlndh authored Sep 16, 2024
1 parent 92a951f commit 83bf3ab
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 105 deletions.
23 changes: 18 additions & 5 deletions src/Testing/TypeInferenceTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,25 +278,38 @@ public static function gatherAssertTypes(string $file): array
* @return array<string, mixed[]>
*/
public static function gatherAssertTypesFromDirectory(string $directory): array
{
$asserts = [];
foreach (self::findTestDataFilesFromDirectory($directory) as $path) {
foreach (self::gatherAssertTypes($path) as $key => $assert) {
$asserts[$key] = $assert;
}
}

return $asserts;
}

/**
* @return list<string>
*/
public static function findTestDataFilesFromDirectory(string $directory): array
{
if (!is_dir($directory)) {
self::fail(sprintf('Directory %s does not exist.', $directory));
}

$finder = new Finder();
$finder->followLinks();
$asserts = [];
$files = [];
foreach ($finder->files()->name('*.php')->in($directory) as $fileInfo) {
$path = $fileInfo->getPathname();
if (self::isFileLintSkipped($path)) {
continue;
}
foreach (self::gatherAssertTypes($path) as $key => $assert) {
$asserts[$key] = $assert;
}
$files[] = $path;
}

return $asserts;
return $files;
}

/**
Expand Down
255 changes: 155 additions & 100 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,87 @@
use EnumTypeAssertions\Foo;
use PHPStan\Testing\TypeInferenceTestCase;
use stdClass;
use function array_shift;
use function define;
use function dirname;
use function implode;
use function sprintf;
use function str_starts_with;
use function strlen;
use function substr;
use const PHP_INT_SIZE;
use const PHP_VERSION_ID;

class NodeScopeResolverTest extends TypeInferenceTestCase
{

public function dataFileAsserts(): iterable
/**
* @return iterable<string>
*/
private static function findTestFiles(): iterable
{
yield from $this->gatherAssertTypesFromDirectory(__DIR__ . '/nsrt');
foreach (self::findTestDataFilesFromDirectory(__DIR__ . '/nsrt') as $testFile) {
yield $testFile;
}

if (PHP_VERSION_ID < 80200 && PHP_VERSION_ID >= 80100) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/enum-reflection-php81.php');
yield __DIR__ . '/data/enum-reflection-php81.php';
}

if (PHP_VERSION_ID < 80000 && PHP_VERSION_ID >= 70400) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4902.php');
yield __DIR__ . '/data/bug-4902.php';
}

if (PHP_VERSION_ID < 80300) {
if (PHP_VERSION_ID >= 80200) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php82.php');
yield __DIR__ . '/data/mb-strlen-php82.php';
} elseif (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php8.php');
yield __DIR__ . '/data/mb-strlen-php8.php';
} elseif (PHP_VERSION_ID < 70300) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php72.php');
yield __DIR__ . '/data/mb-strlen-php72.php';
} else {
yield from $this->gatherAssertTypes(__DIR__ . '/data/mb-strlen-php73.php');
yield __DIR__ . '/data/mb-strlen-php73.php';
}
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-6856.php');
yield __DIR__ . '/../Rules/Methods/data/bug-6856.php';

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/unionTypes.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/mixedType.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Reflection/data/staticReturnType.php');
yield __DIR__ . '/../Reflection/data/unionTypes.php';
yield __DIR__ . '/../Reflection/data/mixedType.php';
yield __DIR__ . '/../Reflection/data/staticReturnType.php';
}

if (PHP_INT_SIZE === 8) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/predefined-constants-64bit.php');
yield __DIR__ . '/data/predefined-constants-64bit.php';
} else {
yield from $this->gatherAssertTypes(__DIR__ . '/data/predefined-constants-32bit.php');
yield __DIR__ . '/data/predefined-constants-32bit.php';
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-10577.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-10610.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-2550.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/bug-3777.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-4552.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/infer-array-key.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Generics/data/bug-3769.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Generics/data/bug-6301.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-4643.php');
yield __DIR__ . '/../Rules/Variables/data/bug-10577.php';
yield __DIR__ . '/../Rules/Variables/data/bug-10610.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-2550.php';
yield __DIR__ . '/../Rules/Properties/data/bug-3777.php';
yield __DIR__ . '/../Rules/Methods/data/bug-4552.php';
yield __DIR__ . '/../Rules/Methods/data/infer-array-key.php';
yield __DIR__ . '/../Rules/Generics/data/bug-3769.php';
yield __DIR__ . '/../Rules/Generics/data/bug-6301.php';
yield __DIR__ . '/../Rules/PhpDoc/data/bug-4643.php';

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-4857.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-4857.php';
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5089.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/unable-to-resolve-callback-parameter-type.php');
yield __DIR__ . '/../Rules/Methods/data/bug-5089.php';
yield __DIR__ . '/../Rules/Methods/data/unable-to-resolve-callback-parameter-type.php';

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/varying-acceptor.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-4415.php');
yield __DIR__ . '/../Rules/Functions/data/varying-acceptor.php';
yield __DIR__ . '/../Rules/Methods/data/bug-4415.php';
if (PHP_VERSION_ID >= 70400) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5372.php');
yield __DIR__ . '/../Rules/Methods/data/bug-5372.php';
}
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5372_2.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5562.php');
yield __DIR__ . '/../Rules/Arrays/data/bug-5372_2.php';
yield __DIR__ . '/../Rules/Methods/data/bug-5562.php';

if (PHP_VERSION_ID >= 80100) {
define('TEST_OBJECT_CONSTANT', new stdClass());
Expand All @@ -82,124 +94,167 @@ public function dataFileAsserts(): iterable
define('TEST_FALSE_CONSTANT', false);
define('TEST_ARRAY_CONSTANT', [true, false, null]);
define('TEST_ENUM_CONSTANT', Foo::ONE);
yield from $this->gatherAssertTypes(__DIR__ . '/data/new-in-initializers-runtime.php');
yield __DIR__ . '/data/new-in-initializers-runtime.php';
}

if (PHP_VERSION_ID >= 70400) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-6473.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-6473.php';
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/filter-iterator-child-class.php');
yield __DIR__ . '/../Rules/Methods/data/filter-iterator-child-class.php';

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5749.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-5757.php');
yield __DIR__ . '/../Rules/Methods/data/bug-5749.php';
yield __DIR__ . '/../Rules/Methods/data/bug-5757.php';

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-6635.php');
yield __DIR__ . '/../Rules/Methods/data/bug-6635.php';
}

if (PHP_VERSION_ID >= 80300) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Constants/data/bug-10212.php');
yield __DIR__ . '/../Rules/Constants/data/bug-10212.php';
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-3284.php');
yield __DIR__ . '/../Rules/Methods/data/bug-3284.php';

if (PHP_VERSION_ID >= 80300) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/return-type-class-constant.php');
yield __DIR__ . '/../Rules/Methods/data/return-type-class-constant.php';
}

//define('ALREADY_DEFINED_CONSTANT', true);
//yield from $this->gatherAssertTypes(__DIR__ . '/data/already-defined-constant.php');

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/conditional-complex-templates.php');
yield __DIR__ . '/../Rules/Methods/data/conditional-complex-templates.php';

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-7511.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/trait-mixin.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/trait-mixin.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-4708.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-7156.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6364.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-5758.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-3931.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-7417.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-7469.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-3391.php');
yield __DIR__ . '/../Rules/Methods/data/bug-7511.php';
yield __DIR__ . '/../Rules/Properties/data/trait-mixin.php';
yield __DIR__ . '/../Rules/Methods/data/trait-mixin.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-4708.php';
yield __DIR__ . '/../Rules/Functions/data/bug-7156.php';
yield __DIR__ . '/../Rules/Arrays/data/bug-6364.php';
yield __DIR__ . '/../Rules/Arrays/data/bug-5758.php';
yield __DIR__ . '/../Rules/Functions/data/bug-3931.php';
yield __DIR__ . '/../Rules/Variables/data/bug-7417.php';
yield __DIR__ . '/../Rules/Arrays/data/bug-7469.php';
yield __DIR__ . '/../Rules/Variables/data/bug-3391.php';

if (PHP_VERSION_ID >= 70400) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-anonymous-function-method-constant.php');
yield __DIR__ . '/../Rules/Functions/data/bug-anonymous-function-method-constant.php';
}

if (PHP_VERSION_ID >= 80200) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/true-typehint.php');
yield __DIR__ . '/../Rules/Methods/data/true-typehint.php';
}
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6000.php');
yield __DIR__ . '/../Rules/Arrays/data/bug-6000.php';

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/slevomat-foreach-unset-bug.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/slevomat-foreach-array-key-exists-bug.php');
yield __DIR__ . '/../Rules/Arrays/data/slevomat-foreach-unset-bug.php';
yield __DIR__ . '/../Rules/Arrays/data/slevomat-foreach-array-key-exists-bug.php';

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-7898.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-7898.php';
}

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-7823.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Analyser/data/is-resource-specified.php');

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-7954.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/docblock-assert-equality.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/bug-7839.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-5333.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-8174.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8169.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-8280.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8277.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-8113.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-8389.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-8467a.php');
yield __DIR__ . '/../Rules/Functions/data/bug-7823.php';
}

yield __DIR__ . '/../Analyser/data/is-resource-specified.php';

yield __DIR__ . '/../Rules/Arrays/data/bug-7954.php';
yield __DIR__ . '/../Rules/Comparison/data/docblock-assert-equality.php';
yield __DIR__ . '/../Rules/Properties/data/bug-7839.php';
yield __DIR__ . '/../Rules/Classes/data/bug-5333.php';
yield __DIR__ . '/../Rules/Methods/data/bug-8174.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-8169.php';
yield __DIR__ . '/../Rules/Functions/data/bug-8280.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-8277.php';
yield __DIR__ . '/../Rules/Variables/data/bug-8113.php';
yield __DIR__ . '/../Rules/Functions/data/bug-8389.php';
yield __DIR__ . '/../Rules/Arrays/data/bug-8467a.php';
if (PHP_VERSION_ID >= 80100) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8485.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-8485.php';
}

if (PHP_VERSION_ID >= 80100) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-9007.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-9007.php';
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/DeadCode/data/bug-8620.php');
yield __DIR__ . '/../Rules/DeadCode/data/bug-8620.php';

if (PHP_VERSION_ID >= 80200) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Constants/data/bug-8957.php');
yield __DIR__ . '/../Rules/Constants/data/bug-8957.php';
}

if (PHP_VERSION_ID >= 80100) {
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-9499.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-8609-function.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-5365.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-6551.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-9403.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-9542.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-9803.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/PhpDoc/data/bug-10594.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591-method-tag.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/bug-11591-property-tag.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Classes/data/mixin-trait-use.php');
yield __DIR__ . '/../Rules/Comparison/data/bug-9499.php';
}

yield __DIR__ . '/../Rules/PhpDoc/data/bug-8609-function.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-5365.php';
yield __DIR__ . '/../Rules/Comparison/data/bug-6551.php';
yield __DIR__ . '/../Rules/Variables/data/bug-9403.php';
yield __DIR__ . '/../Rules/Methods/data/bug-9542.php';
yield __DIR__ . '/../Rules/Functions/data/bug-9803.php';
yield __DIR__ . '/../Rules/PhpDoc/data/bug-10594.php';
yield __DIR__ . '/../Rules/Classes/data/bug-11591.php';
yield __DIR__ . '/../Rules/Classes/data/bug-11591-method-tag.php';
yield __DIR__ . '/../Rules/Classes/data/bug-11591-property-tag.php';
yield __DIR__ . '/../Rules/Classes/data/mixin-trait-use.php';
}

/**
* @dataProvider dataFileAsserts
* @param mixed ...$args
* @return iterable<string, array{string}>
*/
public function testFileAsserts(
string $assertType,
string $file,
...$args,
): void
public static function dataFile(): iterable
{
$this->assertFileAsserts($assertType, $file, ...$args);
$base = dirname(__DIR__, 3) . '/';
$baseLength = strlen($base);

foreach (self::findTestFiles() as $file) {
$testName = $file;
if (str_starts_with($file, $base)) {
$testName = substr($file, $baseLength);
}

yield $testName => [$file];
}
}

/**
* @dataProvider dataFile
*/
public function testFile(string $file): void
{
$asserts = $this->gatherAssertTypes($file);
$this->assertNotCount(0, $asserts, sprintf('File %s has no asserts.', $file));
$failures = [];

foreach ($asserts as $args) {
$assertType = array_shift($args);
$file = array_shift($args);

if ($assertType === 'type') {
$expected = $args[0];
$actual = $args[1];

if ($expected !== $actual) {
$failures[] = sprintf("Line %d:\nExpected: %s\nActual: %s\n", $args[2], $expected, $actual);
}
} elseif ($assertType === 'variableCertainty') {
$expectedCertainty = $args[0];
$actualCertainty = $args[1];
$variableName = $args[2];

if ($expectedCertainty->equals($actualCertainty) !== true) {
$failures[] = sprintf("Certainty of variable \$%s on line %d:\nExpected: %s\nActual: %s\n", $variableName, $args[3], $expectedCertainty->describe(), $actualCertainty->describe());
}
}
}

if ($failures === []) {
return;
}

self::fail(sprintf("Failed assertions in %s:\n\n%s", $file, implode("\n", $failures)));
}

public static function getAdditionalConfigFiles(): array
Expand Down

0 comments on commit 83bf3ab

Please sign in to comment.