From 64dbcf0a261000d71b75288f7df875a42def2a01 Mon Sep 17 00:00:00 2001 From: Fabio Ivona Date: Mon, 20 Feb 2023 23:10:59 +0100 Subject: [PATCH 1/9] init command tweak --- src/Plugins/Init.php | 82 ++++++++++++++++++++++-- stubs/init/{ => Feature}/ExampleTest.php | 0 stubs/init/TestCase.php | 7 ++ stubs/init/Unit/ExampleTest.php | 5 ++ 4 files changed, 89 insertions(+), 5 deletions(-) rename stubs/init/{ => Feature}/ExampleTest.php (100%) create mode 100644 stubs/init/TestCase.php create mode 100644 stubs/init/Unit/ExampleTest.php diff --git a/src/Plugins/Init.php b/src/Plugins/Init.php index 641012e6..9c1c45c5 100644 --- a/src/Plugins/Init.php +++ b/src/Plugins/Init.php @@ -4,6 +4,9 @@ declare(strict_types=1); namespace Pest\Plugins; +use App\Console\Kernel; +use Composer\InstalledVersions; +use Illuminate\Support\Facades\Process; use Pest\Console\Thanks; use Pest\Contracts\Plugins\HandlesArguments; use Pest\Support\View; @@ -26,7 +29,9 @@ final class Init implements HandlesArguments private const STUBS = [ 'phpunit.xml' => 'phpunit.xml', 'Pest.php' => 'tests/Pest.php', - 'ExampleTest.php' => 'tests/ExampleTest.php', + 'TestCase.php' => 'tests/TestCase.php', + 'Unit/ExampleTest.php' => 'tests/Unit/ExampleTest.php', + 'Feature/ExampleTest.php' => 'tests/Feature/ExampleTest.php', ]; /** @@ -59,16 +64,19 @@ final class Init implements HandlesArguments private function init(): void { + if ($this->isLaravelInstalled()) { + exit($this->initLaravel()); + } + $testsBaseDir = "{$this->testSuite->rootPath}/tests"; if (! is_dir($testsBaseDir)) { mkdir($testsBaseDir); } - $this->output->writeln([ - '', - ' INFO Preparing tests directory.', - '', + View::render('components.badge', [ + 'type' => 'INFO', + 'content' => 'Preparing tests directory.', ]); foreach (self::STUBS as $from => $to) { @@ -98,4 +106,68 @@ final class Init implements HandlesArguments exit(0); } + + private function initLaravel(): int + { + View::render('components.badge', [ + 'type' => 'INFO', + 'content' => 'Laravel installation detected, pest-plugin-laravel will be installed.', + ]); + + exec('composer require pestphp/pest-plugin-laravel 2.x-dev', result_code: $result); + + /** @var int $result */ + if ($result > 0) { + View::render('components.badge', [ + 'type' => 'ERROR', + 'content' => 'Something went wrong while installing pest-plugin-laravel package. Please refer the above output for more info.', + ]); + + return $result; + } + + View::render('components.badge', [ + 'type' => 'INFO', + 'content' => 'Running artisan command to install Pest.', + ]); + + $app = require $this->testSuite->rootPath.'/bootstrap/app.php'; + /** @phpstan-ignore-next-line */ + $app->make(Kernel::class)->bootstrap(); + + /** @phpstan-ignore-next-line */ + $result = Process::run('php artisan pest:install --no-interaction'); + + if ($result->failed()) { + $this->output->writeln($result->errorOutput()); + + View::render('components.badge', [ + 'type' => 'ERROR', + 'content' => 'Something went wrong while installing Pest in laravel. Please refer the above output for more info.', + ]); + + return $result->exitCode(); + } + + $this->output->writeln($result->output()); + + View::render('components.two-column-detail', [ + 'left' => 'pest-plugin-laravel', + 'right' => 'Installed', + ]); + + View::render('components.two-column-detail', [ + 'left' => 'Pest', + 'right' => 'Installed in Laravel', + ]); + + View::render('components.new-line'); + + return 0; + } + + private function isLaravelInstalled(): bool + { + return InstalledVersions::isInstalled('laravel/laravel'); + } } diff --git a/stubs/init/ExampleTest.php b/stubs/init/Feature/ExampleTest.php similarity index 100% rename from stubs/init/ExampleTest.php rename to stubs/init/Feature/ExampleTest.php diff --git a/stubs/init/TestCase.php b/stubs/init/TestCase.php new file mode 100644 index 00000000..62e5bd9b --- /dev/null +++ b/stubs/init/TestCase.php @@ -0,0 +1,7 @@ +toBeTrue(); +}); From 69b1c08558ccbc9ec0503300d6feab8f554f4ee2 Mon Sep 17 00:00:00 2001 From: Fabio Ivona Date: Mon, 20 Feb 2023 23:44:15 +0100 Subject: [PATCH 2/9] refactor --- src/Plugins/Init.php | 74 ++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/src/Plugins/Init.php b/src/Plugins/Init.php index 9c1c45c5..d63e88e8 100644 --- a/src/Plugins/Init.php +++ b/src/Plugins/Init.php @@ -4,14 +4,13 @@ declare(strict_types=1); namespace Pest\Plugins; -use App\Console\Kernel; use Composer\InstalledVersions; -use Illuminate\Support\Facades\Process; use Pest\Console\Thanks; use Pest\Contracts\Plugins\HandlesArguments; use Pest\Support\View; use Pest\TestSuite; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Process\Process; /** * @internal @@ -109,63 +108,38 @@ final class Init implements HandlesArguments private function initLaravel(): int { - View::render('components.badge', [ - 'type' => 'INFO', - 'content' => 'Laravel installation detected, pest-plugin-laravel will be installed.', - ]); + $command = [ + 'composer', 'require', + 'pestphp/pest-plugin-laravel 2.x-dev', + '--dev', + ]; - exec('composer require pestphp/pest-plugin-laravel 2.x-dev', result_code: $result); + $result = (new Process($command, $this->testSuite->rootPath, ['COMPOSER_MEMORY_LIMIT' => '-1'])) + ->setTimeout(null) + ->run(function ($type, $output): void { + $this->output->write($output); + }); - /** @var int $result */ if ($result > 0) { - View::render('components.badge', [ - 'type' => 'ERROR', - 'content' => 'Something went wrong while installing pest-plugin-laravel package. Please refer the above output for more info.', - ]); - return $result; } - View::render('components.badge', [ - 'type' => 'INFO', - 'content' => 'Running artisan command to install Pest.', - ]); + $command = [ + 'php', 'artisan', + 'pest:install', + '--no-interaction', + ]; - $app = require $this->testSuite->rootPath.'/bootstrap/app.php'; - /** @phpstan-ignore-next-line */ - $app->make(Kernel::class)->bootstrap(); - - /** @phpstan-ignore-next-line */ - $result = Process::run('php artisan pest:install --no-interaction'); - - if ($result->failed()) { - $this->output->writeln($result->errorOutput()); - - View::render('components.badge', [ - 'type' => 'ERROR', - 'content' => 'Something went wrong while installing Pest in laravel. Please refer the above output for more info.', - ]); - - return $result->exitCode(); - } - - $this->output->writeln($result->output()); - - View::render('components.two-column-detail', [ - 'left' => 'pest-plugin-laravel', - 'right' => 'Installed', - ]); - - View::render('components.two-column-detail', [ - 'left' => 'Pest', - 'right' => 'Installed in Laravel', - ]); - - View::render('components.new-line'); - - return 0; + return (new Process($command, $this->testSuite->rootPath, ['COMPOSER_MEMORY_LIMIT' => '-1'])) + ->setTimeout(null) + ->run(function ($type, $output): void { + $this->output->write($output); + }); } + /** + * Checks if laravel is installed through Composer + */ private function isLaravelInstalled(): bool { return InstalledVersions::isInstalled('laravel/laravel'); From 46b785f29fb581aa92ed732938a751ea3ee0d45a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 20 Feb 2023 22:54:24 +0000 Subject: [PATCH 3/9] Update TestCase.php --- stubs/init/TestCase.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stubs/init/TestCase.php b/stubs/init/TestCase.php index 62e5bd9b..cfb05b6d 100644 --- a/stubs/init/TestCase.php +++ b/stubs/init/TestCase.php @@ -2,6 +2,9 @@ namespace Tests; -class TestCase extends \PHPUnit\Framework\TestCase +use PHPUnit\Framework\TestCase as BaseTestCase; + +abstract class TestCase extends BaseTestCase { + // } From a6e133a19421db05342416f673db669102915cc3 Mon Sep 17 00:00:00 2001 From: Fabio Ivona Date: Mon, 20 Feb 2023 23:56:26 +0100 Subject: [PATCH 4/9] add --ansi option to artisan command call --- src/Plugins/Init.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/Init.php b/src/Plugins/Init.php index d63e88e8..ac1c8ba2 100644 --- a/src/Plugins/Init.php +++ b/src/Plugins/Init.php @@ -127,7 +127,7 @@ final class Init implements HandlesArguments $command = [ 'php', 'artisan', 'pest:install', - '--no-interaction', + '--ansi', '--no-interaction', ]; return (new Process($command, $this->testSuite->rootPath, ['COMPOSER_MEMORY_LIMIT' => '-1'])) From c664094f35e7c4eca9ef2abde133927af2a4e035 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 21 Feb 2023 22:04:30 +0000 Subject: [PATCH 5/9] fix: `--retry` option update --- overrides/Runner/ResultCache/DefaultResultCache.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/overrides/Runner/ResultCache/DefaultResultCache.php b/overrides/Runner/ResultCache/DefaultResultCache.php index f02a06c7..d3438e00 100644 --- a/overrides/Runner/ResultCache/DefaultResultCache.php +++ b/overrides/Runner/ResultCache/DefaultResultCache.php @@ -79,6 +79,11 @@ final class DefaultResultCache implements ResultCache */ private array $defects = []; + /** + * @psalm-var array + */ + private array $currentDefects = []; + /** * @psalm-var array */ @@ -96,6 +101,7 @@ final class DefaultResultCache implements ResultCache public function setStatus(string $id, TestStatus $status): void { if ($status->isFailure() || $status->isError()) { + $this->currentDefects[$id] = $status; $this->defects[$id] = $status; } } @@ -107,6 +113,10 @@ final class DefaultResultCache implements ResultCache public function setTime(string $id, float $time): void { + if (! isset($this->currentDefects[$id])) { + unset($this->defects[$id]); + } + $this->times[$id] = $time; } From b54c24a58943185c3d9182e1bf56a878da3a06f9 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sat, 25 Feb 2023 17:33:28 +0530 Subject: [PATCH 6/9] fix: `--parallel` exit code --- .../Parallel/Paratest/WrapperRunner.php | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Parallel/Paratest/WrapperRunner.php b/src/Plugins/Parallel/Paratest/WrapperRunner.php index e2c7079e..3f0a1835 100644 --- a/src/Plugins/Parallel/Paratest/WrapperRunner.php +++ b/src/Plugins/Parallel/Paratest/WrapperRunner.php @@ -296,6 +296,32 @@ final class WrapperRunner implements RunnerInterface ); } + $testResultSum = new TestResult( + $testResultSum->numberOfTests(), + $testResultSum->numberOfTestsRun(), + $testResultSum->numberOfAssertions(), + $testResultSum->testErroredEvents(), + $testResultSum->testFailedEvents(), + $testResultSum->testConsideredRiskyEvents(), + $testResultSum->testSuiteSkippedEvents(), + $testResultSum->testSkippedEvents(), + $testResultSum->testMarkedIncompleteEvents(), + $testResultSum->testTriggeredDeprecationEvents(), + $testResultSum->testTriggeredPhpDeprecationEvents(), + $testResultSum->testTriggeredPhpunitDeprecationEvents(), + $testResultSum->testTriggeredErrorEvents(), + $testResultSum->testTriggeredNoticeEvents(), + $testResultSum->testTriggeredPhpNoticeEvents(), + $testResultSum->testTriggeredWarningEvents(), + $testResultSum->testTriggeredPhpWarningEvents(), + $testResultSum->testTriggeredPhpunitErrorEvents(), + $testResultSum->testTriggeredPhpunitWarningEvents(), + $testResultSum->testRunnerTriggeredDeprecationEvents(), + array_values(array_filter($testResultSum->testRunnerTriggeredWarningEvents(), function ($event) { + return ! str_contains($event->message(), 'No tests found'); + })), + ); + $this->printer->printResults( $testResultSum, $this->teamcityFiles, @@ -305,7 +331,7 @@ final class WrapperRunner implements RunnerInterface $this->generateCodeCoverageReports(); $this->generateLogs(); - $exitcode = (new ShellExitCodeCalculator())->calculate( + $exitCode = (new ShellExitCodeCalculator())->calculate( $this->options->configuration->failOnEmptyTestSuite(), $this->options->configuration->failOnRisky(), $this->options->configuration->failOnWarning(), @@ -320,7 +346,7 @@ final class WrapperRunner implements RunnerInterface $this->clearFiles($this->teamcityFiles); $this->clearFiles($this->testdoxFiles); - return $exitcode; + return $exitCode; } private function generateCodeCoverageReports(): void From 244087db27b6b14144f997fefb7496894250893e Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sat, 25 Feb 2023 17:42:24 +0530 Subject: [PATCH 7/9] fix: parallel status code --- overrides/Runner/ResultCache/DefaultResultCache.php | 4 ++-- src/Plugins/Parallel/Paratest/WrapperRunner.php | 4 +--- tests/.snapshots/success.txt | 2 +- tests/Visual/Parallel.php | 2 ++ 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/overrides/Runner/ResultCache/DefaultResultCache.php b/overrides/Runner/ResultCache/DefaultResultCache.php index d3438e00..640c3971 100644 --- a/overrides/Runner/ResultCache/DefaultResultCache.php +++ b/overrides/Runner/ResultCache/DefaultResultCache.php @@ -47,7 +47,6 @@ namespace PHPUnit\Runner\ResultCache; use function array_keys; use function assert; -use function Pest\version; use const DIRECTORY_SEPARATOR; use function dirname; use function file_get_contents; @@ -57,6 +56,7 @@ use function is_dir; use function is_file; use function json_decode; use function json_encode; +use function Pest\version; use PHPUnit\Framework\TestStatus\TestStatus; use PHPUnit\Runner\DirectoryCannotBeCreatedException; use PHPUnit\Runner\Exception; @@ -190,6 +190,6 @@ final class DefaultResultCache implements ResultCache */ private function cacheVersion(): string { - return 'pest_' . version(); + return 'pest_'.version(); } } diff --git a/src/Plugins/Parallel/Paratest/WrapperRunner.php b/src/Plugins/Parallel/Paratest/WrapperRunner.php index 3f0a1835..5c3bf2e4 100644 --- a/src/Plugins/Parallel/Paratest/WrapperRunner.php +++ b/src/Plugins/Parallel/Paratest/WrapperRunner.php @@ -317,9 +317,7 @@ final class WrapperRunner implements RunnerInterface $testResultSum->testTriggeredPhpunitErrorEvents(), $testResultSum->testTriggeredPhpunitWarningEvents(), $testResultSum->testRunnerTriggeredDeprecationEvents(), - array_values(array_filter($testResultSum->testRunnerTriggeredWarningEvents(), function ($event) { - return ! str_contains($event->message(), 'No tests found'); - })), + array_values(array_filter($testResultSum->testRunnerTriggeredWarningEvents(), fn ($event): bool => ! str_contains($event->message(), 'No tests found'))), ); $this->printer->printResults( diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index cc563df2..81ae5e23 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -917,4 +917,4 @@ PASS Tests\Visual\Version ✓ visual snapshot of help command output - Tests: 4 incomplete, 4 todos, 18 skipped, 634 passed (1559 assertions) \ No newline at end of file + Tests: 4 incomplete, 4 todos, 18 skipped, 634 passed (1560 assertions) \ No newline at end of file diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 5e83d922..1fbe0ed3 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -9,6 +9,8 @@ $run = function () { $process->run(); + expect($process->getExitCode())->toBe(0); + return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput()); }; From 20012b65fb41349c2acc5912b19868c59c75a6c5 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sat, 25 Feb 2023 17:42:29 +0530 Subject: [PATCH 8/9] chore: bumps phpunit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 24559da5..f2d059c6 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "nunomaduro/collision": "^7.0.5", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", - "phpunit/phpunit": "^10.0.11" + "phpunit/phpunit": "^10.0.12" }, "conflict": { "brianium/paratest": "<7.0.6" From 8abad572eced42c2b95fb3dca5b3da54522c5d8a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sat, 25 Feb 2023 17:45:43 +0530 Subject: [PATCH 9/9] chore: fix CI testing --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f2d059c6..98bc3522 100644 --- a/composer.json +++ b/composer.json @@ -71,7 +71,7 @@ "test:types": "phpstan analyse --ansi --memory-limit=-1 --debug", "test:unit": "php bin/pest --colors=always --exclude-group=integration --compact", "test:inline": "php bin/pest --colors=always --configuration=phpunit.inline.xml", - "test:parallel": "php bin/pest --colors=always --exclude-group=integration --parallel", + "test:parallel": "php bin/pest --colors=always --exclude-group=integration --parallel --processes=10", "test:integration": "php bin/pest --colors=always --group=integration -v", "update:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always", "test": [