| 1 | // Run: tsx src/__tests__/rewind-fork-routing.test.ts |
| 2 | |
| 3 | import assert from "node:assert/strict"; |
| 4 | import { readFileSync } from "node:fs"; |
| 5 | import { dirname, resolve } from "node:path"; |
| 6 | import { fileURLToPath } from "node:url"; |
| 7 | import { dispatchPartialRewindNotice, partialRewindNotice, rewindFailureDetail, rewindOutcome } from "../lib/rewindCommit"; |
| 8 | |
| 9 | const testDir = dirname(fileURLToPath(import.meta.url)); |
| 10 | const undoSource = readFileSync(resolve(testDir, "../app-runtime/useSessionUndo.ts"), "utf8"); |
| 11 | const controllerSource = readFileSync(resolve(testDir, "../lib/useController.ts"), "utf8"); |
| 12 | |
| 13 | assert.match(undoSource, /const targetTabId = outcome\.tabId \|\| sourceTabId/); |
| 14 | assert.match(undoSource, /undoTabId: sourceTabId/); |
| 15 | assert.match(undoSource, /const outcome = await ports\.rewindForTabDetailed\(sourceTabId, turn, "conversation"\)/); |
| 16 | assert.match(undoSource, /ports\.sendToTab\(targetTabId, next, submit, original\)/); |
| 17 | assert.match(controllerSource, /settleRewindTarget\(result, tab => adoptReturnedTab\(tab, sourceTabId, forkNavigationSeq, "tab\.rewind"\)/); |
| 18 | assert.match(controllerSource, /partialNotice = partialRewindNotice\(result\)/); |
| 19 | assert.match(controllerSource, /dispatchPartialRewindNotice\(partialNotice, sourceTabId, outcome\.tabId,/); |
| 20 | assert.ok( |
| 21 | controllerSource.indexOf('await loadSessionDataForTab(sourceTabId, true, "rewind")') |
| 22 | < controllerSource.indexOf("dispatchPartialRewindNotice(partialNotice, sourceTabId, outcome.tabId,"), |
| 23 | "partial rewind warning must be appended after history reload", |
| 24 | ); |
| 25 | assert.equal(partialRewindNotice({ ok: true }), ""); |
| 26 | assert.equal( |
| 27 | partialRewindNotice({ ok: true, partial: true, conflicts: ["a.txt changed", "b.txt missing"] }), |
| 28 | "The conversation was forked, but code could not be fully restored. a.txt changed; b.txt missing", |
| 29 | ); |
| 30 | assert.equal(rewindFailureDetail({ ok: false, conflicts: ["a.txt changed"] }), "a.txt changed"); |
| 31 | assert.deepEqual(rewindOutcome({ ok: true, tabId: "fork-tab" }), { ok: true, tabId: "fork-tab" }); |
| 32 | const notices: Array<[string, string]> = []; |
| 33 | dispatchPartialRewindNotice("partial", "source", "fork", (tabId, text) => notices.push([tabId, text])); |
| 34 | assert.deepEqual(notices, [["source", "partial"], ["fork", "partial"]]); |
| 35 | |
| 36 | console.log("rewind fork routing contract passed"); |
| 37 |