phpstan / phpstan-symfony

Symfony extension for PHPStan
MIT License
714 stars 89 forks source link

ExampleCommand not found when running unit tests #206

Open leongersen opened 3 years ago

leongersen commented 3 years ago

I'm trying to run the unit tests locally, and I'm running into a strange error.

I've cloned the project, and ran composer install and make. The unit test step then fails in the two tests using tests/Rules/Symfony/console_application_loader.php. I've checked, and the class is defined in the generated autoloader. The file also is loaded. I feel like I'm overlooking something, but I can't put my finger on it.

1) PHPStan\Rules\Symfony\UndefinedArgumentRuleTest::testGetArgument
Error: Class 'PHPStan\Rules\Symfony\ExampleCommand' not found

/var/www/html/phpstan-symfony/tests/Rules/Symfony/console_application_loader.php:9
/var/www/html/phpstan-symfony/src/Symfony/ConsoleApplicationResolver.php:39
/var/www/html/phpstan-symfony/src/Symfony/ConsoleApplicationResolver.php:24
/var/www/html/phpstan-symfony/tests/Rules/Symfony/UndefinedArgumentRuleTest.php:18
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Testing/RuleTestCase.php:40
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Testing/RuleTestCase.php:56
/var/www/html/phpstan-symfony/tests/Rules/Symfony/UndefinedArgumentRuleTest.php:29

2) PHPStan\Rules\Symfony\UndefinedOptionRuleTest::testGetArgument
Error: Class 'PHPStan\Rules\Symfony\ExampleCommand' not found
ondrejmirtes commented 3 years ago

Hi, it works in the CI and locally for me too so I don't know what advice to give here...

leongersen commented 3 years ago

The issue seems to be whether/when the file gets loaded. ExampleCommand.php is analysed in:

InvalidArgumentDefaultValueRuleTest
InvalidOptionDefaultValueRuleTest

and loaded and analysed in:

UndefinedArgumentRuleTest
UndefinedOptionRuleTest

If I disable the first two tests, the suite runs fine. If they analyse ExampleCommand.php, the class no longer gets loaded in the latter two tests.

leongersen commented 3 years ago

I can resolve this issue and run all tests by forcing the file to load properly in tests/bootstrap.php (require_once __DIR__ . '/Rules/Symfony/ExampleCommand.php';).

I then run into the next loading issue when running PhpStan itself:

 Line   tests/Rules/Symfony/ContainerInterfacePrivateServiceRuleFakeTest.php
 ------ ----------------------------------------------------------------------
         Class PHPUnit\Framework\SelfDescribing not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  23     Class PHPUnit\Framework\SelfDescribing not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols

...
ondrejmirtes commented 3 years ago

Would be nicer if the class got picked up my Composer autoloader.

leongersen commented 3 years ago

If I use the same bootstrap file for PHPStan, and force loading of SelfDescribing, I can resolve the second issue as well.

    bootstrapFiles:
        - tests/bootstrap.php
require_once __DIR__ . '/../vendor/phpunit/phpunit/src/Framework/SelfDescribing.php';

I have no idea why this is not working in the regular autoloader. There's nothing out of the ordinary in my setup (PHP 7.4.20, Composer 2.1.11), and I don't see why it'd work differently in the CI.

leongersen commented 3 years ago

There are two multiple autoloaders registring, the regular one for phpstan-symfony, and the one from phpstan.phar (with phar:///... paths in it's classmap). It seems to me like the latter should not be trying to autoload the file. Instrumenting the ClassLoader with a stacktrace yields the following:

1) PHPStan\Rules\Symfony\InvalidArgumentDefaultValueRuleTest::testGetArgument
Exception: Failed to autoload:

phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php:221
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php:50
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php:233
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php:116
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/ClassWhitelistSourceLocator.php:32
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.php:31
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php:31
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflector/ClassReflector.php:39
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/Reflector/MemoizingClassReflector.php:25
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/BetterReflectionProvider.php:111
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ReflectionProvider/ChainReflectionProvider.php:25
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ReflectionProvider/MemoizingReflectionProvider.php:31
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php:1157
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php:473
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php:249
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php:464
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php:217
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php:149
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Analyser.php:52
phar:///var/www/html/phpstan-symfony/vendor/phpstan/phpstan/phpstan.phar/src/Testing/RuleTestCase.php:56
/var/www/html/phpstan-symfony/tests/Rules/Symfony/InvalidArgumentDefaultValueRuleTest.php:27