package memory import ( "path/filepath" "testing" "time" ) func TestCapabilityGapStoreAndLoad(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "test.db") store, err := NewSQLiteStore(dbPath, nil) if err != nil { t.Fatalf("NewSQLiteStore error: %v", err) } defer store.Close() if err := store.SaveCapabilityGap("c1", "u1", "intent-a", "reason-a"); err != nil { t.Fatalf("SaveCapabilityGap error: %v", err) } if err := store.SaveCapabilityGap("c1", "u1", "intent-b", "reason-b"); err != nil { t.Fatalf("SaveCapabilityGap error: %v", err) } items, err := store.TopCapabilityGaps(10) if err != nil { t.Fatalf("TopCapabilityGaps error: %v", err) } if len(items) != 2 { t.Fatalf("expected 2 items, got %d", len(items)) } if items[0].Intent != "intent-b" { t.Fatalf("expected newest first, got first intent=%s", items[0].Intent) } } func TestTopCapabilityGapClusters(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "cluster.db") store, err := NewSQLiteStore(dbPath, nil) if err != nil { t.Fatalf("NewSQLiteStore error: %v", err) } defer store.Close() if err := store.SaveCapabilityGap("c1", "u1", "帮我查询 data 目录", "no_skill_matched"); err != nil { t.Fatalf("SaveCapabilityGap error: %v", err) } if err := store.SaveCapabilityGap("c1", "u2", "帮我 查询 data 目录", "no_skill_matched"); err != nil { t.Fatalf("SaveCapabilityGap error: %v", err) } if err := store.SaveCapabilityGap("c2", "u3", "读取配置文件内容", "tool_call_failed:file"); err != nil { t.Fatalf("SaveCapabilityGap error: %v", err) } clusters, err := store.TopCapabilityGapClusters(10, time.Now().UTC().Add(-1*time.Hour)) if err != nil { t.Fatalf("TopCapabilityGapClusters error: %v", err) } if len(clusters) == 0 { t.Fatalf("expected non-empty clusters") } if clusters[0].Count < 2 { t.Fatalf("expected first cluster count >= 2, got %d", clusters[0].Count) } }