• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Ridiculously simple test of the winsound module for Windows.
2
3import functools
4import os
5import time
6import unittest
7
8from test import support
9from test.support import import_helper
10from test.support import os_helper
11
12
13support.requires('audio')
14winsound = import_helper.import_module('winsound')
15
16
17# Unless we actually have an ear in the room, we have no idea whether a sound
18# actually plays, and it's incredibly flaky trying to figure out if a sound
19# even *should* play.  Instead of guessing, just call the function and assume
20# it either passed or raised the RuntimeError we expect in case of failure.
21def sound_func(func):
22    @functools.wraps(func)
23    def wrapper(*args, **kwargs):
24        try:
25            ret = func(*args, **kwargs)
26        except RuntimeError as e:
27            if support.verbose:
28                print(func.__name__, 'failed:', e)
29        else:
30            if support.verbose:
31                print(func.__name__, 'returned')
32            return ret
33    return wrapper
34
35
36safe_Beep = sound_func(winsound.Beep)
37safe_MessageBeep = sound_func(winsound.MessageBeep)
38safe_PlaySound = sound_func(winsound.PlaySound)
39
40
41class BeepTest(unittest.TestCase):
42
43    def test_errors(self):
44        self.assertRaises(TypeError, winsound.Beep)
45        self.assertRaises(ValueError, winsound.Beep, 36, 75)
46        self.assertRaises(ValueError, winsound.Beep, 32768, 75)
47
48    def test_extremes(self):
49        safe_Beep(37, 75)
50        safe_Beep(32767, 75)
51
52    def test_increasingfrequency(self):
53        for i in range(100, 2000, 100):
54            safe_Beep(i, 75)
55
56    def test_keyword_args(self):
57        safe_Beep(duration=75, frequency=2000)
58
59
60class MessageBeepTest(unittest.TestCase):
61
62    def tearDown(self):
63        time.sleep(0.5)
64
65    def test_default(self):
66        self.assertRaises(TypeError, winsound.MessageBeep, "bad")
67        self.assertRaises(TypeError, winsound.MessageBeep, 42, 42)
68        safe_MessageBeep()
69
70    def test_ok(self):
71        safe_MessageBeep(winsound.MB_OK)
72
73    def test_asterisk(self):
74        safe_MessageBeep(winsound.MB_ICONASTERISK)
75
76    def test_exclamation(self):
77        safe_MessageBeep(winsound.MB_ICONEXCLAMATION)
78
79    def test_hand(self):
80        safe_MessageBeep(winsound.MB_ICONHAND)
81
82    def test_question(self):
83        safe_MessageBeep(winsound.MB_ICONQUESTION)
84
85    def test_keyword_args(self):
86        safe_MessageBeep(type=winsound.MB_OK)
87
88
89class PlaySoundTest(unittest.TestCase):
90
91    def test_errors(self):
92        self.assertRaises(TypeError, winsound.PlaySound)
93        self.assertRaises(TypeError, winsound.PlaySound, "bad", "bad")
94        self.assertRaises(
95            RuntimeError,
96            winsound.PlaySound,
97            "none", winsound.SND_ASYNC | winsound.SND_MEMORY
98        )
99        self.assertRaises(TypeError, winsound.PlaySound, b"bad", 0)
100        self.assertRaises(TypeError, winsound.PlaySound, "bad",
101                          winsound.SND_MEMORY)
102        self.assertRaises(TypeError, winsound.PlaySound, 1, 0)
103        # embedded null character
104        self.assertRaises(ValueError, winsound.PlaySound, 'bad\0', 0)
105
106    def test_keyword_args(self):
107        safe_PlaySound(flags=winsound.SND_ALIAS, sound="SystemExit")
108
109    def test_snd_memory(self):
110        with open(support.findfile('pluck-pcm8.wav',
111                                   subdir='audiodata'), 'rb') as f:
112            audio_data = f.read()
113        safe_PlaySound(audio_data, winsound.SND_MEMORY)
114        audio_data = bytearray(audio_data)
115        safe_PlaySound(audio_data, winsound.SND_MEMORY)
116
117    def test_snd_filename(self):
118        fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
119        safe_PlaySound(fn, winsound.SND_FILENAME | winsound.SND_NODEFAULT)
120
121    def test_snd_filepath(self):
122        fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
123        path = os_helper.FakePath(fn)
124        safe_PlaySound(path, winsound.SND_FILENAME | winsound.SND_NODEFAULT)
125
126    def test_snd_filepath_as_bytes(self):
127        fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
128        self.assertRaises(
129            TypeError,
130            winsound.PlaySound,
131            os_helper.FakePath(os.fsencode(fn)),
132            winsound.SND_FILENAME | winsound.SND_NODEFAULT
133        )
134
135    def test_aliases(self):
136        aliases = [
137            "SystemAsterisk",
138            "SystemExclamation",
139            "SystemExit",
140            "SystemHand",
141            "SystemQuestion",
142        ]
143        for alias in aliases:
144            with self.subTest(alias=alias):
145                safe_PlaySound(alias, winsound.SND_ALIAS)
146
147    def test_alias_fallback(self):
148        safe_PlaySound('!"$%&/(#+*', winsound.SND_ALIAS)
149
150    def test_alias_nofallback(self):
151        safe_PlaySound('!"$%&/(#+*', winsound.SND_ALIAS | winsound.SND_NODEFAULT)
152
153    def test_stopasync(self):
154        safe_PlaySound(
155            'SystemQuestion',
156            winsound.SND_ALIAS | winsound.SND_ASYNC | winsound.SND_LOOP
157        )
158        time.sleep(0.5)
159        safe_PlaySound('SystemQuestion', winsound.SND_ALIAS | winsound.SND_NOSTOP)
160        # Issue 8367: PlaySound(None, winsound.SND_PURGE)
161        # does not raise on systems without a sound card.
162        winsound.PlaySound(None, winsound.SND_PURGE)
163
164
165if __name__ == "__main__":
166    unittest.main()
167