89f9b07511c8fee74686d9cc434bf66345a46d6d
[SubU] /
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2 import sys
3 from unittest import TestCase, main, skipUnless
4
5 try:
6     from unittest.mock import patch, Mock
7 except ImportError:
8     from mock import patch, Mock
9
10 from ..ansitowin32 import StreamWrapper
11 from ..initialise import init, just_fix_windows_console, _wipe_internal_state_for_tests
12 from .utils import osname, replace_by
13
14 orig_stdout = sys.stdout
15 orig_stderr = sys.stderr
16
17
18 class InitTest(TestCase):
19
20     @skipUnless(sys.stdout.isatty(), "sys.stdout is not a tty")
21     def setUp(self):
22         # sanity check
23         self.assertNotWrapped()
24
25     def tearDown(self):
26         _wipe_internal_state_for_tests()
27         sys.stdout = orig_stdout
28         sys.stderr = orig_stderr
29
30     def assertWrapped(self):
31         self.assertIsNot(sys.stdout, orig_stdout, 'stdout should be wrapped')
32         self.assertIsNot(sys.stderr, orig_stderr, 'stderr should be wrapped')
33         self.assertTrue(isinstance(sys.stdout, StreamWrapper),
34             'bad stdout wrapper')
35         self.assertTrue(isinstance(sys.stderr, StreamWrapper),
36             'bad stderr wrapper')
37
38     def assertNotWrapped(self):
39         self.assertIs(sys.stdout, orig_stdout, 'stdout should not be wrapped')
40         self.assertIs(sys.stderr, orig_stderr, 'stderr should not be wrapped')
41
42     @patch('colorama.initialise.reset_all')
43     @patch('colorama.ansitowin32.winapi_test', lambda *_: True)
44     @patch('colorama.ansitowin32.enable_vt_processing', lambda *_: False)
45     def testInitWrapsOnWindows(self, _):
46         with osname("nt"):
47             init()
48             self.assertWrapped()
49
50     @patch('colorama.initialise.reset_all')
51     @patch('colorama.ansitowin32.winapi_test', lambda *_: False)
52     def testInitDoesntWrapOnEmulatedWindows(self, _):
53         with osname("nt"):
54             init()
55             self.assertNotWrapped()
56
57     def testInitDoesntWrapOnNonWindows(self):
58         with osname("posix"):
59             init()
60             self.assertNotWrapped()
61
62     def testInitDoesntWrapIfNone(self):
63         with replace_by(None):
64             init()
65             # We can't use assertNotWrapped here because replace_by(None)
66             # changes stdout/stderr already.
67             self.assertIsNone(sys.stdout)
68             self.assertIsNone(sys.stderr)
69
70     def testInitAutoresetOnWrapsOnAllPlatforms(self):
71         with osname("posix"):
72             init(autoreset=True)
73             self.assertWrapped()
74
75     def testInitWrapOffDoesntWrapOnWindows(self):
76         with osname("nt"):
77             init(wrap=False)
78             self.assertNotWrapped()
79
80     def testInitWrapOffIncompatibleWithAutoresetOn(self):
81         self.assertRaises(ValueError, lambda: init(autoreset=True, wrap=False))
82
83     @patch('colorama.win32.SetConsoleTextAttribute')
84     @patch('colorama.initialise.AnsiToWin32')
85     def testAutoResetPassedOn(self, mockATW32, _):
86         with osname("nt"):
87             init(autoreset=True)
88             self.assertEqual(len(mockATW32.call_args_list), 2)
89             self.assertEqual(mockATW32.call_args_list[1][1]['autoreset'], True)
90             self.assertEqual(mockATW32.call_args_list[0][1]['autoreset'], True)
91
92     @patch('colorama.initialise.AnsiToWin32')
93     def testAutoResetChangeable(self, mockATW32):
94         with osname("nt"):
95             init()
96
97             init(autoreset=True)
98             self.assertEqual(len(mockATW32.call_args_list), 4)
99             self.assertEqual(mockATW32.call_args_list[2][1]['autoreset'], True)
100             self.assertEqual(mockATW32.call_args_list[3][1]['autoreset'], True)
101
102             init()
103             self.assertEqual(len(mockATW32.call_args_list), 6)
104             self.assertEqual(
105                 mockATW32.call_args_list[4][1]['autoreset'], False)
106             self.assertEqual(
107                 mockATW32.call_args_list[5][1]['autoreset'], False)
108
109
110     @patch('colorama.initialise.atexit.register')
111     def testAtexitRegisteredOnlyOnce(self, mockRegister):
112         init()
113         self.assertTrue(mockRegister.called)
114         mockRegister.reset_mock()
115         init()
116         self.assertFalse(mockRegister.called)
117
118
119 class JustFixWindowsConsoleTest(TestCase):
120     def _reset(self):
121         _wipe_internal_state_for_tests()
122         sys.stdout = orig_stdout
123         sys.stderr = orig_stderr
124
125     def tearDown(self):
126         self._reset()
127
128     @patch("colorama.ansitowin32.winapi_test", lambda: True)
129     def testJustFixWindowsConsole(self):
130         if sys.platform != "win32":
131             # just_fix_windows_console should be a no-op
132             just_fix_windows_console()
133             self.assertIs(sys.stdout, orig_stdout)
134             self.assertIs(sys.stderr, orig_stderr)
135         else:
136             def fake_std():
137                 # Emulate stdout=not a tty, stderr=tty
138                 # to check that we handle both cases correctly
139                 stdout = Mock()
140                 stdout.closed = False
141                 stdout.isatty.return_value = False
142                 stdout.fileno.return_value = 1
143                 sys.stdout = stdout
144
145                 stderr = Mock()
146                 stderr.closed = False
147                 stderr.isatty.return_value = True
148                 stderr.fileno.return_value = 2
149                 sys.stderr = stderr
150
151             for native_ansi in [False, True]:
152                 with patch(
153                     'colorama.ansitowin32.enable_vt_processing',
154                     lambda *_: native_ansi
155                 ):
156                     self._reset()
157                     fake_std()
158
159                     # Regular single-call test
160                     prev_stdout = sys.stdout
161                     prev_stderr = sys.stderr
162                     just_fix_windows_console()
163                     self.assertIs(sys.stdout, prev_stdout)
164                     if native_ansi:
165                         self.assertIs(sys.stderr, prev_stderr)
166                     else:
167                         self.assertIsNot(sys.stderr, prev_stderr)
168
169                     # second call without resetting is always a no-op
170                     prev_stdout = sys.stdout
171                     prev_stderr = sys.stderr
172                     just_fix_windows_console()
173                     self.assertIs(sys.stdout, prev_stdout)
174                     self.assertIs(sys.stderr, prev_stderr)
175
176                     self._reset()
177                     fake_std()
178
179                     # If init() runs first, just_fix_windows_console should be a no-op
180                     init()
181                     prev_stdout = sys.stdout
182                     prev_stderr = sys.stderr
183                     just_fix_windows_console()
184                     self.assertIs(prev_stdout, sys.stdout)
185                     self.assertIs(prev_stderr, sys.stderr)
186
187
188 if __name__ == '__main__':
189     main()