44# This script doesn't actually display anything very coherent. but it
55# does call (nearly) every method and function.
66#
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()
98# Only called, not tested: getmouse(), ungetmouse()
109#
1110
1211import os
1312import string
1413import sys
1514import tempfile
15+ import functools
1616import unittest
1717
1818from test .support import requires , verbose , SaveSignals
@@ -37,6 +37,15 @@ def requires_curses_func(name):
3737 return unittest .skipUnless (hasattr (curses , name ),
3838 'requires curses.%s' % name )
3939
40+ def requires_colors (test ):
41+ @functools .wraps (test )
42+ def wrapped (self , * args , ** kwargs ):
43+ if not curses .has_colors ():
44+ self .skipTest ('requires colors support' )
45+ curses .start_color ()
46+ test (self , * args , ** kwargs )
47+ return wrapped
48+
4049term = os .environ .get ('TERM' )
4150
4251# If newterm was supported we could use it instead of initscr and not exit
@@ -48,6 +57,8 @@ class TestCurses(unittest.TestCase):
4857
4958 @classmethod
5059 def setUpClass (cls ):
60+ if verbose :
61+ print (f'TERM={ term } ' , file = sys .stderr , flush = True )
5162 # testing setupterm() inside initscr/endwin
5263 # causes terminal breakage
5364 stdout_fd = sys .__stdout__ .fileno ()
@@ -306,31 +317,101 @@ def test_module_funcs(self):
306317 curses .use_env (1 )
307318
308319 # Functions only available on a few platforms
309- def test_colors_funcs (self ):
310- if not curses .has_colors ():
311- self .skipTest ('requires colors support' )
312- curses .start_color ()
313- curses .init_pair (2 , 1 ,1 )
314- curses .color_content (1 )
315- curses .color_pair (2 )
320+
321+ def bad_colors (self ):
322+ return (- 1 , curses .COLORS , - 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
323+
324+ def bad_colors2 (self ):
325+ return (curses .COLORS , 2 ** 31 , 2 ** 63 , 2 ** 64 )
326+
327+ def bad_pairs (self ):
328+ return (- 1 , - 2 ** 31 - 1 , 2 ** 31 , - 2 ** 63 - 1 , 2 ** 63 , 2 ** 64 )
329+
330+ @requires_colors
331+ def test_color_content (self ):
332+ self .assertEqual (curses .color_content (curses .COLOR_BLACK ), (0 , 0 , 0 ))
333+ curses .color_content (0 )
334+ curses .color_content (curses .COLORS - 1 )
335+
336+ for color in self .bad_colors ():
337+ self .assertRaises (ValueError , curses .color_content , color )
338+
339+ @requires_colors
340+ def test_init_color (self ):
341+ if not curses .can_change_color :
342+ self .skipTest ('cannot change color' )
343+
344+ old = curses .color_content (0 )
345+ try :
346+ curses .init_color (0 , * old )
347+ except curses .error :
348+ self .skipTest ('cannot change color (init_color() failed)' )
349+ self .addCleanup (curses .init_color , 0 , * old )
350+ curses .init_color (0 , 0 , 0 , 0 )
351+ self .assertEqual (curses .color_content (0 ), (0 , 0 , 0 ))
352+ curses .init_color (0 , 1000 , 1000 , 1000 )
353+ self .assertEqual (curses .color_content (0 ), (1000 , 1000 , 1000 ))
354+
355+ old = curses .color_content (curses .COLORS - 1 )
356+ curses .init_color (curses .COLORS - 1 , * old )
357+ self .addCleanup (curses .init_color , curses .COLORS - 1 , * old )
358+ curses .init_color (curses .COLORS - 1 , 0 , 500 , 1000 )
359+ self .assertEqual (curses .color_content (curses .COLORS - 1 ), (0 , 500 , 1000 ))
360+
361+ for color in self .bad_colors ():
362+ self .assertRaises (ValueError , curses .init_color , color , 0 , 0 , 0 )
363+ for comp in (- 1 , 1001 ):
364+ self .assertRaises (ValueError , curses .init_color , 0 , comp , 0 , 0 )
365+ self .assertRaises (ValueError , curses .init_color , 0 , 0 , comp , 0 )
366+ self .assertRaises (ValueError , curses .init_color , 0 , 0 , 0 , comp )
367+
368+ @requires_colors
369+ def test_pair_content (self ):
370+ if not hasattr (curses , 'use_default_colors' ):
371+ self .assertEqual (curses .pair_content (0 ),
372+ (curses .COLOR_WHITE , curses .COLOR_BLACK ))
373+ curses .pair_content (0 )
316374 curses .pair_content (curses .COLOR_PAIRS - 1 )
317- curses .pair_number (0 )
318-
319- if hasattr (curses , 'use_default_colors' ):
320- curses .use_default_colors ()
321-
322- self .assertRaises (ValueError , curses .color_content , - 1 )
323- self .assertRaises (ValueError , curses .color_content , curses .COLORS + 1 )
324- self .assertRaises (ValueError , curses .color_content , - 2 ** 31 - 1 )
325- self .assertRaises (ValueError , curses .color_content , 2 ** 31 )
326- self .assertRaises (ValueError , curses .color_content , - 2 ** 63 - 1 )
327- self .assertRaises (ValueError , curses .color_content , 2 ** 63 - 1 )
328- self .assertRaises (ValueError , curses .pair_content , - 1 )
329- self .assertRaises (ValueError , curses .pair_content , curses .COLOR_PAIRS )
330- self .assertRaises (ValueError , curses .pair_content , - 2 ** 31 - 1 )
331- self .assertRaises (ValueError , curses .pair_content , 2 ** 31 )
332- self .assertRaises (ValueError , curses .pair_content , - 2 ** 63 - 1 )
333- self .assertRaises (ValueError , curses .pair_content , 2 ** 63 - 1 )
375+
376+ for pair in self .bad_pairs ():
377+ self .assertRaises (ValueError , curses .pair_content , pair )
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+ curses .init_pair (1 , curses .COLORS - 1 , curses .COLORS - 1 )
388+ self .assertEqual (curses .pair_content (1 ),
389+ (curses .COLORS - 1 , curses .COLORS - 1 ))
390+ curses .init_pair (curses .COLOR_PAIRS - 1 , 2 , 3 )
391+ self .assertEqual (curses .pair_content (curses .COLOR_PAIRS - 1 ), (2 , 3 ))
392+
393+ for pair in self .bad_pairs ():
394+ self .assertRaises (ValueError , curses .init_pair , pair , 0 , 0 )
395+ for color in self .bad_colors2 ():
396+ self .assertRaises (ValueError , curses .init_pair , 1 , color , 0 )
397+ self .assertRaises (ValueError , curses .init_pair , 1 , 0 , color )
398+
399+ @requires_colors
400+ def test_color_attrs (self ):
401+ for pair in 0 , 1 , 255 :
402+ attr = curses .color_pair (pair )
403+ self .assertEqual (curses .pair_number (attr ), pair , attr )
404+ self .assertEqual (curses .pair_number (attr | curses .A_BOLD ), pair )
405+ self .assertEqual (curses .color_pair (0 ), 0 )
406+ self .assertEqual (curses .pair_number (0 ), 0 )
407+
408+ @requires_curses_func ('use_default_colors' )
409+ @requires_colors
410+ def test_use_default_colors (self ):
411+ self .assertIn (curses .pair_content (0 ),
412+ ((curses .COLOR_WHITE , curses .COLOR_BLACK ), (- 1 , - 1 )))
413+ curses .use_default_colors ()
414+ self .assertEqual (curses .pair_content (0 ), (- 1 , - 1 ))
334415
335416 @requires_curses_func ('keyname' )
336417 def test_keyname (self ):
0 commit comments