Remove co-pest, use pest-plugin-hyperf instead. (#5834)

This commit is contained in:
Deeka Wong 2023-06-14 14:35:21 +08:00 committed by GitHub
parent 8ca6e3ee54
commit d5457411dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 340 deletions

View File

@ -1,110 +0,0 @@
#!/usr/bin/env php
<?php
declare (strict_types=1);
use Pest\Kernel;
use Pest\Panic;
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
use Pest\TestCaseMethodFilters\TodoTestCaseFilter;
use Pest\TestSuite;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
(function () {
$prepend = null;
foreach ($_SERVER["argv"] as $index => $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);

View File

@ -1,116 +0,0 @@
#!/usr/bin/env php
<?php
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use PhpParser\Node;
use PhpParser\Node\Stmt\Return_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
require_once 'vendor/autoload.php';
class RunInCoroutineVisitor extends NodeVisitorAbstract
{
/**
* @var Parser
*/
protected $parser;
public function __construct(Parser $parser)
{
$this->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('<?php
(function () {
$prepend = null;
foreach ($_SERVER["argv"] as $index => $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);

View File

@ -515,11 +515,16 @@
"Hyperf\\WebSocketClient\\ConfigProvider", "Hyperf\\WebSocketClient\\ConfigProvider",
"Hyperf\\WebSocketServer\\ConfigProvider" "Hyperf\\WebSocketServer\\ConfigProvider"
] ]
},
"pest": {
"plugins": [
"Hyperf\\Testing\\Plugin\\Pest"
]
} }
}, },
"bin": [], "bin": [],
"scripts": { "scripts": {
"pest": "./bin/co-pest --colors=always", "pest": "pest --coroutine --colors=always",
"test": "./bin/co-phpunit --colors=always", "test": "./bin/co-phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
"license-check": "docheader check src/ test/", "license-check": "docheader check src/ test/",

View File

@ -1,110 +0,0 @@
#!/usr/bin/env php
<?php
declare (strict_types=1);
use Pest\Kernel;
use Pest\Panic;
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
use Pest\TestCaseMethodFilters\TodoTestCaseFilter;
use Pest\TestSuite;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
(function () {
$prepend = null;
foreach ($_SERVER["argv"] as $index => $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);

View File

@ -33,15 +33,19 @@
"symfony/http-foundation": "^5.4|^6.0" "symfony/http-foundation": "^5.4|^6.0"
}, },
"suggest": { "suggest": {
"pestphp/pest": "For testing with Pest" "pestphp/pest": "For testing with Pest.(^2.0)"
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.0-dev" "dev-master": "3.0-dev"
},
"pest": {
"plugins": [
"Hyperf\\Testing\\Plugin\\Pest"
]
} }
}, },
"bin": [ "bin": [
"co-phpunit", "co-phpunit"
"bin/co-pest"
] ]
} }

View File

@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\Testing\Plugin;
use Hyperf\Coordinator\Constants;
use Hyperf\Coordinator\CoordinatorManager;
use Pest\Contracts\Plugins\HandlesArguments;
use Pest\Exceptions\InvalidOption;
use Pest\Kernel;
use Pest\Plugins\Concerns\HandleArguments;
use Pest\Support\Container;
use PHPUnit\TextUI\Application;
use Swoole\Coroutine;
use Swoole\Timer;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @property string $vendorDir
*/
class Pest implements HandlesArguments
{
use HandleArguments;
public function handleArguments(array $arguments): array
{
$arguments = $this->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;
}
}