|
| 1 | +import { describe, expect, test } from "bun:test" |
| 2 | +import { saveDraft, takeDraft } from "../../src/component/prompt/draft-stash" |
| 3 | +import { emptyPrompt } from "../../src/prompt/history" |
| 4 | + |
| 5 | +// The Prompt component stashes an unsent draft in onCleanup and takes it back |
| 6 | +// in onMount across route remounts. The key it uses is undefined by default |
| 7 | +// (one global slot that follows focus across tabs) and the tab identity |
| 8 | +// (sessionID, or "home") when the tab_drafts experiment is on. |
| 9 | + |
| 10 | +function draft(text: string, cursor = text.length) { |
| 11 | + return { prompt: { ...emptyPrompt(), text }, cursor } |
| 12 | +} |
| 13 | + |
| 14 | +describe("prompt draft stash", () => { |
| 15 | + test("global slot follows focus: any tab takes the last stashed draft", () => { |
| 16 | + const entry = draft("follow me") |
| 17 | + saveDraft(undefined, entry) |
| 18 | + expect(takeDraft(undefined)).toBe(entry) |
| 19 | + // Consumed on take, so a remount never restores a stale copy. |
| 20 | + expect(takeDraft(undefined)).toBeUndefined() |
| 21 | + }) |
| 22 | + |
| 23 | + test("tab-keyed drafts stay on the tab they were written in", () => { |
| 24 | + const two = draft("notes for session two") |
| 25 | + saveDraft("ses_two", two) |
| 26 | + |
| 27 | + // Switching to another tab or home finds nothing. |
| 28 | + expect(takeDraft("ses_one")).toBeUndefined() |
| 29 | + expect(takeDraft("home")).toBeUndefined() |
| 30 | + |
| 31 | + // Returning to the original tab restores exactly its draft, once. |
| 32 | + expect(takeDraft("ses_two")).toBe(two) |
| 33 | + expect(takeDraft("ses_two")).toBeUndefined() |
| 34 | + }) |
| 35 | + |
| 36 | + test("each tab keeps its own draft, including home", () => { |
| 37 | + const one = draft("DRAFT-ONE") |
| 38 | + const home = draft("draft on home") |
| 39 | + saveDraft("ses_one", one) |
| 40 | + saveDraft("home", home) |
| 41 | + |
| 42 | + expect(takeDraft("home")).toBe(home) |
| 43 | + expect(takeDraft("ses_one")).toBe(one) |
| 44 | + }) |
| 45 | + |
| 46 | + test("global and tab slots never leak into each other when the experiment toggles mid-draft", () => { |
| 47 | + const global = draft("stashed before enabling tab_drafts") |
| 48 | + const keyed = draft("stashed after enabling tab_drafts") |
| 49 | + saveDraft(undefined, global) |
| 50 | + saveDraft("ses_a", keyed) |
| 51 | + |
| 52 | + // A keyed lookup must not surface the global draft on the wrong tab... |
| 53 | + expect(takeDraft("ses_b")).toBeUndefined() |
| 54 | + // ...and the global slot must not surface a tab's draft. |
| 55 | + expect(takeDraft(undefined)).toBe(global) |
| 56 | + expect(takeDraft("ses_a")).toBe(keyed) |
| 57 | + }) |
| 58 | + |
| 59 | + test("a newer draft for the same slot replaces the older one", () => { |
| 60 | + saveDraft("ses_a", draft("first")) |
| 61 | + const second = draft("second") |
| 62 | + saveDraft("ses_a", second) |
| 63 | + expect(takeDraft("ses_a")).toBe(second) |
| 64 | + }) |
| 65 | +}) |
0 commit comments