diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml index 6129f6dc..667bd150 100644 --- a/.github/workflows/integrate.yaml +++ b/.github/workflows/integrate.yaml @@ -311,3 +311,6 @@ jobs: - name: "Run unit tests with phpunit/phpunit" run: "vendor/bin/phpunit --colors=always --configuration=test/Unit/phpunit.xml" + + - name: "Run end-to-end tests with phpunit/phpunit" + run: "vendor/bin/phpunit --colors=always --configuration=test/EndToEnd/phpunit.xml" diff --git a/Makefile b/Makefile index 81a9c8ff..39dab100 100644 --- a/Makefile +++ b/Makefile @@ -32,9 +32,10 @@ static-code-analysis-baseline: vendor ## Generates a baseline for static code an vendor/bin/psalm --config=psalm.xml --set-baseline=psalm-baseline.xml .PHONY: tests -tests: vendor ## Runs unit tests with phpunit/phpunit +tests: vendor ## Runs unit and end-to-end tests with phpunit/phpunit mkdir -p .build/phpunit vendor/bin/phpunit --configuration=test/Unit/phpunit.xml + vendor/bin/phpunit --configuration=test/EndToEnd/phpunit.xml vendor: composer.json composer.lock composer validate --strict diff --git a/composer.json b/composer.json index 96fe374b..b1e99d55 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "phpunit/phpunit": "^9.5.27", "psalm/plugin-phpunit": "~0.18.4", "symfony/filesystem": "^5.0.0 || ^6.0.0", + "symfony/process": "^5.0.0 || ^6.0.0", "vimeo/psalm": "^5.4.0" }, "autoload": { diff --git a/composer.lock b/composer.lock index 9c48498c..02fa2dd0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a600ca8c849c1dfc15689ffe5585bcae", + "content-hash": "2a2e8f16725addadee5948e16fa1c631", "packages": [ { "name": "composer/pcre", diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 38372f47..1cfb4970 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -10,6 +10,11 @@ $rules + + + Console\Command\FixCommandExitStatusCalculator::EXIT_STATUS_FLAG_HAS_INVALID_CONFIG + + new FixerFactory() diff --git a/test/EndToEnd/RuleSet/AbstractRuleSetTestCase.php b/test/EndToEnd/RuleSet/AbstractRuleSetTestCase.php new file mode 100644 index 00000000..332aa9ae --- /dev/null +++ b/test/EndToEnd/RuleSet/AbstractRuleSetTestCase.php @@ -0,0 +1,151 @@ +mkdir(self::temporaryDirectory()); + + self::fileSystem()->dumpFile( + self::configPath(), + self::configContents(), + ); + } + + protected function tearDown(): void + { + self::fileSystem()->remove(self::temporaryDirectory()); + } + + final public function testConfigurationIsConsideredValid(): void + { + $process = new Process\Process([ + 'vendor/bin/php-cs-fixer', + 'fix', + \sprintf( + '--config=%s', + self::configPath(), + ), + '--dry-run', + ]); + + $process->run(); + + $exitCode = $process->getExitCode(); + + self::assertNotNull($exitCode); + self::assertSame(0, Console\Command\FixCommandExitStatusCalculator::EXIT_STATUS_FLAG_HAS_INVALID_CONFIG & $exitCode, \sprintf( + 'Failed asserting that the configuration in "%s" is considered valid by friendsofphp/php-cs-fixer.', + self::className(), + )); + } + + private static function fileSystem(): Filesystem\Filesystem + { + return new Filesystem\Filesystem(); + } + + private static function configPath(): string + { + return \sprintf( + '%s/.php-cs-fixer.php', + self::temporaryDirectory(), + ); + } + + private static function configContents(): string + { + return \sprintf( + <<<'PHP' +getFinder() + ->exclude([ + '.build/', + '.github/', + '.notes/', + ]) + ->ignoreDotFiles(false) + ->in('%s') + ->name('.php-cs-fixer.php'); + +$config->setUsingCache(false); + +return $config; +PHP + , + self::className(), + self::projectDirectory(), + ); + } + + /** + * @psalm-return class-string + * + * @throws \RuntimeException + */ + private static function className(): string + { + $className = \preg_replace( + '/Test$/', + '', + \str_replace( + '\Test\EndToEnd', + '', + static::class, + ), + ); + + if (!\is_string($className)) { + throw new \RuntimeException(\sprintf( + 'Failed resolving class name from test class name "%s".', + static::class, + )); + } + + if (!\class_exists($className)) { + throw new \RuntimeException(\sprintf( + 'Class name "%s" resolved from test class name "%s" does not reference a class that exists.', + $className, + static::class, + )); + } + + return $className; + } + + private static function projectDirectory(): string + { + return __DIR__ . '/../../..'; + } + + private static function temporaryDirectory(): string + { + return __DIR__ . '/../../../.build/test'; + } +} diff --git a/test/EndToEnd/RuleSet/Php80Test.php b/test/EndToEnd/RuleSet/Php80Test.php new file mode 100644 index 00000000..071562ed --- /dev/null +++ b/test/EndToEnd/RuleSet/Php80Test.php @@ -0,0 +1,25 @@ + + + + . + + +