Files
vscode-cowriting-plugin/test/store.test.ts
T
2026-06-10 06:49:31 -07:00

58 lines
2.0 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import { CoauthorStore } from "../src/store";
import { emptyArtifact, newId, serializeArtifact, type Artifact } from "../src/model";
let root: string;
beforeEach(() => {
root = fs.mkdtempSync(path.join(os.tmpdir(), "coauthor-store-"));
});
afterEach(() => {
fs.rmSync(root, { recursive: true, force: true });
});
function withThread(): Artifact {
const a = emptyArtifact("docs/spec.md");
a.anchors["a1"] = { fingerprint: { text: "hello", before: "", after: "", lineHint: 0 } };
a.threads.push({
id: "t1",
anchorId: "a1",
status: "open",
messages: [{ id: newId("m"), author: { kind: "human", id: "ben" }, body: "note", createdAt: "2026-06-10T00:00:00.000Z" }],
});
return a;
}
describe("CoauthorStore", () => {
it("returns null for a document with no sidecar", () => {
const store = new CoauthorStore(root);
expect(store.load("docs/spec.md")).toBeNull();
});
it("computes the sidecar path as .threads/<docPath>.json", () => {
const store = new CoauthorStore(root);
expect(store.sidecarPath("docs/spec.md")).toBe(path.join(root, ".threads", "docs", "spec.md.json"));
});
it("save then load round-trips the artifact", () => {
const store = new CoauthorStore(root);
const a = withThread();
store.save("docs/spec.md", a);
expect(store.load("docs/spec.md")).toEqual(a);
});
it("writes byte-stable, pretty JSON (re-save is identical)", () => {
const store = new CoauthorStore(root);
const a = withThread();
store.save("docs/spec.md", a);
const first = fs.readFileSync(store.sidecarPath("docs/spec.md"), "utf8");
store.save("docs/spec.md", store.load("docs/spec.md")!);
const second = fs.readFileSync(store.sidecarPath("docs/spec.md"), "utf8");
expect(second).toBe(first);
expect(first).toBe(serializeArtifact(a));
});
});