diff --git a/go.mod b/go.mod index 7bce8b2..90abf2a 100644 --- a/go.mod +++ b/go.mod @@ -12,12 +12,14 @@ require ( ) require ( - github.com/spezifisch/tview-command v0.0.0-20241013135507-37aefd938546 + github.com/spezifisch/tview-command v0.0.0-20241013143719-94366d6323e2 + github.com/stretchr/testify v1.9.0 github.com/supersonic-app/go-mpv v0.1.0 ) require ( github.com/BurntSushi/toml v1.4.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gdamore/encoding v1.0.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -26,6 +28,7 @@ require ( github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index bafb967..7fbbea9 100644 --- a/go.sum +++ b/go.sum @@ -51,10 +51,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spezifisch/tview-command v0.0.0-20241013011314-5b01dcbdc948 h1:0e9YqpET7Zks2lk6IigZIE+fYcjz4cCT6jThcmC84No= -github.com/spezifisch/tview-command v0.0.0-20241013011314-5b01dcbdc948/go.mod h1:BmHPVRuS00KaY6eP3VAoPJVlfN0Fulajx3Dw9CwKfFw= -github.com/spezifisch/tview-command v0.0.0-20241013135507-37aefd938546 h1:2EpfyiBkDaPoU+klGhnrjT7v07OxeIqAfNpZkj80E00= -github.com/spezifisch/tview-command v0.0.0-20241013135507-37aefd938546/go.mod h1:BmHPVRuS00KaY6eP3VAoPJVlfN0Fulajx3Dw9CwKfFw= +github.com/spezifisch/tview-command v0.0.0-20241013143719-94366d6323e2 h1:rhNWDM0v9HbwuF5I8wvOW3bsCdiZ1KRnp7uvhp3Jw+Y= +github.com/spezifisch/tview-command v0.0.0-20241013143719-94366d6323e2/go.mod h1:BmHPVRuS00KaY6eP3VAoPJVlfN0Fulajx3Dw9CwKfFw= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= diff --git a/stmps.go b/stmps.go index 05d6c68..e1399fd 100644 --- a/stmps.go +++ b/stmps.go @@ -20,6 +20,9 @@ import ( "github.com/spf13/viper" ) +var osExit = os.Exit // A variable to allow mocking os.Exit in tests +var headlessMode bool // This can be set to true during tests + func readConfig() { required_properties := []string{"auth.username", "auth.password", "server.host"} @@ -31,7 +34,7 @@ func readConfig() { if err != nil { fmt.Printf("Config file error: %s \n", err) - os.Exit(1) + osExit(1) } for _, prop := range required_properties { @@ -57,10 +60,9 @@ func parseConfig() { u.User = nil viper.Set("server.host", u.String()) } else { - fmt.Printf("Invalid server format; must be a valid URL: http[s]://[user:pass@]server:port") - fmt.Printf("USAGE: %s [http[s]://[user:pass@]server:port]\n", os.Args[0]) - flag.Usage() - os.Exit(1) + fmt.Printf("Invalid server format; must be a valid URL!") + fmt.Printf("Usage: %s [http[s]://[user:pass@]server:port]\n", os.Args[0]) + osExit(1) } } @@ -93,7 +95,7 @@ func main() { if *help { fmt.Printf("USAGE: %s [[user:pass@]server:port]\n", os.Args[0]) flag.Usage() - os.Exit(0) + osExit(0) } // cpu/memprofile code straight from https://pkg.go.dev/runtime/pprof @@ -130,7 +132,7 @@ func main() { indexResponse, err := connection.GetIndexes() if err != nil { fmt.Printf("Error fetching playlists from server: %s\n", err) - os.Exit(1) + osExit(1) } if *list { @@ -151,7 +153,7 @@ func main() { playlistResponse, err := connection.GetPlaylists() if err != nil { fmt.Printf("Error fetching indexes from server: %s\n", err) - os.Exit(1) + osExit(1) } fmt.Printf(" Directory: %s\n", playlistResponse.Directory.Name) fmt.Printf(" Status: %s\n", playlistResponse.Status) @@ -166,14 +168,14 @@ func main() { fmt.Printf(" %s\n", pl.Name) } - os.Exit(0) + osExit(0) } // init mpv engine player, err := mpvplayer.NewPlayer(logger) if err != nil { fmt.Println("Unable to initialize mpv. Is mpv installed?") - os.Exit(1) + osExit(1) } var mprisPlayer *remote.MprisPlayer @@ -183,7 +185,7 @@ func main() { if err != nil { fmt.Printf("Unable to register MPRIS with DBUS: %s\n", err) fmt.Println("Try running without MPRIS") - os.Exit(1) + osExit(1) } defer mprisPlayer.Close() } @@ -192,12 +194,17 @@ func main() { if runtime.GOOS == "darwin" { if err = remote.RegisterMPMediaHandler(player, logger); err != nil { fmt.Printf("Unable to initialize MediaPlayer bindings: %s\n", err) - os.Exit(1) + osExit(1) } else { logger.Print("MacOS MediaPlayer registered") } } + if headlessMode { + fmt.Println("Running in headless mode for testing.") + return + } + ui := InitGui(&indexResponse.Indexes.Index, connection, player, diff --git a/stmps_test.go b/stmps_test.go new file mode 100644 index 0000000..a7fa512 --- /dev/null +++ b/stmps_test.go @@ -0,0 +1,46 @@ +package main + +import ( + "os" + "testing" + + "github.com/spezifisch/stmps/logger" + "github.com/spezifisch/stmps/mpvplayer" + "github.com/stretchr/testify/assert" +) + +// Test initialization of the player +func TestPlayerInitialization(t *testing.T) { + logger := logger.Init() + player, err := mpvplayer.NewPlayer(logger) + assert.NoError(t, err, "Player initialization should not return an error") + assert.NotNil(t, player, "Player should be initialized") +} + +func TestMainWithoutTUI(t *testing.T) { + // Mock osExit to prevent actual exit during test + exitCalled := false + osExit = func(code int) { + exitCalled = true + if code != 0 { + t.Fatalf("Unexpected exit with code: %d", code) + } + // Since we don't abort execution here, we will run main() until the end or a panic. + } + headlessMode = true + + // Restore osExit after the test + defer func() { + osExit = os.Exit + headlessMode = false + }() + + // Set command-line arguments to trigger the help flag + os.Args = []string{"cmd", "--help"} + + main() + + if !exitCalled { + t.Fatalf("osExit was not called") + } +}