From 7f7ea53ee4d3ae62ccedc80441a240da958d4c12 Mon Sep 17 00:00:00 2001 From: Hafiz Muhammad Moaz Date: Fri, 28 Aug 2026 03:58:47 +0500 Subject: [PATCH] test: cover command dispatch and exit codes via subprocesses (fixes #13) --- tests/ExitCodeTest.php | 100 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 tests/ExitCodeTest.php diff --git a/tests/ExitCodeTest.php b/tests/ExitCodeTest.php new file mode 100644 index 0000000..fbda99c --- /dev/null +++ b/tests/ExitCodeTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, + * please view the LICENSE + * file that was distributed with this source code. + */ +declare(strict_types=1); +/* + * This file is part of Webisters CLI Library. + * + * (c) Hafiz Muhammad Moaz + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Tests\CLI; + +use PHPUnit\Framework\TestCase; + +/** + * Covers command dispatch and process exit codes using real subprocesses, + * since exit codes cannot be asserted inside the PHPUnit process itself. + */ +final class ExitCodeTest extends TestCase +{ + public function testSuccessfulCommandExitsWithZero() : void + { + $script = <<<'PHP' + + use Framework\CLI\CLI; + use Framework\CLI\Command; + + class OkCommand extends Command + { + protected string $name = 'ok'; + + public function run() : void + { + CLI::write('done'); + } + } + + (new Framework\CLI\Console())->addCommand(OkCommand::class)->run(); + PHP; + [$exitCode] = $this->runScript($script, ['ok']); + self::assertSame(0, $exitCode); + } + + public function testCommandNotFoundExitsWithOne() : void + { + $script = <<<'PHP' + + (new Framework\CLI\Console())->run(); + PHP; + [$exitCode] = $this->runScript($script, ['this-command-does-not-exist']); + self::assertSame(1, $exitCode); + } + + public function testErrorHelperExitsWithGivenCode() : void + { + $script = <<<'PHP' + + \Framework\CLI\CLI::error('boom', 3); + PHP; + [$exitCode] = $this->runScript($script, []); + self::assertSame(3, $exitCode); + } + + /** + * Run a script as a real PHP process and return its exit code and output. + * + * @param array $argv The arguments passed to the script after its own name + * + * @return array{0:int,1:string} + */ + private function runScript(string $code, array $argv) : array + { + $autoloader = \dirname(__DIR__) . '/vendor/autoload.php'; + $file = \sys_get_temp_dir() . '/webisters-cli-exit-' . \uniqid() . '.php'; + \file_put_contents( + $file, + '&1', $output, $exitCode); + + \unlink($file); + + return [$exitCode, \implode("\n", $output)]; + } +}