clone

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

refactor/root-tui-model
puzzletea / games / takuzuplus / elo_test.go
elo_test.go 3.1K
1package takuzuplus23import (4 "context"5 "reflect"6 "testing"78 "github.com/FelineStateMachine/puzzletea/difficulty"9)1011func TestSpawnEloRejectsInvalidElo(t *testing.T) {12 mode := NewMode("Elo", "test", 8, 0.4, modeProfiles[1])13 tests := []difficulty.Elo{14 difficulty.MinElo - 1,15 difficulty.SoftCapElo + 1,16 }1718 for _, elo := range tests {19 gamer, report, err := mode.SpawnElo("seed", elo)20 if err == nil {21 t.Fatalf("SpawnElo(%d) error = nil, want invalid Elo error", elo)22 }23 if gamer != nil {24 t.Fatalf("SpawnElo(%d) gamer = %#v, want nil", elo, gamer)25 }26 if !reflect.DeepEqual(report, difficulty.Report{}) {27 t.Fatalf("SpawnElo(%d) report = %#v, want zero report", elo, report)28 }29 }30}3132func TestSpawnEloContextCanceled(t *testing.T) {33 mode := NewMode("Elo", "test", 8, 0.4, modeProfiles[1])34 ctx, cancel := context.WithCancel(context.Background())35 cancel()3637 gamer, report, err := mode.SpawnEloContext(ctx, "seed", 1200)38 if err == nil {39 t.Fatal("SpawnEloContext returned nil error for canceled context")40 }41 if gamer != nil {42 t.Fatalf("gamer = %#v, want nil", gamer)43 }44 if !reflect.DeepEqual(report, difficulty.Report{}) {45 t.Fatalf("report = %#v, want zero report", report)46 }47}4849func TestSpawnEloDeterministicForSameSeedAndElo(t *testing.T) {50 mode := NewMode("Elo", "test", 8, 0.4, modeProfiles[1])51 const elo = difficulty.Elo(900)52 const seed = "same-seed"5354 gamerA, reportA, err := mode.SpawnElo(seed, elo)55 if err != nil {56 t.Fatalf("first SpawnElo returned error: %v", err)57 }58 gamerB, reportB, err := mode.SpawnElo(seed, elo)59 if err != nil {60 t.Fatalf("second SpawnElo returned error: %v", err)61 }6263 saveA, err := gamerA.GetSave()64 if err != nil {65 t.Fatalf("first GetSave returned error: %v", err)66 }67 saveB, err := gamerB.GetSave()68 if err != nil {69 t.Fatalf("second GetSave returned error: %v", err)70 }71 if string(saveA) != string(saveB) {72 t.Fatalf("SpawnElo saves differ for same seed and Elo:\n%s\n%s", saveA, saveB)73 }74 if !reflect.DeepEqual(reportA, reportB) {75 t.Fatalf("reports differ for same seed and Elo:\n%#v\n%#v", reportA, reportB)76 }77}7879func TestSpawnEloPopulatesDifficultyReport(t *testing.T) {80 mode := NewMode("Elo", "test", 8, 0.4, modeProfiles[1])81 const target = difficulty.Elo(1200)8283 gamer, report, err := mode.SpawnElo("report-fields", target)84 if err != nil {85 t.Fatalf("SpawnElo returned error: %v", err)86 }87 if gamer == nil {88 t.Fatal("SpawnElo returned nil gamer")89 }90 if report.TargetElo != target {91 t.Fatalf("TargetElo = %d, want %d", report.TargetElo, target)92 }93 if err := difficulty.ValidateElo(report.ActualElo); err != nil {94 t.Fatalf("ActualElo = %d is invalid: %v", report.ActualElo, err)95 }96 if report.Confidence == "" {97 t.Fatal("Confidence is empty")98 }99100 for _, key := range []string{101 "size",102 "clue_density",103 "solution_count",104 "solver_nodes",105 "max_depth",106 "relation_count",107 "same_relations",108 "diff_relations",109 "occupied_regions",110 } {111 if _, ok := report.Metrics[key]; !ok {112 t.Fatalf("Metrics missing %q: %#v", key, report.Metrics)113 }114 }115 if report.Metrics["relation_count"] == 0 {116 t.Fatalf("relation_count = 0, want relation clues in report: %#v", report.Metrics)117 }118}