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 ()
@@ -300,18 +312,111 @@ def test_module_funcs(self):
300
312
curses .use_env (1 )
301
313
302
314
# Functions only available on a few platforms
303
- def test_colors_funcs (self ):
304
- if not curses .has_colors ():
305
- self .skipTest ('requires colors support' )
306
- curses .start_color ()
307
- curses .init_pair (2 , 1 ,1 )
308
- curses .color_content (1 )
309
- curses .color_pair (2 )
310
- curses .pair_content (min (curses .COLOR_PAIRS - 1 , 0x7fff ))
311
- curses .pair_number (0 )
312
-
313
- if hasattr (curses , 'use_default_colors' ):
314
- curses .use_default_colors ()
315
+
316
+ def bad_colors (self ):
317
+ return (- 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
318
+
319
+ def bad_pairs (self ):
320
+ return (- 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
321
+
322
+ @requires_colors
323
+ def test_color_content (self ):
324
+ self .assertEqual (curses .color_content (curses .COLOR_BLACK ), (0 , 0 , 0 ))
325
+ curses .color_content (0 )
326
+ curses .color_content (min (curses .COLORS - 1 , SHORT_MAX ))
327
+
328
+ for color in self .bad_colors ():
329
+ self .assertRaises (OverflowError , curses .color_content , color )
330
+ if curses .COLORS <= SHORT_MAX :
331
+ self .assertRaises (curses .error , curses .color_content , curses .COLORS )
332
+ self .assertRaises (curses .error , curses .color_content , - 1 )
333
+
334
+ @requires_colors
335
+ def test_init_color (self ):
336
+ if not curses .can_change_color :
337
+ self .skipTest ('cannot change color' )
338
+
339
+ old = curses .color_content (0 )
340
+ try :
341
+ curses .init_color (0 , * old )
342
+ except curses .error :
343
+ self .skipTest ('cannot change color (init_color() failed)' )
344
+ self .addCleanup (curses .init_color , 0 , * old )
345
+ curses .init_color (0 , 0 , 0 , 0 )
346
+ self .assertEqual (curses .color_content (0 ), (0 , 0 , 0 ))
347
+ curses .init_color (0 , 1000 , 1000 , 1000 )
348
+ self .assertEqual (curses .color_content (0 ), (1000 , 1000 , 1000 ))
349
+
350
+ maxcolor = min (curses .COLORS - 1 , SHORT_MAX )
351
+ old = curses .color_content (maxcolor )
352
+ curses .init_color (maxcolor , * old )
353
+ self .addCleanup (curses .init_color , maxcolor , * old )
354
+ curses .init_color (maxcolor , 0 , 500 , 1000 )
355
+ self .assertEqual (curses .color_content (maxcolor ), (0 , 500 , 1000 ))
356
+
357
+ for color in self .bad_colors ():
358
+ self .assertRaises (OverflowError , curses .init_color , color , 0 , 0 , 0 )
359
+ if curses .COLORS <= SHORT_MAX :
360
+ self .assertRaises (curses .error , curses .init_color , curses .COLORS , 0 , 0 , 0 )
361
+ self .assertRaises (curses .error , curses .init_color , - 1 , 0 , 0 , 0 )
362
+ for comp in (- 1 , 1001 ):
363
+ self .assertRaises (curses .error , curses .init_color , 0 , comp , 0 , 0 )
364
+ self .assertRaises (curses .error , curses .init_color , 0 , 0 , comp , 0 )
365
+ self .assertRaises (curses .error , curses .init_color , 0 , 0 , 0 , comp )
366
+
367
+ @requires_colors
368
+ def test_pair_content (self ):
369
+ if not hasattr (curses , 'use_default_colors' ):
370
+ self .assertEqual (curses .pair_content (0 ),
371
+ (curses .COLOR_WHITE , curses .COLOR_BLACK ))
372
+ curses .pair_content (0 )
373
+ curses .pair_content (min (curses .COLOR_PAIRS - 1 , SHORT_MAX ))
374
+
375
+ for pair in self .bad_pairs ():
376
+ self .assertRaises (OverflowError , curses .pair_content , pair )
377
+ self .assertRaises (curses .error , curses .pair_content , - 1 )
378
+
379
+ @requires_colors
380
+ def test_init_pair (self ):
381
+ old = curses .pair_content (1 )
382
+ curses .init_pair (1 , * old )
383
+ self .addCleanup (curses .init_pair , 1 , * old )
384
+
385
+ curses .init_pair (1 , 0 , 0 )
386
+ self .assertEqual (curses .pair_content (1 ), (0 , 0 ))
387
+ maxcolor = min (curses .COLORS - 1 , SHORT_MAX )
388
+ curses .init_pair (1 , maxcolor , maxcolor )
389
+ self .assertEqual (curses .pair_content (1 ), (maxcolor , maxcolor ))
390
+ maxpair = min (curses .COLOR_PAIRS - 1 , SHORT_MAX )
391
+ curses .init_pair (maxpair , 2 , 3 )
392
+ self .assertEqual (curses .pair_content (maxpair ), (2 , 3 ))
393
+
394
+ for pair in self .bad_pairs ():
395
+ self .assertRaises (OverflowError , curses .init_pair , pair , 0 , 0 )
396
+ self .assertRaises (curses .error , curses .init_pair , - 1 , 0 , 0 )
397
+ for color in self .bad_colors ():
398
+ self .assertRaises (OverflowError , curses .init_pair , 1 , color , 0 )
399
+ self .assertRaises (OverflowError , curses .init_pair , 1 , 0 , color )
400
+ if curses .COLORS <= SHORT_MAX :
401
+ self .assertRaises (curses .error , curses .init_pair , 1 , curses .COLORS , 0 )
402
+ self .assertRaises (curses .error , curses .init_pair , 1 , 0 , curses .COLORS )
403
+
404
+ @requires_colors
405
+ def test_color_attrs (self ):
406
+ for pair in 0 , 1 , 255 :
407
+ attr = curses .color_pair (pair )
408
+ self .assertEqual (curses .pair_number (attr ), pair , attr )
409
+ self .assertEqual (curses .pair_number (attr | curses .A_BOLD ), pair )
410
+ self .assertEqual (curses .color_pair (0 ), 0 )
411
+ self .assertEqual (curses .pair_number (0 ), 0 )
412
+
413
+ @requires_curses_func ('use_default_colors' )
414
+ @requires_colors
415
+ def test_use_default_colors (self ):
416
+ self .assertIn (curses .pair_content (0 ),
417
+ ((curses .COLOR_WHITE , curses .COLOR_BLACK ), (- 1 , - 1 )))
418
+ curses .use_default_colors ()
419
+ self .assertEqual (curses .pair_content (0 ), (- 1 , - 1 ))
315
420
316
421
@requires_curses_func ('keyname' )
317
422
def test_keyname (self ):
0 commit comments