test(studio): temporary probes in the workbench file reader, silent unless a test installs them, so the poll test's failure on the runner says whether the file entry was empty or evicted

This commit is contained in:
yhh committed 2026-11-07 02:54:13 -08:00
1 parent 8447cc10ac
commit 1317859a0c
2 files changed
+7 -2

No files matched your search

@@ -116,10 +116,12 @@ it("leaves the rendered Workbench untouched when Markdown polls are unchanged",
commits.mockClear();
const base = performance.now();
const seen: string[] = [];
const notes: string[] = [];
(globalThis as { __diag?: (note: string) => void }).__diag = (note) => notes.push(note);
for (const n of [1, 2]) {
await tick();
seen.push(`after poll ${n} (${(performance.now() - base).toFixed(0)}ms): ${commits.mock.calls.length} commits [${commits.mock.calls.map((c) => `${c[1]}@${(c[5] - base).toFixed(0)}ms`).join(",")}], file reads ${read.mock.calls.length}, listings ${listed.mock.calls.length}`);
}
expect(read).toHaveBeenCalledTimes(3);
expect(commits.mock.calls.length, seen.join("; ")).toBe(0);
expect(commits.mock.calls.length, `${seen.join("; ")} | ${notes.join(" / ")}`).toBe(0);
});
@@ -15,6 +15,8 @@ type Entry = {
const blank = (): Entry => ({ file: null, draft: "", diff: "", error: "", errorCode: "", missing: false, pending: "", issued: 0 });
const dirty = (entry: Entry) => !!entry.file && entry.draft !== entry.file.content;
const diag = (note: string) => (globalThis as { __diag?: (note: string) => void }).__diag?.(note);
export function useWorkbenchFiles({ port, workspaceRoot, repos = [], path, openPaths, shown, refresh, poll }: {
port: AgentPort; workspaceRoot: string; repos?: GitRepoRow[]; path: string; openPaths: string[]; shown: boolean; refresh: string; poll: boolean;
}) {
@@ -34,7 +36,7 @@ export function useWorkbenchFiles({ port, workspaceRoot, repos = [], path, openP
}, [entries]);
useEffect(() => {
for (const [path, entry] of entries) {
if (!openPaths.includes(path) && !dirty(entry) && entry.pending !== "save") entries.delete(path);
if (!openPaths.includes(path) && !dirty(entry) && entry.pending !== "save") { diag(`evict ${path} among ${JSON.stringify(openPaths)}`); entries.delete(path); }
}
}, [entries, openPaths, version]);
@@ -45,6 +47,7 @@ export function useWorkbenchFiles({ port, workspaceRoot, repos = [], path, openP
if (entry.pending === "save" || dirty(entry) || (entry.file && !shown) || (quiet && entry.pending === "read")) return;
const ticket = ++entry.issued;
let changed = !quiet || !entry.file;
if (quiet) diag(`quiet read, file ${entry.file ? "held" : "empty"}, pending ${entry.pending || "none"}`);
void (async () => {
const valid = () => live && current.current === entries && ticket === entry.issued;
entry.pending = "read";