blob: f4abd2a81cb679e8ece31d75602cca14d6d60f24 [file] [log] [blame]
Serhiy Storchaka0fa01732013-10-13 17:47:22 +03001from test.test_support import findfile, TESTFN, unlink
2import unittest
3import array
4import io
5import pickle
6import sys
7import base64
8
Serhiy Storchakae891de32013-12-28 10:18:44 +02009class UnseekableIO(file):
Serhiy Storchakad1a61dc2013-12-14 20:34:33 +020010 def tell(self):
11 raise io.UnsupportedOperation
12
13 def seek(self, *args, **kwargs):
14 raise io.UnsupportedOperation
15
Serhiy Storchaka0fa01732013-10-13 17:47:22 +030016def fromhex(s):
17 return base64.b16decode(s.replace(' ', ''))
18
19def byteswap2(data):
Serhiy Storchaka5397c972013-11-21 11:04:37 +020020 a = array.array('h')
21 a.fromstring(data)
Serhiy Storchaka0fa01732013-10-13 17:47:22 +030022 a.byteswap()
23 return a.tostring()
24
25def byteswap3(data):
26 ba = bytearray(data)
27 ba[::3] = data[2::3]
28 ba[2::3] = data[::3]
29 return bytes(ba)
30
31def byteswap4(data):
Serhiy Storchaka5397c972013-11-21 11:04:37 +020032 a = array.array('i')
33 a.fromstring(data)
Serhiy Storchaka0fa01732013-10-13 17:47:22 +030034 a.byteswap()
35 return a.tostring()
36
37
38class AudioTests:
39 close_fd = False
40
41 def setUp(self):
42 self.f = self.fout = None
43
44 def tearDown(self):
45 if self.f is not None:
46 self.f.close()
47 if self.fout is not None:
48 self.fout.close()
49 unlink(TESTFN)
50
51 def check_params(self, f, nchannels, sampwidth, framerate, nframes,
52 comptype, compname):
53 self.assertEqual(f.getnchannels(), nchannels)
54 self.assertEqual(f.getsampwidth(), sampwidth)
55 self.assertEqual(f.getframerate(), framerate)
56 self.assertEqual(f.getnframes(), nframes)
57 self.assertEqual(f.getcomptype(), comptype)
58 self.assertEqual(f.getcompname(), compname)
59
60 params = f.getparams()
61 self.assertEqual(params,
62 (nchannels, sampwidth, framerate, nframes, comptype, compname))
63
64 dump = pickle.dumps(params)
65 self.assertEqual(pickle.loads(dump), params)
66
67
68class AudioWriteTests(AudioTests):
69
70 def create_file(self, testfile):
71 f = self.fout = self.module.open(testfile, 'wb')
72 f.setnchannels(self.nchannels)
73 f.setsampwidth(self.sampwidth)
74 f.setframerate(self.framerate)
75 f.setcomptype(self.comptype, self.compname)
76 return f
77
78 def check_file(self, testfile, nframes, frames):
79 f = self.module.open(testfile, 'rb')
80 try:
81 self.assertEqual(f.getnchannels(), self.nchannels)
82 self.assertEqual(f.getsampwidth(), self.sampwidth)
83 self.assertEqual(f.getframerate(), self.framerate)
84 self.assertEqual(f.getnframes(), nframes)
85 self.assertEqual(f.readframes(nframes), frames)
86 finally:
87 f.close()
88
89 def test_write_params(self):
90 f = self.create_file(TESTFN)
91 f.setnframes(self.nframes)
92 f.writeframes(self.frames)
93 self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
94 self.nframes, self.comptype, self.compname)
95 f.close()
96
97 def test_write(self):
98 f = self.create_file(TESTFN)
99 f.setnframes(self.nframes)
100 f.writeframes(self.frames)
101 f.close()
102
103 self.check_file(TESTFN, self.nframes, self.frames)
104
105 def test_incompleted_write(self):
106 with open(TESTFN, 'wb') as testfile:
107 testfile.write(b'ababagalamaga')
108 f = self.create_file(testfile)
109 f.setnframes(self.nframes + 1)
110 f.writeframes(self.frames)
111 f.close()
112
113 with open(TESTFN, 'rb') as testfile:
114 self.assertEqual(testfile.read(13), b'ababagalamaga')
115 self.check_file(testfile, self.nframes, self.frames)
116
117 def test_multiple_writes(self):
118 with open(TESTFN, 'wb') as testfile:
119 testfile.write(b'ababagalamaga')
120 f = self.create_file(testfile)
121 f.setnframes(self.nframes)
122 framesize = self.nchannels * self.sampwidth
123 f.writeframes(self.frames[:-framesize])
124 f.writeframes(self.frames[-framesize:])
125 f.close()
126
127 with open(TESTFN, 'rb') as testfile:
128 self.assertEqual(testfile.read(13), b'ababagalamaga')
129 self.check_file(testfile, self.nframes, self.frames)
130
131 def test_overflowed_write(self):
132 with open(TESTFN, 'wb') as testfile:
133 testfile.write(b'ababagalamaga')
134 f = self.create_file(testfile)
135 f.setnframes(self.nframes - 1)
136 f.writeframes(self.frames)
137 f.close()
138
139 with open(TESTFN, 'rb') as testfile:
140 self.assertEqual(testfile.read(13), b'ababagalamaga')
141 self.check_file(testfile, self.nframes, self.frames)
142
Serhiy Storchakad1a61dc2013-12-14 20:34:33 +0200143 def test_unseekable_read(self):
144 f = self.create_file(TESTFN)
145 f.setnframes(self.nframes)
146 f.writeframes(self.frames)
147 f.close()
148
149 with UnseekableIO(TESTFN, 'rb') as testfile:
150 self.check_file(testfile, self.nframes, self.frames)
151
152 def test_unseekable_write(self):
153 with UnseekableIO(TESTFN, 'wb') as testfile:
154 f = self.create_file(testfile)
155 f.setnframes(self.nframes)
156 f.writeframes(self.frames)
157 f.close()
158 self.fout = None
159
160 self.check_file(TESTFN, self.nframes, self.frames)
161
162 def test_unseekable_incompleted_write(self):
163 with UnseekableIO(TESTFN, 'wb') as testfile:
164 testfile.write(b'ababagalamaga')
165 f = self.create_file(testfile)
166 f.setnframes(self.nframes + 1)
167 try:
168 f.writeframes(self.frames)
169 except IOError:
170 pass
171 try:
172 f.close()
173 except IOError:
174 pass
175
176 with open(TESTFN, 'rb') as testfile:
177 self.assertEqual(testfile.read(13), b'ababagalamaga')
178 self.check_file(testfile, self.nframes + 1, self.frames)
179
180 def test_unseekable_overflowed_write(self):
181 with UnseekableIO(TESTFN, 'wb') as testfile:
182 testfile.write(b'ababagalamaga')
183 f = self.create_file(testfile)
184 f.setnframes(self.nframes - 1)
185 try:
186 f.writeframes(self.frames)
187 except IOError:
188 pass
189 try:
190 f.close()
191 except IOError:
192 pass
193
194 with open(TESTFN, 'rb') as testfile:
195 self.assertEqual(testfile.read(13), b'ababagalamaga')
196 framesize = self.nchannels * self.sampwidth
197 self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
198
Serhiy Storchaka0fa01732013-10-13 17:47:22 +0300199
200class AudioTestsWithSourceFile(AudioTests):
201
202 @classmethod
203 def setUpClass(cls):
204 cls.sndfilepath = findfile(cls.sndfilename, subdir='audiodata')
205
206 def test_read_params(self):
207 f = self.f = self.module.open(self.sndfilepath)
208 #self.assertEqual(f.getfp().name, self.sndfilepath)
209 self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
210 self.sndfilenframes, self.comptype, self.compname)
211
212 def test_close(self):
Serhiy Storchakae1a8a402013-10-14 20:09:30 +0300213 with open(self.sndfilepath, 'rb') as testfile:
214 f = self.f = self.module.open(testfile)
215 self.assertFalse(testfile.closed)
216 f.close()
217 self.assertEqual(testfile.closed, self.close_fd)
218 with open(TESTFN, 'wb') as testfile:
219 fout = self.fout = self.module.open(testfile, 'wb')
220 self.assertFalse(testfile.closed)
221 with self.assertRaises(self.module.Error):
222 fout.close()
223 self.assertEqual(testfile.closed, self.close_fd)
224 fout.close() # do nothing
Serhiy Storchaka0fa01732013-10-13 17:47:22 +0300225
226 def test_read(self):
227 framesize = self.nchannels * self.sampwidth
228 chunk1 = self.frames[:2 * framesize]
229 chunk2 = self.frames[2 * framesize: 4 * framesize]
230 f = self.f = self.module.open(self.sndfilepath)
231 self.assertEqual(f.readframes(0), b'')
232 self.assertEqual(f.tell(), 0)
233 self.assertEqual(f.readframes(2), chunk1)
234 f.rewind()
235 pos0 = f.tell()
236 self.assertEqual(pos0, 0)
237 self.assertEqual(f.readframes(2), chunk1)
238 pos2 = f.tell()
239 self.assertEqual(pos2, 2)
240 self.assertEqual(f.readframes(2), chunk2)
241 f.setpos(pos2)
242 self.assertEqual(f.readframes(2), chunk2)
243 f.setpos(pos0)
244 self.assertEqual(f.readframes(2), chunk1)
245 with self.assertRaises(self.module.Error):
246 f.setpos(-1)
247 with self.assertRaises(self.module.Error):
248 f.setpos(f.getnframes() + 1)
249
250 def test_copy(self):
251 f = self.f = self.module.open(self.sndfilepath)
252 fout = self.fout = self.module.open(TESTFN, 'wb')
253 fout.setparams(f.getparams())
254 i = 0
255 n = f.getnframes()
256 while n > 0:
257 i += 1
258 fout.writeframes(f.readframes(i))
259 n -= i
260 fout.close()
261 fout = self.fout = self.module.open(TESTFN, 'rb')
262 f.rewind()
263 self.assertEqual(f.getparams(), fout.getparams())
264 self.assertEqual(f.readframes(f.getnframes()),
265 fout.readframes(fout.getnframes()))
266
267 def test_read_not_from_start(self):
268 with open(TESTFN, 'wb') as testfile:
269 testfile.write(b'ababagalamaga')
270 with open(self.sndfilepath, 'rb') as f:
271 testfile.write(f.read())
272
273 with open(TESTFN, 'rb') as testfile:
274 self.assertEqual(testfile.read(13), b'ababagalamaga')
275 f = self.module.open(testfile, 'rb')
276 try:
277 self.assertEqual(f.getnchannels(), self.nchannels)
278 self.assertEqual(f.getsampwidth(), self.sampwidth)
279 self.assertEqual(f.getframerate(), self.framerate)
280 self.assertEqual(f.getnframes(), self.sndfilenframes)
281 self.assertEqual(f.readframes(self.nframes), self.frames)
282 finally:
283 f.close()