import * as assert from "node:assert"; import { execFileSync } from "node:child_process"; import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import * as vscode from "vscode"; import { activateApi, settle, settleUntil } from "./helpers"; const WS = process.env.E2E_WORKSPACE!; suite("baseline router (PUC-1, INV-7/D13/D14)", () => { test("snapshot mode: enter captures; markReviewed re-pins clean", async () => { const api = await activateApi(); const doc = await vscode.workspace.openTextDocument({ language: "markdown", content: "one\n" }); const ed = await vscode.window.showTextDocument(doc); await vscode.commands.executeCommand("cowriting.coeditDocument"); await settle(); assert.strictEqual(api.diffViewController.modeOf(doc.uri.toString()), "snapshot"); assert.strictEqual(api.diffViewController.getBaseline(doc.uri.toString())?.text, "one\n"); await ed.edit((b) => b.insert(new vscode.Position(1, 0), "two\n")); // Task 3 (INV-13): the status-bar/SCM change count tracks the live edit. await settleUntil(() => api.scmSurfaceController.changeCount(doc.uri.toString()) === 1); await vscode.commands.executeCommand("cowriting.markReviewed"); const b = api.diffViewController.getBaseline(doc.uri.toString()); assert.strictEqual(b?.text, "one\ntwo\n"); assert.strictEqual(b?.reason, "pinned"); // A pin re-baselines to the clean current text, so the change count resets. await settleUntil(() => api.scmSurfaceController.changeCount(doc.uri.toString()) === 0); }); test("head mode: baseline = HEAD; commit advances it", async function () { this.timeout(30000); const dir = fs.mkdtempSync(path.join(os.tmpdir(), "cw-git-")); const git = (...a: string[]) => execFileSync("git", ["-C", dir, ...a], { encoding: "utf8" }); git("init", "-q"); fs.writeFileSync(path.join(dir, "doc.md"), "committed\n"); git("add", "doc.md"); git("-c", "user.name=t", "-c", "user.email=t@t", "commit", "-qm", "c1"); const api = await activateApi(); const doc = await vscode.workspace.openTextDocument(vscode.Uri.file(path.join(dir, "doc.md"))); const ed = await vscode.window.showTextDocument(doc); await vscode.commands.executeCommand("cowriting.coeditDocument"); await settleUntil(() => api.diffViewController.modeOf(doc.uri.toString()) === "head", 10000); assert.strictEqual(api.diffViewController.getBaseline(doc.uri.toString())?.text, "committed\n"); await ed.edit((b) => b.insert(new vscode.Position(1, 0), "uncommitted\n")); await doc.save(); git("-c", "user.name=t", "-c", "user.email=t@t", "commit", "-aqm", "c2"); await settleUntil( () => api.diffViewController.getBaseline(doc.uri.toString())?.text === "committed\nuncommitted\n", 15000, ); assert.strictEqual(api.diffViewController.getBaseline(doc.uri.toString())?.reason, "head"); }); // Finding 3 (final whole-branch review, session native-surfaces-exec): // DiffViewController only establishes a baseline on the registry's ENTER // transition (a doc it can find already open) and, at startup, for docs // already open at that moment. A registry member entered while its document // was NOT yet open (the real-world case: a persisted coediting set restored // after a window reload, whose member is only lazily opened later) used to // never get a baseline at all — reproduced here directly via // `coeditingRegistry.enter(uri)` on a URI with no open document yet (the // registry API doesn't require one), then a genuine later open. test("a registry member entered before its doc was open gets its baseline established once the doc IS opened", async () => { const api = await activateApi(); const rel = "docs/finding3-establish-on-open.md"; const abs = path.join(WS, rel); const content = "# late open\n\nestablish-on-open should catch this.\n"; fs.writeFileSync(abs, content, "utf8"); const uri = vscode.Uri.file(abs); // Membership without an open document — DiffViewController's enter- // transition handler no-ops (`textDocuments.find` misses), reproducing // the gap: a coediting member with no mode/baseline yet. api.coeditingRegistry.enter(uri); assert.strictEqual(api.coeditingRegistry.isCoediting(uri), true, "sanity: registry membership recorded"); assert.strictEqual(api.diffViewController.modeOf(uri.toString()), undefined, "sanity: the gap is reproduced"); // A genuine later open — the fix's `renderIfOpen`/`onDidOpenTextDocument` // path must establish the baseline it missed. const doc = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(doc); await settleUntil(() => api.diffViewController.modeOf(uri.toString()) !== undefined, 10000); assert.strictEqual(api.diffViewController.modeOf(uri.toString()), "snapshot"); assert.strictEqual(api.diffViewController.getBaseline(uri.toString())?.text, content); }); });