hyperf/bin/regenerate-phpunit

143 lines
4.1 KiB
PHP
Executable File

#!/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\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)
{
$main = array_pop($nodes);
/** @var Node\Stmt\Expression $main */
$main = $main->expr;
$main = $main->expr;
$require = array_pop($nodes);
$nodes[] = $this->getPrependSetter()[0];
$nodes[] = $require;
$nodes[] = new Node\Stmt\Expression(new Node\Expr\Assign(
new Node\Expr\Variable('code'),
new Node\Scalar\LNumber(0)
));
$nodes[] = $this->getCoroutineSetter()[0];
$nodes[] = new Node\Stmt\Expression(
new Node\Expr\FuncCall(
new Node\Name('Swoole\Coroutine\run'),
[
new Node\Arg(new Node\Expr\Closure([
'stmts' => [
new Node\Stmt\Expression(new Node\Expr\Assign(
new Node\Expr\Variable('code'),
$main
)),
$this->getTimerClearAll()[0],
$this->getCoordinatorResume()[0],
],
'uses' => [
new Node\Expr\ClosureUse(new Node\Expr\Variable('code'), true),
],
])),
]
)
);
$nodes[] = new Node\Stmt\Expression(new Node\Expr\Exit_(new Node\Expr\Variable('code')));
return $nodes;
}
protected function getPrependSetter(): array
{
return $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;
}
})();
');
}
protected function getCoroutineSetter(): array
{
return $this->parser->parse("<?php
Swoole\\Coroutine::set([
'hook_flags' => SWOOLE_HOOK_ALL,
'exit_condition' => function() {
return Swoole\\Coroutine::stats()['coroutine_num'] === 0;
}
]);");
}
protected function getTimerClearAll(): array
{
return $this->parser->parse('<?php Swoole\\Timer::clearAll();');
}
protected function getCoordinatorResume(): array
{
return $this->parser->parse('<?php Hyperf\\Coordinator\\CoordinatorManager::until(Hyperf\\Coordinator\\Constants::WORKER_EXIT)->resume();');
}
}
$parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
$printer = new Standard();
$traverser = new NodeTraverser();
$code = file_get_contents(__DIR__ . '/../vendor/phpunit/phpunit/phpunit');
$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(__DIR__ . '/co-phpunit', $code);
file_put_contents(__DIR__ . '/../src/testing/co-phpunit', $code);