Refactor BaseStoredPlaylistsController.get_by_name to take multiple criteria

This commit is contained in:
Stein Magnus Jodal 2010-03-31 23:28:10 +02:00
parent 682b3cc354
commit 89346aa76b
2 changed files with 28 additions and 18 deletions

View File

@ -509,23 +509,33 @@ class BaseStoredPlaylistsController(object):
""" """
raise NotImplementedError raise NotImplementedError
def get_by_name(self, name): def get(self, **criteria):
""" """
Get playlist with given name from the set of stored playlists. Get playlist by given criterias from the set of stored playlists.
Raises :exc:`KeyError` if not a unique match is found. Raises :exc:`LookupError` if a unique match is not found.
:param name: playlist name Examples::
:type name: string
get(name='a') # Returns track with name 'a'
get(uri='xyz') # Returns track with URI 'xyz'
get(name='a', uri='xyz') # Returns track with name 'a' and URI 'xyz'
:param criteria: on or more criteria to match by
:type criteria: dict
:rtype: :class:`mopidy.models.Playlist` :rtype: :class:`mopidy.models.Playlist`
""" """
matches = filter(lambda p: name == p.name, self._playlists) matches = self._playlists
for (key, value) in criteria.iteritems():
matches = filter(lambda p: getattr(p, key) == value, matches)
if len(matches) == 1: if len(matches) == 1:
return matches[0] return matches[0]
elif len(matches) == 0: criteria_string = ', '.join(
raise KeyError('Name "%s" not found' % name) ['%s=%s' % (k, v) for (k, v) in criteria.iteritems()])
if len(matches) == 0:
raise LookupError('"%s" match no playlists' % criteria_string)
else: else:
raise KeyError('Name "%s" matched multiple elements' % name) raise LookupError('"%s" match multiple playlists' % criteria_string)
def lookup(self, uri): def lookup(self, uri):
""" """

View File

@ -71,21 +71,21 @@ class StoredPlaylistsGetTest(unittest.TestCase):
def test_get_by_name_returns_unique_match(self): def test_get_by_name_returns_unique_match(self):
playlist = Playlist(name='b') playlist = Playlist(name='b')
self.s.playlists = [Playlist(name='a'), playlist] self.s.playlists = [Playlist(name='a'), playlist]
self.assertEqual(playlist, self.s.get_by_name('b')) self.assertEqual(playlist, self.s.get(name='b'))
def test_get_by_name_returns_first_of_multiple_matches(self): def test_get_by_name_returns_first_of_multiple_matches(self):
playlist = Playlist(name='b') playlist = Playlist(name='b')
self.s.playlists = [playlist, Playlist(name='a'), Playlist(name='b')] self.s.playlists = [playlist, Playlist(name='a'), Playlist(name='b')]
try: try:
self.s.get_by_name('b') self.s.get(name='b')
self.fail(u'Should raise KeyError if multiple matches') self.fail(u'Should raise LookupError if multiple matches')
except KeyError as e: except LookupError as e:
self.assertEqual(u'Name "b" matched multiple elements', e[0]) self.assertEqual(u'"name=b" match multiple playlists', e[0])
def test_get_by_id_raises_keyerror_if_no_match(self): def test_get_by_id_raises_keyerror_if_no_match(self):
self.s.playlists = [Playlist(name='a'), Playlist(name='b')] self.s.playlists = [Playlist(name='a'), Playlist(name='b')]
try: try:
self.s.get_by_name('c') self.s.get(name='c')
self.fail(u'Should raise KeyError if no match') self.fail(u'Should raise LookupError if no match')
except KeyError as e: except LookupError as e:
self.assertEqual(u'Name "c" not found', e[0]) self.assertEqual(u'"name=c" match no playlists', e[0])