From 87ba412942340dfc46701b460612a77687193eeb Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 16 Nov 2012 15:01:37 +0100 Subject: [PATCH] models: Make TlTrack an ImmutableObject --- mopidy/models.py | 43 ++++++++++++++++++++--- tests/models_test.py | 84 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 107 insertions(+), 20 deletions(-) diff --git a/mopidy/models.py b/mopidy/models.py index 511ce847..17616f9d 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from collections import namedtuple - class ImmutableObject(object): """ @@ -151,9 +149,6 @@ class Album(ImmutableObject): super(Album, self).__init__(*args, **kwargs) -TlTrack = namedtuple('TlTrack', ['tlid', 'track']) - - class Track(ImmutableObject): """ :param uri: track URI @@ -208,6 +203,44 @@ class Track(ImmutableObject): super(Track, self).__init__(*args, **kwargs) +class TlTrack(ImmutableObject): + """ + A tracklist track. Wraps a regular track and it's tracklist ID. + + The use of :class:`TlTrack` allows the same track to appear multiple times + in the tracklist. + + This class also accepts it's parameters as positional arguments. Both + arguments must be provided, and they must appear in the order they are + listed here. + + This class also supports iteration, so your extract its values like this:: + + (tlid, track) = tl_track + + :param tlid: tracklist ID + :type tlid: int + :param track: the track + :type track: :class:`Track` + """ + + #: The tracklist ID. Read-only. + tlid = None + + #: The track. Read-only. + track = None + + def __init__(self, *args, **kwargs): + if len(args) == 2 and len(kwargs) == 0: + kwargs['tlid'] = args[0] + kwargs['track'] = args[1] + args = [] + super(TlTrack, self).__init__(*args, **kwargs) + + def __iter__(self): + return iter([self.tlid, self.track]) + + class Playlist(ImmutableObject): """ :param uri: playlist URI diff --git a/tests/models_test.py b/tests/models_test.py index 4e3cdabf..d5d58ace 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -314,21 +314,6 @@ class AlbumTest(unittest.TestCase): self.assertNotEqual(hash(album1), hash(album2)) -class TlTrackTest(unittest.TestCase): - def setUp(self): - self.tlid = 123 - self.track = Track() - self.tl_track = TlTrack(self.tlid, self.track) - - def test_tl_track_can_be_accessed_as_a_tuple(self): - self.assertEqual(self.tlid, self.tl_track[0]) - self.assertEqual(self.track, self.tl_track[1]) - - def test_tl_track_can_be_accessed_by_attribute_names(self): - self.assertEqual(self.tlid, self.tl_track.tlid) - self.assertEqual(self.track, self.tl_track.track) - - class TrackTest(unittest.TestCase): def test_uri(self): uri = 'an_uri' @@ -567,6 +552,75 @@ class TrackTest(unittest.TestCase): self.assertNotEqual(hash(track1), hash(track2)) +class TlTrackTest(unittest.TestCase): + def test_tlid(self): + tlid = 123 + tl_track = TlTrack(tlid=tlid) + self.assertEqual(tl_track.tlid, tlid) + self.assertRaises(AttributeError, setattr, tl_track, 'tlid', None) + + def test_track(self): + track = Track() + tl_track = TlTrack(track=track) + self.assertEqual(tl_track.track, track) + self.assertRaises(AttributeError, setattr, tl_track, 'track', None) + + def test_invalid_kwarg(self): + test = lambda: TlTrack(foo='baz') + self.assertRaises(TypeError, test) + + def test_positional_args(self): + tlid = 123 + track = Track() + tl_track = TlTrack(tlid, track) + self.assertEqual(tl_track.tlid, tlid) + self.assertEqual(tl_track.track, track) + + def test_iteration(self): + tlid = 123 + track = Track() + tl_track = TlTrack(tlid, track) + (tlid2, track2) = tl_track + self.assertEqual(tlid2, tlid) + self.assertEqual(track2, track) + + def test_repr(self): + self.assertEquals( + "TlTrack(tlid=123, track=Track(artists=[], uri=u'uri'))", + repr(TlTrack(tlid=123, track=Track(uri='uri')))) + + def test_serialize(self): + self.assertDictEqual( + {'tlid': 123, 'track': {'uri': 'uri', 'name': 'name'}}, + TlTrack(tlid=123, track=Track(uri='uri', name='name')).serialize()) + + def test_eq(self): + tlid = 123 + track = Track() + tl_track1 = TlTrack(tlid=tlid, track=track) + tl_track2 = TlTrack(tlid=tlid, track=track) + self.assertEqual(tl_track1, tl_track2) + self.assertEqual(hash(tl_track1), hash(tl_track2)) + + def test_eq_none(self): + self.assertNotEqual(TlTrack(), None) + + def test_eq_other(self): + self.assertNotEqual(TlTrack(), 'other') + + def test_ne_tlid(self): + tl_track1 = TlTrack(tlid=123) + tl_track2 = TlTrack(tlid=321) + self.assertNotEqual(tl_track1, tl_track2) + self.assertNotEqual(hash(tl_track1), hash(tl_track2)) + + def test_ne_track(self): + tl_track1 = TlTrack(track=Track(uri='a')) + tl_track2 = TlTrack(track=Track(uri='b')) + self.assertNotEqual(tl_track1, tl_track2) + self.assertNotEqual(hash(tl_track1), hash(tl_track2)) + + class PlaylistTest(unittest.TestCase): def test_uri(self): uri = 'an_uri'