1# -*- coding: utf-8 -*- 2 3from tests import TestCase 4from mutagen._vorbis import VComment, VCommentDict, istag, error 5from mutagen._compat import text_type, PY3 6 7 8class Tistag(TestCase): 9 10 def test_empty(self): 11 self.failIf(istag("")) 12 13 def test_tilde(self): 14 self.failIf(istag("ti~tle")) 15 16 def test_equals(self): 17 self.failIf(istag("ti=tle")) 18 19 def test_less(self): 20 self.failIf(istag("ti\x19tle")) 21 22 def test_greater(self): 23 self.failIf(istag("ti\xa0tle")) 24 25 def test_simple(self): 26 self.failUnless(istag("title")) 27 28 def test_space(self): 29 self.failUnless(istag("ti tle")) 30 31 def test_ugly(self): 32 self.failUnless(istag("!{}[]-_()*&")) 33 34 def test_unicode(self): 35 self.failUnless(istag(u"ti tle")) 36 37 if PY3: 38 def test_py3(self): 39 self.failUnlessRaises(TypeError, istag, b"abc") 40 41 42class TVComment(TestCase): 43 44 def setUp(self): 45 self.c = VComment() 46 self.c.append(("artist", u"piman")) 47 self.c.append(("artist", u"mu")) 48 self.c.append(("title", u"more fakes")) 49 50 def test_invalid_init(self): 51 self.failUnlessRaises(TypeError, VComment, []) 52 53 def test_equal(self): 54 self.failUnlessEqual(self.c, self.c) 55 56 def test_not_header(self): 57 self.failUnlessRaises(error, VComment, b"foo") 58 59 def test_unset_framing_bit(self): 60 self.failUnlessRaises( 61 error, VComment, b"\x00\x00\x00\x00" * 2 + b"\x00") 62 63 def test_empty_valid(self): 64 self.failIf(VComment(b"\x00\x00\x00\x00" * 2 + b"\x01")) 65 66 def test_validate(self): 67 self.failUnless(self.c.validate()) 68 69 def test_validate_broken_key(self): 70 self.c.append((1, u"valid")) 71 self.failUnlessRaises(ValueError, self.c.validate) 72 self.failUnlessRaises(ValueError, self.c.write) 73 74 def test_validate_broken_value(self): 75 self.c.append((u"valid", 1)) 76 self.failUnlessRaises(ValueError, self.c.validate) 77 self.failUnlessRaises(ValueError, self.c.write) 78 79 def test_validate_nonunicode_value(self): 80 self.c.append((u"valid", b"wt\xff")) 81 self.failUnlessRaises(ValueError, self.c.validate) 82 self.failUnlessRaises(ValueError, self.c.write) 83 84 def test_vendor_default(self): 85 self.failUnless(self.c.vendor.startswith(u"Mutagen")) 86 87 def test_vendor_set(self): 88 self.c.vendor = u"Not Mutagen" 89 self.failUnless(self.c.write()[4:].startswith(b"Not Mutagen")) 90 91 def test_vendor_invalid(self): 92 self.c.vendor = b"\xffNot Mutagen" 93 self.failUnlessRaises(ValueError, self.c.validate) 94 self.failUnlessRaises(ValueError, self.c.write) 95 96 def test_validate_utf8_value(self): 97 self.c.append((u"valid", b"\xc3\xbc\xc3\xb6\xc3\xa4")) 98 if PY3: 99 self.failUnlessRaises(ValueError, self.c.validate) 100 else: 101 self.c.validate() 102 103 def test_invalid_format_strict(self): 104 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x03\x00\x00' 105 b'\x00abc\x01') 106 self.failUnlessRaises(error, VComment, data, errors='strict') 107 108 def test_invalid_format_replace(self): 109 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x03\x00\x00' 110 b'\x00abc\x01') 111 comment = VComment(data) 112 self.failUnlessEqual(u"abc", comment[0][1]) 113 114 def test_python_key_value_type(self): 115 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x03\x00\x00' 116 b'\x00abc\x01') 117 comment = VComment(data) 118 self.assertTrue(isinstance(comment[0][0], type(''))) 119 self.assertTrue(isinstance(comment[0][1], text_type)) 120 121 if PY3: 122 def test_python3_strict_str(self): 123 comment = VComment() 124 comment.append((u"abc", u"test")) 125 comment.validate() 126 comment[0] = (u"abc", b"test") 127 self.failUnlessRaises(ValueError, comment.validate) 128 comment[0] = (b"abc", u"test") 129 self.failUnlessRaises(ValueError, comment.validate) 130 131 def test_invalid_format_ignore(self): 132 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x03\x00\x00' 133 b'\x00abc\x01') 134 comment = VComment(data, errors='ignore') 135 self.failIf(len(comment)) 136 137 # Slightly different test data than above, we want the tag name 138 # to be valid UTF-8 but not valid ASCII. 139 def test_invalid_tag_strict(self): 140 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x04\x00\x00' 141 b'\x00\xc2\xaa=c\x01') 142 self.failUnlessRaises(error, VComment, data, errors='strict') 143 144 def test_invalid_tag_replace(self): 145 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x04\x00\x00' 146 b'\x00\xc2\xaa=c\x01') 147 comment = VComment(data) 148 self.failUnlessEqual(u"?=c", comment.pprint()) 149 150 def test_invalid_tag_ignore(self): 151 data = (b'\x07\x00\x00\x00Mutagen\x01\x00\x00\x00\x04\x00\x00' 152 b'\x00\xc2\xaa=c\x01') 153 comment = VComment(data, errors='ignore') 154 self.failIf(len(comment)) 155 156 def test_roundtrip(self): 157 self.assertReallyEqual(self.c, VComment(self.c.write())) 158 159 160class TVCommentDict(TestCase): 161 162 Kind = VCommentDict 163 164 def setUp(self): 165 self.c = self.Kind() 166 self.c["artist"] = ["mu", "piman"] 167 self.c["title"] = u"more fakes" 168 169 def test_correct_len(self): 170 self.failUnlessEqual(len(self.c), 3) 171 172 def test_keys(self): 173 self.failUnless("artist" in self.c.keys()) 174 self.failUnless("title" in self.c.keys()) 175 176 def test_values(self): 177 self.failUnless(["mu", "piman"] in self.c.values()) 178 self.failUnless(["more fakes"] in self.c.values()) 179 180 def test_items(self): 181 self.failUnless(("artist", ["mu", "piman"]) in self.c.items()) 182 self.failUnless(("title", ["more fakes"]) in self.c.items()) 183 184 def test_equal(self): 185 self.failUnlessEqual(self.c, self.c) 186 187 def test_get(self): 188 self.failUnlessEqual(self.c["artist"], ["mu", "piman"]) 189 self.failUnlessEqual(self.c["title"], ["more fakes"]) 190 191 def test_set(self): 192 self.c["woo"] = "bar" 193 self.failUnlessEqual(self.c["woo"], ["bar"]) 194 195 def test_slice(self): 196 l = [("foo", "bar"), ("foo", "bar2")] 197 self.c[:] = l 198 self.assertEqual(self.c[:], l) 199 self.failUnlessEqual(self.c["foo"], ["bar", "bar2"]) 200 del self.c[:] 201 self.assertEqual(self.c[:], []) 202 203 def test_iter(self): 204 self.assertEqual(next(iter(self.c)), ("artist", "mu")) 205 self.assertEqual(list(self.c)[0], ("artist", "mu")) 206 207 def test_del(self): 208 del(self.c["title"]) 209 self.failUnlessRaises(KeyError, self.c.__getitem__, "title") 210 211 def test_contains(self): 212 self.failIf("foo" in self.c) 213 self.failUnless("title" in self.c) 214 215 def test_get_case(self): 216 self.failUnlessEqual(self.c["ARTIST"], ["mu", "piman"]) 217 218 def test_set_case(self): 219 self.c["TITLE"] = "another fake" 220 self.failUnlessEqual(self.c["title"], ["another fake"]) 221 222 def test_set_preserve_case(self): 223 del(self.c["title"]) 224 self.c["TiTlE"] = "blah" 225 self.failUnless(("TiTlE", "blah") in list(self.c)) 226 self.failUnless("title" in self.c) 227 228 def test_contains_case(self): 229 self.failUnless("TITLE" in self.c) 230 231 def test_del_case(self): 232 del(self.c["TITLE"]) 233 self.failUnlessRaises(KeyError, self.c.__getitem__, "title") 234 235 def test_get_failure(self): 236 self.failUnlessRaises(KeyError, self.c.__getitem__, "woo") 237 238 def test_del_failure(self): 239 self.failUnlessRaises(KeyError, self.c.__delitem__, "woo") 240 241 def test_roundtrip(self): 242 self.failUnlessEqual(self.c, self.Kind(self.c.write())) 243 244 def test_roundtrip_vc(self): 245 self.failUnlessEqual(self.c, VComment(self.c.write())) 246 247 def test_case_items_426(self): 248 self.c.append(("WOO", "bar")) 249 self.failUnless(("woo", ["bar"]) in self.c.items()) 250 251 def test_empty(self): 252 self.c = VCommentDict() 253 self.failIf(list(self.c.keys())) 254 self.failIf(list(self.c.values())) 255 self.failIf(list(self.c.items())) 256 257 def test_as_dict(self): 258 d = self.c.as_dict() 259 self.failUnless("artist" in d) 260 self.failUnless("title" in d) 261 self.failUnlessEqual(d["artist"], self.c["artist"]) 262 self.failUnlessEqual(d["title"], self.c["title"]) 263 264 def test_bad_key(self): 265 self.failUnlessRaises(ValueError, self.c.get, u"\u1234") 266 self.failUnlessRaises( 267 ValueError, self.c.__setitem__, u"\u1234", "foo") 268 self.failUnlessRaises( 269 ValueError, self.c.__delitem__, u"\u1234") 270 271 if PY3: 272 def test_py3_bad_key(self): 273 self.failUnlessRaises(TypeError, self.c.get, b"a") 274 self.failUnlessRaises( 275 TypeError, self.c.__setitem__, b"a", "foo") 276 self.failUnlessRaises( 277 TypeError, self.c.__delitem__, b"a") 278 279 def test_duplicate_keys(self): 280 self.c = VCommentDict() 281 keys = ("key", "Key", "KEY") 282 for key in keys: 283 self.c.append((key, "value")) 284 self.failUnlessEqual(len(self.c.keys()), 1) 285 self.failUnlessEqual(len(self.c.as_dict()), 1) 286