返回 DeepSeek-Reasonix
catalog_retract_test.go
根目录 / internal / session / catalog_retract_test.go
1 package session
2
3 import (
4 "encoding/json"
5 "reflect"
6 "testing"
7
8 "reasonix/internal/provider"
9 )
10
11 func TestCatalogReducerRetractionRestoreAndAuthoredPreview(t *testing.T) {
12 var commits []Commit
13 reducer := catalogReducer{}
14 var sequence uint64
15 apply := func(turnID string, events ...Event) {
16 t.Helper()
17 commit := Commit{TurnID: turnID, FirstSequence: sequence + 1, EventCount: len(events), Events: events}
18 for i := range commit.Events {
19 sequence++
20 commit.Events[i].Sequence = sequence
21 }
22 commits = append(commits, commit)
23 if err := reducer.apply(commit); err != nil {
24 t.Fatal(err)
25 }
26 full, err := Project(commits)
27 if err != nil {
28 t.Fatal(err)
29 }
30 if got, want := reducer.metadata(Manifest{}), metadataFromProjection(Manifest{}, sequence, full); !reflect.DeepEqual(got, want) {
31 t.Fatalf("reducer=%+v canonical=%+v", got, want)
32 }
33 if len(reducer.state.Messages)+len(reducer.state.ModelMessages)+len(reducer.state.Turns) != 0 {
34 t.Fatal("catalog retained transcript bodies or full turn boundaries")
35 }
36 }
37 message := func(kind, id, raw string) Event {
38 payload, _ := json.Marshal(map[string]any{"message": provider.Message{ID: id, Role: provider.RoleUser, RawContent: raw, Content: "<context>provider-only</context>"}})
39 return Event{Kind: kind, Payload: payload}
40 }
41 check := func(turns int, preview string) {
42 t.Helper()
43 got := reducer.metadata(Manifest{})
44 if got.Turns != turns || got.Preview != preview {
45 t.Fatalf("turns=%d preview=%q; want %d %q", got.Turns, got.Preview, turns, preview)
46 }
47 }
48 for _, id := range []string{"first", "second"} {
49 apply(id+"-turn", Event{Kind: "turn/start", Payload: json.RawMessage(`{}`)}, message("message/complete", id, id+" question"), Event{Kind: "turn/end", Payload: json.RawMessage(`{"status":"completed"}`)})
50 }
51 check(2, "first question")
52 apply("", Event{Kind: "message/retract", Payload: json.RawMessage(`{"messageIds":["first"]}`)})
53 check(1, "second question")
54 apply("", message("message/upsert", "first", "restored question"))
55 check(2, "second question")
56 apply("", Event{Kind: "message/retract", Payload: json.RawMessage(`{"messageIds":["second"]}`)})
57 check(1, "restored question")
58 apply("", Event{Kind: "message/upsert", Payload: json.RawMessage(`{"message":{"id":"first","role":"assistant","content":"not a user preview"}}`)})
59 check(1, "")
60 }
61
61 lines GO