TestCtrlCCancelsInflightOp: with a turn in flight, Ctrl+C cancels, clears pending tool calls, and leaves a "✗ cancelled" line in scrollback.
(t *testing.T)
| 179 | // TestCtrlCCancelsInflightOp: with a turn in flight, Ctrl+C cancels, clears |
| 180 | // pending tool calls, and leaves a "✗ cancelled" line in scrollback. |
| 181 | func TestCtrlCCancelsInflightOp(t *testing.T) { |
| 182 | m := newTestModel(t, func(http.ResponseWriter, *http.Request) {}) |
| 183 | ctx, cancel := context.WithCancel(context.Background()) |
| 184 | m.turnCtx = ctx |
| 185 | m.cancel = cancel |
| 186 | m.phase = phaseThinking |
| 187 | m.pending = []chmctx.ToolCall{{Name: "bash"}} |
| 188 | |
| 189 | out, _ := m.Update(tea.KeyMsg{Type: tea.KeyCtrlC}) |
| 190 | om := out.(Model) |
| 191 | |
| 192 | if om.phase.active() { |
| 193 | t.Fatalf("phase should be idle after cancel, got %v", om.phase) |
| 194 | } |
| 195 | if om.cancel != nil { |
| 196 | t.Fatal("cancel should be cleared after use") |
| 197 | } |
| 198 | if len(om.pending) != 0 { |
| 199 | t.Fatalf("pending should be cleared: %+v", om.pending) |
| 200 | } |
| 201 | if !strings.Contains(om.scroll.String(), "cancelled") { |
| 202 | t.Fatalf("expected ✗ cancelled in scrollback: %s", om.scroll.String()) |
| 203 | } |
| 204 | select { |
| 205 | case <-ctx.Done(): |
| 206 | // ctx propagated cancel, good |
| 207 | default: |
| 208 | t.Fatal("underlying context was not cancelled") |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // TestNonCtrlCKeypressResetsArming: once arming is live, pressing anything |
| 213 | // other than Ctrl+C clears the arm so the next idle Ctrl+C re-arms cleanly |
nothing calls this directly
no test coverage detected