/** * Shared bash-tool helper tests. * Covers strict env parsing and compact session labels. */ import { afterEach, describe, expect, it, vi } from "vitest"; import { deriveSessionName, readEnvInt } from "./bash-tools.shared.js"; describe("readEnvInt", () => { afterEach(() => { vi.unstubAllEnvs(); }); it("reads deprecated PI env integer aliases behind OPENCLAW env names", () => { vi.stubEnv("PI_BASH_YIELD_MS", "250"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBe(250); vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "500"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBe(500); }); it("ignores partial environment integers", () => { vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "250ms"); vi.stubEnv("PI_BASH_YIELD_MS", "500"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBeUndefined(); }); it("reads only strict signed decimal environment integers", () => { vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "+250"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBe(250); vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "0x10"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBeUndefined(); vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "1e2"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBeUndefined(); }); it("ignores unsafe environment integers", () => { vi.stubEnv("OPENCLAW_BASH_YIELD_MS", "9007199254740993"); expect(readEnvInt("OPENCLAW_BASH_YIELD_MS", "PI_BASH_YIELD_MS")).toBeUndefined(); }); }); describe("deriveSessionName", () => { it("labels well-formed quoted commands", () => { expect(deriveSessionName('node "my server.js" --port 8080')).toBe("node my server.js"); expect(deriveSessionName("git commit -m 'fix bug'")).toBe("git commit"); }); it("keeps grouping backslash-bearing quoted spans into one token", () => { expect(deriveSessionName('tar "a\\b c"')).toBe("tar a\\b c"); }); it("treats backslash as literal inside single-quoted spans", () => { expect(deriveSessionName("cmd 'a b\\' next")).toBe("cmd a b\\"); }); it("returns a label without catastrophic backtracking on unterminated quoted backslash runs", () => { for (const quote of [`"`, `'`]) { const malicious = `node ${quote}${"\\".repeat(50000)}`; const start = process.hrtime.bigint(); const label = deriveSessionName(malicious); const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6; expect(typeof label).toBe("string"); expect(elapsedMs).toBeLessThan(100); } }); });