package main // preferences_test.go — M8-4 Preferences 持久化單元測試 import ( "encoding/json" "os" "path/filepath" "runtime" "testing" ) func TestDefaultPreferences_PlatformSpecific(t *testing.T) { p := DefaultPreferences() wantOpen := runtime.GOOS != "linux" if p.AutoOpenBrowser != wantOpen { t.Fatalf("DefaultPreferences.AutoOpenBrowser=%v on %s, want %v", p.AutoOpenBrowser, runtime.GOOS, wantOpen) } if p.Locale != "" { t.Fatalf("default Locale=%q, want empty", p.Locale) } if p.LogRingSize != 0 { t.Fatalf("default LogRingSize=%d, want 0", p.LogRingSize) } } func TestLoadPreferences_MissingFile(t *testing.T) { dir := t.TempDir() p := LoadPreferences(dir) want := DefaultPreferences() if p != want { t.Fatalf("LoadPreferences on empty dir=%+v, want default %+v", p, want) } } func TestLoadPreferences_CorruptJSON(t *testing.T) { dir := t.TempDir() path := preferencesPath(dir) if err := os.WriteFile(path, []byte("{not json"), 0o644); err != nil { t.Fatalf("prep: %v", err) } p := LoadPreferences(dir) want := DefaultPreferences() if p != want { t.Fatalf("LoadPreferences on corrupt json=%+v, want default %+v", p, want) } } func TestSaveAndLoadPreferences_Roundtrip(t *testing.T) { dir := t.TempDir() orig := Preferences{ AutoOpenBrowser: false, Locale: "zh-TW", LogRingSize: 1000, } if err := SavePreferences(dir, orig); err != nil { t.Fatalf("Save: %v", err) } // 確認 .tmp 不存在(rename 已完成) if _, err := os.Stat(preferencesPath(dir) + ".tmp"); !os.IsNotExist(err) { t.Fatalf("tmp file should not exist after rename, got err=%v", err) } // 檢查檔案內容是合法 JSON raw, err := os.ReadFile(preferencesPath(dir)) if err != nil { t.Fatalf("read file: %v", err) } var check Preferences if err := json.Unmarshal(raw, &check); err != nil { t.Fatalf("unmarshal: %v", err) } if check != orig { t.Fatalf("on-disk=%+v, want %+v", check, orig) } // Load 回來應該一致 loaded := LoadPreferences(dir) if loaded != orig { t.Fatalf("loaded=%+v, want %+v", loaded, orig) } } func TestSavePreferences_AtomicRename(t *testing.T) { dir := t.TempDir() // 預先寫一個舊 preferences.json oldData := `{"autoOpenBrowser":true,"locale":"en-US"}` if err := os.WriteFile(preferencesPath(dir), []byte(oldData), 0o644); err != nil { t.Fatalf("prep: %v", err) } // 寫新的 newPref := Preferences{AutoOpenBrowser: false, Locale: "zh-TW"} if err := SavePreferences(dir, newPref); err != nil { t.Fatalf("Save: %v", err) } loaded := LoadPreferences(dir) if loaded != newPref { t.Fatalf("loaded=%+v, want %+v", loaded, newPref) } // tmp cleanup 後 data dir 只該有 preferences.json entries, _ := os.ReadDir(dir) for _, e := range entries { if filepath.Ext(e.Name()) == ".tmp" { t.Fatalf("leftover tmp file: %s", e.Name()) } } }