Home | History | Annotate | Download | only in test_tkinter
      1 import unittest
      2 import Tkinter as tkinter
      3 from Tkinter import TclError
      4 import os
      5 import sys
      6 from test.test_support import requires, run_unittest
      7 
      8 from test_ttk.support import (tcl_version, requires_tcl, get_tk_patchlevel,
      9                               widget_eq)
     10 from widget_tests import (
     11     add_standard_options, noconv, noconv_meth, int_round, pixels_round,
     12     AbstractWidgetTest, StandardOptionsTests,
     13     IntegerSizeTests, PixelSizeTests,
     14     setUpModule)
     15 
     16 requires('gui')
     17 
     18 
     19 class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
     20     _conv_pad_pixels = noconv_meth
     21 
     22     def test_class(self):
     23         widget = self.create()
     24         self.assertEqual(widget['class'],
     25                          widget.__class__.__name__.title())
     26         self.checkInvalidParam(widget, 'class', 'Foo',
     27                 errmsg="can't modify -class option after widget is created")
     28         widget2 = self.create(class_='Foo')
     29         self.assertEqual(widget2['class'], 'Foo')
     30 
     31     def test_colormap(self):
     32         widget = self.create()
     33         self.assertEqual(widget['colormap'], '')
     34         self.checkInvalidParam(widget, 'colormap', 'new',
     35                 errmsg="can't modify -colormap option after widget is created")
     36         widget2 = self.create(colormap='new')
     37         self.assertEqual(widget2['colormap'], 'new')
     38 
     39     def test_container(self):
     40         widget = self.create()
     41         self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
     42         self.checkInvalidParam(widget, 'container', 1,
     43                 errmsg="can't modify -container option after widget is created")
     44         widget2 = self.create(container=True)
     45         self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
     46 
     47     def test_visual(self):
     48         widget = self.create()
     49         self.assertEqual(widget['visual'], '')
     50         self.checkInvalidParam(widget, 'visual', 'default',
     51                 errmsg="can't modify -visual option after widget is created")
     52         widget2 = self.create(visual='default')
     53         self.assertEqual(widget2['visual'], 'default')
     54 
     55 
     56 @add_standard_options(StandardOptionsTests)
     57 class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
     58     OPTIONS = (
     59         'background', 'borderwidth',
     60         'class', 'colormap', 'container', 'cursor', 'height',
     61         'highlightbackground', 'highlightcolor', 'highlightthickness',
     62         'menu', 'padx', 'pady', 'relief', 'screen',
     63         'takefocus', 'use', 'visual', 'width',
     64     )
     65 
     66     def create(self, **kwargs):
     67         return tkinter.Toplevel(self.root, **kwargs)
     68 
     69     def test_menu(self):
     70         widget = self.create()
     71         menu = tkinter.Menu(self.root)
     72         self.checkParam(widget, 'menu', menu, eq=widget_eq)
     73         self.checkParam(widget, 'menu', '')
     74 
     75     def test_screen(self):
     76         widget = self.create()
     77         self.assertEqual(widget['screen'], '')
     78         try:
     79             display = os.environ['DISPLAY']
     80         except KeyError:
     81             self.skipTest('No $DISPLAY set.')
     82         self.checkInvalidParam(widget, 'screen', display,
     83                 errmsg="can't modify -screen option after widget is created")
     84         widget2 = self.create(screen=display)
     85         self.assertEqual(widget2['screen'], display)
     86 
     87     def test_use(self):
     88         widget = self.create()
     89         self.assertEqual(widget['use'], '')
     90         parent = self.create(container=True)
     91         wid = parent.winfo_id()
     92         widget2 = self.create(use=wid)
     93         self.assertEqual(int(widget2['use']), wid)
     94 
     95 
     96 @add_standard_options(StandardOptionsTests)
     97 class FrameTest(AbstractToplevelTest, unittest.TestCase):
     98     OPTIONS = (
     99         'background', 'borderwidth',
    100         'class', 'colormap', 'container', 'cursor', 'height',
    101         'highlightbackground', 'highlightcolor', 'highlightthickness',
    102         'padx', 'pady', 'relief', 'takefocus', 'visual', 'width',
    103     )
    104 
    105     def create(self, **kwargs):
    106         return tkinter.Frame(self.root, **kwargs)
    107 
    108 
    109 @add_standard_options(StandardOptionsTests)
    110 class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
    111     OPTIONS = (
    112         'background', 'borderwidth',
    113         'class', 'colormap', 'container', 'cursor',
    114         'font', 'foreground', 'height',
    115         'highlightbackground', 'highlightcolor', 'highlightthickness',
    116         'labelanchor', 'labelwidget', 'padx', 'pady', 'relief',
    117         'takefocus', 'text', 'visual', 'width',
    118     )
    119 
    120     def create(self, **kwargs):
    121         return tkinter.LabelFrame(self.root, **kwargs)
    122 
    123     def test_labelanchor(self):
    124         widget = self.create()
    125         self.checkEnumParam(widget, 'labelanchor',
    126                             'e', 'en', 'es', 'n', 'ne', 'nw',
    127                             's', 'se', 'sw', 'w', 'wn', 'ws')
    128         self.checkInvalidParam(widget, 'labelanchor', 'center')
    129 
    130     def test_labelwidget(self):
    131         widget = self.create()
    132         label = tkinter.Label(self.root, text='Mupp', name='foo')
    133         self.checkParam(widget, 'labelwidget', label, expected='.foo')
    134         label.destroy()
    135 
    136 
    137 class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
    138     _conv_pixels = noconv_meth
    139 
    140     def test_highlightthickness(self):
    141         widget = self.create()
    142         self.checkPixelsParam(widget, 'highlightthickness',
    143                               0, 1.3, 2.6, 6, -2, '10p')
    144 
    145 
    146 @add_standard_options(StandardOptionsTests)
    147 class LabelTest(AbstractLabelTest, unittest.TestCase):
    148     OPTIONS = (
    149         'activebackground', 'activeforeground', 'anchor',
    150         'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
    151         'disabledforeground', 'font', 'foreground', 'height',
    152         'highlightbackground', 'highlightcolor', 'highlightthickness',
    153         'image', 'justify', 'padx', 'pady', 'relief', 'state',
    154         'takefocus', 'text', 'textvariable',
    155         'underline', 'width', 'wraplength',
    156     )
    157 
    158     def create(self, **kwargs):
    159         return tkinter.Label(self.root, **kwargs)
    160 
    161 
    162 @add_standard_options(StandardOptionsTests)
    163 class ButtonTest(AbstractLabelTest, unittest.TestCase):
    164     OPTIONS = (
    165         'activebackground', 'activeforeground', 'anchor',
    166         'background', 'bitmap', 'borderwidth',
    167         'command', 'compound', 'cursor', 'default',
    168         'disabledforeground', 'font', 'foreground', 'height',
    169         'highlightbackground', 'highlightcolor', 'highlightthickness',
    170         'image', 'justify', 'overrelief', 'padx', 'pady', 'relief',
    171         'repeatdelay', 'repeatinterval',
    172         'state', 'takefocus', 'text', 'textvariable',
    173         'underline', 'width', 'wraplength')
    174 
    175     def create(self, **kwargs):
    176         return tkinter.Button(self.root, **kwargs)
    177 
    178     def test_default(self):
    179         widget = self.create()
    180         self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
    181 
    182 
    183 @add_standard_options(StandardOptionsTests)
    184 class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
    185     OPTIONS = (
    186         'activebackground', 'activeforeground', 'anchor',
    187         'background', 'bitmap', 'borderwidth',
    188         'command', 'compound', 'cursor',
    189         'disabledforeground', 'font', 'foreground', 'height',
    190         'highlightbackground', 'highlightcolor', 'highlightthickness',
    191         'image', 'indicatoron', 'justify',
    192         'offrelief', 'offvalue', 'onvalue', 'overrelief',
    193         'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
    194         'takefocus', 'text', 'textvariable',
    195         'tristateimage', 'tristatevalue',
    196         'underline', 'variable', 'width', 'wraplength',
    197     )
    198 
    199     def create(self, **kwargs):
    200         return tkinter.Checkbutton(self.root, **kwargs)
    201 
    202 
    203     def test_offvalue(self):
    204         widget = self.create()
    205         self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
    206 
    207     def test_onvalue(self):
    208         widget = self.create()
    209         self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
    210 
    211 
    212 @add_standard_options(StandardOptionsTests)
    213 class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
    214     OPTIONS = (
    215         'activebackground', 'activeforeground', 'anchor',
    216         'background', 'bitmap', 'borderwidth',
    217         'command', 'compound', 'cursor',
    218         'disabledforeground', 'font', 'foreground', 'height',
    219         'highlightbackground', 'highlightcolor', 'highlightthickness',
    220         'image', 'indicatoron', 'justify', 'offrelief', 'overrelief',
    221         'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
    222         'takefocus', 'text', 'textvariable',
    223         'tristateimage', 'tristatevalue',
    224         'underline', 'value', 'variable', 'width', 'wraplength',
    225     )
    226 
    227     def create(self, **kwargs):
    228         return tkinter.Radiobutton(self.root, **kwargs)
    229 
    230     def test_value(self):
    231         widget = self.create()
    232         self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
    233 
    234 
    235 @add_standard_options(StandardOptionsTests)
    236 class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
    237     OPTIONS = (
    238         'activebackground', 'activeforeground', 'anchor',
    239         'background', 'bitmap', 'borderwidth',
    240         'compound', 'cursor', 'direction',
    241         'disabledforeground', 'font', 'foreground', 'height',
    242         'highlightbackground', 'highlightcolor', 'highlightthickness',
    243         'image', 'indicatoron', 'justify', 'menu',
    244         'padx', 'pady', 'relief', 'state',
    245         'takefocus', 'text', 'textvariable',
    246         'underline', 'width', 'wraplength',
    247     )
    248     _conv_pixels = staticmethod(pixels_round)
    249 
    250     def create(self, **kwargs):
    251         return tkinter.Menubutton(self.root, **kwargs)
    252 
    253     def test_direction(self):
    254         widget = self.create()
    255         self.checkEnumParam(widget, 'direction',
    256                 'above', 'below', 'flush', 'left', 'right')
    257 
    258     def test_height(self):
    259         widget = self.create()
    260         self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
    261 
    262     test_highlightthickness = StandardOptionsTests.test_highlightthickness.im_func
    263 
    264     @unittest.skipIf(sys.platform == 'darwin',
    265                      'crashes with Cocoa Tk (issue19733)')
    266     def test_image(self):
    267         widget = self.create()
    268         image = tkinter.PhotoImage(master=self.root, name='image1')
    269         self.checkParam(widget, 'image', image, conv=str)
    270         errmsg = 'image "spam" doesn\'t exist'
    271         with self.assertRaises(tkinter.TclError) as cm:
    272             widget['image'] = 'spam'
    273         if errmsg is not None:
    274             self.assertEqual(str(cm.exception), errmsg)
    275         with self.assertRaises(tkinter.TclError) as cm:
    276             widget.configure({'image': 'spam'})
    277         if errmsg is not None:
    278             self.assertEqual(str(cm.exception), errmsg)
    279 
    280     def test_menu(self):
    281         widget = self.create()
    282         menu = tkinter.Menu(widget, name='menu')
    283         self.checkParam(widget, 'menu', menu, eq=widget_eq)
    284         menu.destroy()
    285 
    286     def test_padx(self):
    287         widget = self.create()
    288         self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
    289         self.checkParam(widget, 'padx', -2, expected=0)
    290 
    291     def test_pady(self):
    292         widget = self.create()
    293         self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
    294         self.checkParam(widget, 'pady', -2, expected=0)
    295 
    296     def test_width(self):
    297         widget = self.create()
    298         self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
    299 
    300 
    301 class OptionMenuTest(MenubuttonTest, unittest.TestCase):
    302 
    303     def create(self, default='b', values=('a', 'b', 'c'), **kwargs):
    304         return tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
    305 
    306 
    307 @add_standard_options(IntegerSizeTests, StandardOptionsTests)
    308 class EntryTest(AbstractWidgetTest, unittest.TestCase):
    309     OPTIONS = (
    310         'background', 'borderwidth', 'cursor',
    311         'disabledbackground', 'disabledforeground',
    312         'exportselection', 'font', 'foreground',
    313         'highlightbackground', 'highlightcolor', 'highlightthickness',
    314         'insertbackground', 'insertborderwidth',
    315         'insertofftime', 'insertontime', 'insertwidth',
    316         'invalidcommand', 'justify', 'readonlybackground', 'relief',
    317         'selectbackground', 'selectborderwidth', 'selectforeground',
    318         'show', 'state', 'takefocus', 'textvariable',
    319         'validate', 'validatecommand', 'width', 'xscrollcommand',
    320     )
    321 
    322     def create(self, **kwargs):
    323         return tkinter.Entry(self.root, **kwargs)
    324 
    325     def test_disabledbackground(self):
    326         widget = self.create()
    327         self.checkColorParam(widget, 'disabledbackground')
    328 
    329     def test_insertborderwidth(self):
    330         widget = self.create(insertwidth=100)
    331         self.checkPixelsParam(widget, 'insertborderwidth',
    332                               0, 1.3, 2.6, 6, -2, '10p')
    333         # insertborderwidth is bounded above by a half of insertwidth.
    334         self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
    335 
    336     def test_insertwidth(self):
    337         widget = self.create()
    338         self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
    339         self.checkParam(widget, 'insertwidth', 0.1, expected=2)
    340         self.checkParam(widget, 'insertwidth', -2, expected=2)
    341         if pixels_round(0.9) <= 0:
    342             self.checkParam(widget, 'insertwidth', 0.9, expected=2)
    343         else:
    344             self.checkParam(widget, 'insertwidth', 0.9, expected=1)
    345 
    346     def test_invalidcommand(self):
    347         widget = self.create()
    348         self.checkCommandParam(widget, 'invalidcommand')
    349         self.checkCommandParam(widget, 'invcmd')
    350 
    351     def test_readonlybackground(self):
    352         widget = self.create()
    353         self.checkColorParam(widget, 'readonlybackground')
    354 
    355     def test_show(self):
    356         widget = self.create()
    357         self.checkParam(widget, 'show', '*')
    358         self.checkParam(widget, 'show', '')
    359         self.checkParam(widget, 'show', ' ')
    360 
    361     def test_state(self):
    362         widget = self.create()
    363         self.checkEnumParam(widget, 'state',
    364                             'disabled', 'normal', 'readonly')
    365 
    366     def test_validate(self):
    367         widget = self.create()
    368         self.checkEnumParam(widget, 'validate',
    369                 'all', 'key', 'focus', 'focusin', 'focusout', 'none')
    370 
    371     def test_validatecommand(self):
    372         widget = self.create()
    373         self.checkCommandParam(widget, 'validatecommand')
    374         self.checkCommandParam(widget, 'vcmd')
    375 
    376 
    377 @add_standard_options(StandardOptionsTests)
    378 class SpinboxTest(EntryTest, unittest.TestCase):
    379     OPTIONS = (
    380         'activebackground', 'background', 'borderwidth',
    381         'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',
    382         'command', 'cursor', 'disabledbackground', 'disabledforeground',
    383         'exportselection', 'font', 'foreground', 'format', 'from',
    384         'highlightbackground', 'highlightcolor', 'highlightthickness',
    385         'increment',
    386         'insertbackground', 'insertborderwidth',
    387         'insertofftime', 'insertontime', 'insertwidth',
    388         'invalidcommand', 'justify', 'relief', 'readonlybackground',
    389         'repeatdelay', 'repeatinterval',
    390         'selectbackground', 'selectborderwidth', 'selectforeground',
    391         'state', 'takefocus', 'textvariable', 'to',
    392         'validate', 'validatecommand', 'values',
    393         'width', 'wrap', 'xscrollcommand',
    394     )
    395 
    396     def create(self, **kwargs):
    397         return tkinter.Spinbox(self.root, **kwargs)
    398 
    399     test_show = None
    400 
    401     def test_buttonbackground(self):
    402         widget = self.create()
    403         self.checkColorParam(widget, 'buttonbackground')
    404 
    405     def test_buttoncursor(self):
    406         widget = self.create()
    407         self.checkCursorParam(widget, 'buttoncursor')
    408 
    409     def test_buttondownrelief(self):
    410         widget = self.create()
    411         self.checkReliefParam(widget, 'buttondownrelief')
    412 
    413     def test_buttonuprelief(self):
    414         widget = self.create()
    415         self.checkReliefParam(widget, 'buttonuprelief')
    416 
    417     def test_format(self):
    418         widget = self.create()
    419         self.checkParam(widget, 'format', '%2f')
    420         self.checkParam(widget, 'format', '%2.2f')
    421         self.checkParam(widget, 'format', '%.2f')
    422         self.checkParam(widget, 'format', '%2.f')
    423         self.checkInvalidParam(widget, 'format', '%2e-1f')
    424         self.checkInvalidParam(widget, 'format', '2.2')
    425         self.checkInvalidParam(widget, 'format', '%2.-2f')
    426         self.checkParam(widget, 'format', '%-2.02f')
    427         self.checkParam(widget, 'format', '% 2.02f')
    428         self.checkParam(widget, 'format', '% -2.200f')
    429         self.checkParam(widget, 'format', '%09.200f')
    430         self.checkInvalidParam(widget, 'format', '%d')
    431 
    432     def test_from(self):
    433         widget = self.create()
    434         self.checkParam(widget, 'to', 100.0)
    435         self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
    436         self.checkInvalidParam(widget, 'from', 200,
    437                 errmsg='-to value must be greater than -from value')
    438 
    439     def test_increment(self):
    440         widget = self.create()
    441         self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
    442 
    443     def test_to(self):
    444         widget = self.create()
    445         self.checkParam(widget, 'from', -100.0)
    446         self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
    447         self.checkInvalidParam(widget, 'to', -200,
    448                 errmsg='-to value must be greater than -from value')
    449 
    450     def test_values(self):
    451         # XXX
    452         widget = self.create()
    453         self.assertEqual(widget['values'], '')
    454         self.checkParam(widget, 'values', 'mon tue wed thur')
    455         self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),
    456                         expected='mon tue wed thur')
    457         self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),
    458                         expected='42 3.14 {} {any string}')
    459         self.checkParam(widget, 'values', '')
    460 
    461     def test_wrap(self):
    462         widget = self.create()
    463         self.checkBooleanParam(widget, 'wrap')
    464 
    465     def test_bbox(self):
    466         widget = self.create()
    467         self.assertIsBoundingBox(widget.bbox(0))
    468         self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')
    469         self.assertRaises(tkinter.TclError, widget.bbox, None)
    470         self.assertRaises(TypeError, widget.bbox)
    471         self.assertRaises(TypeError, widget.bbox, 0, 1)
    472 
    473 
    474 @add_standard_options(StandardOptionsTests)
    475 class TextTest(AbstractWidgetTest, unittest.TestCase):
    476     OPTIONS = (
    477         'autoseparators', 'background', 'blockcursor', 'borderwidth',
    478         'cursor', 'endline', 'exportselection',
    479         'font', 'foreground', 'height',
    480         'highlightbackground', 'highlightcolor', 'highlightthickness',
    481         'inactiveselectbackground', 'insertbackground', 'insertborderwidth',
    482         'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth',
    483         'maxundo', 'padx', 'pady', 'relief',
    484         'selectbackground', 'selectborderwidth', 'selectforeground',
    485         'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state',
    486         'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',
    487         'xscrollcommand', 'yscrollcommand',
    488     )
    489     if tcl_version < (8, 5):
    490         _stringify = True
    491 
    492     def create(self, **kwargs):
    493         return tkinter.Text(self.root, **kwargs)
    494 
    495     def test_autoseparators(self):
    496         widget = self.create()
    497         self.checkBooleanParam(widget, 'autoseparators')
    498 
    499     @requires_tcl(8, 5)
    500     def test_blockcursor(self):
    501         widget = self.create()
    502         self.checkBooleanParam(widget, 'blockcursor')
    503 
    504     @requires_tcl(8, 5)
    505     def test_endline(self):
    506         widget = self.create()
    507         text = '\n'.join('Line %d' for i in range(100))
    508         widget.insert('end', text)
    509         self.checkParam(widget, 'endline', 200, expected='')
    510         self.checkParam(widget, 'endline', -10, expected='')
    511         self.checkInvalidParam(widget, 'endline', 'spam',
    512                 errmsg='expected integer but got "spam"')
    513         self.checkParam(widget, 'endline', 50)
    514         self.checkParam(widget, 'startline', 15)
    515         self.checkInvalidParam(widget, 'endline', 10,
    516                 errmsg='-startline must be less than or equal to -endline')
    517 
    518     def test_height(self):
    519         widget = self.create()
    520         self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
    521         self.checkParam(widget, 'height', -100, expected=1)
    522         self.checkParam(widget, 'height', 0, expected=1)
    523 
    524     def test_maxundo(self):
    525         widget = self.create()
    526         self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
    527 
    528     @requires_tcl(8, 5)
    529     def test_inactiveselectbackground(self):
    530         widget = self.create()
    531         self.checkColorParam(widget, 'inactiveselectbackground')
    532 
    533     @requires_tcl(8, 6)
    534     def test_insertunfocussed(self):
    535         widget = self.create()
    536         self.checkEnumParam(widget, 'insertunfocussed',
    537                             'hollow', 'none', 'solid')
    538 
    539     def test_selectborderwidth(self):
    540         widget = self.create()
    541         self.checkPixelsParam(widget, 'selectborderwidth',
    542                               1.3, 2.6, -2, '10p', conv=noconv,
    543                               keep_orig=tcl_version >= (8, 5))
    544 
    545     def test_spacing1(self):
    546         widget = self.create()
    547         self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
    548         self.checkParam(widget, 'spacing1', -5, expected=0)
    549 
    550     def test_spacing2(self):
    551         widget = self.create()
    552         self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
    553         self.checkParam(widget, 'spacing2', -1, expected=0)
    554 
    555     def test_spacing3(self):
    556         widget = self.create()
    557         self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
    558         self.checkParam(widget, 'spacing3', -10, expected=0)
    559 
    560     @requires_tcl(8, 5)
    561     def test_startline(self):
    562         widget = self.create()
    563         text = '\n'.join('Line %d' for i in range(100))
    564         widget.insert('end', text)
    565         self.checkParam(widget, 'startline', 200, expected='')
    566         self.checkParam(widget, 'startline', -10, expected='')
    567         self.checkInvalidParam(widget, 'startline', 'spam',
    568                 errmsg='expected integer but got "spam"')
    569         self.checkParam(widget, 'startline', 10)
    570         self.checkParam(widget, 'endline', 50)
    571         self.checkInvalidParam(widget, 'startline', 70,
    572                 errmsg='-startline must be less than or equal to -endline')
    573 
    574     def test_state(self):
    575         widget = self.create()
    576         if tcl_version < (8, 5):
    577             self.checkParams(widget, 'state', 'disabled', 'normal')
    578         else:
    579             self.checkEnumParam(widget, 'state', 'disabled', 'normal')
    580 
    581     def test_tabs(self):
    582         widget = self.create()
    583         if get_tk_patchlevel() < (8, 5, 11):
    584             self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'),
    585                             expected=('10.2', '20.7', '1i', '2i'))
    586         else:
    587             self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'))
    588         self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i',
    589                         expected=('10.2', '20.7', '1i', '2i'))
    590         self.checkParam(widget, 'tabs', '2c left 4c 6c center',
    591                         expected=('2c', 'left', '4c', '6c', 'center'))
    592         self.checkInvalidParam(widget, 'tabs', 'spam',
    593                                errmsg='bad screen distance "spam"',
    594                                keep_orig=tcl_version >= (8, 5))
    595 
    596     @requires_tcl(8, 5)
    597     def test_tabstyle(self):
    598         widget = self.create()
    599         self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
    600 
    601     def test_undo(self):
    602         widget = self.create()
    603         self.checkBooleanParam(widget, 'undo')
    604 
    605     def test_width(self):
    606         widget = self.create()
    607         self.checkIntegerParam(widget, 'width', 402)
    608         self.checkParam(widget, 'width', -402, expected=1)
    609         self.checkParam(widget, 'width', 0, expected=1)
    610 
    611     def test_wrap(self):
    612         widget = self.create()
    613         if tcl_version < (8, 5):
    614             self.checkParams(widget, 'wrap', 'char', 'none', 'word')
    615         else:
    616             self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word')
    617 
    618     def test_bbox(self):
    619         widget = self.create()
    620         self.assertIsBoundingBox(widget.bbox('1.1'))
    621         self.assertIsNone(widget.bbox('end'))
    622         self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')
    623         self.assertRaises(tkinter.TclError, widget.bbox, None)
    624         self.assertRaises(tkinter.TclError, widget.bbox)
    625         self.assertRaises(tkinter.TclError, widget.bbox, '1.1', 'end')
    626 
    627 
    628 @add_standard_options(PixelSizeTests, StandardOptionsTests)
    629 class CanvasTest(AbstractWidgetTest, unittest.TestCase):
    630     OPTIONS = (
    631         'background', 'borderwidth',
    632         'closeenough', 'confine', 'cursor', 'height',
    633         'highlightbackground', 'highlightcolor', 'highlightthickness',
    634         'insertbackground', 'insertborderwidth',
    635         'insertofftime', 'insertontime', 'insertwidth',
    636         'offset', 'relief', 'scrollregion',
    637         'selectbackground', 'selectborderwidth', 'selectforeground',
    638         'state', 'takefocus',
    639         'xscrollcommand', 'xscrollincrement',
    640         'yscrollcommand', 'yscrollincrement', 'width',
    641     )
    642 
    643     _conv_pixels = staticmethod(int_round)
    644     _stringify = True
    645 
    646     def create(self, **kwargs):
    647         return tkinter.Canvas(self.root, **kwargs)
    648 
    649     def test_closeenough(self):
    650         widget = self.create()
    651         self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
    652                              conv=float)
    653 
    654     def test_confine(self):
    655         widget = self.create()
    656         self.checkBooleanParam(widget, 'confine')
    657 
    658     def test_offset(self):
    659         widget = self.create()
    660         self.assertEqual(widget['offset'], '0,0')
    661         self.checkParams(widget, 'offset',
    662                 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
    663         self.checkParam(widget, 'offset', '10,20')
    664         self.checkParam(widget, 'offset', '#5,6')
    665         self.checkInvalidParam(widget, 'offset', 'spam')
    666 
    667     def test_scrollregion(self):
    668         widget = self.create()
    669         self.checkParam(widget, 'scrollregion', '0 0 200 150')
    670         self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
    671                         expected='0 0 200 150')
    672         self.checkParam(widget, 'scrollregion', '')
    673         self.checkInvalidParam(widget, 'scrollregion', 'spam',
    674                                errmsg='bad scrollRegion "spam"')
    675         self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam'))
    676         self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
    677         self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
    678 
    679     def test_state(self):
    680         widget = self.create()
    681         self.checkEnumParam(widget, 'state', 'disabled', 'normal',
    682                 errmsg='bad state value "{}": must be normal or disabled')
    683 
    684     def test_xscrollincrement(self):
    685         widget = self.create()
    686         self.checkPixelsParam(widget, 'xscrollincrement',
    687                               40, 0, 41.2, 43.6, -40, '0.5i')
    688 
    689     def test_yscrollincrement(self):
    690         widget = self.create()
    691         self.checkPixelsParam(widget, 'yscrollincrement',
    692                               10, 0, 11.2, 13.6, -10, '0.1i')
    693 
    694 
    695 @add_standard_options(IntegerSizeTests, StandardOptionsTests)
    696 class ListboxTest(AbstractWidgetTest, unittest.TestCase):
    697     OPTIONS = (
    698         'activestyle', 'background', 'borderwidth', 'cursor',
    699         'disabledforeground', 'exportselection',
    700         'font', 'foreground', 'height',
    701         'highlightbackground', 'highlightcolor', 'highlightthickness',
    702         'listvariable', 'relief',
    703         'selectbackground', 'selectborderwidth', 'selectforeground',
    704         'selectmode', 'setgrid', 'state',
    705         'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
    706     )
    707 
    708     def create(self, **kwargs):
    709         return tkinter.Listbox(self.root, **kwargs)
    710 
    711     def test_activestyle(self):
    712         widget = self.create()
    713         self.checkEnumParam(widget, 'activestyle',
    714                             'dotbox', 'none', 'underline')
    715 
    716     def test_listvariable(self):
    717         widget = self.create()
    718         var = tkinter.DoubleVar(self.root)
    719         self.checkVariableParam(widget, 'listvariable', var)
    720 
    721     def test_selectmode(self):
    722         widget = self.create()
    723         self.checkParam(widget, 'selectmode', 'single')
    724         self.checkParam(widget, 'selectmode', 'browse')
    725         self.checkParam(widget, 'selectmode', 'multiple')
    726         self.checkParam(widget, 'selectmode', 'extended')
    727 
    728     def test_state(self):
    729         widget = self.create()
    730         self.checkEnumParam(widget, 'state', 'disabled', 'normal')
    731 
    732     def test_itemconfigure(self):
    733         widget = self.create()
    734         with self.assertRaisesRegexp(TclError, 'item number "0" out of range'):
    735             widget.itemconfigure(0)
    736         colors = 'red orange yellow green blue white violet'.split()
    737         widget.insert('end', *colors)
    738         for i, color in enumerate(colors):
    739             widget.itemconfigure(i, background=color)
    740         with self.assertRaises(TypeError):
    741             widget.itemconfigure()
    742         with self.assertRaisesRegexp(TclError, 'bad listbox index "red"'):
    743             widget.itemconfigure('red')
    744         self.assertEqual(widget.itemconfigure(0, 'background'),
    745                          ('background', 'background', 'Background', '', 'red'))
    746         self.assertEqual(widget.itemconfigure('end', 'background'),
    747                          ('background', 'background', 'Background', '', 'violet'))
    748         self.assertEqual(widget.itemconfigure('@0,0', 'background'),
    749                          ('background', 'background', 'Background', '', 'red'))
    750 
    751         d = widget.itemconfigure(0)
    752         self.assertIsInstance(d, dict)
    753         for k, v in d.items():
    754             self.assertIn(len(v), (2, 5))
    755             if len(v) == 5:
    756                 self.assertEqual(v, widget.itemconfigure(0, k))
    757                 self.assertEqual(v[4], widget.itemcget(0, k))
    758 
    759     def check_itemconfigure(self, name, value):
    760         widget = self.create()
    761         widget.insert('end', 'a', 'b', 'c', 'd')
    762         widget.itemconfigure(0, **{name: value})
    763         self.assertEqual(widget.itemconfigure(0, name)[4], value)
    764         self.assertEqual(widget.itemcget(0, name), value)
    765         with self.assertRaisesRegexp(TclError, 'unknown color name "spam"'):
    766             widget.itemconfigure(0, **{name: 'spam'})
    767 
    768     def test_itemconfigure_background(self):
    769         self.check_itemconfigure('background', '#ff0000')
    770 
    771     def test_itemconfigure_bg(self):
    772         self.check_itemconfigure('bg', '#ff0000')
    773 
    774     def test_itemconfigure_fg(self):
    775         self.check_itemconfigure('fg', '#110022')
    776 
    777     def test_itemconfigure_foreground(self):
    778         self.check_itemconfigure('foreground', '#110022')
    779 
    780     def test_itemconfigure_selectbackground(self):
    781         self.check_itemconfigure('selectbackground', '#110022')
    782 
    783     def test_itemconfigure_selectforeground(self):
    784         self.check_itemconfigure('selectforeground', '#654321')
    785 
    786     def test_box(self):
    787         lb = self.create()
    788         lb.insert(0, *('el%d' % i for i in range(8)))
    789         lb.pack()
    790         self.assertIsBoundingBox(lb.bbox(0))
    791         self.assertIsNone(lb.bbox(-1))
    792         self.assertIsNone(lb.bbox(10))
    793         self.assertRaises(TclError, lb.bbox, 'noindex')
    794         self.assertRaises(TclError, lb.bbox, None)
    795         self.assertRaises(TypeError, lb.bbox)
    796         self.assertRaises(TypeError, lb.bbox, 0, 1)
    797 
    798     def test_curselection(self):
    799         lb = self.create()
    800         lb.insert(0, *('el%d' % i for i in range(8)))
    801         lb.selection_clear(0, tkinter.END)
    802         lb.selection_set(2, 4)
    803         lb.selection_set(6)
    804         self.assertEqual(lb.curselection(), (2, 3, 4, 6))
    805         self.assertRaises(TypeError, lb.curselection, 0)
    806 
    807     def test_get(self):
    808         lb = self.create()
    809         lb.insert(0, *('el%d' % i for i in range(8)))
    810         self.assertEqual(lb.get(0), 'el0')
    811         self.assertEqual(lb.get(3), 'el3')
    812         self.assertEqual(lb.get('end'), 'el7')
    813         self.assertEqual(lb.get(8), '')
    814         self.assertEqual(lb.get(-1), '')
    815         self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5'))
    816         self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7'))
    817         self.assertEqual(lb.get(5, 0), ())
    818         self.assertEqual(lb.get(0, 0), ('el0',))
    819         self.assertRaises(TclError, lb.get, 'noindex')
    820         self.assertRaises(TclError, lb.get, None)
    821         self.assertRaises(TypeError, lb.get)
    822         self.assertRaises(TclError, lb.get, 'end', 'noindex')
    823         self.assertRaises(TypeError, lb.get, 1, 2, 3)
    824         self.assertRaises(TclError, lb.get, 2.4)
    825 
    826 
    827 @add_standard_options(PixelSizeTests, StandardOptionsTests)
    828 class ScaleTest(AbstractWidgetTest, unittest.TestCase):
    829     OPTIONS = (
    830         'activebackground', 'background', 'bigincrement', 'borderwidth',
    831         'command', 'cursor', 'digits', 'font', 'foreground', 'from',
    832         'highlightbackground', 'highlightcolor', 'highlightthickness',
    833         'label', 'length', 'orient', 'relief',
    834         'repeatdelay', 'repeatinterval',
    835         'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',
    836         'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',
    837     )
    838     default_orient = 'vertical'
    839 
    840     def create(self, **kwargs):
    841         return tkinter.Scale(self.root, **kwargs)
    842 
    843     def test_bigincrement(self):
    844         widget = self.create()
    845         self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
    846 
    847     def test_digits(self):
    848         widget = self.create()
    849         self.checkIntegerParam(widget, 'digits', 5, 0)
    850 
    851     def test_from(self):
    852         widget = self.create()
    853         self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=round)
    854 
    855     def test_label(self):
    856         widget = self.create()
    857         self.checkParam(widget, 'label', 'any string')
    858         self.checkParam(widget, 'label', '')
    859 
    860     def test_length(self):
    861         widget = self.create()
    862         self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
    863 
    864     def test_resolution(self):
    865         widget = self.create()
    866         self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
    867 
    868     def test_showvalue(self):
    869         widget = self.create()
    870         self.checkBooleanParam(widget, 'showvalue')
    871 
    872     def test_sliderlength(self):
    873         widget = self.create()
    874         self.checkPixelsParam(widget, 'sliderlength',
    875                               10, 11.2, 15.6, -3, '3m')
    876 
    877     def test_sliderrelief(self):
    878         widget = self.create()
    879         self.checkReliefParam(widget, 'sliderrelief')
    880 
    881     def test_tickinterval(self):
    882         widget = self.create()
    883         self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
    884                              conv=round)
    885         self.checkParam(widget, 'tickinterval', -2, expected=2,
    886                         conv=round)
    887 
    888     def test_to(self):
    889         widget = self.create()
    890         self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
    891                              conv=round)
    892 
    893 
    894 @add_standard_options(PixelSizeTests, StandardOptionsTests)
    895 class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
    896     OPTIONS = (
    897         'activebackground', 'activerelief',
    898         'background', 'borderwidth',
    899         'command', 'cursor', 'elementborderwidth',
    900         'highlightbackground', 'highlightcolor', 'highlightthickness',
    901         'jump', 'orient', 'relief',
    902         'repeatdelay', 'repeatinterval',
    903         'takefocus', 'troughcolor', 'width',
    904     )
    905     _conv_pixels = staticmethod(int_round)
    906     _stringify = True
    907     default_orient = 'vertical'
    908 
    909     def create(self, **kwargs):
    910         return tkinter.Scrollbar(self.root, **kwargs)
    911 
    912     def test_activerelief(self):
    913         widget = self.create()
    914         self.checkReliefParam(widget, 'activerelief')
    915 
    916     def test_elementborderwidth(self):
    917         widget = self.create()
    918         self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
    919 
    920     def test_orient(self):
    921         widget = self.create()
    922         self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
    923                 errmsg='bad orientation "{}": must be vertical or horizontal')
    924 
    925     def test_activate(self):
    926         sb = self.create()
    927         for e in ('arrow1', 'slider', 'arrow2'):
    928             sb.activate(e)
    929         sb.activate('')
    930         self.assertRaises(TypeError, sb.activate)
    931         self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2')
    932 
    933     def test_set(self):
    934         sb = self.create()
    935         sb.set(0.2, 0.4)
    936         self.assertEqual(sb.get(), (0.2, 0.4))
    937         self.assertRaises(TclError, sb.set, 'abc', 'def')
    938         self.assertRaises(TclError, sb.set, 0.6, 'def')
    939         self.assertRaises(TclError, sb.set, 0.6, None)
    940         self.assertRaises(TclError, sb.set, 0.6)
    941         self.assertRaises(TclError, sb.set, 0.6, 0.7, 0.8)
    942 
    943 
    944 @add_standard_options(StandardOptionsTests)
    945 class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
    946     OPTIONS = (
    947         'background', 'borderwidth', 'cursor',
    948         'handlepad', 'handlesize', 'height',
    949         'opaqueresize', 'orient', 'relief',
    950         'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',
    951         'showhandle', 'width',
    952     )
    953     default_orient = 'horizontal'
    954 
    955     def create(self, **kwargs):
    956         return tkinter.PanedWindow(self.root, **kwargs)
    957 
    958     def test_handlepad(self):
    959         widget = self.create()
    960         self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
    961 
    962     def test_handlesize(self):
    963         widget = self.create()
    964         self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
    965                               conv=noconv)
    966 
    967     def test_height(self):
    968         widget = self.create()
    969         self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
    970                               conv=noconv)
    971 
    972     def test_opaqueresize(self):
    973         widget = self.create()
    974         self.checkBooleanParam(widget, 'opaqueresize')
    975 
    976     def test_sashcursor(self):
    977         widget = self.create()
    978         self.checkCursorParam(widget, 'sashcursor')
    979 
    980     def test_sashpad(self):
    981         widget = self.create()
    982         self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
    983 
    984     def test_sashrelief(self):
    985         widget = self.create()
    986         self.checkReliefParam(widget, 'sashrelief')
    987 
    988     def test_sashwidth(self):
    989         widget = self.create()
    990         self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
    991                               conv=noconv)
    992 
    993     def test_showhandle(self):
    994         widget = self.create()
    995         self.checkBooleanParam(widget, 'showhandle')
    996 
    997     def test_width(self):
    998         widget = self.create()
    999         self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
   1000                               conv=noconv)
   1001 
   1002     def create2(self):
   1003         p = self.create()
   1004         b = tkinter.Button(p)
   1005         c = tkinter.Button(p)
   1006         p.add(b)
   1007         p.add(c)
   1008         return p, b, c
   1009 
   1010     def test_paneconfigure(self):
   1011         p, b, c = self.create2()
   1012         self.assertRaises(TypeError, p.paneconfigure)
   1013         d = p.paneconfigure(b)
   1014         self.assertIsInstance(d, dict)
   1015         for k, v in d.items():
   1016             self.assertEqual(len(v), 5)
   1017             self.assertEqual(v, p.paneconfigure(b, k))
   1018             self.assertEqual(v[4], p.panecget(b, k))
   1019 
   1020     def check_paneconfigure(self, p, b, name, value, expected, stringify=False):
   1021         conv = lambda x: x
   1022         if not self.wantobjects or stringify:
   1023             expected = str(expected)
   1024         if self.wantobjects and stringify:
   1025             conv = str
   1026         p.paneconfigure(b, **{name: value})
   1027         self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected)
   1028         self.assertEqual(conv(p.panecget(b, name)), expected)
   1029 
   1030     def check_paneconfigure_bad(self, p, b, name, msg):
   1031         with self.assertRaisesRegexp(TclError, msg):
   1032             p.paneconfigure(b, **{name: 'badValue'})
   1033 
   1034     def test_paneconfigure_after(self):
   1035         p, b, c = self.create2()
   1036         self.check_paneconfigure(p, b, 'after', c, str(c))
   1037         self.check_paneconfigure_bad(p, b, 'after',
   1038                                      'bad window path name "badValue"')
   1039 
   1040     def test_paneconfigure_before(self):
   1041         p, b, c = self.create2()
   1042         self.check_paneconfigure(p, b, 'before', c, str(c))
   1043         self.check_paneconfigure_bad(p, b, 'before',
   1044                                      'bad window path name "badValue"')
   1045 
   1046     def test_paneconfigure_height(self):
   1047         p, b, c = self.create2()
   1048         self.check_paneconfigure(p, b, 'height', 10, 10,
   1049                                  stringify=get_tk_patchlevel() < (8, 5, 11))
   1050         self.check_paneconfigure_bad(p, b, 'height',
   1051                                      'bad screen distance "badValue"')
   1052 
   1053     @requires_tcl(8, 5)
   1054     def test_paneconfigure_hide(self):
   1055         p, b, c = self.create2()
   1056         self.check_paneconfigure(p, b, 'hide', False, 0)
   1057         self.check_paneconfigure_bad(p, b, 'hide',
   1058                                      'expected boolean value but got "badValue"')
   1059 
   1060     def test_paneconfigure_minsize(self):
   1061         p, b, c = self.create2()
   1062         self.check_paneconfigure(p, b, 'minsize', 10, 10)
   1063         self.check_paneconfigure_bad(p, b, 'minsize',
   1064                                      'bad screen distance "badValue"')
   1065 
   1066     def test_paneconfigure_padx(self):
   1067         p, b, c = self.create2()
   1068         self.check_paneconfigure(p, b, 'padx', 1.3, 1)
   1069         self.check_paneconfigure_bad(p, b, 'padx',
   1070                                      'bad screen distance "badValue"')
   1071 
   1072     def test_paneconfigure_pady(self):
   1073         p, b, c = self.create2()
   1074         self.check_paneconfigure(p, b, 'pady', 1.3, 1)
   1075         self.check_paneconfigure_bad(p, b, 'pady',
   1076                                      'bad screen distance "badValue"')
   1077 
   1078     def test_paneconfigure_sticky(self):
   1079         p, b, c = self.create2()
   1080         self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw')
   1081         self.check_paneconfigure_bad(p, b, 'sticky',
   1082                                      'bad stickyness value "badValue": must '
   1083                                      'be a string containing zero or more of '
   1084                                      'n, e, s, and w')
   1085 
   1086     @requires_tcl(8, 5)
   1087     def test_paneconfigure_stretch(self):
   1088         p, b, c = self.create2()
   1089         self.check_paneconfigure(p, b, 'stretch', 'alw', 'always')
   1090         self.check_paneconfigure_bad(p, b, 'stretch',
   1091                                      'bad stretch "badValue": must be '
   1092                                      'always, first, last, middle, or never')
   1093 
   1094     def test_paneconfigure_width(self):
   1095         p, b, c = self.create2()
   1096         self.check_paneconfigure(p, b, 'width', 10, 10,
   1097                                  stringify=get_tk_patchlevel() < (8, 5, 11))
   1098         self.check_paneconfigure_bad(p, b, 'width',
   1099                                      'bad screen distance "badValue"')
   1100 
   1101 
   1102 @add_standard_options(StandardOptionsTests)
   1103 class MenuTest(AbstractWidgetTest, unittest.TestCase):
   1104     OPTIONS = (
   1105         'activebackground', 'activeborderwidth', 'activeforeground',
   1106         'background', 'borderwidth', 'cursor',
   1107         'disabledforeground', 'font', 'foreground',
   1108         'postcommand', 'relief', 'selectcolor', 'takefocus',
   1109         'tearoff', 'tearoffcommand', 'title', 'type',
   1110     )
   1111     _conv_pixels = noconv_meth
   1112 
   1113     def create(self, **kwargs):
   1114         return tkinter.Menu(self.root, **kwargs)
   1115 
   1116     def test_postcommand(self):
   1117         widget = self.create()
   1118         self.checkCommandParam(widget, 'postcommand')
   1119 
   1120     def test_tearoff(self):
   1121         widget = self.create()
   1122         self.checkBooleanParam(widget, 'tearoff')
   1123 
   1124     def test_tearoffcommand(self):
   1125         widget = self.create()
   1126         self.checkCommandParam(widget, 'tearoffcommand')
   1127 
   1128     def test_title(self):
   1129         widget = self.create()
   1130         self.checkParam(widget, 'title', 'any string')
   1131 
   1132     def test_type(self):
   1133         widget = self.create()
   1134         self.checkEnumParam(widget, 'type',
   1135                 'normal', 'tearoff', 'menubar')
   1136 
   1137     def test_entryconfigure(self):
   1138         m1 = self.create()
   1139         m1.add_command(label='test')
   1140         self.assertRaises(TypeError, m1.entryconfigure)
   1141         with self.assertRaisesRegexp(TclError, 'bad menu entry index "foo"'):
   1142             m1.entryconfigure('foo')
   1143         d = m1.entryconfigure(1)
   1144         self.assertIsInstance(d, dict)
   1145         for k, v in d.items():
   1146             self.assertIsInstance(k, str)
   1147             self.assertIsInstance(v, tuple)
   1148             self.assertEqual(len(v), 5)
   1149             self.assertEqual(v[0], k)
   1150             self.assertEqual(m1.entrycget(1, k), v[4])
   1151         m1.destroy()
   1152 
   1153     def test_entryconfigure_label(self):
   1154         m1 = self.create()
   1155         m1.add_command(label='test')
   1156         self.assertEqual(m1.entrycget(1, 'label'), 'test')
   1157         m1.entryconfigure(1, label='changed')
   1158         self.assertEqual(m1.entrycget(1, 'label'), 'changed')
   1159 
   1160     def test_entryconfigure_variable(self):
   1161         m1 = self.create()
   1162         v1 = tkinter.BooleanVar(self.root)
   1163         v2 = tkinter.BooleanVar(self.root)
   1164         m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False,
   1165                            label='Nonsense')
   1166         self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1))
   1167         m1.entryconfigure(1, variable=v2)
   1168         self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2))
   1169 
   1170 
   1171 @add_standard_options(PixelSizeTests, StandardOptionsTests)
   1172 class MessageTest(AbstractWidgetTest, unittest.TestCase):
   1173     OPTIONS = (
   1174         'anchor', 'aspect', 'background', 'borderwidth',
   1175         'cursor', 'font', 'foreground',
   1176         'highlightbackground', 'highlightcolor', 'highlightthickness',
   1177         'justify', 'padx', 'pady', 'relief',
   1178         'takefocus', 'text', 'textvariable', 'width',
   1179     )
   1180     _conv_pad_pixels = noconv_meth
   1181 
   1182     def create(self, **kwargs):
   1183         return tkinter.Message(self.root, **kwargs)
   1184 
   1185     def test_aspect(self):
   1186         widget = self.create()
   1187         self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
   1188 
   1189 
   1190 tests_gui = [
   1191         ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,
   1192         FrameTest, LabelFrameTest,LabelTest, ListboxTest,
   1193         MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,
   1194         PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,
   1195         SpinboxTest, TextTest, ToplevelTest,
   1196 ]
   1197 
   1198 if __name__ == '__main__':
   1199     run_unittest(*tests_gui)
   1200