clone

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

feat/app-decomposition
puzzletea / config / config_test.go
config_test.go 2.8K
1package config23import (4 "os"5 "path/filepath"6 "testing"78 "github.com/FelineStateMachine/puzzletea/puzzle"9)1011// --- Load / Save round-trip (P0) ---1213func TestLoadMissingFile(t *testing.T) {14 cfg, err := Load("/tmp/puzzletea-test-nonexistent/config.json")15 if err != nil {16 t.Fatalf("expected no error for missing file, got: %v", err)17 }18 if cfg.Theme != "" {19 t.Errorf("expected empty theme for default config, got %q", cfg.Theme)20 }21}2223func TestSaveAndLoad(t *testing.T) {24 dir := t.TempDir()25 path := filepath.Join(dir, "config.json")2627 cfg := &Config{Theme: "Dracula"}28 if err := cfg.Save(path); err != nil {29 t.Fatalf("Save failed: %v", err)30 }3132 loaded, err := Load(path)33 if err != nil {34 t.Fatalf("Load failed: %v", err)35 }36 if loaded.Theme != "Dracula" {37 t.Errorf("expected theme Dracula, got %q", loaded.Theme)38 }39}4041func TestSaveAndLoadExportConfig(t *testing.T) {42 dir := t.TempDir()43 path := filepath.Join(dir, "config.json")4445 cfg := &Config{46 Theme: "Dracula",47 Export: ExportConfig{48 Title: "Sampler",49 Volume: 2,50 SheetLayout: "duplex-booklet",51 PDFOutputPath: filepath.Join(dir, "sample.pdf"),52 JSONLEnabled: true,53 JSONLOutputPath: filepath.Join(dir, "sample.jsonl"),54 Counts: map[puzzle.GameID]map[puzzle.ModeID]int{55 puzzle.CanonicalGameID("Sudoku"): {56 puzzle.CanonicalModeID("Easy"): 2,57 },58 },59 },60 }61 if err := cfg.Save(path); err != nil {62 t.Fatalf("Save failed: %v", err)63 }6465 loaded, err := Load(path)66 if err != nil {67 t.Fatalf("Load failed: %v", err)68 }69 if loaded.Export.Title != cfg.Export.Title {70 t.Fatalf("loaded export title = %q, want %q", loaded.Export.Title, cfg.Export.Title)71 }72 if !loaded.Export.JSONLEnabled {73 t.Fatal("expected jsonl toggle to round-trip")74 }75 if got := loaded.Export.Counts[puzzle.CanonicalGameID("Sudoku")][puzzle.CanonicalModeID("Easy")]; got != 2 {76 t.Fatalf("loaded export count = %d, want 2", got)77 }78}7980func TestSaveCreatesDirectory(t *testing.T) {81 dir := t.TempDir()82 path := filepath.Join(dir, "nested", "deep", "config.json")8384 cfg := &Config{Theme: "Monokai Pro"}85 if err := cfg.Save(path); err != nil {86 t.Fatalf("Save failed: %v", err)87 }8889 if _, err := os.Stat(path); err != nil {90 t.Fatalf("expected config file to exist: %v", err)91 }92}9394func TestLoadInvalidJSON(t *testing.T) {95 dir := t.TempDir()96 path := filepath.Join(dir, "config.json")97 if err := os.WriteFile(path, []byte("{invalid"), 0o644); err != nil {98 t.Fatal(err)99 }100101 cfg, err := Load(path)102 if err == nil {103 t.Fatal("expected error for invalid JSON")104 }105 // Should still return a usable default.106 if cfg.Theme != "" {107 t.Errorf("expected default theme on error, got %q", cfg.Theme)108 }109}110111func TestDefaultConfig(t *testing.T) {112 cfg := Default()113 if cfg.Theme != "" {114 t.Errorf("expected empty theme, got %q", cfg.Theme)115 }116}