Move controllers to a new core actor
The frontends use the new core actor, while the core actor uses the backend. This is a step towards supporting multiple backends, where the core actor will coordinate the backends.
This commit is contained in:
parent
c5ef8431c3
commit
2fdeec9f5a
@ -31,6 +31,7 @@ sys.path.insert(0,
|
||||
from mopidy import (get_version, settings, OptionalDependencyError,
|
||||
SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE)
|
||||
from mopidy.audio import Audio
|
||||
from mopidy.core import Core
|
||||
from mopidy.utils import get_class
|
||||
from mopidy.utils.deps import list_deps_optparse_callback
|
||||
from mopidy.utils.log import setup_logging
|
||||
@ -52,7 +53,8 @@ def main():
|
||||
check_old_folders()
|
||||
setup_settings(options.interactive)
|
||||
audio = setup_audio()
|
||||
setup_backend(audio)
|
||||
backend = setup_backend(audio)
|
||||
setup_core(audio, backend)
|
||||
setup_frontends()
|
||||
loop.run()
|
||||
except SettingsError as e:
|
||||
@ -64,6 +66,7 @@ def main():
|
||||
finally:
|
||||
loop.quit()
|
||||
stop_frontends()
|
||||
stop_core()
|
||||
stop_backend()
|
||||
stop_audio()
|
||||
stop_remaining_actors()
|
||||
@ -126,13 +129,21 @@ def stop_audio():
|
||||
|
||||
|
||||
def setup_backend(audio):
|
||||
get_class(settings.BACKENDS[0]).start(audio=audio)
|
||||
return get_class(settings.BACKENDS[0]).start(audio=audio).proxy()
|
||||
|
||||
|
||||
def stop_backend():
|
||||
stop_actors_by_class(get_class(settings.BACKENDS[0]))
|
||||
|
||||
|
||||
def setup_core(audio, backend):
|
||||
return Core.start(audio, backend).proxy()
|
||||
|
||||
|
||||
def stop_core():
|
||||
stop_actors_by_class(Core)
|
||||
|
||||
|
||||
def setup_frontends():
|
||||
for frontend_class_name in settings.FRONTENDS:
|
||||
try:
|
||||
|
||||
@ -8,8 +8,7 @@ import logging
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import settings, utils
|
||||
from mopidy.backends.base import Backend
|
||||
from mopidy import core, settings, utils
|
||||
from mopidy.utils import process
|
||||
|
||||
# Trigger install of gst mixer plugins
|
||||
@ -150,7 +149,7 @@ class Audio(ThreadingActor):
|
||||
|
||||
def _on_message(self, bus, message):
|
||||
if message.type == gst.MESSAGE_EOS:
|
||||
self._notify_backend_of_eos()
|
||||
self._notify_core_of_eos()
|
||||
elif message.type == gst.MESSAGE_ERROR:
|
||||
error, debug = message.parse_error()
|
||||
logger.error(u'%s %s', error, debug)
|
||||
@ -159,14 +158,14 @@ class Audio(ThreadingActor):
|
||||
error, debug = message.parse_warning()
|
||||
logger.warning(u'%s %s', error, debug)
|
||||
|
||||
def _notify_backend_of_eos(self):
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) <= 1, 'Expected at most one running backend.'
|
||||
if backend_refs:
|
||||
logger.debug(u'Notifying backend of end-of-stream.')
|
||||
backend_refs[0].proxy().playback.on_end_of_track()
|
||||
def _notify_core_of_eos(self):
|
||||
core_refs = ActorRegistry.get_by_class(core.Core)
|
||||
assert len(core_refs) <= 1, 'Expected at most one running core instance'
|
||||
if core_refs:
|
||||
logger.debug(u'Notifying core of end-of-stream')
|
||||
core_refs[0].proxy().playback.on_end_of_track()
|
||||
else:
|
||||
logger.debug(u'No backend to notify of end-of-stream found.')
|
||||
logger.debug(u'No core instance to notify of end-of-stream found')
|
||||
|
||||
def set_uri(self, uri):
|
||||
"""
|
||||
|
||||
@ -10,24 +10,20 @@ class Backend(object):
|
||||
#: which will then set this field.
|
||||
audio = None
|
||||
|
||||
#: The current playlist controller. An instance of
|
||||
#: :class:`mopidy.backends.base.CurrentPlaylistController`.
|
||||
current_playlist = None
|
||||
|
||||
#: The library controller. An instance of
|
||||
# :class:`mopidy.backends.base.LibraryController`.
|
||||
#: The library provider. An instance of
|
||||
# :class:`mopidy.backends.base.BaseLibraryProvider`.
|
||||
library = None
|
||||
|
||||
#: The playback controller. An instance of
|
||||
#: :class:`mopidy.backends.base.PlaybackController`.
|
||||
#: The playback provider. An instance of
|
||||
#: :class:`mopidy.backends.base.BasePlaybackProvider`.
|
||||
playback = None
|
||||
|
||||
#: The stored playlists controller. An instance of
|
||||
#: :class:`mopidy.backends.base.StoredPlaylistsController`.
|
||||
#: The stored playlists provider. An instance of
|
||||
#: :class:`mopidy.backends.base.BaseStoredPlaylistsProvider`.
|
||||
stored_playlists = None
|
||||
|
||||
#: List of URI schemes this backend can handle.
|
||||
uri_schemes = []
|
||||
|
||||
def __init__(self, audio=None):
|
||||
def __init__(self, audio):
|
||||
self.audio = audio
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
from pykka.actor import ThreadingActor
|
||||
|
||||
from mopidy import core
|
||||
from mopidy.backends import base
|
||||
from mopidy.models import Playlist
|
||||
|
||||
@ -14,21 +13,11 @@ class DummyBackend(ThreadingActor, base.Backend):
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DummyBackend, self).__init__(*args, **kwargs)
|
||||
base.Backend.__init__(self, *args, **kwargs)
|
||||
|
||||
self.current_playlist = core.CurrentPlaylistController(backend=self)
|
||||
|
||||
library_provider = DummyLibraryProvider(backend=self)
|
||||
self.library = core.LibraryController(backend=self,
|
||||
provider=library_provider)
|
||||
|
||||
playback_provider = DummyPlaybackProvider(backend=self)
|
||||
self.playback = core.PlaybackController(backend=self,
|
||||
provider=playback_provider)
|
||||
|
||||
stored_playlists_provider = DummyStoredPlaylistsProvider(backend=self)
|
||||
self.stored_playlists = core.StoredPlaylistsController(backend=self,
|
||||
provider=stored_playlists_provider)
|
||||
self.library = DummyLibraryProvider(backend=self)
|
||||
self.playback = DummyPlaybackProvider(backend=self)
|
||||
self.stored_playlists = DummyStoredPlaylistsProvider(backend=self)
|
||||
|
||||
self.uri_schemes = [u'dummy']
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import shutil
|
||||
|
||||
from pykka.actor import ThreadingActor
|
||||
|
||||
from mopidy import audio, core, settings
|
||||
from mopidy import settings
|
||||
from mopidy.backends import base
|
||||
from mopidy.models import Playlist, Track, Album
|
||||
|
||||
@ -33,19 +33,9 @@ class LocalBackend(ThreadingActor, base.Backend):
|
||||
def __init__(self, *args, **kwargs):
|
||||
base.Backend.__init__(self, *args, **kwargs)
|
||||
|
||||
self.current_playlist = core.CurrentPlaylistController(backend=self)
|
||||
|
||||
self.library_provider = LocalLibraryProvider(backend=self)
|
||||
self.library = core.LibraryController(backend=self,
|
||||
provider=self.library_provider)
|
||||
|
||||
playback_provider = base.BasePlaybackProvider(backend=self)
|
||||
self.playback = core.PlaybackController(backend=self,
|
||||
provider=playback_provider)
|
||||
|
||||
stored_playlists_provider = LocalStoredPlaylistsProvider(backend=self)
|
||||
self.stored_playlists = core.StoredPlaylistsController(backend=self,
|
||||
provider=stored_playlists_provider)
|
||||
self.library = LocalLibraryProvider(backend=self)
|
||||
self.playback = base.BasePlaybackProvider(backend=self)
|
||||
self.stored_playlists = LocalStoredPlaylistsProvider(backend=self)
|
||||
|
||||
self.uri_schemes = [u'file']
|
||||
|
||||
@ -69,7 +59,7 @@ class LocalStoredPlaylistsProvider(base.BaseStoredPlaylistsProvider):
|
||||
tracks = []
|
||||
for uri in parse_m3u(m3u, settings.LOCAL_MUSIC_PATH):
|
||||
try:
|
||||
tracks.append(self.backend.library_provider.lookup(uri))
|
||||
tracks.append(self.backend.library.lookup(uri))
|
||||
except LookupError, e:
|
||||
logger.error('Playlist item could not be added: %s', e)
|
||||
playlist = Playlist(tracks=tracks, name=name)
|
||||
|
||||
@ -2,7 +2,7 @@ import logging
|
||||
|
||||
from pykka.actor import ThreadingActor
|
||||
|
||||
from mopidy import audio, core, settings
|
||||
from mopidy import settings
|
||||
from mopidy.backends import base
|
||||
|
||||
logger = logging.getLogger('mopidy.backends.spotify')
|
||||
@ -48,20 +48,9 @@ class SpotifyBackend(ThreadingActor, base.Backend):
|
||||
|
||||
base.Backend.__init__(self, *args, **kwargs)
|
||||
|
||||
self.current_playlist = core.CurrentPlaylistController(backend=self)
|
||||
|
||||
library_provider = SpotifyLibraryProvider(backend=self)
|
||||
self.library = core.LibraryController(backend=self,
|
||||
provider=library_provider)
|
||||
|
||||
playback_provider = SpotifyPlaybackProvider(backend=self)
|
||||
self.playback = core.PlaybackController(backend=self,
|
||||
provider=playback_provider)
|
||||
|
||||
self.stored_playlists_provider = SpotifyStoredPlaylistsProvider(
|
||||
backend=self)
|
||||
self.stored_playlists = core.StoredPlaylistsController(backend=self,
|
||||
provider=self.stored_playlists_provider)
|
||||
self.library = SpotifyLibraryProvider(backend=self)
|
||||
self.playback = SpotifyPlaybackProvider(backend=self)
|
||||
self.stored_playlists = SpotifyStoredPlaylistsProvider(backend=self)
|
||||
|
||||
self.uri_schemes = [u'spotify']
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ class SpotifyLibraryProvider(BaseLibraryProvider):
|
||||
# Since we can't search for the entire Spotify library, we return
|
||||
# all tracks in the stored playlists when the query is empty.
|
||||
tracks = []
|
||||
for playlist in self.backend.stored_playlists_provider.playlists:
|
||||
for playlist in self.backend.stored_playlists.playlists:
|
||||
tracks += playlist.tracks
|
||||
return Playlist(tracks=tracks)
|
||||
spotify_query = []
|
||||
|
||||
@ -138,7 +138,7 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
playlists = map(SpotifyTranslator.to_mopidy_playlist,
|
||||
self.session.playlist_container())
|
||||
playlists = filter(None, playlists)
|
||||
self.backend.stored_playlists_provider.playlists = playlists
|
||||
self.backend.stored_playlists.playlists = playlists
|
||||
logger.info(u'Loaded %d Spotify playlist(s)', len(playlists))
|
||||
|
||||
def search(self, query, queue):
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from .actor import Core
|
||||
from .current_playlist import CurrentPlaylistController
|
||||
from .library import LibraryController
|
||||
from .playback import PlaybackController, PlaybackState
|
||||
|
||||
42
mopidy/core/actor.py
Normal file
42
mopidy/core/actor.py
Normal file
@ -0,0 +1,42 @@
|
||||
from pykka.actor import ThreadingActor
|
||||
|
||||
from .current_playlist import CurrentPlaylistController
|
||||
from .library import LibraryController
|
||||
from .playback import PlaybackController
|
||||
from .stored_playlists import StoredPlaylistsController
|
||||
|
||||
|
||||
class Core(ThreadingActor):
|
||||
#: The current playlist controller. An instance of
|
||||
#: :class:`mopidy.core.CurrentPlaylistController`.
|
||||
current_playlist = None
|
||||
|
||||
#: The library controller. An instance of
|
||||
# :class:`mopidy.core.LibraryController`.
|
||||
library = None
|
||||
|
||||
#: The playback controller. An instance of
|
||||
#: :class:`mopidy.core.PlaybackController`.
|
||||
playback = None
|
||||
|
||||
#: The stored playlists controller. An instance of
|
||||
#: :class:`mopidy.core.StoredPlaylistsController`.
|
||||
stored_playlists = None
|
||||
|
||||
def __init__(self, audio=None, backend=None):
|
||||
self._backend = backend
|
||||
|
||||
self.current_playlist = CurrentPlaylistController(core=self)
|
||||
|
||||
self.library = LibraryController(backend=backend, core=self)
|
||||
|
||||
self.playback = PlaybackController(
|
||||
audio=audio, backend=backend, core=self)
|
||||
|
||||
self.stored_playlists = StoredPlaylistsController(
|
||||
backend=backend, core=self)
|
||||
|
||||
@property
|
||||
def uri_schemes(self):
|
||||
"""List of URI schemes we can handle"""
|
||||
return self._backend.uri_schemes.get()
|
||||
@ -17,8 +17,8 @@ class CurrentPlaylistController(object):
|
||||
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, backend):
|
||||
self.backend = backend
|
||||
def __init__(self, core):
|
||||
self.core = core
|
||||
self.cp_id = 0
|
||||
self._cp_tracks = []
|
||||
self._version = 0
|
||||
@ -59,7 +59,7 @@ class CurrentPlaylistController(object):
|
||||
@version.setter
|
||||
def version(self, version):
|
||||
self._version = version
|
||||
self.backend.playback.on_current_playlist_change()
|
||||
self.core.playback.on_current_playlist_change()
|
||||
self._trigger_playlist_changed()
|
||||
|
||||
def add(self, track, at_position=None, increase_version=True):
|
||||
|
||||
@ -8,9 +8,9 @@ class LibraryController(object):
|
||||
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, backend, provider):
|
||||
def __init__(self, backend, core):
|
||||
self.backend = backend
|
||||
self.provider = provider
|
||||
self.core = core
|
||||
|
||||
def find_exact(self, **query):
|
||||
"""
|
||||
@ -29,7 +29,7 @@ class LibraryController(object):
|
||||
:type query: dict
|
||||
:rtype: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.find_exact(**query)
|
||||
return self.backend.library.find_exact(**query).get()
|
||||
|
||||
def lookup(self, uri):
|
||||
"""
|
||||
@ -39,7 +39,7 @@ class LibraryController(object):
|
||||
:type uri: string
|
||||
:rtype: :class:`mopidy.models.Track` or :class:`None`
|
||||
"""
|
||||
return self.provider.lookup(uri)
|
||||
return self.backend.library.lookup(uri).get()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
"""
|
||||
@ -48,7 +48,7 @@ class LibraryController(object):
|
||||
:param uri: directory or track URI
|
||||
:type uri: string
|
||||
"""
|
||||
return self.provider.refresh(uri)
|
||||
return self.backend.library.refresh(uri).get()
|
||||
|
||||
def search(self, **query):
|
||||
"""
|
||||
@ -67,4 +67,4 @@ class LibraryController(object):
|
||||
:type query: dict
|
||||
:rtype: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.search(**query)
|
||||
return self.backend.library.search(**query).get()
|
||||
|
||||
@ -79,9 +79,10 @@ class PlaybackController(object):
|
||||
#: Playback continues after current song.
|
||||
single = option_wrapper('_single', False)
|
||||
|
||||
def __init__(self, backend, provider):
|
||||
def __init__(self, audio, backend, core):
|
||||
self.audio = audio
|
||||
self.backend = backend
|
||||
self.provider = provider
|
||||
self.core = core
|
||||
self._state = PlaybackState.STOPPED
|
||||
self._shuffled = []
|
||||
self._first_shuffle = True
|
||||
@ -125,7 +126,7 @@ class PlaybackController(object):
|
||||
if self.current_cp_track is None:
|
||||
return None
|
||||
try:
|
||||
return self.backend.current_playlist.cp_tracks.index(
|
||||
return self.core.current_playlist.cp_tracks.index(
|
||||
self.current_cp_track)
|
||||
except ValueError:
|
||||
return None
|
||||
@ -152,7 +153,7 @@ class PlaybackController(object):
|
||||
# pylint: disable = R0911
|
||||
# Too many return statements
|
||||
|
||||
cp_tracks = self.backend.current_playlist.cp_tracks
|
||||
cp_tracks = self.core.current_playlist.cp_tracks
|
||||
|
||||
if not cp_tracks:
|
||||
return None
|
||||
@ -204,7 +205,7 @@ class PlaybackController(object):
|
||||
enabled this should be a random track, all tracks should be played once
|
||||
before the list repeats.
|
||||
"""
|
||||
cp_tracks = self.backend.current_playlist.cp_tracks
|
||||
cp_tracks = self.core.current_playlist.cp_tracks
|
||||
|
||||
if not cp_tracks:
|
||||
return None
|
||||
@ -258,7 +259,7 @@ class PlaybackController(object):
|
||||
if self.current_playlist_position in (None, 0):
|
||||
return None
|
||||
|
||||
return self.backend.current_playlist.cp_tracks[
|
||||
return self.core.current_playlist.cp_tracks[
|
||||
self.current_playlist_position - 1]
|
||||
|
||||
@property
|
||||
@ -291,15 +292,16 @@ class PlaybackController(object):
|
||||
@property
|
||||
def time_position(self):
|
||||
"""Time position in milliseconds."""
|
||||
return self.provider.get_time_position()
|
||||
return self.backend.playback.get_time_position().get()
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
return self.provider.get_volume()
|
||||
"""Volume as int in range [0..100]."""
|
||||
return self.backend.playback.get_volume().get()
|
||||
|
||||
@volume.setter
|
||||
def volume(self, volume):
|
||||
self.provider.set_volume(volume)
|
||||
self.backend.playback.set_volume(volume).get()
|
||||
|
||||
def change_track(self, cp_track, on_error_step=1):
|
||||
"""
|
||||
@ -337,20 +339,20 @@ class PlaybackController(object):
|
||||
self.stop(clear_current_track=True)
|
||||
|
||||
if self.consume:
|
||||
self.backend.current_playlist.remove(cpid=original_cp_track.cpid)
|
||||
self.core.current_playlist.remove(cpid=original_cp_track.cpid)
|
||||
|
||||
def on_current_playlist_change(self):
|
||||
"""
|
||||
Tell the playback controller that the current playlist has changed.
|
||||
|
||||
Used by :class:`mopidy.backends.base.CurrentPlaylistController`.
|
||||
Used by :class:`mopidy.core.CurrentPlaylistController`.
|
||||
"""
|
||||
self._first_shuffle = True
|
||||
self._shuffled = []
|
||||
|
||||
if (not self.backend.current_playlist.cp_tracks or
|
||||
if (not self.core.current_playlist.cp_tracks or
|
||||
self.current_cp_track not in
|
||||
self.backend.current_playlist.cp_tracks):
|
||||
self.core.current_playlist.cp_tracks):
|
||||
self.stop(clear_current_track=True)
|
||||
|
||||
def next(self):
|
||||
@ -368,7 +370,7 @@ class PlaybackController(object):
|
||||
|
||||
def pause(self):
|
||||
"""Pause playback."""
|
||||
if self.provider.pause():
|
||||
if self.backend.playback.pause().get():
|
||||
self.state = PlaybackState.PAUSED
|
||||
self._trigger_track_playback_paused()
|
||||
|
||||
@ -386,7 +388,7 @@ class PlaybackController(object):
|
||||
"""
|
||||
|
||||
if cp_track is not None:
|
||||
assert cp_track in self.backend.current_playlist.cp_tracks
|
||||
assert cp_track in self.core.current_playlist.cp_tracks
|
||||
elif cp_track is None:
|
||||
if self.state == PlaybackState.PAUSED:
|
||||
return self.resume()
|
||||
@ -400,7 +402,7 @@ class PlaybackController(object):
|
||||
if cp_track is not None:
|
||||
self.current_cp_track = cp_track
|
||||
self.state = PlaybackState.PLAYING
|
||||
if not self.provider.play(cp_track.track):
|
||||
if not self.backend.playback.play(cp_track.track).get():
|
||||
# Track is not playable
|
||||
if self.random and self._shuffled:
|
||||
self._shuffled.remove(cp_track)
|
||||
@ -426,7 +428,8 @@ class PlaybackController(object):
|
||||
|
||||
def resume(self):
|
||||
"""If paused, resume playing the current track."""
|
||||
if self.state == PlaybackState.PAUSED and self.provider.resume():
|
||||
if (self.state == PlaybackState.PAUSED and
|
||||
self.backend.playback.resume().get()):
|
||||
self.state = PlaybackState.PLAYING
|
||||
self._trigger_track_playback_resumed()
|
||||
|
||||
@ -438,7 +441,7 @@ class PlaybackController(object):
|
||||
:type time_position: int
|
||||
:rtype: :class:`True` if successful, else :class:`False`
|
||||
"""
|
||||
if not self.backend.current_playlist.tracks:
|
||||
if not self.core.current_playlist.tracks:
|
||||
return False
|
||||
|
||||
if self.state == PlaybackState.STOPPED:
|
||||
@ -452,7 +455,7 @@ class PlaybackController(object):
|
||||
self.next()
|
||||
return True
|
||||
|
||||
success = self.provider.seek(time_position)
|
||||
success = self.backend.playback.seek(time_position).get()
|
||||
if success:
|
||||
self._trigger_seeked(time_position)
|
||||
return success
|
||||
@ -466,7 +469,7 @@ class PlaybackController(object):
|
||||
:type clear_current_track: boolean
|
||||
"""
|
||||
if self.state != PlaybackState.STOPPED:
|
||||
if self.provider.stop():
|
||||
if self.backend.playback.stop().get():
|
||||
self._trigger_track_playback_ended()
|
||||
self.state = PlaybackState.STOPPED
|
||||
if clear_current_track:
|
||||
|
||||
@ -8,9 +8,9 @@ class StoredPlaylistsController(object):
|
||||
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, backend, provider):
|
||||
def __init__(self, backend, core):
|
||||
self.backend = backend
|
||||
self.provider = provider
|
||||
self.core = core
|
||||
|
||||
@property
|
||||
def playlists(self):
|
||||
@ -19,11 +19,11 @@ class StoredPlaylistsController(object):
|
||||
|
||||
Read/write. List of :class:`mopidy.models.Playlist`.
|
||||
"""
|
||||
return self.provider.playlists
|
||||
return self.backend.stored_playlists.playlists.get()
|
||||
|
||||
@playlists.setter
|
||||
def playlists(self, playlists):
|
||||
self.provider.playlists = playlists
|
||||
self.backend.stored_playlists.playlists = playlists
|
||||
|
||||
def create(self, name):
|
||||
"""
|
||||
@ -33,7 +33,7 @@ class StoredPlaylistsController(object):
|
||||
:type name: string
|
||||
:rtype: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.create(name)
|
||||
return self.backend.stored_playlists.create(name).get()
|
||||
|
||||
def delete(self, playlist):
|
||||
"""
|
||||
@ -42,7 +42,7 @@ class StoredPlaylistsController(object):
|
||||
:param playlist: the playlist to delete
|
||||
:type playlist: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.delete(playlist)
|
||||
return self.backend.stored_playlists.delete(playlist).get()
|
||||
|
||||
def get(self, **criteria):
|
||||
"""
|
||||
@ -83,14 +83,14 @@ class StoredPlaylistsController(object):
|
||||
:type uri: string
|
||||
:rtype: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.lookup(uri)
|
||||
return self.backend.stored_playlists.lookup(uri).get()
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
Refresh the stored playlists in
|
||||
:attr:`mopidy.backends.base.StoredPlaylistsController.playlists`.
|
||||
"""
|
||||
return self.provider.refresh()
|
||||
return self.backend.stored_playlists.refresh().get()
|
||||
|
||||
def rename(self, playlist, new_name):
|
||||
"""
|
||||
@ -101,7 +101,7 @@ class StoredPlaylistsController(object):
|
||||
:param new_name: the new name
|
||||
:type new_name: string
|
||||
"""
|
||||
return self.provider.rename(playlist, new_name)
|
||||
return self.backend.stored_playlists.rename(playlist, new_name).get()
|
||||
|
||||
def save(self, playlist):
|
||||
"""
|
||||
@ -110,4 +110,4 @@ class StoredPlaylistsController(object):
|
||||
:param playlist: the playlist
|
||||
:type playlist: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
return self.provider.save(playlist)
|
||||
return self.backend.stored_playlists.save(playlist).get()
|
||||
|
||||
@ -4,8 +4,7 @@ import re
|
||||
from pykka import ActorDeadError
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.backends.base import Backend
|
||||
from mopidy import core, settings
|
||||
from mopidy.frontends.mpd import exceptions
|
||||
from mopidy.frontends.mpd.protocol import mpd_commands, request_handlers
|
||||
# Do not remove the following import. The protocol modules must be imported to
|
||||
@ -233,16 +232,17 @@ class MpdContext(object):
|
||||
self.session = session
|
||||
self.events = set()
|
||||
self.subscriptions = set()
|
||||
self._backend = None
|
||||
self._core = None
|
||||
|
||||
@property
|
||||
def backend(self):
|
||||
"""
|
||||
The backend. An instance of :class:`mopidy.backends.base.Backend`.
|
||||
The Mopidy core. An instance of :class:`mopidy.core.Core`.
|
||||
"""
|
||||
if self._backend is None:
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) == 1, \
|
||||
'Expected exactly one running backend.'
|
||||
self._backend = backend_refs[0].proxy()
|
||||
return self._backend
|
||||
# TODO: Rename property to 'core'
|
||||
if self._core is None:
|
||||
core_refs = ActorRegistry.get_by_class(core.Core)
|
||||
assert len(core_refs) == 1, \
|
||||
'Expected exactly one running core instance.'
|
||||
self._core = core_refs[0].proxy()
|
||||
return self._core
|
||||
|
||||
@ -14,8 +14,7 @@ except ImportError as import_error:
|
||||
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.backends.base import Backend
|
||||
from mopidy import core, settings
|
||||
from mopidy.core import PlaybackState
|
||||
from mopidy.utils.process import exit_process
|
||||
|
||||
@ -35,7 +34,7 @@ class MprisObject(dbus.service.Object):
|
||||
properties = None
|
||||
|
||||
def __init__(self):
|
||||
self._backend = None
|
||||
self._core = None
|
||||
self.properties = {
|
||||
ROOT_IFACE: self._get_root_iface_properties(),
|
||||
PLAYER_IFACE: self._get_player_iface_properties(),
|
||||
@ -86,12 +85,13 @@ class MprisObject(dbus.service.Object):
|
||||
|
||||
@property
|
||||
def backend(self):
|
||||
if self._backend is None:
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) == 1, \
|
||||
'Expected exactly one running backend.'
|
||||
self._backend = backend_refs[0].proxy()
|
||||
return self._backend
|
||||
# TODO: Rename property to 'core'
|
||||
if self._core is None:
|
||||
core_refs = ActorRegistry.get_by_class(core.Core)
|
||||
assert len(core_refs) == 1, \
|
||||
'Expected exactly one running core instance.'
|
||||
self._core = core_refs[0].proxy()
|
||||
return self._core
|
||||
|
||||
def _get_track_id(self, cp_track):
|
||||
return '/com/mopidy/track/%d' % cp_track.cpid
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
def populate_playlist(func):
|
||||
def wrapper(self):
|
||||
for track in self.tracks:
|
||||
self.backend.current_playlist.add(track)
|
||||
self.core.current_playlist.add(track)
|
||||
return func(self)
|
||||
|
||||
wrapper.__name__ = func.__name__
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import mock
|
||||
import random
|
||||
|
||||
from mopidy import audio
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import audio, core
|
||||
from mopidy.core import PlaybackState
|
||||
from mopidy.models import CpTrack, Playlist, Track
|
||||
|
||||
@ -12,13 +14,17 @@ class CurrentPlaylistControllerTest(object):
|
||||
tracks = []
|
||||
|
||||
def setUp(self):
|
||||
self.backend = self.backend_class()
|
||||
self.backend.audio = mock.Mock(spec=audio.Audio)
|
||||
self.controller = self.backend.current_playlist
|
||||
self.playback = self.backend.playback
|
||||
self.audio = mock.Mock(spec=audio.Audio)
|
||||
self.backend = self.backend_class.start(audio=self.audio).proxy()
|
||||
self.core = core.Core(audio=audio, backend=self.backend)
|
||||
self.controller = self.core.current_playlist
|
||||
self.playback = self.core.playback
|
||||
|
||||
assert len(self.tracks) == 3, 'Need three tracks to run tests.'
|
||||
|
||||
def tearDown(self):
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_length(self):
|
||||
self.assertEqual(0, len(self.controller.cp_tracks))
|
||||
self.assertEqual(0, self.controller.length)
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
import mock
|
||||
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core
|
||||
from mopidy.models import Playlist, Track, Album, Artist
|
||||
|
||||
from tests import unittest, path_to_data_dir
|
||||
@ -15,8 +20,12 @@ class LibraryControllerTest(object):
|
||||
Track()]
|
||||
|
||||
def setUp(self):
|
||||
self.backend = self.backend_class()
|
||||
self.library = self.backend.library
|
||||
self.backend = self.backend_class.start(audio=None).proxy()
|
||||
self.core = core.Core(backend=self.backend)
|
||||
self.library = self.core.library
|
||||
|
||||
def tearDown(self):
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_refresh(self):
|
||||
self.library.refresh()
|
||||
|
||||
@ -2,7 +2,7 @@ import mock
|
||||
import random
|
||||
import time
|
||||
|
||||
from mopidy import audio
|
||||
from mopidy import audio, core
|
||||
from mopidy.core import PlaybackState
|
||||
from mopidy.models import Track
|
||||
|
||||
@ -16,10 +16,11 @@ class PlaybackControllerTest(object):
|
||||
tracks = []
|
||||
|
||||
def setUp(self):
|
||||
self.backend = self.backend_class()
|
||||
self.backend.audio = mock.Mock(spec=audio.Audio)
|
||||
self.playback = self.backend.playback
|
||||
self.current_playlist = self.backend.current_playlist
|
||||
self.audio = mock.Mock(spec=audio.Audio)
|
||||
self.backend = self.backend_class.start(audio=self.audio).proxy()
|
||||
self.core = core.Core(backend=self.backend)
|
||||
self.playback = self.core.playback
|
||||
self.current_playlist = self.core.current_playlist
|
||||
|
||||
assert len(self.tracks) >= 3, \
|
||||
'Need at least three tracks to run tests.'
|
||||
@ -97,8 +98,8 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_play_skips_to_next_track_on_failure(self):
|
||||
# If provider.play() returns False, it is a failure.
|
||||
self.playback.provider.play = lambda track: track != self.tracks[0]
|
||||
# If backend's play() returns False, it is a failure.
|
||||
self.backend.playback.play = lambda track: track != self.tracks[0]
|
||||
self.playback.play()
|
||||
self.assertNotEqual(self.playback.current_track, self.tracks[0])
|
||||
self.assertEqual(self.playback.current_track, self.tracks[1])
|
||||
@ -157,8 +158,8 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_previous_skips_to_previous_track_on_failure(self):
|
||||
# If provider.play() returns False, it is a failure.
|
||||
self.playback.provider.play = lambda track: track != self.tracks[1]
|
||||
# If backend's play() returns False, it is a failure.
|
||||
self.backend.playback.play = lambda track: track != self.tracks[1]
|
||||
self.playback.play(self.current_playlist.cp_tracks[2])
|
||||
self.assertEqual(self.playback.current_track, self.tracks[2])
|
||||
self.playback.previous()
|
||||
@ -221,8 +222,8 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_next_skips_to_next_track_on_failure(self):
|
||||
# If provider.play() returns False, it is a failure.
|
||||
self.playback.provider.play = lambda track: track != self.tracks[1]
|
||||
# If backend's play() returns False, it is a failure.
|
||||
self.backend.playback.play = lambda track: track != self.tracks[1]
|
||||
self.playback.play()
|
||||
self.assertEqual(self.playback.current_track, self.tracks[0])
|
||||
self.playback.next()
|
||||
@ -274,7 +275,7 @@ class PlaybackControllerTest(object):
|
||||
self.playback.consume = True
|
||||
self.playback.play()
|
||||
self.playback.next()
|
||||
self.assertIn(self.tracks[0], self.backend.current_playlist.tracks)
|
||||
self.assertIn(self.tracks[0], self.current_playlist.tracks)
|
||||
|
||||
@populate_playlist
|
||||
def test_next_with_single_and_repeat(self):
|
||||
@ -298,7 +299,7 @@ class PlaybackControllerTest(object):
|
||||
random.seed(1)
|
||||
self.playback.random = True
|
||||
self.assertEqual(self.playback.track_at_next, self.tracks[2])
|
||||
self.backend.current_playlist.append(self.tracks[:1])
|
||||
self.current_playlist.append(self.tracks[:1])
|
||||
self.assertEqual(self.playback.track_at_next, self.tracks[1])
|
||||
|
||||
@populate_playlist
|
||||
@ -357,8 +358,8 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_end_of_track_skips_to_next_track_on_failure(self):
|
||||
# If provider.play() returns False, it is a failure.
|
||||
self.playback.provider.play = lambda track: track != self.tracks[1]
|
||||
# If backend's play() returns False, it is a failure.
|
||||
self.backend.playback.play = lambda track: track != self.tracks[1]
|
||||
self.playback.play()
|
||||
self.assertEqual(self.playback.current_track, self.tracks[0])
|
||||
self.playback.on_end_of_track()
|
||||
@ -411,7 +412,7 @@ class PlaybackControllerTest(object):
|
||||
self.playback.consume = True
|
||||
self.playback.play()
|
||||
self.playback.on_end_of_track()
|
||||
self.assertNotIn(self.tracks[0], self.backend.current_playlist.tracks)
|
||||
self.assertNotIn(self.tracks[0], self.current_playlist.tracks)
|
||||
|
||||
@populate_playlist
|
||||
def test_end_of_track_with_random(self):
|
||||
@ -427,7 +428,7 @@ class PlaybackControllerTest(object):
|
||||
random.seed(1)
|
||||
self.playback.random = True
|
||||
self.assertEqual(self.playback.track_at_next, self.tracks[2])
|
||||
self.backend.current_playlist.append(self.tracks[:1])
|
||||
self.current_playlist.append(self.tracks[:1])
|
||||
self.assertEqual(self.playback.track_at_next, self.tracks[1])
|
||||
|
||||
@populate_playlist
|
||||
@ -517,7 +518,7 @@ class PlaybackControllerTest(object):
|
||||
wrapper.called = False
|
||||
|
||||
self.playback.on_current_playlist_change = wrapper
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.current_playlist.append([Track()])
|
||||
|
||||
self.assert_(wrapper.called)
|
||||
|
||||
@ -534,13 +535,13 @@ class PlaybackControllerTest(object):
|
||||
def test_on_current_playlist_change_when_playing(self):
|
||||
self.playback.play()
|
||||
current_track = self.playback.current_track
|
||||
self.backend.current_playlist.append([self.tracks[2]])
|
||||
self.current_playlist.append([self.tracks[2]])
|
||||
self.assertEqual(self.playback.state, PlaybackState.PLAYING)
|
||||
self.assertEqual(self.playback.current_track, current_track)
|
||||
|
||||
@populate_playlist
|
||||
def test_on_current_playlist_change_when_stopped(self):
|
||||
self.backend.current_playlist.append([self.tracks[2]])
|
||||
self.current_playlist.append([self.tracks[2]])
|
||||
self.assertEqual(self.playback.state, PlaybackState.STOPPED)
|
||||
self.assertEqual(self.playback.current_track, None)
|
||||
|
||||
@ -549,7 +550,7 @@ class PlaybackControllerTest(object):
|
||||
self.playback.play()
|
||||
self.playback.pause()
|
||||
current_track = self.playback.current_track
|
||||
self.backend.current_playlist.append([self.tracks[2]])
|
||||
self.current_playlist.append([self.tracks[2]])
|
||||
self.assertEqual(self.playback.state, PlaybackState.PAUSED)
|
||||
self.assertEqual(self.playback.current_track, current_track)
|
||||
|
||||
@ -640,7 +641,7 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_seek_when_playing_updates_position(self):
|
||||
length = self.backend.current_playlist.tracks[0].length
|
||||
length = self.current_playlist.tracks[0].length
|
||||
self.playback.play()
|
||||
self.playback.seek(length - 1000)
|
||||
position = self.playback.time_position
|
||||
@ -655,7 +656,7 @@ class PlaybackControllerTest(object):
|
||||
|
||||
@populate_playlist
|
||||
def test_seek_when_paused_updates_position(self):
|
||||
length = self.backend.current_playlist.tracks[0].length
|
||||
length = self.current_playlist.tracks[0].length
|
||||
self.playback.play()
|
||||
self.playback.pause()
|
||||
self.playback.seek(length - 1000)
|
||||
@ -730,7 +731,7 @@ class PlaybackControllerTest(object):
|
||||
def test_time_position_when_stopped(self):
|
||||
future = mock.Mock()
|
||||
future.get = mock.Mock(return_value=0)
|
||||
self.backend.audio.get_position = mock.Mock(return_value=future)
|
||||
self.audio.get_position = mock.Mock(return_value=future)
|
||||
|
||||
self.assertEqual(self.playback.time_position, 0)
|
||||
|
||||
@ -738,7 +739,7 @@ class PlaybackControllerTest(object):
|
||||
def test_time_position_when_stopped_with_playlist(self):
|
||||
future = mock.Mock()
|
||||
future.get = mock.Mock(return_value=0)
|
||||
self.backend.audio.get_position = mock.Mock(return_value=future)
|
||||
self.audio.get_position = mock.Mock(return_value=future)
|
||||
|
||||
self.assertEqual(self.playback.time_position, 0)
|
||||
|
||||
@ -772,9 +773,9 @@ class PlaybackControllerTest(object):
|
||||
def test_playlist_is_empty_after_all_tracks_are_played_with_consume(self):
|
||||
self.playback.consume = True
|
||||
self.playback.play()
|
||||
for _ in range(len(self.backend.current_playlist.tracks)):
|
||||
for _ in range(len(self.current_playlist.tracks)):
|
||||
self.playback.on_end_of_track()
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks), 0)
|
||||
self.assertEqual(len(self.current_playlist.tracks), 0)
|
||||
|
||||
@populate_playlist
|
||||
def test_play_with_random(self):
|
||||
|
||||
@ -2,7 +2,9 @@ import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from mopidy import settings
|
||||
import mock
|
||||
|
||||
from mopidy import audio, core, settings
|
||||
from mopidy.models import Playlist
|
||||
|
||||
from tests import unittest, path_to_data_dir
|
||||
@ -14,8 +16,10 @@ class StoredPlaylistsControllerTest(object):
|
||||
settings.LOCAL_TAG_CACHE_FILE = path_to_data_dir('library_tag_cache')
|
||||
settings.LOCAL_MUSIC_PATH = path_to_data_dir('')
|
||||
|
||||
self.backend = self.backend_class()
|
||||
self.stored = self.backend.stored_playlists
|
||||
self.audio = mock.Mock(spec=audio.Audio)
|
||||
self.backend = self.backend_class.start(audio=self.audio).proxy()
|
||||
self.core = core.Core(backend=self.backend)
|
||||
self.stored = self.core.stored_playlists
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(settings.LOCAL_PLAYLIST_PATH):
|
||||
|
||||
@ -2,7 +2,8 @@ import mock
|
||||
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy.backends.dummy import DummyBackend
|
||||
from mopidy import audio, core
|
||||
from mopidy.backends import dummy
|
||||
from mopidy.listeners import BackendListener
|
||||
from mopidy.models import Track
|
||||
|
||||
@ -12,42 +13,44 @@ from tests import unittest
|
||||
@mock.patch.object(BackendListener, 'send')
|
||||
class BackendEventsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.backend = DummyBackend.start().proxy()
|
||||
self.audio = mock.Mock(spec=audio.Audio)
|
||||
self.backend = dummy.DummyBackend.start(audio=audio).proxy()
|
||||
self.core = core.Core.start(backend=self.backend).proxy()
|
||||
|
||||
def tearDown(self):
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_pause_sends_track_playback_paused_event(self, send):
|
||||
self.backend.current_playlist.add(Track(uri='a'))
|
||||
self.backend.playback.play().get()
|
||||
self.core.current_playlist.add(Track(uri='a'))
|
||||
self.core.playback.play().get()
|
||||
send.reset_mock()
|
||||
self.backend.playback.pause().get()
|
||||
self.core.playback.pause().get()
|
||||
self.assertEqual(send.call_args[0][0], 'track_playback_paused')
|
||||
|
||||
def test_resume_sends_track_playback_resumed(self, send):
|
||||
self.backend.current_playlist.add(Track(uri='a'))
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.pause().get()
|
||||
self.core.current_playlist.add(Track(uri='a'))
|
||||
self.core.playback.play()
|
||||
self.core.playback.pause().get()
|
||||
send.reset_mock()
|
||||
self.backend.playback.resume().get()
|
||||
self.core.playback.resume().get()
|
||||
self.assertEqual(send.call_args[0][0], 'track_playback_resumed')
|
||||
|
||||
def test_play_sends_track_playback_started_event(self, send):
|
||||
self.backend.current_playlist.add(Track(uri='a'))
|
||||
self.core.current_playlist.add(Track(uri='a'))
|
||||
send.reset_mock()
|
||||
self.backend.playback.play().get()
|
||||
self.core.playback.play().get()
|
||||
self.assertEqual(send.call_args[0][0], 'track_playback_started')
|
||||
|
||||
def test_stop_sends_track_playback_ended_event(self, send):
|
||||
self.backend.current_playlist.add(Track(uri='a'))
|
||||
self.backend.playback.play().get()
|
||||
self.core.current_playlist.add(Track(uri='a'))
|
||||
self.core.playback.play().get()
|
||||
send.reset_mock()
|
||||
self.backend.playback.stop().get()
|
||||
self.core.playback.stop().get()
|
||||
self.assertEqual(send.call_args_list[0][0][0], 'track_playback_ended')
|
||||
|
||||
def test_seek_sends_seeked_event(self, send):
|
||||
self.backend.current_playlist.add(Track(uri='a', length=40000))
|
||||
self.backend.playback.play().get()
|
||||
self.core.current_playlist.add(Track(uri='a', length=40000))
|
||||
self.core.playback.play().get()
|
||||
send.reset_mock()
|
||||
self.backend.playback.seek(1000).get()
|
||||
self.core.playback.seek(1000).get()
|
||||
self.assertEqual(send.call_args[0][0], 'seeked')
|
||||
|
||||
@ -20,10 +20,7 @@ class LocalPlaybackControllerTest(PlaybackControllerTest, unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
settings.BACKENDS = ('mopidy.backends.local.LocalBackend',)
|
||||
|
||||
super(LocalPlaybackControllerTest, self).setUp()
|
||||
# Two tests does not work at all when using the fake sink
|
||||
#self.backend.playback.use_fake_sink()
|
||||
|
||||
def tearDown(self):
|
||||
super(LocalPlaybackControllerTest, self).tearDown()
|
||||
@ -32,10 +29,10 @@ class LocalPlaybackControllerTest(PlaybackControllerTest, unittest.TestCase):
|
||||
def add_track(self, path):
|
||||
uri = path_to_uri(path_to_data_dir(path))
|
||||
track = Track(uri=uri, length=4464)
|
||||
self.backend.current_playlist.add(track)
|
||||
self.current_playlist.add(track)
|
||||
|
||||
def test_uri_scheme(self):
|
||||
self.assertIn('file', self.backend.uri_schemes)
|
||||
self.assertIn('file', self.core.uri_schemes)
|
||||
|
||||
def test_play_mp3(self):
|
||||
self.add_track('blank.mp3')
|
||||
|
||||
@ -65,8 +65,7 @@ class LocalStoredPlaylistsControllerTest(StoredPlaylistsControllerTest,
|
||||
|
||||
self.stored.save(playlist)
|
||||
|
||||
self.backend = self.backend_class()
|
||||
self.stored = self.backend.stored_playlists
|
||||
self.backend = self.backend_class.start(audio=self.audio).proxy()
|
||||
|
||||
self.assert_(self.stored.playlists)
|
||||
self.assertEqual('test', self.stored.playlists[0].name)
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
from mopidy.backends.dummy import DummyBackend
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core
|
||||
from mopidy.backends import dummy
|
||||
from mopidy.frontends.mpd.dispatcher import MpdDispatcher
|
||||
from mopidy.frontends.mpd.exceptions import MpdAckError
|
||||
from mopidy.frontends.mpd.protocol import request_handlers, handle_request
|
||||
@ -8,11 +11,12 @@ from tests import unittest
|
||||
|
||||
class MpdDispatcherTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.backend = DummyBackend.start().proxy()
|
||||
self.backend = dummy.DummyBackend.start(audio=None).proxy()
|
||||
self.core = core.Core.start(backend=self.backend).proxy()
|
||||
self.dispatcher = MpdDispatcher()
|
||||
|
||||
def tearDown(self):
|
||||
self.backend.stop().get()
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_register_same_pattern_twice_fails(self):
|
||||
func = lambda: None
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import mock
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.backends import dummy as backend
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core, settings
|
||||
from mopidy.backends import dummy
|
||||
from mopidy.frontends import mpd
|
||||
|
||||
from tests import unittest
|
||||
@ -21,7 +23,8 @@ class MockConnection(mock.Mock):
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.backend = backend.DummyBackend.start().proxy()
|
||||
self.backend = dummy.DummyBackend.start(audio=None).proxy()
|
||||
self.core = core.Core.start(backend=self.backend).proxy()
|
||||
|
||||
self.connection = MockConnection()
|
||||
self.session = mpd.MpdSession(self.connection)
|
||||
@ -29,7 +32,7 @@ class BaseTestCase(unittest.TestCase):
|
||||
self.context = self.dispatcher.context
|
||||
|
||||
def tearDown(self):
|
||||
self.backend.stop().get()
|
||||
ActorRegistry.stop_all()
|
||||
settings.runtime.clear()
|
||||
|
||||
def sendRequest(self, request):
|
||||
|
||||
@ -6,15 +6,15 @@ from tests.frontends.mpd import protocol
|
||||
class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
def test_add(self):
|
||||
needle = Track(uri='dummy://foo')
|
||||
self.backend.library.provider.dummy_library = [
|
||||
self.backend.library.dummy_library = [
|
||||
Track(), Track(), needle, Track()]
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'add "dummy://foo"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.backend.current_playlist.tracks.get()[5], needle)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.core.current_playlist.tracks.get()[5], needle)
|
||||
self.assertEqualResponse(u'OK')
|
||||
|
||||
def test_add_with_uri_not_found_in_library_should_ack(self):
|
||||
@ -29,17 +29,17 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_addid_without_songpos(self):
|
||||
needle = Track(uri='dummy://foo')
|
||||
self.backend.library.provider.dummy_library = [
|
||||
self.backend.library.dummy_library = [
|
||||
Track(), Track(), needle, Track()]
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'addid "dummy://foo"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.backend.current_playlist.tracks.get()[5], needle)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.core.current_playlist.tracks.get()[5], needle)
|
||||
self.assertInResponse(u'Id: %d' %
|
||||
self.backend.current_playlist.cp_tracks.get()[5][0])
|
||||
self.core.current_playlist.cp_tracks.get()[5][0])
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_addid_with_empty_uri_acks(self):
|
||||
@ -48,26 +48,26 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_addid_with_songpos(self):
|
||||
needle = Track(uri='dummy://foo')
|
||||
self.backend.library.provider.dummy_library = [
|
||||
self.backend.library.dummy_library = [
|
||||
Track(), Track(), needle, Track()]
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'addid "dummy://foo" "3"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.backend.current_playlist.tracks.get()[3], needle)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 6)
|
||||
self.assertEqual(self.core.current_playlist.tracks.get()[3], needle)
|
||||
self.assertInResponse(u'Id: %d' %
|
||||
self.backend.current_playlist.cp_tracks.get()[3][0])
|
||||
self.core.current_playlist.cp_tracks.get()[3][0])
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_addid_with_songpos_out_of_bounds_should_ack(self):
|
||||
needle = Track(uri='dummy://foo')
|
||||
self.backend.library.provider.dummy_library = [
|
||||
self.backend.library.dummy_library = [
|
||||
Track(), Track(), needle, Track()]
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'addid "dummy://foo" "6"')
|
||||
self.assertEqualResponse(u'ACK [2@0] {addid} Bad song index')
|
||||
@ -77,85 +77,85 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqualResponse(u'ACK [50@0] {addid} No such song')
|
||||
|
||||
def test_clear(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'clear')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 0)
|
||||
self.assertEqual(self.backend.playback.current_track.get(), None)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 0)
|
||||
self.assertEqual(self.core.playback.current_track.get(), None)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_delete_songpos(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'delete "%d"' %
|
||||
self.backend.current_playlist.cp_tracks.get()[2][0])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 4)
|
||||
self.core.current_playlist.cp_tracks.get()[2][0])
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 4)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_delete_songpos_out_of_bounds(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'delete "5"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
self.assertEqualResponse(u'ACK [2@0] {delete} Bad song index')
|
||||
|
||||
def test_delete_open_range(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'delete "1:"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 1)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 1)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_delete_closed_range(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'delete "1:3"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 3)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 3)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_delete_range_out_of_bounds(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(), Track(), Track(), Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
|
||||
self.sendRequest(u'delete "5:7"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 5)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 5)
|
||||
self.assertEqualResponse(u'ACK [2@0] {delete} Bad song index')
|
||||
|
||||
def test_deleteid(self):
|
||||
self.backend.current_playlist.append([Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 2)
|
||||
self.core.current_playlist.append([Track(), Track()])
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 2)
|
||||
|
||||
self.sendRequest(u'deleteid "1"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 1)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 1)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_deleteid_does_not_exist(self):
|
||||
self.backend.current_playlist.append([Track(), Track()])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 2)
|
||||
self.core.current_playlist.append([Track(), Track()])
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 2)
|
||||
|
||||
self.sendRequest(u'deleteid "12345"')
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 2)
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 2)
|
||||
self.assertEqualResponse(u'ACK [50@0] {deleteid} No such song')
|
||||
|
||||
def test_move_songpos(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'move "1" "0"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'b')
|
||||
self.assertEqual(tracks[1].name, 'a')
|
||||
self.assertEqual(tracks[2].name, 'c')
|
||||
@ -165,13 +165,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_move_open_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'move "2:" "0"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'c')
|
||||
self.assertEqual(tracks[1].name, 'd')
|
||||
self.assertEqual(tracks[2].name, 'e')
|
||||
@ -181,13 +181,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_move_closed_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'move "1:3" "0"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'b')
|
||||
self.assertEqual(tracks[1].name, 'c')
|
||||
self.assertEqual(tracks[2].name, 'a')
|
||||
@ -197,13 +197,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_moveid(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'moveid "4" "2"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'a')
|
||||
self.assertEqual(tracks[1].name, 'b')
|
||||
self.assertEqual(tracks[2].name, 'e')
|
||||
@ -230,7 +230,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqualResponse(u'OK')
|
||||
|
||||
def test_playlistfind_by_filename_in_current_playlist(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(uri='file:///exists')])
|
||||
|
||||
self.sendRequest( u'playlistfind filename "file:///exists"')
|
||||
@ -240,7 +240,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playlistid_without_songid(self):
|
||||
self.backend.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
self.core.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
|
||||
self.sendRequest(u'playlistid')
|
||||
self.assertInResponse(u'Title: a')
|
||||
@ -248,7 +248,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playlistid_with_songid(self):
|
||||
self.backend.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
self.core.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
|
||||
self.sendRequest(u'playlistid "1"')
|
||||
self.assertNotInResponse(u'Title: a')
|
||||
@ -258,13 +258,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playlistid_with_not_existing_songid_fails(self):
|
||||
self.backend.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
self.core.current_playlist.append([Track(name='a'), Track(name='b')])
|
||||
|
||||
self.sendRequest(u'playlistid "25"')
|
||||
self.assertEqualResponse(u'ACK [50@0] {playlistid} No such song')
|
||||
|
||||
def test_playlistinfo_without_songpos_or_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
@ -286,8 +286,8 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_playlistinfo_with_songpos(self):
|
||||
# Make the track's CPID not match the playlist position
|
||||
self.backend.current_playlist.cp_id = 17
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.cp_id = 17
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
@ -313,7 +313,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqual(response1, response2)
|
||||
|
||||
def test_playlistinfo_with_open_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
@ -334,7 +334,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playlistinfo_with_closed_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
@ -365,7 +365,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqualResponse(u'ACK [0@0] {} Not implemented')
|
||||
|
||||
def test_plchanges(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(name='a'), Track(name='b'), Track(name='c')])
|
||||
|
||||
self.sendRequest(u'plchanges "0"')
|
||||
@ -375,7 +375,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_plchanges_with_minus_one_returns_entire_playlist(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(name='a'), Track(name='b'), Track(name='c')])
|
||||
|
||||
self.sendRequest(u'plchanges "-1"')
|
||||
@ -385,7 +385,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_plchanges_without_quotes_works(self):
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(name='a'), Track(name='b'), Track(name='c')])
|
||||
|
||||
self.sendRequest(u'plchanges 0')
|
||||
@ -395,10 +395,10 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_plchangesposid(self):
|
||||
self.backend.current_playlist.append([Track(), Track(), Track()])
|
||||
self.core.current_playlist.append([Track(), Track(), Track()])
|
||||
|
||||
self.sendRequest(u'plchangesposid "0"')
|
||||
cp_tracks = self.backend.current_playlist.cp_tracks.get()
|
||||
cp_tracks = self.core.current_playlist.cp_tracks.get()
|
||||
self.assertInResponse(u'cpos: 0')
|
||||
self.assertInResponse(u'Id: %d' % cp_tracks[0][0])
|
||||
self.assertInResponse(u'cpos: 2')
|
||||
@ -408,26 +408,26 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_shuffle_without_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
version = self.backend.current_playlist.version.get()
|
||||
version = self.core.current_playlist.version.get()
|
||||
|
||||
self.sendRequest(u'shuffle')
|
||||
self.assertLess(version, self.backend.current_playlist.version.get())
|
||||
self.assertLess(version, self.core.current_playlist.version.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_shuffle_with_open_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
version = self.backend.current_playlist.version.get()
|
||||
version = self.core.current_playlist.version.get()
|
||||
|
||||
self.sendRequest(u'shuffle "4:"')
|
||||
self.assertLess(version, self.backend.current_playlist.version.get())
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
self.assertLess(version, self.core.current_playlist.version.get())
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'a')
|
||||
self.assertEqual(tracks[1].name, 'b')
|
||||
self.assertEqual(tracks[2].name, 'c')
|
||||
@ -435,15 +435,15 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_shuffle_with_closed_range(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
version = self.backend.current_playlist.version.get()
|
||||
version = self.core.current_playlist.version.get()
|
||||
|
||||
self.sendRequest(u'shuffle "1:3"')
|
||||
self.assertLess(version, self.backend.current_playlist.version.get())
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
self.assertLess(version, self.core.current_playlist.version.get())
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'a')
|
||||
self.assertEqual(tracks[3].name, 'd')
|
||||
self.assertEqual(tracks[4].name, 'e')
|
||||
@ -451,13 +451,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_swap(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'swap "1" "4"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'a')
|
||||
self.assertEqual(tracks[1].name, 'e')
|
||||
self.assertEqual(tracks[2].name, 'c')
|
||||
@ -467,13 +467,13 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_swapid(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(name='a'), Track(name='b'), Track(name='c'),
|
||||
Track(name='d'), Track(name='e'), Track(name='f'),
|
||||
])
|
||||
|
||||
self.sendRequest(u'swapid "1" "4"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(tracks[0].name, 'a')
|
||||
self.assertEqual(tracks[1].name, 'e')
|
||||
self.assertEqual(tracks[2].name, 'c')
|
||||
|
||||
@ -13,22 +13,22 @@ STOPPED = PlaybackState.STOPPED
|
||||
class PlaybackOptionsHandlerTest(protocol.BaseTestCase):
|
||||
def test_consume_off(self):
|
||||
self.sendRequest(u'consume "0"')
|
||||
self.assertFalse(self.backend.playback.consume.get())
|
||||
self.assertFalse(self.core.playback.consume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_consume_off_without_quotes(self):
|
||||
self.sendRequest(u'consume 0')
|
||||
self.assertFalse(self.backend.playback.consume.get())
|
||||
self.assertFalse(self.core.playback.consume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_consume_on(self):
|
||||
self.sendRequest(u'consume "1"')
|
||||
self.assertTrue(self.backend.playback.consume.get())
|
||||
self.assertTrue(self.core.playback.consume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_consume_on_without_quotes(self):
|
||||
self.sendRequest(u'consume 1')
|
||||
self.assertTrue(self.backend.playback.consume.get())
|
||||
self.assertTrue(self.core.playback.consume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_crossfade(self):
|
||||
@ -37,97 +37,97 @@ class PlaybackOptionsHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_random_off(self):
|
||||
self.sendRequest(u'random "0"')
|
||||
self.assertFalse(self.backend.playback.random.get())
|
||||
self.assertFalse(self.core.playback.random.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_random_off_without_quotes(self):
|
||||
self.sendRequest(u'random 0')
|
||||
self.assertFalse(self.backend.playback.random.get())
|
||||
self.assertFalse(self.core.playback.random.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_random_on(self):
|
||||
self.sendRequest(u'random "1"')
|
||||
self.assertTrue(self.backend.playback.random.get())
|
||||
self.assertTrue(self.core.playback.random.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_random_on_without_quotes(self):
|
||||
self.sendRequest(u'random 1')
|
||||
self.assertTrue(self.backend.playback.random.get())
|
||||
self.assertTrue(self.core.playback.random.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_repeat_off(self):
|
||||
self.sendRequest(u'repeat "0"')
|
||||
self.assertFalse(self.backend.playback.repeat.get())
|
||||
self.assertFalse(self.core.playback.repeat.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_repeat_off_without_quotes(self):
|
||||
self.sendRequest(u'repeat 0')
|
||||
self.assertFalse(self.backend.playback.repeat.get())
|
||||
self.assertFalse(self.core.playback.repeat.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_repeat_on(self):
|
||||
self.sendRequest(u'repeat "1"')
|
||||
self.assertTrue(self.backend.playback.repeat.get())
|
||||
self.assertTrue(self.core.playback.repeat.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_repeat_on_without_quotes(self):
|
||||
self.sendRequest(u'repeat 1')
|
||||
self.assertTrue(self.backend.playback.repeat.get())
|
||||
self.assertTrue(self.core.playback.repeat.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_below_min(self):
|
||||
self.sendRequest(u'setvol "-10"')
|
||||
self.assertEqual(0, self.backend.playback.volume.get())
|
||||
self.assertEqual(0, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_min(self):
|
||||
self.sendRequest(u'setvol "0"')
|
||||
self.assertEqual(0, self.backend.playback.volume.get())
|
||||
self.assertEqual(0, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_middle(self):
|
||||
self.sendRequest(u'setvol "50"')
|
||||
self.assertEqual(50, self.backend.playback.volume.get())
|
||||
self.assertEqual(50, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_max(self):
|
||||
self.sendRequest(u'setvol "100"')
|
||||
self.assertEqual(100, self.backend.playback.volume.get())
|
||||
self.assertEqual(100, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_above_max(self):
|
||||
self.sendRequest(u'setvol "110"')
|
||||
self.assertEqual(100, self.backend.playback.volume.get())
|
||||
self.assertEqual(100, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_plus_is_ignored(self):
|
||||
self.sendRequest(u'setvol "+10"')
|
||||
self.assertEqual(10, self.backend.playback.volume.get())
|
||||
self.assertEqual(10, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_setvol_without_quotes(self):
|
||||
self.sendRequest(u'setvol 50')
|
||||
self.assertEqual(50, self.backend.playback.volume.get())
|
||||
self.assertEqual(50, self.core.playback.volume.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_single_off(self):
|
||||
self.sendRequest(u'single "0"')
|
||||
self.assertFalse(self.backend.playback.single.get())
|
||||
self.assertFalse(self.core.playback.single.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_single_off_without_quotes(self):
|
||||
self.sendRequest(u'single 0')
|
||||
self.assertFalse(self.backend.playback.single.get())
|
||||
self.assertFalse(self.core.playback.single.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_single_on(self):
|
||||
self.sendRequest(u'single "1"')
|
||||
self.assertTrue(self.backend.playback.single.get())
|
||||
self.assertTrue(self.core.playback.single.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_single_on_without_quotes(self):
|
||||
self.sendRequest(u'single 1')
|
||||
self.assertTrue(self.backend.playback.single.get())
|
||||
self.assertTrue(self.core.playback.single.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_replay_gain_mode_off(self):
|
||||
@ -166,198 +166,198 @@ class PlaybackControlHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_pause_off(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'play "0"')
|
||||
self.sendRequest(u'pause "1"')
|
||||
self.sendRequest(u'pause "0"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_pause_on(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'play "0"')
|
||||
self.sendRequest(u'pause "1"')
|
||||
self.assertEqual(PAUSED, self.backend.playback.state.get())
|
||||
self.assertEqual(PAUSED, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_pause_toggle(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'play "0"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
self.sendRequest(u'pause')
|
||||
self.assertEqual(PAUSED, self.backend.playback.state.get())
|
||||
self.assertEqual(PAUSED, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
self.sendRequest(u'pause')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_without_pos(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.backend.playback.state = PAUSED
|
||||
self.core.current_playlist.append([Track()])
|
||||
self.core.playback.state = PAUSED
|
||||
|
||||
self.sendRequest(u'play')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_with_pos(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'play "0"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_with_pos_without_quotes(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'play 0')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_with_pos_out_of_bounds(self):
|
||||
self.backend.current_playlist.append([])
|
||||
self.core.current_playlist.append([])
|
||||
|
||||
self.sendRequest(u'play "0"')
|
||||
self.assertEqual(STOPPED, self.backend.playback.state.get())
|
||||
self.assertEqual(STOPPED, self.core.playback.state.get())
|
||||
self.assertInResponse(u'ACK [2@0] {play} Bad song index')
|
||||
|
||||
def test_play_minus_one_plays_first_in_playlist_if_no_current_track(self):
|
||||
self.assertEqual(self.backend.playback.current_track.get(), None)
|
||||
self.backend.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.core.playback.current_track.get(), None)
|
||||
self.core.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
|
||||
self.sendRequest(u'play "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual('a', self.backend.playback.current_track.get().uri)
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertEqual('a', self.core.playback.current_track.get().uri)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_minus_one_plays_current_track_if_current_track_is_set(self):
|
||||
self.backend.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.backend.playback.current_track.get(), None)
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.next()
|
||||
self.backend.playback.stop()
|
||||
self.assertNotEqual(self.backend.playback.current_track.get(), None)
|
||||
self.core.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.core.playback.current_track.get(), None)
|
||||
self.core.playback.play()
|
||||
self.core.playback.next()
|
||||
self.core.playback.stop()
|
||||
self.assertNotEqual(self.core.playback.current_track.get(), None)
|
||||
|
||||
self.sendRequest(u'play "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual('b', self.backend.playback.current_track.get().uri)
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertEqual('b', self.core.playback.current_track.get().uri)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_minus_one_on_empty_playlist_does_not_ack(self):
|
||||
self.backend.current_playlist.clear()
|
||||
self.core.current_playlist.clear()
|
||||
|
||||
self.sendRequest(u'play "-1"')
|
||||
self.assertEqual(STOPPED, self.backend.playback.state.get())
|
||||
self.assertEqual(None, self.backend.playback.current_track.get())
|
||||
self.assertEqual(STOPPED, self.core.playback.state.get())
|
||||
self.assertEqual(None, self.core.playback.current_track.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_minus_is_ignored_if_playing(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.backend.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
self.core.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertEquals(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEquals(PLAYING, self.core.playback.state.get())
|
||||
|
||||
self.sendRequest(u'play "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_play_minus_one_resumes_if_paused(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.backend.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
self.core.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertEquals(PLAYING, self.backend.playback.state.get())
|
||||
self.backend.playback.pause()
|
||||
self.assertEquals(PAUSED, self.backend.playback.state.get())
|
||||
self.assertEquals(PLAYING, self.core.playback.state.get())
|
||||
self.core.playback.pause()
|
||||
self.assertEquals(PAUSED, self.core.playback.state.get())
|
||||
|
||||
self.sendRequest(u'play "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'playid "0"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_without_quotes(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'playid 0')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_minus_one_plays_first_in_playlist_if_no_current_track(self):
|
||||
self.assertEqual(self.backend.playback.current_track.get(), None)
|
||||
self.backend.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.core.playback.current_track.get(), None)
|
||||
self.core.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
|
||||
self.sendRequest(u'playid "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual('a', self.backend.playback.current_track.get().uri)
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertEqual('a', self.core.playback.current_track.get().uri)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_minus_one_plays_current_track_if_current_track_is_set(self):
|
||||
self.backend.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.backend.playback.current_track.get(), None)
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.next()
|
||||
self.backend.playback.stop()
|
||||
self.assertNotEqual(None, self.backend.playback.current_track.get())
|
||||
self.core.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(self.core.playback.current_track.get(), None)
|
||||
self.core.playback.play()
|
||||
self.core.playback.next()
|
||||
self.core.playback.stop()
|
||||
self.assertNotEqual(None, self.core.playback.current_track.get())
|
||||
|
||||
self.sendRequest(u'playid "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEqual('b', self.backend.playback.current_track.get().uri)
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertEqual('b', self.core.playback.current_track.get().uri)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_minus_one_on_empty_playlist_does_not_ack(self):
|
||||
self.backend.current_playlist.clear()
|
||||
self.core.current_playlist.clear()
|
||||
|
||||
self.sendRequest(u'playid "-1"')
|
||||
self.assertEqual(STOPPED, self.backend.playback.state.get())
|
||||
self.assertEqual(None, self.backend.playback.current_track.get())
|
||||
self.assertEqual(STOPPED, self.core.playback.state.get())
|
||||
self.assertEqual(None, self.core.playback.current_track.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_minus_is_ignored_if_playing(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.backend.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
self.core.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertEquals(PLAYING, self.backend.playback.state.get())
|
||||
self.assertEquals(PLAYING, self.core.playback.state.get())
|
||||
|
||||
self.sendRequest(u'playid "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_minus_one_resumes_if_paused(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.backend.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
self.core.playback.seek(30000)
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertEquals(PLAYING, self.backend.playback.state.get())
|
||||
self.backend.playback.pause()
|
||||
self.assertEquals(PAUSED, self.backend.playback.state.get())
|
||||
self.assertEquals(PLAYING, self.core.playback.state.get())
|
||||
self.core.playback.pause()
|
||||
self.assertEquals(PAUSED, self.core.playback.state.get())
|
||||
|
||||
self.sendRequest(u'playid "-1"')
|
||||
self.assertEqual(PLAYING, self.backend.playback.state.get())
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertEqual(PLAYING, self.core.playback.state.get())
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_playid_which_does_not_exist(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.core.current_playlist.append([Track()])
|
||||
|
||||
self.sendRequest(u'playid "12345"')
|
||||
self.assertInResponse(u'ACK [50@0] {playid} No such song')
|
||||
@ -367,49 +367,49 @@ class PlaybackControlHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_seek(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
|
||||
self.sendRequest(u'seek "0"')
|
||||
self.sendRequest(u'seek "0" "30"')
|
||||
self.assertGreaterEqual(self.backend.playback.time_position, 30000)
|
||||
self.assertGreaterEqual(self.core.playback.time_position, 30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_seek_with_songpos(self):
|
||||
seek_track = Track(uri='2', length=40000)
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(uri='1', length=40000), seek_track])
|
||||
|
||||
self.sendRequest(u'seek "1" "30"')
|
||||
self.assertEqual(self.backend.playback.current_track.get(), seek_track)
|
||||
self.assertEqual(self.core.playback.current_track.get(), seek_track)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_seek_without_quotes(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
|
||||
self.sendRequest(u'seek 0')
|
||||
self.sendRequest(u'seek 0 30')
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_seekid(self):
|
||||
self.backend.current_playlist.append([Track(length=40000)])
|
||||
self.core.current_playlist.append([Track(length=40000)])
|
||||
self.sendRequest(u'seekid "0" "30"')
|
||||
self.assertGreaterEqual(self.backend.playback.time_position.get(),
|
||||
self.assertGreaterEqual(self.core.playback.time_position.get(),
|
||||
30000)
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_seekid_with_cpid(self):
|
||||
seek_track = Track(uri='2', length=40000)
|
||||
self.backend.current_playlist.append(
|
||||
self.core.current_playlist.append(
|
||||
[Track(length=40000), seek_track])
|
||||
|
||||
self.sendRequest(u'seekid "1" "30"')
|
||||
self.assertEqual(1, self.backend.playback.current_cpid.get())
|
||||
self.assertEqual(seek_track, self.backend.playback.current_track.get())
|
||||
self.assertEqual(1, self.core.playback.current_cpid.get())
|
||||
self.assertEqual(seek_track, self.core.playback.current_track.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_stop(self):
|
||||
self.sendRequest(u'stop')
|
||||
self.assertEqual(STOPPED, self.backend.playback.state.get())
|
||||
self.assertEqual(STOPPED, self.core.playback.state.get())
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
@ -16,23 +16,23 @@ class IssueGH17RegressionTest(protocol.BaseTestCase):
|
||||
- Press next until you get to the unplayable track
|
||||
"""
|
||||
def test(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(uri='a'), Track(uri='b'), None,
|
||||
Track(uri='d'), Track(uri='e'), Track(uri='f')])
|
||||
random.seed(1) # Playlist order: abcfde
|
||||
|
||||
self.sendRequest(u'play')
|
||||
self.assertEquals('a', self.backend.playback.current_track.get().uri)
|
||||
self.assertEquals('a', self.core.playback.current_track.get().uri)
|
||||
self.sendRequest(u'random "1"')
|
||||
self.sendRequest(u'next')
|
||||
self.assertEquals('b', self.backend.playback.current_track.get().uri)
|
||||
self.assertEquals('b', self.core.playback.current_track.get().uri)
|
||||
self.sendRequest(u'next')
|
||||
# Should now be at track 'c', but playback fails and it skips ahead
|
||||
self.assertEquals('f', self.backend.playback.current_track.get().uri)
|
||||
self.assertEquals('f', self.core.playback.current_track.get().uri)
|
||||
self.sendRequest(u'next')
|
||||
self.assertEquals('d', self.backend.playback.current_track.get().uri)
|
||||
self.assertEquals('d', self.core.playback.current_track.get().uri)
|
||||
self.sendRequest(u'next')
|
||||
self.assertEquals('e', self.backend.playback.current_track.get().uri)
|
||||
self.assertEquals('e', self.core.playback.current_track.get().uri)
|
||||
|
||||
|
||||
class IssueGH18RegressionTest(protocol.BaseTestCase):
|
||||
@ -47,7 +47,7 @@ class IssueGH18RegressionTest(protocol.BaseTestCase):
|
||||
"""
|
||||
|
||||
def test(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(uri='a'), Track(uri='b'), Track(uri='c'),
|
||||
Track(uri='d'), Track(uri='e'), Track(uri='f')])
|
||||
random.seed(1)
|
||||
@ -59,11 +59,11 @@ class IssueGH18RegressionTest(protocol.BaseTestCase):
|
||||
self.sendRequest(u'next')
|
||||
|
||||
self.sendRequest(u'next')
|
||||
cp_track_1 = self.backend.playback.current_cp_track.get()
|
||||
cp_track_1 = self.core.playback.current_cp_track.get()
|
||||
self.sendRequest(u'next')
|
||||
cp_track_2 = self.backend.playback.current_cp_track.get()
|
||||
cp_track_2 = self.core.playback.current_cp_track.get()
|
||||
self.sendRequest(u'next')
|
||||
cp_track_3 = self.backend.playback.current_cp_track.get()
|
||||
cp_track_3 = self.core.playback.current_cp_track.get()
|
||||
|
||||
self.assertNotEqual(cp_track_1, cp_track_2)
|
||||
self.assertNotEqual(cp_track_2, cp_track_3)
|
||||
@ -83,7 +83,7 @@ class IssueGH22RegressionTest(protocol.BaseTestCase):
|
||||
"""
|
||||
|
||||
def test(self):
|
||||
self.backend.current_playlist.append([
|
||||
self.core.current_playlist.append([
|
||||
Track(uri='a'), Track(uri='b'), Track(uri='c'),
|
||||
Track(uri='d'), Track(uri='e'), Track(uri='f')])
|
||||
random.seed(1)
|
||||
@ -111,8 +111,8 @@ class IssueGH69RegressionTest(protocol.BaseTestCase):
|
||||
"""
|
||||
|
||||
def test(self):
|
||||
self.backend.stored_playlists.create('foo')
|
||||
self.backend.current_playlist.append([
|
||||
self.core.stored_playlists.create('foo')
|
||||
self.core.current_playlist.append([
|
||||
Track(uri='a'), Track(uri='b'), Track(uri='c'),
|
||||
Track(uri='d'), Track(uri='e'), Track(uri='f')])
|
||||
|
||||
@ -136,7 +136,7 @@ class IssueGH113RegressionTest(protocol.BaseTestCase):
|
||||
"""
|
||||
|
||||
def test(self):
|
||||
self.backend.stored_playlists.create(
|
||||
self.core.stored_playlists.create(
|
||||
u'all lart spotify:track:\w\{22\} pastes')
|
||||
|
||||
self.sendRequest(u'lsinfo "/"')
|
||||
|
||||
@ -10,8 +10,8 @@ class StatusHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_currentsong(self):
|
||||
track = Track()
|
||||
self.backend.current_playlist.append([track])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([track])
|
||||
self.core.playback.play()
|
||||
self.sendRequest(u'currentsong')
|
||||
self.assertInResponse(u'file: ')
|
||||
self.assertInResponse(u'Time: 0')
|
||||
|
||||
@ -7,7 +7,7 @@ from tests.frontends.mpd import protocol
|
||||
|
||||
class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
|
||||
def test_listplaylist(self):
|
||||
self.backend.stored_playlists.playlists = [
|
||||
self.core.stored_playlists.playlists = [
|
||||
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
|
||||
|
||||
self.sendRequest(u'listplaylist "name"')
|
||||
@ -19,7 +19,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqualResponse(u'ACK [50@0] {listplaylist} No such playlist')
|
||||
|
||||
def test_listplaylistinfo(self):
|
||||
self.backend.stored_playlists.playlists = [
|
||||
self.core.stored_playlists.playlists = [
|
||||
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
|
||||
|
||||
self.sendRequest(u'listplaylistinfo "name"')
|
||||
@ -35,7 +35,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_listplaylists(self):
|
||||
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
|
||||
self.backend.stored_playlists.playlists = [Playlist(name='a',
|
||||
self.core.stored_playlists.playlists = [Playlist(name='a',
|
||||
last_modified=last_modified)]
|
||||
|
||||
self.sendRequest(u'listplaylists')
|
||||
@ -45,13 +45,13 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse(u'OK')
|
||||
|
||||
def test_load_known_playlist_appends_to_current_playlist(self):
|
||||
self.backend.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(len(self.backend.current_playlist.tracks.get()), 2)
|
||||
self.backend.stored_playlists.playlists = [Playlist(name='A-list',
|
||||
self.core.current_playlist.append([Track(uri='a'), Track(uri='b')])
|
||||
self.assertEqual(len(self.core.current_playlist.tracks.get()), 2)
|
||||
self.core.stored_playlists.playlists = [Playlist(name='A-list',
|
||||
tracks=[Track(uri='c'), Track(uri='d'), Track(uri='e')])]
|
||||
|
||||
self.sendRequest(u'load "A-list"')
|
||||
tracks = self.backend.current_playlist.tracks.get()
|
||||
tracks = self.core.current_playlist.tracks.get()
|
||||
self.assertEqual(5, len(tracks))
|
||||
self.assertEqual('a', tracks[0].uri)
|
||||
self.assertEqual('b', tracks[1].uri)
|
||||
@ -62,7 +62,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
|
||||
|
||||
def test_load_unknown_playlist_acks(self):
|
||||
self.sendRequest(u'load "unknown playlist"')
|
||||
self.assertEqual(0, len(self.backend.current_playlist.tracks.get()))
|
||||
self.assertEqual(0, len(self.core.current_playlist.tracks.get()))
|
||||
self.assertEqualResponse(u'ACK [50@0] {load} No such playlist')
|
||||
|
||||
def test_playlistadd(self):
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import audio, core
|
||||
from mopidy.backends import dummy
|
||||
from mopidy.core import PlaybackState
|
||||
from mopidy.frontends.mpd import dispatcher
|
||||
@ -17,12 +20,13 @@ STOPPED = PlaybackState.STOPPED
|
||||
|
||||
class StatusHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.backend = dummy.DummyBackend.start().proxy()
|
||||
self.backend = dummy.DummyBackend.start(audio=None).proxy()
|
||||
self.core = core.Core.start(backend=self.backend).proxy()
|
||||
self.dispatcher = dispatcher.MpdDispatcher()
|
||||
self.context = self.dispatcher.context
|
||||
|
||||
def tearDown(self):
|
||||
self.backend.stop().get()
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_stats_method(self):
|
||||
result = status.stats(self.context)
|
||||
@ -47,7 +51,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertEqual(int(result['volume']), -1)
|
||||
|
||||
def test_status_method_contains_volume(self):
|
||||
self.backend.playback.volume = 17
|
||||
self.core.playback.volume = 17
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('volume', result)
|
||||
self.assertEqual(int(result['volume']), 17)
|
||||
@ -58,7 +62,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertEqual(int(result['repeat']), 0)
|
||||
|
||||
def test_status_method_contains_repeat_is_1(self):
|
||||
self.backend.playback.repeat = 1
|
||||
self.core.playback.repeat = 1
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('repeat', result)
|
||||
self.assertEqual(int(result['repeat']), 1)
|
||||
@ -69,7 +73,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertEqual(int(result['random']), 0)
|
||||
|
||||
def test_status_method_contains_random_is_1(self):
|
||||
self.backend.playback.random = 1
|
||||
self.core.playback.random = 1
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('random', result)
|
||||
self.assertEqual(int(result['random']), 1)
|
||||
@ -85,7 +89,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertEqual(int(result['consume']), 0)
|
||||
|
||||
def test_status_method_contains_consume_is_1(self):
|
||||
self.backend.playback.consume = 1
|
||||
self.core.playback.consume = 1
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('consume', result)
|
||||
self.assertEqual(int(result['consume']), 1)
|
||||
@ -106,41 +110,41 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertGreaterEqual(int(result['xfade']), 0)
|
||||
|
||||
def test_status_method_contains_state_is_play(self):
|
||||
self.backend.playback.state = PLAYING
|
||||
self.core.playback.state = PLAYING
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('state', result)
|
||||
self.assertEqual(result['state'], 'play')
|
||||
|
||||
def test_status_method_contains_state_is_stop(self):
|
||||
self.backend.playback.state = STOPPED
|
||||
self.core.playback.state = STOPPED
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('state', result)
|
||||
self.assertEqual(result['state'], 'stop')
|
||||
|
||||
def test_status_method_contains_state_is_pause(self):
|
||||
self.backend.playback.state = PLAYING
|
||||
self.backend.playback.state = PAUSED
|
||||
self.core.playback.state = PLAYING
|
||||
self.core.playback.state = PAUSED
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('state', result)
|
||||
self.assertEqual(result['state'], 'pause')
|
||||
|
||||
def test_status_method_when_playlist_loaded_contains_song(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([Track()])
|
||||
self.core.playback.play()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('song', result)
|
||||
self.assertGreaterEqual(int(result['song']), 0)
|
||||
|
||||
def test_status_method_when_playlist_loaded_contains_cpid_as_songid(self):
|
||||
self.backend.current_playlist.append([Track()])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([Track()])
|
||||
self.core.playback.play()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('songid', result)
|
||||
self.assertEqual(int(result['songid']), 0)
|
||||
|
||||
def test_status_method_when_playing_contains_time_with_no_length(self):
|
||||
self.backend.current_playlist.append([Track(length=None)])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([Track(length=None)])
|
||||
self.core.playback.play()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('time', result)
|
||||
(position, total) = result['time'].split(':')
|
||||
@ -149,8 +153,8 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertLessEqual(position, total)
|
||||
|
||||
def test_status_method_when_playing_contains_time_with_length(self):
|
||||
self.backend.current_playlist.append([Track(length=10000)])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([Track(length=10000)])
|
||||
self.core.playback.play()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('time', result)
|
||||
(position, total) = result['time'].split(':')
|
||||
@ -159,25 +163,25 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assertLessEqual(position, total)
|
||||
|
||||
def test_status_method_when_playing_contains_elapsed(self):
|
||||
self.backend.current_playlist.append([Track(length=60000)])
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.pause()
|
||||
self.backend.playback.seek(59123)
|
||||
self.core.current_playlist.append([Track(length=60000)])
|
||||
self.core.playback.play()
|
||||
self.core.playback.pause()
|
||||
self.core.playback.seek(59123)
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('elapsed', result)
|
||||
self.assertEqual(result['elapsed'], '59.123')
|
||||
|
||||
def test_status_method_when_starting_playing_contains_elapsed_zero(self):
|
||||
self.backend.current_playlist.append([Track(length=10000)])
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.pause()
|
||||
self.core.current_playlist.append([Track(length=10000)])
|
||||
self.core.playback.play()
|
||||
self.core.playback.pause()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('elapsed', result)
|
||||
self.assertEqual(result['elapsed'], '0.000')
|
||||
|
||||
def test_status_method_when_playing_contains_bitrate(self):
|
||||
self.backend.current_playlist.append([Track(bitrate=320)])
|
||||
self.backend.playback.play()
|
||||
self.core.current_playlist.append([Track(bitrate=320)])
|
||||
self.core.playback.play()
|
||||
result = dict(status.status(self.context))
|
||||
self.assertIn('bitrate', result)
|
||||
self.assertEqual(int(result['bitrate']), 320)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,10 @@ import sys
|
||||
|
||||
import mock
|
||||
|
||||
from mopidy import OptionalDependencyError, settings
|
||||
from mopidy.backends.dummy import DummyBackend
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core, settings, OptionalDependencyError
|
||||
from mopidy.backends import dummy
|
||||
|
||||
try:
|
||||
from mopidy.frontends.mpris import objects
|
||||
@ -18,11 +20,12 @@ class RootInterfaceTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
objects.exit_process = mock.Mock()
|
||||
objects.MprisObject._connect_to_dbus = mock.Mock()
|
||||
self.backend = DummyBackend.start().proxy()
|
||||
self.backend = dummy.DummyBackend.start(audio=None).proxy()
|
||||
self.core = core.Core.start(backend=self.backend).proxy()
|
||||
self.mpris = objects.MprisObject()
|
||||
|
||||
def tearDown(self):
|
||||
self.backend.stop()
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_constructor_connects_to_dbus(self):
|
||||
self.assert_(self.mpris._connect_to_dbus.called)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user