|
1 # Ridiculously simple test of the winsound module for Windows. |
|
2 |
|
3 import unittest |
|
4 from test import test_support |
|
5 import winsound, time |
|
6 import os |
|
7 import subprocess |
|
8 |
|
9 |
|
10 class BeepTest(unittest.TestCase): |
|
11 # As with PlaySoundTest, incorporate the _have_soundcard() check |
|
12 # into our test methods. If there's no audio device present, |
|
13 # winsound.Beep returns 0 and GetLastError() returns 127, which |
|
14 # is: ERROR_PROC_NOT_FOUND ("The specified procedure could not |
|
15 # be found"). (FWIW, virtual/Hyper-V systems fall under this |
|
16 # scenario as they have no sound devices whatsoever (not even |
|
17 # a legacy Beep device).) |
|
18 |
|
19 def test_errors(self): |
|
20 self.assertRaises(TypeError, winsound.Beep) |
|
21 self.assertRaises(ValueError, winsound.Beep, 36, 75) |
|
22 self.assertRaises(ValueError, winsound.Beep, 32768, 75) |
|
23 |
|
24 def test_extremes(self): |
|
25 self._beep(37, 75) |
|
26 self._beep(32767, 75) |
|
27 |
|
28 def test_increasingfrequency(self): |
|
29 for i in xrange(100, 2000, 100): |
|
30 self._beep(i, 75) |
|
31 |
|
32 def _beep(self, *args): |
|
33 # these tests used to use _have_soundcard(), but it's quite |
|
34 # possible to have a soundcard, and yet have the beep driver |
|
35 # disabled. So basically, we have no way of knowing whether |
|
36 # a beep should be produced or not, so currently if these |
|
37 # tests fail we're ignoring them |
|
38 # |
|
39 # XXX the right fix for this is to define something like |
|
40 # _have_enabled_beep_driver() and use that instead of the |
|
41 # try/except below |
|
42 try: |
|
43 winsound.Beep(*args) |
|
44 except RuntimeError: |
|
45 pass |
|
46 |
|
47 class MessageBeepTest(unittest.TestCase): |
|
48 |
|
49 def tearDown(self): |
|
50 time.sleep(0.5) |
|
51 |
|
52 def test_default(self): |
|
53 self.assertRaises(TypeError, winsound.MessageBeep, "bad") |
|
54 self.assertRaises(TypeError, winsound.MessageBeep, 42, 42) |
|
55 winsound.MessageBeep() |
|
56 |
|
57 def test_ok(self): |
|
58 winsound.MessageBeep(winsound.MB_OK) |
|
59 |
|
60 def test_asterisk(self): |
|
61 winsound.MessageBeep(winsound.MB_ICONASTERISK) |
|
62 |
|
63 def test_exclamation(self): |
|
64 winsound.MessageBeep(winsound.MB_ICONEXCLAMATION) |
|
65 |
|
66 def test_hand(self): |
|
67 winsound.MessageBeep(winsound.MB_ICONHAND) |
|
68 |
|
69 def test_question(self): |
|
70 winsound.MessageBeep(winsound.MB_ICONQUESTION) |
|
71 |
|
72 |
|
73 class PlaySoundTest(unittest.TestCase): |
|
74 |
|
75 def test_errors(self): |
|
76 self.assertRaises(TypeError, winsound.PlaySound) |
|
77 self.assertRaises(TypeError, winsound.PlaySound, "bad", "bad") |
|
78 self.assertRaises( |
|
79 RuntimeError, |
|
80 winsound.PlaySound, |
|
81 "none", winsound.SND_ASYNC | winsound.SND_MEMORY |
|
82 ) |
|
83 |
|
84 def test_alias_asterisk(self): |
|
85 if _have_soundcard(): |
|
86 winsound.PlaySound('SystemAsterisk', winsound.SND_ALIAS) |
|
87 else: |
|
88 self.assertRaises( |
|
89 RuntimeError, |
|
90 winsound.PlaySound, |
|
91 'SystemAsterisk', winsound.SND_ALIAS |
|
92 ) |
|
93 |
|
94 def test_alias_exclamation(self): |
|
95 if _have_soundcard(): |
|
96 winsound.PlaySound('SystemExclamation', winsound.SND_ALIAS) |
|
97 else: |
|
98 self.assertRaises( |
|
99 RuntimeError, |
|
100 winsound.PlaySound, |
|
101 'SystemExclamation', winsound.SND_ALIAS |
|
102 ) |
|
103 |
|
104 def test_alias_exit(self): |
|
105 if _have_soundcard(): |
|
106 winsound.PlaySound('SystemExit', winsound.SND_ALIAS) |
|
107 else: |
|
108 self.assertRaises( |
|
109 RuntimeError, |
|
110 winsound.PlaySound, |
|
111 'SystemExit', winsound.SND_ALIAS |
|
112 ) |
|
113 |
|
114 def test_alias_hand(self): |
|
115 if _have_soundcard(): |
|
116 winsound.PlaySound('SystemHand', winsound.SND_ALIAS) |
|
117 else: |
|
118 self.assertRaises( |
|
119 RuntimeError, |
|
120 winsound.PlaySound, |
|
121 'SystemHand', winsound.SND_ALIAS |
|
122 ) |
|
123 |
|
124 def test_alias_question(self): |
|
125 if _have_soundcard(): |
|
126 winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS) |
|
127 else: |
|
128 self.assertRaises( |
|
129 RuntimeError, |
|
130 winsound.PlaySound, |
|
131 'SystemQuestion', winsound.SND_ALIAS |
|
132 ) |
|
133 |
|
134 def test_alias_fallback(self): |
|
135 # This test can't be expected to work on all systems. The MS |
|
136 # PlaySound() docs say: |
|
137 # |
|
138 # If it cannot find the specified sound, PlaySound uses the |
|
139 # default system event sound entry instead. If the function |
|
140 # can find neither the system default entry nor the default |
|
141 # sound, it makes no sound and returns FALSE. |
|
142 # |
|
143 # It's known to return FALSE on some real systems. |
|
144 |
|
145 # winsound.PlaySound('!"$%&/(#+*', winsound.SND_ALIAS) |
|
146 return |
|
147 |
|
148 def test_alias_nofallback(self): |
|
149 if _have_soundcard(): |
|
150 # Note that this is not the same as asserting RuntimeError |
|
151 # will get raised: you cannot convert this to |
|
152 # self.assertRaises(...) form. The attempt may or may not |
|
153 # raise RuntimeError, but it shouldn't raise anything other |
|
154 # than RuntimeError, and that's all we're trying to test |
|
155 # here. The MS docs aren't clear about whether the SDK |
|
156 # PlaySound() with SND_ALIAS and SND_NODEFAULT will return |
|
157 # True or False when the alias is unknown. On Tim's WinXP |
|
158 # box today, it returns True (no exception is raised). What |
|
159 # we'd really like to test is that no sound is played, but |
|
160 # that requires first wiring an eardrum class into unittest |
|
161 # <wink>. |
|
162 try: |
|
163 winsound.PlaySound( |
|
164 '!"$%&/(#+*', |
|
165 winsound.SND_ALIAS | winsound.SND_NODEFAULT |
|
166 ) |
|
167 except RuntimeError: |
|
168 pass |
|
169 else: |
|
170 self.assertRaises( |
|
171 RuntimeError, |
|
172 winsound.PlaySound, |
|
173 '!"$%&/(#+*', winsound.SND_ALIAS | winsound.SND_NODEFAULT |
|
174 ) |
|
175 |
|
176 def test_stopasync(self): |
|
177 if _have_soundcard(): |
|
178 winsound.PlaySound( |
|
179 'SystemQuestion', |
|
180 winsound.SND_ALIAS | winsound.SND_ASYNC | winsound.SND_LOOP |
|
181 ) |
|
182 time.sleep(0.5) |
|
183 try: |
|
184 winsound.PlaySound( |
|
185 'SystemQuestion', |
|
186 winsound.SND_ALIAS | winsound.SND_NOSTOP |
|
187 ) |
|
188 except RuntimeError: |
|
189 pass |
|
190 else: # the first sound might already be finished |
|
191 pass |
|
192 winsound.PlaySound(None, winsound.SND_PURGE) |
|
193 else: |
|
194 self.assertRaises( |
|
195 RuntimeError, |
|
196 winsound.PlaySound, |
|
197 None, winsound.SND_PURGE |
|
198 ) |
|
199 |
|
200 |
|
201 def _get_cscript_path(): |
|
202 """Return the full path to cscript.exe or None.""" |
|
203 for dir in os.environ.get("PATH", "").split(os.pathsep): |
|
204 cscript_path = os.path.join(dir, "cscript.exe") |
|
205 if os.path.exists(cscript_path): |
|
206 return cscript_path |
|
207 |
|
208 __have_soundcard_cache = None |
|
209 def _have_soundcard(): |
|
210 """Return True iff this computer has a soundcard.""" |
|
211 global __have_soundcard_cache |
|
212 if __have_soundcard_cache is None: |
|
213 cscript_path = _get_cscript_path() |
|
214 if cscript_path is None: |
|
215 # Could not find cscript.exe to run our VBScript helper. Default |
|
216 # to True: most computers these days *do* have a soundcard. |
|
217 return True |
|
218 |
|
219 check_script = os.path.join(os.path.dirname(__file__), |
|
220 "check_soundcard.vbs") |
|
221 p = subprocess.Popen([cscript_path, check_script], |
|
222 stdout=subprocess.PIPE) |
|
223 __have_soundcard_cache = not p.wait() |
|
224 return __have_soundcard_cache |
|
225 |
|
226 |
|
227 def test_main(): |
|
228 test_support.run_unittest(BeepTest, MessageBeepTest, PlaySoundTest) |
|
229 |
|
230 if __name__=="__main__": |
|
231 test_main() |