返回 DeepSeek-Reasonix
message_identity_test.go
根目录 / internal / event / message_identity_test.go
1 package event
2
3 import (
4 "errors"
5 "testing"
6 "time"
7 )
8
9 func TestMessageIdentitySurvivesCoalescingAndAttemptBoundary(t *testing.T) {
10 inner := &coalesceRecordSink{}
11 coalesced := Coalesce(inner, time.Hour)
12 first := WithMessageIdentity(coalesced, "message-1", "attempt-1")
13 second := WithMessageIdentity(coalesced, "message-2", "attempt-2")
14 first.Emit(Event{Kind: Reasoning, Text: "a"})
15 first.Emit(Event{Kind: Reasoning, Text: "b"})
16 first.Emit(Event{Kind: Reasoning, Text: "c"})
17 second.Emit(Event{Kind: Reasoning, Text: "d"})
18 if err := EmitChecked(second, Event{Kind: ToolDispatch}); err != nil {
19 t.Fatal(err)
20 }
21 got := inner.snapshot()
22 if len(got) != 4 || got[0].Text != "a" || got[1].Text != "bc" || got[2].Text != "d" {
23 t.Fatalf("coalesced output: %+v", got)
24 }
25 for i, e := range got {
26 messageID, attemptID := "message-1", "attempt-1"
27 if i >= 2 {
28 messageID, attemptID = "message-2", "attempt-2"
29 }
30 if e.MessageID != messageID || e.AttemptID != attemptID {
31 t.Fatalf("event %d lost ownership: %+v", i, e)
32 }
33 }
34 }
35
36 func TestMessageIdentityPreservesCheckedFailureAndExistingOwner(t *testing.T) {
37 want := errors.New("durability failure")
38 inner := &checkedRecordSink{err: want}
39 sink := WithMessageIdentity(inner, "outer", "outer-attempt")
40 if err := EmitChecked(sink, Event{Kind: ToolDispatch}); !errors.Is(err, want) {
41 t.Fatalf("durability failure = %v", err)
42 }
43 sink.Emit(Event{Kind: Message, MessageID: "inner", AttemptID: "inner-attempt"})
44 sink.Emit(Event{Kind: TurnDone})
45 got := inner.snapshot()
46 if len(got) != 2 || got[0].MessageID != "inner" || got[0].AttemptID != "inner-attempt" || got[1].MessageID != "" {
47 t.Fatalf("identity ownership changed: %+v", got)
48 }
49 }
50
50 lines GO