Files
gonic/jukebox/jukebox_test.go
2024-02-27 00:39:44 +00:00

221 lines
5.3 KiB
Go

package jukebox_test
import (
"context"
"errors"
"os"
"path/filepath"
"sort"
"testing"
"github.com/stretchr/testify/require"
"go.senan.xyz/gonic/jukebox"
)
func TestPlaySkipReset(t *testing.T) {
t.Skip("bit flakey since mpv ipc doesn't block while internal state has settled")
t.Parallel()
j := newJukebox(t)
require.NoError(t, j.SetPlaylist([]string{
testPath("tr_0.mp3"),
testPath("tr_1.mp3"),
testPath("tr_2.mp3"),
testPath("tr_3.mp3"),
testPath("tr_4.mp3"),
}))
status, err := j.GetStatus()
require.NoError(t, err)
require.Equal(t, 0, status.CurrentIndex)
require.Equal(t, testPath("tr_0.mp3"), status.CurrentFilename)
require.Equal(t, 5, status.Length)
require.Equal(t, true, status.Playing)
items, err := j.GetPlaylist()
require.NoError(t, err)
itemsSorted := append([]string(nil), items...)
sort.Strings(itemsSorted)
require.Equal(t, itemsSorted, items)
require.NoError(t, j.Play())
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, true, status.Playing)
require.NoError(t, j.Pause())
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, false, status.Playing)
require.NoError(t, j.Play())
// skip to 2
require.NoError(t, j.SkipToPlaylistIndex(2, 0))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 2, status.CurrentIndex)
require.Equal(t, testPath("tr_2.mp3"), status.CurrentFilename)
require.Equal(t, 5, status.Length)
require.Equal(t, true, status.Playing)
// skip to 3
require.NoError(t, j.SkipToPlaylistIndex(3, 0))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 3, status.CurrentIndex)
require.Equal(t, testPath("tr_3.mp3"), status.CurrentFilename)
require.Equal(t, 5, status.Length)
require.Equal(t, true, status.Playing)
// just add one more by overwriting the playlist like some clients do
// we should move keep the playing indedx
require.NoError(t, j.SetPlaylist([]string{
"testdata/tr_0.mp3",
"testdata/tr_1.mp3",
"testdata/tr_2.mp3",
"testdata/tr_3.mp3",
"testdata/tr_4.mp3",
"testdata/tr_5.mp3",
}))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 3, status.CurrentIndex) // index moved to start
require.Equal(t, testPath("tr_3.mp3"), status.CurrentFilename)
require.Equal(t, 6, status.Length) // we added one more track
require.Equal(t, true, status.Playing)
// new playlist with out current track (tr_2)
require.NoError(t, j.SetPlaylist([]string{
"testdata/tr_6.mp3",
"testdata/tr_7.mp3",
"testdata/tr_8.mp3",
"testdata/tr_9.mp3",
}))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 0, status.CurrentIndex) // index unchanged
require.Equal(t, testPath("tr_6.mp3"), status.CurrentFilename)
require.Equal(t, 4, status.Length)
require.Equal(t, true, status.Playing)
// skip to index 2 (5s long) in the middle of the track
require.NoError(t, j.SkipToPlaylistIndex(2, 2))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 2, status.CurrentIndex) // index unchanged
require.Equal(t, testPath("tr_8.mp3"), status.CurrentFilename)
require.Equal(t, 4, status.Length)
require.Equal(t, true, status.Playing)
require.Equal(t, 2, status.Position) // at new position
}
func TestShuffle(t *testing.T) {
t.Skip("bit flakey since mpv ipc doesn't block while internal state has settled")
t.Parallel()
j := newJukebox(t)
require.NoError(t, j.SetPlaylist([]string{
testPath("tr_0.mp3"),
testPath("tr_1.mp3"),
testPath("tr_2.mp3"),
testPath("tr_3.mp3"),
testPath("tr_4.mp3"),
testPath("tr_5.mp3"),
testPath("tr_6.mp3"),
testPath("tr_7.mp3"),
}))
require.NoError(t, j.SkipToPlaylistIndex(2, 0))
status, err := j.GetStatus()
require.NoError(t, err)
require.Equal(t, 2, status.CurrentIndex)
require.True(t, status.Playing)
desiredOrder := []string{
testPath("tr_2.mp3"), // the was-playing index moves to position 0
testPath("tr_1.mp3"),
testPath("tr_0.mp3"),
testPath("tr_3.mp3"),
testPath("tr_5.mp3"),
testPath("tr_6.mp3"),
testPath("tr_7.mp3"),
testPath("tr_4.mp3"),
}
require.NoError(t, j.SetPlaylist(desiredOrder))
status, err = j.GetStatus()
require.NoError(t, err)
require.Equal(t, 0, status.CurrentIndex)
require.Equal(t, len(desiredOrder), status.Length)
playlist, err := j.GetPlaylist()
require.NoError(t, err)
require.Equal(t, desiredOrder, playlist)
}
func TestVolume(t *testing.T) {
t.Skip("bit flakey since mpv ipc doesn't block while internal state has settled")
t.Parallel()
j := newJukebox(t)
vol, err := j.GetVolumePct()
require.NoError(t, err)
require.Equal(t, 100.0, vol)
require.NoError(t, j.SetVolumePct(69.0))
vol, err = j.GetVolumePct()
require.NoError(t, err)
require.Equal(t, 69.0, vol)
require.NoError(t, j.SetVolumePct(0.0))
vol, err = j.GetVolumePct()
require.NoError(t, err)
require.Equal(t, 0.0, vol)
}
func newJukebox(tb testing.TB) *jukebox.Jukebox {
tb.Helper()
sockPath := filepath.Join(tb.TempDir(), "mpv.sock")
ctx, cancel := context.WithCancel(context.Background())
j := jukebox.New()
err := j.Start(
ctx,
sockPath,
[]string{jukebox.MPVArg("--ao", "null")},
)
if errors.Is(err, jukebox.ErrMPVTooOld) {
tb.Skip("old mpv found, skipping")
}
if err != nil {
tb.Fatalf("start jukebox: %v", err)
}
tb.Cleanup(func() {
cancel()
})
return j
}
func testPath(path string) string {
cwd, _ := os.Getwd()
return filepath.Join(cwd, "testdata", path)
}