OmniRoute/tests/unit/cli-runtime.test.ts
diegosouzapw b329cfc84a feat(cli): fase 8.13 — self-heal native deps (omniroute runtime check/repair/clean)
- bin/cli/runtime/nativeDeps.mjs: ensureRuntimeDir, hasModule, isBetterSqliteBinaryValid
  (ELF/Mach-O/PE magic bytes), npmInstallRuntime (shell:false, cmd.exe /c no Windows),
  ensureBetterSqliteRuntime, buildEnvWithRuntime com NODE_PATH extendido
- bin/cli/commands/runtime.mjs: subcomandos check/repair --force/clean --yes
- Registrado em commands/registry.mjs
- Chaves i18n runtime.* em en.json e pt-BR.json
- 9 testes unitários cobrindo todas as funções exportadas
2026-05-15 03:46:26 -03:00

94 lines
4 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
let tmpDir: string;
let origDataDir: string | undefined;
test.before(() => {
tmpDir = mkdtempSync(join(tmpdir(), "omniroute-runtime-test-"));
origDataDir = process.env.DATA_DIR;
process.env.DATA_DIR = tmpDir;
});
test.after(() => {
if (origDataDir === undefined) delete process.env.DATA_DIR;
else process.env.DATA_DIR = origDataDir;
try {
rmSync(tmpDir, { recursive: true, force: true });
} catch {}
});
test("nativeDeps.mjs pode ser importado sem erro", async () => {
const mod = await import("../../bin/cli/runtime/nativeDeps.mjs");
assert.equal(typeof mod.ensureRuntimeDir, "function");
assert.equal(typeof mod.getRuntimeNodeModules, "function");
assert.equal(typeof mod.hasModule, "function");
assert.equal(typeof mod.isBetterSqliteBinaryValid, "function");
assert.equal(typeof mod.npmInstallRuntime, "function");
assert.equal(typeof mod.ensureBetterSqliteRuntime, "function");
assert.equal(typeof mod.buildEnvWithRuntime, "function");
});
test("ensureRuntimeDir cria diretório e package.json", async () => {
const { ensureRuntimeDir } = await import("../../bin/cli/runtime/nativeDeps.mjs");
const dir = ensureRuntimeDir();
const { existsSync } = await import("node:fs");
assert.ok(existsSync(dir), "runtime dir deve existir");
assert.ok(existsSync(join(dir, "package.json")), "package.json deve existir");
});
test("getRuntimeNodeModules retorna caminho dentro do DATA_DIR", async () => {
const { getRuntimeNodeModules } = await import("../../bin/cli/runtime/nativeDeps.mjs");
const nm = getRuntimeNodeModules();
assert.ok(nm.startsWith(tmpDir), "node_modules deve estar dentro do tmpDir");
assert.ok(nm.endsWith("node_modules"), "path deve terminar com node_modules");
});
test("hasModule retorna false para módulo inexistente", async () => {
const { hasModule } = await import("../../bin/cli/runtime/nativeDeps.mjs");
assert.equal(hasModule("definitely-not-installed-xyz"), false);
});
test("isBetterSqliteBinaryValid retorna false quando binário não existe", async () => {
const { isBetterSqliteBinaryValid } = await import("../../bin/cli/runtime/nativeDeps.mjs");
assert.equal(isBetterSqliteBinaryValid(), false);
});
test("buildEnvWithRuntime extende NODE_PATH com runtime node_modules", async () => {
const { buildEnvWithRuntime, getRuntimeNodeModules } =
await import("../../bin/cli/runtime/nativeDeps.mjs");
const nm = getRuntimeNodeModules();
const env = buildEnvWithRuntime({});
assert.ok(env.NODE_PATH.includes(nm), "NODE_PATH deve conter runtime node_modules");
});
test("buildEnvWithRuntime preserva NODE_PATH existente", async () => {
const { buildEnvWithRuntime } = await import("../../bin/cli/runtime/nativeDeps.mjs");
const env = buildEnvWithRuntime({ NODE_PATH: "/existing/path" });
assert.ok(env.NODE_PATH.includes("/existing/path"), "NODE_PATH original deve ser preservado");
});
test("isBetterSqliteBinaryValid detecta ELF magic bytes (Linux)", async () => {
const { getRuntimeNodeModules, isBetterSqliteBinaryValid } =
await import("../../bin/cli/runtime/nativeDeps.mjs");
const nm = getRuntimeNodeModules();
const buildDir = join(nm, "better-sqlite3", "build", "Release");
mkdirSync(buildDir, { recursive: true });
const binary = join(buildDir, "better_sqlite3.node");
const buf = Buffer.from([0x7f, 0x45, 0x4c, 0x46, 0x00, 0x00, 0x00, 0x00]);
writeFileSync(binary, buf);
const result = isBetterSqliteBinaryValid();
const { platform } = await import("node:os");
if (platform() === "linux") {
assert.equal(result, true, "ELF magic bytes devem ser válidos no Linux");
}
rmSync(join(nm, "better-sqlite3"), { recursive: true, force: true });
});
test("commands/runtime.mjs pode ser importado sem erro", async () => {
const mod = await import("../../bin/cli/commands/runtime.mjs");
assert.equal(typeof mod.registerRuntime, "function");
});