diff --git a/composer.json b/composer.json index 8ba5f95..d715a50 100644 --- a/composer.json +++ b/composer.json @@ -22,9 +22,11 @@ "php": "^7.1", "composer/composer": "^1.6", "composer-plugin-api": "^1.1", - "nikic/php-parser": "^3.0 | ^4.0" + "nikic/php-parser": "^3.0 | ^4.0", + "roave/better-reflection": "^3.1" }, "require-dev": { + "symfony/process": "@stable", "mediact/testing-suite": "@stable", "mikey179/vfsstream": "^1.6", "phpro/grumphp": "~0.1", diff --git a/phpunit.xml b/phpunit.xml index a66b884..5c4659c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -5,6 +5,9 @@ tests + + tests/Regression + diff --git a/src/Candidate/CandidateExtractor.php b/src/Candidate/CandidateExtractor.php index 7bb2765..51ced65 100644 --- a/src/Candidate/CandidateExtractor.php +++ b/src/Candidate/CandidateExtractor.php @@ -11,7 +11,7 @@ use Mediact\DependencyGuard\Php\SymbolInterface; use Mediact\DependencyGuard\Php\SymbolIterator; use Mediact\DependencyGuard\Php\SymbolIteratorInterface; -use ReflectionClass; +use Roave\BetterReflection\Reflection\ReflectionClass; class CandidateExtractor implements CandidateExtractorInterface { @@ -100,7 +100,7 @@ private function extractPackage( $name = $symbol->getName(); if (!array_key_exists($name, $packagesPerSymbol)) { - $reflection = new ReflectionClass($name); + $reflection = ReflectionClass::createFromName($name); $file = $reflection->getFileName(); // This happens for symbols in the current package. diff --git a/src/Composer/Command/DependencyGuardCommand.php b/src/Composer/Command/DependencyGuardCommand.php index 7aa7df2..84596ce 100644 --- a/src/Composer/Command/DependencyGuardCommand.php +++ b/src/Composer/Command/DependencyGuardCommand.php @@ -7,7 +7,6 @@ namespace Mediact\DependencyGuard\Composer\Command; use Composer\Command\BaseCommand; -use Composer\Composer; use Mediact\DependencyGuard\Composer\Command\Exporter\ViolationExporterFactory; use Mediact\DependencyGuard\Composer\Command\Exporter\ViolationExporterFactoryInterface; use Mediact\DependencyGuard\DependencyGuardFactory; @@ -85,37 +84,15 @@ protected function execute( InputInterface $input, OutputInterface $output ): int { - $composer = $this->getComposer(true); - $guard = $this->guardFactory->create(); - - $this->registerAutoloader($composer); + $composer = $this->getComposer(true); + $guard = $this->guardFactory->create(); $violations = $guard->determineViolations($composer); + $exporter = $this->exporterFactory->create($input, $output); - $exporter = $this->exporterFactory->create($input, $output); $exporter->export($violations); return count($violations) > 0 ? static::EXIT_VIOLATIONS : static::EXIT_NO_VIOLATIONS; } - - /** - * Register the autoloader for the current project, so subject classes can - * be automatically loaded. - * - * @param Composer $composer - * - * @return void - */ - private function registerAutoloader(Composer $composer): void - { - $config = $composer->getConfig(); - $vendor = $config->get('vendor-dir', 0); - $autoloader = $vendor . DIRECTORY_SEPARATOR . 'autoload.php'; - - if (is_readable($autoloader)) { - /** @noinspection PhpIncludeInspection */ - require_once $autoloader; - } - } } diff --git a/src/Php/Filter/UserDefinedSymbolFilter.php b/src/Php/Filter/UserDefinedSymbolFilter.php index 39bf001..81b2333 100644 --- a/src/Php/Filter/UserDefinedSymbolFilter.php +++ b/src/Php/Filter/UserDefinedSymbolFilter.php @@ -6,7 +6,7 @@ namespace Mediact\DependencyGuard\Php\Filter; -use ReflectionClass; +use Roave\BetterReflection\Reflection\ReflectionClass; use Throwable; class UserDefinedSymbolFilter implements SymbolFilterInterface @@ -21,7 +21,7 @@ class UserDefinedSymbolFilter implements SymbolFilterInterface public function __invoke(string $symbol): bool { try { - $reflection = new ReflectionClass($symbol); + $reflection = ReflectionClass::createFromName($symbol); } catch (Throwable $e) { return false; } diff --git a/tests/Composer/Command/DependencyGuardCommandTest.php b/tests/Composer/Command/DependencyGuardCommandTest.php index 02451c8..3399a86 100644 --- a/tests/Composer/Command/DependencyGuardCommandTest.php +++ b/tests/Composer/Command/DependencyGuardCommandTest.php @@ -8,6 +8,7 @@ use Composer\Composer; use Composer\Config; +use Composer\EventDispatcher\EventDispatcher; use Mediact\DependencyGuard\Composer\Command\Exporter\ViolationExporterFactoryInterface; use Mediact\DependencyGuard\DependencyGuardFactoryInterface; use Mediact\DependencyGuard\DependencyGuardInterface; @@ -22,6 +23,7 @@ /** * @coversDefaultClass \Mediact\DependencyGuard\Composer\Command\DependencyGuardCommand + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DependencyGuardCommandTest extends TestCase { @@ -64,6 +66,13 @@ private function createComposer(string $vendorDir): Composer ->method('getConfig') ->willReturn($config); + $composer + ->expects(self::any()) + ->method('getEventDispatcher') + ->willReturn( + $this->createMock(EventDispatcher::class) + ); + $config ->expects(self::any()) ->method('get') @@ -82,7 +91,6 @@ private function createComposer(string $vendorDir): Composer * @return void * * @covers ::execute - * @covers ::registerAutoloader */ public function testExecute( ViolationIteratorInterface $violations, diff --git a/tests/GrumPHP/DependencyGuardTest.php b/tests/GrumPHP/DependencyGuardTest.php index 2e58766..50461c0 100644 --- a/tests/GrumPHP/DependencyGuardTest.php +++ b/tests/GrumPHP/DependencyGuardTest.php @@ -99,7 +99,7 @@ public function testCanRunInContext( } /** - * @return ContextInterface[][]|bool[][] + * @return array */ public function contextProvider(): array { @@ -223,7 +223,7 @@ private function createViolations( } /** - * @return DependencyGuardInterface[][]|bool[][] + * @return array */ public function guardProvider(): array { diff --git a/tests/Php/SymbolExtractorTest.php b/tests/Php/SymbolExtractorTest.php index 8044a22..fd265d0 100644 --- a/tests/Php/SymbolExtractorTest.php +++ b/tests/Php/SymbolExtractorTest.php @@ -103,7 +103,7 @@ private function createFileIterator( } /** - * @return Parser[][]|FileIteratorInterface[][] + * @return array */ public function emptyProvider(): array { @@ -164,7 +164,7 @@ private function createFile(string $content): SplFileInfo } /** - * @return Parser[][]|FileIteratorInterface[][] + * @return array */ public function nonParsingFilesProvider(): array { @@ -191,7 +191,7 @@ public function nonParsingFilesProvider(): array } /** - * @return Parser[][]|FileIteratorInterface[][] + * @return array */ public function filledFilesProvider(): array { diff --git a/tests/Php/SymbolTest.php b/tests/Php/SymbolTest.php index 12195dd..5c4e30a 100644 --- a/tests/Php/SymbolTest.php +++ b/tests/Php/SymbolTest.php @@ -76,7 +76,7 @@ public function testConstructor(): void } /** - * @return Name[][]|string[][] + * @return array */ public function nameProvider(): array { @@ -126,7 +126,7 @@ public function testToString(Name $name, string $expected): void } /** - * @return Name[][]|string[][] + * @return array */ public function lineProvider(): array { diff --git a/tests/Php/SymbolTrackerTest.php b/tests/Php/SymbolTrackerTest.php index 5431b2a..61ee6b1 100644 --- a/tests/Php/SymbolTrackerTest.php +++ b/tests/Php/SymbolTrackerTest.php @@ -71,7 +71,7 @@ private function createNode(string $name = null): Node } /** - * @return SymbolFilterInterface[][]|Node[][][]|Node[][] + * @return array */ public function whitelistedNodesProvider(): array { @@ -100,7 +100,7 @@ public function whitelistedNodesProvider(): array } /** - * @return SymbolFilterInterface[][]|Node[][][]|Node[][] + * @return array */ public function blacklistedNodesProvider(): array { diff --git a/tests/Regression/Issue21/Issue21Test.php b/tests/Regression/Issue21/Issue21Test.php new file mode 100644 index 0000000..a4664ab --- /dev/null +++ b/tests/Regression/Issue21/Issue21Test.php @@ -0,0 +1,65 @@ +run() !== 0) { + self::markTestSkipped( + $process->getErrorOutput() + ); + } + } + + /** + * @return void + * @coversNothing + */ + public function testNoFatalsBecauseOfConflicts(): void + { + $process = new Process( + [ + PHP_BINARY, + '../../../bin/dependency-guard' + ], + __DIR__ + ); + + $process->run(); + + self::assertNotContains('Fatal error:', $process->getErrorOutput()); + } + + /** + * @return void + */ + public function tearDown(): void + { + $filesystem = new Filesystem(); + $filesystem->removeDirectory( + __DIR__ . DIRECTORY_SEPARATOR . 'vendor' + ); + } +} diff --git a/tests/Regression/Issue21/composer.json b/tests/Regression/Issue21/composer.json new file mode 100644 index 0000000..83b0063 --- /dev/null +++ b/tests/Regression/Issue21/composer.json @@ -0,0 +1,6 @@ +{ + "name": "issue21/test", + "require": { + "symfony/console": "2.8.45" + } +} diff --git a/tests/Regression/Issue21/composer.lock b/tests/Regression/Issue21/composer.lock new file mode 100644 index 0000000..a768c94 --- /dev/null +++ b/tests/Regression/Issue21/composer.lock @@ -0,0 +1,242 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "d1a5af04abd836c57137646c0b398a5a", + "packages": [ + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "symfony/console", + "version": "v2.8.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0c1fcbb9afb5cff992c982ff99c0434f0146dcfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0c1fcbb9afb5cff992c982ff99c0434f0146dcfc", + "reference": "0c1fcbb9afb5cff992c982ff99c0434f0146dcfc", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/debug": "^2.7.2|~3.0.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:13:39+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-07-30T07:22:48+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/tests/Violation/Filter/ViolationFilterChainTest.php b/tests/Violation/Filter/ViolationFilterChainTest.php index 4c2110f..44a407e 100644 --- a/tests/Violation/Filter/ViolationFilterChainTest.php +++ b/tests/Violation/Filter/ViolationFilterChainTest.php @@ -42,7 +42,7 @@ public function testInvoke( } /** - * @return ViolationInterface[][]|bool[][] + * @return array */ public function emptyProvider(): array { @@ -79,7 +79,7 @@ function (ViolationInterface $subject) use ($violation) : bool { } /** - * @return ViolationInterface[][]|bool[][]|ViolationFilterInterface[][] + * @return array */ public function matchingProvider(): array { @@ -116,7 +116,7 @@ public function matchingProvider(): array } /** - * @return ViolationInterface[][]|bool[][]|ViolationFilterInterface[][] + * @return array */ public function nonMatchingProvider(): array {