package compaction import ( "testing" "git.gobha.me/xcaliber/chat-switchboard/treepath" ) func TestEstimateTokens(t *testing.T) { tests := []struct { input string want int }{ {"", 0}, {"a", 1}, {"abcd", 1}, {"abcde", 2}, {"Hello, world!", 4}, // 13 chars → ceil(13/4) = 4 {string(make([]byte, 100)), 25}, {string(make([]byte, 1000)), 250}, } for _, tt := range tests { got := EstimateTokens(tt.input) if got != tt.want { t.Errorf("EstimateTokens(%d chars) = %d, want %d", len(tt.input), got, tt.want) } } } func TestEstimatePath(t *testing.T) { path := []treepath.PathMessage{ {Content: string(make([]byte, 40))}, // 10 tokens + 4 overhead = 14 {Content: string(make([]byte, 80))}, // 20 tokens + 4 overhead = 24 {Content: string(make([]byte, 120))}, // 30 tokens + 4 overhead = 34 } got := EstimatePath(path) // (10+4) + (20+4) + (30+4) = 72 if got != 72 { t.Errorf("EstimatePath = %d, want 72", got) } } func TestEstimatePathFromSummary_NoSummary(t *testing.T) { path := make([]treepath.PathMessage, 10) for i := range path { path[i] = treepath.PathMessage{Role: "user", Content: string(make([]byte, 40))} } tokens, count, ok := EstimatePathFromSummary(path, 8) if !ok { t.Fatal("expected ok=true for 10 messages >= minMessages=8") } if count != 10 { t.Errorf("count = %d, want 10", count) } // Each: 10 tokens + 4 overhead = 14, × 10 = 140 if tokens != 140 { t.Errorf("tokens = %d, want 140", tokens) } } func TestEstimatePathFromSummary_TooFew(t *testing.T) { path := make([]treepath.PathMessage, 3) for i := range path { path[i] = treepath.PathMessage{Role: "user", Content: "hello"} } _, _, ok := EstimatePathFromSummary(path, 8) if ok { t.Error("expected ok=false for 3 messages < minMessages=8") } } func TestEstimatePathFromSummary_SkipsSystemMessages(t *testing.T) { path := []treepath.PathMessage{ {Role: "system", Content: "You are helpful."}, {Role: "user", Content: string(make([]byte, 40))}, {Role: "assistant", Content: string(make([]byte, 40))}, } tokens, count, ok := EstimatePathFromSummary(path, 1) if !ok { t.Fatal("expected ok=true") } // system skipped, 2 non-system messages if count != 2 { t.Errorf("count = %d, want 2", count) } if tokens != 28 { // 2 × (10 + 4) = 28 t.Errorf("tokens = %d, want 28", tokens) } }