get_tk_patchlevel, widget_eq,
wait_until_mapped,
AbstractDefaultRootTest)
+
from test.test_tkinter.widget_tests import (
- add_standard_options,
- AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests)
+ add_configure_tests,
+ AbstractWidgetTest,
+ StandardOptionsTests,
+ IntegerSizeTests,
+ PixelSizeTests)
requires('gui')
def float_round(x):
return float(round(x))
-
class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
- _conv_pad_pixels = False
+ _no_round = {'padx', 'pady'}
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'height', 'highlightthickness', 'padx',
+ 'pady', 'width'}
def test_configure_class(self):
widget = self.create()
self.assertEqual(widget2['visual'], 'default')
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
OPTIONS = (
'background', 'backgroundimage', 'borderwidth',
self.assertEqual(widget2['use'], wid)
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class FrameTest(AbstractToplevelTest, unittest.TestCase):
OPTIONS = (
'background', 'backgroundimage', 'borderwidth',
return tkinter.Frame(self.root, **kwargs)
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
OPTIONS = (
'background', 'borderwidth',
self.checkParam(widget, 'labelwidget', label, expected='.foo')
label.destroy()
-
+# Label, Button, Checkbutton, Radiobutton, MenuButton
class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
- _conv_pixels = False
- _clip_highlightthickness = tk_version >= (8, 7)
- _clip_pad = tk_version >= (8, 7)
- _clip_borderwidth = tk_version >= (8, 7)
-
-
-@add_standard_options(StandardOptionsTests)
+ _rounds_pixels = False
+ if tk_version < (8, 7):
+ _clipped = {}
+ elif tk_version < (9, 0):
+ _clipped = {'borderwidth', 'height', 'highlightthickness', 'padx', 'pady', 'width'}
+ else:
+ _clipped = {'borderwidth', 'height', 'highlightthickness',
+ 'insertborderwidth', 'padx', 'pady', 'width'}
+
+ def setUp(self):
+ super().setUp()
+ if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 2):
+ self._clipped = self._clipped - {'height', 'width'}
+
+
+@add_configure_tests(StandardOptionsTests)
class LabelTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeforeground', 'anchor',
return tkinter.Label(self.root, **kwargs)
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class ButtonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeforeground', 'anchor',
'repeatdelay', 'repeatinterval',
'state', 'takefocus', 'text', 'textvariable',
'underline', 'width', 'wraplength')
+ if tk_version < (8, 7):
+ _clipped = {}
+ else:
+ _clipped = {'borderwidth', 'height', 'highlightthickness',
+ 'padx', 'pady', 'width'}
def create(self, **kwargs):
return tkinter.Button(self.root, **kwargs)
widget.flash() # No exception.
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeforeground', 'anchor',
widget.flash() # No exception.
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeforeground', 'anchor',
widget.flash() # No exception.
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeforeground', 'anchor',
'takefocus', 'text', 'textvariable',
'underline', 'width', 'wraplength',
)
- _conv_pixels = round
- _clip_highlightthickness = True
- _clip_pad = True
- _clip_borderwidth = False
+ _rounds_pixels = (tk_version < (9, 0))
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness', 'padx', 'pady'}
+ elif tk_version < (9, 0):
+ _clipped = {'borderwidth', 'highlightthickness', 'padx', 'pady'}
+ else:
+ _clipped = {'borderwidth', 'highlightthickness', 'insertborderwidth', 'padx', 'pady'}
+
+ def setUp(self):
+ super().setUp()
+ if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1):
+ self._clipped = self._clipped - {'borderwidth'}
def create(self, **kwargs):
return tkinter.Menubutton(self.root, **kwargs)
def test_configure_height(self):
widget = self.create()
- self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
+ if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)):
+ conv = str
+ else:
+ conv = False
+ self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=conv)
def test_configure_image(self):
widget = self.create()
image = tkinter.PhotoImage(master=self.root, name='image1')
self.checkParam(widget, 'image', image, conv=str)
- errmsg = 'image "spam" doesn\'t exist'
+ if tk_version < (8, 7):
+ errmsg = 'image "spam" doesn\'t exist'
+ else:
+ errmsg = 'image "spam" does not exist'
with self.assertRaises(tkinter.TclError) as cm:
widget['image'] = 'spam'
if errmsg is not None:
def test_configure_width(self):
widget = self.create()
- self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
+ if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)):
+ conv = str
+ else:
+ conv = False
+ self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=conv)
class OptionMenuTest(MenubuttonTest, unittest.TestCase):
with self.assertRaisesRegex(TclError, r"^unknown option -image$"):
tkinter.OptionMenu(self.root, None, 'b', image='')
-
-@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'highlightthickness', 'insertborderwidth',
+ 'insertwidth', 'selectborderwidth'}
+
OPTIONS = (
'background', 'borderwidth', 'cursor',
'disabledbackground', 'disabledforeground',
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
# insertborderwidth is bounded above by a half of insertwidth.
- self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
+ expected = 100 // 2 if tk_version < (8, 7) else 60
+ self.checkParam(widget, 'insertborderwidth', 60, expected=expected)
def test_configure_insertwidth(self):
widget = self.create()
- self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
- self.checkParam(widget, 'insertwidth', 0.1, expected=2)
- self.checkParam(widget, 'insertwidth', -2, expected=2)
- self.checkParam(widget, 'insertwidth', 0.9, expected=1)
+ self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, 0.9, '10p')
+ if tk_version < (8, 7):
+ self.checkParam(widget, 'insertwidth', 0, expected=2)
+ self.checkParam(widget, 'insertwidth', 0.1, expected=2)
+ self.checkParam(widget, 'insertwidth', -2, expected=2)
+ else:
+ self.checkPixelsParam(widget, 'insertwidth', 0, 0.1, -2)
def test_configure_invalidcommand(self):
widget = self.create()
widget.select_range, 'xyz', 'end')
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class SpinboxTest(EntryTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'background', 'borderwidth',
# XXX
widget = self.create()
self.assertEqual(widget['values'], '')
- self.checkParam(widget, 'values', 'mon tue wed thur')
+ if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)):
+ expected = 'mon tue wed thur'
+ else:
+ expected = ('mon', 'tue', 'wed', 'thur')
+ self.checkParam(widget, 'values', 'mon tue wed thur',
+ expected=expected)
self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),
- expected='mon tue wed thur')
+ expected=expected)
+
+ if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)):
+ expected = '42 3.14 {} {any string}'
+ else:
+ expected = (42, 3.14, '', 'any string')
self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),
- expected='42 3.14 {} {any string}')
+ expected=expected)
+
self.checkParam(widget, 'values', '')
def test_configure_wrap(self):
self.assertRaises(TypeError, widget.scan_mark)
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class TextTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'autoseparators', 'background', 'blockcursor', 'borderwidth',
'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',
'xscrollcommand', 'yscrollcommand',
)
+ _no_round = {'selectborderwidth'}
+ if tk_version < (9, 0):
+ _clipped = {'highlightthickness', 'spacing1', 'spacing2', 'spacing3'}
+ else:
+ _clipped = {'borderwidth', 'height', 'highlightthickness',
+ 'insertborderwidth', 'insertwidth', 'padx', 'pady',
+ 'selectborderwidth', 'spacing1', 'spacing2', 'spacing3'}
+
+ def setUp(self):
+ super().setUp()
+ if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 2):
+ self._clipped = self._clipped - {'borderwidth', 'height', 'padx', 'pady'}
+ if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1):
+ self._clipped = self._clipped - {'insertborderwidth', 'insertwidth', 'selectborderwidth'}
def create(self, **kwargs):
return tkinter.Text(self.root, **kwargs)
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
- self.checkParam(widget, 'height', -100, expected=1)
- self.checkParam(widget, 'height', 0, expected=1)
+ if tk_version < (9, 0):
+ self.checkParam(widget, 'height', 0, expected=1)
+ self.checkParam(widget, 'height', -100, expected=1)
+ else:
+ self.checkPixelsParam(widget, 'height', 0, -100)
def test_configure_maxundo(self):
widget = self.create()
self.checkEnumParam(widget, 'insertunfocussed',
'hollow', 'none', 'solid')
- def test_configure_selectborderwidth(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'selectborderwidth',
- 1.3, 2.6, -2, '10p', conv=False)
-
def test_configure_spacing1(self):
widget = self.create()
- self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
- self.checkParam(widget, 'spacing1', -5, expected=0)
+ self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, -5, '0.5c')
def test_configure_spacing2(self):
widget = self.create()
- self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
- self.checkParam(widget, 'spacing2', -1, expected=0)
+ self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, -1, '0.1c')
def test_configure_spacing3(self):
widget = self.create()
- self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
- self.checkParam(widget, 'spacing3', -10, expected=0)
+ self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, -10, '0.5c')
def test_configure_startline(self):
widget = self.create()
self.assertRaises(TypeError, widget.bbox, '1.1', 'end')
-@add_standard_options(PixelSizeTests, StandardOptionsTests)
+@add_configure_tests(PixelSizeTests, StandardOptionsTests)
class CanvasTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'background', 'borderwidth',
'xscrollcommand', 'xscrollincrement',
'yscrollcommand', 'yscrollincrement', 'width',
)
-
- _conv_pixels = round
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'height', 'highlightthickness',
+ 'insertborderwidth', 'insertwidth', 'selectborderwidth',
+ 'width', 'xscrollincrement', 'yscrollincrement'}
_stringify = True
+ def setUp(self):
+ super().setUp()
+ if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1):
+ self._rounds_pixels = True
+ self._no_round = {'borderwidth', 'height', 'highlightthickness',
+ 'width', 'xscrollincrement', 'yscrollincrement'}
+ self._clipped = self._clipped - {'insertborderwidth', 'insertwidth', 'selectborderwidth'}
+
def create(self, **kwargs):
return tkinter.Canvas(self.root, **kwargs)
def test_create_polygon(self):
c = self.create()
- tk87 = tk_version >= (8, 7)
# In Tk < 8.7 polygons are filled, but has no outline by default.
# This affects its size, so always explicitly specify outline.
i1 = c.create_polygon(20, 30, 40, 50, 60, 10, outline='red')
self.assertRaises(TypeError, c.tag_unbind, item)
-@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardOptionsTests)
class ListboxTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'activestyle', 'background', 'borderwidth', 'cursor',
'selectmode', 'setgrid', 'state',
'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
)
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'highlightthickness', 'selectborderwidth'}
def create(self, **kwargs):
return tkinter.Listbox(self.root, **kwargs)
self.assertEqual(lb.curselection(), (2,))
-@add_standard_options(PixelSizeTests, StandardOptionsTests)
+@add_configure_tests(PixelSizeTests, StandardOptionsTests)
class ScaleTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'background', 'bigincrement', 'borderwidth',
'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',
'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',
)
+ _clipped = {'highlightthickness'}
default_orient = 'vertical'
def create(self, **kwargs):
self.assertRaises(TclError, widget.identify, 'a', 'b')
-@add_standard_options(PixelSizeTests, StandardOptionsTests)
+@add_configure_tests(PixelSizeTests, StandardOptionsTests)
class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activerelief',
'repeatdelay', 'repeatinterval',
'takefocus', 'troughcolor', 'width',
)
- _conv_pixels = round
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ elif tk_version < (9, 0):
+ _clipped = {'borderwidth', 'elementborderwidth', 'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'elementborderwidth', 'highlightthickness', 'width'}
+ _clipped_to_default = {'elementborderwidth'}
_stringify = True
default_orient = 'vertical'
def test_configure_elementborderwidth(self):
widget = self.create()
- self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, '1m')
- expected = self._default_pixels if tk_version >= (8, 7) else -2
- self.checkParam(widget, 'elementborderwidth', -2, expected=expected)
+ self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
def test_configure_orient(self):
widget = self.create()
self.assertRaises(TclError, sb.identify, 'a', 'b')
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(PixelSizeTests, StandardOptionsTests)
class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'background', 'borderwidth', 'cursor',
'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',
'showhandle', 'width',
)
+ _no_round = {'handlesize', 'height', 'proxyborderwidth', 'sashwidth',
+ 'selectborderwidth', 'width'}
+ _clipped = {}
default_orient = 'horizontal'
def create(self, **kwargs):
def test_configure_handlesize(self):
widget = self.create()
- self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
- conv=False)
-
- def test_configure_height(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
- conv=False)
+ self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m')
def test_configure_opaqueresize(self):
widget = self.create()
def test_configure_proxyborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'proxyborderwidth',
- 0, 1.3, 2.9, 6, -2, '10p',
- conv=False)
+ 0, 1.3, 2.9, 6, -2, '10p')
@requires_tk(8, 6, 5)
def test_configure_proxyrelief(self):
def test_configure_sashwidth(self):
widget = self.create()
- self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
- conv=False)
+ self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m')
def test_configure_showhandle(self):
widget = self.create()
self.checkBooleanParam(widget, 'showhandle')
- def test_configure_width(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
- conv=False)
-
def create2(self):
p = self.create()
b = tkinter.Button(p)
def test_paneconfigure_padx(self):
p, b, c = self.create2()
- self.check_paneconfigure(p, b, 'padx', 1.3, 1)
+ self.check_paneconfigure(p, b, 'padx', 1.3, 1 if tk_version < (9, 0) else 1.3)
self.check_paneconfigure_bad(p, b, 'padx',
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('badValue'))
def test_paneconfigure_pady(self):
p, b, c = self.create2()
- self.check_paneconfigure(p, b, 'pady', 1.3, 1)
+ self.check_paneconfigure(p, b, 'pady', 1.3, 1 if tk_version < (9, 0) else 1.3)
self.check_paneconfigure_bad(p, b, 'pady',
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('badValue'))
EXPECTED_SCREEN_DISTANCE_OR_EMPTY_ERRMSG.format('badValue'))
-@add_standard_options(StandardOptionsTests)
+@add_configure_tests(StandardOptionsTests)
class MenuTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'activebackground', 'activeborderwidth', 'activeforeground',
- 'activerelief',
- 'background', 'borderwidth', 'cursor',
+ 'activerelief', 'background', 'borderwidth', 'cursor',
'disabledforeground', 'font', 'foreground',
'postcommand', 'relief', 'selectcolor', 'takefocus',
'tearoff', 'tearoffcommand', 'title', 'type',
)
- _conv_pixels = False
+ _rounds_pixels = False
+ _clipped = {}
def create(self, **kwargs):
return tkinter.Menu(self.root, **kwargs)
m.entrycget, 0, 'onvalue')
-@add_standard_options(PixelSizeTests, StandardOptionsTests)
+@add_configure_tests(PixelSizeTests, StandardOptionsTests)
class MessageTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'anchor', 'aspect', 'background', 'borderwidth',
'justify', 'padx', 'pady', 'relief',
'takefocus', 'text', 'textvariable', 'width',
)
- _conv_pad_pixels = False
- if tk_version >= (8, 7):
- _conv_pixels = False
- _clip_pad = tk_version >= (8, 7)
- _clip_borderwidth = tk_version >= (8, 7)
+ _no_round = {'padx', 'pady'}
+ if tk_version < (8, 7):
+ _clipped = {'highlightthickness'}
+ else:
+ _clipped = {'borderwidth', 'highlightthickness', 'padx', 'pady', 'width'}
+ _clipped_to_default = {'padx', 'pady'}
def create(self, **kwargs):
return tkinter.Message(self.root, **kwargs)
widget = self.create()
self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
- def test_configure_padx(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m',
- conv=self._conv_pad_pixels)
- expected = self._default_pixels if self._clip_pad else -2
- self.checkParam(widget, 'padx', -2, expected=expected)
-
- def test_configure_pady(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m',
- conv=self._conv_pad_pixels)
- expected = self._default_pixels if self._clip_pad else -2
- self.checkParam(widget, 'pady', -2, expected=expected)
-
- def test_configure_width(self):
- widget = self.create()
- self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, 0, '5i')
- expected = 0 if tk_version >= (8, 7) else -402
- self.checkParam(widget, 'width', -402, expected=expected)
-
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
pixels_conv, tcl_obj_eq)
import test.support
-
_sentinel = object()
# Abbreviated option names accepted by Tk in addition to the full names.
# borderwidth = bd
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
+ _default_pixels = '' if tk_version >= (9, 0) else -1 # Value for unset pixel options.
+ _rounds_pixels = (tk_version < (9, 0)) # True if some pixel options are rounded.
+ _no_round = set() # Pixel options which are not rounded nonetheless
+ _stringify = False # Whether to convert tuples to strings
_allow_empty_justify = False
+ _clipped_to_default = set()
@property
def scaling(self):
widget[name] = value
if expected is _sentinel:
expected = value
+ if name in self._clipped:
+ if not isinstance(expected, str) and expected < 0:
+ if tk_version >= (8, 7) and name in self._clipped_to_default:
+ expected = self._default_pixels
+ else:
+ expected = 0
if conv:
expected = conv(expected)
if self._stringify or not self.wantobjects:
errmsg = 'bad' + errmsg2
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
- def checkPixelsParam(self, widget, name, *values,
- conv=None, **kwargs):
+ def checkPixelsParam(self, widget, name, *values, conv=None, **kwargs):
if conv is None:
- conv = self._conv_pixels
+ if self._rounds_pixels and name not in self._no_round:
+ conv = round
+ alow_neg = tk_version < (9, 1)
for value in values:
expected = _sentinel
conv1 = conv
if isinstance(value, str):
+ if not getattr(self, '_converts_pixels', True):
+ conv1 = str
if conv1 and conv1 is not str:
expected = pixels_conv(value) * self.scaling
conv1 = round
+ elif not alow_neg and isinstance(value, (int, float)) and value < 0:
+ self.checkInvalidParam(widget, name, value)
+ continue
self.checkParam(widget, name, value, expected=expected,
conv=conv1, **kwargs)
errmsg = '(bad|expected) screen distance ((or "" )?but got )?"{}"'
def checkImageParam(self, widget, name):
image = tkinter.PhotoImage(master=self.root, name='image1')
self.checkParam(widget, name, image, conv=str)
+ if tk_version < (8, 7):
+ errmsg = 'image "spam" doesn\'t exist'
+ else:
+ errmsg = 'image "spam" does not exist'
self.checkInvalidParam(widget, name, 'spam',
- errmsg='image "spam" doesn\'t exist')
+ errmsg=errmsg)
widget[name] = ''
def checkVariableParam(self, widget, name, var):
print('%s.__init__ docstring doesn\'t contain "%s"'
% (type(widget).__name__, key))
+class PixelOptionsTests:
+ """Standard options that accept all formats acceptable to Tk_GetPixels.
-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')
+ In addition to numbers, these options can be set with distances
+ specified as a string consisting of a number followed by a single
+ character giving the unit of distance. The allowed units are:
+ millimeters ('m'), centimeters ('c'), inches ('i') or points ('p').
+ In Tk 9 a cget call for one of these options returns a Tcl_Obj of
+ type "pixels", whose string representation is the distance string
+ passed to configure.
+ """
+ PIXEL_OPTIONS = ('activeborderwidth', 'borderwidth', 'highlightthickness',
+ 'insertborderwidth', 'insertwidth', 'padx', 'pady', 'selectborderwidth')
def test_configure_activeborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'activeborderwidth',
0, 1.3, 2.9, 6, -2, '10p')
+ def test_configure_borderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'borderwidth',
+ 0, 1.3, 2.6, 6, -2, '10p')
+
+ if 'bd' in self.OPTIONS:
+ self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, '10p')
+ self.checkParam(widget, 'bd', -2, expected=expected)
+
+ def test_configure_highlightthickness(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'highlightthickness',
+ 0, 1.3, 2.6, 6, -2, '10p')
+
+ def test_configure_insertborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'insertborderwidth', 0, 1.3, 2.6, 6, -2, '10p')
+
+ def test_configure_insertwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
+
+ def test_configure_padx(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m')
+
+ def test_configure_pady(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m')
+
+ def test_configure_selectborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
+
+
+class StandardOptionsTests(PixelOptionsTests):
+
+ STANDARD_OPTIONS = ( 'activebackground', 'activeforeground',
+ 'anchor', 'background', 'bitmap', 'compound', 'cursor',
+ 'disabledforeground', 'exportselection', 'font', 'foreground',
+ 'highlightbackground', 'highlightcolor', 'image',
+ 'insertbackground', 'insertofftime', 'insertontime', 'jump',
+ 'justify', 'orient', 'relief', 'repeatdelay', 'repeatinterval',
+ 'selectbackground', 'selectforeground', 'setgrid', 'takefocus',
+ 'text', 'textvariable', 'troughcolor', 'underline', 'wraplength',
+ 'xscrollcommand', 'yscrollcommand', ) + PixelOptionsTests.PIXEL_OPTIONS
+
+ def test_configure_activebackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'activebackground')
+
def test_configure_activeforeground(self):
widget = self.create()
self.checkColorParam(widget, 'activeforeground')
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',
'-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')
+ errmsg = 'font "" does ?n[o\']t exist'
+ self.checkInvalidParam(widget, 'font', '', errmsg=errmsg)
def test_configure_foreground(self):
widget = self.create()
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')
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)
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')
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()
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')
class IntegerSizeTests:
+ """ Tests widgets which only accept integral width and height."""
def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0)
class PixelSizeTests:
+ """ Tests widgets which accept screen distances for width and height."""
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
-def add_standard_options(*source_classes):
+def add_configure_tests(*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.
from test.test_tkinter.support import (
AbstractTkTest, requires_tk, tk_version, get_tk_patchlevel,
simulate_mouse_click, wait_until_mapped, AbstractDefaultRootTest)
-from test.test_tkinter.widget_tests import (add_standard_options,
+from test.test_tkinter.widget_tests import (add_configure_tests,
AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests)
requires('gui')
class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
- _conv_pixels = False
+ _rounds_pixels = False
+ _clipped = {}
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class FrameTest(AbstractToplevelTest, unittest.TestCase):
OPTIONS = (
'borderwidth', 'class', 'cursor', 'height',
return ttk.Frame(self.root, **kwargs)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
OPTIONS = (
'borderwidth', 'class', 'cursor', 'height',
class AbstractLabelTest(AbstractWidgetTest):
_allow_empty_justify = True
+ _rounds_pixels = False
+ _clipped = {}
def checkImageParam(self, widget, name):
image = tkinter.PhotoImage(master=self.root, name='image1')
expected=('image1', 'active', 'image2'))
self.checkParam(widget, name, 'image1 active image2',
expected=('image1', 'active', 'image2'))
- self.checkInvalidParam(widget, name, 'spam',
- errmsg='image "spam" doesn\'t exist')
+ if tk_version < (8, 7):
+ errmsg = 'image "spam" doesn\'t exist'
+ else:
+ errmsg = 'image "spam" does not exist'
+ self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def test_configure_compound(self):
values = ('none', 'text', 'image', 'center', 'top', 'bottom', 'left', 'right')
self.checkParams(widget, 'width', 402, -402, 0)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class LabelTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'anchor', 'background', 'borderwidth',
test_configure_justify = StandardOptionsTests.test_configure_justify
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class ButtonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'compound', 'cursor', 'default',
self.assertTrue(success)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'compound', 'cursor',
self.assertEqual(len(set(variables)), len(buttons), variables)
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardTtkOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'background', 'class', 'cursor',
'show', 'state', 'style', 'takefocus', 'textvariable',
'validate', 'validatecommand', 'width', 'xscrollcommand',
)
+ _rounds_pixels = False
+ _clipped = {}
# bpo-27313: macOS Tk/Tcl may or may not report 'Entry.field'.
IDENTIFY_AS = {'Entry.field', 'textarea'}
self.assertRaises(tkinter.TclError, self.entry.bbox, None)
def test_identify(self):
+ if (tk_version >= (9, 0) and sys.platform == 'darwin'
+ and isinstance(self.entry, ttk.Combobox)):
+ self.skipTest('Test does not work on macOS Tk 9.')
+ # https://core.tcl-lang.org/tk/tktview/8b49e9cfa6
self.entry.pack()
+ self.root.update()
# Identifying the element under a point requires the widget to be
# mapped with a real size; the rest of the checks do not.
self.assertEqual(self.entry.state(), ())
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardTtkOptionsTests)
class ComboboxTest(EntryTest, unittest.TestCase):
OPTIONS = (
'background', 'class', 'cursor', 'exportselection',
x, y = width - 5, 5
if sys.platform != 'darwin': # there's no down arrow on macOS
self.assertRegex(self.combo.identify(x, y), r'.*downarrow\Z')
- self.combo.event_generate('<ButtonPress-1>', x=x, y=y)
+ self.combo.event_generate('<Button-1>', x=x, y=y)
self.combo.event_generate('<ButtonRelease-1>', x=x, y=y)
- self.combo.update_idletasks()
def test_virtual_event(self):
+ if (tk_version >= (9, 0) and sys.platform == 'darwin'
+ and isinstance(self.entry, ttk.Combobox)):
+ self.skipTest('Test does not work on macOS Tk 9.')
+ # https://core.tcl-lang.org/tk/tktview/8b49e9cfa6
success = []
self.combo['values'] = [1]
self.assertTrue(success)
def test_configure_postcommand(self):
+ if (tk_version >= (9, 0) and sys.platform == 'darwin'
+ and isinstance(self.entry, ttk.Combobox)):
+ self.skipTest('Test does not work on macOS Tk 9.')
+ # https://core.tcl-lang.org/tk/tktview/8b49e9cfa6
success = []
self.combo['postcommand'] = lambda: success.append(True)
combo2.destroy()
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardTtkOptionsTests)
class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'cursor', 'height',
'orient', 'style', 'takefocus', 'width',
)
+ _rounds_pixels = False
+ _clipped = {}
def setUp(self):
super().setUp()
self.assertIsInstance(self.paned.sashpos(0), int)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'compound', 'cursor',
self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'compound', 'cursor', 'direction',
menu.destroy()
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class ScaleTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'cursor', 'from', 'length',
'orient', 'state', 'style', 'takefocus', 'to', 'value', 'variable',
)
- _conv_pixels = False
+ _rounds_pixels = False
+ _clipped = {}
default_orient = 'horizontal'
def setUp(self):
self.assertRaises(tkinter.TclError, self.scale.set, None)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'anchor', 'class', 'cursor', 'font', 'foreground', 'justify',
'mode', 'maximum', 'phase', 'text', 'wraplength',
'style', 'takefocus', 'value', 'variable',
)
- _conv_pixels = False
+ _rounds_pixels = False
+ _clipped = {}
_allow_empty_justify = True
default_orient = 'horizontal'
@unittest.skipIf(sys.platform == 'darwin',
'ttk.Scrollbar is special on MacOSX')
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'cursor', 'orient', 'style', 'takefocus',
)
+ _rounds_pixels = False
+ _clipped = {}
default_orient = 'vertical'
def create(self, **kwargs):
return ttk.Scrollbar(self.root, **kwargs)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class NotebookTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width',
)
- if tk_version >= (8, 7):
- _conv_pixels = False
+ _rounds_pixels = (tk_version < (9,0))
+ _converts_pixels = False
+ _clipped = {}
def setUp(self):
super().setUp()
if get_tk_patchlevel(self.root) < (8, 6, 15):
self.checkIntegerParam(widget, 'height', 402, -402, 0)
else:
- self.checkPixelsParam(widget, 'height', '10c', 402, -402, 0, conv=False)
+ self.checkPixelsParam(widget, 'height', '10c', 402, -402, 0)
def test_configure_width(self):
widget = self.create()
if get_tk_patchlevel(self.root) < (8, 6, 15):
self.checkIntegerParam(widget, 'width', 402, -402, 0)
else:
- self.checkPixelsParam(widget, 'width', '10c', 402, -402, 0, conv=False)
+ self.checkPixelsParam(widget, 'width', '10c', 402, -402, 0)
def test_tab_identifiers(self):
self.nb.forget(0)
self.assertEqual(self.nb.select(), str(self.child2))
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+@add_configure_tests(IntegerSizeTests, StandardTtkOptionsTests)
class SpinboxTest(EntryTest, unittest.TestCase):
OPTIONS = (
'background', 'class', 'command', 'cursor', 'exportselection',
spin2.destroy()
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'columns', 'cursor', 'displaycolumns',
'style', 'takefocus', 'titlecolumns', 'titleitems',
'xscrollcommand', 'yscrollcommand',
)
+ _rounds_pixels = False
+ _clipped = {}
def setUp(self):
super().setUp()
def test_configure_height(self):
widget = self.create()
- self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
- self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=False)
+ self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c',
+ conv=False)
+ self.checkPixelsParam(widget, 'height', 101.2, 102.6, '3c',
+ conv=False)
def test_configure_selectmode(self):
widget = self.create()
self.assertEqual(self.tv.tag_has('tag3'), ())
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class SeparatorTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'cursor', 'orient', 'style', 'takefocus',
# 'state'?
)
+ _rounds_pixels = False
+ _clipped = {}
default_orient = 'horizontal'
def create(self, **kwargs):
return ttk.Separator(self.root, **kwargs)
-@add_standard_options(StandardTtkOptionsTests)
+@add_configure_tests(StandardTtkOptionsTests)
class SizegripTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'cursor', 'style', 'takefocus',
# 'state'?
)
+ _rounds_pixels = False
+ _clipped = {}
def create(self, **kwargs):
return ttk.Sizegrip(self.root, **kwargs)