fable-agent/src/fable5/flat-ledger.test.ts

78 lines
2.8 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import { FlatLedger, setLedgerDir } from "./flat-ledger.js";
describe("flat ledger", () => {
const testDir = path.join(os.tmpdir(), "fable-ledger-test");
beforeEach(() => {
fs.mkdirSync(testDir, { recursive: true });
setLedgerDir(testDir);
});
afterEach(() => {
fs.rmSync(testDir, { recursive: true, force: true });
});
it("writes and reads entries", () => {
const ledger = new FlatLedger("test-session");
const entry = ledger.append({
timestamp: new Date().toISOString(),
agent: "test-agent",
action: "build",
target: "src/main.ts",
result: "ok",
durationMs: 100,
});
expect(entry.step).toBe(1);
expect(entry.result).toBe("ok");
const state = ledger.readState();
expect(state.length).toBe(1);
expect(state[0].step).toBe(1);
});
it("returns last step", () => {
const ledger = new FlatLedger("test-session");
expect(ledger.lastStep()).toBeNull();
ledger.append({ timestamp: new Date().toISOString(), agent: "a", action: "build", target: "x", result: "ok", durationMs: 10 });
ledger.append({ timestamp: new Date().toISOString(), agent: "a", action: "test", target: "x", result: "fail", durationMs: 20 });
const last = ledger.lastStep();
expect(last?.step).toBe(2);
expect(last?.result).toBe("fail");
expect(ledger.lastActionResult()).toBe("fail");
});
it("produces summary", () => {
const ledger = new FlatLedger("test-session");
ledger.append({ timestamp: "t1", agent: "a", action: "b", target: "t", result: "ok", durationMs: 1 });
ledger.append({ timestamp: "t2", agent: "a", action: "b", target: "t", result: "ok", durationMs: 1 });
ledger.append({ timestamp: "t3", agent: "a", action: "b", target: "t", result: "fail", durationMs: 1 });
ledger.append({ timestamp: "t4", agent: "a", action: "b", target: "t", result: "skip", durationMs: 1 });
const summary = ledger.summary();
expect(summary).toContain("4 steps");
expect(summary).toContain("2 ok");
expect(summary).toContain("1 fail");
expect(summary).toContain("1 skip");
});
it("clear resets state", () => {
const ledger = new FlatLedger("test-session");
ledger.append({ timestamp: "t1", agent: "a", action: "b", target: "t", result: "ok", durationMs: 1 });
expect(ledger.readState().length).toBe(1);
ledger.clear();
expect(ledger.readState().length).toBe(0);
});
it("sessionNameFromTask generates safe names", () => {
const name = FlatLedger.sessionNameFromTask("Fix: broken auth on /api/v2/users");
expect(name).toBe("fix-broken-auth-on-api-v2-users");
expect(name.length).toBeLessThanOrEqual(40);
});
});