TestStaleStreamEventDoesNotMutateLiveTurn: after Ctrl+C kills turn 1 and the user submits turn 2, turn 1's readEvent Cmd can still fire (buffered channel or producer not yet exited). That stale event must not write turn 2's streaming buffer or session counters.
(t *testing.T)
| 2588 | // handleStream must drain-only. |
| 2589 | func TestHandleStreamDrainsAfterCancel(t *testing.T) { |
| 2590 | m := newTestModel(t, func(http.ResponseWriter, *http.Request) {}) |
| 2591 | m.phase = phaseIdle // post-cancel state |
| 2592 | m.sessionTokens = 100 |
| 2593 | |
| 2594 | out, _ := m.handleStream(llm.Event{Kind: llm.EventContent, Content: "ghost"}) |
| 2595 | om := out.(Model) |
| 2596 | if om.streaming.Len() != 0 { |
| 2597 | t.Fatalf("stale EventContent wrote to streaming: %q", om.streaming.String()) |
| 2598 | } |
| 2599 | out, _ = om.handleStream(llm.Event{Kind: llm.EventToolCall, ToolCall: &chmctx.ToolCall{ID: "c", Name: "bash"}}) |
| 2600 | om = out.(Model) |
| 2601 | if len(om.pending) != 0 { |
| 2602 | t.Fatalf("stale EventToolCall re-populated pending: %+v", om.pending) |
| 2603 | } |
| 2604 | out, _ = om.handleStream(llm.Event{Kind: llm.EventDone, Tokens: 50}) |
| 2605 | om = out.(Model) |
| 2606 | if om.sessionTokens != 100 { |
| 2607 | t.Fatalf("stale EventDone credited tokens to session: %d", om.sessionTokens) |
| 2608 | } |
| 2609 | } |
| 2610 | |
| 2611 | // TestHandleStreamClosedSkipsAdvanceAfterCancel: after Ctrl+C leaves phase=idle, |
| 2612 | // the deferred streamClosedMsg must not auto-restart a turn (the agent re- |
nothing calls this directly
no test coverage detected