def test_read(self): pl = Playlist(self.temp, "playlist") pl.extend(NUMERIC_SONGS) pl.write() lib = FileLibrary("foobar") lib.add(NUMERIC_SONGS) pl = Playlist(self.temp, "playlist", lib) self.assertEqual(len(pl), len(NUMERIC_SONGS))
def test_playlists_featuring(s): pl = Playlist(s.temp, "playlist") pl.extend(NUMERIC_SONGS) playlists = Playlist.playlists_featuring(NUMERIC_SONGS[0]) s.failUnlessEqual(set(playlists), set([pl])) # Now add a second one, check that instance tracking works pl2 = Playlist(s.temp, "playlist2") pl2.append(NUMERIC_SONGS[0]) playlists = Playlist.playlists_featuring(NUMERIC_SONGS[0]) s.failUnlessEqual(set(playlists), set([pl, pl2])) pl.delete() pl2.delete()
def test_equality(s): pl = Playlist(s.temp, "playlist") pl2 = Playlist(s.temp, "playlist") pl3 = Playlist(s.temp2, "playlist") s.failUnlessEqual(pl, pl2) # Debatable s.failUnlessEqual(pl, pl3) pl4 = Playlist(s.temp, "foobar") s.failIfEqual(pl, pl4) pl.delete() pl2.delete() pl3.delete() pl4.delete()
def test_listlike(s): pl = Playlist(s.temp, "playlist") pl.extend(NUMERIC_SONGS) s.failUnlessEqual(NUMERIC_SONGS[0], pl[0]) s.failUnlessEqual(NUMERIC_SONGS[1:2], pl[1:2]) s.failUnless(NUMERIC_SONGS[1] in pl) pl.delete()
def test_updating_aggregates_remove_songs(s): pl = Playlist(s.temp, "playlist") pl.extend(NUMERIC_SONGS) s.failUnless(pl.get("~#length")) pl.remove_songs(NUMERIC_SONGS) s.failIf(pl.get("~#length"))
def test_masked_handling(self): if os.name == "nt": # FIXME: masking isn't properly implemented on Windows return # playlists can contain songs and paths for masked handling.. lib = FileLibrary("foobar") pl = Playlist(self.temp, "playlist", lib) song = Fakesong({"date": "2038", "~filename": "/fake"}) song.sanitize() lib.add([song]) # mask and update lib.mask("/") pl.append(song) pl.remove_songs([song]) self.failUnless("/fake" in pl) pl.extend(self.TWO_SONGS) # check if collections can handle the mix self.failUnlessEqual(pl("date"), "2038") # unmask and update lib.unmask("/") pl.add_songs(["/fake"], lib) self.failUnless(song in pl) pl.delete() lib.destroy()
def test_duplicates(self): pl = Playlist(self.temp, "playlist") pl.extend(self.TWO_SONGS) pl.extend(self.TWO_SONGS) self.failUnlessEqual(len(pl), 4) self.failUnless(pl.has_duplicates, ("Playlist has un-detected duplicates: %s " % "\n".join([str(s) for s in pl._list])))
def test_playlists_tag(self): # Arguably belongs in _audio songs = NUMERIC_SONGS pl_name = "playlist 123!" pl = Playlist(self.temp, pl_name) pl.extend(songs) for song in songs: self.assertEquals(pl_name, song("~playlists")) pl.delete()
def test_write(self): pl = Playlist(self.temp, "playlist") pl.extend(NUMERIC_SONGS) pl.extend([fsnative(u"xf0xf0")]) pl.write() with open(pl.filename, "rb") as h: self.assertEqual(len(h.read().splitlines()), len(NUMERIC_SONGS) + 1)
def test_updating_aggregates_append(s): pl = Playlist(s.temp, "playlist") pl.extend(NUMERIC_SONGS) old_rating = pl.get("~#rating") pl.append(AMAZING_SONG) new_rating = pl.get("~#filesize") s.failUnless(new_rating > old_rating)
def test_internal_tags(s): pl = Playlist(s.temp, "playlist") pl.extend(s.TWO_SONGS) s.failIfEqual(pl.comma("~long-length"), "") s.failIfEqual(pl.comma("~tracks"), "") s.failIfEqual(pl.comma("~discs"), "") s.failUnlessEqual(pl.comma("~foo"), "") s.failUnlessEqual(pl.comma(""), "") s.failUnlessEqual(pl.comma("~"), "") s.failUnlessEqual(pl.get("~#"), "") pl.delete()
def init(klass, library): model = klass.__lists.get_model() for playlist in os.listdir(PLAYLISTS): try: playlist = Playlist(PLAYLISTS, Playlist.unquote(playlist), library=library) model.append(row=[playlist]) except EnvironmentError: pass library.connect('removed', klass.__removed) library.connect('added', klass.__added) library.connect('changed', klass.__changed)
def test_updating_aggregates_extend(s): pl = Playlist(s.temp, "playlist") pl.extend(NUMERIC_SONGS) old_length = pl.get("~#length") old_size = pl.get("~#filesize") # Double the playlist pl.extend(NUMERIC_SONGS) new_length = pl.get("~#length") new_size = pl.get("~#filesize") s.failUnless(new_length > old_length, msg="Ooops, %d <= %d" % (new_length, old_length)) s.failUnless(new_size > old_size, msg="Ooops, %d <= %d" % (new_size, old_size))
def test_index(s): pl = Playlist(s.temp, "playlist") songs = s.TWO_SONGS pl.extend(songs) # Just a sanity check... s.failUnlessEqual(1, songs.index(songs[1])) # And now the happy paths.. s.failUnlessEqual(0, pl.index(songs[0])) s.failUnlessEqual(1, pl.index(songs[1])) # ValueError is what we want here try: pl.index(Fakesong({})) s.fail() except ValueError: pass pl.delete()
def test_playlist_plugin(self): pl = Playlist("foo", library=app.librarian) pl.extend([AudioFile({"~filename": "/dev/null"})]) self.called_pl = None self.called_songs = None def proxy(songs, playlist=None): self.called_pl = playlist self.called_songs = songs plugin = self.plugin(playlists=[pl]) plugin._handle_songs = proxy # Test that as a Playlist plugin it delegates correctly plugin.plugin_playlist(pl) self.failUnless(self.called_songs) self.assertEqual(self.called_pl, pl) self.assertEqual(self.called_songs, pl.songs)
def test_add_remove(self): pl = Playlist("only", self.lib, self.playlists) assert self.received == ["added", "pl_added"] self.received.clear() # Update playlist, should trigger changes in files too pl.extend(self.lib._contents.values()) # Changing files then does trigger another change, # annoying but seems impossible to avoid if we want to save metadata, ~playlists assert self.received == ["pl_changed", "changed", "pl_changed"] self.received.clear() # Remove some songs and watch the playlist change songs = list(self.lib._contents.values()) self.lib.remove(songs[:2]) assert self.received == [ "removed", "pl_changed", "changed", "pl_changed" ] self.received.clear() pl.delete() assert self.received == ["pl_removed"]
def test_numeric_ops(s): songs = NUMERIC_SONGS pl = Playlist(s.temp, "playlist") pl.extend(songs) s.failUnlessEqual(pl.get("~#length"), 12) s.failUnlessEqual(pl.get("~#length:sum"), 12) s.failUnlessEqual(pl.get("~#length:max"), 7) s.failUnlessEqual(pl.get("~#length:min"), 1) s.failUnlessEqual(pl.get("~#length:avg"), 4) s.failUnlessEqual(pl.get("~#length:foo"), 0) s.failUnlessEqual(pl.get("~#rating:avg"), avg([0.1, 0.3, 0.5])) s.failUnlessEqual(pl.get("~#filesize"), 303) s.failUnlessEqual(pl.get("~#added"), 7) s.failUnlessEqual(pl.get("~#lastplayed"), 88) s.failUnlessEqual(pl.get("~#bitrate"), 200) s.failUnlessEqual(pl.get("~#year"), 33) s.failUnlessEqual(pl.get("~#rating"), 0.3) s.failUnlessEqual(pl.get("~#originalyear"), 2002) pl.delete()
def pl(self, name, lib=None): return Playlist(name, lib)
def generate_playlists(n): return [Playlist(DIR, "Playlist %d" % x) for x in range(n)]
import os from gi.repository import Gtk from quodlibet.browsers import Browser from quodlibet.library import SongLibrary from quodlibet.plugins.playlist import PlaylistPlugin, PlaylistPluginHandler from quodlibet.util.collection import Playlist from tests import TestCase, mkstemp, mkdtemp from quodlibet.plugins import PluginManager, Plugin from tests.helper import capture_output MAX_PLAYLISTS = 50 DIR = mkdtemp() TEST_PLAYLIST = Playlist(DIR, "foo") def generate_playlists(n): return [Playlist(DIR, "Playlist %d" % x) for x in range(n)] class TPlaylistPlugins(TestCase): class MockBrowser(Browser): def __init__(self): super(TPlaylistPlugins.MockBrowser, self).__init__() self.activated = False def activate(self): self.activated = True
import os import shutil from gi.repository import Gtk from quodlibet.browsers import Browser from quodlibet.library import SongLibrary from quodlibet.plugins.playlist import PlaylistPlugin, PlaylistPluginHandler from quodlibet.util.collection import Playlist from tests import TestCase, mkstemp, mkdtemp from quodlibet.plugins import PluginManager, Plugin from tests.helper import capture_output MAX_PLAYLISTS = 50 TEST_PLAYLIST = Playlist("foo") def generate_playlists(n): return [Playlist("Playlist %d" % x) for x in range(n)] class TPlaylistPlugins(TestCase): class MockBrowser(Browser): def __init__(self): super(TPlaylistPlugins.MockBrowser, self).__init__() self.activated = False def activate(self): self.activated = True
def test_playlist_info_markup(self): pl = Playlist("foobar") pl.extend(SONGS[0:2]) pat = MarkupPattern("<~name>: <artist|<artist>|?> [b]<~length>[/b]") markup = playlist_info_markup(pl, pat) self.failUnlessEqual(markup, "foobar: mu, piman <b>3:54</b>")
def test_duplicates_single_item(self): pl = Playlist(self.temp, "playlist") pl.append(self.TWO_SONGS[0]) self.failIf(pl.has_duplicates) pl.append(self.TWO_SONGS[0]) self.failUnless(pl.has_duplicates)
# TODO: Share better with, i.e. test MenuItemPlugin directly import os from gi.repository import Gtk from quodlibet.browsers import Browser from quodlibet.library import SongLibrary from quodlibet.plugins.playlist import PlaylistPlugin, PlaylistPluginHandler from quodlibet.util.collection import Playlist from tests import TestCase, mkstemp, mkdtemp from quodlibet.plugins import PluginManager, Plugin from tests.helper import capture_output MAX_PLAYLISTS = 50 TEST_PLAYLIST = Playlist("/tmp", "foo") def generate_playlists(n): return [Playlist("/tmp", "Playlist %d" % x) for x in range(n)] class TPlaylistPlugins(TestCase): class MockBrowser(Browser): def __init__(self): super(TPlaylistPlugins.MockBrowser, self).__init__() self.activated = False def activate(self): self.activated = True