1# This program is free software; you can redistribute it and/or modify
2# it under the terms of the GNU General Public License as published by
3# the Free Software Foundation; either version 2 of the License, or
4# (at your option) any later version.
5
6from tests import mkstemp, TestCase, get_data_path
7
8import os
9
10from quodlibet import formats
11from quodlibet import config
12
13from shutil import copyfileobj
14
15
16class TestMetaDataBase(TestCase):
17
18    base = get_data_path("silence-44-s")
19
20    def setUp(self):
21        """Copy the base silent file to a temp name/location and load it"""
22
23        config.init()
24        fd, self.filename = mkstemp(suffix=self.ext, text=False)
25        dst = os.fdopen(fd, 'wb')
26        src = open(self.base + self.ext, 'rb')
27        copyfileobj(src, dst)
28        dst.close()
29        self.song = formats.MusicFile(self.filename)
30
31    def tearDown(self):
32        """Delete the temp file"""
33
34        os.remove(self.filename)
35        del self.filename
36        del self.song
37        config.quit()
38
39
40class _TestMetaDataMixin(object):
41
42    def test_base_data(self):
43        self.failUnlessEqual(self.song['artist'], 'piman\njzig')
44        self.failUnlessEqual(self.song['album'], 'Quod Libet Test Data')
45        self.failUnlessEqual(self.song['title'], 'Silence')
46
47    def test_mutability(self):
48        self.failIf(self.song.can_change('=foo'))
49        self.failIf(self.song.can_change('foo~bar'))
50        self.failUnless(self.song.can_change('artist'))
51        self.failUnless(self.song.can_change('title'))
52        self.failUnless(self.song.can_change('tracknumber'))
53        self.failUnless(self.song.can_change('somebadtag'))
54        self.failUnless(self.song.can_change('some%punctuated:tag.'))
55
56    def _test_tag(self, tag, values, remove=True):
57        self.failUnless(self.song.can_change(tag))
58        for value in values:
59            self.song[tag] = value
60            self.song.write()
61            written = formats.MusicFile(self.filename)
62            self.failUnlessEqual(written[tag], value)
63            if remove:
64                del self.song[tag]
65                self.song.write()
66                deleted = formats.MusicFile(self.filename)
67                self.failIf(tag in deleted)
68
69    def test_artist(self): # a normalish tag
70        self._test_tag('artist', [u'me', u'you\nme',
71            u'\u6d5c\u5d0e\u3042\u3086\u307f'])
72
73    def test_date(self): # unusual special handling for mp3s
74        self._test_tag('date', [u'2004', u'2005', u'2005-06-12'], False)
75
76    def test_genre(self): # unusual special handling for mp3s
77        self._test_tag('genre', [u'Pop', u'Rock\nClassical', u'Big Bird',
78             u'\u30a2\u30cb\u30e1\u30b5\u30f3\u30c8\u30e9'])
79
80    def test_odd_performer(self):
81        values = [u"A Person", u"Another"]
82        self._test_tag("performer:vocals", values)
83        self._test_tag("performer:guitar", values)
84
85    def test_wackjob(self): # undefined tag
86        self._test_tag('wackjob', [u'Jelly\nDanish', u'Muppet',
87             u'\u30cf\u30f3\u30d0\u30fc\u30ac\u30fc'])
88
89tags = ['album', 'arranger', 'artist', 'author', 'comment', 'composer',
90'conductor', 'copyright', 'discnumber', 'encodedby', 'genre', 'isrc',
91'language', 'license', 'lyricist', 'organization', 'performer', 'title',
92'tracknumber', 'version', 'xyzzy_undefined_tag', 'musicbrainz_trackid',
93'releasecountry']
94
95for ext in formats.loaders.keys():
96    if os.path.exists(TestMetaDataBase.base + ext):
97        extra_tests = {}
98        for tag in tags:
99            if tag in ['artist', 'date', 'genre']:
100                continue
101
102            def _test_tag(self, tag=tag):
103                self._test_tag(tag, [u'a'])
104            extra_tests['test_tag_' + tag] = _test_tag
105
106            def _test_tags(self, tag=tag):
107                self._test_tag(tag, [u'b\nc'])
108            extra_tests['test_tags_' + tag] = _test_tags
109
110        name = 'MetaData' + ext
111        testcase = type(
112            name, (TestMetaDataBase, _TestMetaDataMixin), extra_tests)
113        testcase.ext = ext
114        globals()[name] = testcase
115