blob: 743e56ec9cfc1afa5e33363cce46a296ba0737ce [file] [log] [blame]
Andrew M. Kuchling2158df02001-10-22 15:26:09 +00001#
2# Test script for the curses module
3#
4# This script doesn't actually display anything very coherent. but it
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +03005# does call (nearly) every method and function.
Andrew M. Kuchling2158df02001-10-22 15:26:09 +00006#
7# Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
Neal Norwitz88bbd732006-01-10 07:05:44 +00008# init_color()
9# Only called, not tested: getmouse(), ungetmouse()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000010#
11
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030012import os
Serhiy Storchaka41833872016-06-18 22:08:49 +030013import string
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030014import sys
15import tempfile
16import unittest
17
Victor Stinner1d481822017-10-31 03:44:55 -070018from test.support import (requires, import_module, verbose, run_unittest,
19 SaveSignals)
20
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000021
22# Optionally test curses module. This currently requires that the
23# 'curses' resource be given on the regrtest command line using the -u
24# option. If not available, nothing after this line will be executed.
Neal Norwitz9f39f682006-01-06 04:18:21 +000025requires('curses')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030026
27# If either of these don't exist, skip the tests.
R. David Murray3db8a342009-03-30 23:05:48 +000028curses = import_module('curses')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030029import_module('curses.panel')
30import_module('curses.ascii')
Serhiy Storchaka4d42af12016-12-28 10:16:06 +020031import_module('curses.textpad')
Neal Norwitz9f39f682006-01-06 04:18:21 +000032
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030033def requires_curses_func(name):
34 return unittest.skipUnless(hasattr(curses, name),
35 'requires curses.%s' % name)
Mark Dickinson45ad8012010-02-21 13:37:53 +000036
Neal Norwitz9f39f682006-01-06 04:18:21 +000037term = os.environ.get('TERM')
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000038
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030039# If newterm was supported we could use it instead of initscr and not exit
40@unittest.skipIf(not term or term == 'unknown',
41 "$TERM=%r, calling initscr() may cause exit" % term)
42@unittest.skipIf(sys.platform == "cygwin",
43 "cygwin's curses mostly just hangs")
44class TestCurses(unittest.TestCase):
Anthony Baxter76801852006-04-04 13:32:08 +000045
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030046 @classmethod
47 def setUpClass(cls):
48 if not sys.__stdout__.isatty():
49 # Temporary skip tests on non-tty
50 raise unittest.SkipTest('sys.__stdout__ is not a tty')
51 cls.tmp = tempfile.TemporaryFile()
52 fd = cls.tmp.fileno()
53 else:
54 cls.tmp = None
55 fd = sys.__stdout__.fileno()
56 # testing setupterm() inside initscr/endwin
57 # causes terminal breakage
58 curses.setupterm(fd=fd)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000059
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030060 @classmethod
61 def tearDownClass(cls):
62 if cls.tmp:
63 cls.tmp.close()
64 del cls.tmp
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000065
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030066 def setUp(self):
Victor Stinner1d481822017-10-31 03:44:55 -070067 self.save_signals = SaveSignals()
68 self.save_signals.save()
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030069 if verbose:
70 # just to make the test output a little more readable
Martin Panterad6a99c2016-09-10 10:38:22 +000071 print('')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030072 self.stdscr = curses.initscr()
73 curses.savetty()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000074
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030075 def tearDown(self):
76 curses.resetty()
77 curses.endwin()
Victor Stinner1d481822017-10-31 03:44:55 -070078 self.save_signals.restore()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000079
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030080 def test_window_funcs(self):
81 "Test the methods of windows"
82 stdscr = self.stdscr
83 win = curses.newwin(10,10)
84 win = curses.newwin(5,5, 5,5)
85 win2 = curses.newwin(15,15, 5,5)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000086
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030087 for meth in [stdscr.addch, stdscr.addstr]:
88 for args in [('a'), ('a', curses.A_BOLD),
89 (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
90 meth(*args)
91
92 for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
93 stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
94 stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
95 stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
96 stdscr.getparyx, stdscr.getyx, stdscr.inch,
97 stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
98 win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
99 stdscr.standout, stdscr.standend, stdscr.syncdown,
100 stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
101 meth()
102
103 stdscr.addnstr('1234', 3)
104 stdscr.addnstr('1234', 3, curses.A_BOLD)
105 stdscr.addnstr(4,4, '1234', 3)
106 stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD)
107
108 stdscr.attron(curses.A_BOLD)
109 stdscr.attroff(curses.A_BOLD)
110 stdscr.attrset(curses.A_BOLD)
111 stdscr.bkgd(' ')
112 stdscr.bkgd(' ', curses.A_REVERSE)
113 stdscr.bkgdset(' ')
114 stdscr.bkgdset(' ', curses.A_REVERSE)
115
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000116 win.border(65, 66, 67, 68,
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300117 69, 70, 71, 72)
118 win.border('|', '!', '-', '_',
119 '+', '\\', '#', '/')
120 with self.assertRaises(TypeError,
121 msg="Expected win.border() to raise TypeError"):
122 win.border(65, 66, 67, 68,
123 69, [], 71, 72)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000124
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300125 stdscr.clearok(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000126
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300127 win4 = stdscr.derwin(2,2)
128 win4 = stdscr.derwin(1,1, 5,5)
129 win4.mvderwin(9,9)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000130
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300131 stdscr.echochar('a')
132 stdscr.echochar('a', curses.A_BOLD)
133 stdscr.hline('-', 5)
134 stdscr.hline('-', 5, curses.A_BOLD)
135 stdscr.hline(1,1,'-', 5)
136 stdscr.hline(1,1,'-', 5, curses.A_BOLD)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000137
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300138 stdscr.idcok(1)
139 stdscr.idlok(1)
140 stdscr.immedok(1)
141 stdscr.insch('c')
142 stdscr.insdelln(1)
143 stdscr.insnstr('abc', 3)
144 stdscr.insnstr('abc', 3, curses.A_BOLD)
145 stdscr.insnstr(5, 5, 'abc', 3)
146 stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000147
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300148 stdscr.insstr('def')
149 stdscr.insstr('def', curses.A_BOLD)
150 stdscr.insstr(5, 5, 'def')
151 stdscr.insstr(5, 5, 'def', curses.A_BOLD)
152 stdscr.is_linetouched(0)
153 stdscr.keypad(1)
154 stdscr.leaveok(1)
155 stdscr.move(3,3)
156 win.mvwin(2,2)
157 stdscr.nodelay(1)
158 stdscr.notimeout(1)
159 win2.overlay(win)
160 win2.overwrite(win)
161 win2.overlay(win, 1, 2, 2, 1, 3, 3)
162 win2.overwrite(win, 1, 2, 2, 1, 3, 3)
163 stdscr.redrawln(1,2)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000164
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300165 stdscr.scrollok(1)
166 stdscr.scroll()
167 stdscr.scroll(2)
168 stdscr.scroll(-3)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000169
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300170 stdscr.move(12, 2)
171 stdscr.setscrreg(10,15)
172 win3 = stdscr.subwin(10,10)
173 win3 = stdscr.subwin(10,10, 5,5)
174 stdscr.syncok(1)
175 stdscr.timeout(5)
176 stdscr.touchline(5,5)
177 stdscr.touchline(5,5,0)
178 stdscr.vline('a', 3)
179 stdscr.vline('a', 3, curses.A_STANDOUT)
180 stdscr.chgat(5, 2, 3, curses.A_BLINK)
181 stdscr.chgat(3, curses.A_BOLD)
182 stdscr.chgat(5, 8, curses.A_UNDERLINE)
183 stdscr.chgat(curses.A_BLINK)
184 stdscr.refresh()
Andrew M. Kuchling400a49b2007-04-11 13:39:00 +0000185
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300186 stdscr.vline(1,1, 'a', 3)
187 stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000188
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300189 if hasattr(curses, 'resize'):
190 stdscr.resize()
191 if hasattr(curses, 'enclose'):
192 stdscr.enclose()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000193
Benjamin Petersonf6701202016-08-13 18:15:28 -0700194 self.assertRaises(ValueError, stdscr.getstr, -400)
195 self.assertRaises(ValueError, stdscr.getstr, 2, 3, -400)
Benjamin Peterson505989c2016-08-15 21:40:14 -0700196 self.assertRaises(ValueError, stdscr.instr, -2)
197 self.assertRaises(ValueError, stdscr.instr, 2, 3, -2)
Benjamin Petersonf6701202016-08-13 18:15:28 -0700198
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000199
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300200 def test_module_funcs(self):
201 "Test module-level functions"
202 for func in [curses.baudrate, curses.beep, curses.can_change_color,
203 curses.cbreak, curses.def_prog_mode, curses.doupdate,
204 curses.filter, curses.flash, curses.flushinp,
205 curses.has_colors, curses.has_ic, curses.has_il,
206 curses.isendwin, curses.killchar, curses.longname,
207 curses.nocbreak, curses.noecho, curses.nonl,
208 curses.noqiflush, curses.noraw,
209 curses.reset_prog_mode, curses.termattrs,
210 curses.termname, curses.erasechar, curses.getsyx]:
211 func()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000212
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300213 # Functions that actually need arguments
214 if curses.tigetstr("cnorm"):
215 curses.curs_set(1)
216 curses.delay_output(1)
217 curses.echo() ; curses.echo(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000218
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300219 with tempfile.TemporaryFile() as f:
220 self.stdscr.putwin(f)
221 f.seek(0)
222 curses.getwin(f)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000223
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300224 curses.halfdelay(1)
225 curses.intrflush(1)
226 curses.meta(1)
227 curses.napms(100)
228 curses.newpad(50,50)
229 win = curses.newwin(5,5)
230 win = curses.newwin(5,5, 1,1)
231 curses.nl() ; curses.nl(1)
232 curses.putp(b'abc')
233 curses.qiflush()
234 curses.raw() ; curses.raw(1)
235 curses.setsyx(5,5)
236 curses.tigetflag('hc')
237 curses.tigetnum('co')
238 curses.tigetstr('cr')
239 curses.tparm(b'cr')
240 curses.typeahead(sys.__stdin__.fileno())
241 curses.unctrl('a')
242 curses.ungetch('a')
243 curses.use_env(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000244
245 # Functions only available on a few platforms
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300246 def test_colors_funcs(self):
247 if not curses.has_colors():
Xavier de Gaye92201112017-01-06 09:44:36 +0100248 self.skipTest('requires colors support')
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000249 curses.start_color()
250 curses.init_pair(2, 1,1)
251 curses.color_content(1)
252 curses.color_pair(2)
Andrew M. Kuchlingd1badac2005-06-15 18:44:23 +0000253 curses.pair_content(curses.COLOR_PAIRS - 1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000254 curses.pair_number(0)
255
Michael W. Hudson2b3feec2004-08-07 15:27:16 +0000256 if hasattr(curses, 'use_default_colors'):
257 curses.use_default_colors()
Andrew M. Kuchling69f31eb2003-08-13 23:11:04 +0000258
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300259 @requires_curses_func('keyname')
260 def test_keyname(self):
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000261 curses.keyname(13)
262
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300263 @requires_curses_func('has_key')
264 def test_has_key(self):
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000265 curses.has_key(13)
266
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300267 @requires_curses_func('getmouse')
268 def test_getmouse(self):
Anthony Baxtere94e3b42006-04-06 07:12:39 +0000269 (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300270 if availmask == 0:
Xavier de Gaye92201112017-01-06 09:44:36 +0100271 self.skipTest('mouse stuff not available')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300272 curses.mouseinterval(10)
273 # just verify these don't cause errors
274 curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
275 m = curses.getmouse()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000276
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300277 def test_userptr_without_set(self):
278 w = curses.newwin(10, 10)
279 p = curses.panel.new_panel(w)
280 # try to access userptr() before calling set_userptr() -- segfaults
281 with self.assertRaises(curses.panel.error,
282 msg='userptr should fail since not set'):
283 p.userptr()
Walter Dörwald4994d952006-06-19 08:07:50 +0000284
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300285 def test_userptr_memory_leak(self):
286 w = curses.newwin(10, 10)
287 p = curses.panel.new_panel(w)
288 obj = object()
289 nrefs = sys.getrefcount(obj)
290 for i in range(100):
291 p.set_userptr(obj)
Tim Peters58eb11c2004-01-18 20:29:55 +0000292
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300293 p.set_userptr(None)
294 self.assertEqual(sys.getrefcount(obj), nrefs,
295 "set_userptr leaked references")
Andrew M. Kuchlinge752e202003-08-29 18:37:37 +0000296
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300297 def test_userptr_segfault(self):
298 panel = curses.panel.new_panel(self.stdscr)
299 class A:
300 def __del__(self):
301 panel.set_userptr(None)
302 panel.set_userptr(A())
303 panel.set_userptr(None)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000304
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300305 def test_new_curses_panel(self):
306 panel = curses.panel.new_panel(self.stdscr)
307 self.assertRaises(TypeError, type(panel))
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400308
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300309 @requires_curses_func('is_term_resized')
310 def test_is_term_resized(self):
311 curses.is_term_resized(*self.stdscr.getmaxyx())
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400312
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300313 @requires_curses_func('resize_term')
314 def test_resize_term(self):
315 curses.resize_term(*self.stdscr.getmaxyx())
Andrew Kuchlingaa6c2972013-06-22 12:33:05 -0400316
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300317 @requires_curses_func('resizeterm')
318 def test_resizeterm(self):
319 stdscr = self.stdscr
Walter Dörwaldd391f082007-03-06 20:38:57 +0000320 lines, cols = curses.LINES, curses.COLS
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300321 new_lines = lines - 1
322 new_cols = cols + 1
323 curses.resizeterm(new_lines, new_cols)
Tim Petersea5962f2007-03-12 18:07:52 +0000324
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300325 self.assertEqual(curses.LINES, new_lines)
326 self.assertEqual(curses.COLS, new_cols)
Walter Dörwaldd391f082007-03-06 20:38:57 +0000327
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300328 def test_issue6243(self):
329 curses.ungetch(1025)
330 self.stdscr.getkey()
Andrew M. Kuchlingb49e53e2009-09-25 22:23:54 +0000331
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300332 def test_issue10570(self):
333 b = curses.tparm(curses.tigetstr("cup"), 5, 3)
334 self.assertIs(type(b), bytes)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000335
Serhiy Storchaka4d42af12016-12-28 10:16:06 +0200336 def test_issue13051(self):
337 stdscr = self.stdscr
338 box = curses.textpad.Textbox(stdscr, insert_mode=True)
339 lines, cols = stdscr.getmaxyx()
340 stdscr.resize(lines-2, cols-2)
341 # this may cause infinite recursion, leading to a RuntimeError
342 box._insert_printable_char('a')
343
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300344
345class TestAscii(unittest.TestCase):
346
Serhiy Storchaka41833872016-06-18 22:08:49 +0300347 def test_controlnames(self):
348 for name in curses.ascii.controlnames:
349 self.assertTrue(hasattr(curses.ascii, name), name)
350
351 def test_ctypes(self):
352 def check(func, expected):
353 self.assertEqual(func(i), expected)
354 self.assertEqual(func(c), expected)
355
356 for i in range(256):
357 c = b = chr(i)
358 check(curses.ascii.isalnum, b.isalnum())
359 check(curses.ascii.isalpha, b.isalpha())
360 check(curses.ascii.isdigit, b.isdigit())
361 check(curses.ascii.islower, b.islower())
362 check(curses.ascii.isspace, b.isspace())
363 check(curses.ascii.isupper, b.isupper())
364
365 check(curses.ascii.isascii, i < 128)
366 check(curses.ascii.ismeta, i >= 128)
367 check(curses.ascii.isctrl, i < 32)
368 check(curses.ascii.iscntrl, i < 32 or i == 127)
369 check(curses.ascii.isblank, c in ' \t')
370 check(curses.ascii.isgraph, 32 < i <= 126)
371 check(curses.ascii.isprint, 32 <= i <= 126)
372 check(curses.ascii.ispunct, c in string.punctuation)
373 check(curses.ascii.isxdigit, c in string.hexdigits)
374
Serhiy Storchakaf77fe6b2016-12-28 10:04:27 +0200375 for i in (-2, -1, 256, sys.maxunicode, sys.maxunicode+1):
376 self.assertFalse(curses.ascii.isalnum(i))
377 self.assertFalse(curses.ascii.isalpha(i))
378 self.assertFalse(curses.ascii.isdigit(i))
379 self.assertFalse(curses.ascii.islower(i))
380 self.assertFalse(curses.ascii.isspace(i))
381 self.assertFalse(curses.ascii.isupper(i))
382
383 self.assertFalse(curses.ascii.isascii(i))
384 self.assertFalse(curses.ascii.isctrl(i))
385 self.assertFalse(curses.ascii.iscntrl(i))
386 self.assertFalse(curses.ascii.isblank(i))
387 self.assertFalse(curses.ascii.isgraph(i))
388 self.assertFalse(curses.ascii.isprint(i))
389 self.assertFalse(curses.ascii.ispunct(i))
390 self.assertFalse(curses.ascii.isxdigit(i))
391
392 self.assertFalse(curses.ascii.ismeta(-1))
393
Serhiy Storchaka41833872016-06-18 22:08:49 +0300394 def test_ascii(self):
395 ascii = curses.ascii.ascii
396 self.assertEqual(ascii('\xc1'), 'A')
397 self.assertEqual(ascii('A'), 'A')
398 self.assertEqual(ascii(ord('\xc1')), ord('A'))
399
400 def test_ctrl(self):
401 ctrl = curses.ascii.ctrl
402 self.assertEqual(ctrl('J'), '\n')
403 self.assertEqual(ctrl('\n'), '\n')
404 self.assertEqual(ctrl('@'), '\0')
405 self.assertEqual(ctrl(ord('J')), ord('\n'))
406
407 def test_alt(self):
408 alt = curses.ascii.alt
409 self.assertEqual(alt('\n'), '\x8a')
410 self.assertEqual(alt('A'), '\xc1')
411 self.assertEqual(alt(ord('A')), 0xc1)
412
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300413 def test_unctrl(self):
414 unctrl = curses.ascii.unctrl
415 self.assertEqual(unctrl('a'), 'a')
416 self.assertEqual(unctrl('A'), 'A')
417 self.assertEqual(unctrl(';'), ';')
418 self.assertEqual(unctrl(' '), ' ')
419 self.assertEqual(unctrl('\x7f'), '^?')
420 self.assertEqual(unctrl('\n'), '^J')
421 self.assertEqual(unctrl('\0'), '^@')
Serhiy Storchaka41833872016-06-18 22:08:49 +0300422 self.assertEqual(unctrl(ord('A')), 'A')
423 self.assertEqual(unctrl(ord('\n')), '^J')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300424 # Meta-bit characters
425 self.assertEqual(unctrl('\x8a'), '!^J')
426 self.assertEqual(unctrl('\xc1'), '!A')
Serhiy Storchaka41833872016-06-18 22:08:49 +0300427 self.assertEqual(unctrl(ord('\x8a')), '!^J')
428 self.assertEqual(unctrl(ord('\xc1')), '!A')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300429
430
431def test_main():
432 run_unittest(TestCurses, TestAscii)
433
434
435if __name__ == "__main__":
436 unittest.main()