diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e1a25c..88eca38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,9 @@ jobs: if: runner.os == 'Linux' run: sudo apt install libx11-dev + - name: Test + run: go test -v ./... + - name: Build run: go build -trimpath -ldflags=-s . diff --git a/go.mod b/go.mod index b79f4b0..0ab678d 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/diamondburned/ningen/v3 v3.0.1-0.20250920191746-98fbd92e134d github.com/gdamore/tcell/v3 v3.0.6 github.com/gen2brain/beeep v0.11.2 + github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/klauspost/compress v1.18.2 diff --git a/go.sum b/go.sum index 41ca6fc..e5ca139 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= diff --git a/internal/config/config.go b/internal/config/config.go index 008acc7..d801e9a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -97,14 +97,16 @@ func Load(path string) (*Config, error) { } } - // set defaults + applyDefaults(&cfg) + return &cfg, nil +} + +func applyDefaults(cfg *Config) { if cfg.Editor == "default" { cfg.Editor = os.Getenv("EDITOR") } if cfg.Status == "default" { - cfg.Status = "" + cfg.Status = discord.UnknownStatus } - - return &cfg, nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..908ca8f --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,91 @@ +package config + +import ( + "os" + "path/filepath" + "testing" + + "github.com/BurntSushi/toml" + "github.com/ayn2op/discordo/internal/consts" + "github.com/gdamore/tcell/v3" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +func TestDefaultPath(t *testing.T) { + t.Run("user config dir fallback", func(t *testing.T) { + t.Setenv("AppData", "") + t.Setenv("HOME", "") + t.Setenv("home", "") + t.Setenv("XDG_CONFIG_HOME", "") + + // filepath.Join strips the leading dot. + got := DefaultPath() + want := filepath.Join(".", consts.Name, fileName) + if got != want { + t.Fatalf("got = %v, want = %v", got, want) + } + }) +} + +func TestLoad(t *testing.T) { + t.Run("invalid default config returns error", func(t *testing.T) { + orig := defaultCfg + defaultCfg = []byte("invalid =") + t.Cleanup(func() { defaultCfg = orig }) + if _, err := Load("does-not-matter.toml"); err == nil { + t.Fatal(err) + } + }) + + t.Run("invalid config returns error", func(t *testing.T) { + path := filepath.Join(t.TempDir(), "bad.toml") + if err := os.WriteFile(path, []byte("invalid ="), os.ModePerm); err != nil { + t.Fatal(err) + } + + if _, err := Load(path); err == nil { + t.Fatal("expected error") + } + }) + + t.Run("valid config does not return error", func(t *testing.T) { + path := filepath.Join(t.TempDir(), "good.toml") + if err := os.WriteFile(path, []byte("mouse = false"), os.ModePerm); err != nil { + t.Fatal(err) + } + + cfg, err := Load(path) + if err != nil { + t.Fatal(err) + } + + if cfg.Mouse != false { + t.Fatalf("got = %v, want = false", cfg.Mouse) + } + }) + + t.Run("open with bad path returns error (!= ErrNotExist)", func(t *testing.T) { + if _, err := Load("bad\x00path"); err == nil { + t.Fatal("expected error") + } + }) + + t.Run("missing file uses defaults", func(t *testing.T) { + path := filepath.Join(t.TempDir(), "missing.toml") + cfg, err := Load(path) + if err != nil { + t.Fatal(err) + } + + var defCfg Config + if err := toml.Unmarshal(defaultCfg, &defCfg); err != nil { + t.Fatal(err) + } + applyDefaults(&defCfg) + + if diff := cmp.Diff(defCfg, *cfg, cmpopts.EquateComparable(tcell.Style{})); diff != "" { + t.Fatalf("got = -, want = +, diff=%s", diff) + } + }) +}