Files
2026-08-14 23:41:57 +08:00

101 lines
2.8 KiB
Go

package dream
import (
"os"
"path/filepath"
"testing"
"time"
)
func TestStateRoundTrip(t *testing.T) {
root := t.TempDir()
report := &Report{Merged: 3, Deduped: 1, DryRun: false}
want := State{
LastRunAt: time.Date(2026, 8, 1, 9, 0, 0, 0, time.UTC),
LastStatus: "ok",
LastReport: report,
}
if err := SaveState(root, want); err != nil {
t.Fatalf("SaveState: %v", err)
}
got, err := LoadState(root)
if err != nil {
t.Fatalf("LoadState: %v", err)
}
if !got.LastRunAt.Equal(want.LastRunAt) {
t.Errorf("LastRunAt = %v, want %v", got.LastRunAt, want.LastRunAt)
}
if got.LastStatus != want.LastStatus {
t.Errorf("LastStatus = %q, want %q", got.LastStatus, want.LastStatus)
}
if got.LastReport == nil {
t.Fatalf("LastReport = nil, want %+v", want.LastReport)
}
if got.LastReport.Merged != report.Merged || got.LastReport.Deduped != report.Deduped {
t.Errorf("LastReport = %+v, want %+v", got.LastReport, report)
}
}
func TestSaveStateCreatesDir(t *testing.T) {
root := t.TempDir()
if err := SaveState(root, State{LastStatus: "ok"}); err != nil {
t.Fatalf("SaveState: %v", err)
}
if _, err := os.Stat(filepath.Join(root, "global", "dream", "state.json")); err != nil {
t.Errorf("state.json not created: %v", err)
}
}
func TestLoadStateMissingIsZero(t *testing.T) {
got, err := LoadState(t.TempDir())
if err != nil {
t.Fatalf("LoadState: %v", err)
}
if !got.LastRunAt.IsZero() || got.LastStatus != "" || got.LastReport != nil {
t.Errorf("missing state = %+v, want zero-value", got)
}
}
func TestLoadStateCorruptTolerated(t *testing.T) {
root := t.TempDir()
dir := filepath.Join(root, "global", "dream")
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "state.json"), []byte("{not valid json"), 0o644); err != nil {
t.Fatal(err)
}
got, err := LoadState(root)
if err != nil {
t.Fatalf("LoadState returned error on corrupt JSON, want tolerated: %v", err)
}
if !got.LastRunAt.IsZero() {
t.Errorf("corrupt state = %+v, want zero-value (never run)", got)
}
}
func TestDue(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cfg := Config{Enabled: true, IntervalDays: 7, RecentSessions: 20}
tests := []struct {
name string
cfg Config
last time.Time
want bool
}{
{"due: interval elapsed", cfg, now.Add(-8 * 24 * time.Hour), true},
{"due: exactly at interval", cfg, now.Add(-7 * 24 * time.Hour), true},
{"not due: within interval", cfg, now.Add(-3 * 24 * time.Hour), false},
{"zero LastRunAt never due", cfg, time.Time{}, false},
{"disabled never due", Config{Enabled: false, IntervalDays: 7}, now.Add(-30 * 24 * time.Hour), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := State{LastRunAt: tt.last}
if got := s.Due(tt.cfg, now); got != tt.want {
t.Errorf("Due = %v, want %v", got, tt.want)
}
})
}
}