Add generic copy method to models (including tests)

This commit is contained in:
Thomas Adamcik 2010-11-02 00:35:27 +01:00
parent dd25fadd8b
commit d05e48c439
2 changed files with 55 additions and 28 deletions

View File

@ -38,6 +38,17 @@ class ImmutableObject(object):
def __ne__(self, other):
return not self.__eq__(other)
def copy(self, **kwargs):
data = {}
for key in self.__dict__.keys():
public_key = key.lstrip('_')
data[public_key] = kwargs.pop(public_key, self.__dict__[key])
for key in kwargs.keys():
if hasattr(self, key):
data[key] = kwargs.pop(key)
if kwargs:
raise TypeError("copy() got an unexpected keyword argument '%s'" % key)
return self.__class__(**data)
class Artist(ImmutableObject):
"""
@ -178,31 +189,3 @@ class Playlist(ImmutableObject):
def mpd_format(self, *args, **kwargs):
return translator.playlist_to_mpd_format(self, *args, **kwargs)
def copy(self, uri=None, name=None, tracks=None, last_modified=None):
"""
Create a new playlist object with the given values. The values that are
not given are taken from the object the method is called on.
Does not change the object on which it is called.
:param uri: playlist URI
:type uri: string
:param name: playlist name
:type name: string
:param tracks: playlist's tracks
:type tracks: list of :class:`Track` elements
:param last_modified: playlist's modification time
:type last_modified: :class:`datetime.datetime`
:rtype: :class:`Playlist`
"""
if uri is None:
uri = self.uri
if name is None:
name = self.name
if tracks is None:
tracks = self.tracks
if last_modified is None:
last_modified = self.last_modified
return Playlist(uri=uri, name=name, tracks=tracks,
last_modified=last_modified)

View File

@ -5,6 +5,50 @@ from mopidy.models import Artist, Album, Track, Playlist
from tests import SkipTest
class GenericCopyTets(unittest.TestCase):
def compare(self, orig, other):
self.assertEqual(orig, other)
self.assertNotEqual(id(orig), id(other))
def test_copying_track(self):
track = Track()
self.compare(track, track.copy())
def test_copying_artist(self):
artist = Artist()
self.compare(artist, artist.copy())
def test_copying_album(self):
album = Album()
self.compare(album, album.copy())
def test_copying_playlist(self):
playlist = Playlist()
self.compare(playlist, playlist.copy())
def test_copying_track_with_basic_values(self):
track = Track(name='foo', uri='bar')
copy = track.copy(name='baz')
self.assertEqual('baz', copy.name)
self.assertEqual('bar', copy.uri)
def test_copying_track_with_missing_values(self):
track = Track(uri='bar')
copy = track.copy(name='baz')
self.assertEqual('baz', copy.name)
self.assertEqual('bar', copy.uri)
def test_copying_track_with_private_internal_value(self):
artists1 = [Artist(name='foo')]
artists2 = [Artist(name='bar')]
track = Track(artists=artists1)
copy = track.copy(artists=artists2)
self.assertEqual(copy.artists, artists2)
def test_copying_track_with_invalid_key(self):
test = lambda: Track().copy(invalid_key=True)
self.assertRaises(TypeError, test)
class ArtistTest(unittest.TestCase):
def test_uri(self):
uri = u'an_uri'