import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; import { RECENT_CAP, addRecent, loadRecent, saveRecent } from "../src/recent.js"; import type { EditorRecentEntry } from "../src/ipc.js"; function entry(root: string, name = "p"): EditorRecentEntry { return { root, name }; } describe("addRecent", () => { it("prepends new entries and dedupes by root", () => { const base = [entry("/a"), entry("/b")]; const next = addRecent(base, entry("/b", "b2")); expect(next.map((e) => e.root)).toEqual(["/b", "/a"]); expect(next[0]?.name).toBe("b2"); }); it("caps the list at RECENT_CAP", () => { let list: EditorRecentEntry[] = []; for (let i = 0; i < RECENT_CAP + 3; i++) list = addRecent(list, entry(`/p${i}`)); expect(list.length).toBe(RECENT_CAP); expect(list[0]?.root).toBe(`/p${RECENT_CAP + 2}`); }); }); describe("recent persistence", () => { it("roundtrips through a json file", async () => { const dir = await mkdtemp(join(tmpdir(), "editor-recent-")); try { const file = join(dir, "recent.json"); const entries = [entry("/a", "A"), entry("/b", "B")]; await saveRecent(file, entries); expect(await loadRecent(file)).toEqual(entries); } finally { await rm(dir, { recursive: true, force: true }); } }); it("returns [] for a missing file", async () => { const dir = await mkdtemp(join(tmpdir(), "editor-recent-")); try { expect(await loadRecent(join(dir, "nope.json"))).toEqual([]); } finally { await rm(dir, { recursive: true, force: true }); } }); it("returns [] for corrupt json and drops invalid entries", async () => { const dir = await mkdtemp(join(tmpdir(), "editor-recent-")); try { const corrupt = join(dir, "corrupt.json"); const { writeFile } = await import("node:fs/promises"); await writeFile(corrupt, "{ not json", "utf8"); expect(await loadRecent(corrupt)).toEqual([]); const mixed = join(dir, "mixed.json"); await writeFile(mixed, JSON.stringify([{ root: "/ok", name: "Ok" }, { root: 42 }, "junk"]), "utf8"); expect(await loadRecent(mixed)).toEqual([{ root: "/ok", name: "Ok" }]); } finally { await rm(dir, { recursive: true, force: true }); } }); });