1 | #
|
---|
2 | # Test script for the curses module
|
---|
3 | #
|
---|
4 | # This script doesn't actually display anything very coherent. but it
|
---|
5 | # does call every method and function.
|
---|
6 | #
|
---|
7 | # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
|
---|
8 | # init_color()
|
---|
9 | # Only called, not tested: getmouse(), ungetmouse()
|
---|
10 | #
|
---|
11 |
|
---|
12 | import sys, tempfile, os
|
---|
13 |
|
---|
14 | # Optionally test curses module. This currently requires that the
|
---|
15 | # 'curses' resource be given on the regrtest command line using the -u
|
---|
16 | # option. If not available, nothing after this line will be executed.
|
---|
17 |
|
---|
18 | import unittest
|
---|
19 | from test.test_support import requires, import_module
|
---|
20 | requires('curses')
|
---|
21 | curses = import_module('curses')
|
---|
22 | curses.panel = import_module('curses.panel')
|
---|
23 |
|
---|
24 |
|
---|
25 | # XXX: if newterm was supported we could use it instead of initscr and not exit
|
---|
26 | term = os.environ.get('TERM')
|
---|
27 | if not term or term == 'unknown':
|
---|
28 | raise unittest.SkipTest, "$TERM=%r, calling initscr() may cause exit" % term
|
---|
29 |
|
---|
30 | if sys.platform == "cygwin":
|
---|
31 | raise unittest.SkipTest("cygwin's curses mostly just hangs")
|
---|
32 |
|
---|
33 | def window_funcs(stdscr):
|
---|
34 | "Test the methods of windows"
|
---|
35 | win = curses.newwin(10,10)
|
---|
36 | win = curses.newwin(5,5, 5,5)
|
---|
37 | win2 = curses.newwin(15,15, 5,5)
|
---|
38 |
|
---|
39 | for meth in [stdscr.addch, stdscr.addstr]:
|
---|
40 | for args in [('a'), ('a', curses.A_BOLD),
|
---|
41 | (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
|
---|
42 | meth(*args)
|
---|
43 |
|
---|
44 | for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
|
---|
45 | stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
|
---|
46 | stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
|
---|
47 | stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
|
---|
48 | stdscr.getparyx, stdscr.getyx, stdscr.inch,
|
---|
49 | stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
|
---|
50 | win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
|
---|
51 | stdscr.standout, stdscr.standend, stdscr.syncdown,
|
---|
52 | stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
|
---|
53 | meth()
|
---|
54 |
|
---|
55 | stdscr.addnstr('1234', 3)
|
---|
56 | stdscr.addnstr('1234', 3, curses.A_BOLD)
|
---|
57 | stdscr.addnstr(4,4, '1234', 3)
|
---|
58 | stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD)
|
---|
59 |
|
---|
60 | stdscr.attron(curses.A_BOLD)
|
---|
61 | stdscr.attroff(curses.A_BOLD)
|
---|
62 | stdscr.attrset(curses.A_BOLD)
|
---|
63 | stdscr.bkgd(' ')
|
---|
64 | stdscr.bkgd(' ', curses.A_REVERSE)
|
---|
65 | stdscr.bkgdset(' ')
|
---|
66 | stdscr.bkgdset(' ', curses.A_REVERSE)
|
---|
67 |
|
---|
68 | win.border(65, 66, 67, 68,
|
---|
69 | 69, 70, 71, 72)
|
---|
70 | win.border('|', '!', '-', '_',
|
---|
71 | '+', '\\', '#', '/')
|
---|
72 | try:
|
---|
73 | win.border(65, 66, 67, 68,
|
---|
74 | 69, [], 71, 72)
|
---|
75 | except TypeError:
|
---|
76 | pass
|
---|
77 | else:
|
---|
78 | raise RuntimeError, "Expected win.border() to raise TypeError"
|
---|
79 |
|
---|
80 | stdscr.clearok(1)
|
---|
81 |
|
---|
82 | win4 = stdscr.derwin(2,2)
|
---|
83 | win4 = stdscr.derwin(1,1, 5,5)
|
---|
84 | win4.mvderwin(9,9)
|
---|
85 |
|
---|
86 | stdscr.echochar('a')
|
---|
87 | stdscr.echochar('a', curses.A_BOLD)
|
---|
88 | stdscr.hline('-', 5)
|
---|
89 | stdscr.hline('-', 5, curses.A_BOLD)
|
---|
90 | stdscr.hline(1,1,'-', 5)
|
---|
91 | stdscr.hline(1,1,'-', 5, curses.A_BOLD)
|
---|
92 |
|
---|
93 | stdscr.idcok(1)
|
---|
94 | stdscr.idlok(1)
|
---|
95 | stdscr.immedok(1)
|
---|
96 | stdscr.insch('c')
|
---|
97 | stdscr.insdelln(1)
|
---|
98 | stdscr.insnstr('abc', 3)
|
---|
99 | stdscr.insnstr('abc', 3, curses.A_BOLD)
|
---|
100 | stdscr.insnstr(5, 5, 'abc', 3)
|
---|
101 | stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD)
|
---|
102 |
|
---|
103 | stdscr.insstr('def')
|
---|
104 | stdscr.insstr('def', curses.A_BOLD)
|
---|
105 | stdscr.insstr(5, 5, 'def')
|
---|
106 | stdscr.insstr(5, 5, 'def', curses.A_BOLD)
|
---|
107 | stdscr.is_linetouched(0)
|
---|
108 | stdscr.keypad(1)
|
---|
109 | stdscr.leaveok(1)
|
---|
110 | stdscr.move(3,3)
|
---|
111 | win.mvwin(2,2)
|
---|
112 | stdscr.nodelay(1)
|
---|
113 | stdscr.notimeout(1)
|
---|
114 | win2.overlay(win)
|
---|
115 | win2.overwrite(win)
|
---|
116 | win2.overlay(win, 1, 2, 3, 3, 2, 1)
|
---|
117 | win2.overwrite(win, 1, 2, 3, 3, 2, 1)
|
---|
118 | stdscr.redrawln(1,2)
|
---|
119 |
|
---|
120 | stdscr.scrollok(1)
|
---|
121 | stdscr.scroll()
|
---|
122 | stdscr.scroll(2)
|
---|
123 | stdscr.scroll(-3)
|
---|
124 |
|
---|
125 | stdscr.move(12, 2)
|
---|
126 | stdscr.setscrreg(10,15)
|
---|
127 | win3 = stdscr.subwin(10,10)
|
---|
128 | win3 = stdscr.subwin(10,10, 5,5)
|
---|
129 | stdscr.syncok(1)
|
---|
130 | stdscr.timeout(5)
|
---|
131 | stdscr.touchline(5,5)
|
---|
132 | stdscr.touchline(5,5,0)
|
---|
133 | stdscr.vline('a', 3)
|
---|
134 | stdscr.vline('a', 3, curses.A_STANDOUT)
|
---|
135 | stdscr.chgat(5, 2, 3, curses.A_BLINK)
|
---|
136 | stdscr.chgat(3, curses.A_BOLD)
|
---|
137 | stdscr.chgat(5, 8, curses.A_UNDERLINE)
|
---|
138 | stdscr.chgat(curses.A_BLINK)
|
---|
139 | stdscr.refresh()
|
---|
140 |
|
---|
141 | stdscr.vline(1,1, 'a', 3)
|
---|
142 | stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
|
---|
143 |
|
---|
144 | if hasattr(curses, 'resize'):
|
---|
145 | stdscr.resize()
|
---|
146 | if hasattr(curses, 'enclose'):
|
---|
147 | stdscr.enclose()
|
---|
148 |
|
---|
149 |
|
---|
150 | def module_funcs(stdscr):
|
---|
151 | "Test module-level functions"
|
---|
152 |
|
---|
153 | for func in [curses.baudrate, curses.beep, curses.can_change_color,
|
---|
154 | curses.cbreak, curses.def_prog_mode, curses.doupdate,
|
---|
155 | curses.filter, curses.flash, curses.flushinp,
|
---|
156 | curses.has_colors, curses.has_ic, curses.has_il,
|
---|
157 | curses.isendwin, curses.killchar, curses.longname,
|
---|
158 | curses.nocbreak, curses.noecho, curses.nonl,
|
---|
159 | curses.noqiflush, curses.noraw,
|
---|
160 | curses.reset_prog_mode, curses.termattrs,
|
---|
161 | curses.termname, curses.erasechar, curses.getsyx]:
|
---|
162 | func()
|
---|
163 |
|
---|
164 | # Functions that actually need arguments
|
---|
165 | if curses.tigetstr("cnorm"):
|
---|
166 | curses.curs_set(1)
|
---|
167 | curses.delay_output(1)
|
---|
168 | curses.echo() ; curses.echo(1)
|
---|
169 |
|
---|
170 | f = tempfile.TemporaryFile()
|
---|
171 | stdscr.putwin(f)
|
---|
172 | f.seek(0)
|
---|
173 | curses.getwin(f)
|
---|
174 | f.close()
|
---|
175 |
|
---|
176 | curses.halfdelay(1)
|
---|
177 | curses.intrflush(1)
|
---|
178 | curses.meta(1)
|
---|
179 | curses.napms(100)
|
---|
180 | curses.newpad(50,50)
|
---|
181 | win = curses.newwin(5,5)
|
---|
182 | win = curses.newwin(5,5, 1,1)
|
---|
183 | curses.nl() ; curses.nl(1)
|
---|
184 | curses.putp('abc')
|
---|
185 | curses.qiflush()
|
---|
186 | curses.raw() ; curses.raw(1)
|
---|
187 | curses.setsyx(5,5)
|
---|
188 | curses.tigetflag('hc')
|
---|
189 | curses.tigetnum('co')
|
---|
190 | curses.tigetstr('cr')
|
---|
191 | curses.tparm('cr')
|
---|
192 | curses.typeahead(sys.__stdin__.fileno())
|
---|
193 | curses.unctrl('a')
|
---|
194 | curses.ungetch('a')
|
---|
195 | curses.use_env(1)
|
---|
196 |
|
---|
197 | # Functions only available on a few platforms
|
---|
198 | if curses.has_colors():
|
---|
199 | curses.start_color()
|
---|
200 | curses.init_pair(2, 1,1)
|
---|
201 | curses.color_content(1)
|
---|
202 | curses.color_pair(2)
|
---|
203 | curses.pair_content(curses.COLOR_PAIRS - 1)
|
---|
204 | curses.pair_number(0)
|
---|
205 |
|
---|
206 | if hasattr(curses, 'use_default_colors'):
|
---|
207 | curses.use_default_colors()
|
---|
208 |
|
---|
209 | if hasattr(curses, 'keyname'):
|
---|
210 | curses.keyname(13)
|
---|
211 |
|
---|
212 | if hasattr(curses, 'has_key'):
|
---|
213 | curses.has_key(13)
|
---|
214 |
|
---|
215 | if hasattr(curses, 'getmouse'):
|
---|
216 | (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
|
---|
217 | # availmask indicates that mouse stuff not available.
|
---|
218 | if availmask != 0:
|
---|
219 | curses.mouseinterval(10)
|
---|
220 | # just verify these don't cause errors
|
---|
221 | curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
|
---|
222 | m = curses.getmouse()
|
---|
223 |
|
---|
224 | if hasattr(curses, 'is_term_resized'):
|
---|
225 | curses.is_term_resized(*stdscr.getmaxyx())
|
---|
226 | if hasattr(curses, 'resizeterm'):
|
---|
227 | curses.resizeterm(*stdscr.getmaxyx())
|
---|
228 | if hasattr(curses, 'resize_term'):
|
---|
229 | curses.resize_term(*stdscr.getmaxyx())
|
---|
230 |
|
---|
231 | def unit_tests():
|
---|
232 | from curses import ascii
|
---|
233 | for ch, expected in [('a', 'a'), ('A', 'A'),
|
---|
234 | (';', ';'), (' ', ' '),
|
---|
235 | ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'),
|
---|
236 | # Meta-bit characters
|
---|
237 | ('\x8a', '!^J'), ('\xc1', '!A'),
|
---|
238 | ]:
|
---|
239 | if ascii.unctrl(ch) != expected:
|
---|
240 | print 'curses.unctrl fails on character', repr(ch)
|
---|
241 |
|
---|
242 |
|
---|
243 | def test_userptr_without_set(stdscr):
|
---|
244 | w = curses.newwin(10, 10)
|
---|
245 | p = curses.panel.new_panel(w)
|
---|
246 | # try to access userptr() before calling set_userptr() -- segfaults
|
---|
247 | try:
|
---|
248 | p.userptr()
|
---|
249 | raise RuntimeError, 'userptr should fail since not set'
|
---|
250 | except curses.panel.error:
|
---|
251 | pass
|
---|
252 |
|
---|
253 | def test_userptr_memory_leak(stdscr):
|
---|
254 | w = curses.newwin(10, 10)
|
---|
255 | p = curses.panel.new_panel(w)
|
---|
256 | obj = object()
|
---|
257 | nrefs = sys.getrefcount(obj)
|
---|
258 | for i in range(100):
|
---|
259 | p.set_userptr(obj)
|
---|
260 |
|
---|
261 | p.set_userptr(None)
|
---|
262 | if sys.getrefcount(obj) != nrefs:
|
---|
263 | raise RuntimeError, "set_userptr leaked references"
|
---|
264 |
|
---|
265 | def test_userptr_segfault(stdscr):
|
---|
266 | panel = curses.panel.new_panel(stdscr)
|
---|
267 | class A:
|
---|
268 | def __del__(self):
|
---|
269 | panel.set_userptr(None)
|
---|
270 | panel.set_userptr(A())
|
---|
271 | panel.set_userptr(None)
|
---|
272 |
|
---|
273 | def test_resize_term(stdscr):
|
---|
274 | if hasattr(curses, 'resizeterm'):
|
---|
275 | lines, cols = curses.LINES, curses.COLS
|
---|
276 | curses.resizeterm(lines - 1, cols + 1)
|
---|
277 |
|
---|
278 | if curses.LINES != lines - 1 or curses.COLS != cols + 1:
|
---|
279 | raise RuntimeError, "Expected resizeterm to update LINES and COLS"
|
---|
280 |
|
---|
281 | def test_issue6243(stdscr):
|
---|
282 | curses.ungetch(1025)
|
---|
283 | stdscr.getkey()
|
---|
284 |
|
---|
285 | def main(stdscr):
|
---|
286 | curses.savetty()
|
---|
287 | try:
|
---|
288 | module_funcs(stdscr)
|
---|
289 | window_funcs(stdscr)
|
---|
290 | test_userptr_without_set(stdscr)
|
---|
291 | test_userptr_memory_leak(stdscr)
|
---|
292 | test_userptr_segfault(stdscr)
|
---|
293 | test_resize_term(stdscr)
|
---|
294 | test_issue6243(stdscr)
|
---|
295 | finally:
|
---|
296 | curses.resetty()
|
---|
297 |
|
---|
298 | if __name__ == '__main__':
|
---|
299 | curses.wrapper(main)
|
---|
300 | unit_tests()
|
---|
301 | else:
|
---|
302 | if not sys.__stdout__.isatty():
|
---|
303 | raise unittest.SkipTest("sys.__stdout__ is not a tty")
|
---|
304 | # testing setupterm() inside initscr/endwin
|
---|
305 | # causes terminal breakage
|
---|
306 | curses.setupterm(fd=sys.__stdout__.fileno())
|
---|
307 | try:
|
---|
308 | stdscr = curses.initscr()
|
---|
309 | main(stdscr)
|
---|
310 | finally:
|
---|
311 | curses.endwin()
|
---|
312 | unit_tests()
|
---|