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:
Stein Magnus Jodal 2012-09-26 14:54:44 +02:00
parent c5ef8431c3
commit 2fdeec9f5a
34 changed files with 815 additions and 759 deletions

View File

@ -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:

View File

@ -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):
"""

View File

@ -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

View File

@ -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']

View File

@ -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)

View File

@ -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']

View File

@ -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 = []

View File

@ -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):

View File

@ -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
View 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()

View File

@ -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):

View File

@ -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()

View File

@ -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:

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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)

View File

@ -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()

View File

@ -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):

View File

@ -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):

View File

@ -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')

View File

@ -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')

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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')

View File

@ -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')

View File

@ -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 "/"')

View File

@ -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')

View File

@ -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):

View File

@ -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

View File

@ -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)