Files
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

269 lines
5.9 KiB
Go

package playlist
import "testing"
func TestNextRepeatOff(t *testing.T) {
p := makePlaylist(3, false) // A B C
// Advance through all tracks
track, ok := p.Next()
if !ok || track.Title != "B" {
t.Fatalf("Next() = (%q, %v), want (B, true)", track.Title, ok)
}
track, ok = p.Next()
if !ok || track.Title != "C" {
t.Fatalf("Next() = (%q, %v), want (C, true)", track.Title, ok)
}
// Past the end with RepeatOff
_, ok = p.Next()
if ok {
t.Fatal("Next() past end should return false with RepeatOff")
}
}
func TestNextRepeatAll(t *testing.T) {
p := makePlaylist(3, false) // A B C
p.SetRepeat(RepeatAll)
// Advance to end
p.Next() // B
p.Next() // C
// Should wrap around
track, ok := p.Next()
if !ok || track.Title != "A" {
t.Fatalf("Next() wrap = (%q, %v), want (A, true)", track.Title, ok)
}
}
func TestNextRepeatOne(t *testing.T) {
p := makePlaylist(3, false) // A B C
p.SetRepeat(RepeatOne)
// Should repeat the same track
track, ok := p.Next()
if !ok || track.Title != "A" {
t.Fatalf("Next() RepeatOne = (%q, %v), want (A, true)", track.Title, ok)
}
track, ok = p.Next()
if !ok || track.Title != "A" {
t.Fatalf("Next() RepeatOne again = (%q, %v), want (A, true)", track.Title, ok)
}
}
func TestNextWithQueue(t *testing.T) {
p := makePlaylist(4, false) // A B C D
p.Queue(2) // Queue C
p.Queue(3) // Queue D
// Queue should be played first
track, ok := p.Next()
if !ok || track.Title != "C" {
t.Fatalf("Next() from queue = (%q, %v), want (C, true)", track.Title, ok)
}
track, ok = p.Next()
if !ok || track.Title != "D" {
t.Fatalf("Next() from queue = (%q, %v), want (D, true)", track.Title, ok)
}
// Queue exhausted, resume normal order
track, ok = p.Next()
if !ok || track.Title != "B" {
t.Fatalf("Next() after queue = (%q, %v), want (B, true)", track.Title, ok)
}
}
func TestNextRepeatOneResumesOrderAfterQueuedTrack(t *testing.T) {
p := makePlaylist(2, false) // A B
p.SetRepeat(RepeatOne)
p.Queue(1)
track, ok := p.Next()
if !ok || track.Title != "B" {
t.Fatalf("Next() from queue = (%q, %v), want (B, true)", track.Title, ok)
}
track, ok = p.Next()
if !ok || track.Title != "A" {
t.Fatalf("Next() after queued repeat-one = (%q, %v), want (A, true)", track.Title, ok)
}
if current, idx := p.Current(); current.Title != "A" || idx != 0 {
t.Fatalf("Current() = (%q, %d), want (A, 0)", current.Title, idx)
}
}
func TestPrevBasic(t *testing.T) {
p := makePlaylist(3, false)
p.SetIndex(2) // C
track, ok := p.Prev()
if !ok || track.Title != "B" {
t.Fatalf("Prev() = (%q, %v), want (B, true)", track.Title, ok)
}
track, ok = p.Prev()
if !ok || track.Title != "A" {
t.Fatalf("Prev() = (%q, %v), want (A, true)", track.Title, ok)
}
// At the beginning with RepeatOff
_, ok = p.Prev()
if ok {
t.Fatal("Prev() at beginning should return false with RepeatOff")
}
}
func TestPrevRepeatAll(t *testing.T) {
p := makePlaylist(3, false)
p.SetRepeat(RepeatAll)
// At position 0, should wrap to end
track, ok := p.Prev()
if !ok || track.Title != "C" {
t.Fatalf("Prev() wrap = (%q, %v), want (C, true)", track.Title, ok)
}
}
func TestPeekNextBasic(t *testing.T) {
p := makePlaylist(3, false)
track, ok := p.PeekNext()
if !ok || track.Title != "B" {
t.Fatalf("PeekNext() = (%q, %v), want (B, true)", track.Title, ok)
}
// PeekNext should NOT advance the position
cur, _ := p.Current()
if cur.Title != "A" {
t.Fatalf("Current after PeekNext = %q, want A", cur.Title)
}
}
func TestPeekNextAtEnd(t *testing.T) {
p := makePlaylist(3, false)
p.SetIndex(2) // C
// RepeatOff at end
_, ok := p.PeekNext()
if ok {
t.Fatal("PeekNext() at end with RepeatOff should return false")
}
}
func TestPeekNextRepeatAll(t *testing.T) {
p := makePlaylist(3, false)
p.SetRepeat(RepeatAll)
p.SetIndex(2) // C
track, ok := p.PeekNext()
if !ok || track.Title != "A" {
t.Fatalf("PeekNext() RepeatAll at end = (%q, %v), want (A, true)", track.Title, ok)
}
}
func TestPeekNextRepeatOne(t *testing.T) {
p := makePlaylist(3, false)
p.SetRepeat(RepeatOne)
p.SetIndex(1) // B
track, ok := p.PeekNext()
if !ok || track.Title != "B" {
t.Fatalf("PeekNext() RepeatOne = (%q, %v), want (B, true)", track.Title, ok)
}
}
func TestPeekNextWithQueue(t *testing.T) {
p := makePlaylist(3, false)
p.Queue(2) // Queue C
track, ok := p.PeekNext()
if !ok || track.Title != "C" {
t.Fatalf("PeekNext() with queue = (%q, %v), want (C, true)", track.Title, ok)
}
}
func TestPeekNextRepeatOneUsesOrderAfterQueuedTrack(t *testing.T) {
p := makePlaylist(2, false) // A B
p.SetRepeat(RepeatOne)
p.Queue(1)
if track, ok := p.Next(); !ok || track.Title != "B" {
t.Fatalf("Next() from queue = (%q, %v), want (B, true)", track.Title, ok)
}
track, ok := p.PeekNext()
if !ok || track.Title != "A" {
t.Fatalf("PeekNext() after queued repeat-one = (%q, %v), want (A, true)", track.Title, ok)
}
}
func TestCurrentEmpty(t *testing.T) {
p := New()
_, idx := p.Current()
if idx != -1 {
t.Fatalf("Current() on empty = %d, want -1", idx)
}
}
func TestIndexEmpty(t *testing.T) {
p := New()
if idx := p.Index(); idx != -1 {
t.Fatalf("Index() on empty = %d, want -1", idx)
}
}
func TestNextEmpty(t *testing.T) {
p := New()
_, ok := p.Next()
if ok {
t.Fatal("Next() on empty should return false")
}
}
func TestPrevEmpty(t *testing.T) {
p := New()
_, ok := p.Prev()
if ok {
t.Fatal("Prev() on empty should return false")
}
}
func TestSetIndex(t *testing.T) {
p := makePlaylist(5, false)
p.SetIndex(3) // D
cur, idx := p.Current()
if idx != 3 || cur.Title != "D" {
t.Fatalf("Current() = (%q, %d), want (D, 3)", cur.Title, idx)
}
}
func TestReplace(t *testing.T) {
p := makePlaylist(3, false)
p.SetIndex(2)
// Replace with new tracks
newTracks := []Track{
{Title: "X"},
{Title: "Y"},
}
p.Replace(newTracks)
if p.Len() != 2 {
t.Fatalf("Len() = %d, want 2", p.Len())
}
cur, idx := p.Current()
if idx != 0 || cur.Title != "X" {
t.Fatalf("Current() = (%q, %d), want (X, 0)", cur.Title, idx)
}
}