1 |
# coding=UTF-8
|
2 |
|
3 |
"""
|
4 |
For now this tests only tagging support
|
5 |
"""
|
6 |
|
7 |
from django.test import TestCase
|
8 |
from prolatio.music_tagger.tagging import MetaFile
|
9 |
import os.path
|
10 |
import random
|
11 |
import shutil
|
12 |
import tempfile
|
13 |
|
14 |
class TaggingTest(TestCase):
|
15 |
def setUp(self):
|
16 |
# we should use setUpClass, but it's only available in python 2.7
|
17 |
# so we workaround this by making sure we call setUp code only once
|
18 |
# FIXME: blet, reinitializina visa objekta pries kiekviena metoda
|
19 |
if not hasattr(self, 'field_test_map') and not hasattr(self, 'test_files'):
|
20 |
print "WTF"
|
21 |
if getattr(self, 'initialized', None):
|
22 |
return
|
23 |
|
24 |
self.initialized = True
|
25 |
# list of tag properties we try to set/get
|
26 |
# (<property name>, <property type>, <test value>)
|
27 |
# if <test value> == None, default test value according to type will be used
|
28 |
self.field_test_map = (
|
29 |
# basic fields
|
30 |
#('album', 'str', None),
|
31 |
#('comment', 'str', None),
|
32 |
#('title', 'str', None),
|
33 |
#('track', 'int', None),
|
34 |
#('year', 'int', None),
|
35 |
# extended fields
|
36 |
('album_artists', 'array', None),
|
37 |
('album_artists_sort', 'array', None),
|
38 |
('album_sort', 'str', None),
|
39 |
('amazon_id', 'str', None),
|
40 |
('beats_per_minute', 'int', None),
|
41 |
('composers', 'array', None),
|
42 |
('composers_sort', 'array', None),
|
43 |
('conductor', 'str', None),
|
44 |
('copyright', 'str', None),
|
45 |
('disc', 'int', None),
|
46 |
('disc_count', 'int', None),
|
47 |
('genres', 'array', None),
|
48 |
#('is_compilation', 'bool'), this is only available for XiphComment so we don't test this
|
49 |
#('lyrics', 'str'), TODO: implement this in id3v2 !
|
50 |
('grouping', 'str', None),
|
51 |
('musicbrainz_artist_id', 'str', None),
|
52 |
('musicbrainz_disc_id', 'str', None),
|
53 |
('musicbrainz_release_artist_id', 'str', None),
|
54 |
('musicbrainz_release_id', 'str', None),
|
55 |
('musicbrainz_release_status', 'str', None),
|
56 |
('musicbrainz_release_country', 'str', None),
|
57 |
('musicbrainz_release_type', 'str', None),
|
58 |
('musicbrainz_track_id', 'str', 'identificator_without_utf'),
|
59 |
('musicip_id', 'str', None),
|
60 |
('performers', 'array', None),
|
61 |
('performers_sort', 'array', None),
|
62 |
('title_sort', 'str', None),
|
63 |
#('track_count', 'int', None)
|
64 |
)
|
65 |
base_dir = os.path.dirname(os.path.dirname(__file__))
|
66 |
orig_test_dir = os.path.join(base_dir, 'tests', 'music_tagger')
|
67 |
# files for testing (should be in tests/music_tagger directory)
|
68 |
#self.test_files = ('l.flac', 'l.mp3', 'l.mpc', 'l.ogg')#, 'l.ape')
|
69 |
self.test_files = ('l.mpc',)
|
70 |
# we don't want to damage our test files during the test, so just copy them
|
71 |
self.test_dir = tempfile.mkdtemp()
|
72 |
print "test dir is '%s'" % self.test_dir
|
73 |
for file in self.test_files:
|
74 |
shutil.copy(os.path.join(orig_test_dir, file), os.path.join(self.test_dir, file))
|
75 |
|
76 |
def tearDown(self):
|
77 |
# FIXME: how to make sure this is called only after all test methods are run???
|
78 |
# shutil.rmtree(self.test_dir, True)
|
79 |
pass
|
80 |
|
81 |
def test1_fields_set_get(self):
|
82 |
"""
|
83 |
Tests setting and getting various tags in various file formats
|
84 |
sets/gets all fields, then saves to file, then checks field values
|
85 |
"""
|
86 |
def test_field(tag, field, test_value=None):
|
87 |
if not test_value:
|
88 |
test_value = u'string with some ąčę %d' % random.randint(1, 100)
|
89 |
setattr(tag, field, test_value)
|
90 |
cached_value = getattr(tag, field)
|
91 |
self.assertEqual(test_value, cached_value)
|
92 |
return test_value
|
93 |
|
94 |
def test_field_array(tag, field, test_value=None):
|
95 |
if not test_value:
|
96 |
test_value = [u'ąčę xx %d%d xx' % (i, random.randint(1, 100)) for i in range(0, 5)]
|
97 |
return test_field(tag, field, test_value)
|
98 |
|
99 |
def test_field_int(tag, field, test_value=None):
|
100 |
if not test_value:
|
101 |
test_value = random.randint(1, 100)
|
102 |
return test_field(tag, field, test_value)
|
103 |
|
104 |
def test_field_bool(tag, field, test_value=None):
|
105 |
if not test_value:
|
106 |
test_value = [True, False][random.randint(0, 1)]
|
107 |
return test_field(tag, field, test_value)
|
108 |
|
109 |
for test_filename in self.test_files:
|
110 |
print "testing %s" % test_filename
|
111 |
filename = os.path.join(self.test_dir, test_filename)
|
112 |
print "f1: %s" % filename
|
113 |
file = MetaFile(filename)
|
114 |
tag = file.tag
|
115 |
mem = dict()
|
116 |
|
117 |
for prop, type, test_val in self.field_test_map:
|
118 |
if type == 'str':
|
119 |
value = test_field(tag, prop, test_val)
|
120 |
elif type == 'int':
|
121 |
value = test_field_int(tag, prop, test_val)
|
122 |
elif type == 'array':
|
123 |
value = test_field_array(tag, prop, test_val)
|
124 |
elif type == 'bool':
|
125 |
value = test_field_bool(tag, prop, test_val)
|
126 |
else:
|
127 |
self.fail('bad field_test_map')
|
128 |
mem[prop] = value
|
129 |
|
130 |
# save and reopen
|
131 |
print "before save"
|
132 |
file.save()
|
133 |
del file
|
134 |
file2 = MetaFile(filename)
|
135 |
tag2 = file2.tag
|
136 |
print "f2: %s" % filename
|
137 |
for k in tag2.map.keys():
|
138 |
print k
|
139 |
# check what we set previously
|
140 |
for prop, value in mem.items():
|
141 |
#print prop
|
142 |
#err_msg = "property '%s' did not have correct value after rereading file '%s'" % (prop, test_filename)
|
143 |
self.assertEqual(value, getattr(tag2, prop))#, err_msg)
|
144 |
|
145 |
def test2_fields_copy(self):
|
146 |
"""
|
147 |
Tests copying all fields from one file to another
|
148 |
"""
|
149 |
def check(tag1, tag2, after_reread=False):
|
150 |
for entry in self.field_test_map:
|
151 |
prop = entry[0]
|
152 |
err_msg = "property '%s' did not have correct value" % prop
|
153 |
if after_reread:
|
154 |
err_msg += ' after rereading file'
|
155 |
else:
|
156 |
err_msg += ' after set/get'
|
157 |
self.assertEqual(getattr(tag1, prop), getattr(tag2, prop), err_msg)
|
158 |
|
159 |
i = 0
|
160 |
while i < len(self.test_files)-1:
|
161 |
print "copying tags from '%s' to '%s'" % (self.test_files[i], self.test_files[i+1])
|
162 |
# copy fields of first file to the second one
|
163 |
filename1 = os.path.join(self.test_dir, self.test_files[i])
|
164 |
filename2 = os.path.join(self.test_dir, self.test_files[i+1])
|
165 |
file1 = MetaFile(filename1)
|
166 |
file2 = MetaFile(filename2)
|
167 |
tag1 = file1.tag
|
168 |
tag2 = file2.tag
|
169 |
tag1.copy_to(tag2)
|
170 |
# check
|
171 |
check(tag1, tag2)
|
172 |
|
173 |
# save and recheck
|
174 |
file2.save()
|
175 |
file2 = MetaFile(filename2)
|
176 |
tag2 = file2.tag
|
177 |
check(tag1, tag2, True)
|
178 |
|
179 |
i += 1
|
180 |
|
181 |
def test3_fields_clear(self):
|
182 |
"""
|
183 |
Tests clearing all fields
|
184 |
"""
|
185 |
pass
|