| 📦 Turbo Core — files rewritten outside reload into their windows; the agent window wraps what you type and keeps a long paste aside as a token (#28); configrepo fetches a shared .turbo-<slug> from a forge URL (#25) fe23288 k33g 6h ago | 1 | package app |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/gdamore/tcell/v2" |
| 8 | ) |
| 9 | |
| 10 | // pasteKeys sends text as a terminal's bracketed paste would: a start mark, |
| 11 | // the characters as keys with Enter for each newline, an end mark. |
| 12 | func pasteKeys(a *App, text string) { |
| 13 | a.handle(tcell.NewEventPaste(true)) |
| 14 | for _, r := range text { |
| 15 | if r == '\n' { |
| 16 | a.handle(tcell.NewEventKey(tcell.KeyEnter, 0, tcell.ModNone)) |
| 17 | continue |
| 18 | } |
| 19 | a.handle(tcell.NewEventKey(tcell.KeyRune, r, tcell.ModNone)) |
| 20 | } |
| 21 | a.handle(tcell.NewEventPaste(false)) |
| 22 | } |
| 23 | |
| 24 | func TestABracketedPasteReachesAnAgentWindowWhole(t *testing.T) { |
| 25 | // Key by key, the two Enters would each have sent a prompt; whole, the |
| 26 | // three lines are one paste, kept aside as a token. |
| 27 | a, _ := newAgentsApp(t, "[[agent]]\nname=\"Echo\"\ncommand=\"cat\"\n") |
| 28 | a.NewAgent("Echo") |
| 29 | agent := a.activeAgent() |
| 30 | if agent == nil { |
| 31 | t.Fatal("no agent window is in front") |
| 32 | } |
| 33 | |
| 34 | pasteKeys(a, "one\ntwo\nthree") |
| 35 | |
| 36 | if got := agent.view.Input(); got != "[Pasted #1 · 3 lines · 13 chars]" { |
| 37 | t.Errorf("the box holds %q", got) |
| 38 | } |
| 39 | if entries := agent.session.Entries(); len(entries) != 0 { |
| 40 | t.Errorf("%d prompt(s) were sent by the newlines inside the paste", len(entries)) |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | func TestABracketedPasteIntoAFileIsTypedAsBefore(t *testing.T) { |
| 45 | a, _ := newTestApp(t) |
| 46 | a.NewFile() |
| 47 | |
| 48 | pasteKeys(a, "ab") |
| 49 | |
| 50 | if got := a.activeView().Buffer().Text(); got != "ab" { |
| 51 | t.Errorf("the file holds %q after a paste, want %q", got, "ab") |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | func TestKeysAreNotLostWhenAPasteIsCancelledByAnotherWindow(t *testing.T) { |
| 56 | // The paste starts in an agent window; nothing else in the editor sees |
| 57 | // its keys until it ends — so a key layer cannot half-act on them. |
| 58 | a, _ := newAgentsApp(t, "[[agent]]\nname=\"Echo\"\ncommand=\"cat\"\n") |
| 59 | a.NewAgent("Echo") |
| 60 | |
| 61 | a.handle(tcell.NewEventPaste(true)) |
| 62 | a.handle(tcell.NewEventKey(tcell.KeyF4, 0, tcell.ModNone)) // New file, were it a keystroke |
| 63 | a.handle(tcell.NewEventPaste(false)) |
| 64 | |
| 65 | if len(a.desktop.Windows()) != 1 { |
| 66 | t.Errorf("%d windows are open: a key inside a paste acted as a shortcut", len(a.desktop.Windows())) |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | func TestEditPasteGoesIntoTheAgentBox(t *testing.T) { |
| 71 | a, _ := newAgentsApp(t, "[[agent]]\nname=\"Echo\"\ncommand=\"cat\"\n") |
| 72 | a.NewAgent("Echo") |
| 73 | a.clipboard.SetText("from a file\nin the editor\n") |
| 74 | |
| 75 | a.Paste() |
| 76 | |
| 77 | if got := a.activeAgent().view.Input(); !strings.HasPrefix(got, "[Pasted #1 · 2 lines") { |
| 78 | t.Errorf("the box holds %q after Edit ▸ Paste", got) |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | func TestCtrlVInAnAgentWindowPastesTheEditorsClipboard(t *testing.T) { |
| 83 | a, _ := newAgentsApp(t, "[[agent]]\nname=\"Echo\"\ncommand=\"cat\"\n") |
| 84 | a.NewAgent("Echo") |
| 85 | a.clipboard.SetText("buildMenus") |
| 86 | |
| 87 | press(a, tcell.KeyCtrlV, 0, tcell.ModNone) |
| 88 | |
| 89 | if got := a.activeAgent().view.Input(); got != "buildMenus" { |
| 90 | t.Errorf("the box holds %q after Ctrl-V", got) |
| 91 | } |
| 92 | } |