PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/exaile-0.3.2.2/tests/xl/trax/test_track.py

#
Python | 574 lines | 469 code | 76 blank | 29 comment | 18 complexity | 5f6879049ab4067492a42717a356aaca MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. # -*- coding: utf-8 -*-
  2. from __future__ import with_statement
  3. import os
  4. import shutil
  5. import tempfile
  6. import unittest
  7. import logging
  8. import weakref
  9. import types
  10. import mox
  11. import gio
  12. import glib
  13. try:
  14. from nose.plugins.skip import SkipTest
  15. except ImportError:
  16. SkipTest = None
  17. import xl.trax.track as track
  18. import xl.settings as settings
  19. from tests.xl.trax import test_data
  20. LOG = logging.getLogger(__name__)
  21. class Test_MetadataCacher(unittest.TestCase):
  22. TIMEOUT = 2000
  23. MAX_ENTRIES = 2048
  24. def setUp(self):
  25. self.mox = mox.Mox()
  26. self.mc = track._MetadataCacher(self.TIMEOUT, self.MAX_ENTRIES)
  27. def tearDown(self):
  28. self.mox.UnsetStubs()
  29. def test_add(self):
  30. timeout_id = 1
  31. self.mox.StubOutWithMock(glib, 'timeout_add_seconds')
  32. self.mox.StubOutWithMock(glib, 'source_remove')
  33. glib.timeout_add_seconds(
  34. self.TIMEOUT,
  35. self.mc._MetadataCacher__cleanup).AndReturn(timeout_id)
  36. self.mox.ReplayAll()
  37. self.mc.add('foo', 'bar')
  38. self.assertEqual(self.mc.get('foo'), 'bar')
  39. self.mox.VerifyAll()
  40. def test_double_add(self):
  41. timeout_id = 1
  42. self.mox.StubOutWithMock(glib, 'timeout_add_seconds')
  43. self.mox.StubOutWithMock(glib, 'source_remove')
  44. glib.timeout_add_seconds(
  45. mox.IsA(types.IntType),
  46. mox.IsA(types.MethodType)).AndReturn(timeout_id)
  47. self.mox.ReplayAll()
  48. self.mc.add('foo', 'bar')
  49. self.assertEqual(self.mc.get('foo'), 'bar')
  50. self.mc.add('foo', 'bar')
  51. self.assertEqual(self.mc.get('foo'), 'bar')
  52. self.mox.VerifyAll()
  53. def test_remove(self):
  54. timeout_id = 1
  55. self.mox.StubOutWithMock(glib, 'timeout_add_seconds')
  56. glib.timeout_add_seconds(
  57. self.TIMEOUT,
  58. mox.IsA(types.MethodType)).AndReturn(timeout_id)
  59. self.mox.ReplayAll()
  60. self.mc.add('foo', 'bar')
  61. self.mc.remove('foo')
  62. self.assertEqual(self.mc.get('foo'), None)
  63. self.mox.VerifyAll()
  64. def test_remove_not_exist(self):
  65. self.assertEqual(self.mc.remove('foo'), None)
  66. class TestTrack(unittest.TestCase):
  67. def setUp(self):
  68. self.mox = mox.Mox()
  69. track.Track._Track__the_cuts = ['the', 'a']
  70. for key in track.Track._Track__tracksdict.keys():
  71. del track.Track._Track__tracksdict[key]
  72. def tearDown(self):
  73. self.mox.UnsetStubs()
  74. ## Creation
  75. def test_flyweight(self):
  76. """There can only be one object based on a url in args"""
  77. t1 = track.Track(test_data.TEST_TRACKS[0])
  78. t2 = track.Track(uri=test_data.TEST_TRACKS[0])
  79. self.assertTrue(t1 is t2, "%s should be %s" % (repr(t1), repr(t2)))
  80. def test_different_url_not_flyweighted(self):
  81. t1 = track.Track(test_data.TEST_TRACKS[0])
  82. t2 = track.Track(uri=test_data.TEST_TRACKS[1])
  83. self.assertTrue(t1 is not t2, "%s should not be %s" % (repr(t1),
  84. repr(t2)))
  85. def test_none_url(self):
  86. self.assertRaises(ValueError, track.Track)
  87. def test_pickles(self):
  88. tr = track.Track('/foo')
  89. tr.set_tag_raw('artist', 'bar')
  90. self.assertEqual(tr._pickles(), {
  91. '__loc': u'file:///foo',
  92. 'artist': [u'bar']
  93. })
  94. def test_unpickles(self):
  95. tr1 = track.Track(_unpickles={'artist': [u'my_artist'],
  96. '__loc': u'uri'})
  97. self.assertEqual(tr1.get_loc_for_io(), u'uri')
  98. def test_unpickles_flyweight(self):
  99. tr1 = track.Track(_unpickles={'artist': [u'my_artist'],
  100. '__loc': u'uri'})
  101. tr2 = track.Track(_unpickles={'artist': [u'my_artist'],
  102. '__loc': u'uri'})
  103. self.assertTrue(tr1 is tr2)
  104. def test_takes_nonurl(self):
  105. for tr in test_data.TEST_TRACKS:
  106. tr = track.Track(tr)
  107. self.assertTrue(tr.local_file_name())
  108. self.assertTrue(tr.exists())
  109. ## Information
  110. def test_local_type(self):
  111. for tr in test_data.TEST_TRACKS:
  112. tr = track.Track(tr)
  113. self.assertEqual(tr.get_type(), 'file')
  114. def test_is_local_local(self):
  115. """Tests a local filename -> True"""
  116. tr = track.Track('foo')
  117. self.assertEqual(tr.is_local(), True)
  118. def test_is_local_remote(self):
  119. """Tests a remote filename -> False"""
  120. tr = track.Track('http://foo')
  121. self.assertEqual(tr.is_local(), False)
  122. def test_local_filesize(self):
  123. for tr_name in test_data.TEST_TRACKS_SIZE:
  124. tr = track.Track(tr_name)
  125. self.assertEqual(tr.get_size(), test_data.TEST_TRACKS_SIZE[tr_name])
  126. def test_str(self):
  127. loc = test_data.TEST_TRACKS[0]
  128. tr = track.Track(loc)
  129. self.empty_track_of_tags(tr, ('__loc',))
  130. self.assertEqual(str(tr),
  131. "'Unknown (%s)' from 'Unknown' by 'Unknown'"
  132. % os.path.basename(loc))
  133. tr.set_tag_raw('artist', 'art')
  134. tr.set_tag_raw('album', 'alb')
  135. tr.set_tag_raw('title', 'title')
  136. self.assertEqual(str(tr), "'title' from 'alb' by 'art'")
  137. def test_read_tags_no_perms(self):
  138. # We test by creating a new file, changing the tags, writing tags
  139. # and finally reopening a track with the name and seeing if it stuck
  140. for tr_url in test_data.TEST_TRACKS:
  141. # We run through this process with each filetype we have
  142. suffix = os.extsep + tr_url.split(os.extsep)[-1]
  143. # Stuff we can't actually write metadata to
  144. if suffix in ('.aac', '.aiff', '.au', '.spx', '.wav'):
  145. LOG.info("Skipping tag write test for " + suffix)
  146. continue
  147. # This fails. i don't feel like reading about it's failing for now
  148. if suffix in ('.wma',):
  149. LOG.critical("Skipping known failure :" + suffix)
  150. continue
  151. LOG.info("Testing writes for filetype: " + suffix)
  152. with tempfile.NamedTemporaryFile(suffix=suffix) as temp_copy:
  153. # Copy and write new file
  154. shutil.copyfileobj(open(tr_url, 'r'), temp_copy)
  155. tr = track.Track(temp_copy.name)
  156. del tr
  157. os.chmod(temp_copy.name, 0o000)
  158. tr = track.Track(temp_copy.name)
  159. # Remove the artist tag and reread from file. This is done
  160. # because of the whole flyweight thing
  161. tr.set_tag_raw('artist', '')
  162. tr.read_tags()
  163. self.assertEqual(tr.get_tag_raw('artist'), None)
  164. def test_write_tags_no_perms(self):
  165. # We test by creating a new file, changing the tags, writing tags
  166. # and finally reopening a track with the name and seeing if it stuck
  167. for tr_url in test_data.TEST_TRACKS:
  168. # We run through this process with each filetype we have
  169. suffix = os.extsep + tr_url.split(os.extsep)[-1]
  170. # Stuff we can't actually write metadata to
  171. if suffix in ('.aac', '.aiff', '.au', '.spx', '.wav'):
  172. LOG.info("Skipping tag write test for " + suffix)
  173. continue
  174. # This fails. i don't feel like reading about it's failing for now
  175. if suffix in ('.wma',):
  176. LOG.critical("Skipping known failure :" + suffix)
  177. continue
  178. LOG.info("Testing writes for filetype: " + suffix)
  179. with tempfile.NamedTemporaryFile(suffix=suffix) as temp_copy:
  180. # Copy and write new file
  181. shutil.copyfileobj(open(tr_url, 'r'), temp_copy)
  182. os.chmod(temp_copy.name, 0o444)
  183. tr = track.Track(temp_copy.name)
  184. tr.set_tag_raw('artist', 'Delerium')
  185. self.assertFalse(tr.write_tags())
  186. def test_write_tags(self):
  187. # We test by creating a new file, changing the tags, writing tags
  188. # and finally reopening a track with the name and seeing if it stuck
  189. for tr_url in test_data.TEST_TRACKS:
  190. # We run through this process with each filetype we have
  191. suffix = os.extsep + tr_url.split(os.extsep)[-1]
  192. # Stuff we can't actually write metadata to
  193. if suffix in ('.aac', '.aiff', '.au', '.spx', '.wav'):
  194. LOG.info("Skipping tag write test for " + suffix)
  195. continue
  196. # This fails. i don't feel like reading about it's failing for now
  197. if suffix in ('.wma',):
  198. LOG.critical("Skipping known failure :" + suffix)
  199. continue
  200. LOG.info("Testing writes for filetype: " + suffix)
  201. with tempfile.NamedTemporaryFile(suffix=suffix) as temp_copy:
  202. # Copy and write new file
  203. shutil.copyfileobj(open(tr_url, 'r'), temp_copy)
  204. tr = track.Track(temp_copy.name)
  205. tr.set_tag_raw('artist', 'Delerium')
  206. tr.write_tags()
  207. del tr
  208. tr = track.Track(temp_copy.name)
  209. # Remove the artist tag and reread from file. This is done
  210. # because of the whole flyweight thing
  211. tr.set_tag_raw('artist', '')
  212. tr.read_tags()
  213. self.assertEqual(tr.get_tag_raw('artist'), [u'Delerium'])
  214. if SkipTest is not None:
  215. raise SkipTest("Skipped known failure: .wma")
  216. def test_write_tag_invalid_format(self):
  217. tr = track.Track('/tmp/foo.foo')
  218. self.assertEqual(tr.write_tags(), False)
  219. def test_join_tag_empty(self):
  220. """Tests get_tag_raw with join=True and an empty tag"""
  221. tr = track.Track('foo')
  222. self.assertEqual(tr.get_tag_raw('artist', join=True), None)
  223. def test_join_tag_one(self):
  224. """Tests get_tag_raw with join=True and one element in tag"""
  225. tr = track.Track('foo')
  226. tr.set_tag_raw('artist', 'foo')
  227. self.assertEqual(tr.get_tag_raw('artist', join=True), u'foo')
  228. def test_join_tag_two(self):
  229. """Tests get_tag_raw with join=True and one element in tag"""
  230. tr = track.Track('foo')
  231. tr.set_tag_raw('artist', [u'foo', u'bar'])
  232. self.assertEqual(tr.get_tag_raw('artist', join=True), u'foo / bar')
  233. def empty_track_of_tags(self, track, exclude=None):
  234. """Removes all the tags from a track"""
  235. for tag in track.list_tags():
  236. if exclude is not None and tag in exclude:
  237. continue
  238. track.set_tag_raw(tag, None)
  239. def test_list_tags(self):
  240. loc = test_data.TEST_TRACKS[0]
  241. tr = track.Track(loc)
  242. tags = {'artist': 'foo', 'album': 'bar', '__loc': loc}
  243. self.empty_track_of_tags(tr, tags)
  244. for tag, val in tags.iteritems():
  245. tr.set_tag_raw(tag, val)
  246. self.assertEqual(tr.list_tags(), ['album', '__loc', 'artist'])
  247. def test_rating_empty(self):
  248. """Test get_rating when no rating has been set"""
  249. tr = track.Track('/foo')
  250. self.assertEqual(tr.get_rating(), 0)
  251. def test_set_rating(self):
  252. tr = track.Track('/foo')
  253. tr.set_rating(2)
  254. self.assertEqual(tr.get_rating(), 2)
  255. def test_set_rating_invalid(self):
  256. tr = track.Track('/bar')
  257. self.assertRaises(ValueError, tr.set_rating, 'foo')
  258. ## Tag Getting helper methods
  259. def test_split_numerical_none(self):
  260. self.assertEqual(track.Track.split_numerical(None), (0, 0))
  261. def test_split_numerical_str(self):
  262. fn = track.Track.split_numerical
  263. self.assertEqual(fn('12/15'), (12, 15))
  264. self.assertEqual(fn('foo/15'), (0, 15))
  265. self.assertEqual(fn('12/foo'), (12, 0))
  266. self.assertEqual(fn('12/15/2009'), (12, 15))
  267. def test_split_numerical_list(self):
  268. fn = track.Track.split_numerical
  269. self.assertEqual(fn(['12/15']), (12, 15))
  270. self.assertEqual(fn(['foo/15']), (0, 15))
  271. self.assertEqual(fn(['12/foo']), (12, 0))
  272. self.assertEqual(fn(['12/15/2009']), (12, 15))
  273. def test_strip_leading(self):
  274. # Strips whitespace if it's an empty string
  275. value = " `~!@#$%^&*()_+-={}|[]\\\";'<>?,./"
  276. retvalue = "`~!@#$%^&*()_+-={}|[]\\\";'<>?,./"
  277. self.assertEqual(track.Track.strip_leading(value), retvalue)
  278. self.assertEqual(track.Track.strip_leading(value + "foo"), "foo")
  279. def test_cutter(self):
  280. value = 'the a foo'
  281. self.assertEqual(track.Track.the_cutter(value), 'a foo')
  282. def test_expand_doubles(self):
  283. value = u'яж??Ь???????'
  284. self.assertEqual(track.Track.expand_doubles(value),
  285. u'ssaeijngoehvdzljnjdzngts')
  286. def test_lower(self):
  287. value = u'FooBar'
  288. self.assertEqual(track.Track.lower(value), 'foobar FooBar')
  289. def test_cuts_cb(self):
  290. value = []
  291. settings.set_option('collection/strip_list', value)
  292. track.Track._the_cuts_cb(None, None, 'collection/strip_list')
  293. self.assertEqual(track.Track._Track__the_cuts, value)
  294. value = ['the', 'foo']
  295. settings.set_option('collection/strip_list', value)
  296. track.Track._the_cuts_cb(None, None, 'collection/strip_list')
  297. self.assertEqual(track.Track._Track__the_cuts, value)
  298. def test_strip_marks(self):
  299. value = u'The Hлllт Wую?dв'
  300. retval = u'The Hello Woю?da The Hлllт Wую?dв'
  301. self.assertEqual(track.Track.strip_marks(value), retval)
  302. ## Sort tags
  303. def test_get_sort_tag_no_join(self):
  304. tr = track.Track('/foo')
  305. value = u'hello'
  306. retval = [u'hello hello hello hello']
  307. tr.set_tag_raw('artist', value)
  308. self.assertEqual(tr.get_tag_sort('artist', join=False), retval)
  309. def test_get_sort_tag_discnumber(self):
  310. tr = track.Track('/foo')
  311. value = '12/15'
  312. retval = 12
  313. tr.set_tag_raw('discnumber', value)
  314. self.assertEqual(tr.get_tag_sort('discnumber'), retval)
  315. def test_get_sort_tag_tracknumber(self):
  316. tr = track.Track('/foo')
  317. value = '12/15'
  318. retval = 12
  319. tr.set_tag_raw('tracknumber', value)
  320. self.assertEqual(tr.get_tag_sort('tracknumber'), retval)
  321. def test_get_sort_tag_artist(self):
  322. tr = track.Track('/foo')
  323. value = u'The Hлllт Wую?dв'
  324. retval = u'hello woю?da the hлllт wую?dв ' \
  325. u'The Hello Woю?da The Hлllт Wую?dв'
  326. tr.set_tag_raw('artist', value)
  327. self.assertEqual(tr.get_tag_sort('artist'), retval)
  328. def test_get_sort_tag_albumsort(self):
  329. tr = track.Track('/foo')
  330. value = u'the hello world'
  331. val_as = u'Foo Bar'
  332. retval = u'foo bar foo bar Foo Bar Foo Bar'
  333. tr.set_tag_raw('album', value)
  334. tr.set_tag_raw('albumsort', val_as)
  335. self.assertEqual(tr.get_tag_sort('album'), retval)
  336. def test_get_sort_tag_compilation_unknown(self):
  337. tr = track.Track('/foo')
  338. tr.set_tag_raw('__compilation', 'foo')
  339. # Does not actually modify anything
  340. value = u'hello world'
  341. retval = u' '.join([u'\uffff\uffff\uffff\ufffe'] * 4)
  342. tr.set_tag_raw('artist', value)
  343. self.assertEqual(tr.get_tag_sort('artist'), retval)
  344. def test_get_sort_tag_compilation_known(self):
  345. tr = track.Track('/foo')
  346. tr.set_tag_raw('__compilation', 'foo')
  347. value = u'foo bar'
  348. retval = u'foo bar foo bar foo bar foo bar'
  349. tr.set_tag_raw('artist', u'hello world')
  350. tr.set_tag_raw('albumartist', u'albumartist')
  351. tr.set_tag_raw('artistsort', value)
  352. self.assertEqual(tr.get_tag_sort('artist'), retval)
  353. def test_get_sort_tag_length(self):
  354. tr = track.Track('/foo')
  355. tr.set_tag_raw('__length', 36)
  356. self.assertEqual(tr.get_tag_sort('__length'), 36)
  357. def test_get_sort_tag_playcount(self):
  358. tr = track.Track('/foo')
  359. tr.set_tag_raw('__playcount', 36)
  360. self.assertEqual(tr.get_tag_sort('__playcount'), 36)
  361. def test_get_sort_tag_other(self):
  362. tr = track.Track('/foo')
  363. val = u'foobar'
  364. ret = u'foobar foobar foobar foobar'
  365. tr.set_tag_raw('coverart', u'foobar')
  366. self.assertEqual(tr.get_tag_sort('coverart'), ret)
  367. ## Display Tags
  368. def test_get_display_tag_loc(self):
  369. tr = track.Track('/foo')
  370. self.assertEqual(tr.get_tag_display('__loc'), '/foo')
  371. tr = track.Track('http://foo')
  372. self.assertEqual(tr.get_tag_display('__loc'), 'http://foo')
  373. def test_get_display_tag_compilation(self):
  374. tr = track.Track('/foo')
  375. tr.set_tag_raw('__compilation', u'foo')
  376. self.assertEqual(tr.get_tag_display('artist'),
  377. track._VARIOUSARTISTSSTR)
  378. def test_get_display_tag_discnumber(self):
  379. tr = track.Track('/foo')
  380. value = '12/15'
  381. retval = '12'
  382. tr.set_tag_raw('discnumber', value)
  383. self.assertEqual(tr.get_tag_display('discnumber'), retval)
  384. def test_get_display_tag_tracknumber(self):
  385. tr = track.Track('/foo')
  386. value = '12/15'
  387. retval = '12'
  388. tr.set_tag_raw('tracknumber', value)
  389. self.assertEqual(tr.get_tag_display('tracknumber'), retval)
  390. def test_get_display_tag_length(self):
  391. tr = track.Track('/foo')
  392. tr.set_tag_raw('__length', 360)
  393. self.assertEqual(tr.get_tag_display('__length'), u'360')
  394. def test_get_display_tag_bitrate(self):
  395. tr = track.Track('/foo')
  396. tr.set_tag_raw('__bitrate', 48000)
  397. self.assertEqual(tr.get_tag_display('__bitrate'), u'48k')
  398. def test_get_display_tag_bitrate_bitrateless_formate(self):
  399. tr = track.Track(test_data.get_file_with_ext('.flac'))
  400. self.assertEqual(tr.get_tag_display('__bitrate'), u' ')
  401. def test_get_display_tag_bitrate_bad(self):
  402. tr = track.Track('/foo')
  403. tr.set_tag_raw('__bitrate', u'lol')
  404. self.assertEqual(tr.get_tag_display('__bitrate'), u' ')
  405. def test_get_display_tag_numeric_zero(self):
  406. tr = track.Track('/foo')
  407. self.assertEqual(tr.get_tag_display('tracknumber'), u'0')
  408. self.assertEqual(tr.get_tag_display('discnumber'), u'0')
  409. self.assertEqual(tr.get_tag_display('__rating'), u'0')
  410. self.assertEqual(tr.get_tag_display('__playcount'), u'0')
  411. def test_get_display_tag_join_true(self):
  412. tr = track.Track('/foo')
  413. tr.set_tag_raw('artist', [u'foo', u'bar'])
  414. self.assertEqual(tr.get_tag_display('artist'), 'foo / bar')
  415. def test_get_display_tag_join_false(self):
  416. tr = track.Track('/foo')
  417. tr.set_tag_raw('artist', [u'foo', u'bar'])
  418. self.assertEqual(tr.get_tag_display('artist', join=False),
  419. [u'foo', u'bar'])
  420. ## Sort tags
  421. def test_get_search_tag_loc(self):
  422. tr = track.Track('/foo')
  423. self.assertEqual(tr.get_tag_search('__loc'), '__loc=="file:///foo"')
  424. def test_get_search_tag_artist_compilation(self):
  425. tr = track.Track('/foo')
  426. tr.set_tag_raw('__compilation', 'foo')
  427. retval = u'albumartist=="albumartist" ! __compilation==__null__'
  428. tr.set_tag_raw('artist', u'hello world')
  429. tr.set_tag_raw('albumartist', u'albumartist')
  430. tr.set_tag_raw('artistsort', u'foo bar')
  431. self.assertEqual(tr.get_tag_search('artist'), retval)
  432. def test_get_search_tag_artist(self):
  433. tr = track.Track('/foo')
  434. retval = u'artist=="hello world"'
  435. tr.set_tag_raw('artist', u'hello world')
  436. self.assertEqual(tr.get_tag_search('artist'), retval)
  437. def test_get_search_tag_artist_none(self):
  438. tr = track.Track('/foo')
  439. retval = u'artist==__null__'
  440. self.assertEqual(tr.get_tag_search('artist'), retval)
  441. def test_get_search_tag_discnumber(self):
  442. tr = track.Track('/foo')
  443. value = '12/15'
  444. retval = 'discnumber=="12"'
  445. tr.set_tag_raw('discnumber', value)
  446. self.assertEqual(tr.get_tag_search('discnumber'), retval)
  447. def test_get_search_tag_tracknumber(self):
  448. tr = track.Track('/foo')
  449. value = '12/15'
  450. retval = 'tracknumber=="12"'
  451. tr.set_tag_raw('tracknumber', value)
  452. self.assertEqual(tr.get_tag_search('tracknumber'), retval)
  453. def test_get_search_tag_length(self):
  454. tr = track.Track('/foo')
  455. tr.set_tag_raw('__length', 36)
  456. self.assertEqual(tr.get_tag_search('__length'), '__length=="36"')
  457. def test_get_search_tag_bitrate(self):
  458. tr = track.Track('/foo')
  459. tr.set_tag_raw('__bitrate', 48000)
  460. self.assertEqual(tr.get_tag_search('__bitrate'), '__bitrate=="48k"')
  461. ## Disk tags
  462. def test_get_disk_tag_length(self):
  463. if SkipTest is not None:
  464. raise SkipTest("Metadata's do not return length. Might never.")
  465. tr_name = test_data.get_file_with_ext('.mp3')
  466. tr = track.Track(tr_name)
  467. self.assertEqual(tr.get_tag_disk('__length'),
  468. test_data.TEST_TRACKS_SIZE[tr_name])
  469. def test_get_disk_tag(self):
  470. tr_name = test_data.get_file_with_ext('.mp3')
  471. tr = track.Track(tr_name)
  472. self.assertEqual(tr.get_tag_disk('artist'), [u'Delerium'])
  473. def test_get_disk_tag_invalid_format(self):
  474. tr = track.Track('/tmp/foo.bah')
  475. self.assertEqual(tr.get_tag_disk('artist'), None)
  476. def test_list_disk_tag(self):
  477. tr_name = test_data.get_file_with_ext('.ogg')
  478. tr = track.Track(tr_name)
  479. self.assertEqual(set(tr.list_tags_disk()),
  480. set(('album', 'tracknumber', 'artist', 'title')))
  481. def test_list_disk_tag_invalid_format(self):
  482. tr_name = '/tmp/foo.foo'
  483. tr = track.Track(tr_name)
  484. self.assertEqual(tr.list_tags_disk(), None)