| 1 | package serve |
| 2 | |
| 3 | import ( |
| 4 | "slices" |
| 5 | "testing" |
| 6 | "time" |
| 7 | |
| 8 | "reasonix/internal/checkpoint" |
| 9 | ) |
| 10 | |
| 11 | func TestServeCheckpointMetasExposeRewindCapabilities(t *testing.T) { |
| 12 | now := time.Unix(1_700_000_000, 0) |
| 13 | raw := []checkpoint.Meta{ |
| 14 | {Turn: 1, Prompt: "first", Time: now, CanUndoFiles: true}, |
| 15 | {Turn: 2, Prompt: "second", Paths: []string{"z.go", "a.go"}, Time: now.Add(time.Second), CanUndoFiles: true}, |
| 16 | } |
| 17 | boundaries := map[int]bool{1: true, 2: false} |
| 18 | |
| 19 | got := serveCheckpointMetas(raw, func(turn int) bool { return boundaries[turn] }) |
| 20 | if len(got) != 2 { |
| 21 | t.Fatalf("checkpoint count = %d, want 2", len(got)) |
| 22 | } |
| 23 | if !got[0].CanCode || !got[0].CanConversation { |
| 24 | t.Fatalf("first capabilities = code:%v conversation:%v, want true/true", got[0].CanCode, got[0].CanConversation) |
| 25 | } |
| 26 | if got[1].CanConversation { |
| 27 | t.Fatal("checkpoint without a message boundary must not advertise conversation rewind") |
| 28 | } |
| 29 | if got[0].FileCount != 2 || got[0].TurnFileCount != 0 || !slices.Equal(got[0].Files, []string{"a.go", "z.go"}) { |
| 30 | t.Fatalf("first cumulative files = %#v count=%d turnCount=%d", got[0].Files, got[0].FileCount, got[0].TurnFileCount) |
| 31 | } |
| 32 | if got[0].Time != now.UnixMilli() { |
| 33 | t.Fatalf("first time = %d, want %d", got[0].Time, now.UnixMilli()) |
| 34 | } |
| 35 | } |
| 36 |