test(#70): lock the honest hard-failure reject path (distrusted span → warn, keep, false)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -256,6 +256,43 @@ suite("F12 inline diff — #70 reject after interior edit (INV-5)", () => {
|
||||
await settle();
|
||||
assert.strictEqual(doc.getText(), `# T\n\n${ORIGINAL}\n`, "original restored exactly (INV-5)");
|
||||
});
|
||||
|
||||
// Fix direction (b): when the tracked span itself is distrusted (an edit
|
||||
// straddled its boundary — here a deletion running from the heading into the
|
||||
// span's interior), the reject FAILS honestly: warning path, proposal kept,
|
||||
// buffer untouched. Silent-skip-and-report-success (the #70 bug) must not come
|
||||
// back; reverting at a clamped guessed offset (INV-11) must not either.
|
||||
// (A boundary-straddling DELETION is used because VS Code minimizes workspace
|
||||
// edits before change events fire — a wholesale rewrite sharing a prefix/suffix
|
||||
// decomposes into interior hunks the span legitimately survives.)
|
||||
test("reject fails loudly — proposal kept, buffer untouched — when the span is distrusted", async () => {
|
||||
const ORIGINAL = "Sentence one stands here.";
|
||||
const { doc } = await freshDoc("docs/s70-reject-distrust.md", `# T\n\n${ORIGINAL}\n`);
|
||||
const api = await getApi();
|
||||
const p = api.proposalController;
|
||||
const docKey = p.keyFor(doc);
|
||||
const fp = { text: ORIGINAL, before: "", after: "", lineHint: 2 };
|
||||
const id = await p.propose(doc, fp, "Sentence ONE stands here.",
|
||||
{ kind: "agent", id: "claude", agent: { sdk: "x", model: "m", sessionId: "s" } }, { granularity: "block" });
|
||||
await p.optimisticApply(doc, id!);
|
||||
await settle();
|
||||
// Delete from inside the heading through the middle of the applied span:
|
||||
// the edit straddles the span's start boundary → the tracked span is
|
||||
// distrusted AND the exact anchor no longer resolves.
|
||||
const mid = doc.getText().indexOf("ONE");
|
||||
const we = new vscode.WorkspaceEdit();
|
||||
we.replace(doc.uri, new vscode.Range(doc.positionAt(2), doc.positionAt(mid + 1)), "");
|
||||
assert.ok(await vscode.workspace.applyEdit(we), "boundary-straddling deletion applied");
|
||||
await settle();
|
||||
const before = doc.getText();
|
||||
assert.strictEqual(await p.revertInPlace(docKey, id!), false, "reject reports failure (no silent success)");
|
||||
await settle();
|
||||
assert.strictEqual(doc.getText(), before, "buffer untouched — never reverted by guess (INV-11)");
|
||||
assert.ok(p.listProposals(doc).some((v) => v.id === id), "proposal kept (not silently dropped)");
|
||||
// Cleanup for later tests: the never-locatable husk is discarded via the
|
||||
// plain record-only reject.
|
||||
assert.strictEqual(p.rejectById(docKey, id!), true);
|
||||
});
|
||||
});
|
||||
|
||||
// Reload-safety: a proposal that was optimistically applied in a PRIOR session
|
||||
|
||||
Reference in New Issue
Block a user