blob: c9abfe34f3308ec9a6146e742de99f81d1ec625c [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
13import sys
14import tempfile
15import unittest
16
17from test.test_support import requires, import_module, verbose, run_unittest
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000018
19# Optionally test curses module. This currently requires that the
20# 'curses' resource be given on the regrtest command line using the -u
21# option. If not available, nothing after this line will be executed.
Neal Norwitz9f39f682006-01-06 04:18:21 +000022requires('curses')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030023
24# If either of these don't exist, skip the tests.
R. David Murray3db8a342009-03-30 23:05:48 +000025curses = import_module('curses')
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030026import_module('curses.panel')
27import_module('curses.ascii')
Neal Norwitz9f39f682006-01-06 04:18:21 +000028
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030029def requires_curses_func(name):
30 return unittest.skipUnless(hasattr(curses, name),
31 'requires curses.%s' % name)
Mark Dickinson45ad8012010-02-21 13:37:53 +000032
Neal Norwitz9f39f682006-01-06 04:18:21 +000033term = os.environ.get('TERM')
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000034
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030035# If newterm was supported we could use it instead of initscr and not exit
36@unittest.skipIf(not term or term == 'unknown',
37 "$TERM=%r, calling initscr() may cause exit" % term)
38@unittest.skipIf(sys.platform == "cygwin",
39 "cygwin's curses mostly just hangs")
40class TestCurses(unittest.TestCase):
Anthony Baxter76801852006-04-04 13:32:08 +000041
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030042 @classmethod
43 def setUpClass(cls):
44 if not sys.__stdout__.isatty():
45 # Temporary skip tests on non-tty
46 raise unittest.SkipTest('sys.__stdout__ is not a tty')
47 cls.tmp = tempfile.TemporaryFile()
48 fd = cls.tmp.fileno()
49 else:
50 cls.tmp = None
51 fd = sys.__stdout__.fileno()
52 # testing setupterm() inside initscr/endwin
53 # causes terminal breakage
54 curses.setupterm(fd=fd)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000055
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030056 @classmethod
57 def tearDownClass(cls):
58 if cls.tmp:
59 cls.tmp.close()
60 del cls.tmp
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000061
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030062 def setUp(self):
63 if verbose:
64 # just to make the test output a little more readable
65 print()
66 self.stdscr = curses.initscr()
67 curses.savetty()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000068
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030069 def tearDown(self):
70 curses.resetty()
71 curses.endwin()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000072
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030073 def test_window_funcs(self):
74 "Test the methods of windows"
75 stdscr = self.stdscr
76 win = curses.newwin(10,10)
77 win = curses.newwin(5,5, 5,5)
78 win2 = curses.newwin(15,15, 5,5)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +000079
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +030080 for meth in [stdscr.addch, stdscr.addstr]:
81 for args in [('a'), ('a', curses.A_BOLD),
82 (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
83 meth(*args)
84
85 for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
86 stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
87 stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
88 stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
89 stdscr.getparyx, stdscr.getyx, stdscr.inch,
90 stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
91 win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
92 stdscr.standout, stdscr.standend, stdscr.syncdown,
93 stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
94 meth()
95
96 stdscr.addnstr('1234', 3)
97 stdscr.addnstr('1234', 3, curses.A_BOLD)
98 stdscr.addnstr(4,4, '1234', 3)
99 stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD)
100
101 stdscr.attron(curses.A_BOLD)
102 stdscr.attroff(curses.A_BOLD)
103 stdscr.attrset(curses.A_BOLD)
104 stdscr.bkgd(' ')
105 stdscr.bkgd(' ', curses.A_REVERSE)
106 stdscr.bkgdset(' ')
107 stdscr.bkgdset(' ', curses.A_REVERSE)
108
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000109 win.border(65, 66, 67, 68,
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300110 69, 70, 71, 72)
111 win.border('|', '!', '-', '_',
112 '+', '\\', '#', '/')
113 with self.assertRaises(TypeError,
114 msg="Expected win.border() to raise TypeError"):
115 win.border(65, 66, 67, 68,
116 69, [], 71, 72)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000117
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300118 stdscr.clearok(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000119
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300120 win4 = stdscr.derwin(2,2)
121 win4 = stdscr.derwin(1,1, 5,5)
122 win4.mvderwin(9,9)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000123
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300124 stdscr.echochar('a')
125 stdscr.echochar('a', curses.A_BOLD)
126 stdscr.hline('-', 5)
127 stdscr.hline('-', 5, curses.A_BOLD)
128 stdscr.hline(1,1,'-', 5)
129 stdscr.hline(1,1,'-', 5, curses.A_BOLD)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000130
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300131 stdscr.idcok(1)
132 stdscr.idlok(1)
133 stdscr.immedok(1)
134 stdscr.insch('c')
135 stdscr.insdelln(1)
136 stdscr.insnstr('abc', 3)
137 stdscr.insnstr('abc', 3, curses.A_BOLD)
138 stdscr.insnstr(5, 5, 'abc', 3)
139 stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000140
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300141 stdscr.insstr('def')
142 stdscr.insstr('def', curses.A_BOLD)
143 stdscr.insstr(5, 5, 'def')
144 stdscr.insstr(5, 5, 'def', curses.A_BOLD)
145 stdscr.is_linetouched(0)
146 stdscr.keypad(1)
147 stdscr.leaveok(1)
148 stdscr.move(3,3)
149 win.mvwin(2,2)
150 stdscr.nodelay(1)
151 stdscr.notimeout(1)
152 win2.overlay(win)
153 win2.overwrite(win)
154 win2.overlay(win, 1, 2, 2, 1, 3, 3)
155 win2.overwrite(win, 1, 2, 2, 1, 3, 3)
156 stdscr.redrawln(1,2)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000157
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300158 stdscr.scrollok(1)
159 stdscr.scroll()
160 stdscr.scroll(2)
161 stdscr.scroll(-3)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000162
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300163 stdscr.move(12, 2)
164 stdscr.setscrreg(10,15)
165 win3 = stdscr.subwin(10,10)
166 win3 = stdscr.subwin(10,10, 5,5)
167 stdscr.syncok(1)
168 stdscr.timeout(5)
169 stdscr.touchline(5,5)
170 stdscr.touchline(5,5,0)
171 stdscr.vline('a', 3)
172 stdscr.vline('a', 3, curses.A_STANDOUT)
173 stdscr.chgat(5, 2, 3, curses.A_BLINK)
174 stdscr.chgat(3, curses.A_BOLD)
175 stdscr.chgat(5, 8, curses.A_UNDERLINE)
176 stdscr.chgat(curses.A_BLINK)
177 stdscr.refresh()
Andrew M. Kuchling400a49b2007-04-11 13:39:00 +0000178
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300179 stdscr.vline(1,1, 'a', 3)
180 stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000181
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300182 if hasattr(curses, 'resize'):
183 stdscr.resize()
184 if hasattr(curses, 'enclose'):
185 stdscr.enclose()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000186
187
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300188 def test_module_funcs(self):
189 "Test module-level functions"
190 for func in [curses.baudrate, curses.beep, curses.can_change_color,
191 curses.cbreak, curses.def_prog_mode, curses.doupdate,
192 curses.filter, curses.flash, curses.flushinp,
193 curses.has_colors, curses.has_ic, curses.has_il,
194 curses.isendwin, curses.killchar, curses.longname,
195 curses.nocbreak, curses.noecho, curses.nonl,
196 curses.noqiflush, curses.noraw,
197 curses.reset_prog_mode, curses.termattrs,
198 curses.termname, curses.erasechar, curses.getsyx]:
199 func()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000200
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300201 # Functions that actually need arguments
202 if curses.tigetstr("cnorm"):
203 curses.curs_set(1)
204 curses.delay_output(1)
205 curses.echo() ; curses.echo(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000206
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300207 with tempfile.TemporaryFile() as f:
208 self.stdscr.putwin(f)
209 f.seek(0)
210 curses.getwin(f)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000211
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300212 curses.halfdelay(1)
213 curses.intrflush(1)
214 curses.meta(1)
215 curses.napms(100)
216 curses.newpad(50,50)
217 win = curses.newwin(5,5)
218 win = curses.newwin(5,5, 1,1)
219 curses.nl() ; curses.nl(1)
220 curses.putp(b'abc')
221 curses.qiflush()
222 curses.raw() ; curses.raw(1)
223 curses.setsyx(5,5)
224 curses.tigetflag('hc')
225 curses.tigetnum('co')
226 curses.tigetstr('cr')
227 curses.tparm(b'cr')
228 curses.typeahead(sys.__stdin__.fileno())
229 curses.unctrl('a')
230 curses.ungetch('a')
231 curses.use_env(1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000232
233 # Functions only available on a few platforms
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300234 def test_colors_funcs(self):
235 if not curses.has_colors():
236 self.skip('requires colors support')
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000237 curses.start_color()
238 curses.init_pair(2, 1,1)
239 curses.color_content(1)
240 curses.color_pair(2)
Andrew M. Kuchlingd1badac2005-06-15 18:44:23 +0000241 curses.pair_content(curses.COLOR_PAIRS - 1)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000242 curses.pair_number(0)
243
Michael W. Hudson2b3feec2004-08-07 15:27:16 +0000244 if hasattr(curses, 'use_default_colors'):
245 curses.use_default_colors()
Andrew M. Kuchling69f31eb2003-08-13 23:11:04 +0000246
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300247 @requires_curses_func('keyname')
248 def test_keyname(self):
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000249 curses.keyname(13)
250
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300251 @requires_curses_func('has_key')
252 def test_has_key(self):
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000253 curses.has_key(13)
254
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300255 @requires_curses_func('getmouse')
256 def test_getmouse(self):
Anthony Baxtere94e3b42006-04-06 07:12:39 +0000257 (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300258 if availmask == 0:
259 self.skip('mouse stuff not available')
260 curses.mouseinterval(10)
261 # just verify these don't cause errors
262 curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
263 m = curses.getmouse()
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000264
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300265 def test_userptr_without_set(self):
266 w = curses.newwin(10, 10)
267 p = curses.panel.new_panel(w)
268 # try to access userptr() before calling set_userptr() -- segfaults
269 with self.assertRaises(curses.panel.error,
270 msg='userptr should fail since not set'):
271 p.userptr()
Walter Dörwald4994d952006-06-19 08:07:50 +0000272
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300273 def test_userptr_memory_leak(self):
274 w = curses.newwin(10, 10)
275 p = curses.panel.new_panel(w)
276 obj = object()
277 nrefs = sys.getrefcount(obj)
278 for i in range(100):
279 p.set_userptr(obj)
Tim Peters58eb11c2004-01-18 20:29:55 +0000280
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300281 p.set_userptr(None)
282 self.assertEqual(sys.getrefcount(obj), nrefs,
283 "set_userptr leaked references")
Andrew M. Kuchlinge752e202003-08-29 18:37:37 +0000284
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300285 def test_userptr_segfault(self):
286 panel = curses.panel.new_panel(self.stdscr)
287 class A:
288 def __del__(self):
289 panel.set_userptr(None)
290 panel.set_userptr(A())
291 panel.set_userptr(None)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000292
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300293 def test_new_curses_panel(self):
294 panel = curses.panel.new_panel(self.stdscr)
295 self.assertRaises(TypeError, type(panel))
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400296
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300297 @requires_curses_func('is_term_resized')
298 def test_is_term_resized(self):
299 curses.is_term_resized(*self.stdscr.getmaxyx())
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400300
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300301 @requires_curses_func('resize_term')
302 def test_resize_term(self):
303 curses.resize_term(*self.stdscr.getmaxyx())
Andrew Kuchlingaa6c2972013-06-22 12:33:05 -0400304
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300305 @requires_curses_func('resizeterm')
306 def test_resizeterm(self):
307 stdscr = self.stdscr
Walter Dörwaldd391f082007-03-06 20:38:57 +0000308 lines, cols = curses.LINES, curses.COLS
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300309 new_lines = lines - 1
310 new_cols = cols + 1
311 curses.resizeterm(new_lines, new_cols)
Tim Petersea5962f2007-03-12 18:07:52 +0000312
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300313 self.assertEqual(curses.LINES, new_lines)
314 self.assertEqual(curses.COLS, new_cols)
Walter Dörwaldd391f082007-03-06 20:38:57 +0000315
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300316 def test_issue6243(self):
317 curses.ungetch(1025)
318 self.stdscr.getkey()
Andrew M. Kuchlingb49e53e2009-09-25 22:23:54 +0000319
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300320 def test_issue10570(self):
321 b = curses.tparm(curses.tigetstr("cup"), 5, 3)
322 self.assertIs(type(b), bytes)
Andrew M. Kuchling2158df02001-10-22 15:26:09 +0000323
Serhiy Storchakaa8a259e2016-05-22 18:24:48 +0300324
325class TestAscii(unittest.TestCase):
326
327 def test_unctrl(self):
328 unctrl = curses.ascii.unctrl
329 self.assertEqual(unctrl('a'), 'a')
330 self.assertEqual(unctrl('A'), 'A')
331 self.assertEqual(unctrl(';'), ';')
332 self.assertEqual(unctrl(' '), ' ')
333 self.assertEqual(unctrl('\x7f'), '^?')
334 self.assertEqual(unctrl('\n'), '^J')
335 self.assertEqual(unctrl('\0'), '^@')
336 # Meta-bit characters
337 self.assertEqual(unctrl('\x8a'), '!^J')
338 self.assertEqual(unctrl('\xc1'), '!A')
339
340
341def test_main():
342 run_unittest(TestCurses, TestAscii)
343
344
345if __name__ == "__main__":
346 unittest.main()