From d5457411ddc65167d4ff9c502b291bd0b055652f Mon Sep 17 00:00:00 2001 From: Deeka Wong Date: Wed, 14 Jun 2023 14:35:21 +0800 Subject: [PATCH] Remove `co-pest`, use `pest-plugin-hyperf` instead. (#5834) --- bin/co-pest | 110 ------------------------------ bin/regenerate-pest | 116 -------------------------------- composer.json | 7 +- src/testing/bin/co-pest | 110 ------------------------------ src/testing/composer.json | 10 ++- src/testing/src/Plugin/Pest.php | 103 ++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 340 deletions(-) delete mode 100755 bin/co-pest delete mode 100755 bin/regenerate-pest delete mode 100755 src/testing/bin/co-pest create mode 100644 src/testing/src/Plugin/Pest.php diff --git a/bin/co-pest b/bin/co-pest deleted file mode 100755 index 60609320a..000000000 --- a/bin/co-pest +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env php - $argv) { - // --prepend /path/to/file - if ($argv === "--prepend") { - unset($_SERVER["argv"][$index]); - if (isset($_SERVER["argv"][$index + 1])) { - $prepend = $_SERVER["argv"][$index + 1]; - unset($_SERVER["argv"][$index + 1]); - } - break; - } - // --prepend=/path/to/file - if (strpos($argv, "--prepend=") === 0) { - $prepend = substr($argv, 10); - unset($_SERVER["argv"][$index]); - break; - } - } - if ($prepend !== null && file_exists($prepend)) { - require $prepend; - } -})(); -$code = 0; -Swoole\Coroutine::set(["hook_flags" => SWOOLE_HOOK_ALL, "exit_condition" => function () { - return Swoole\Coroutine::stats()["coroutine_num"] === 0; -}]); -Swoole\Coroutine\run(function () use(&$code) { - try { - $code = (static function () { - // Ensures Collision's Printer is registered. - $_SERVER['COLLISION_PRINTER'] = 'DefaultPrinter'; - $args = $_SERVER['argv']; - $dirty = false; - $todo = false; - foreach ($args as $key => $value) { - if ($value === '--compact') { - $_SERVER['COLLISION_PRINTER_COMPACT'] = 'true'; - unset($args[$key]); - } - if ($value === '--profile') { - $_SERVER['COLLISION_PRINTER_PROFILE'] = 'true'; - unset($args[$key]); - } - if (str_contains($value, '--test-directory')) { - unset($args[$key]); - } - if ($value === '--dirty') { - $dirty = true; - unset($args[$key]); - } - if ($value === '--todos') { - $todo = true; - unset($args[$key]); - } - if (str_contains($value, '--teamcity')) { - unset($args[$key]); - $args[] = '--no-output'; - unset($_SERVER['COLLISION_PRINTER']); - } - } - // Used when Pest is required using composer. - $vendorPath = dirname(__DIR__, 4) . '/vendor/autoload.php'; - // Used when Pest maintainers are running Pest tests. - $localPath = dirname(__DIR__) . '/vendor/autoload.php'; - if (file_exists($vendorPath)) { - include_once $vendorPath; - $autoloadPath = $vendorPath; - } else { - include_once $localPath; - $autoloadPath = $localPath; - } - // Get $rootPath based on $autoloadPath - $rootPath = dirname($autoloadPath, 2); - $input = new ArgvInput(); - $testSuite = TestSuite::getInstance($rootPath, $input->getParameterOption('--test-directory', 'tests')); - if ($dirty) { - $testSuite->tests->addTestCaseFilter(new GitDirtyTestCaseFilter($rootPath)); - } - if ($todo) { - $testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter()); - } - $isDecorated = $input->getParameterOption('--colors', 'always') !== 'never'; - $output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated); - try { - $kernel = Kernel::boot($testSuite, $input, $output); - $result = $kernel->handle($args); - $kernel->shutdown(); - } catch (Throwable|Error $e) { - Panic::with($e); - } - return $result; - })(); - } catch (Swoole\ExitException $e) { - $code = $e->getStatus(); - } - Swoole\Timer::clearAll(); - Hyperf\Coordinator\CoordinatorManager::until(Hyperf\Coordinator\Constants::WORKER_EXIT)->resume(); -}); -die($code); \ No newline at end of file diff --git a/bin/regenerate-pest b/bin/regenerate-pest deleted file mode 100755 index 027cf4b53..000000000 --- a/bin/regenerate-pest +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env php -parser = $parser; - } - - public function afterTraverse(array $nodes) - { - /** @var Node\Stmt\Expression $main */ - $main = array_pop($nodes); - $main = $main->expr; - foreach ($this->wrapCoroutine($main) as $node) { - $nodes[] = $node; - } - return $nodes; - } - - /** - * @param PhpParser\Node\Expr\FuncCall $expr - */ - protected function wrapCoroutine($expr): array - { - $exit = array_pop($expr->name->stmts); - $expr->name->stmts[] = new Return_(new Node\Expr\Variable($exit->expr->expr->name)); - /** @var PhpParser\Node\Stmt\Expression[] $nodes */ - $nodes = $this->parser->parse(' $argv) { - // --prepend /path/to/file - if ($argv === "--prepend") { - unset($_SERVER["argv"][$index]); - if (isset($_SERVER["argv"][$index + 1])) { - $prepend = $_SERVER["argv"][$index + 1]; - unset($_SERVER["argv"][$index + 1]); - } - break; - } - // --prepend=/path/to/file - if (strpos($argv, "--prepend=") === 0) { - $prepend = substr($argv, 10); - unset($_SERVER["argv"][$index]); - break; - } - } - if ($prepend !== null && file_exists($prepend)) { - require $prepend; - } -})(); -$code = 0; -Swoole\Coroutine::set(["hook_flags" => SWOOLE_HOOK_ALL, "exit_condition" => function () { - return Swoole\Coroutine::stats()["coroutine_num"] === 0; -}]); -Swoole\Coroutine\run(function () use(&$code) { - try { - } catch (Swoole\ExitException $e) { - $code = $e->getStatus(); - } - Swoole\Timer::clearAll(); - Hyperf\Coordinator\CoordinatorManager::until(Hyperf\Coordinator\Constants::WORKER_EXIT)->resume(); -}); -die($code); -'); - $nodes[3]->expr->args[0]->value->stmts[0]->stmts[0] = new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable('code'), - $expr - )); - return $nodes; - } -} - -$parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7); -$printer = new Standard(); -$traverser = new NodeTraverser(); - -$code = file_get_contents(__DIR__ . '/../vendor/pestphp/pest/bin/pest'); - -$stmts = $parser->parse($code); -$traverser->addVisitor(new RunInCoroutineVisitor($parser)); -$stmts = $traverser->traverse($stmts); - -$code = $printer->prettyPrint($stmts); - -// TODO: Unknown reason -$code = ltrim($code, '?>' . PHP_EOL); - -file_put_contents($coPest = __DIR__ . '/co-pest', $code); -chmod($coPest, 0755); -file_put_contents($coPest = __DIR__ . '/../src/testing/bin/co-pest', $code); -chmod($coPest, 0755); diff --git a/composer.json b/composer.json index f79fd4b01..47c92e5da 100644 --- a/composer.json +++ b/composer.json @@ -515,11 +515,16 @@ "Hyperf\\WebSocketClient\\ConfigProvider", "Hyperf\\WebSocketServer\\ConfigProvider" ] + }, + "pest": { + "plugins": [ + "Hyperf\\Testing\\Plugin\\Pest" + ] } }, "bin": [], "scripts": { - "pest": "./bin/co-pest --colors=always", + "pest": "pest --coroutine --colors=always", "test": "./bin/co-phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "license-check": "docheader check src/ test/", diff --git a/src/testing/bin/co-pest b/src/testing/bin/co-pest deleted file mode 100755 index 60609320a..000000000 --- a/src/testing/bin/co-pest +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env php - $argv) { - // --prepend /path/to/file - if ($argv === "--prepend") { - unset($_SERVER["argv"][$index]); - if (isset($_SERVER["argv"][$index + 1])) { - $prepend = $_SERVER["argv"][$index + 1]; - unset($_SERVER["argv"][$index + 1]); - } - break; - } - // --prepend=/path/to/file - if (strpos($argv, "--prepend=") === 0) { - $prepend = substr($argv, 10); - unset($_SERVER["argv"][$index]); - break; - } - } - if ($prepend !== null && file_exists($prepend)) { - require $prepend; - } -})(); -$code = 0; -Swoole\Coroutine::set(["hook_flags" => SWOOLE_HOOK_ALL, "exit_condition" => function () { - return Swoole\Coroutine::stats()["coroutine_num"] === 0; -}]); -Swoole\Coroutine\run(function () use(&$code) { - try { - $code = (static function () { - // Ensures Collision's Printer is registered. - $_SERVER['COLLISION_PRINTER'] = 'DefaultPrinter'; - $args = $_SERVER['argv']; - $dirty = false; - $todo = false; - foreach ($args as $key => $value) { - if ($value === '--compact') { - $_SERVER['COLLISION_PRINTER_COMPACT'] = 'true'; - unset($args[$key]); - } - if ($value === '--profile') { - $_SERVER['COLLISION_PRINTER_PROFILE'] = 'true'; - unset($args[$key]); - } - if (str_contains($value, '--test-directory')) { - unset($args[$key]); - } - if ($value === '--dirty') { - $dirty = true; - unset($args[$key]); - } - if ($value === '--todos') { - $todo = true; - unset($args[$key]); - } - if (str_contains($value, '--teamcity')) { - unset($args[$key]); - $args[] = '--no-output'; - unset($_SERVER['COLLISION_PRINTER']); - } - } - // Used when Pest is required using composer. - $vendorPath = dirname(__DIR__, 4) . '/vendor/autoload.php'; - // Used when Pest maintainers are running Pest tests. - $localPath = dirname(__DIR__) . '/vendor/autoload.php'; - if (file_exists($vendorPath)) { - include_once $vendorPath; - $autoloadPath = $vendorPath; - } else { - include_once $localPath; - $autoloadPath = $localPath; - } - // Get $rootPath based on $autoloadPath - $rootPath = dirname($autoloadPath, 2); - $input = new ArgvInput(); - $testSuite = TestSuite::getInstance($rootPath, $input->getParameterOption('--test-directory', 'tests')); - if ($dirty) { - $testSuite->tests->addTestCaseFilter(new GitDirtyTestCaseFilter($rootPath)); - } - if ($todo) { - $testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter()); - } - $isDecorated = $input->getParameterOption('--colors', 'always') !== 'never'; - $output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated); - try { - $kernel = Kernel::boot($testSuite, $input, $output); - $result = $kernel->handle($args); - $kernel->shutdown(); - } catch (Throwable|Error $e) { - Panic::with($e); - } - return $result; - })(); - } catch (Swoole\ExitException $e) { - $code = $e->getStatus(); - } - Swoole\Timer::clearAll(); - Hyperf\Coordinator\CoordinatorManager::until(Hyperf\Coordinator\Constants::WORKER_EXIT)->resume(); -}); -die($code); \ No newline at end of file diff --git a/src/testing/composer.json b/src/testing/composer.json index f24424970..68187f91b 100644 --- a/src/testing/composer.json +++ b/src/testing/composer.json @@ -33,15 +33,19 @@ "symfony/http-foundation": "^5.4|^6.0" }, "suggest": { - "pestphp/pest": "For testing with Pest" + "pestphp/pest": "For testing with Pest.(^2.0)" }, "extra": { "branch-alias": { "dev-master": "3.0-dev" + }, + "pest": { + "plugins": [ + "Hyperf\\Testing\\Plugin\\Pest" + ] } }, "bin": [ - "co-phpunit", - "bin/co-pest" + "co-phpunit" ] } diff --git a/src/testing/src/Plugin/Pest.php b/src/testing/src/Plugin/Pest.php new file mode 100644 index 000000000..50e4706ff --- /dev/null +++ b/src/testing/src/Plugin/Pest.php @@ -0,0 +1,103 @@ +prepend($arguments); + + if (Coroutine::getCid() > 0) { + return $arguments; + } + + if (! $this->hasArgument('--coroutine', $arguments)) { + return $arguments; + } + + if ($this->hasArgument('--parallel', $arguments) || $this->hasArgument('-p', $arguments)) { + throw new InvalidOption('The coroutine mode is not supported when running in parallel.'); + } + + $arguments = $this->popArgument('--coroutine', $arguments); + + exit($this->runInCoroutine($arguments)); + } + + private function runInCoroutine(array $arguments): int + { + $code = 0; + $output = Container::getInstance()->get(OutputInterface::class); + $kernel = new Kernel( + new Application(), + $output, + ); + + Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL, 'exit_condition' => function () { + return Coroutine::stats()['coroutine_num'] === 0; + }]); + + /* @phpstan-ignore-next-line */ + \Swoole\Coroutine\run(function () use (&$code, $kernel, $arguments) { + $code = $kernel->handle($arguments); + Timer::clearAll(); + CoordinatorManager::until(Constants::WORKER_EXIT)->resume(); + }); + + $kernel->shutdown(); + + return $code; + } + + private function prepend(array $arguments): array + { + $prepend = null; + foreach ($arguments as $key => $argument) { + if (str_starts_with($argument, '--prepend=')) { + $prepend = explode('=', $argument, 2)[1]; + unset($arguments[$key]); + break; + } + if (str_starts_with($argument, '--prepend')) { + if (isset($arguments[$key + 1])) { + $prepend = $arguments[$key + 1]; + unset($arguments[$key + 1]); + } + unset($arguments[$key]); + } + } + + if ($prepend && file_exists($prepend)) { + require_once $prepend; + } + + return $arguments; + } +}