1
# Copyright (C) 2009 Abhishek Mukherjee
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 3, or (at your option)
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
Simple test case for MPRIS. Make sure you set the global variable FILE with an
18
absolute path to a valid playable, local music piece before running this test
20
@warning: DO not run this with an old unpatched Notifications plugin enabled.
21
Your Galago daemon will get DoS'd. It is normal for your songs to randomly
29
OBJECT_NAME = 'org.mpris.exaile'
30
INTERFACE = 'org.freedesktop.MediaPlayer'
31
FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
32
os.path.pardir, os.path.pardir,
33
'tests', 'data', 'music', 'delerium', 'chimera',
35
assert os.path.isfile(FILE), FILE + " must be a valid musical piece"
36
FILE = "file://" + FILE
38
bus = dbus.SessionBus()
43
object = bus.get_object(OBJECT_NAME, '/')
44
interface = dbus.Interface(object, INTERFACE)
48
# only run mpris tests if the dbus object is available
50
class TestExaileMpris(unittest.TestCase):
53
Tests Exaile MPRIS plugin
58
Simple setUp that makes dbus connections and assigns them to
59
self.player, self.track_list, and self.root. Also begins playing
60
a song so every test case can assume that a song is playing
62
bus = dbus.SessionBus()
63
objects = {'root': '/',
65
'track_list': '/TrackList',
69
object = bus.get_object(OBJECT_NAME, objects[key])
70
intfs[key] = dbus.Interface(object, INTERFACE)
71
self.root = intfs['root']
72
self.player = intfs['player']
73
self.track_list = intfs['track_list']
77
def __wait_after(function):
79
Decorator to add a delay after a function call
81
def inner(*args, **kwargs):
82
function(*args, **kwargs)
89
Stops playing w/ delay
96
Starts playing w/ delay
103
Pauses playing w/ delay
108
class TestMprisRoot(TestExaileMpris):
111
Check / (Root) object functions for MPRIS. Does not check Quit
114
def testIdentity(self):
116
Make sure we output Exaile with our identity
118
id = self.root.Identity()
119
self.assertEqual(id, self.root.Identity())
120
self.assertTrue(id.startswith("Exaile"))
122
def testMprisVersion(self):
124
Checks that we are using MPRIS version 1.0
126
version = self.root.MprisVersion()
127
self.assertEqual(dbus.UInt16(1), version[0])
128
self.assertEqual(dbus.UInt16(0), version[1])
130
class TestTrackList(TestExaileMpris):
133
Tests the /TrackList object for MPRIS
136
def testGetMetadata(self):
138
Make sure we can get metadata. Also makes sure that locations will
141
md = self.track_list.GetMetadata(0)
142
md_2 = self.track_list.GetMetadata(0)
143
self.assertEqual(md, md_2)
145
def testAppendDelWithoutPlay(self):
147
Tests appending and deleting songs from the playlist without
150
cur_track = self.track_list.GetCurrentTrack()
151
len = self.track_list.GetLength()
153
self.assertEqual(0, self.track_list.AddTrack(FILE, False))
154
self.assertEqual(len + 1, self.track_list.GetLength())
155
self.assertEqual(cur_track, self.track_list.GetCurrentTrack())
157
md = self.track_list.GetMetadata(len)
158
self.assertEqual(FILE, md['location'])
160
self.track_list.DelTrack(len)
161
self.assertEqual(len, self.track_list.GetLength())
162
self.assertEqual(cur_track, self.track_list.GetCurrentTrack())
164
def testAppendDelWithPlay(self):
166
Tests appending songs into the playlist with playing the songs
168
cur_track = self.track_list.GetCurrentTrack()
169
cur_md = self.track_list.GetMetadata(cur_track)
170
len = self.track_list.GetLength()
172
self.assertEqual(0, self.track_list.AddTrack(FILE, True))
173
self.assertEqual(len + 1, self.track_list.GetLength())
175
md = self.track_list.GetMetadata(len)
176
self.assertEqual(FILE, md['location'])
177
self.assertEqual(len, self.track_list.GetCurrentTrack())
179
self.track_list.DelTrack(len)
180
self.assertEqual(len, self.track_list.GetLength())
182
self.track_list.AddTrack(cur_md['location'], True)
184
def testGetCurrentTrack(self):
186
Check the GetCurrentTrack information
188
cur_track = self.track_list.GetCurrentTrack()
189
self.assertTrue(cur_track >= 0, "Tests start with playing music")
192
self.assertEqual(dbus.Int32(-1), self.track_list.GetCurrentTrack(),
193
"Our implementation returns -1 if no tracks are playing")
196
self.assertEqual(cur_track, self.track_list.GetCurrentTrack(),
197
"After a stop and play, we should be at the same track")
199
def __test_bools(self, getter, setter):
201
Generic function for checking that a boolean value changes
204
if cur_val == dbus.Int32(0):
206
elif cur_val == dbus.Int32(1):
209
self.fail("Got an invalid value from status")
213
self.assertEqual(dbus.Int32(0), status)
217
self.assertEqual(dbus.Int32(1), status)
220
self.track_list.SetLoop(val)
224
Tests that you can change the loop settings
226
self.__test_bools(lambda: self.player.GetStatus()[3],
227
lambda x: self.track_list.SetLoop(x))
229
def testRandom(self):
231
Tests that you can change the random settings
233
self.__test_bools(lambda: self.player.GetStatus()[1],
234
lambda x: self.track_list.SetRandom(x))
236
class TestPlayer(TestExaileMpris):
239
Tests the /Player object for MPRIS
242
def testNextPrev(self):
244
Make sure you can skip back and forward
246
cur_track = self.track_list.GetCurrentTrack()
248
new_track = self.track_list.GetCurrentTrack()
249
self.assertNotEqual(cur_track, new_track)
251
self.assertEqual(cur_track, self.track_list.GetCurrentTrack())
253
def testStopPlayPause(self):
255
Make sure play, pause, and stop behaive as designed
258
self.assertEqual(dbus.Int32(2), self.player.GetStatus()[0])
261
self.assertEqual(dbus.Int32(0), self.player.GetStatus()[0])
263
self.assertEqual(dbus.Int32(0), self.player.GetStatus()[0])
266
self.assertEqual(dbus.Int32(1), self.player.GetStatus()[0])
268
self.assertEqual(dbus.Int32(0), self.player.GetStatus()[0])
271
self.assertEqual(dbus.Int32(2), self.player.GetStatus()[0])
273
self.assertEqual(dbus.Int32(2), self.player.GetStatus()[0])
275
def testVolume(self):
277
Test to make sure volumes are set happily
279
vol = self.player.VolumeGet()
280
self.player.VolumeSet(1 - vol)
281
self.assertEqual(1 - vol, self.player.VolumeGet())
282
self.player.VolumeSet(vol)
283
self.assertEqual(vol, self.player.VolumeGet())
285
def testPosition(self):
287
Test the PositionGet and PositionSet functions. Unfortuantely this
288
is very time sensitive and thus has about a 10 second sleep in the
294
pos = self.player.PositionGet()
296
self.assertEqual(pos, self.player.PositionGet(),
297
"Position shouldn't move while paused")
301
last_pos = self.player.PositionGet()
302
self.assertTrue(pos < last_pos,
303
"Position shouldn't advance while paused: %d >= %d" %
306
self.player.PositionSet(pos)
309
mid_pos = self.player.PositionGet(),
310
self.assertTrue(mid_pos[0] < last_pos,
311
"Resetting to position %d, %d should be between that at %d"
312
% (pos, mid_pos[0], last_pos))
316
self.assertTrue(pos < self.player.PositionGet(),
317
"Make sure it still advances")
319
self.player.PositionSet(-1)
320
self.assertTrue(pos < self.player.PositionGet(),
321
"Don't move to invalid position")
325
sub_test = [TestMprisRoot, TestTrackList]
329
for test in sub_test:
330
suites.append(unittest.defaultTestLoader.loadTestsFromTestCase(test))
332
return unittest.TestSuite(suites)
334
if __name__ == "__main__":