1# Ridiculously simple test of the winsound module for Windows.
2
3from __future__ import print_function
4
5import functools
6import os
7import subprocess
8import time
9import unittest
10
11from test import test_support as support
12
13support.requires('audio')
14winsound = support.import_module('winsound')
15
16# Unless we actually have an ear in the room, we have no idea whether a sound
17# actually plays, and it's incredibly flaky trying to figure out if a sound
18# even *should* play.  Instead of guessing, just call the function and assume
19# it either passed or raised the RuntimeError we expect in case of failure.
20def sound_func(func):
21    @functools.wraps(func)
22    def wrapper(*args, **kwargs):
23        try:
24            ret = func(*args, **kwargs)
25        except RuntimeError as e:
26            if support.verbose:
27                print(func.__name__, 'failed:', e)
28        else:
29            if support.verbose:
30                print(func.__name__, 'returned')
31            return ret
32    return wrapper
33
34safe_Beep = sound_func(winsound.Beep)
35safe_MessageBeep = sound_func(winsound.MessageBeep)
36safe_PlaySound = sound_func(winsound.PlaySound)
37
38class BeepTest(unittest.TestCase):
39
40    def test_errors(self):
41        self.assertRaises(TypeError, winsound.Beep)
42        self.assertRaises(ValueError, winsound.Beep, 36, 75)
43        self.assertRaises(ValueError, winsound.Beep, 32768, 75)
44
45    def test_extremes(self):
46        safe_Beep(37, 75)
47        safe_Beep(32767, 75)
48
49    def test_increasingfrequency(self):
50        for i in xrange(100, 2000, 100):
51            safe_Beep(i, 75)
52
53
54class MessageBeepTest(unittest.TestCase):
55
56    def tearDown(self):
57        time.sleep(0.5)
58
59    def test_default(self):
60        self.assertRaises(TypeError, winsound.MessageBeep, "bad")
61        self.assertRaises(TypeError, winsound.MessageBeep, 42, 42)
62        safe_MessageBeep()
63
64    def test_ok(self):
65        safe_MessageBeep(winsound.MB_OK)
66
67    def test_asterisk(self):
68        safe_MessageBeep(winsound.MB_ICONASTERISK)
69
70    def test_exclamation(self):
71        safe_MessageBeep(winsound.MB_ICONEXCLAMATION)
72
73    def test_hand(self):
74        safe_MessageBeep(winsound.MB_ICONHAND)
75
76    def test_question(self):
77        safe_MessageBeep(winsound.MB_ICONQUESTION)
78
79
80class PlaySoundTest(unittest.TestCase):
81
82    def test_errors(self):
83        self.assertRaises(TypeError, winsound.PlaySound)
84        self.assertRaises(TypeError, winsound.PlaySound, "bad", "bad")
85        self.assertRaises(
86            RuntimeError,
87            winsound.PlaySound,
88            "none", winsound.SND_ASYNC | winsound.SND_MEMORY
89        )
90
91    def test_aliases(self):
92        aliases = [
93            "SystemAsterisk",
94            "SystemExclamation",
95            "SystemExit",
96            "SystemHand",
97            "SystemQuestion",
98        ]
99        for alias in aliases:
100            safe_PlaySound(alias, winsound.SND_ALIAS)
101
102    def test_alias_fallback(self):
103        safe_PlaySound('!"$%&/(#+*', winsound.SND_ALIAS)
104
105    def test_alias_nofallback(self):
106        safe_PlaySound('!"$%&/(#+*', winsound.SND_ALIAS | winsound.SND_NODEFAULT)
107
108    def test_stopasync(self):
109        safe_PlaySound(
110            'SystemQuestion',
111            winsound.SND_ALIAS | winsound.SND_ASYNC | winsound.SND_LOOP
112        )
113        time.sleep(0.5)
114        safe_PlaySound('SystemQuestion', winsound.SND_ALIAS | winsound.SND_NOSTOP)
115        # Issue 8367: PlaySound(None, winsound.SND_PURGE)
116        # does not raise on systems without a sound card.
117        winsound.PlaySound(None, winsound.SND_PURGE)
118
119
120def test_main():
121    support.run_unittest(BeepTest, MessageBeepTest, PlaySoundTest)
122
123
124if __name__=="__main__":
125    test_main()
126