blob: 7ed04140d929402e4c90966336ad3a94981d761b [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
Serhiy Storchaka655720e2014-12-15 14:02:43 +020064 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
65 dump = pickle.dumps(params, proto)
66 self.assertEqual(pickle.loads(dump), params)
Serhiy Storchaka0fa01732013-10-13 17:47:22 +030067
68
69class AudioWriteTests(AudioTests):
70
71 def create_file(self, testfile):
72 f = self.fout = self.module.open(testfile, 'wb')
73 f.setnchannels(self.nchannels)
74 f.setsampwidth(self.sampwidth)
75 f.setframerate(self.framerate)
76 f.setcomptype(self.comptype, self.compname)
77 return f
78
79 def check_file(self, testfile, nframes, frames):
80 f = self.module.open(testfile, 'rb')
81 try:
82 self.assertEqual(f.getnchannels(), self.nchannels)
83 self.assertEqual(f.getsampwidth(), self.sampwidth)
84 self.assertEqual(f.getframerate(), self.framerate)
85 self.assertEqual(f.getnframes(), nframes)
86 self.assertEqual(f.readframes(nframes), frames)
87 finally:
88 f.close()
89
90 def test_write_params(self):
91 f = self.create_file(TESTFN)
92 f.setnframes(self.nframes)
93 f.writeframes(self.frames)
94 self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
95 self.nframes, self.comptype, self.compname)
96 f.close()
97
98 def test_write(self):
99 f = self.create_file(TESTFN)
100 f.setnframes(self.nframes)
101 f.writeframes(self.frames)
102 f.close()
103
104 self.check_file(TESTFN, self.nframes, self.frames)
105
106 def test_incompleted_write(self):
107 with open(TESTFN, 'wb') as testfile:
108 testfile.write(b'ababagalamaga')
109 f = self.create_file(testfile)
110 f.setnframes(self.nframes + 1)
111 f.writeframes(self.frames)
112 f.close()
113
114 with open(TESTFN, 'rb') as testfile:
115 self.assertEqual(testfile.read(13), b'ababagalamaga')
116 self.check_file(testfile, self.nframes, self.frames)
117
118 def test_multiple_writes(self):
119 with open(TESTFN, 'wb') as testfile:
120 testfile.write(b'ababagalamaga')
121 f = self.create_file(testfile)
122 f.setnframes(self.nframes)
123 framesize = self.nchannels * self.sampwidth
124 f.writeframes(self.frames[:-framesize])
125 f.writeframes(self.frames[-framesize:])
126 f.close()
127
128 with open(TESTFN, 'rb') as testfile:
129 self.assertEqual(testfile.read(13), b'ababagalamaga')
130 self.check_file(testfile, self.nframes, self.frames)
131
132 def test_overflowed_write(self):
133 with open(TESTFN, 'wb') as testfile:
134 testfile.write(b'ababagalamaga')
135 f = self.create_file(testfile)
136 f.setnframes(self.nframes - 1)
137 f.writeframes(self.frames)
138 f.close()
139
140 with open(TESTFN, 'rb') as testfile:
141 self.assertEqual(testfile.read(13), b'ababagalamaga')
142 self.check_file(testfile, self.nframes, self.frames)
143
Serhiy Storchakad1a61dc2013-12-14 20:34:33 +0200144 def test_unseekable_read(self):
145 f = self.create_file(TESTFN)
146 f.setnframes(self.nframes)
147 f.writeframes(self.frames)
148 f.close()
149
150 with UnseekableIO(TESTFN, 'rb') as testfile:
151 self.check_file(testfile, self.nframes, self.frames)
152
153 def test_unseekable_write(self):
154 with UnseekableIO(TESTFN, 'wb') as testfile:
155 f = self.create_file(testfile)
156 f.setnframes(self.nframes)
157 f.writeframes(self.frames)
158 f.close()
159 self.fout = None
160
161 self.check_file(TESTFN, self.nframes, self.frames)
162
163 def test_unseekable_incompleted_write(self):
164 with UnseekableIO(TESTFN, 'wb') as testfile:
165 testfile.write(b'ababagalamaga')
166 f = self.create_file(testfile)
167 f.setnframes(self.nframes + 1)
168 try:
169 f.writeframes(self.frames)
170 except IOError:
171 pass
172 try:
173 f.close()
174 except IOError:
175 pass
176
177 with open(TESTFN, 'rb') as testfile:
178 self.assertEqual(testfile.read(13), b'ababagalamaga')
179 self.check_file(testfile, self.nframes + 1, self.frames)
180
181 def test_unseekable_overflowed_write(self):
182 with UnseekableIO(TESTFN, 'wb') as testfile:
183 testfile.write(b'ababagalamaga')
184 f = self.create_file(testfile)
185 f.setnframes(self.nframes - 1)
186 try:
187 f.writeframes(self.frames)
188 except IOError:
189 pass
190 try:
191 f.close()
192 except IOError:
193 pass
194
195 with open(TESTFN, 'rb') as testfile:
196 self.assertEqual(testfile.read(13), b'ababagalamaga')
197 framesize = self.nchannels * self.sampwidth
198 self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
199
Serhiy Storchaka0fa01732013-10-13 17:47:22 +0300200
201class AudioTestsWithSourceFile(AudioTests):
202
203 @classmethod
204 def setUpClass(cls):
205 cls.sndfilepath = findfile(cls.sndfilename, subdir='audiodata')
206
207 def test_read_params(self):
208 f = self.f = self.module.open(self.sndfilepath)
209 #self.assertEqual(f.getfp().name, self.sndfilepath)
210 self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
211 self.sndfilenframes, self.comptype, self.compname)
212
213 def test_close(self):
Serhiy Storchakae1a8a402013-10-14 20:09:30 +0300214 with open(self.sndfilepath, 'rb') as testfile:
215 f = self.f = self.module.open(testfile)
216 self.assertFalse(testfile.closed)
217 f.close()
218 self.assertEqual(testfile.closed, self.close_fd)
219 with open(TESTFN, 'wb') as testfile:
220 fout = self.fout = self.module.open(testfile, 'wb')
221 self.assertFalse(testfile.closed)
222 with self.assertRaises(self.module.Error):
223 fout.close()
224 self.assertEqual(testfile.closed, self.close_fd)
225 fout.close() # do nothing
Serhiy Storchaka0fa01732013-10-13 17:47:22 +0300226
227 def test_read(self):
228 framesize = self.nchannels * self.sampwidth
229 chunk1 = self.frames[:2 * framesize]
230 chunk2 = self.frames[2 * framesize: 4 * framesize]
231 f = self.f = self.module.open(self.sndfilepath)
232 self.assertEqual(f.readframes(0), b'')
233 self.assertEqual(f.tell(), 0)
234 self.assertEqual(f.readframes(2), chunk1)
235 f.rewind()
236 pos0 = f.tell()
237 self.assertEqual(pos0, 0)
238 self.assertEqual(f.readframes(2), chunk1)
239 pos2 = f.tell()
240 self.assertEqual(pos2, 2)
241 self.assertEqual(f.readframes(2), chunk2)
242 f.setpos(pos2)
243 self.assertEqual(f.readframes(2), chunk2)
244 f.setpos(pos0)
245 self.assertEqual(f.readframes(2), chunk1)
246 with self.assertRaises(self.module.Error):
247 f.setpos(-1)
248 with self.assertRaises(self.module.Error):
249 f.setpos(f.getnframes() + 1)
250
251 def test_copy(self):
252 f = self.f = self.module.open(self.sndfilepath)
253 fout = self.fout = self.module.open(TESTFN, 'wb')
254 fout.setparams(f.getparams())
255 i = 0
256 n = f.getnframes()
257 while n > 0:
258 i += 1
259 fout.writeframes(f.readframes(i))
260 n -= i
261 fout.close()
262 fout = self.fout = self.module.open(TESTFN, 'rb')
263 f.rewind()
264 self.assertEqual(f.getparams(), fout.getparams())
265 self.assertEqual(f.readframes(f.getnframes()),
266 fout.readframes(fout.getnframes()))
267
268 def test_read_not_from_start(self):
269 with open(TESTFN, 'wb') as testfile:
270 testfile.write(b'ababagalamaga')
271 with open(self.sndfilepath, 'rb') as f:
272 testfile.write(f.read())
273
274 with open(TESTFN, 'rb') as testfile:
275 self.assertEqual(testfile.read(13), b'ababagalamaga')
276 f = self.module.open(testfile, 'rb')
277 try:
278 self.assertEqual(f.getnchannels(), self.nchannels)
279 self.assertEqual(f.getsampwidth(), self.sampwidth)
280 self.assertEqual(f.getframerate(), self.framerate)
281 self.assertEqual(f.getnframes(), self.sndfilenframes)
282 self.assertEqual(f.readframes(self.nframes), self.frames)
283 finally:
284 f.close()