python (3.11.7)

(root)/
lib/
python3.11/
tkinter/
test/
test_tkinter/
test_widgets.py
       1  import unittest
       2  import tkinter
       3  from tkinter import TclError
       4  import os
       5  from test.support import requires
       6  
       7  from tkinter.test.support import (requires_tk,
       8                                    get_tk_patchlevel, widget_eq,
       9                                    AbstractDefaultRootTest)
      10  from tkinter.test.widget_tests import (
      11      add_standard_options,
      12      AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
      13      setUpModule)
      14  
      15  requires('gui')
      16  
      17  
      18  def float_round(x):
      19      return float(round(x))
      20  
      21  
      22  class ESC[4;38;5;81mAbstractToplevelTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149mPixelSizeTests):
      23      _conv_pad_pixels = False
      24  
      25      def test_configure_class(self):
      26          widget = self.create()
      27          self.assertEqual(widget['class'],
      28                           widget.__class__.__name__.title())
      29          self.checkInvalidParam(widget, 'class', 'Foo',
      30                  errmsg="can't modify -class option after widget is created")
      31          widget2 = self.create(class_='Foo')
      32          self.assertEqual(widget2['class'], 'Foo')
      33  
      34      def test_configure_colormap(self):
      35          widget = self.create()
      36          self.assertEqual(widget['colormap'], '')
      37          self.checkInvalidParam(widget, 'colormap', 'new',
      38                  errmsg="can't modify -colormap option after widget is created")
      39          widget2 = self.create(colormap='new')
      40          self.assertEqual(widget2['colormap'], 'new')
      41  
      42      def test_configure_container(self):
      43          widget = self.create()
      44          self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
      45          self.checkInvalidParam(widget, 'container', 1,
      46                  errmsg="can't modify -container option after widget is created")
      47          widget2 = self.create(container=True)
      48          self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
      49  
      50      def test_configure_visual(self):
      51          widget = self.create()
      52          self.assertEqual(widget['visual'], '')
      53          self.checkInvalidParam(widget, 'visual', 'default',
      54                  errmsg="can't modify -visual option after widget is created")
      55          widget2 = self.create(visual='default')
      56          self.assertEqual(widget2['visual'], 'default')
      57  
      58  
      59  @add_standard_options(StandardOptionsTests)
      60  class ESC[4;38;5;81mToplevelTest(ESC[4;38;5;149mAbstractToplevelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      61      OPTIONS = (
      62          'background', 'borderwidth',
      63          'class', 'colormap', 'container', 'cursor', 'height',
      64          'highlightbackground', 'highlightcolor', 'highlightthickness',
      65          'menu', 'padx', 'pady', 'relief', 'screen',
      66          'takefocus', 'use', 'visual', 'width',
      67      )
      68  
      69      def create(self, **kwargs):
      70          return tkinter.Toplevel(self.root, **kwargs)
      71  
      72      def test_configure_menu(self):
      73          widget = self.create()
      74          menu = tkinter.Menu(self.root)
      75          self.checkParam(widget, 'menu', menu, eq=widget_eq)
      76          self.checkParam(widget, 'menu', '')
      77  
      78      def test_configure_screen(self):
      79          widget = self.create()
      80          if widget._windowingsystem != 'x11':
      81              self.skipTest('Not using Tk for X11')
      82          self.assertEqual(widget['screen'], '')
      83          try:
      84              display = os.environ['DISPLAY']
      85          except KeyError:
      86              self.skipTest('No $DISPLAY set.')
      87          self.checkInvalidParam(widget, 'screen', display,
      88                  errmsg="can't modify -screen option after widget is created")
      89          widget2 = self.create(screen=display)
      90          self.assertEqual(widget2['screen'], display)
      91  
      92      def test_configure_use(self):
      93          widget = self.create()
      94          self.assertEqual(widget['use'], '')
      95          parent = self.create(container=True)
      96          wid = hex(parent.winfo_id())
      97          with self.subTest(wid=wid):
      98              widget2 = self.create(use=wid)
      99              self.assertEqual(widget2['use'], wid)
     100  
     101  
     102  @add_standard_options(StandardOptionsTests)
     103  class ESC[4;38;5;81mFrameTest(ESC[4;38;5;149mAbstractToplevelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     104      OPTIONS = (
     105          'background', 'borderwidth',
     106          'class', 'colormap', 'container', 'cursor', 'height',
     107          'highlightbackground', 'highlightcolor', 'highlightthickness',
     108          'padx', 'pady', 'relief', 'takefocus', 'visual', 'width',
     109      )
     110  
     111      def create(self, **kwargs):
     112          return tkinter.Frame(self.root, **kwargs)
     113  
     114  
     115  @add_standard_options(StandardOptionsTests)
     116  class ESC[4;38;5;81mLabelFrameTest(ESC[4;38;5;149mAbstractToplevelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     117      OPTIONS = (
     118          'background', 'borderwidth',
     119          'class', 'colormap', 'container', 'cursor',
     120          'font', 'foreground', 'height',
     121          'highlightbackground', 'highlightcolor', 'highlightthickness',
     122          'labelanchor', 'labelwidget', 'padx', 'pady', 'relief',
     123          'takefocus', 'text', 'visual', 'width',
     124      )
     125  
     126      def create(self, **kwargs):
     127          return tkinter.LabelFrame(self.root, **kwargs)
     128  
     129      def test_configure_labelanchor(self):
     130          widget = self.create()
     131          self.checkEnumParam(widget, 'labelanchor',
     132                              'e', 'en', 'es', 'n', 'ne', 'nw',
     133                              's', 'se', 'sw', 'w', 'wn', 'ws')
     134          self.checkInvalidParam(widget, 'labelanchor', 'center')
     135  
     136      def test_configure_labelwidget(self):
     137          widget = self.create()
     138          label = tkinter.Label(self.root, text='Mupp', name='foo')
     139          self.checkParam(widget, 'labelwidget', label, expected='.foo')
     140          label.destroy()
     141  
     142  
     143  class ESC[4;38;5;81mAbstractLabelTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149mIntegerSizeTests):
     144      _conv_pixels = False
     145  
     146      def test_configure_highlightthickness(self):
     147          widget = self.create()
     148          self.checkPixelsParam(widget, 'highlightthickness',
     149                                0, 1.3, 2.6, 6, -2, '10p')
     150  
     151  
     152  @add_standard_options(StandardOptionsTests)
     153  class ESC[4;38;5;81mLabelTest(ESC[4;38;5;149mAbstractLabelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     154      OPTIONS = (
     155          'activebackground', 'activeforeground', 'anchor',
     156          'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
     157          'disabledforeground', 'font', 'foreground', 'height',
     158          'highlightbackground', 'highlightcolor', 'highlightthickness',
     159          'image', 'justify', 'padx', 'pady', 'relief', 'state',
     160          'takefocus', 'text', 'textvariable',
     161          'underline', 'width', 'wraplength',
     162      )
     163  
     164      def create(self, **kwargs):
     165          return tkinter.Label(self.root, **kwargs)
     166  
     167  
     168  @add_standard_options(StandardOptionsTests)
     169  class ESC[4;38;5;81mButtonTest(ESC[4;38;5;149mAbstractLabelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     170      OPTIONS = (
     171          'activebackground', 'activeforeground', 'anchor',
     172          'background', 'bitmap', 'borderwidth',
     173          'command', 'compound', 'cursor', 'default',
     174          'disabledforeground', 'font', 'foreground', 'height',
     175          'highlightbackground', 'highlightcolor', 'highlightthickness',
     176          'image', 'justify', 'overrelief', 'padx', 'pady', 'relief',
     177          'repeatdelay', 'repeatinterval',
     178          'state', 'takefocus', 'text', 'textvariable',
     179          'underline', 'width', 'wraplength')
     180  
     181      def create(self, **kwargs):
     182          return tkinter.Button(self.root, **kwargs)
     183  
     184      def test_configure_default(self):
     185          widget = self.create()
     186          self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
     187  
     188  
     189  @add_standard_options(StandardOptionsTests)
     190  class ESC[4;38;5;81mCheckbuttonTest(ESC[4;38;5;149mAbstractLabelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     191      OPTIONS = (
     192          'activebackground', 'activeforeground', 'anchor',
     193          'background', 'bitmap', 'borderwidth',
     194          'command', 'compound', 'cursor',
     195          'disabledforeground', 'font', 'foreground', 'height',
     196          'highlightbackground', 'highlightcolor', 'highlightthickness',
     197          'image', 'indicatoron', 'justify',
     198          'offrelief', 'offvalue', 'onvalue', 'overrelief',
     199          'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
     200          'takefocus', 'text', 'textvariable',
     201          'tristateimage', 'tristatevalue',
     202          'underline', 'variable', 'width', 'wraplength',
     203      )
     204  
     205      def create(self, **kwargs):
     206          return tkinter.Checkbutton(self.root, **kwargs)
     207  
     208  
     209      def test_configure_offvalue(self):
     210          widget = self.create()
     211          self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
     212  
     213      def test_configure_onvalue(self):
     214          widget = self.create()
     215          self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
     216  
     217      def test_unique_variables(self):
     218          frames = []
     219          buttons = []
     220          for i in range(2):
     221              f = tkinter.Frame(self.root)
     222              f.pack()
     223              frames.append(f)
     224              for j in 'AB':
     225                  b = tkinter.Checkbutton(f, text=j)
     226                  b.pack()
     227                  buttons.append(b)
     228          variables = [str(b['variable']) for b in buttons]
     229          self.assertEqual(len(set(variables)), 4, variables)
     230  
     231      def test_same_name(self):
     232          f1 = tkinter.Frame(self.root)
     233          f2 = tkinter.Frame(self.root)
     234          b1 = tkinter.Checkbutton(f1, name='test', text='Test1')
     235          b2 = tkinter.Checkbutton(f2, name='test', text='Test2')
     236  
     237          v = tkinter.IntVar(self.root, name='test')
     238          b1.select()
     239          self.assertEqual(v.get(), 1)
     240          b2.deselect()
     241          self.assertEqual(v.get(), 0)
     242  
     243  
     244  @add_standard_options(StandardOptionsTests)
     245  class ESC[4;38;5;81mRadiobuttonTest(ESC[4;38;5;149mAbstractLabelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     246      OPTIONS = (
     247          'activebackground', 'activeforeground', 'anchor',
     248          'background', 'bitmap', 'borderwidth',
     249          'command', 'compound', 'cursor',
     250          'disabledforeground', 'font', 'foreground', 'height',
     251          'highlightbackground', 'highlightcolor', 'highlightthickness',
     252          'image', 'indicatoron', 'justify', 'offrelief', 'overrelief',
     253          'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
     254          'takefocus', 'text', 'textvariable',
     255          'tristateimage', 'tristatevalue',
     256          'underline', 'value', 'variable', 'width', 'wraplength',
     257      )
     258  
     259      def create(self, **kwargs):
     260          return tkinter.Radiobutton(self.root, **kwargs)
     261  
     262      def test_configure_value(self):
     263          widget = self.create()
     264          self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
     265  
     266  
     267  @add_standard_options(StandardOptionsTests)
     268  class ESC[4;38;5;81mMenubuttonTest(ESC[4;38;5;149mAbstractLabelTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     269      OPTIONS = (
     270          'activebackground', 'activeforeground', 'anchor',
     271          'background', 'bitmap', 'borderwidth',
     272          'compound', 'cursor', 'direction',
     273          'disabledforeground', 'font', 'foreground', 'height',
     274          'highlightbackground', 'highlightcolor', 'highlightthickness',
     275          'image', 'indicatoron', 'justify', 'menu',
     276          'padx', 'pady', 'relief', 'state',
     277          'takefocus', 'text', 'textvariable',
     278          'underline', 'width', 'wraplength',
     279      )
     280      _conv_pixels = round
     281  
     282      def create(self, **kwargs):
     283          return tkinter.Menubutton(self.root, **kwargs)
     284  
     285      def test_configure_direction(self):
     286          widget = self.create()
     287          self.checkEnumParam(widget, 'direction',
     288                  'above', 'below', 'flush', 'left', 'right')
     289  
     290      def test_configure_height(self):
     291          widget = self.create()
     292          self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
     293  
     294      test_configure_highlightthickness = \
     295          StandardOptionsTests.test_configure_highlightthickness
     296  
     297      def test_configure_image(self):
     298          widget = self.create()
     299          image = tkinter.PhotoImage(master=self.root, name='image1')
     300          self.checkParam(widget, 'image', image, conv=str)
     301          errmsg = 'image "spam" doesn\'t exist'
     302          with self.assertRaises(tkinter.TclError) as cm:
     303              widget['image'] = 'spam'
     304          if errmsg is not None:
     305              self.assertEqual(str(cm.exception), errmsg)
     306          with self.assertRaises(tkinter.TclError) as cm:
     307              widget.configure({'image': 'spam'})
     308          if errmsg is not None:
     309              self.assertEqual(str(cm.exception), errmsg)
     310  
     311      def test_configure_menu(self):
     312          widget = self.create()
     313          menu = tkinter.Menu(widget, name='menu')
     314          self.checkParam(widget, 'menu', menu, eq=widget_eq)
     315          menu.destroy()
     316  
     317      def test_configure_padx(self):
     318          widget = self.create()
     319          self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
     320          self.checkParam(widget, 'padx', -2, expected=0)
     321  
     322      def test_configure_pady(self):
     323          widget = self.create()
     324          self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
     325          self.checkParam(widget, 'pady', -2, expected=0)
     326  
     327      def test_configure_width(self):
     328          widget = self.create()
     329          self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
     330  
     331  
     332  class ESC[4;38;5;81mOptionMenuTest(ESC[4;38;5;149mMenubuttonTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     333  
     334      def create(self, default='b', values=('a', 'b', 'c'), **kwargs):
     335          return tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
     336  
     337      def test_bad_kwarg(self):
     338          with self.assertRaisesRegex(TclError, r"^unknown option -image$"):
     339              tkinter.OptionMenu(self.root, None, 'b', image='')
     340  
     341  
     342  @add_standard_options(IntegerSizeTests, StandardOptionsTests)
     343  class ESC[4;38;5;81mEntryTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     344      OPTIONS = (
     345          'background', 'borderwidth', 'cursor',
     346          'disabledbackground', 'disabledforeground',
     347          'exportselection', 'font', 'foreground',
     348          'highlightbackground', 'highlightcolor', 'highlightthickness',
     349          'insertbackground', 'insertborderwidth',
     350          'insertofftime', 'insertontime', 'insertwidth',
     351          'invalidcommand', 'justify', 'readonlybackground', 'relief',
     352          'selectbackground', 'selectborderwidth', 'selectforeground',
     353          'show', 'state', 'takefocus', 'textvariable',
     354          'validate', 'validatecommand', 'width', 'xscrollcommand',
     355      )
     356  
     357      def create(self, **kwargs):
     358          return tkinter.Entry(self.root, **kwargs)
     359  
     360      def test_configure_disabledbackground(self):
     361          widget = self.create()
     362          self.checkColorParam(widget, 'disabledbackground')
     363  
     364      def test_configure_insertborderwidth(self):
     365          widget = self.create(insertwidth=100)
     366          self.checkPixelsParam(widget, 'insertborderwidth',
     367                                0, 1.3, 2.6, 6, -2, '10p')
     368          # insertborderwidth is bounded above by a half of insertwidth.
     369          self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
     370  
     371      def test_configure_insertwidth(self):
     372          widget = self.create()
     373          self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
     374          self.checkParam(widget, 'insertwidth', 0.1, expected=2)
     375          self.checkParam(widget, 'insertwidth', -2, expected=2)
     376          self.checkParam(widget, 'insertwidth', 0.9, expected=1)
     377  
     378      def test_configure_invalidcommand(self):
     379          widget = self.create()
     380          self.checkCommandParam(widget, 'invalidcommand')
     381          self.checkCommandParam(widget, 'invcmd')
     382  
     383      def test_configure_readonlybackground(self):
     384          widget = self.create()
     385          self.checkColorParam(widget, 'readonlybackground')
     386  
     387      def test_configure_show(self):
     388          widget = self.create()
     389          self.checkParam(widget, 'show', '*')
     390          self.checkParam(widget, 'show', '')
     391          self.checkParam(widget, 'show', ' ')
     392  
     393      def test_configure_state(self):
     394          widget = self.create()
     395          self.checkEnumParam(widget, 'state',
     396                              'disabled', 'normal', 'readonly')
     397  
     398      def test_configure_validate(self):
     399          widget = self.create()
     400          self.checkEnumParam(widget, 'validate',
     401                  'all', 'key', 'focus', 'focusin', 'focusout', 'none')
     402  
     403      def test_configure_validatecommand(self):
     404          widget = self.create()
     405          self.checkCommandParam(widget, 'validatecommand')
     406          self.checkCommandParam(widget, 'vcmd')
     407  
     408      def test_selection_methods(self):
     409          widget = self.create()
     410          widget.insert(0, '12345')
     411          self.assertFalse(widget.selection_present())
     412          widget.selection_range(0, 'end')
     413          self.assertEqual(widget.selection_get(), '12345')
     414          self.assertTrue(widget.selection_present())
     415          widget.selection_from(1)
     416          widget.selection_to(2)
     417          self.assertEqual(widget.selection_get(), '2')
     418          widget.selection_range(3, 4)
     419          self.assertEqual(widget.selection_get(), '4')
     420          widget.selection_clear()
     421          self.assertFalse(widget.selection_present())
     422          widget.selection_range(0, 'end')
     423          widget.selection_adjust(4)
     424          self.assertEqual(widget.selection_get(), '1234')
     425          widget.selection_adjust(1)
     426          self.assertEqual(widget.selection_get(), '234')
     427          widget.selection_adjust(5)
     428          self.assertEqual(widget.selection_get(), '2345')
     429          widget.selection_adjust(0)
     430          self.assertEqual(widget.selection_get(), '12345')
     431          widget.selection_adjust(0)
     432  
     433  
     434  @add_standard_options(StandardOptionsTests)
     435  class ESC[4;38;5;81mSpinboxTest(ESC[4;38;5;149mEntryTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     436      OPTIONS = (
     437          'activebackground', 'background', 'borderwidth',
     438          'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',
     439          'command', 'cursor', 'disabledbackground', 'disabledforeground',
     440          'exportselection', 'font', 'foreground', 'format', 'from',
     441          'highlightbackground', 'highlightcolor', 'highlightthickness',
     442          'increment',
     443          'insertbackground', 'insertborderwidth',
     444          'insertofftime', 'insertontime', 'insertwidth',
     445          'invalidcommand', 'justify', 'relief', 'readonlybackground',
     446          'repeatdelay', 'repeatinterval',
     447          'selectbackground', 'selectborderwidth', 'selectforeground',
     448          'state', 'takefocus', 'textvariable', 'to',
     449          'validate', 'validatecommand', 'values',
     450          'width', 'wrap', 'xscrollcommand',
     451      )
     452  
     453      def create(self, **kwargs):
     454          return tkinter.Spinbox(self.root, **kwargs)
     455  
     456      test_configure_show = None
     457  
     458      def test_configure_buttonbackground(self):
     459          widget = self.create()
     460          self.checkColorParam(widget, 'buttonbackground')
     461  
     462      def test_configure_buttoncursor(self):
     463          widget = self.create()
     464          self.checkCursorParam(widget, 'buttoncursor')
     465  
     466      def test_configure_buttondownrelief(self):
     467          widget = self.create()
     468          self.checkReliefParam(widget, 'buttondownrelief')
     469  
     470      def test_configure_buttonuprelief(self):
     471          widget = self.create()
     472          self.checkReliefParam(widget, 'buttonuprelief')
     473  
     474      def test_configure_format(self):
     475          widget = self.create()
     476          self.checkParam(widget, 'format', '%2f')
     477          self.checkParam(widget, 'format', '%2.2f')
     478          self.checkParam(widget, 'format', '%.2f')
     479          self.checkParam(widget, 'format', '%2.f')
     480          self.checkInvalidParam(widget, 'format', '%2e-1f')
     481          self.checkInvalidParam(widget, 'format', '2.2')
     482          self.checkInvalidParam(widget, 'format', '%2.-2f')
     483          self.checkParam(widget, 'format', '%-2.02f')
     484          self.checkParam(widget, 'format', '% 2.02f')
     485          self.checkParam(widget, 'format', '% -2.200f')
     486          self.checkParam(widget, 'format', '%09.200f')
     487          self.checkInvalidParam(widget, 'format', '%d')
     488  
     489      def test_configure_from(self):
     490          widget = self.create()
     491          self.checkParam(widget, 'to', 100.0)
     492          self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
     493          self.checkInvalidParam(widget, 'from', 200,
     494                  errmsg='-to value must be greater than -from value')
     495  
     496      def test_configure_increment(self):
     497          widget = self.create()
     498          self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
     499  
     500      def test_configure_to(self):
     501          widget = self.create()
     502          self.checkParam(widget, 'from', -100.0)
     503          self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
     504          self.checkInvalidParam(widget, 'to', -200,
     505                  errmsg='-to value must be greater than -from value')
     506  
     507      def test_configure_values(self):
     508          # XXX
     509          widget = self.create()
     510          self.assertEqual(widget['values'], '')
     511          self.checkParam(widget, 'values', 'mon tue wed thur')
     512          self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),
     513                          expected='mon tue wed thur')
     514          self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),
     515                          expected='42 3.14 {} {any string}')
     516          self.checkParam(widget, 'values', '')
     517  
     518      def test_configure_wrap(self):
     519          widget = self.create()
     520          self.checkBooleanParam(widget, 'wrap')
     521  
     522      def test_bbox(self):
     523          widget = self.create()
     524          self.assertIsBoundingBox(widget.bbox(0))
     525          self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')
     526          self.assertRaises(tkinter.TclError, widget.bbox, None)
     527          self.assertRaises(TypeError, widget.bbox)
     528          self.assertRaises(TypeError, widget.bbox, 0, 1)
     529  
     530      def test_selection_methods(self):
     531          widget = self.create()
     532          widget.insert(0, '12345')
     533          self.assertFalse(widget.selection_present())
     534          widget.selection_range(0, 'end')
     535          self.assertEqual(widget.selection_get(), '12345')
     536          self.assertTrue(widget.selection_present())
     537          widget.selection_from(1)
     538          widget.selection_to(2)
     539          self.assertEqual(widget.selection_get(), '2')
     540          widget.selection_range(3, 4)
     541          self.assertEqual(widget.selection_get(), '4')
     542          widget.selection_clear()
     543          self.assertFalse(widget.selection_present())
     544          widget.selection_range(0, 'end')
     545          widget.selection_adjust(4)
     546          self.assertEqual(widget.selection_get(), '1234')
     547          widget.selection_adjust(1)
     548          self.assertEqual(widget.selection_get(), '234')
     549          widget.selection_adjust(5)
     550          self.assertEqual(widget.selection_get(), '2345')
     551          widget.selection_adjust(0)
     552          self.assertEqual(widget.selection_get(), '12345')
     553  
     554      def test_selection_element(self):
     555          widget = self.create()
     556          self.assertEqual(widget.selection_element(), "none")
     557          widget.selection_element("buttonup")
     558          self.assertEqual(widget.selection_element(), "buttonup")
     559          widget.selection_element("buttondown")
     560          self.assertEqual(widget.selection_element(), "buttondown")
     561  
     562  
     563  @add_standard_options(StandardOptionsTests)
     564  class ESC[4;38;5;81mTextTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     565      OPTIONS = (
     566          'autoseparators', 'background', 'blockcursor', 'borderwidth',
     567          'cursor', 'endline', 'exportselection',
     568          'font', 'foreground', 'height',
     569          'highlightbackground', 'highlightcolor', 'highlightthickness',
     570          'inactiveselectbackground', 'insertbackground', 'insertborderwidth',
     571          'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth',
     572          'maxundo', 'padx', 'pady', 'relief',
     573          'selectbackground', 'selectborderwidth', 'selectforeground',
     574          'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state',
     575          'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',
     576          'xscrollcommand', 'yscrollcommand',
     577      )
     578  
     579      def create(self, **kwargs):
     580          return tkinter.Text(self.root, **kwargs)
     581  
     582      def test_configure_autoseparators(self):
     583          widget = self.create()
     584          self.checkBooleanParam(widget, 'autoseparators')
     585  
     586      def test_configure_blockcursor(self):
     587          widget = self.create()
     588          self.checkBooleanParam(widget, 'blockcursor')
     589  
     590      def test_configure_endline(self):
     591          widget = self.create()
     592          text = '\n'.join('Line %d' for i in range(100))
     593          widget.insert('end', text)
     594          self.checkParam(widget, 'endline', 200, expected='')
     595          self.checkParam(widget, 'endline', -10, expected='')
     596          self.checkInvalidParam(widget, 'endline', 'spam',
     597                  errmsg='expected integer but got "spam"')
     598          self.checkParam(widget, 'endline', 50)
     599          self.checkParam(widget, 'startline', 15)
     600          self.checkInvalidParam(widget, 'endline', 10,
     601                  errmsg='-startline must be less than or equal to -endline')
     602  
     603      def test_configure_height(self):
     604          widget = self.create()
     605          self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
     606          self.checkParam(widget, 'height', -100, expected=1)
     607          self.checkParam(widget, 'height', 0, expected=1)
     608  
     609      def test_configure_maxundo(self):
     610          widget = self.create()
     611          self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
     612  
     613      def test_configure_inactiveselectbackground(self):
     614          widget = self.create()
     615          self.checkColorParam(widget, 'inactiveselectbackground')
     616  
     617      @requires_tk(8, 6)
     618      def test_configure_insertunfocussed(self):
     619          widget = self.create()
     620          self.checkEnumParam(widget, 'insertunfocussed',
     621                              'hollow', 'none', 'solid')
     622  
     623      def test_configure_selectborderwidth(self):
     624          widget = self.create()
     625          self.checkPixelsParam(widget, 'selectborderwidth',
     626                                1.3, 2.6, -2, '10p', conv=False)
     627  
     628      def test_configure_spacing1(self):
     629          widget = self.create()
     630          self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
     631          self.checkParam(widget, 'spacing1', -5, expected=0)
     632  
     633      def test_configure_spacing2(self):
     634          widget = self.create()
     635          self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
     636          self.checkParam(widget, 'spacing2', -1, expected=0)
     637  
     638      def test_configure_spacing3(self):
     639          widget = self.create()
     640          self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
     641          self.checkParam(widget, 'spacing3', -10, expected=0)
     642  
     643      def test_configure_startline(self):
     644          widget = self.create()
     645          text = '\n'.join('Line %d' for i in range(100))
     646          widget.insert('end', text)
     647          self.checkParam(widget, 'startline', 200, expected='')
     648          self.checkParam(widget, 'startline', -10, expected='')
     649          self.checkInvalidParam(widget, 'startline', 'spam',
     650                  errmsg='expected integer but got "spam"')
     651          self.checkParam(widget, 'startline', 10)
     652          self.checkParam(widget, 'endline', 50)
     653          self.checkInvalidParam(widget, 'startline', 70,
     654                  errmsg='-startline must be less than or equal to -endline')
     655  
     656      def test_configure_state(self):
     657          widget = self.create()
     658          self.checkEnumParam(widget, 'state', 'disabled', 'normal')
     659  
     660      def test_configure_tabs(self):
     661          widget = self.create()
     662          self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'))
     663          self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i',
     664                          expected=('10.2', '20.7', '1i', '2i'))
     665          self.checkParam(widget, 'tabs', '2c left 4c 6c center',
     666                          expected=('2c', 'left', '4c', '6c', 'center'))
     667          self.checkInvalidParam(widget, 'tabs', 'spam',
     668                                 errmsg='bad screen distance "spam"')
     669  
     670      def test_configure_tabstyle(self):
     671          widget = self.create()
     672          self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
     673  
     674      def test_configure_undo(self):
     675          widget = self.create()
     676          self.checkBooleanParam(widget, 'undo')
     677  
     678      def test_configure_width(self):
     679          widget = self.create()
     680          self.checkIntegerParam(widget, 'width', 402)
     681          self.checkParam(widget, 'width', -402, expected=1)
     682          self.checkParam(widget, 'width', 0, expected=1)
     683  
     684      def test_configure_wrap(self):
     685          widget = self.create()
     686          self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word')
     687  
     688      def test_bbox(self):
     689          widget = self.create()
     690          self.assertIsBoundingBox(widget.bbox('1.1'))
     691          self.assertIsNone(widget.bbox('end'))
     692          self.assertRaises(tkinter.TclError, widget.bbox, 'noindex')
     693          self.assertRaises(tkinter.TclError, widget.bbox, None)
     694          self.assertRaises(TypeError, widget.bbox)
     695          self.assertRaises(TypeError, widget.bbox, '1.1', 'end')
     696  
     697  
     698  @add_standard_options(PixelSizeTests, StandardOptionsTests)
     699  class ESC[4;38;5;81mCanvasTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     700      OPTIONS = (
     701          'background', 'borderwidth',
     702          'closeenough', 'confine', 'cursor', 'height',
     703          'highlightbackground', 'highlightcolor', 'highlightthickness',
     704          'insertbackground', 'insertborderwidth',
     705          'insertofftime', 'insertontime', 'insertwidth',
     706          'offset', 'relief', 'scrollregion',
     707          'selectbackground', 'selectborderwidth', 'selectforeground',
     708          'state', 'takefocus',
     709          'xscrollcommand', 'xscrollincrement',
     710          'yscrollcommand', 'yscrollincrement', 'width',
     711      )
     712  
     713      _conv_pixels = round
     714      _stringify = True
     715  
     716      def create(self, **kwargs):
     717          return tkinter.Canvas(self.root, **kwargs)
     718  
     719      def test_configure_closeenough(self):
     720          widget = self.create()
     721          self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
     722                               conv=float)
     723  
     724      def test_configure_confine(self):
     725          widget = self.create()
     726          self.checkBooleanParam(widget, 'confine')
     727  
     728      def test_configure_offset(self):
     729          widget = self.create()
     730          self.assertEqual(widget['offset'], '0,0')
     731          self.checkParams(widget, 'offset',
     732                  'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
     733          self.checkParam(widget, 'offset', '10,20')
     734          self.checkParam(widget, 'offset', '#5,6')
     735          self.checkInvalidParam(widget, 'offset', 'spam')
     736  
     737      def test_configure_scrollregion(self):
     738          widget = self.create()
     739          self.checkParam(widget, 'scrollregion', '0 0 200 150')
     740          self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
     741                          expected='0 0 200 150')
     742          self.checkParam(widget, 'scrollregion', '')
     743          self.checkInvalidParam(widget, 'scrollregion', 'spam',
     744                                 errmsg='bad scrollRegion "spam"')
     745          self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam'))
     746          self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
     747          self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
     748  
     749      def test_configure_state(self):
     750          widget = self.create()
     751          self.checkEnumParam(widget, 'state', 'disabled', 'normal',
     752                  errmsg='bad state value "{}": must be normal or disabled')
     753  
     754      def test_configure_xscrollincrement(self):
     755          widget = self.create()
     756          self.checkPixelsParam(widget, 'xscrollincrement',
     757                                40, 0, 41.2, 43.6, -40, '0.5i')
     758  
     759      def test_configure_yscrollincrement(self):
     760          widget = self.create()
     761          self.checkPixelsParam(widget, 'yscrollincrement',
     762                                10, 0, 11.2, 13.6, -10, '0.1i')
     763  
     764      def _test_option_joinstyle(self, c, factory):
     765          for joinstyle in 'bevel', 'miter', 'round':
     766              i = factory(joinstyle=joinstyle)
     767              self.assertEqual(c.itemcget(i, 'joinstyle'), joinstyle)
     768          self.assertRaises(TclError, factory, joinstyle='spam')
     769  
     770      def _test_option_smooth(self, c, factory):
     771          for smooth in 1, True, '1', 'true', 'yes', 'on':
     772              i = factory(smooth=smooth)
     773              self.assertEqual(c.itemcget(i, 'smooth'), 'true')
     774          for smooth in 0, False, '0', 'false', 'no', 'off':
     775              i = factory(smooth=smooth)
     776              self.assertEqual(c.itemcget(i, 'smooth'), '0')
     777          i = factory(smooth=True, splinestep=30)
     778          self.assertEqual(c.itemcget(i, 'smooth'), 'true')
     779          self.assertEqual(c.itemcget(i, 'splinestep'), '30')
     780          i = factory(smooth='raw', splinestep=30)
     781          self.assertEqual(c.itemcget(i, 'smooth'), 'raw')
     782          self.assertEqual(c.itemcget(i, 'splinestep'), '30')
     783          self.assertRaises(TclError, factory, smooth='spam')
     784  
     785      def test_create_rectangle(self):
     786          c = self.create()
     787          i1 = c.create_rectangle(20, 30, 60, 10)
     788          self.assertEqual(c.coords(i1), [20.0, 10.0, 60.0, 30.0])
     789          self.assertEqual(c.bbox(i1), (19, 9, 61, 31))
     790  
     791          i2 = c.create_rectangle([21, 31, 61, 11])
     792          self.assertEqual(c.coords(i2), [21.0, 11.0, 61.0, 31.0])
     793          self.assertEqual(c.bbox(i2), (20, 10, 62, 32))
     794  
     795          i3 = c.create_rectangle((22, 32), (62, 12))
     796          self.assertEqual(c.coords(i3), [22.0, 12.0, 62.0, 32.0])
     797          self.assertEqual(c.bbox(i3), (21, 11, 63, 33))
     798  
     799          i4 = c.create_rectangle([(23, 33), (63, 13)])
     800          self.assertEqual(c.coords(i4), [23.0, 13.0, 63.0, 33.0])
     801          self.assertEqual(c.bbox(i4), (22, 12, 64, 34))
     802  
     803          self.assertRaises(TclError, c.create_rectangle, 20, 30, 60)
     804          self.assertRaises(TclError, c.create_rectangle, [20, 30, 60])
     805          self.assertRaises(TclError, c.create_rectangle, 20, 30, 40, 50, 60, 10)
     806          self.assertRaises(TclError, c.create_rectangle, [20, 30, 40, 50, 60, 10])
     807          self.assertRaises(TclError, c.create_rectangle, 20, 30)
     808          self.assertRaises(TclError, c.create_rectangle, [20, 30])
     809          self.assertRaises(IndexError, c.create_rectangle)
     810          self.assertRaises(IndexError, c.create_rectangle, [])
     811  
     812      def test_create_line(self):
     813          c = self.create()
     814          i1 = c.create_line(20, 30, 40, 50, 60, 10)
     815          self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0])
     816          self.assertEqual(c.bbox(i1), (18, 8, 62, 52))
     817          self.assertEqual(c.itemcget(i1, 'arrow'), 'none')
     818          self.assertEqual(c.itemcget(i1, 'arrowshape'), '8 10 3')
     819          self.assertEqual(c.itemcget(i1, 'capstyle'), 'butt')
     820          self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round')
     821          self.assertEqual(c.itemcget(i1, 'smooth'), '0')
     822          self.assertEqual(c.itemcget(i1, 'splinestep'), '12')
     823  
     824          i2 = c.create_line([21, 31, 41, 51, 61, 11])
     825          self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0])
     826          self.assertEqual(c.bbox(i2), (19, 9, 63, 53))
     827  
     828          i3 = c.create_line((22, 32), (42, 52), (62, 12))
     829          self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0])
     830          self.assertEqual(c.bbox(i3), (20, 10, 64, 54))
     831  
     832          i4 = c.create_line([(23, 33), (43, 53), (63, 13)])
     833          self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0])
     834          self.assertEqual(c.bbox(i4), (21, 11, 65, 55))
     835  
     836          self.assertRaises(TclError, c.create_line, 20, 30, 60)
     837          self.assertRaises(TclError, c.create_line, [20, 30, 60])
     838          self.assertRaises(TclError, c.create_line, 20, 30)
     839          self.assertRaises(TclError, c.create_line, [20, 30])
     840          self.assertRaises(IndexError, c.create_line)
     841          self.assertRaises(IndexError, c.create_line, [])
     842  
     843          for arrow in 'none', 'first', 'last', 'both':
     844              i = c.create_line(20, 30, 60, 10, arrow=arrow)
     845              self.assertEqual(c.itemcget(i, 'arrow'), arrow)
     846          i = c.create_line(20, 30, 60, 10, arrow='first', arrowshape=[10, 15, 5])
     847          self.assertEqual(c.itemcget(i, 'arrowshape'), '10 15 5')
     848          self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, arrow='spam')
     849  
     850          for capstyle in 'butt', 'projecting', 'round':
     851              i = c.create_line(20, 30, 60, 10, capstyle=capstyle)
     852              self.assertEqual(c.itemcget(i, 'capstyle'), capstyle)
     853          self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, capstyle='spam')
     854  
     855          self._test_option_joinstyle(c,
     856                  lambda **kwargs: c.create_line(20, 30, 40, 50, 60, 10, **kwargs))
     857          self._test_option_smooth(c,
     858                  lambda **kwargs: c.create_line(20, 30, 60, 10, **kwargs))
     859  
     860      def test_create_polygon(self):
     861          c = self.create()
     862          i1 = c.create_polygon(20, 30, 40, 50, 60, 10)
     863          self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0])
     864          self.assertEqual(c.bbox(i1), (19, 9, 61, 51))
     865          self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round')
     866          self.assertEqual(c.itemcget(i1, 'smooth'), '0')
     867          self.assertEqual(c.itemcget(i1, 'splinestep'), '12')
     868  
     869          i2 = c.create_polygon([21, 31, 41, 51, 61, 11])
     870          self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0])
     871          self.assertEqual(c.bbox(i2), (20, 10, 62, 52))
     872  
     873          i3 = c.create_polygon((22, 32), (42, 52), (62, 12))
     874          self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0])
     875          self.assertEqual(c.bbox(i3), (21, 11, 63, 53))
     876  
     877          i4 = c.create_polygon([(23, 33), (43, 53), (63, 13)])
     878          self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0])
     879          self.assertEqual(c.bbox(i4), (22, 12, 64, 54))
     880  
     881          self.assertRaises(TclError, c.create_polygon, 20, 30, 60)
     882          self.assertRaises(TclError, c.create_polygon, [20, 30, 60])
     883          self.assertRaises(IndexError, c.create_polygon)
     884          self.assertRaises(IndexError, c.create_polygon, [])
     885  
     886          self._test_option_joinstyle(c,
     887                  lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs))
     888          self._test_option_smooth(c,
     889                  lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs))
     890  
     891      def test_coords(self):
     892          c = self.create()
     893          i = c.create_line(20, 30, 40, 50, 60, 10, tags='x')
     894          self.assertEqual(c.coords(i), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0])
     895          self.assertEqual(c.coords('x'), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0])
     896          self.assertEqual(c.bbox(i), (18, 8, 62, 52))
     897  
     898          c.coords(i, 50, 60, 70, 80, 90, 40)
     899          self.assertEqual(c.coords(i), [50.0, 60.0, 70.0, 80.0, 90.0, 40.0])
     900          self.assertEqual(c.bbox(i), (48, 38, 92, 82))
     901  
     902          c.coords(i, [21, 31, 41, 51, 61, 11])
     903          self.assertEqual(c.coords(i), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0])
     904  
     905          c.coords(i, 20, 30, 60, 10)
     906          self.assertEqual(c.coords(i), [20.0, 30.0, 60.0, 10.0])
     907          self.assertEqual(c.bbox(i), (18, 8, 62, 32))
     908  
     909          self.assertRaises(TclError, c.coords, i, 20, 30, 60)
     910          self.assertRaises(TclError, c.coords, i, [20, 30, 60])
     911          self.assertRaises(TclError, c.coords, i, 20, 30)
     912          self.assertRaises(TclError, c.coords, i, [20, 30])
     913  
     914          c.coords(i, '20', '30c', '60i', '10p')
     915          coords = c.coords(i)
     916          self.assertIsInstance(coords, list)
     917          self.assertEqual(len(coords), 4)
     918          self.assertEqual(coords[0], 20)
     919          for i in range(4):
     920              self.assertIsInstance(coords[i], float)
     921  
     922      @requires_tk(8, 6)
     923      def test_moveto(self):
     924          widget = self.create()
     925          i1 = widget.create_rectangle(1, 1, 20, 20, tags='group')
     926          i2 = widget.create_rectangle(30, 30, 50, 70, tags='group')
     927          x1, y1, _, _ = widget.bbox(i1)
     928          x2, y2, _, _ = widget.bbox(i2)
     929          widget.moveto('group', 200, 100)
     930          x1_2, y1_2, _, _ = widget.bbox(i1)
     931          x2_2, y2_2, _, _ = widget.bbox(i2)
     932          self.assertEqual(x1_2, 200)
     933          self.assertEqual(y1_2, 100)
     934          self.assertEqual(x2 - x1, x2_2 - x1_2)
     935          self.assertEqual(y2 - y1, y2_2 - y1_2)
     936          widget.tag_lower(i2, i1)
     937          widget.moveto('group', y=50)
     938          x1_3, y1_3, _, _ = widget.bbox(i1)
     939          x2_3, y2_3, _, _ = widget.bbox(i2)
     940          self.assertEqual(y2_3, 50)
     941          self.assertEqual(x2_3, x2_2)
     942          self.assertEqual(x2_2 - x1_2, x2_3 - x1_3)
     943          self.assertEqual(y2_2 - y1_2, y2_3 - y1_3)
     944  
     945  
     946  @add_standard_options(IntegerSizeTests, StandardOptionsTests)
     947  class ESC[4;38;5;81mListboxTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     948      OPTIONS = (
     949          'activestyle', 'background', 'borderwidth', 'cursor',
     950          'disabledforeground', 'exportselection',
     951          'font', 'foreground', 'height',
     952          'highlightbackground', 'highlightcolor', 'highlightthickness',
     953          'justify', 'listvariable', 'relief',
     954          'selectbackground', 'selectborderwidth', 'selectforeground',
     955          'selectmode', 'setgrid', 'state',
     956          'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
     957      )
     958  
     959      def create(self, **kwargs):
     960          return tkinter.Listbox(self.root, **kwargs)
     961  
     962      def test_configure_activestyle(self):
     963          widget = self.create()
     964          self.checkEnumParam(widget, 'activestyle',
     965                              'dotbox', 'none', 'underline')
     966  
     967      test_configure_justify = requires_tk(8, 6, 5)(StandardOptionsTests.test_configure_justify)
     968  
     969      def test_configure_listvariable(self):
     970          widget = self.create()
     971          var = tkinter.DoubleVar(self.root)
     972          self.checkVariableParam(widget, 'listvariable', var)
     973  
     974      def test_configure_selectmode(self):
     975          widget = self.create()
     976          self.checkParam(widget, 'selectmode', 'single')
     977          self.checkParam(widget, 'selectmode', 'browse')
     978          self.checkParam(widget, 'selectmode', 'multiple')
     979          self.checkParam(widget, 'selectmode', 'extended')
     980  
     981      def test_configure_state(self):
     982          widget = self.create()
     983          self.checkEnumParam(widget, 'state', 'disabled', 'normal')
     984  
     985      def test_itemconfigure(self):
     986          widget = self.create()
     987          with self.assertRaisesRegex(TclError, 'item number "0" out of range'):
     988              widget.itemconfigure(0)
     989          colors = 'red orange yellow green blue white violet'.split()
     990          widget.insert('end', *colors)
     991          for i, color in enumerate(colors):
     992              widget.itemconfigure(i, background=color)
     993          with self.assertRaises(TypeError):
     994              widget.itemconfigure()
     995          with self.assertRaisesRegex(TclError, 'bad listbox index "red"'):
     996              widget.itemconfigure('red')
     997          self.assertEqual(widget.itemconfigure(0, 'background'),
     998                           ('background', 'background', 'Background', '', 'red'))
     999          self.assertEqual(widget.itemconfigure('end', 'background'),
    1000                           ('background', 'background', 'Background', '', 'violet'))
    1001          self.assertEqual(widget.itemconfigure('@0,0', 'background'),
    1002                           ('background', 'background', 'Background', '', 'red'))
    1003  
    1004          d = widget.itemconfigure(0)
    1005          self.assertIsInstance(d, dict)
    1006          for k, v in d.items():
    1007              self.assertIn(len(v), (2, 5))
    1008              if len(v) == 5:
    1009                  self.assertEqual(v, widget.itemconfigure(0, k))
    1010                  self.assertEqual(v[4], widget.itemcget(0, k))
    1011  
    1012      def check_itemconfigure(self, name, value):
    1013          widget = self.create()
    1014          widget.insert('end', 'a', 'b', 'c', 'd')
    1015          widget.itemconfigure(0, **{name: value})
    1016          self.assertEqual(widget.itemconfigure(0, name)[4], value)
    1017          self.assertEqual(widget.itemcget(0, name), value)
    1018          with self.assertRaisesRegex(TclError, 'unknown color name "spam"'):
    1019              widget.itemconfigure(0, **{name: 'spam'})
    1020  
    1021      def test_itemconfigure_background(self):
    1022          self.check_itemconfigure('background', '#ff0000')
    1023  
    1024      def test_itemconfigure_bg(self):
    1025          self.check_itemconfigure('bg', '#ff0000')
    1026  
    1027      def test_itemconfigure_fg(self):
    1028          self.check_itemconfigure('fg', '#110022')
    1029  
    1030      def test_itemconfigure_foreground(self):
    1031          self.check_itemconfigure('foreground', '#110022')
    1032  
    1033      def test_itemconfigure_selectbackground(self):
    1034          self.check_itemconfigure('selectbackground', '#110022')
    1035  
    1036      def test_itemconfigure_selectforeground(self):
    1037          self.check_itemconfigure('selectforeground', '#654321')
    1038  
    1039      def test_box(self):
    1040          lb = self.create()
    1041          lb.insert(0, *('el%d' % i for i in range(8)))
    1042          lb.pack()
    1043          self.assertIsBoundingBox(lb.bbox(0))
    1044          self.assertIsNone(lb.bbox(-1))
    1045          self.assertIsNone(lb.bbox(10))
    1046          self.assertRaises(TclError, lb.bbox, 'noindex')
    1047          self.assertRaises(TclError, lb.bbox, None)
    1048          self.assertRaises(TypeError, lb.bbox)
    1049          self.assertRaises(TypeError, lb.bbox, 0, 1)
    1050  
    1051      def test_curselection(self):
    1052          lb = self.create()
    1053          lb.insert(0, *('el%d' % i for i in range(8)))
    1054          lb.selection_clear(0, tkinter.END)
    1055          lb.selection_set(2, 4)
    1056          lb.selection_set(6)
    1057          self.assertEqual(lb.curselection(), (2, 3, 4, 6))
    1058          self.assertRaises(TypeError, lb.curselection, 0)
    1059  
    1060      def test_get(self):
    1061          lb = self.create()
    1062          lb.insert(0, *('el%d' % i for i in range(8)))
    1063          self.assertEqual(lb.get(0), 'el0')
    1064          self.assertEqual(lb.get(3), 'el3')
    1065          self.assertEqual(lb.get('end'), 'el7')
    1066          self.assertEqual(lb.get(8), '')
    1067          self.assertEqual(lb.get(-1), '')
    1068          self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5'))
    1069          self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7'))
    1070          self.assertEqual(lb.get(5, 0), ())
    1071          self.assertEqual(lb.get(0, 0), ('el0',))
    1072          self.assertRaises(TclError, lb.get, 'noindex')
    1073          self.assertRaises(TclError, lb.get, None)
    1074          self.assertRaises(TypeError, lb.get)
    1075          self.assertRaises(TclError, lb.get, 'end', 'noindex')
    1076          self.assertRaises(TypeError, lb.get, 1, 2, 3)
    1077          self.assertRaises(TclError, lb.get, 2.4)
    1078  
    1079  
    1080  @add_standard_options(PixelSizeTests, StandardOptionsTests)
    1081  class ESC[4;38;5;81mScaleTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1082      OPTIONS = (
    1083          'activebackground', 'background', 'bigincrement', 'borderwidth',
    1084          'command', 'cursor', 'digits', 'font', 'foreground', 'from',
    1085          'highlightbackground', 'highlightcolor', 'highlightthickness',
    1086          'label', 'length', 'orient', 'relief',
    1087          'repeatdelay', 'repeatinterval',
    1088          'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',
    1089          'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',
    1090      )
    1091      default_orient = 'vertical'
    1092  
    1093      def create(self, **kwargs):
    1094          return tkinter.Scale(self.root, **kwargs)
    1095  
    1096      def test_configure_bigincrement(self):
    1097          widget = self.create()
    1098          self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
    1099  
    1100      def test_configure_digits(self):
    1101          widget = self.create()
    1102          self.checkIntegerParam(widget, 'digits', 5, 0)
    1103  
    1104      def test_configure_from(self):
    1105          widget = self.create()
    1106          conv = float if get_tk_patchlevel(self.root) >= (8, 6, 10) else float_round
    1107          self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv)
    1108  
    1109      def test_configure_label(self):
    1110          widget = self.create()
    1111          self.checkParam(widget, 'label', 'any string')
    1112          self.checkParam(widget, 'label', '')
    1113  
    1114      def test_configure_length(self):
    1115          widget = self.create()
    1116          self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
    1117  
    1118      def test_configure_resolution(self):
    1119          widget = self.create()
    1120          self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
    1121  
    1122      def test_configure_showvalue(self):
    1123          widget = self.create()
    1124          self.checkBooleanParam(widget, 'showvalue')
    1125  
    1126      def test_configure_sliderlength(self):
    1127          widget = self.create()
    1128          self.checkPixelsParam(widget, 'sliderlength',
    1129                                10, 11.2, 15.6, -3, '3m')
    1130  
    1131      def test_configure_sliderrelief(self):
    1132          widget = self.create()
    1133          self.checkReliefParam(widget, 'sliderrelief')
    1134  
    1135      def test_configure_tickinterval(self):
    1136          widget = self.create()
    1137          self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
    1138                               conv=float_round)
    1139          self.checkParam(widget, 'tickinterval', -2, expected=2,
    1140                          conv=float_round)
    1141  
    1142      def test_configure_to(self):
    1143          widget = self.create()
    1144          self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
    1145                               conv=float_round)
    1146  
    1147  
    1148  @add_standard_options(PixelSizeTests, StandardOptionsTests)
    1149  class ESC[4;38;5;81mScrollbarTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1150      OPTIONS = (
    1151          'activebackground', 'activerelief',
    1152          'background', 'borderwidth',
    1153          'command', 'cursor', 'elementborderwidth',
    1154          'highlightbackground', 'highlightcolor', 'highlightthickness',
    1155          'jump', 'orient', 'relief',
    1156          'repeatdelay', 'repeatinterval',
    1157          'takefocus', 'troughcolor', 'width',
    1158      )
    1159      _conv_pixels = round
    1160      _stringify = True
    1161      default_orient = 'vertical'
    1162  
    1163      def create(self, **kwargs):
    1164          return tkinter.Scrollbar(self.root, **kwargs)
    1165  
    1166      def test_configure_activerelief(self):
    1167          widget = self.create()
    1168          self.checkReliefParam(widget, 'activerelief')
    1169  
    1170      def test_configure_elementborderwidth(self):
    1171          widget = self.create()
    1172          self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
    1173  
    1174      def test_configure_orient(self):
    1175          widget = self.create()
    1176          self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
    1177                  errmsg='bad orientation "{}": must be vertical or horizontal')
    1178  
    1179      def test_activate(self):
    1180          sb = self.create()
    1181          for e in ('arrow1', 'slider', 'arrow2'):
    1182              sb.activate(e)
    1183              self.assertEqual(sb.activate(), e)
    1184          sb.activate('')
    1185          self.assertIsNone(sb.activate())
    1186          self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2')
    1187  
    1188      def test_set(self):
    1189          sb = self.create()
    1190          sb.set(0.2, 0.4)
    1191          self.assertEqual(sb.get(), (0.2, 0.4))
    1192          self.assertRaises(TclError, sb.set, 'abc', 'def')
    1193          self.assertRaises(TclError, sb.set, 0.6, 'def')
    1194          self.assertRaises(TclError, sb.set, 0.6, None)
    1195          self.assertRaises(TypeError, sb.set, 0.6)
    1196          self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8)
    1197  
    1198  
    1199  @add_standard_options(StandardOptionsTests)
    1200  class ESC[4;38;5;81mPanedWindowTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1201      OPTIONS = (
    1202          'background', 'borderwidth', 'cursor',
    1203          'handlepad', 'handlesize', 'height',
    1204          'opaqueresize', 'orient',
    1205          'proxybackground', 'proxyborderwidth', 'proxyrelief',
    1206          'relief',
    1207          'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',
    1208          'showhandle', 'width',
    1209      )
    1210      default_orient = 'horizontal'
    1211  
    1212      def create(self, **kwargs):
    1213          return tkinter.PanedWindow(self.root, **kwargs)
    1214  
    1215      def test_configure_handlepad(self):
    1216          widget = self.create()
    1217          self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
    1218  
    1219      def test_configure_handlesize(self):
    1220          widget = self.create()
    1221          self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
    1222                                conv=False)
    1223  
    1224      def test_configure_height(self):
    1225          widget = self.create()
    1226          self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
    1227                                conv=False)
    1228  
    1229      def test_configure_opaqueresize(self):
    1230          widget = self.create()
    1231          self.checkBooleanParam(widget, 'opaqueresize')
    1232  
    1233      @requires_tk(8, 6, 5)
    1234      def test_configure_proxybackground(self):
    1235          widget = self.create()
    1236          self.checkColorParam(widget, 'proxybackground')
    1237  
    1238      @requires_tk(8, 6, 5)
    1239      def test_configure_proxyborderwidth(self):
    1240          widget = self.create()
    1241          self.checkPixelsParam(widget, 'proxyborderwidth',
    1242                                0, 1.3, 2.9, 6, -2, '10p',
    1243                                conv=False)
    1244  
    1245      @requires_tk(8, 6, 5)
    1246      def test_configure_proxyrelief(self):
    1247          widget = self.create()
    1248          self.checkReliefParam(widget, 'proxyrelief')
    1249  
    1250      def test_configure_sashcursor(self):
    1251          widget = self.create()
    1252          self.checkCursorParam(widget, 'sashcursor')
    1253  
    1254      def test_configure_sashpad(self):
    1255          widget = self.create()
    1256          self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
    1257  
    1258      def test_configure_sashrelief(self):
    1259          widget = self.create()
    1260          self.checkReliefParam(widget, 'sashrelief')
    1261  
    1262      def test_configure_sashwidth(self):
    1263          widget = self.create()
    1264          self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
    1265                                conv=False)
    1266  
    1267      def test_configure_showhandle(self):
    1268          widget = self.create()
    1269          self.checkBooleanParam(widget, 'showhandle')
    1270  
    1271      def test_configure_width(self):
    1272          widget = self.create()
    1273          self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
    1274                                conv=False)
    1275  
    1276      def create2(self):
    1277          p = self.create()
    1278          b = tkinter.Button(p)
    1279          c = tkinter.Button(p)
    1280          p.add(b)
    1281          p.add(c)
    1282          return p, b, c
    1283  
    1284      def test_paneconfigure(self):
    1285          p, b, c = self.create2()
    1286          self.assertRaises(TypeError, p.paneconfigure)
    1287          d = p.paneconfigure(b)
    1288          self.assertIsInstance(d, dict)
    1289          for k, v in d.items():
    1290              self.assertEqual(len(v), 5)
    1291              self.assertEqual(v, p.paneconfigure(b, k))
    1292              self.assertEqual(v[4], p.panecget(b, k))
    1293  
    1294      def check_paneconfigure(self, p, b, name, value, expected):
    1295          if not self.wantobjects:
    1296              expected = str(expected)
    1297          p.paneconfigure(b, **{name: value})
    1298          self.assertEqual(p.paneconfigure(b, name)[4], expected)
    1299          self.assertEqual(p.panecget(b, name), expected)
    1300  
    1301      def check_paneconfigure_bad(self, p, b, name, msg):
    1302          with self.assertRaisesRegex(TclError, msg):
    1303              p.paneconfigure(b, **{name: 'badValue'})
    1304  
    1305      def test_paneconfigure_after(self):
    1306          p, b, c = self.create2()
    1307          self.check_paneconfigure(p, b, 'after', c, str(c))
    1308          self.check_paneconfigure_bad(p, b, 'after',
    1309                                       'bad window path name "badValue"')
    1310  
    1311      def test_paneconfigure_before(self):
    1312          p, b, c = self.create2()
    1313          self.check_paneconfigure(p, b, 'before', c, str(c))
    1314          self.check_paneconfigure_bad(p, b, 'before',
    1315                                       'bad window path name "badValue"')
    1316  
    1317      def test_paneconfigure_height(self):
    1318          p, b, c = self.create2()
    1319          self.check_paneconfigure(p, b, 'height', 10, 10)
    1320          self.check_paneconfigure_bad(p, b, 'height',
    1321                                       'bad screen distance "badValue"')
    1322  
    1323      def test_paneconfigure_hide(self):
    1324          p, b, c = self.create2()
    1325          self.check_paneconfigure(p, b, 'hide', False, 0)
    1326          self.check_paneconfigure_bad(p, b, 'hide',
    1327                                       'expected boolean value but got "badValue"')
    1328  
    1329      def test_paneconfigure_minsize(self):
    1330          p, b, c = self.create2()
    1331          self.check_paneconfigure(p, b, 'minsize', 10, 10)
    1332          self.check_paneconfigure_bad(p, b, 'minsize',
    1333                                       'bad screen distance "badValue"')
    1334  
    1335      def test_paneconfigure_padx(self):
    1336          p, b, c = self.create2()
    1337          self.check_paneconfigure(p, b, 'padx', 1.3, 1)
    1338          self.check_paneconfigure_bad(p, b, 'padx',
    1339                                       'bad screen distance "badValue"')
    1340  
    1341      def test_paneconfigure_pady(self):
    1342          p, b, c = self.create2()
    1343          self.check_paneconfigure(p, b, 'pady', 1.3, 1)
    1344          self.check_paneconfigure_bad(p, b, 'pady',
    1345                                       'bad screen distance "badValue"')
    1346  
    1347      def test_paneconfigure_sticky(self):
    1348          p, b, c = self.create2()
    1349          self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw')
    1350          self.check_paneconfigure_bad(p, b, 'sticky',
    1351                                       'bad stickyness value "badValue": must '
    1352                                       'be a string containing zero or more of '
    1353                                       'n, e, s, and w')
    1354  
    1355      def test_paneconfigure_stretch(self):
    1356          p, b, c = self.create2()
    1357          self.check_paneconfigure(p, b, 'stretch', 'alw', 'always')
    1358          self.check_paneconfigure_bad(p, b, 'stretch',
    1359                                       'bad stretch "badValue": must be '
    1360                                       'always, first, last, middle, or never')
    1361  
    1362      def test_paneconfigure_width(self):
    1363          p, b, c = self.create2()
    1364          self.check_paneconfigure(p, b, 'width', 10, 10)
    1365          self.check_paneconfigure_bad(p, b, 'width',
    1366                                       'bad screen distance "badValue"')
    1367  
    1368  
    1369  @add_standard_options(StandardOptionsTests)
    1370  class ESC[4;38;5;81mMenuTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1371      OPTIONS = (
    1372          'activebackground', 'activeborderwidth', 'activeforeground',
    1373          'background', 'borderwidth', 'cursor',
    1374          'disabledforeground', 'font', 'foreground',
    1375          'postcommand', 'relief', 'selectcolor', 'takefocus',
    1376          'tearoff', 'tearoffcommand', 'title', 'type',
    1377      )
    1378      _conv_pixels = False
    1379  
    1380      def create(self, **kwargs):
    1381          return tkinter.Menu(self.root, **kwargs)
    1382  
    1383      def test_indexcommand_none(self):
    1384          widget = self.create()
    1385          i = widget.index('none')
    1386          self.assertIsNone(i)
    1387  
    1388      def test_configure_postcommand(self):
    1389          widget = self.create()
    1390          self.checkCommandParam(widget, 'postcommand')
    1391  
    1392      def test_configure_tearoff(self):
    1393          widget = self.create()
    1394          self.checkBooleanParam(widget, 'tearoff')
    1395  
    1396      def test_configure_tearoffcommand(self):
    1397          widget = self.create()
    1398          self.checkCommandParam(widget, 'tearoffcommand')
    1399  
    1400      def test_configure_title(self):
    1401          widget = self.create()
    1402          self.checkParam(widget, 'title', 'any string')
    1403  
    1404      def test_configure_type(self):
    1405          widget = self.create()
    1406          opts = ('normal, tearoff, or menubar'
    1407                  if widget.info_patchlevel() < (8, 7) else
    1408                  'menubar, normal, or tearoff')
    1409          self.checkEnumParam(
    1410              widget, 'type',
    1411              'normal', 'tearoff', 'menubar',
    1412              errmsg='bad type "{}": must be ' + opts,
    1413              )
    1414  
    1415      def test_entryconfigure(self):
    1416          m1 = self.create()
    1417          m1.add_command(label='test')
    1418          self.assertRaises(TypeError, m1.entryconfigure)
    1419          with self.assertRaisesRegex(TclError, 'bad menu entry index "foo"'):
    1420              m1.entryconfigure('foo')
    1421          d = m1.entryconfigure(1)
    1422          self.assertIsInstance(d, dict)
    1423          for k, v in d.items():
    1424              self.assertIsInstance(k, str)
    1425              self.assertIsInstance(v, tuple)
    1426              self.assertEqual(len(v), 5)
    1427              self.assertEqual(v[0], k)
    1428              self.assertEqual(m1.entrycget(1, k), v[4])
    1429          m1.destroy()
    1430  
    1431      def test_entryconfigure_label(self):
    1432          m1 = self.create()
    1433          m1.add_command(label='test')
    1434          self.assertEqual(m1.entrycget(1, 'label'), 'test')
    1435          m1.entryconfigure(1, label='changed')
    1436          self.assertEqual(m1.entrycget(1, 'label'), 'changed')
    1437  
    1438      def test_entryconfigure_variable(self):
    1439          m1 = self.create()
    1440          v1 = tkinter.BooleanVar(self.root)
    1441          v2 = tkinter.BooleanVar(self.root)
    1442          m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False,
    1443                             label='Nonsense')
    1444          self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1))
    1445          m1.entryconfigure(1, variable=v2)
    1446          self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2))
    1447  
    1448  
    1449  @add_standard_options(PixelSizeTests, StandardOptionsTests)
    1450  class ESC[4;38;5;81mMessageTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1451      OPTIONS = (
    1452          'anchor', 'aspect', 'background', 'borderwidth',
    1453          'cursor', 'font', 'foreground',
    1454          'highlightbackground', 'highlightcolor', 'highlightthickness',
    1455          'justify', 'padx', 'pady', 'relief',
    1456          'takefocus', 'text', 'textvariable', 'width',
    1457      )
    1458      _conv_pad_pixels = False
    1459  
    1460      def create(self, **kwargs):
    1461          return tkinter.Message(self.root, **kwargs)
    1462  
    1463      def test_configure_aspect(self):
    1464          widget = self.create()
    1465          self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
    1466  
    1467  
    1468  class ESC[4;38;5;81mDefaultRootTest(ESC[4;38;5;149mAbstractDefaultRootTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1469  
    1470      def test_frame(self):
    1471          self._test_widget(tkinter.Frame)
    1472  
    1473      def test_label(self):
    1474          self._test_widget(tkinter.Label)
    1475  
    1476  
    1477  tests_gui = (
    1478          ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,
    1479          FrameTest, LabelFrameTest,LabelTest, ListboxTest,
    1480          MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,
    1481          PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,
    1482          SpinboxTest, TextTest, ToplevelTest, DefaultRootTest,
    1483  )
    1484  
    1485  if __name__ == '__main__':
    1486      unittest.main()