*/ public static array $failures = []; public static string $suite = ''; public static function suite(string $name): void { self::$suite = $name; } public static function it(string $description, callable $fn): void { try { $fn(); self::$passed++; fwrite(STDOUT, " \033[32mok\033[0m " . $description . PHP_EOL); } catch (\Throwable $e) { self::$failed++; self::$failures[] = self::$suite . ' :: ' . $description . ' -> ' . $e->getMessage(); fwrite(STDOUT, " \033[31mFAIL\033[0m " . $description . ' -> ' . $e->getMessage() . PHP_EOL); } } public static function summary(): int { fwrite(STDOUT, PHP_EOL); fwrite(STDOUT, sprintf("passed: %d, failed: %d\n", self::$passed, self::$failed)); if (self::$failed > 0) { fwrite(STDOUT, "Failures:\n"); foreach (self::$failures as $failure) { fwrite(STDOUT, ' - ' . $failure . PHP_EOL); } return 1; } return 0; } } function ok(bool $condition, string $message = 'assertion failed'): void { if (!$condition) { throw new \RuntimeException($message); } } function eq(mixed $expected, mixed $actual, string $message = ''): void { if ($expected !== $actual) { throw new \RuntimeException(sprintf( '%s expected %s, got %s', $message !== '' ? $message . ':' : 'values differ,', var_export($expected, true), var_export($actual, true) )); } } function throws(callable $fn, string $message = 'expected exception'): void { try { $fn(); } catch (\Throwable) { return; } throw new \RuntimeException($message); } function tmpdir(string $prefix = 'duckbrain-test'): string { $dir = sys_get_temp_dir() . '/' . $prefix . '-' . bin2hex(random_bytes(6)); mkdir($dir, 0777, true); return $dir; } function rrmdir(string $dir): void { if (!is_dir($dir)) { return; } exec('rm -rf ' . escapeshellarg($dir) . ' 2>/dev/null'); } function write_file(string $path, string $contents): void { if (!is_dir(dirname($path))) { mkdir(dirname($path), 0777, true); } file_put_contents($path, $contents); } function git_init(string $dir): void { exec('git init -q ' . escapeshellarg($dir)); exec('git -C ' . escapeshellarg($dir) . ' config user.email test@test'); exec('git -C ' . escapeshellarg($dir) . ' config user.name test'); exec('git -C ' . escapeshellarg($dir) . ' config commit.gpgsign false'); } function git_commit(string $dir, string $msg): void { exec('git -C ' . escapeshellarg($dir) . ' add -A'); exec('git -C ' . escapeshellarg($dir) . ' commit -qm ' . escapeshellarg($msg)); } function git_tag(string $dir, string $tag): void { exec('git -C ' . escapeshellarg($dir) . ' tag ' . escapeshellarg($tag)); } function seed_package(string $repo, string $version): void { write_file($repo . '/packages/http/duckbrain.json', json_encode([ 'name' => 'http', 'version' => $version, 'components' => ['aria2' => ['files' => ['src/Libs/Aria2.php']]], ], JSON_PRETTY_PRINT)); }