diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 8684d07f..53de9450 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -26,7 +26,7 @@ jobs: runs-on: ${{ matrix.operating-system }} strategy: matrix: - operating-system: [ "ubuntu-latest", "macos-latest" ] + operating-system: [ "ubuntu-latest", "macos-latest", "windows-latest" ] php-versions: [ "7.4", "8.0", "8.1" ] steps: - name: Checkout code @@ -36,7 +36,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: php-version: ${{ matrix.php-versions }} - extensions: swoole, posix, json + extensions: swoole, posix, json, mbstring env: SWOOLE_CONFIGURE_OPTS: --enable-openssl @@ -63,6 +63,9 @@ jobs: - name: Run Static Analysis run: "composer analyse" + - name: Run PHPUnit + run: "composer test" + cs-check: name: PHP CS Fixer Check runs-on: ubuntu-latest diff --git a/bin/phpunit-zm b/bin/phpunit-zm index f93908b9..335ecc2e 100755 --- a/bin/phpunit-zm +++ b/bin/phpunit-zm @@ -7,38 +7,49 @@ const ZM_TEST_LOG_DEBUG = false; use OneBot\Driver\Event\Process\WorkerStartEvent; use PHPUnit\TextUI\Command; +use Swoole\Atomic; use ZM\Command\Server\ServerStartCommand; +use ZM\Event\EventProvider; use ZM\Framework; use ZM\Logger\ConsoleLogger; +use ZM\Store\MockAtomic; -$root = dirname(__DIR__); - -require $root . '/vendor/autoload.php'; +// 引入自动加载 +require dirname(__DIR__) . '/vendor/autoload.php'; +// 声明一个全局的原子计数,用于保存整个进程的退出状态码 global $_swoole_atomic; -$_swoole_atomic = new \Swoole\Atomic(); +// Windows 没有 Swoole,所以就使用了一个假的原子计数器,反正 Windows 只有单进程 +$_swoole_atomic = class_exists('\\Swoole\\Atomic') ? new Atomic() : new MockAtomic(); -ob_logger_register(new ConsoleLogger('error')); +// 注册 Logger 等级 +ob_logger_register(new ConsoleLogger(ZM_TEST_LOG_DEBUG ? 'debug' : 'error')); + +// 使用框架自身的 EventProvider global $ob_event_provider; -$ob_event_provider = new \ZM\Event\EventProvider(); +$ob_event_provider = new EventProvider(); +// 注册一个最低级别的 WorkerStart 事件,用于在框架的事件初始化之后开始运行 PHPUnit ob_event_provider()->addEventListener(WorkerStartEvent::getName(), function () { try { + // 不退出,而是返回 code $retcode = Command::main(false); } finally { global $_swoole_atomic; $_swoole_atomic->set($retcode ?? 0); + if (DIRECTORY_SEPARATOR === '\\') { + exit($retcode ?? 0); + } Framework::getInstance()->stop(); } }, 1); try { $options = ServerStartCommand::exportOptionArray(); - $options['driver'] = 'swoole'; + $options['driver'] = DIRECTORY_SEPARATOR === '/' ? 'swoole' : 'workerman'; $options['worker-num'] = 1; $options['private-mode'] = true; (new Framework($options))->init()->start(); - exit($_swoole_atomic->get()); } catch (Throwable $e) { echo $e->getMessage() . PHP_EOL; diff --git a/bin/phpunit-zm.bat b/bin/phpunit-zm.bat new file mode 100644 index 00000000..56a4bffa --- /dev/null +++ b/bin/phpunit-zm.bat @@ -0,0 +1,3 @@ +@echo off + +php %~dp0phpunit-zm %* diff --git a/src/ZM/Event/Listener/WorkerEventListener.php b/src/ZM/Event/Listener/WorkerEventListener.php index c275648d..2ca083ef 100644 --- a/src/ZM/Event/Listener/WorkerEventListener.php +++ b/src/ZM/Event/Listener/WorkerEventListener.php @@ -97,7 +97,9 @@ class WorkerEventListener public function onWorkerStop999() { logger()->debug('Worker #' . ProcessManager::getProcessId() . ' stopping'); - ProcessStateManager::removeProcessState(ZM_PROCESS_WORKER, ProcessManager::getProcessId()); + if (DIRECTORY_SEPARATOR !== '\\') { + ProcessStateManager::removeProcessState(ZM_PROCESS_WORKER, ProcessManager::getProcessId()); + } } /** diff --git a/src/ZM/Process/ProcessStateManager.php b/src/ZM/Process/ProcessStateManager.php index 4a889521..5c4db757 100644 --- a/src/ZM/Process/ProcessStateManager.php +++ b/src/ZM/Process/ProcessStateManager.php @@ -12,7 +12,7 @@ class ProcessStateManager /** * @var array */ - public static $process_mode; + public static array $process_mode = []; /** * @param null|int|string $id_or_name diff --git a/src/ZM/Store/MockAtomic.php b/src/ZM/Store/MockAtomic.php new file mode 100644 index 00000000..28df11cb --- /dev/null +++ b/src/ZM/Store/MockAtomic.php @@ -0,0 +1,20 @@ +num = $num; + } + + public function get(): int + { + return $this->num; + } +} diff --git a/tests/ZM/Middleware/PipelineTest.php b/tests/ZM/Middleware/PipelineTest.php new file mode 100644 index 00000000..0be8f860 --- /dev/null +++ b/tests/ZM/Middleware/PipelineTest.php @@ -0,0 +1,37 @@ +send('APP') + ->through([TimerMiddleware::class]) + ->then(function (string $value) { + return $value; + }); + $this->assertEquals('APP', $a); + } +}