clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

bug/architecture-test-trim-path
puzzletea / daily / daily_test.go
daily_test.go 3.6K
1package daily23import (4 "strings"5 "testing"6 "time"7)89// --- Seed (P0) ---1011func TestSeed(t *testing.T) {12 tests := []struct {13 name string14 dateA time.Time15 dateB time.Time16 wantSame bool17 }{18 {19 name: "same date same seed",20 dateA: time.Date(2026, 2, 14, 10, 30, 0, 0, time.UTC),21 dateB: time.Date(2026, 2, 14, 23, 59, 0, 0, time.UTC),22 wantSame: true,23 },24 {25 name: "different dates different seeds",26 dateA: time.Date(2026, 2, 14, 0, 0, 0, 0, time.UTC),27 dateB: time.Date(2026, 2, 15, 0, 0, 0, 0, time.UTC),28 wantSame: false,29 },30 }3132 for _, tt := range tests {33 t.Run(tt.name, func(t *testing.T) {34 seedA := Seed(tt.dateA)35 seedB := Seed(tt.dateB)36 if (seedA == seedB) != tt.wantSame {37 t.Errorf("Seed(%v)=%d, Seed(%v)=%d, wantSame=%v",38 tt.dateA, seedA, tt.dateB, seedB, tt.wantSame)39 }40 })41 }42}4344func TestSeedDeterministic(t *testing.T) {45 date := time.Date(2026, 6, 15, 12, 0, 0, 0, time.UTC)46 s1 := Seed(date)47 s2 := Seed(date)48 if s1 != s2 {49 t.Errorf("Seed is not deterministic: %d != %d", s1, s2)50 }51}5253// --- RNG (P0) ---5455func TestRNG(t *testing.T) {56 date := time.Date(2026, 3, 1, 0, 0, 0, 0, time.UTC)57 rng1 := RNG(date)58 rng2 := RNG(date)5960 // Same date should produce the same sequence of random numbers.61 for i := range 10 {62 a := rng1.Int64()63 b := rng2.Int64()64 if a != b {65 t.Fatalf("RNG diverged at draw %d: %d != %d", i, a, b)66 }67 }68}6970func TestRNGDifferentDates(t *testing.T) {71 rng1 := RNG(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC))72 rng2 := RNG(time.Date(2026, 1, 2, 0, 0, 0, 0, time.UTC))7374 // Different dates should produce different sequences.75 same := true76 for range 5 {77 if rng1.Int64() != rng2.Int64() {78 same = false79 break80 }81 }82 if same {83 t.Error("RNG produced identical sequences for different dates")84 }85}8687// --- Name (P0) ---8889func TestName(t *testing.T) {90 date := time.Date(2026, 2, 14, 0, 0, 0, 0, time.UTC)91 name := Name(date)9293 if !strings.HasPrefix(name, "Daily Feb 14 26 - ") {94 t.Errorf("Name = %q, want prefix %q", name, "Daily Feb 14 26 - ")95 }96}9798func TestNameDeterministic(t *testing.T) {99 date := time.Date(2026, 7, 4, 0, 0, 0, 0, time.UTC)100 name1 := Name(date)101 name2 := Name(date)102 if name1 != name2 {103 t.Errorf("Name not deterministic: %q != %q", name1, name2)104 }105}106107// --- Mode (P1) ---108109func TestMode(t *testing.T) {110 date := time.Date(2026, 3, 15, 0, 0, 0, 0, time.UTC)111 spawner, gameType, mode := Mode(date)112113 if spawner == nil {114 t.Fatal("Mode returned nil spawner")115 }116 if gameType == "" {117 t.Error("Mode returned empty gameType")118 }119 if mode == "" {120 t.Error("Mode returned empty mode title")121 }122}123124func TestModeDeterministic(t *testing.T) {125 date := time.Date(2026, 5, 20, 0, 0, 0, 0, time.UTC)126127 _, gt1, m1 := Mode(date)128 _, gt2, m2 := Mode(date)129130 if gt1 != gt2 || m1 != m2 {131 t.Errorf("Mode not deterministic: (%q,%q) vs (%q,%q)", gt1, m1, gt2, m2)132 }133}134135// --- EligibleModes pool (P1) ---136137func TestEligibleModesNotEmpty(t *testing.T) {138 if len(eligibleModes) == 0 {139 t.Fatal("eligibleModes is empty; no daily modes registered")140 }141}142143func TestEligibleModesHaveMetadata(t *testing.T) {144 for i, e := range eligibleModes {145 if e.Spawner == nil {146 t.Errorf("eligibleModes[%d].Spawner is nil", i)147 }148 if e.GameType == "" {149 t.Errorf("eligibleModes[%d].GameType is empty", i)150 }151 if e.Mode == "" {152 t.Errorf("eligibleModes[%d].Mode is empty", i)153 }154 }155}156157func TestEligibleModesIncludeSudokuRGBVariant(t *testing.T) {158 found := map[string]bool{}159 for _, entry := range eligibleModes {160 if entry.GameType == "Sudoku RGB" {161 found[entry.Mode] = true162 }163 }164165 if !found["Sudoku RGB"] {166 t.Fatalf("eligibleModes missing Sudoku RGB variant")167 }168}