4
4
# This script doesn't actually display anything very coherent. but it
5
5
# does call (nearly) every method and function.
6
6
#
7
- # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
8
- # init_color()
7
+ # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr()
9
8
# Only called, not tested: getmouse(), ungetmouse()
10
9
#
11
10
12
11
import os
13
12
import string
14
13
import sys
15
14
import tempfile
15
+ import functools
16
16
import unittest
17
17
18
18
from test .support import requires , import_module , verbose , SaveSignals
@@ -36,7 +36,17 @@ def requires_curses_func(name):
36
36
return unittest .skipUnless (hasattr (curses , name ),
37
37
'requires curses.%s' % name )
38
38
39
+ def requires_colors (test ):
40
+ @functools .wraps (test )
41
+ def wrapped (self , * args , ** kwargs ):
42
+ if not curses .has_colors ():
43
+ self .skipTest ('requires colors support' )
44
+ curses .start_color ()
45
+ test (self , * args , ** kwargs )
46
+ return wrapped
47
+
39
48
term = os .environ .get ('TERM' )
49
+ SHORT_MAX = 0x7fff
40
50
41
51
# If newterm was supported we could use it instead of initscr and not exit
42
52
@unittest .skipIf (not term or term == 'unknown' ,
@@ -47,6 +57,8 @@ class TestCurses(unittest.TestCase):
47
57
48
58
@classmethod
49
59
def setUpClass (cls ):
60
+ if verbose :
61
+ print (f'TERM={ term } ' , file = sys .stderr , flush = True )
50
62
# testing setupterm() inside initscr/endwin
51
63
# causes terminal breakage
52
64
stdout_fd = sys .__stdout__ .fileno ()
@@ -304,18 +316,111 @@ def test_module_funcs(self):
304
316
curses .use_env (1 )
305
317
306
318
# Functions only available on a few platforms
307
- def test_colors_funcs (self ):
308
- if not curses .has_colors ():
309
- self .skipTest ('requires colors support' )
310
- curses .start_color ()
311
- curses .init_pair (2 , 1 ,1 )
312
- curses .color_content (1 )
313
- curses .color_pair (2 )
314
- curses .pair_content (min (curses .COLOR_PAIRS - 1 , 0x7fff ))
315
- curses .pair_number (0 )
316
-
317
- if hasattr (curses , 'use_default_colors' ):
318
- curses .use_default_colors ()
319
+
320
+ def bad_colors (self ):
321
+ return (- 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
322
+
323
+ def bad_pairs (self ):
324
+ return (- 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
325
+
326
+ @requires_colors
327
+ def test_color_content (self ):
328
+ self .assertEqual (curses .color_content (curses .COLOR_BLACK ), (0 , 0 , 0 ))
329
+ curses .color_content (0 )
330
+ curses .color_content (min (curses .COLORS - 1 , SHORT_MAX ))
331
+
332
+ for color in self .bad_colors ():
333
+ self .assertRaises (OverflowError , curses .color_content , color )
334
+ if curses .COLORS <= SHORT_MAX :
335
+ self .assertRaises (curses .error , curses .color_content , curses .COLORS )
336
+ self .assertRaises (curses .error , curses .color_content , - 1 )
337
+
338
+ @requires_colors
339
+ def test_init_color (self ):
340
+ if not curses .can_change_color :
341
+ self .skipTest ('cannot change color' )
342
+
343
+ old = curses .color_content (0 )
344
+ try :
345
+ curses .init_color (0 , * old )
346
+ except curses .error :
347
+ self .skipTest ('cannot change color (init_color() failed)' )
348
+ self .addCleanup (curses .init_color , 0 , * old )
349
+ curses .init_color (0 , 0 , 0 , 0 )
350
+ self .assertEqual (curses .color_content (0 ), (0 , 0 , 0 ))
351
+ curses .init_color (0 , 1000 , 1000 , 1000 )
352
+ self .assertEqual (curses .color_content (0 ), (1000 , 1000 , 1000 ))
353
+
354
+ maxcolor = min (curses .COLORS - 1 , SHORT_MAX )
355
+ old = curses .color_content (maxcolor )
356
+ curses .init_color (maxcolor , * old )
357
+ self .addCleanup (curses .init_color , maxcolor , * old )
358
+ curses .init_color (maxcolor , 0 , 500 , 1000 )
359
+ self .assertEqual (curses .color_content (maxcolor ), (0 , 500 , 1000 ))
360
+
361
+ for color in self .bad_colors ():
362
+ self .assertRaises (OverflowError , curses .init_color , color , 0 , 0 , 0 )
363
+ if curses .COLORS <= SHORT_MAX :
364
+ self .assertRaises (curses .error , curses .init_color , curses .COLORS , 0 , 0 , 0 )
365
+ self .assertRaises (curses .error , curses .init_color , - 1 , 0 , 0 , 0 )
366
+ for comp in (- 1 , 1001 ):
367
+ self .assertRaises (curses .error , curses .init_color , 0 , comp , 0 , 0 )
368
+ self .assertRaises (curses .error , curses .init_color , 0 , 0 , comp , 0 )
369
+ self .assertRaises (curses .error , curses .init_color , 0 , 0 , 0 , comp )
370
+
371
+ @requires_colors
372
+ def test_pair_content (self ):
373
+ if not hasattr (curses , 'use_default_colors' ):
374
+ self .assertEqual (curses .pair_content (0 ),
375
+ (curses .COLOR_WHITE , curses .COLOR_BLACK ))
376
+ curses .pair_content (0 )
377
+ curses .pair_content (min (curses .COLOR_PAIRS - 1 , SHORT_MAX ))
378
+
379
+ for pair in self .bad_pairs ():
380
+ self .assertRaises (OverflowError , curses .pair_content , pair )
381
+ self .assertRaises (curses .error , curses .pair_content , - 1 )
382
+
383
+ @requires_colors
384
+ def test_init_pair (self ):
385
+ old = curses .pair_content (1 )
386
+ curses .init_pair (1 , * old )
387
+ self .addCleanup (curses .init_pair , 1 , * old )
388
+
389
+ curses .init_pair (1 , 0 , 0 )
390
+ self .assertEqual (curses .pair_content (1 ), (0 , 0 ))
391
+ maxcolor = min (curses .COLORS - 1 , SHORT_MAX )
392
+ curses .init_pair (1 , maxcolor , maxcolor )
393
+ self .assertEqual (curses .pair_content (1 ), (maxcolor , maxcolor ))
394
+ maxpair = min (curses .COLOR_PAIRS - 1 , SHORT_MAX )
395
+ curses .init_pair (maxpair , 2 , 3 )
396
+ self .assertEqual (curses .pair_content (maxpair ), (2 , 3 ))
397
+
398
+ for pair in self .bad_pairs ():
399
+ self .assertRaises (OverflowError , curses .init_pair , pair , 0 , 0 )
400
+ self .assertRaises (curses .error , curses .init_pair , - 1 , 0 , 0 )
401
+ for color in self .bad_colors ():
402
+ self .assertRaises (OverflowError , curses .init_pair , 1 , color , 0 )
403
+ self .assertRaises (OverflowError , curses .init_pair , 1 , 0 , color )
404
+ if curses .COLORS <= SHORT_MAX :
405
+ self .assertRaises (curses .error , curses .init_pair , 1 , curses .COLORS , 0 )
406
+ self .assertRaises (curses .error , curses .init_pair , 1 , 0 , curses .COLORS )
407
+
408
+ @requires_colors
409
+ def test_color_attrs (self ):
410
+ for pair in 0 , 1 , 255 :
411
+ attr = curses .color_pair (pair )
412
+ self .assertEqual (curses .pair_number (attr ), pair , attr )
413
+ self .assertEqual (curses .pair_number (attr | curses .A_BOLD ), pair )
414
+ self .assertEqual (curses .color_pair (0 ), 0 )
415
+ self .assertEqual (curses .pair_number (0 ), 0 )
416
+
417
+ @requires_curses_func ('use_default_colors' )
418
+ @requires_colors
419
+ def test_use_default_colors (self ):
420
+ self .assertIn (curses .pair_content (0 ),
421
+ ((curses .COLOR_WHITE , curses .COLOR_BLACK ), (- 1 , - 1 )))
422
+ curses .use_default_colors ()
423
+ self .assertEqual (curses .pair_content (0 ), (- 1 , - 1 ))
319
424
320
425
@requires_curses_func ('keyname' )
321
426
def test_keyname (self ):
0 commit comments