mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	(cherry picked from commit a046c848c1)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
		
	
			
		
			
				
	
	
		
			583 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			583 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
 | 
						|
 | 
						|
import re
 | 
						|
import tkinter
 | 
						|
from test.test_tkinter.support import (AbstractTkTest, requires_tk, tk_version,
 | 
						|
                                  pixels_conv, tcl_obj_eq)
 | 
						|
import test.support
 | 
						|
 | 
						|
 | 
						|
_sentinel = object()
 | 
						|
 | 
						|
class AbstractWidgetTest(AbstractTkTest):
 | 
						|
    _default_pixels = '' if tk_version >= (9, 0) else -1 if tk_version >= (8, 7) else ''
 | 
						|
    _conv_pixels = round
 | 
						|
    _conv_pad_pixels = None
 | 
						|
    _stringify = False
 | 
						|
    _clip_highlightthickness = True
 | 
						|
    _clip_pad = False
 | 
						|
    _clip_borderwidth = False
 | 
						|
    _allow_empty_justify = False
 | 
						|
 | 
						|
    @property
 | 
						|
    def scaling(self):
 | 
						|
        try:
 | 
						|
            return self._scaling
 | 
						|
        except AttributeError:
 | 
						|
            self._scaling = float(self.root.call('tk', 'scaling'))
 | 
						|
            return self._scaling
 | 
						|
 | 
						|
    def _str(self, value):
 | 
						|
        if not self._stringify and self.wantobjects and tk_version >= (8, 6):
 | 
						|
            return value
 | 
						|
        if isinstance(value, tuple):
 | 
						|
            return ' '.join(map(self._str, value))
 | 
						|
        return str(value)
 | 
						|
 | 
						|
    def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__):
 | 
						|
        if eq(actual, expected):
 | 
						|
            return
 | 
						|
        self.assertEqual(actual, expected, msg)
 | 
						|
 | 
						|
    def checkParam(self, widget, name, value, *, expected=_sentinel,
 | 
						|
                   conv=False, eq=None):
 | 
						|
        widget[name] = value
 | 
						|
        if expected is _sentinel:
 | 
						|
            expected = value
 | 
						|
        if conv:
 | 
						|
            expected = conv(expected)
 | 
						|
        if self._stringify or not self.wantobjects:
 | 
						|
            if isinstance(expected, tuple):
 | 
						|
                expected = tkinter._join(expected)
 | 
						|
            else:
 | 
						|
                expected = str(expected)
 | 
						|
        if eq is None:
 | 
						|
            eq = tcl_obj_eq
 | 
						|
        self.assertEqual2(widget[name], expected, eq=eq)
 | 
						|
        self.assertEqual2(widget.cget(name), expected, eq=eq)
 | 
						|
        t = widget.configure(name)
 | 
						|
        self.assertEqual(len(t), 5)
 | 
						|
        self.assertEqual2(t[4], expected, eq=eq)
 | 
						|
 | 
						|
    def checkInvalidParam(self, widget, name, value, errmsg=None):
 | 
						|
        orig = widget[name]
 | 
						|
        if errmsg is not None:
 | 
						|
            errmsg = errmsg.format(re.escape(str(value)))
 | 
						|
            errmsg = fr'\A{errmsg}\Z'
 | 
						|
        with self.assertRaisesRegex(tkinter.TclError, errmsg or ''):
 | 
						|
            widget[name] = value
 | 
						|
        self.assertEqual(widget[name], orig)
 | 
						|
        with self.assertRaisesRegex(tkinter.TclError, errmsg or ''):
 | 
						|
            widget.configure({name: value})
 | 
						|
        self.assertEqual(widget[name], orig)
 | 
						|
 | 
						|
    def checkParams(self, widget, name, *values, **kwargs):
 | 
						|
        for value in values:
 | 
						|
            self.checkParam(widget, name, value, **kwargs)
 | 
						|
 | 
						|
    def checkIntegerParam(self, widget, name, *values, **kwargs):
 | 
						|
        self.checkParams(widget, name, *values, **kwargs)
 | 
						|
        errmsg = 'expected integer but got "{}"'
 | 
						|
        self.checkInvalidParam(widget, name, '', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, name, '10p', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, name, 3.2, errmsg=errmsg)
 | 
						|
 | 
						|
    def checkFloatParam(self, widget, name, *values, conv=float, **kwargs):
 | 
						|
        for value in values:
 | 
						|
            self.checkParam(widget, name, value, conv=conv, **kwargs)
 | 
						|
        errmsg = 'expected floating-point number but got "{}"'
 | 
						|
        self.checkInvalidParam(widget, name, '', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
 | 
						|
 | 
						|
    def checkBooleanParam(self, widget, name):
 | 
						|
        for value in (False, 0, 'false', 'no', 'off'):
 | 
						|
            self.checkParam(widget, name, value, expected=0)
 | 
						|
        for value in (True, 1, 'true', 'yes', 'on'):
 | 
						|
            self.checkParam(widget, name, value, expected=1)
 | 
						|
        errmsg = 'expected boolean value but got "{}"'
 | 
						|
        self.checkInvalidParam(widget, name, '', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
 | 
						|
 | 
						|
    def checkColorParam(self, widget, name, *, allow_empty=None, **kwargs):
 | 
						|
        self.checkParams(widget, name,
 | 
						|
                         '#ff0000', '#00ff00', '#0000ff', '#123456',
 | 
						|
                         'red', 'green', 'blue', 'white', 'black', 'grey',
 | 
						|
                         **kwargs)
 | 
						|
        self.checkInvalidParam(widget, name, 'spam',
 | 
						|
                errmsg='unknown color name "spam"')
 | 
						|
 | 
						|
    def checkCursorParam(self, widget, name, **kwargs):
 | 
						|
        self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs)
 | 
						|
        self.checkParam(widget, name, 'none')
 | 
						|
        self.checkInvalidParam(widget, name, 'spam',
 | 
						|
                errmsg='bad cursor spec "spam"')
 | 
						|
 | 
						|
    def checkCommandParam(self, widget, name):
 | 
						|
        def command(*args):
 | 
						|
            pass
 | 
						|
        widget[name] = command
 | 
						|
        self.assertTrue(widget[name])
 | 
						|
        self.checkParams(widget, name, '')
 | 
						|
 | 
						|
    def checkEnumParam(self, widget, name, *values,
 | 
						|
                       errmsg=None, allow_empty=False, fullname=None,
 | 
						|
                       sort=False, **kwargs):
 | 
						|
        self.checkParams(widget, name, *values, **kwargs)
 | 
						|
        if errmsg is None:
 | 
						|
            if sort:
 | 
						|
                if values[-1]:
 | 
						|
                    values = tuple(sorted(values))
 | 
						|
                else:
 | 
						|
                    values = tuple(sorted(values[:-1])) + ('',)
 | 
						|
            errmsg2 = ' %s "{}": must be %s%s or %s' % (
 | 
						|
                    fullname or name,
 | 
						|
                    ', '.join(values[:-1]),
 | 
						|
                    ',' if len(values) > 2 else '',
 | 
						|
                    values[-1] or '""')
 | 
						|
            if '' not in values and not allow_empty:
 | 
						|
                self.checkInvalidParam(widget, name, '',
 | 
						|
                                       errmsg='ambiguous' + errmsg2)
 | 
						|
            errmsg = 'bad' + errmsg2
 | 
						|
        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
 | 
						|
 | 
						|
    def checkPixelsParam(self, widget, name, *values,
 | 
						|
                         conv=None, **kwargs):
 | 
						|
        if conv is None:
 | 
						|
            conv = self._conv_pixels
 | 
						|
        for value in values:
 | 
						|
            expected = _sentinel
 | 
						|
            conv1 = conv
 | 
						|
            if isinstance(value, str):
 | 
						|
                if conv1 and conv1 is not str:
 | 
						|
                    expected = pixels_conv(value) * self.scaling
 | 
						|
                    conv1 = round
 | 
						|
            self.checkParam(widget, name, value, expected=expected,
 | 
						|
                            conv=conv1, **kwargs)
 | 
						|
        errmsg = '(bad|expected) screen distance ((or "" )?but got )?"{}"'
 | 
						|
        self.checkInvalidParam(widget, name, '6x', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
 | 
						|
 | 
						|
    def checkReliefParam(self, widget, name, *, allow_empty=False):
 | 
						|
        values = ('flat', 'groove', 'raised', 'ridge', 'solid', 'sunken')
 | 
						|
        if allow_empty:
 | 
						|
            values += ('',)
 | 
						|
        self.checkParams(widget, name, *values)
 | 
						|
        errmsg = 'bad relief "{}": must be %s, or %s' % (
 | 
						|
                ', '.join(values[:-1]),
 | 
						|
                values[-1] or '""')
 | 
						|
        if tk_version < (8, 6):
 | 
						|
            errmsg = None
 | 
						|
        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
 | 
						|
 | 
						|
    def checkImageParam(self, widget, name):
 | 
						|
        image = tkinter.PhotoImage(master=self.root, name='image1')
 | 
						|
        self.checkParam(widget, name, image, conv=str)
 | 
						|
        self.checkInvalidParam(widget, name, 'spam',
 | 
						|
                errmsg='image "spam" doesn\'t exist')
 | 
						|
        widget[name] = ''
 | 
						|
 | 
						|
    def checkVariableParam(self, widget, name, var):
 | 
						|
        self.checkParam(widget, name, var, conv=str)
 | 
						|
 | 
						|
    def assertIsBoundingBox(self, bbox):
 | 
						|
        self.assertIsNotNone(bbox)
 | 
						|
        self.assertIsInstance(bbox, tuple)
 | 
						|
        if len(bbox) != 4:
 | 
						|
            self.fail('Invalid bounding box: %r' % (bbox,))
 | 
						|
        for item in bbox:
 | 
						|
            if not isinstance(item, int):
 | 
						|
                self.fail('Invalid bounding box: %r' % (bbox,))
 | 
						|
                break
 | 
						|
 | 
						|
 | 
						|
    def test_keys(self):
 | 
						|
        widget = self.create()
 | 
						|
        keys = widget.keys()
 | 
						|
        self.assertEqual(sorted(keys), sorted(widget.configure()))
 | 
						|
        for k in keys:
 | 
						|
            widget[k]
 | 
						|
        # Test if OPTIONS contains all keys
 | 
						|
        if test.support.verbose:
 | 
						|
            aliases = {
 | 
						|
                'bd': 'borderwidth',
 | 
						|
                'bg': 'background',
 | 
						|
                'bgimg': 'backgroundimage',
 | 
						|
                'fg': 'foreground',
 | 
						|
                'invcmd': 'invalidcommand',
 | 
						|
                'vcmd': 'validatecommand',
 | 
						|
            }
 | 
						|
            keys = set(keys)
 | 
						|
            expected = set(self.OPTIONS)
 | 
						|
            for k in sorted(keys - expected):
 | 
						|
                if not (k in aliases and
 | 
						|
                        aliases[k] in keys and
 | 
						|
                        aliases[k] in expected):
 | 
						|
                    print('%s.OPTIONS doesn\'t contain "%s"' %
 | 
						|
                          (self.__class__.__name__, k))
 | 
						|
 | 
						|
 | 
						|
class StandardOptionsTests:
 | 
						|
    STANDARD_OPTIONS = (
 | 
						|
        'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',
 | 
						|
        'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
 | 
						|
        'disabledforeground', 'exportselection', 'font', 'foreground',
 | 
						|
        'highlightbackground', 'highlightcolor', 'highlightthickness',
 | 
						|
        'image', 'insertbackground', 'insertborderwidth',
 | 
						|
        'insertofftime', 'insertontime', 'insertwidth',
 | 
						|
        'jump', 'justify', 'orient', 'padx', 'pady', 'relief',
 | 
						|
        'repeatdelay', 'repeatinterval',
 | 
						|
        'selectbackground', 'selectborderwidth', 'selectforeground',
 | 
						|
        'setgrid', 'takefocus', 'text', 'textvariable', 'troughcolor',
 | 
						|
        'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
 | 
						|
    )
 | 
						|
 | 
						|
    def test_configure_activebackground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'activebackground')
 | 
						|
 | 
						|
    def test_configure_activeborderwidth(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'activeborderwidth',
 | 
						|
                              0, 1.3, 2.9, 6, -2, '10p')
 | 
						|
 | 
						|
    def test_configure_activeforeground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'activeforeground')
 | 
						|
 | 
						|
    def test_configure_activerelief(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkReliefParam(widget, 'activerelief')
 | 
						|
 | 
						|
    def test_configure_anchor(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkEnumParam(widget, 'anchor',
 | 
						|
                'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
 | 
						|
 | 
						|
    def test_configure_background(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'background')
 | 
						|
        if 'bg' in self.OPTIONS:
 | 
						|
            self.checkColorParam(widget, 'bg')
 | 
						|
 | 
						|
    @requires_tk(8, 7)
 | 
						|
    def test_configure_backgroundimage(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkImageParam(widget, 'backgroundimage')
 | 
						|
 | 
						|
    def test_configure_bitmap(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParam(widget, 'bitmap', 'questhead')
 | 
						|
        self.checkParam(widget, 'bitmap', 'gray50')
 | 
						|
        filename = test.support.findfile('python.xbm', subdir='tkinterdata')
 | 
						|
        self.checkParam(widget, 'bitmap', '@' + filename)
 | 
						|
        # Cocoa Tk widgets don't detect invalid -bitmap values
 | 
						|
        # See https://core.tcl.tk/tk/info/31cd33dbf0
 | 
						|
        if not ('aqua' in self.root.tk.call('tk', 'windowingsystem') and
 | 
						|
                'AppKit' in self.root.winfo_server()):
 | 
						|
            self.checkInvalidParam(widget, 'bitmap', 'spam',
 | 
						|
                    errmsg='bitmap "spam" not defined')
 | 
						|
 | 
						|
    def test_configure_borderwidth(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'borderwidth',
 | 
						|
                              0, 1.3, 2.6, 6, '10p')
 | 
						|
        expected = 0 if self._clip_borderwidth else -2
 | 
						|
        self.checkParam(widget, 'borderwidth', -2, expected=expected,
 | 
						|
                        conv=self._conv_pixels)
 | 
						|
        if 'bd' in self.OPTIONS:
 | 
						|
            self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, '10p')
 | 
						|
            self.checkParam(widget, 'bd', -2, expected=expected,
 | 
						|
                            conv=self._conv_pixels)
 | 
						|
 | 
						|
    def test_configure_compound(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkEnumParam(widget, 'compound',
 | 
						|
                'bottom', 'center', 'left', 'none', 'right', 'top')
 | 
						|
 | 
						|
    def test_configure_cursor(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkCursorParam(widget, 'cursor')
 | 
						|
 | 
						|
    def test_configure_disabledforeground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'disabledforeground')
 | 
						|
 | 
						|
    def test_configure_exportselection(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkBooleanParam(widget, 'exportselection')
 | 
						|
 | 
						|
    def test_configure_font(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParam(widget, 'font',
 | 
						|
                        '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
 | 
						|
        is_ttk = widget.__class__.__module__ == 'tkinter.ttk'
 | 
						|
        if not is_ttk:
 | 
						|
            self.checkInvalidParam(widget, 'font', '',
 | 
						|
                                   errmsg='font "" doesn\'t exist')
 | 
						|
 | 
						|
    def test_configure_foreground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'foreground')
 | 
						|
        if 'fg' in self.OPTIONS:
 | 
						|
            self.checkColorParam(widget, 'fg')
 | 
						|
 | 
						|
    def test_configure_highlightbackground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'highlightbackground')
 | 
						|
 | 
						|
    def test_configure_highlightcolor(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'highlightcolor')
 | 
						|
 | 
						|
    def test_configure_highlightthickness(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'highlightthickness',
 | 
						|
                              0, 1.3, 2.6, 6, '10p')
 | 
						|
        expected = 0 if self._clip_highlightthickness else -2
 | 
						|
        self.checkParam(widget, 'highlightthickness', -2, expected=expected,
 | 
						|
                        conv=self._conv_pixels)
 | 
						|
 | 
						|
    def test_configure_image(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkImageParam(widget, 'image')
 | 
						|
 | 
						|
    def test_configure_insertbackground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'insertbackground')
 | 
						|
 | 
						|
    def test_configure_insertborderwidth(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'insertborderwidth',
 | 
						|
                              0, 1.3, 2.6, 6, -2, '10p')
 | 
						|
 | 
						|
    def test_configure_insertofftime(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'insertofftime', 100)
 | 
						|
 | 
						|
    def test_configure_insertontime(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'insertontime', 100)
 | 
						|
 | 
						|
    def test_configure_insertwidth(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
 | 
						|
 | 
						|
    def test_configure_jump(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkBooleanParam(widget, 'jump')
 | 
						|
 | 
						|
    def test_configure_justify(self):
 | 
						|
        widget = self.create()
 | 
						|
        values = ('left', 'right', 'center')
 | 
						|
        if self._allow_empty_justify:
 | 
						|
            values += ('',)
 | 
						|
        self.checkEnumParam(widget, 'justify', *values,
 | 
						|
                            fullname='justification')
 | 
						|
 | 
						|
    def test_configure_orient(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.assertEqual(str(widget['orient']), self.default_orient)
 | 
						|
        self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
 | 
						|
 | 
						|
    def test_configure_padx(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m',
 | 
						|
                              conv=self._conv_pad_pixels)
 | 
						|
        expected = 0 if self._clip_pad else -2
 | 
						|
        self.checkParam(widget, 'padx', -2, expected=expected,
 | 
						|
                        conv=self._conv_pad_pixels)
 | 
						|
 | 
						|
    def test_configure_pady(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m',
 | 
						|
                              conv=self._conv_pad_pixels)
 | 
						|
        expected = 0 if self._clip_pad else -2
 | 
						|
        self.checkParam(widget, 'pady', -2, expected=expected,
 | 
						|
                        conv=self._conv_pad_pixels)
 | 
						|
 | 
						|
    @requires_tk(8, 7)
 | 
						|
    def test_configure_placeholder(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParam(widget, 'placeholder', 'xxx')
 | 
						|
 | 
						|
    @requires_tk(8, 7)
 | 
						|
    def test_configure_placeholderforeground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'placeholderforeground')
 | 
						|
 | 
						|
    def test_configure_relief(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkReliefParam(widget, 'relief')
 | 
						|
 | 
						|
    def test_configure_repeatdelay(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
 | 
						|
 | 
						|
    def test_configure_repeatinterval(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
 | 
						|
 | 
						|
    def test_configure_selectbackground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'selectbackground')
 | 
						|
 | 
						|
    def test_configure_selectborderwidth(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
 | 
						|
 | 
						|
    def test_configure_selectforeground(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'selectforeground')
 | 
						|
 | 
						|
    def test_configure_setgrid(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkBooleanParam(widget, 'setgrid')
 | 
						|
 | 
						|
    def test_configure_state(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
 | 
						|
 | 
						|
    def test_configure_takefocus(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParams(widget, 'takefocus', '0', '1', '')
 | 
						|
 | 
						|
    def test_configure_text(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParams(widget, 'text', '', 'any string')
 | 
						|
 | 
						|
    def test_configure_textvariable(self):
 | 
						|
        widget = self.create()
 | 
						|
        var = tkinter.StringVar(self.root)
 | 
						|
        self.checkVariableParam(widget, 'textvariable', var)
 | 
						|
 | 
						|
    @requires_tk(8, 7)
 | 
						|
    def test_configure_tile(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkBooleanParam(widget, 'tile')
 | 
						|
 | 
						|
    def test_configure_troughcolor(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'troughcolor')
 | 
						|
 | 
						|
    def test_configure_underline(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParams(widget, 'underline', 0, 1, 10)
 | 
						|
        if tk_version >= (8, 7):
 | 
						|
            is_ttk = widget.__class__.__module__ == 'tkinter.ttk'
 | 
						|
            self.checkParam(widget, 'underline', '',
 | 
						|
                            expected='' if is_ttk else self._default_pixels)
 | 
						|
            self.checkParam(widget, 'underline', '5+2',
 | 
						|
                            expected='5+2' if is_ttk else 7)
 | 
						|
            self.checkParam(widget, 'underline', '5-2',
 | 
						|
                            expected='5-2' if is_ttk else 3)
 | 
						|
            self.checkParam(widget, 'underline', 'end', expected='end')
 | 
						|
            self.checkParam(widget, 'underline', 'end-2', expected='end-2')
 | 
						|
            errmsg = (r'bad index "{}": must be integer\?\[\+-\]integer\?, '
 | 
						|
                      r'end\?\[\+-\]integer\?, or ""')
 | 
						|
        else:
 | 
						|
            errmsg = 'expected integer but got "{}"'
 | 
						|
            self.checkInvalidParam(widget, 'underline', '', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, 'underline', '10p', errmsg=errmsg)
 | 
						|
        self.checkInvalidParam(widget, 'underline', 3.2, errmsg=errmsg)
 | 
						|
 | 
						|
    def test_configure_wraplength(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'wraplength', 100)
 | 
						|
 | 
						|
    def test_configure_xscrollcommand(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkCommandParam(widget, 'xscrollcommand')
 | 
						|
 | 
						|
    def test_configure_yscrollcommand(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkCommandParam(widget, 'yscrollcommand')
 | 
						|
 | 
						|
    # non-standard but common options
 | 
						|
 | 
						|
    def test_configure_command(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkCommandParam(widget, 'command')
 | 
						|
 | 
						|
    def test_configure_indicatoron(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkBooleanParam(widget, 'indicatoron')
 | 
						|
 | 
						|
    def test_configure_offrelief(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkReliefParam(widget, 'offrelief')
 | 
						|
 | 
						|
    def test_configure_overrelief(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkReliefParam(widget, 'overrelief',
 | 
						|
                              allow_empty=(tk_version >= (8, 7)))
 | 
						|
 | 
						|
    def test_configure_selectcolor(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkColorParam(widget, 'selectcolor')
 | 
						|
 | 
						|
    def test_configure_selectimage(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkImageParam(widget, 'selectimage')
 | 
						|
 | 
						|
    def test_configure_tristateimage(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkImageParam(widget, 'tristateimage')
 | 
						|
 | 
						|
    def test_configure_tristatevalue(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkParam(widget, 'tristatevalue', 'unknowable')
 | 
						|
 | 
						|
    def test_configure_variable(self):
 | 
						|
        widget = self.create()
 | 
						|
        var = tkinter.DoubleVar(self.root)
 | 
						|
        self.checkVariableParam(widget, 'variable', var)
 | 
						|
 | 
						|
 | 
						|
class IntegerSizeTests:
 | 
						|
    def test_configure_height(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'height', 100, -100, 0)
 | 
						|
 | 
						|
    def test_configure_width(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkIntegerParam(widget, 'width', 402, -402, 0)
 | 
						|
 | 
						|
 | 
						|
class PixelSizeTests:
 | 
						|
    def test_configure_height(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
 | 
						|
 | 
						|
    def test_configure_width(self):
 | 
						|
        widget = self.create()
 | 
						|
        self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
 | 
						|
 | 
						|
 | 
						|
def add_standard_options(*source_classes):
 | 
						|
    # This decorator adds test_configure_xxx methods from source classes for
 | 
						|
    # every xxx option in the OPTIONS class attribute if they are not defined
 | 
						|
    # explicitly.
 | 
						|
    def decorator(cls):
 | 
						|
        for option in cls.OPTIONS:
 | 
						|
            methodname = 'test_configure_' + option
 | 
						|
            if not hasattr(cls, methodname):
 | 
						|
                for source_class in source_classes:
 | 
						|
                    if hasattr(source_class, methodname):
 | 
						|
                        setattr(cls, methodname,
 | 
						|
                                getattr(source_class, methodname))
 | 
						|
                        break
 | 
						|
                else:
 | 
						|
                    def test(self, option=option):
 | 
						|
                        widget = self.create()
 | 
						|
                        widget[option]
 | 
						|
                        raise AssertionError('Option "%s" is not tested in %s' %
 | 
						|
                                             (option, cls.__name__))
 | 
						|
                    test.__name__ = methodname
 | 
						|
                    setattr(cls, methodname, test)
 | 
						|
        return cls
 | 
						|
    return decorator
 | 
						|
 | 
						|
def setUpModule():
 | 
						|
    if test.support.verbose:
 | 
						|
        tcl = tkinter.Tcl()
 | 
						|
        print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True)
 |