import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createMockClosableStateStores } from "../helpers/mock-stores.js"; import { Ok } from "@tff/core"; import { SQLiteStateAdapter } from "../../../../src/infrastructure/adapters/sqlite/sqlite-state.adapter.js"; import { checkpointLoadCmd } from "../../../../src/cli/commands/checkpoint-load.cmd.js"; const { getAdapter, setAdapter } = vi.hoisted(() => { let _adapter: SQLiteStateAdapter | null = null; return { getAdapter: () => _adapter, setAdapter: (a: SQLiteStateAdapter) => { _adapter = a; }, }; }); vi.mock("../../../../src/infrastructure/adapters/sqlite/create-state-stores.js", () => ({ createClosableStateStoresUnchecked: vi.fn(() => createMockClosableStateStores(getAdapter()!)), })); vi.mock("../../../../src/infrastructure/adapters/filesystem/markdown-artifact.adapter.js", () => ({ MarkdownArtifactAdapter: class { async read(path: string) { if (path.includes("M01-S01")) { return Ok( '', ); } return { ok: false, error: { code: "NOT_FOUND", message: "File not found", meta: { path } } }; } }, })); function seedAdapter(): { adapter: SQLiteStateAdapter; sliceId: string } { const adapter = SQLiteStateAdapter.createInMemory(); adapter.init(); adapter.saveProject({ name: "Test Project" }); adapter.createMilestone({ number: 1, name: "Milestone One" }); const msR = adapter.listMilestones(); if (!msR.ok || msR.data.length === 0) throw new Error("No milestones seeded"); const milestoneId = msR.data[0].id; adapter.createSlice({ milestoneId, number: 1, title: "Slice One" }); return { adapter, sliceId: "M01-S01" }; } describe("checkpoint:load", () => { beforeEach(() => { const { adapter } = seedAdapter(); setAdapter(adapter); }); afterEach(() => { getAdapter()?.close(); }); it("loads checkpoint for valid slice-id", async () => { const result = JSON.parse(await checkpointLoadCmd(["--slice-id", "M01-S01"])); expect(result.ok).toBe(true); expect(result.data.baseCommit).toBe("abc123"); }); it("fails when checkpoint is missing", async () => { const adapter = getAdapter()!; adapter.createSlice({ milestoneId: adapter.listMilestones().data![0].id, number: 2, title: "Slice Two", }); const result = JSON.parse(await checkpointLoadCmd(["--slice-id", "M01-S02"])); expect(result.ok).toBe(false); expect(result.error.code).toBe("NOT_FOUND"); }); it("fails for invalid slice-id format", async () => { const result = JSON.parse(await checkpointLoadCmd(["--slice-id", "invalid"])); expect(result.ok).toBe(false); expect(result.error.code).toBe("PATTERN_MISMATCH"); }); it("fails when missing required flag", async () => { const result = JSON.parse(await checkpointLoadCmd([])); expect(result.ok).toBe(false); expect(result.error.code).toBe("MISSING_REQUIRED_FLAG"); }); });