local: use limit and offset when searching json library

Fixes the json local library's search behavior. Uses limit and offset
arguments when returning search results.
This commit is contained in:
Ali Ukani 2015-01-26 16:16:46 -05:00
parent 92910e4362
commit fc21d466f0
3 changed files with 85 additions and 8 deletions

View File

@ -157,11 +157,12 @@ class JsonLibrary(local.Library):
def search(self, query=None, limit=100, offset=0, uris=None, exact=False):
tracks = self._tracks.values()
# TODO: pass limit and offset into search helpers
if exact:
return search.find_exact(tracks, query=query, uris=uris)
return search.find_exact(
tracks, query=query, limit=limit, offset=offset, uris=uris)
else:
return search.search(tracks, query=query, uris=uris)
return search.search(
tracks, query=query, limit=limit, offset=offset, uris=uris)
def begin(self):
return compat.itervalues(self._tracks)

View File

@ -3,7 +3,18 @@ from __future__ import absolute_import, unicode_literals
from mopidy.models import SearchResult
def find_exact(tracks, query=None, uris=None):
def find_exact(tracks, query=None, limit=100, offset=0, uris=None):
"""
Filter a list of tracks where ``field`` is ``values``.
:param list tracks: a list of :class:`~mopidy.models.Track`
:param dict query: one or more queries to search for
:param int limit: maximum number of results to return
:param int offset: offset into result set to use.
:param uris: zero or more URI roots to limit the search to
:type uris: list of strings or :class:`None`
:rtype: :class:`~mopidy.models.SearchResult`
"""
# TODO Only return results within URI roots given by ``uris``
if query is None:
@ -96,10 +107,22 @@ def find_exact(tracks, query=None, uris=None):
raise LookupError('Invalid lookup field: %s' % field)
# TODO: add local:search:<query>
return SearchResult(uri='local:search', tracks=tracks)
return SearchResult(
uri='local:search', tracks=tracks[offset:offset+limit])
def search(tracks, query=None, uris=None):
def search(tracks, query=None, limit=100, offset=0, uris=None):
"""
Filter a list of tracks where ``field`` is like ``values``.
:param list tracks: a list of :class:`~mopidy.models.Track`
:param dict query: one or more queries to search for
:param int limit: maximum number of results to return
:param int offset: offset into result set to use.
:param uris: zero or more URI roots to limit the search to
:type uris: list of strings or :class:`None`
:rtype: :class:`~mopidy.models.SearchResult`
"""
# TODO Only return results within URI roots given by ``uris``
if query is None:
@ -195,7 +218,7 @@ def search(tracks, query=None, uris=None):
else:
raise LookupError('Invalid lookup field: %s' % field)
# TODO: add local:search:<query>
return SearchResult(uri='local:search', tracks=tracks)
return SearchResult(uri='local:search', tracks=tracks[offset:offset+limit])
def _validate_query(query):

View File

@ -1,9 +1,13 @@
from __future__ import absolute_import, unicode_literals
import unittest
from mopidy.local import json
from mopidy.models import Ref
from mopidy.models import Ref, Track
from tests import path_to_data_dir
class BrowseCacheTest(unittest.TestCase):
@ -38,3 +42,52 @@ class BrowseCacheTest(unittest.TestCase):
def test_lookup_foo_baz(self):
result = self.cache.lookup('local:directory:foo/unknown')
self.assertEqual([], result)
class JsonLibraryTest(unittest.TestCase):
config = {
'local': {
'media_dir': path_to_data_dir(''),
'data_dir': path_to_data_dir(''),
'playlists_dir': b'',
'library': 'json',
},
}
def setUp(self): # noqa: N802
self.library = json.JsonLibrary(self.config)
def _create_tracks(self, count):
for i in xrange(count):
self.library.add(Track(uri='local:track:%d' % i))
def test_search_should_default_limit_results(self):
self._create_tracks(101)
result = self.library.search()
result_exact = self.library.search(exact=True)
self.assertEqual(len(result.tracks), 100)
self.assertEqual(len(result_exact.tracks), 100)
def test_search_should_limit_results(self):
self._create_tracks(100)
result = self.library.search(limit=35)
result_exact = self.library.search(exact=True, limit=35)
self.assertEqual(len(result.tracks), 35)
self.assertEqual(len(result_exact.tracks), 35)
def test_search_should_offset_results(self):
self._create_tracks(200)
expected = self.library.search(limit=110).tracks[10:]
expected_exact = self.library.search(exact=True, limit=110).tracks[10:]
result = self.library.search(offset=10).tracks
result_exact = self.library.search(offset=10, exact=True).tracks
self.assertEqual(expected, result)
self.assertEqual(expected_exact, result_exact)