401 lines
15 KiB
Python
401 lines
15 KiB
Python
# Copyright 2019 (c) Anna Schumaker.
|
|
from . import playlist
|
|
from .. import notify
|
|
from .. import trak
|
|
from .. import tree
|
|
import os
|
|
import random
|
|
import unittest
|
|
|
|
test_library = os.path.abspath("./trier/Test Library")
|
|
test_album = os.path.join(test_library, "Test Artist 01", "Test Album 1")
|
|
|
|
class TestPlaylist(unittest.TestCase):
|
|
def setUp(self):
|
|
trak.reset()
|
|
notify.register("add-track", self.on_add_remove)
|
|
notify.register("remove-track", self.on_add_remove)
|
|
notify.register("playlist-changed", self.on_plist_changed)
|
|
self.cb_plist = None
|
|
self.cb_index = None
|
|
self.cb_changed = None
|
|
self.plist = playlist.Playlist("Test Playlist", sort=[])
|
|
|
|
def tearDown(self):
|
|
notify.cancel("add-track", self.on_add_remove)
|
|
notify.cancel("remove-track", self.on_add_remove)
|
|
notify.cancel("playlist-changed", self.on_plist_changed)
|
|
|
|
def add_tracks(self, tracknos):
|
|
tracks = [ ]
|
|
for t in tracknos:
|
|
path = os.path.join(test_album, f"{t:02} - Test Track {t:02}.ogg")
|
|
tracks.append(trak.lookup(path))
|
|
self.plist.add(tracks[-1])
|
|
return tracks
|
|
|
|
def on_add_remove(self, plist, track, index):
|
|
self.cb_plist = plist
|
|
self.cb_track = track
|
|
self.cb_index = index
|
|
|
|
def on_plist_changed(self, plist):
|
|
self.cb_changed = plist
|
|
|
|
def test_playlist__init__(self):
|
|
self.assertIsInstance(self.plist, tree.ETree)
|
|
self.assertEqual(self.plist.name, "Test Playlist")
|
|
self.assertEqual(self.plist.icon, "")
|
|
self.assertEqual(self.plist.list, [ ])
|
|
self.assertEqual(self.plist.sort_order, [ ])
|
|
self.assertEqual(self.plist.current, -1)
|
|
self.assertTrue( self.plist.can_loop)
|
|
self.assertFalse(self.plist.loop)
|
|
self.assertTrue( self.plist.can_random)
|
|
self.assertFalse(self.plist.random)
|
|
self.assertFalse(self.plist.visible)
|
|
self.assertFalse(self.plist.plist_lock.locked())
|
|
|
|
def test_playlist__getitem__(self):
|
|
self.assertIsNone(self.plist[0])
|
|
tracks = self.add_tracks([1, 2])
|
|
self.assertEqual(self.plist[0], tracks[0])
|
|
self.assertEqual(self.plist[1], tracks[1])
|
|
|
|
def test_playlist__getstate__(self):
|
|
tracks = self.add_tracks([1, 2])
|
|
state = self.plist.__getstate__()
|
|
self.assertEqual(state["name"], "Test Playlist")
|
|
self.assertEqual(state["icon"], "")
|
|
self.assertEqual(state["list"], [ tracks[0].path, tracks[1].path ])
|
|
self.assertNotIn("plist_lock", state)
|
|
|
|
def test_playlist__len__(self):
|
|
self.assertEqual(len(self.plist), 0)
|
|
self.add_tracks([1, 2])
|
|
self.assertEqual(len(self.plist), 2)
|
|
|
|
def test_playlist__setstate__(self):
|
|
tracks = self.add_tracks([1, 2])
|
|
state = { "name" : "Test", "icon" : "test", "children" : [ ],
|
|
"sibling" : None, "parent" : None,
|
|
"list" : [ tracks[0].path, tracks[1].path ],
|
|
"sort_order" : [ 1 ], "current" : 2, "can_loop" : False,
|
|
"loop" : True, "can_random" : False, "random" : True,
|
|
"visible" : True }
|
|
self.plist.reset()
|
|
self.plist.plist_lock = None
|
|
|
|
self.plist.__setstate__(state)
|
|
self.assertEqual(self.plist.name, "Test")
|
|
self.assertEqual(self.plist.icon, "test")
|
|
self.assertEqual(self.plist.list, tracks)
|
|
self.assertEqual(self.plist.sort_order, [ 1 ])
|
|
self.assertEqual(self.plist.current, 2)
|
|
self.assertFalse(self.plist.can_loop)
|
|
self.assertTrue( self.plist.loop)
|
|
self.assertFalse(self.plist.can_random)
|
|
self.assertTrue( self.plist.random)
|
|
self.assertFalse(self.plist.visible)
|
|
self.assertFalse(self.plist.plist_lock.locked())
|
|
|
|
def test_playlist_add_append(self):
|
|
tracks = self.add_tracks(range(1, 6))
|
|
|
|
self.assertEqual(len(self.plist), 5)
|
|
self.assertEqual(self.cb_changed, self.plist)
|
|
self.assertIsNone(self.cb_plist)
|
|
self.assertIsNone(self.cb_index)
|
|
for i, track in enumerate(tracks):
|
|
self.assertEqual(self.plist[i], track)
|
|
|
|
self.plist.visible = True
|
|
self.add_tracks([6])
|
|
self.assertEqual(len(self.plist), 6)
|
|
self.assertEqual(self.cb_plist, self.plist)
|
|
self.assertEqual(self.cb_index, 5)
|
|
|
|
self.add_tracks([6])
|
|
self.assertEqual(len(self.plist), 6)
|
|
|
|
self.plist.add(None)
|
|
self.assertEqual(len(self.plist), 6)
|
|
|
|
def test_playlist_add_sorted(self):
|
|
self.plist.sort("tracknumber")
|
|
tracknos = [ 5, 6, 4, 7, 3, 8, 2, 9, 1, 10 ]
|
|
tracks = self.add_tracks(tracknos)
|
|
self.assertEqual(len(self.plist), 10)
|
|
for i, track in enumerate(self.plist.list):
|
|
self.assertEqual(track.tracknumber, i + 1)
|
|
|
|
def test_playlist_contains(self):
|
|
tracks = self.add_tracks(range(9, 0, -1))
|
|
for track in tracks:
|
|
self.assertTrue(self.plist.contains(track))
|
|
|
|
track = trak.lookup(os.path.join(test_album, f"10 - Test Track 10.ogg"))
|
|
self.assertFalse(self.plist.contains(track))
|
|
|
|
def test_playlist_get_markup(self):
|
|
self.assertEqual(self.plist.get_markup(), "Test Playlist\n0 Tracks")
|
|
self.add_tracks([1])
|
|
self.assertEqual(self.plist.get_markup(), "Test Playlist\n1 Track")
|
|
self.add_tracks([2])
|
|
self.assertEqual(self.plist.get_markup(), "Test Playlist\n2 Tracks")
|
|
self.plist.name = "Test & Playlist"
|
|
self.assertEqual(self.plist.get_markup(), "Test & Playlist\n2 Tracks")
|
|
|
|
def test_playlist_index(self):
|
|
tracks = self.add_tracks(range(9, 0, -1))
|
|
for i, track in enumerate(tracks):
|
|
self.assertEqual(self.plist.index(track), i)
|
|
|
|
track = trak.lookup(os.path.join(test_album, f"10 - Test Track 10.ogg"))
|
|
self.assertIsNone(self.plist.index(track))
|
|
self.assertIsNone(self.plist.index(None))
|
|
|
|
def test_playlist_index_sorted(self):
|
|
self.plist.sort("tracknumber")
|
|
tracks = self.add_tracks(range(1, 10))
|
|
for i, track in enumerate(tracks):
|
|
self.assertEqual(self.plist.index(track), i)
|
|
|
|
track = trak.lookup(os.path.join(test_album, f"10 - Test Track 10.ogg"))
|
|
self.assertIsNone(self.plist.index(track))
|
|
self.assertIsNone(self.plist.index(None))
|
|
|
|
def test_playlist_move_up(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.plist.current = 5
|
|
self.plist.sort("tracknumber")
|
|
|
|
self.plist.move(tracks[8], 6)
|
|
self.assertEqual(self.plist.current, 5)
|
|
self.assertEqual(self.plist.list[6], tracks[8])
|
|
self.assertEqual(self.plist.sort_order, [ ])
|
|
|
|
self.plist.move(tracks[8], 5)
|
|
self.assertEqual(self.plist.current, 6)
|
|
self.assertEqual(self.plist.list[5], tracks[8])
|
|
|
|
self.plist.move(tracks[9], 0)
|
|
self.assertEqual(self.plist.current, 7)
|
|
self.assertEqual(self.plist.list[0], tracks[9])
|
|
|
|
def test_playlist_move_down(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.plist.current = 5
|
|
|
|
self.plist.move(tracks[1], 4)
|
|
self.assertEqual(self.plist.current, 5)
|
|
self.assertEqual(self.plist.list[4], tracks[1])
|
|
|
|
self.plist.move(tracks[1], 5)
|
|
self.assertEqual(self.plist.current, 6)
|
|
self.assertEqual(self.plist.list[5], tracks[1])
|
|
|
|
self.plist.move(tracks[0], 9)
|
|
self.assertEqual(self.plist.current, 5)
|
|
self.assertEqual(self.plist.list[9], tracks[0])
|
|
|
|
self.plist.move(42, 0)
|
|
|
|
def test_playlist_move_current(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.plist.current = 5
|
|
|
|
self.plist.move(tracks[5], 8)
|
|
self.assertEqual(self.plist.current, 8)
|
|
self.assertEqual(self.plist.list[8], tracks[5])
|
|
|
|
self.plist.move(tracks[5], 0)
|
|
self.assertEqual(self.plist.current, 0)
|
|
self.assertEqual(self.plist.list[0], tracks[5])
|
|
|
|
def test_playlist_next_empty_one(self):
|
|
self.assertIsNone(self.plist.next())
|
|
self.assertEqual(self.plist.current, -1)
|
|
|
|
track = self.add_tracks([1])[0]
|
|
self.assertEqual(self.plist.current, -1)
|
|
self.assertEqual(self.plist.next(), track)
|
|
self.assertEqual(self.plist.current, 0)
|
|
self.assertEqual(self.plist.next(), None)
|
|
self.assertEqual(self.plist.current, 0)
|
|
|
|
self.plist.set_loop(True)
|
|
self.assertEqual(self.plist.next(), track)
|
|
self.assertEqual(self.plist.current, 0)
|
|
|
|
def test_playlist_next(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
|
|
for i, t in enumerate(tracks):
|
|
track = self.plist.next()
|
|
self.assertEqual(track, t)
|
|
self.assertEqual(self.plist.current, i)
|
|
|
|
self.assertIsNone(self.plist.next())
|
|
self.assertEqual(self.plist.current, len(tracks) - 1)
|
|
|
|
def test_playlist_next_loop(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.assertTrue(self.plist.set_loop(True))
|
|
|
|
for i, t in enumerate(tracks):
|
|
track = self.plist.next()
|
|
self.assertEqual(track, t)
|
|
self.assertEqual(self.plist.current, i)
|
|
|
|
for i, t in enumerate(tracks):
|
|
track = self.plist.next()
|
|
self.assertEqual(track, t)
|
|
self.assertEqual(self.plist.current, i)
|
|
|
|
def test_playlist_next_random(self):
|
|
current = -1
|
|
tracks = self.add_tracks(range(1, 11))
|
|
max = len(tracks) - 1
|
|
|
|
random.seed(1)
|
|
offsets = [ random.randint(1, max) for i in range(max * 2) ]
|
|
self.assertTrue(self.plist.set_random(True))
|
|
|
|
random.seed(1)
|
|
for offset in offsets:
|
|
current = (current + offset) % max
|
|
track = self.plist.next()
|
|
self.assertEqual(self.plist.current, current)
|
|
self.assertEqual(track, tracks[current])
|
|
|
|
def test_playlist_peek(self):
|
|
tracks = self.add_tracks(range(1, 5))
|
|
peek = self.plist.peek(0)
|
|
self.assertEqual(peek, [ ])
|
|
self.assertEqual(self.plist.current, -1)
|
|
|
|
peek = self.plist.peek(2)
|
|
self.assertEqual(peek, tracks[:2])
|
|
self.assertEqual(self.plist.current, -1)
|
|
|
|
peek = self.plist.peek(10)
|
|
self.assertEqual(peek, tracks)
|
|
self.assertEqual(self.plist.current, -1)
|
|
|
|
def test_playlist_remove(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.plist.current = 5
|
|
self.cb_plist = None
|
|
self.cb_track = None
|
|
self.cb_index = None
|
|
|
|
self.plist.remove(tracks[8])
|
|
self.assertEqual(self.plist.current, 5)
|
|
self.assertEqual(len(self.plist), 9)
|
|
self.assertNotIn(tracks[8], self.plist.list)
|
|
self.assertEqual(self.cb_changed, self.plist)
|
|
self.assertIsNone(self.cb_plist)
|
|
self.assertIsNone(self.cb_track)
|
|
self.assertIsNone(self.cb_index)
|
|
|
|
self.plist.visible = True
|
|
self.plist.remove(tracks[5])
|
|
self.assertEqual(self.plist.current, 4)
|
|
self.assertEqual(len(self.plist), 8)
|
|
self.assertNotIn(tracks[5], self.plist.list)
|
|
self.assertEqual(self.cb_plist, self.plist)
|
|
self.assertEqual(self.cb_track, tracks[5])
|
|
self.assertEqual(self.cb_index, 5)
|
|
|
|
self.plist.remove(tracks[2])
|
|
self.plist.remove(tracks[2])
|
|
self.assertEqual(self.plist.current, 3)
|
|
self.assertEqual(len(self.plist), 7)
|
|
self.assertNotIn(tracks[2], self.plist.list)
|
|
|
|
def test_playlist_reset(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
self.plist.current = 2
|
|
self.plist.loop = True
|
|
self.plist.random = True
|
|
|
|
self.plist.reset()
|
|
self.assertEqual(len(self.plist.list), 0)
|
|
self.assertEqual(self.plist.current, -1)
|
|
self.assertFalse(self.plist.loop)
|
|
self.assertFalse(self.plist.random)
|
|
|
|
def test_playlist_runtime(self):
|
|
track = self.add_tracks([1])[0]
|
|
self.assertEqual(self.plist.runtime(), "1 second")
|
|
track.length = 2
|
|
self.assertEqual(self.plist.runtime(), "2 seconds")
|
|
track.length = 60
|
|
self.assertEqual(self.plist.runtime(), "1 minute")
|
|
track.length = 120
|
|
self.assertEqual(self.plist.runtime(), "2 minutes")
|
|
track.length = 3600
|
|
self.assertEqual(self.plist.runtime(), "1 hour")
|
|
track.length = 7200
|
|
self.assertEqual(self.plist.runtime(), "2 hours")
|
|
track.length = 86400
|
|
self.assertEqual(self.plist.runtime(), "1 day")
|
|
track.length = 172800
|
|
self.assertEqual(self.plist.runtime(), "2 days")
|
|
|
|
def test_playlist_set_loop(self):
|
|
self.assertTrue( self.plist.can_loop)
|
|
self.assertFalse(self.plist.loop)
|
|
self.assertTrue( self.plist.set_loop(True))
|
|
self.assertTrue( self.plist.loop)
|
|
self.assertFalse( self.plist.set_loop(False))
|
|
self.assertFalse(self.plist.loop)
|
|
|
|
self.plist = playlist.Playlist("Test Playlist", can_loop=False)
|
|
self.assertFalse(self.plist.can_loop)
|
|
self.assertFalse(self.plist.set_loop(True))
|
|
self.assertFalse(self.plist.loop)
|
|
|
|
def test_playlist_set_random(self):
|
|
self.assertTrue( self.plist.can_random)
|
|
self.assertFalse(self.plist.random)
|
|
self.assertTrue( self.plist.set_random(True))
|
|
self.assertTrue( self.plist.random)
|
|
self.assertFalse( self.plist.set_random(False))
|
|
self.assertFalse(self.plist.random)
|
|
|
|
self.plist = playlist.Playlist("Test Playlist", can_random=False)
|
|
self.assertFalse(self.plist.can_random)
|
|
self.assertFalse(self.plist.set_random(True))
|
|
self.assertFalse(self.plist.random)
|
|
|
|
def test_playlist_sort(self):
|
|
tracks = self.add_tracks(range(1, 11))
|
|
random.shuffle(self.plist.list)
|
|
|
|
self.assertEqual(self.plist.sort_order, [ ])
|
|
|
|
self.assertTrue( self.plist.sort("tracknumber"))
|
|
self.assertEqual(self.plist.sort_order, [ "tracknumber" ])
|
|
for i, track in enumerate(tracks):
|
|
self.assertEqual(self.plist[i], track)
|
|
|
|
self.assertTrue( self.plist.sort("artist"))
|
|
self.assertEqual(self.plist.sort_order, [ "tracknumber", "artist" ])
|
|
self.assertFalse(self.plist.sort("tracknumber"))
|
|
self.assertEqual(self.plist.sort_order, [ "artist" ])
|
|
self.assertFalse(self.plist.sort("artist"))
|
|
self.assertEqual(self.plist.sort_order, [ ])
|
|
|
|
def test_playlist_track_key(self):
|
|
track = self.add_tracks([1])[0]
|
|
trackno = track.tracknumber
|
|
artist = track["artist"].lower().split()
|
|
|
|
self.assertEqual(self.plist.track_key(track), [ ])
|
|
self.assertTrue( self.plist.sort("tracknumber"))
|
|
self.assertEqual(self.plist.track_key(track), [ trackno ])
|
|
self.assertTrue( self.plist.sort("artist"))
|
|
self.assertEqual(self.plist.track_key(track), [ trackno, artist ])
|