PageRenderTime 100ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/zeyatest.py

https://github.com/TheSkorm/zeya
Python | 238 lines | 187 code | 9 blank | 42 comment | 0 complexity | 7feece85246060364c7fe5d37a86f95d MD5 | raw file
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Copyright (C) 2009, 2010 Phil Sung
  5. #
  6. # This file is part of Zeya.
  7. #
  8. # Zeya is free software: you can redistribute it and/or modify it under the
  9. # terms of the GNU Affero General Public License as published by the Free
  10. # Software Foundation, either version 3 of the License, or (at your option) any
  11. # later version.
  12. #
  13. # Zeya is distributed in the hope that it will be useful, but WITHOUT ANY
  14. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  15. # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  16. # details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with Zeya. If not, see <http://www.gnu.org/licenses/>.
  20. # Test suite for Zeya.
  21. import StringIO
  22. import os
  23. import unittest
  24. import backends
  25. import decoders
  26. import m3u
  27. import options
  28. import pls
  29. import rhythmbox
  30. class FakeTagpy():
  31. """
  32. Fake object that can be a stand-in for the tagpy module, but which returns
  33. a fixed tag object.
  34. """
  35. def __init__(self, retval):
  36. self.retval = retval
  37. def FileRef(self, filename):
  38. class FakeTag():
  39. # Avoid shadowing the outer instance of 'self', so we can read from
  40. # it.
  41. def tag(inner_self):
  42. return self.retval
  43. return FakeTag()
  44. class TagData():
  45. """
  46. Tag object that holds metadata for a single song.
  47. """
  48. def __init__(self, artist, title, album):
  49. self.artist = artist
  50. self.title = title
  51. self.album = album
  52. class CommonTest(unittest.TestCase):
  53. def test_tokenization(self):
  54. """
  55. Test that our tokenization method yields a correct ordering of songs.
  56. """
  57. # Note, filename1 > filename2
  58. filename1 = "/home/phil/9 - something.ogg"
  59. filename2 = "/home/phil/10 - something.ogg"
  60. t1 = rhythmbox.tokenize_filename(filename1)
  61. t2 = rhythmbox.tokenize_filename(filename2)
  62. self.assertTrue(t1 < t2)
  63. class DecodersTest(unittest.TestCase):
  64. def test_extensions(self):
  65. """
  66. Test decoders.get_extension.
  67. """
  68. self.assertEqual("mp3", decoders.get_extension("/path/to/SOMETHING.MP3"))
  69. def test_is_decoder_registered(self):
  70. """
  71. Test decoders.is_decoder_registered.
  72. """
  73. self.assertTrue(decoders.is_decoder_registered("/path/to/something.mp3"))
  74. self.assertFalse(decoders.is_decoder_registered("/path/to/something.xyz"))
  75. def test_get_decoder(self):
  76. """
  77. Test decoders.get_decoder
  78. """
  79. self.assertTrue(decoders.get_decoder("/path/to/SOMETHING.MP3")[0]
  80. .startswith("/usr/bin"))
  81. class M3uTest(unittest.TestCase):
  82. def test_parse_m3u(self):
  83. playlist_data = """#EXTM3U
  84. #EXTINF:,One
  85. /home/phil/music/1 One.flac
  86. #EXTINF:,Something
  87. /home/phil/music/2 Two.flac"""
  88. playlist = m3u.M3uPlaylist("/home/phil/foo.m3u",
  89. StringIO.StringIO(playlist_data))
  90. self.assertEqual(['/home/phil/music/1 One.flac', '/home/phil/music/2 Two.flac'],
  91. playlist.get_filenames())
  92. self.assertEqual(u'foo.m3u', playlist.get_title())
  93. def test_parse_m3u_with_relative_paths(self):
  94. playlist_data = "music/1 One.flac\nmusic/2 Two.flac"
  95. playlist = m3u.M3uPlaylist("/home/phil/foo.m3u",
  96. StringIO.StringIO(playlist_data))
  97. self.assertEqual(['/home/phil/music/1 One.flac', '/home/phil/music/2 Two.flac'],
  98. playlist.get_filenames())
  99. class MetadataExtractionTest(unittest.TestCase):
  100. def test_with_metadata(self):
  101. tagpy = FakeTagpy(TagData(artist="Beatles", title="Ticket to Ride",
  102. album="Help!"))
  103. metadata = backends.extract_metadata("/dev/null", tagpy)
  104. self.assertEqual("Ticket to Ride", metadata[backends.TITLE])
  105. self.assertEqual("Beatles", metadata[backends.ARTIST])
  106. self.assertEqual("Help!", metadata[backends.ALBUM])
  107. def test_without_metadata(self):
  108. tagpy = FakeTagpy(None)
  109. metadata = backends.extract_metadata("/the/path/to/Song.flac", tagpy)
  110. self.assertEqual("Song.flac", metadata[backends.TITLE])
  111. self.assertEqual("", metadata[backends.ARTIST])
  112. self.assertEqual("path/to", metadata[backends.ALBUM])
  113. def test_short_path(self):
  114. tagpy = FakeTagpy(None)
  115. metadata = backends.extract_metadata("/music/Song.flac", tagpy)
  116. self.assertEqual("music", metadata[backends.ALBUM])
  117. def test_noalbum_path(self):
  118. tagpy = FakeTagpy(TagData(artist="Beatles", title=None, album=None))
  119. metadata = backends.extract_metadata("/music/Song.flac", tagpy)
  120. self.assertEqual("", metadata[backends.ALBUM])
  121. def test_decode_filename(self):
  122. tagpy = FakeTagpy(None)
  123. metadata = backends.extract_metadata("/path/to/\xe4\xb8\xad.flac", tagpy)
  124. self.assertEqual(u"\u4e2d.flac", metadata[backends.TITLE])
  125. def test_album_name_from_path_unicode(self):
  126. value1 = backends.album_name_from_path(
  127. TagData(artist="Beatles", title=None, album=None),
  128. "/path/to/music")
  129. self.assertTrue(type(value1) == unicode)
  130. self.assertEqual(u'', value1)
  131. value2 = backends.album_name_from_path(None, "/path/\xc3\x84/music")
  132. self.assertEqual(u'path/\u00c4', value2)
  133. value3 = backends.album_name_from_path(None, "/\xc3\x84/music")
  134. self.assertEqual(u'\u00c4', value3)
  135. class OptionsTest(unittest.TestCase):
  136. def test_default(self):
  137. params = options.get_options([])
  138. self.assertFalse(params[0])
  139. self.assertEqual('dir', params[1])
  140. self.assertEqual(os.path.abspath('.'), params[5])
  141. def test_get_help(self):
  142. params = options.get_options(["--help"])
  143. self.assertTrue(params[0])
  144. def test_path(self):
  145. params = options.get_options(["--path=/foo/bar"])
  146. self.assertEqual('/foo/bar', params[5])
  147. def test_backend(self):
  148. params = options.get_options(["--backend=rhythmbox"])
  149. self.assertEqual('rhythmbox', params[1])
  150. def test_bad_backend(self):
  151. try:
  152. params = options.get_options(["--backend=invalid"])
  153. self.fail("get_options should have raised BadArgsError")
  154. except options.BadArgsError:
  155. pass
  156. def test_bitrate(self):
  157. params = options.get_options(["-b128"])
  158. self.assertEqual(128, params[2])
  159. def test_bad_bitrate(self):
  160. try:
  161. params = options.get_options(["--bitrate=0"])
  162. self.fail("get_options should have raised BadArgsError")
  163. except options.BadArgsError:
  164. pass
  165. def test_port(self):
  166. params = options.get_options(["-p9999"])
  167. self.assertEqual(9999, params[4])
  168. def test_bad_port(self):
  169. try:
  170. params = options.get_options(["--port=p"])
  171. self.fail("get_options should have raised BadArgsError")
  172. except options.BadArgsError:
  173. pass
  174. class PlsTest(unittest.TestCase):
  175. def test_parse_pls(self):
  176. playlist_data = """[playlist]
  177. X-GNOME-Title=Foo
  178. NumberOfEntries=2
  179. File1=foo/bar/1 one.flac
  180. Title1=One
  181. File2=/var/bar/2 two.flac
  182. Title2=Something"""
  183. playlist = \
  184. pls.PlsPlaylist("/home/phil/playlist.pls",
  185. StringIO.StringIO(playlist_data))
  186. self.assertEqual(['/home/phil/foo/bar/1 one.flac',
  187. '/var/bar/2 two.flac'],
  188. playlist.get_filenames())
  189. self.assertEqual(u'Foo', playlist.get_title())
  190. def test_parse_pls_with_file_url(self):
  191. playlist_data = """[playlist]
  192. X-GNOME-Title=Foo
  193. NumberOfEntries=1
  194. File1=file:///home/phil/music/Beach%20Boys,%20The/One.flac
  195. Title1=One"""
  196. playlist = \
  197. pls.PlsPlaylist("/home/phil/playlist.pls",
  198. StringIO.StringIO(playlist_data))
  199. self.assertEqual(['/home/phil/music/Beach Boys, The/One.flac'],
  200. playlist.get_filenames())
  201. class RhythmboxTest(unittest.TestCase):
  202. def test_read_library(self):
  203. """
  204. Verify that the contents of the Rhythmbox XML library are read
  205. correctly.
  206. """
  207. backend = rhythmbox.RhythmboxBackend(open("testdata/rhythmbox.xml"))
  208. library = backend.get_library_contents()
  209. self.assertEqual(u'Help!', library[0]['album'])
  210. self.assertEqual(u'The Beatles', library[0]['artist'])
  211. self.assertEqual(u'Help!', library[0]['title'])
  212. key1 = library[0]['key']
  213. self.assertEqual('/tmp/Beatles, The/Help.flac',
  214. backend.get_filename_from_key(key1))
  215. # Test correct handling of songs and filenames with non-Latin
  216. # characters.
  217. self.assertEqual(u'', library[1]['album'])
  218. self.assertEqual(u'', library[1]['artist'])
  219. self.assertEqual(u'\u4e2d\u6587', library[1]['title'])
  220. key2 = library[1]['key']
  221. self.assertEqual(u'/tmp/\u4e2d\u6587.flac'.encode('UTF-8'),
  222. backend.get_filename_from_key(key2))
  223. if __name__ == "__main__":
  224. unittest.main()