Files
awesome-coding-agents/history_test.go
T
2026-05-14 15:49:05 +07:00

229 lines
5.9 KiB
Go

package main
import (
"bytes"
"encoding/json"
"os"
"testing"
"time"
)
func TestComputeDeltas_NoHistory(t *testing.T) {
// Empty history slice should return empty delta map without panicking.
current := Snapshot{
Date: "2026-05-14",
Stars: map[string]int{
"org/repo": 100,
},
}
deltas := computeDeltas(nil, current)
if deltas == nil {
t.Errorf("expected non-nil empty map, got nil")
}
if len(deltas) != 0 {
t.Errorf("expected empty deltas, got %d entries", len(deltas))
}
}
func TestComputeDeltas_SevenDayWindow(t *testing.T) {
// The cutoff window is (cutoff-3d, cutoff] where cutoff = now - 7d.
// So valid snapshots have date in range (now-10d, now-7d].
now := time.Now().UTC()
today := now.Format("2006-01-02")
tests := []struct {
name string
daysAgo int
expectDelta bool
desc string
}{
{
name: "snapshot at exactly 7 days ago",
daysAgo: 7,
expectDelta: true,
desc: "at cutoff boundary — should be included",
},
{
name: "snapshot at 9 days ago",
daysAgo: 9,
expectDelta: true,
desc: "within (cutoff-3d, cutoff] — should be included",
},
{
name: "snapshot at 11 days ago",
daysAgo: 11,
expectDelta: false,
desc: "older than cutoff-3d — should be excluded",
},
{
name: "snapshot at 6 days ago",
daysAgo: 6,
expectDelta: false,
desc: "newer than cutoff — should be excluded",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
snapshotDate := now.AddDate(0, 0, -tt.daysAgo).Format("2006-01-02")
history := []Snapshot{
{
Date: snapshotDate,
Stars: map[string]int{
"org/repo": 100,
},
},
}
current := Snapshot{
Date: today,
Stars: map[string]int{
"org/repo": 150,
},
}
deltas := computeDeltas(history, current)
if tt.expectDelta {
if len(deltas) == 0 {
t.Errorf("%s: expected delta for 'org/repo', got empty map", tt.desc)
}
if delta, ok := deltas["org/repo"]; !ok || delta != 50 {
t.Errorf("%s: expected delta=50, got %v", tt.desc, delta)
}
} else {
if len(deltas) > 0 {
t.Errorf("%s: expected no delta, got %v", tt.desc, deltas)
}
}
})
}
}
func TestReadSnapshots_MalformedLine(t *testing.T) {
// Temp JSONL with: valid, malformed, empty, valid lines.
// Should skip malformed/empty and return only the 2 valid snapshots.
tmpDir := t.TempDir()
tmpFile := tmpDir + "/history.jsonl"
content := `{"date":"2026-05-01","stars":{"org/repo":100}}
not json at all { bad
{"date":"2026-05-02","stars":{"org/repo":200}}
{"date":"2026-05-03","stars":{"org/repo":300}}
`
if err := os.WriteFile(tmpFile, []byte(content), 0600); err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
snapshots, err := readSnapshots(tmpFile)
if err != nil {
t.Fatalf("readSnapshots failed: %v", err)
}
if len(snapshots) != 3 {
t.Errorf("expected 3 snapshots (skipped 1 malformed), got %d", len(snapshots))
}
// Check dates are in order.
if len(snapshots) >= 3 {
if snapshots[0].Date != "2026-05-01" {
t.Errorf("snapshot[0] date: expected 2026-05-01, got %s", snapshots[0].Date)
}
if snapshots[1].Date != "2026-05-02" {
t.Errorf("snapshot[1] date: expected 2026-05-02, got %s", snapshots[1].Date)
}
if snapshots[2].Date != "2026-05-03" {
t.Errorf("snapshot[2] date: expected 2026-05-03, got %s", snapshots[2].Date)
}
}
}
func TestReadSnapshots_MissingFile(t *testing.T) {
// Non-existent file should return nil with no error (not os.IsNotExist error).
snapshots, err := readSnapshots("/nonexistent/path/history.jsonl")
if err != nil {
t.Errorf("expected nil error on missing file, got %v", err)
}
if snapshots != nil {
t.Errorf("expected nil snapshots on missing file, got %v", snapshots)
}
}
func TestApplyMigrations(t *testing.T) {
// Test the canonical key migration logic.
stars := map[string]int{
"aaif-goose/goose": 45115,
"other/repo": 1000,
}
result := applyMigrations(stars)
// The old key should be removed.
if _, ok := result["aaif-goose/goose"]; ok {
t.Errorf("old key 'aaif-goose/goose' should be removed")
}
// The new key should be present with the value.
if v, ok := result["block/goose"]; !ok || v != 45115 {
t.Errorf("new key 'block/goose': expected 45115, got %v", v)
}
// Other keys should be unchanged.
if v, ok := result["other/repo"]; !ok || v != 1000 {
t.Errorf("'other/repo': expected 1000, got %v", v)
}
}
func TestWriteSnapshots_AtomicWrite(t *testing.T) {
// Verify that writeSnapshots uses atomic rename (writes to .tmp first).
tmpDir := t.TempDir()
tmpFile := tmpDir + "/history.jsonl"
snapshots := []Snapshot{
{Date: "2026-05-01", Stars: map[string]int{"org/repo": 100}},
{Date: "2026-05-02", Stars: map[string]int{"org/repo": 200}},
}
err := writeSnapshots(tmpFile, snapshots)
if err != nil {
t.Fatalf("writeSnapshots failed: %v", err)
}
// Verify file exists and has correct content.
if _, err := os.Stat(tmpFile); err != nil {
t.Fatalf("output file missing: %v", err)
}
content, err := os.ReadFile(tmpFile)
if err != nil {
t.Fatalf("ReadFile failed: %v", err)
}
// Verify JSON is valid and correct.
var readBack []Snapshot
decoder := json.NewDecoder(bytes.NewReader(content))
for decoder.More() {
var s Snapshot
if err := decoder.Decode(&s); err != nil {
t.Fatalf("decode failed: %v", err)
}
readBack = append(readBack, s)
}
if len(readBack) != 2 {
t.Errorf("expected 2 snapshots, got %d", len(readBack))
}
if readBack[0].Date != "2026-05-01" || readBack[0].Stars["org/repo"] != 100 {
t.Errorf("snapshot 0 mismatch: %+v", readBack[0])
}
if readBack[1].Date != "2026-05-02" || readBack[1].Stars["org/repo"] != 200 {
t.Errorf("snapshot 1 mismatch: %+v", readBack[1])
}
// .tmp file should not exist (cleaned up after rename).
if _, err := os.Stat(tmpFile + ".tmp"); !os.IsNotExist(err) {
t.Errorf("temp file should not exist after successful write")
}
}