mirror of
https://github.com/tiennm99/awesome-coding-agents.git
synced 2026-06-06 16:13:32 +00:00
229 lines
5.9 KiB
Go
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")
|
|
}
|
|
}
|