1# -*- coding: utf-8 -*-
2
3import os
4
5from mutagen.dsf import DSF, DSFFile, delete
6from mutagen.dsf import error as DSFError
7
8from tests import TestCase, DATA_DIR, get_temp_copy
9
10
11class TDSF(TestCase):
12    silence_1 = os.path.join(DATA_DIR, '2822400-1ch-0s-silence.dsf')
13    silence_2 = os.path.join(DATA_DIR, '5644800-2ch-s01-silence.dsf')
14
15    has_tags = os.path.join(DATA_DIR, 'with-id3.dsf')
16    no_tags = os.path.join(DATA_DIR, 'without-id3.dsf')
17
18    def setUp(self):
19        self.filename_1 = get_temp_copy(self.has_tags)
20        self.filename_2 = get_temp_copy(self.no_tags)
21
22        self.dsf_tmp_id3 = DSF(self.filename_1)
23        self.dsf_tmp_no_id3 = DSF(self.filename_2)
24
25        self.dsf_1 = DSF(self.silence_1)
26        self.dsf_2 = DSF(self.silence_2)
27
28    def test_channels(self):
29        self.failUnlessEqual(self.dsf_1.info.channels, 1)
30        self.failUnlessEqual(self.dsf_2.info.channels, 2)
31
32    def test_length(self):
33        self.failUnlessEqual(self.dsf_1.info.length, 0)
34        self.failUnlessEqual(self.dsf_2.info.length, 0.01)
35
36    def test_sampling_frequency(self):
37        self.failUnlessEqual(self.dsf_1.info.sample_rate, 2822400)
38        self.failUnlessEqual(self.dsf_2.info.sample_rate, 5644800)
39
40    def test_bits_per_sample(self):
41        self.failUnlessEqual(self.dsf_1.info.bits_per_sample, 1)
42
43    def test_notdsf(self):
44        self.failUnlessRaises(
45            DSFError, DSF, os.path.join(DATA_DIR, 'empty.ofr'))
46
47    def test_pprint(self):
48        self.failUnless(self.dsf_tmp_id3.pprint())
49
50    def test_delete(self):
51        self.dsf_tmp_id3.delete()
52        self.failIf(self.dsf_tmp_id3.tags)
53        self.failUnless(DSF(self.filename_1).tags is None)
54
55    def test_module_delete(self):
56        delete(self.filename_1)
57        self.failUnless(DSF(self.filename_1).tags is None)
58
59    def test_module_double_delete(self):
60        delete(self.filename_1)
61        delete(self.filename_1)
62
63    def test_pprint_no_tags(self):
64        self.dsf_tmp_id3.tags = None
65        self.failUnless(self.dsf_tmp_id3.pprint())
66
67    def test_save_no_tags(self):
68        self.dsf_tmp_id3.tags = None
69        self.dsf_tmp_id3.save()
70        self.assertTrue(self.dsf_tmp_id3.tags is None)
71
72    def test_add_tags_already_there(self):
73        self.failUnless(self.dsf_tmp_id3.tags)
74        self.failUnlessRaises(Exception, self.dsf_tmp_id3.add_tags)
75
76    def test_mime(self):
77        self.failUnless("audio/dsf" in self.dsf_tmp_id3.mime)
78
79    def test_loaded_tags(self):
80        self.failUnless(self.dsf_tmp_id3["TIT2"] == "DSF title")
81
82    def test_roundtrip(self):
83        self.failUnlessEqual(self.dsf_tmp_id3["TIT2"], ["DSF title"])
84        self.dsf_tmp_id3.save()
85        new = DSF(self.dsf_tmp_id3.filename)
86        self.failUnlessEqual(new["TIT2"], ["DSF title"])
87
88    def test_save_tags(self):
89        from mutagen.id3 import TIT2
90        tags = self.dsf_tmp_id3.tags
91        tags.add(TIT2(encoding=3, text="foobar"))
92        tags.save()
93
94        new = DSF(self.dsf_tmp_id3.filename)
95        self.failUnlessEqual(new["TIT2"], ["foobar"])
96
97    def test_corrupt_tag(self):
98        with open(self.filename_1, "r+b") as h:
99            chunk = DSFFile(h).dsd_chunk
100            h.seek(chunk.offset_metdata_chunk)
101            h.seek(4, 1)
102            h.write(b"\xff\xff")
103        self.assertRaises(DSFError, DSF, self.filename_1)
104
105    def test_padding(self):
106        DSF(self.filename_1).save()
107        self.assertEqual(DSF(self.filename_1).tags._padding, 1024)
108        DSF(self.filename_1).save()
109        self.assertEqual(DSF(self.filename_1).tags._padding, 1024)
110
111        tags = DSF(self.filename_1)
112        tags.save(padding=lambda x: 1)
113        self.assertEqual(DSF(self.filename_1).tags._padding, 1)
114
115        tags = DSF(self.filename_1)
116        tags.save(padding=lambda x: 100)
117        self.assertEqual(DSF(self.filename_1).tags._padding, 100)
118
119        tags = DSF(self.filename_1)
120        self.assertRaises(DSFError, tags.save, padding=lambda x: -1)
121
122    def tearDown(self):
123        os.unlink(self.filename_1)
124        os.unlink(self.filename_2)
125