class TSongTracker(TestCase): def setUp(self): config.init() self.p = NullPlayer() self.w = SongLibrary() self.s1 = AudioFile( {"~#playcount": 0, "~#skipcount": 0, "~#lastplayed": 10, "~filename": "foo", "~#length": 1.5}) self.s2 = AudioFile( {"~#playcount": 0, "~#skipcount": 0, "~#lastplayed": 10, "~filename": "foo", "~#length": 1.5}) self.cm = SongTracker(self.w, self.p, self) self.current = None def do(self): while Gtk.events_pending(): Gtk.main_iteration() def test_destroy(self): self.cm.destroy() def test_play(self): import time # Allow at least 2 second to elapse to simulate playing self.p.song = self.s1 self.p.paused = False time.sleep(2) self.do() self.p.emit('song-ended', self.s1, False) self.do() t = time.time() self.assertEquals(self.s1["~#playcount"], 1) self.assertEquals(self.s1["~#skipcount"], 0) self.failUnless(t - self.s1["~#lastplayed"] <= 1) def test_skip(self): self.p.emit('song-ended', self.s1, True) self.do() self.assertEquals(self.s1["~#playcount"], 0) self.assertEquals(self.s1["~#skipcount"], 1) self.failUnless(self.s1["~#lastplayed"], 10) def test_error(self): self.current = self.p.song = self.s1 self.p._error('Test error') self.do() self.assertEquals(self.s1["~#playcount"], 0) self.assertEquals(self.s1["~#skipcount"], 0) self.failUnless(self.s1["~#lastplayed"], 10) def test_restart(self): self.current = self.s1 self.p.emit('song-ended', self.s1, True) self.do() self.assertEquals(self.s1["~#playcount"], 0) self.assertEquals(self.s1["~#skipcount"], 0) def tearDown(self): self.w.destroy() config.quit()
class TInformation(TestCase): def setUp(self): quodlibet.config.init() self.library = SongLibrary() def test_none(self): Information(self.library, []).destroy() def test_one(self): f = AF({"~filename": "/dev/null"}) Information(self.library, [f]).destroy() def test_two(self): f = AF({"~filename": "/dev/null"}) f2 = AF({"~filename": "/dev/null2"}) Information(self.library, [f, f2]).destroy() def test_album(self): f = AF({"~filename": "/dev/null", "album": "woo"}) f2 = AF({"~filename": "/dev/null2", "album": "woo"}) Information(self.library, [f, f2]).destroy() def test_artist(self): f = AF({"~filename": "/dev/null", "artist": "woo"}) f2 = AF({"~filename": "/dev/null2", "artist": "woo"}) Information(self.library, [f, f2]).destroy() def tearDown(self): self.library.destroy() quodlibet.config.quit()
class TRatingsMenuItem(TestCase): def setUp(self): config.RATINGS = config.HardCodedRatingsPrefs() self.failUnlessEqual(config.RATINGS.number, NUM_RATINGS) self.library = SongLibrary() self.library.librarian = SongLibrarian() self.af = AudioFile({"~filename": fsnative(u"/foo"), "~#rating": 1.0}) self.af.sanitize() self.rmi = RatingsMenuItem([self.af], self.library) def tearDown(self): self.rmi.destroy() self.library.destroy() self.library.librarian.destroy() def test_menuitem_children(self): children = [mi for mi in self.rmi.get_submenu().get_children() if isinstance(mi, Gtk.CheckMenuItem)] self.failUnlessEqual(len(children), NUM_RATINGS + 1) highest = children[-1] self.failUnlessEqual(highest.get_active(), True) self.failUnlessEqual(children[1].get_active(), False) def test_set_remove_rating(self): self.rmi.set_rating(0.5, [self.af], self.library) self.failUnless(self.af.has_rating) self.failUnlessEqual(self.af('~#rating'), 0.5) self.rmi.remove_rating([self.af], self.library) self.failIf(self.af.has_rating)
def test_menuitem(self): library = SongLibrary() library.librarian = SongLibrarian() a = AudioFile({"~filename": fsnative(u"/foo")}) a.sanitize() x = RatingsMenuItem([a], library) x.set_rating(0, [a], library) x.destroy() library.destroy() library.librarian.destroy()
class TAudioFeeds(TestCase): def setUp(self): quodlibet.config.init() self.library = SongLibrary() self.bar = AudioFeeds(self.library, NullPlayer("fakesink")) def test_can_filter(self): for key in ["foo", "title", "fake~key", "~woobar", "~#huh"]: self.failIf(self.bar.can_filter(key)) def tearDown(self): self.bar.destroy() self.library.destroy() quodlibet.config.quit()
class TPlaylists(TestCase): def setUp(self): quodlibet.config.init() self.library = SongLibrary() self.bar = PlaylistsBrowser(SongLibrary(), NullPlayer()) def test_can_filter(self): for key in ["foo", "title", "fake~key", "~woobar", "~#huh"]: self.failIf(self.bar.can_filter(key)) def tearDown(self): self.bar.destroy() self.library.destroy() quodlibet.config.quit()
class TPlaylists(TestCase): def setUp(self): quodlibet.config.init() self.library = SongLibrary() self.bar = PlaylistsBrowser(SongLibrary()) def test_can_filter(self): for key in ["foo", "title", "fake~key", "~woobar", "~#huh"]: self.failIf(self.bar.can_filter(key)) def tearDown(self): self.bar.destroy() self.library.destroy() quodlibet.config.quit()
class TLyricsPane(TestCase): def setUp(self): quodlibet.config.init() init_fake_app() self.pane = None self.library = SongLibrary() def tearDown(self): destroy_fake_app() self.library.destroy() quodlibet.config.quit() if self.pane: self.pane.destroy() def test_construction(self): af = AF({"~filename": fsnative(u"/dev/null")}) self.pane = LyricsPane(af) def test_save_lyrics(self): af = self.temp_mp3() self.pane = LyricsPane(af) self.pane._save_lyrics(af, LYRICS) self.failUnlessEqual(af("~lyrics"), LYRICS) def test_save_encoded_lyrics(self): af = self.temp_mp3() self.pane = LyricsPane(af) self.pane._save_lyrics(af, LYRICS) self.failUnlessEqual(af("~lyrics"), LYRICS) def test_save_lyrics_deletes_lyric_file(self): af = self.temp_mp3() lf_name = af.lyric_filename os.makedirs(os.path.dirname(lf_name)) with open(lf_name, "wb") as f: f.write(LYRICS.encode("utf-8")) self.failUnless(os.path.exists(lf_name)) self.pane = LyricsPane(af) self.pane._save_lyrics(af, LYRICS) self.failIf(os.path.exists(lf_name)) def temp_mp3(self): name = get_temp_copy(get_data_path('silence-44-s.mp3')) af = MP3File(name) af.sanitize() return af
class TInformation(TestCase): def setUp(self): quodlibet.config.init() init_fake_app() self.inf = None self.library = SongLibrary() def tearDown(self): destroy_fake_app() self.library.destroy() quodlibet.config.quit() if self.inf: self.inf.destroy() def test_none(self): Information(self.library, []).destroy() def test_one(self): f = AF({"~filename": fsnative(u"/dev/null")}) self.inf = Information(self.library, [f]) self.assert_child_is(OneSong) def test_two(self): f = AF({"~filename": fsnative(u"/dev/null")}) f2 = AF({"~filename": fsnative(u"/dev/null2")}) self.inf = Information(self.library, [f, f2]) self.assert_child_is(ManySongs) def test_album(self): f = AF({"~filename": fsnative(u"/dev/null"), "album": "woo"}) f2 = AF({"~filename": fsnative(u"/dev/null2"), "album": "woo"}) self.inf = Information(self.library, [f, f2]) self.assert_child_is(OneAlbum) def test_artist(self): f = AF({"~filename": fsnative(u"/dev/null"), "artist": "woo"}) f2 = AF({"~filename": fsnative(u"/dev/null2"), "artist": "woo"}) self.inf = Information(self.library, [f, f2]) self.assert_child_is(OneArtist) def assert_child_is(self, cls): self.failUnless(isinstance(self.inf.get_child(), cls))
class TSongProperties(TestCase): af1 = AudioFile({"title": "woo"}) af1.sanitize(fsnative(u"invalid")) af2 = AudioFile({"title": "bar", "album": "quux"}) af2.sanitize(fsnative(u"alsoinvalid")) def setUp(self): SongProperties.plugins = DummyPlugins() config.init() self.library = SongLibrary() def test_onesong(self): self.window = SongProperties(self.library, [self.af1]) def test_twosong(self): self.window = SongProperties(self.library, [self.af2, self.af1]) def test_changed(self): self.test_twosong() self.window.hide() self.library.emit('changed', [self.af2]) while Gtk.events_pending(): Gtk.main_iteration() def test_removed(self): self.test_twosong() self.window.hide() self.library.emit('removed', [self.af2]) while Gtk.events_pending(): Gtk.main_iteration() def tearDown(self): try: self.window.destroy() except AttributeError: pass else: del(self.window) self.library.destroy() del(SongProperties.plugins) config.quit()
class TSongsMenuPlugins(TestCase): def _confirmer(self, *args): self.confirmed = True def setUp(self): self.tempdir = mkdtemp() self.pm = PluginManager(folders=[self.tempdir]) self.confirmed = False self.handler = SongsMenuPluginHandler(self._confirmer, self._confirmer) self.pm.register_handler(self.handler) self.pm.rescan() self.assertEquals(self.pm.plugins, []) self.library = SongLibrary('foo') def tearDown(self): self.library.destroy() self.pm.quit() for f in os.listdir(self.tempdir): os.remove(os.path.join(self.tempdir, f)) os.rmdir(self.tempdir) def create_plugin(self, id='', name='', desc='', icon='', funcs=None, mod=False): fd, fn = mkstemp(suffix='.py', text=True, dir=self.tempdir) file = os.fdopen(fd, 'w') if mod: indent = '' else: file.write( "from quodlibet.plugins.songsmenu import SongsMenuPlugin\n") file.write("class %s(SongsMenuPlugin):\n" % name) indent = ' ' file.write("%spass\n" % indent) if name: file.write("%sPLUGIN_ID = %r\n" % (indent, name)) if name: file.write("%sPLUGIN_NAME = %r\n" % (indent, name)) if desc: file.write("%sPLUGIN_DESC = %r\n" % (indent, desc)) if icon: file.write("%sPLUGIN_ICON = %r\n" % (indent, icon)) for f in (funcs or []): if f in ["__init__"]: file.write("%sdef %s(self, *args): super(%s, self).__init__(" "*args); raise Exception(\"as expected\")\n" % (indent, f, name)) else: file.write("%sdef %s(*args): return args\n" % (indent, f)) file.flush() file.close() def test_empty_has_no_plugins(self): self.pm.rescan() self.assertEquals(self.pm.plugins, []) def test_name_and_desc_plus_func_is_one(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 1) def test_additional_functions_still_only_one(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song', 'plugin_songs']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 1) def test_two_plugins_are_two(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song']) self.create_plugin(name='Name2', desc='Desc2', funcs=['plugin_albums']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 2) def test_disables_plugin(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song']) self.pm.rescan() self.failIf(self.pm.enabled(self.pm.plugins[0])) def test_enabledisable_plugin(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song']) self.pm.rescan() plug = self.pm.plugins[0] self.pm.enable(plug, True) self.failUnless(self.pm.enabled(plug)) self.pm.enable(plug, False) self.failIf(self.pm.enabled(plug)) def test_ignores_broken_plugin(self): self.create_plugin(name="Broken", desc="Desc", funcs=["__init__", "plugin_song"]) self.pm.rescan() plug = self.pm.plugins[0] self.pm.enable(plug, True) with capture_output(): menu = self.handler.Menu(None, [AudioFile()]) self.failIf(menu and menu.get_children()) def test_Menu(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song']) self.handler.Menu(None, [AudioFile()]) def test_handling_songs_without_confirmation(self): plugin = Plugin(FakeSongsMenuPlugin) self.handler.plugin_enable(plugin) MAX = FakeSongsMenuPlugin.MAX_INVOCATIONS songs = [AudioFile({'~filename': "/tmp/%s" % x, 'artist': 'foo'}) for x in range(MAX)] self.handler.handle(plugin.id, self.library, None, songs) self.failIf(self.confirmed, ("Wasn't expecting a confirmation for %d" " invocations" % len(songs))) def test_handling_lots_of_songs_with_confirmation(self): plugin = Plugin(FakeSongsMenuPlugin) self.handler.plugin_enable(plugin) MAX = FakeSongsMenuPlugin.MAX_INVOCATIONS songs = [AudioFile({'~filename': "/tmp/%s" % x, 'artist': 'foo'}) for x in range(MAX + 1)] self.handler.handle(plugin.id, self.library, None, songs) self.failUnless(self.confirmed, ("Should have confirmed %d invocations (Max=%d)." % (len(songs), MAX)))
class TSongsMenu(TestCase): def setUp(self): config.init() self.library = SongLibrary() backend = quodlibet.player.init_backend("nullbe") self.device = backend.init(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(fsnative(text_type(song["title"]))) def test_empty(self): self.menu = SongsMenu(self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(0, len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=True, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=True, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def tearDown(self): self.device.destroy() self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del(self.menu) config.quit()
class TSongsMenu(TestCase): def setUp(self): self.library = SongLibrary() quodlibet.player.init("nullbe") self.device = quodlibet.player.init_device(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(song["title"]) def test_empty(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(0, len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_devices(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=True, remove=False, delete=False, edit=False, ) from quodlibet import browsers if browsers.media.MediaDevices in browsers.browsers: self.failUnlessEqual(1, len(self.menu)) else: self.failUnlessEqual(0, len(self.menu)) def test_remove(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=True, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=True, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=True, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=True, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def tearDown(self): quodlibet.player.quit(self.device) self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del (self.menu)
class TPlaylistPlugins(TestCase): class MockBrowser(Browser): def __init__(self): super(TPlaylistPlugins.MockBrowser, self).__init__() self.activated = False def activate(self): self.activated = True def get_toplevel(self): return self def is_toplevel(self): return True def _confirmer(self, *args): self.confirmed = True def setUp(self): self.tempdir = mkdtemp() self.pm = PluginManager(folders=[self.tempdir]) self.confirmed = False self.mock_browser = self.MockBrowser() self.handler = PlaylistPluginHandler(self._confirmer) self.pm.register_handler(self.handler) self.pm.rescan() self.assertEquals(self.pm.plugins, []) self.library = SongLibrary('foo') def tearDown(self): self.library.destroy() self.pm.quit() shutil.rmtree(self.tempdir) def create_plugin(self, id='', name='', desc='', icon='', funcs=None, mod=False): fd, fn = mkstemp(suffix='.py', text=True, dir=self.tempdir) file = os.fdopen(fd, 'w') if mod: indent = '' else: file.write( "from quodlibet.plugins.playlist import PlaylistPlugin\n") file.write("class %s(PlaylistPlugin):\n" % name) indent = ' ' file.write("%spass\n" % indent) if name: file.write("%sPLUGIN_ID = %r\n" % (indent, name)) if name: file.write("%sPLUGIN_NAME = %r\n" % (indent, name)) if desc: file.write("%sPLUGIN_DESC = %r\n" % (indent, desc)) if icon: file.write("%sPLUGIN_ICON = %r\n" % (indent, icon)) for f in (funcs or []): if f in ["__init__"]: file.write("%sdef %s(self, *args): super(%s, self).__init__(" "*args); raise Exception(\"as expected.\")\n" % (indent, f, name)) else: file.write("%sdef %s(*args): return args\n" % (indent, f)) file.flush() file.close() def test_empty_has_no_plugins(self): self.pm.rescan() self.assertEquals(self.pm.plugins, []) def test_name_and_desc_plus_func_is_one(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_playlist']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 1) def test_additional_functions_still_only_one(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_playlist', 'plugin_playlists']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 1) def test_two_plugins_are_two(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_playlist']) self.create_plugin(name='Name2', desc='Desc2', funcs=['plugin_albums']) self.pm.rescan() self.assertEquals(len(self.pm.plugins), 2) def test_disables_plugin(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_playlist']) self.pm.rescan() self.failIf(self.pm.enabled(self.pm.plugins[0])) def test_enabledisable_plugin(self): self.create_plugin(name='Name', desc='Desc', funcs=['plugin_playlist']) self.pm.rescan() plug = self.pm.plugins[0] self.pm.enable(plug, True) self.failUnless(self.pm.enabled(plug)) self.pm.enable(plug, False) self.failIf(self.pm.enabled(plug)) def test_ignores_broken_plugin(self): self.create_plugin(name="Broken", desc="Desc", funcs=["__init__", "plugin_playlist"]) self.pm.rescan() plug = self.pm.plugins[0] self.pm.enable(plug, True) menu = Gtk.Menu() with capture_output(): self.handler.populate_menu(menu, None, self.mock_browser, [TEST_PLAYLIST]) self.failUnlessEqual(len(menu.get_children()), 0, msg="Shouldn't have enabled a broken plugin") def test_populate_menu(self): plugin = Plugin(FakePlaylistPlugin) self.handler.plugin_enable(plugin) menu = Gtk.Menu() self.handler.populate_menu(menu, None, self.mock_browser, [TEST_PLAYLIST]) # Don't forget the separator num = len(menu.get_children()) - 1 self.failUnlessEqual(num, 1, msg="Need 1 plugin not %d" % num) def test_handling_playlists_without_confirmation(self): plugin = Plugin(FakePlaylistPlugin) self.handler.plugin_enable(plugin) playlists = generate_playlists(MAX_PLAYLISTS) self.handler.handle(plugin.id, self.library, self.mock_browser, playlists) self.failUnless("Didn't execute plugin", FakePlaylistPlugin.total > 0) self.failIf(self.confirmed, ("Wasn't expecting a confirmation for %d" " invocations" % len(playlists))) def test_handling_lots_of_songs_with_confirmation(self): plugin = Plugin(FakePlaylistPlugin) self.handler.plugin_enable(plugin) playlists = generate_playlists(MAX_PLAYLISTS + 1) self.handler.handle(plugin.id, self.library, self.mock_browser, playlists) self.failUnless(self.confirmed, ("Should have confirmed %d invocations (Max=%d)." % (len(playlists), MAX_PLAYLISTS)))
class TSongsMenu(TestCase): def _confirmer(self, *args): self.confirmed = True return False def setUp(self): config.init() self.library = SongLibrary() backend = quodlibet.player.init_backend("nullbe") self.device = backend.init(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(fsnative(text_type(song["title"]))) self.confirmed = False def test_empty(self): self.menu = self.empty_menu_with() self.failIf(len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove(self): self.menu = self.empty_menu_with(remove=True, removal_confirmer=self._confirmer) self.failUnlessEqual(len(self.menu), 1) item = self.menu.get_children()[0] self.failIf(item.props.sensitive) item.activate() self.failUnless(self.confirmed, "Should have confirmed song removal") def test_remove_sensitive(self): self.library.add(self.songs) self.menu = self.empty_menu_with(remove=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = self.empty_menu_with(delete=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = self.empty_menu_with(delete=True) self.failIf(self.menu.get_children()[0].props.sensitive) def test_show_files(self): self.menu = self.empty_menu_with(show_files=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) item = self.menu.get_children()[0] self.failUnless(item.props.sensitive) def test_show_files_remote_songs(self): self.songs = self.library.songs = [RemoteFile("http://example.com/")] self.menu = self.empty_menu_with(show_files=True) self.failIf(len(self.menu)) def test_show_files_too_many_songs(self): self.songs = self.library.songs = [an_af(i) for i in range(50)] self.menu = self.empty_menu_with(show_files=True) item = self.menu.get_children()[0] self.failIf(item.props.sensitive, msg="Should have disabled show files for 50 files") def empty_menu_with(self, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False, show_files=False, removal_confirmer=None): return SongsMenu(self.library, self.songs, plugins=plugins, playlists=playlists, queue=queue, remove=remove, delete=delete, edit=edit, ratings=ratings, show_files=show_files, removal_confirmer=removal_confirmer) def tearDown(self): self.device.destroy() self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del(self.menu) config.quit()