1  import unittest
       2  import re
       3  import tkinter
       4  from tkinter import TclError
       5  from test.support import requires
       6  
       7  from tkinter.test.support import pixels_conv
       8  from tkinter.test.widget_tests import AbstractWidgetTest
       9  
      10  requires('gui')
      11  
      12  
      13  class ESC[4;38;5;81mPackTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      14  
      15      test_keys = None
      16  
      17      def create2(self):
      18          pack = tkinter.Toplevel(self.root, name='pack')
      19          pack.wm_geometry('300x200+0+0')
      20          pack.wm_minsize(1, 1)
      21          a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red')
      22          b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue')
      23          c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green')
      24          d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow')
      25          return pack, a, b, c, d
      26  
      27      def test_pack_configure_after(self):
      28          pack, a, b, c, d = self.create2()
      29          with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
      30              a.pack_configure(after=b)
      31          with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
      32              a.pack_configure(after='.foo')
      33          a.pack_configure(side='top')
      34          b.pack_configure(side='top')
      35          c.pack_configure(side='top')
      36          d.pack_configure(side='top')
      37          self.assertEqual(pack.pack_slaves(), [a, b, c, d])
      38          a.pack_configure(after=b)
      39          self.assertEqual(pack.pack_slaves(), [b, a, c, d])
      40          a.pack_configure(after=a)
      41          self.assertEqual(pack.pack_slaves(), [b, a, c, d])
      42  
      43      def test_pack_configure_anchor(self):
      44          pack, a, b, c, d = self.create2()
      45          def check(anchor, geom):
      46              a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20,
      47                               expand=True, anchor=anchor)
      48              self.root.update()
      49              self.assertEqual(a.winfo_geometry(), geom)
      50          check('n', '30x70+135+20')
      51          check('ne', '30x70+260+20')
      52          check('e', '30x70+260+65')
      53          check('se', '30x70+260+110')
      54          check('s', '30x70+135+110')
      55          check('sw', '30x70+10+110')
      56          check('w', '30x70+10+65')
      57          check('nw', '30x70+10+20')
      58          check('center', '30x70+135+65')
      59  
      60      def test_pack_configure_before(self):
      61          pack, a, b, c, d = self.create2()
      62          with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
      63              a.pack_configure(before=b)
      64          with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
      65              a.pack_configure(before='.foo')
      66          a.pack_configure(side='top')
      67          b.pack_configure(side='top')
      68          c.pack_configure(side='top')
      69          d.pack_configure(side='top')
      70          self.assertEqual(pack.pack_slaves(), [a, b, c, d])
      71          a.pack_configure(before=d)
      72          self.assertEqual(pack.pack_slaves(), [b, c, a, d])
      73          a.pack_configure(before=a)
      74          self.assertEqual(pack.pack_slaves(), [b, c, a, d])
      75  
      76      def test_pack_configure_expand(self):
      77          pack, a, b, c, d = self.create2()
      78          def check(*geoms):
      79              self.root.update()
      80              self.assertEqual(a.winfo_geometry(), geoms[0])
      81              self.assertEqual(b.winfo_geometry(), geoms[1])
      82              self.assertEqual(c.winfo_geometry(), geoms[2])
      83              self.assertEqual(d.winfo_geometry(), geoms[3])
      84          a.pack_configure(side='left')
      85          b.pack_configure(side='top')
      86          c.pack_configure(side='right')
      87          d.pack_configure(side='bottom')
      88          check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170')
      89          a.pack_configure(side='left', expand='yes')
      90          b.pack_configure(side='top', expand='on')
      91          c.pack_configure(side='right', expand=True)
      92          d.pack_configure(side='bottom', expand=1)
      93          check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135')
      94          a.pack_configure(side='left', expand='yes', fill='both')
      95          b.pack_configure(side='top', expand='on', fill='both')
      96          c.pack_configure(side='right', expand=True, fill='both')
      97          d.pack_configure(side='bottom', expand=1, fill='both')
      98          check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100')
      99  
     100      def test_pack_configure_in(self):
     101          pack, a, b, c, d = self.create2()
     102          a.pack_configure(side='top')
     103          b.pack_configure(side='top')
     104          c.pack_configure(side='top')
     105          d.pack_configure(side='top')
     106          a.pack_configure(in_=pack)
     107          self.assertEqual(pack.pack_slaves(), [b, c, d, a])
     108          a.pack_configure(in_=c)
     109          self.assertEqual(pack.pack_slaves(), [b, c, d])
     110          self.assertEqual(c.pack_slaves(), [a])
     111          with self.assertRaisesRegex(
     112                  TclError, """can't pack "?%s"? inside itself""" % (a,)):
     113              a.pack_configure(in_=a)
     114          with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
     115              a.pack_configure(in_='.foo')
     116  
     117      def test_pack_configure_padx_ipadx_fill(self):
     118          pack, a, b, c, d = self.create2()
     119          def check(geom1, geom2, **kwargs):
     120              a.pack_forget()
     121              b.pack_forget()
     122              a.pack_configure(**kwargs)
     123              b.pack_configure(expand=True, fill='both')
     124              self.root.update()
     125              self.assertEqual(a.winfo_geometry(), geom1)
     126              self.assertEqual(b.winfo_geometry(), geom2)
     127          check('20x40+260+80', '240x200+0+0', side='right', padx=20)
     128          check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30))
     129          check('60x40+240+80', '240x200+0+0', side='right', ipadx=20)
     130          check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10)
     131          check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x')
     132          check('20x40+249+80', '240x200+0+0',
     133                side='right', padx=(9, 31), fill='x')
     134          check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x')
     135          check('30x40+260+80', '250x200+0+0',
     136                side='right', ipadx=5, padx=10, fill='x')
     137          check('30x40+255+80', '250x200+0+0',
     138                side='right', ipadx=5, padx=(5, 15), fill='x')
     139          check('20x40+140+0', '300x160+0+40', side='top', padx=20)
     140          check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40))
     141          check('60x40+120+0', '300x160+0+40', side='top', ipadx=20)
     142          check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10)
     143          check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15))
     144          check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x')
     145          check('260x40+25+0', '300x160+0+40',
     146                side='top', padx=(25, 15), fill='x')
     147          check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x')
     148          check('280x40+10+0', '300x160+0+40',
     149                side='top', ipadx=5, padx=10, fill='x')
     150          check('280x40+5+0', '300x160+0+40',
     151                side='top', ipadx=5, padx=(5, 15), fill='x')
     152          a.pack_configure(padx='1c')
     153          self.assertEqual(a.pack_info()['padx'],
     154                           self._str(pack.winfo_pixels('1c')))
     155          a.pack_configure(ipadx='1c')
     156          self.assertEqual(a.pack_info()['ipadx'],
     157                           self._str(pack.winfo_pixels('1c')))
     158  
     159      def test_pack_configure_pady_ipady_fill(self):
     160          pack, a, b, c, d = self.create2()
     161          def check(geom1, geom2, **kwargs):
     162              a.pack_forget()
     163              b.pack_forget()
     164              a.pack_configure(**kwargs)
     165              b.pack_configure(expand=True, fill='both')
     166              self.root.update()
     167              self.assertEqual(a.winfo_geometry(), geom1)
     168              self.assertEqual(b.winfo_geometry(), geom2)
     169          check('20x40+280+80', '280x200+0+0', side='right', pady=20)
     170          check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30))
     171          check('20x80+280+60', '280x200+0+0', side='right', ipady=20)
     172          check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10)
     173          check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x')
     174          check('20x40+280+69', '280x200+0+0',
     175                side='right', pady=(9, 31), fill='x')
     176          check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x')
     177          check('20x50+280+75', '280x200+0+0',
     178                side='right', ipady=5, pady=10, fill='x')
     179          check('20x50+280+70', '280x200+0+0',
     180                side='right', ipady=5, pady=(5, 15), fill='x')
     181          check('20x40+140+20', '300x120+0+80', side='top', pady=20)
     182          check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40))
     183          check('20x80+140+0', '300x120+0+80', side='top', ipady=20)
     184          check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10)
     185          check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15))
     186          check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x')
     187          check('300x40+0+25', '300x120+0+80',
     188                side='top', pady=(25, 15), fill='x')
     189          check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x')
     190          check('300x50+0+10', '300x130+0+70',
     191                side='top', ipady=5, pady=10, fill='x')
     192          check('300x50+0+5', '300x130+0+70',
     193                side='top', ipady=5, pady=(5, 15), fill='x')
     194          a.pack_configure(pady='1c')
     195          self.assertEqual(a.pack_info()['pady'],
     196                           self._str(pack.winfo_pixels('1c')))
     197          a.pack_configure(ipady='1c')
     198          self.assertEqual(a.pack_info()['ipady'],
     199                           self._str(pack.winfo_pixels('1c')))
     200  
     201      def test_pack_configure_side(self):
     202          pack, a, b, c, d = self.create2()
     203          def check(side, geom1, geom2):
     204              a.pack_configure(side=side)
     205              self.assertEqual(a.pack_info()['side'], side)
     206              b.pack_configure(expand=True, fill='both')
     207              self.root.update()
     208              self.assertEqual(a.winfo_geometry(), geom1)
     209              self.assertEqual(b.winfo_geometry(), geom2)
     210          check('top', '20x40+140+0', '300x160+0+40')
     211          check('bottom', '20x40+140+160', '300x160+0+0')
     212          check('left', '20x40+0+80', '280x200+20+0')
     213          check('right', '20x40+280+80', '280x200+0+0')
     214  
     215      def test_pack_forget(self):
     216          pack, a, b, c, d = self.create2()
     217          a.pack_configure()
     218          b.pack_configure()
     219          c.pack_configure()
     220          self.assertEqual(pack.pack_slaves(), [a, b, c])
     221          b.pack_forget()
     222          self.assertEqual(pack.pack_slaves(), [a, c])
     223          b.pack_forget()
     224          self.assertEqual(pack.pack_slaves(), [a, c])
     225          d.pack_forget()
     226  
     227      def test_pack_info(self):
     228          pack, a, b, c, d = self.create2()
     229          with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a):
     230              a.pack_info()
     231          a.pack_configure()
     232          b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x',
     233                           ipadx=5, padx=10, ipady=2, pady=(5, 15))
     234          info = a.pack_info()
     235          self.assertIsInstance(info, dict)
     236          self.assertEqual(info['anchor'], 'center')
     237          self.assertEqual(info['expand'], self._str(0))
     238          self.assertEqual(info['fill'], 'none')
     239          self.assertEqual(info['in'], pack)
     240          self.assertEqual(info['ipadx'], self._str(0))
     241          self.assertEqual(info['ipady'], self._str(0))
     242          self.assertEqual(info['padx'], self._str(0))
     243          self.assertEqual(info['pady'], self._str(0))
     244          self.assertEqual(info['side'], 'top')
     245          info = b.pack_info()
     246          self.assertIsInstance(info, dict)
     247          self.assertEqual(info['anchor'], 's')
     248          self.assertEqual(info['expand'], self._str(1))
     249          self.assertEqual(info['fill'], 'x')
     250          self.assertEqual(info['in'], a)
     251          self.assertEqual(info['ipadx'], self._str(5))
     252          self.assertEqual(info['ipady'], self._str(2))
     253          self.assertEqual(info['padx'], self._str(10))
     254          self.assertEqual(info['pady'], self._str((5, 15)))
     255          self.assertEqual(info['side'], 'right')
     256  
     257      def test_pack_propagate(self):
     258          pack, a, b, c, d = self.create2()
     259          pack.configure(width=300, height=200)
     260          a.pack_configure()
     261          pack.pack_propagate(False)
     262          self.root.update()
     263          self.assertEqual(pack.winfo_reqwidth(), 300)
     264          self.assertEqual(pack.winfo_reqheight(), 200)
     265          pack.pack_propagate(True)
     266          self.root.update()
     267          self.assertEqual(pack.winfo_reqwidth(), 20)
     268          self.assertEqual(pack.winfo_reqheight(), 40)
     269  
     270      def test_pack_slaves(self):
     271          pack, a, b, c, d = self.create2()
     272          self.assertEqual(pack.pack_slaves(), [])
     273          a.pack_configure()
     274          self.assertEqual(pack.pack_slaves(), [a])
     275          b.pack_configure()
     276          self.assertEqual(pack.pack_slaves(), [a, b])
     277  
     278  
     279  class ESC[4;38;5;81mPlaceTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     280  
     281      test_keys = None
     282  
     283      def create2(self):
     284          t = tkinter.Toplevel(self.root, width=300, height=200, bd=0)
     285          t.wm_geometry('300x200+0+0')
     286          f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised')
     287          f.place_configure(x=48, y=38)
     288          f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised')
     289          self.root.update()
     290          return t, f, f2
     291  
     292      def test_place_configure_in(self):
     293          t, f, f2 = self.create2()
     294          self.assertEqual(f2.winfo_manager(), '')
     295          with self.assertRaisesRegex(
     296                  TclError,
     297                  """can't place "?%s"? relative to itself"""
     298                   % re.escape(str(f2))):
     299              f2.place_configure(in_=f2)
     300          self.assertEqual(f2.winfo_manager(), '')
     301          with self.assertRaisesRegex(TclError, 'bad window path name'):
     302              f2.place_configure(in_='spam')
     303          f2.place_configure(in_=f)
     304          self.assertEqual(f2.winfo_manager(), 'place')
     305  
     306      def test_place_configure_x(self):
     307          t, f, f2 = self.create2()
     308          f2.place_configure(in_=f)
     309          self.assertEqual(f2.place_info()['x'], '0')
     310          self.root.update()
     311          self.assertEqual(f2.winfo_x(), 50)
     312          f2.place_configure(x=100)
     313          self.assertEqual(f2.place_info()['x'], '100')
     314          self.root.update()
     315          self.assertEqual(f2.winfo_x(), 150)
     316          f2.place_configure(x=-10, relx=1)
     317          self.assertEqual(f2.place_info()['x'], '-10')
     318          self.root.update()
     319          self.assertEqual(f2.winfo_x(), 190)
     320          with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'):
     321              f2.place_configure(in_=f, x='spam')
     322  
     323      def test_place_configure_y(self):
     324          t, f, f2 = self.create2()
     325          f2.place_configure(in_=f)
     326          self.assertEqual(f2.place_info()['y'], '0')
     327          self.root.update()
     328          self.assertEqual(f2.winfo_y(), 40)
     329          f2.place_configure(y=50)
     330          self.assertEqual(f2.place_info()['y'], '50')
     331          self.root.update()
     332          self.assertEqual(f2.winfo_y(), 90)
     333          f2.place_configure(y=-10, rely=1)
     334          self.assertEqual(f2.place_info()['y'], '-10')
     335          self.root.update()
     336          self.assertEqual(f2.winfo_y(), 110)
     337          with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'):
     338              f2.place_configure(in_=f, y='spam')
     339  
     340      def test_place_configure_relx(self):
     341          t, f, f2 = self.create2()
     342          f2.place_configure(in_=f)
     343          self.assertEqual(f2.place_info()['relx'], '0')
     344          self.root.update()
     345          self.assertEqual(f2.winfo_x(), 50)
     346          f2.place_configure(relx=0.5)
     347          self.assertEqual(f2.place_info()['relx'], '0.5')
     348          self.root.update()
     349          self.assertEqual(f2.winfo_x(), 125)
     350          f2.place_configure(relx=1)
     351          self.assertEqual(f2.place_info()['relx'], '1')
     352          self.root.update()
     353          self.assertEqual(f2.winfo_x(), 200)
     354          with self.assertRaisesRegex(TclError, 'expected floating-point number '
     355                                      'but got "spam"'):
     356              f2.place_configure(in_=f, relx='spam')
     357  
     358      def test_place_configure_rely(self):
     359          t, f, f2 = self.create2()
     360          f2.place_configure(in_=f)
     361          self.assertEqual(f2.place_info()['rely'], '0')
     362          self.root.update()
     363          self.assertEqual(f2.winfo_y(), 40)
     364          f2.place_configure(rely=0.5)
     365          self.assertEqual(f2.place_info()['rely'], '0.5')
     366          self.root.update()
     367          self.assertEqual(f2.winfo_y(), 80)
     368          f2.place_configure(rely=1)
     369          self.assertEqual(f2.place_info()['rely'], '1')
     370          self.root.update()
     371          self.assertEqual(f2.winfo_y(), 120)
     372          with self.assertRaisesRegex(TclError, 'expected floating-point number '
     373                                      'but got "spam"'):
     374              f2.place_configure(in_=f, rely='spam')
     375  
     376      def test_place_configure_anchor(self):
     377          f = tkinter.Frame(self.root)
     378          with self.assertRaisesRegex(TclError, 'bad anchor "j"'):
     379              f.place_configure(anchor='j')
     380          with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
     381              f.place_configure(anchor='')
     382          for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center':
     383              f.place_configure(anchor=value)
     384              self.assertEqual(f.place_info()['anchor'], value)
     385  
     386      def test_place_configure_width(self):
     387          t, f, f2 = self.create2()
     388          f2.place_configure(in_=f, width=120)
     389          self.root.update()
     390          self.assertEqual(f2.winfo_width(), 120)
     391          f2.place_configure(width='')
     392          self.root.update()
     393          self.assertEqual(f2.winfo_width(), 30)
     394          with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'):
     395              f2.place_configure(width='abcd')
     396  
     397      def test_place_configure_height(self):
     398          t, f, f2 = self.create2()
     399          f2.place_configure(in_=f, height=120)
     400          self.root.update()
     401          self.assertEqual(f2.winfo_height(), 120)
     402          f2.place_configure(height='')
     403          self.root.update()
     404          self.assertEqual(f2.winfo_height(), 60)
     405          with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'):
     406              f2.place_configure(height='abcd')
     407  
     408      def test_place_configure_relwidth(self):
     409          t, f, f2 = self.create2()
     410          f2.place_configure(in_=f, relwidth=0.5)
     411          self.root.update()
     412          self.assertEqual(f2.winfo_width(), 75)
     413          f2.place_configure(relwidth='')
     414          self.root.update()
     415          self.assertEqual(f2.winfo_width(), 30)
     416          with self.assertRaisesRegex(TclError, 'expected floating-point number '
     417                                      'but got "abcd"'):
     418              f2.place_configure(relwidth='abcd')
     419  
     420      def test_place_configure_relheight(self):
     421          t, f, f2 = self.create2()
     422          f2.place_configure(in_=f, relheight=0.5)
     423          self.root.update()
     424          self.assertEqual(f2.winfo_height(), 40)
     425          f2.place_configure(relheight='')
     426          self.root.update()
     427          self.assertEqual(f2.winfo_height(), 60)
     428          with self.assertRaisesRegex(TclError, 'expected floating-point number '
     429                                      'but got "abcd"'):
     430              f2.place_configure(relheight='abcd')
     431  
     432      def test_place_configure_bordermode(self):
     433          f = tkinter.Frame(self.root)
     434          with self.assertRaisesRegex(TclError, 'bad bordermode "j"'):
     435              f.place_configure(bordermode='j')
     436          with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'):
     437              f.place_configure(bordermode='')
     438          for value in 'inside', 'outside', 'ignore':
     439              f.place_configure(bordermode=value)
     440              self.assertEqual(f.place_info()['bordermode'], value)
     441  
     442      def test_place_forget(self):
     443          foo = tkinter.Frame(self.root)
     444          foo.place_configure(width=50, height=50)
     445          self.root.update()
     446          foo.place_forget()
     447          self.root.update()
     448          self.assertFalse(foo.winfo_ismapped())
     449          with self.assertRaises(TypeError):
     450              foo.place_forget(0)
     451  
     452      def test_place_info(self):
     453          t, f, f2 = self.create2()
     454          f2.place_configure(in_=f, x=1, y=2, width=3, height=4,
     455                             relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4,
     456                             anchor='se', bordermode='outside')
     457          info = f2.place_info()
     458          self.assertIsInstance(info, dict)
     459          self.assertEqual(info['x'], '1')
     460          self.assertEqual(info['y'], '2')
     461          self.assertEqual(info['width'], '3')
     462          self.assertEqual(info['height'], '4')
     463          self.assertEqual(info['relx'], '0.1')
     464          self.assertEqual(info['rely'], '0.2')
     465          self.assertEqual(info['relwidth'], '0.3')
     466          self.assertEqual(info['relheight'], '0.4')
     467          self.assertEqual(info['anchor'], 'se')
     468          self.assertEqual(info['bordermode'], 'outside')
     469          self.assertEqual(info['x'], '1')
     470          self.assertEqual(info['x'], '1')
     471          with self.assertRaises(TypeError):
     472              f2.place_info(0)
     473  
     474      def test_place_slaves(self):
     475          foo = tkinter.Frame(self.root)
     476          bar = tkinter.Frame(self.root)
     477          self.assertEqual(foo.place_slaves(), [])
     478          bar.place_configure(in_=foo)
     479          self.assertEqual(foo.place_slaves(), [bar])
     480          with self.assertRaises(TypeError):
     481              foo.place_slaves(0)
     482  
     483  
     484  class ESC[4;38;5;81mGridTest(ESC[4;38;5;149mAbstractWidgetTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     485  
     486      test_keys = None
     487  
     488      def tearDown(self):
     489          cols, rows = self.root.grid_size()
     490          for i in range(cols + 1):
     491              self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='')
     492          for i in range(rows + 1):
     493              self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='')
     494          self.root.grid_propagate(1)
     495          self.root.grid_anchor('nw')
     496          super().tearDown()
     497  
     498      def test_grid_configure(self):
     499          b = tkinter.Button(self.root)
     500          self.assertEqual(b.grid_info(), {})
     501          b.grid_configure()
     502          self.assertEqual(b.grid_info()['in'], self.root)
     503          self.assertEqual(b.grid_info()['column'], self._str(0))
     504          self.assertEqual(b.grid_info()['row'], self._str(0))
     505          b.grid_configure({'column': 1}, row=2)
     506          self.assertEqual(b.grid_info()['column'], self._str(1))
     507          self.assertEqual(b.grid_info()['row'], self._str(2))
     508  
     509      def test_grid_configure_column(self):
     510          b = tkinter.Button(self.root)
     511          with self.assertRaisesRegex(TclError, 'bad column value "-1": '
     512                                      'must be a non-negative integer'):
     513              b.grid_configure(column=-1)
     514          b.grid_configure(column=2)
     515          self.assertEqual(b.grid_info()['column'], self._str(2))
     516  
     517      def test_grid_configure_columnspan(self):
     518          b = tkinter.Button(self.root)
     519          with self.assertRaisesRegex(TclError, 'bad columnspan value "0": '
     520                                      'must be a positive integer'):
     521              b.grid_configure(columnspan=0)
     522          b.grid_configure(columnspan=2)
     523          self.assertEqual(b.grid_info()['columnspan'], self._str(2))
     524  
     525      def test_grid_configure_in(self):
     526          f = tkinter.Frame(self.root)
     527          b = tkinter.Button(self.root)
     528          self.assertEqual(b.grid_info(), {})
     529          b.grid_configure()
     530          self.assertEqual(b.grid_info()['in'], self.root)
     531          b.grid_configure(in_=f)
     532          self.assertEqual(b.grid_info()['in'], f)
     533          b.grid_configure({'in': self.root})
     534          self.assertEqual(b.grid_info()['in'], self.root)
     535  
     536      def test_grid_configure_ipadx(self):
     537          b = tkinter.Button(self.root)
     538          with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": '
     539                                      'must be positive screen distance'):
     540              b.grid_configure(ipadx=-1)
     541          b.grid_configure(ipadx=1)
     542          self.assertEqual(b.grid_info()['ipadx'], self._str(1))
     543          b.grid_configure(ipadx='.5c')
     544          self.assertEqual(b.grid_info()['ipadx'],
     545                           self._str(round(pixels_conv('.5c') * self.scaling)))
     546  
     547      def test_grid_configure_ipady(self):
     548          b = tkinter.Button(self.root)
     549          with self.assertRaisesRegex(TclError, 'bad ipady value "-1": '
     550                                      'must be positive screen distance'):
     551              b.grid_configure(ipady=-1)
     552          b.grid_configure(ipady=1)
     553          self.assertEqual(b.grid_info()['ipady'], self._str(1))
     554          b.grid_configure(ipady='.5c')
     555          self.assertEqual(b.grid_info()['ipady'],
     556                           self._str(round(pixels_conv('.5c') * self.scaling)))
     557  
     558      def test_grid_configure_padx(self):
     559          b = tkinter.Button(self.root)
     560          with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
     561                                      'must be positive screen distance'):
     562              b.grid_configure(padx=-1)
     563          b.grid_configure(padx=1)
     564          self.assertEqual(b.grid_info()['padx'], self._str(1))
     565          b.grid_configure(padx=(10, 5))
     566          self.assertEqual(b.grid_info()['padx'], self._str((10, 5)))
     567          b.grid_configure(padx='.5c')
     568          self.assertEqual(b.grid_info()['padx'],
     569                           self._str(round(pixels_conv('.5c') * self.scaling)))
     570  
     571      def test_grid_configure_pady(self):
     572          b = tkinter.Button(self.root)
     573          with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
     574                                      'must be positive screen distance'):
     575              b.grid_configure(pady=-1)
     576          b.grid_configure(pady=1)
     577          self.assertEqual(b.grid_info()['pady'], self._str(1))
     578          b.grid_configure(pady=(10, 5))
     579          self.assertEqual(b.grid_info()['pady'], self._str((10, 5)))
     580          b.grid_configure(pady='.5c')
     581          self.assertEqual(b.grid_info()['pady'],
     582                           self._str(round(pixels_conv('.5c') * self.scaling)))
     583  
     584      def test_grid_configure_row(self):
     585          b = tkinter.Button(self.root)
     586          with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": '
     587                                      'must be a non-negative integer'):
     588              b.grid_configure(row=-1)
     589          b.grid_configure(row=2)
     590          self.assertEqual(b.grid_info()['row'], self._str(2))
     591  
     592      def test_grid_configure_rownspan(self):
     593          b = tkinter.Button(self.root)
     594          with self.assertRaisesRegex(TclError, 'bad rowspan value "0": '
     595                                      'must be a positive integer'):
     596              b.grid_configure(rowspan=0)
     597          b.grid_configure(rowspan=2)
     598          self.assertEqual(b.grid_info()['rowspan'], self._str(2))
     599  
     600      def test_grid_configure_sticky(self):
     601          f = tkinter.Frame(self.root, bg='red')
     602          with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'):
     603              f.grid_configure(sticky='glue')
     604          f.grid_configure(sticky='ne')
     605          self.assertEqual(f.grid_info()['sticky'], 'ne')
     606          f.grid_configure(sticky='n,s,e,w')
     607          self.assertEqual(f.grid_info()['sticky'], 'nesw')
     608  
     609      def test_grid_columnconfigure(self):
     610          with self.assertRaises(TypeError):
     611              self.root.grid_columnconfigure()
     612          self.assertEqual(self.root.grid_columnconfigure(0),
     613                           {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
     614          with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
     615              self.root.grid_columnconfigure(0, 'foo')
     616          self.root.grid_columnconfigure((0, 3), weight=2)
     617          with self.assertRaisesRegex(TclError,
     618                                      'must specify a single element on retrieval'):
     619              self.root.grid_columnconfigure((0, 3))
     620          b = tkinter.Button(self.root)
     621          b.grid_configure(column=0, row=0)
     622          self.root.grid_columnconfigure('all', weight=3)
     623          with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
     624              self.root.grid_columnconfigure('all')
     625          self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
     626          self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2)
     627          self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0)
     628          self.root.grid_columnconfigure(b, weight=4)
     629          self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4)
     630  
     631      def test_grid_columnconfigure_minsize(self):
     632          with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
     633              self.root.grid_columnconfigure(0, minsize='foo')
     634          self.root.grid_columnconfigure(0, minsize=10)
     635          self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10)
     636          self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10)
     637  
     638      def test_grid_columnconfigure_weight(self):
     639          with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
     640              self.root.grid_columnconfigure(0, weight='bad')
     641          with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
     642                                      'should be non-negative'):
     643              self.root.grid_columnconfigure(0, weight=-3)
     644          self.root.grid_columnconfigure(0, weight=3)
     645          self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
     646          self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3)
     647  
     648      def test_grid_columnconfigure_pad(self):
     649          with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
     650              self.root.grid_columnconfigure(0, pad='foo')
     651          with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
     652                                      'should be non-negative'):
     653              self.root.grid_columnconfigure(0, pad=-3)
     654          self.root.grid_columnconfigure(0, pad=3)
     655          self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3)
     656          self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3)
     657  
     658      def test_grid_columnconfigure_uniform(self):
     659          self.root.grid_columnconfigure(0, uniform='foo')
     660          self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo')
     661          self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo')
     662  
     663      def test_grid_rowconfigure(self):
     664          with self.assertRaises(TypeError):
     665              self.root.grid_rowconfigure()
     666          self.assertEqual(self.root.grid_rowconfigure(0),
     667                           {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
     668          with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
     669              self.root.grid_rowconfigure(0, 'foo')
     670          self.root.grid_rowconfigure((0, 3), weight=2)
     671          with self.assertRaisesRegex(TclError,
     672                                      'must specify a single element on retrieval'):
     673              self.root.grid_rowconfigure((0, 3))
     674          b = tkinter.Button(self.root)
     675          b.grid_configure(column=0, row=0)
     676          self.root.grid_rowconfigure('all', weight=3)
     677          with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
     678              self.root.grid_rowconfigure('all')
     679          self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
     680          self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2)
     681          self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0)
     682          self.root.grid_rowconfigure(b, weight=4)
     683          self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4)
     684  
     685      def test_grid_rowconfigure_minsize(self):
     686          with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
     687              self.root.grid_rowconfigure(0, minsize='foo')
     688          self.root.grid_rowconfigure(0, minsize=10)
     689          self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10)
     690          self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10)
     691  
     692      def test_grid_rowconfigure_weight(self):
     693          with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
     694              self.root.grid_rowconfigure(0, weight='bad')
     695          with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
     696                                      'should be non-negative'):
     697              self.root.grid_rowconfigure(0, weight=-3)
     698          self.root.grid_rowconfigure(0, weight=3)
     699          self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
     700          self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3)
     701  
     702      def test_grid_rowconfigure_pad(self):
     703          with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
     704              self.root.grid_rowconfigure(0, pad='foo')
     705          with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
     706                                      'should be non-negative'):
     707              self.root.grid_rowconfigure(0, pad=-3)
     708          self.root.grid_rowconfigure(0, pad=3)
     709          self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3)
     710          self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3)
     711  
     712      def test_grid_rowconfigure_uniform(self):
     713          self.root.grid_rowconfigure(0, uniform='foo')
     714          self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo')
     715          self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo')
     716  
     717      def test_grid_forget(self):
     718          b = tkinter.Button(self.root)
     719          c = tkinter.Button(self.root)
     720          b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
     721                           padx=3, pady=4, sticky='ns')
     722          self.assertEqual(self.root.grid_slaves(), [b])
     723          b.grid_forget()
     724          c.grid_forget()
     725          self.assertEqual(self.root.grid_slaves(), [])
     726          self.assertEqual(b.grid_info(), {})
     727          b.grid_configure(row=0, column=0)
     728          info = b.grid_info()
     729          self.assertEqual(info['row'], self._str(0))
     730          self.assertEqual(info['column'], self._str(0))
     731          self.assertEqual(info['rowspan'], self._str(1))
     732          self.assertEqual(info['columnspan'], self._str(1))
     733          self.assertEqual(info['padx'], self._str(0))
     734          self.assertEqual(info['pady'], self._str(0))
     735          self.assertEqual(info['sticky'], '')
     736  
     737      def test_grid_remove(self):
     738          b = tkinter.Button(self.root)
     739          c = tkinter.Button(self.root)
     740          b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
     741                           padx=3, pady=4, sticky='ns')
     742          self.assertEqual(self.root.grid_slaves(), [b])
     743          b.grid_remove()
     744          c.grid_remove()
     745          self.assertEqual(self.root.grid_slaves(), [])
     746          self.assertEqual(b.grid_info(), {})
     747          b.grid_configure(row=0, column=0)
     748          info = b.grid_info()
     749          self.assertEqual(info['row'], self._str(0))
     750          self.assertEqual(info['column'], self._str(0))
     751          self.assertEqual(info['rowspan'], self._str(2))
     752          self.assertEqual(info['columnspan'], self._str(2))
     753          self.assertEqual(info['padx'], self._str(3))
     754          self.assertEqual(info['pady'], self._str(4))
     755          self.assertEqual(info['sticky'], 'ns')
     756  
     757      def test_grid_info(self):
     758          b = tkinter.Button(self.root)
     759          self.assertEqual(b.grid_info(), {})
     760          b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
     761                           padx=3, pady=4, sticky='ns')
     762          info = b.grid_info()
     763          self.assertIsInstance(info, dict)
     764          self.assertEqual(info['in'], self.root)
     765          self.assertEqual(info['row'], self._str(2))
     766          self.assertEqual(info['column'], self._str(2))
     767          self.assertEqual(info['rowspan'], self._str(2))
     768          self.assertEqual(info['columnspan'], self._str(2))
     769          self.assertEqual(info['padx'], self._str(3))
     770          self.assertEqual(info['pady'], self._str(4))
     771          self.assertEqual(info['sticky'], 'ns')
     772  
     773      def test_grid_anchor(self):
     774          with self.assertRaisesRegex(TclError, 'bad anchor "x"'):
     775              self.root.grid_anchor('x')
     776          with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
     777              self.root.grid_anchor('')
     778          with self.assertRaises(TypeError):
     779              self.root.grid_anchor('se', 'nw')
     780          self.root.grid_anchor('se')
     781          self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se')
     782  
     783      def test_grid_bbox(self):
     784          self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0))
     785          self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0))
     786          self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0))
     787          with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
     788              self.root.grid_bbox('x', 0)
     789          with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
     790              self.root.grid_bbox(0, 'x')
     791          with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
     792              self.root.grid_bbox(0, 0, 'x', 0)
     793          with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
     794              self.root.grid_bbox(0, 0, 0, 'x')
     795          with self.assertRaises(TypeError):
     796              self.root.grid_bbox(0, 0, 0, 0, 0)
     797          t = self.root
     798          # de-maximize
     799          t.wm_geometry('1x1+0+0')
     800          t.wm_geometry('')
     801          f1 = tkinter.Frame(t, width=75, height=75, bg='red')
     802          f2 = tkinter.Frame(t, width=90, height=90, bg='blue')
     803          f1.grid_configure(row=0, column=0)
     804          f2.grid_configure(row=1, column=1)
     805          self.root.update()
     806          self.assertEqual(t.grid_bbox(), (0, 0, 165, 165))
     807          self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75))
     808          self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165))
     809          self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90))
     810          self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165))
     811          self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0))
     812          self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0))
     813  
     814      def test_grid_location(self):
     815          with self.assertRaises(TypeError):
     816              self.root.grid_location()
     817          with self.assertRaises(TypeError):
     818              self.root.grid_location(0)
     819          with self.assertRaises(TypeError):
     820              self.root.grid_location(0, 0, 0)
     821          with self.assertRaisesRegex(TclError, 'bad screen distance "x"'):
     822              self.root.grid_location('x', 'y')
     823          with self.assertRaisesRegex(TclError, 'bad screen distance "y"'):
     824              self.root.grid_location('1c', 'y')
     825          t = self.root
     826          # de-maximize
     827          t.wm_geometry('1x1+0+0')
     828          t.wm_geometry('')
     829          f = tkinter.Frame(t, width=200, height=100,
     830                            highlightthickness=0, bg='red')
     831          self.assertEqual(f.grid_location(10, 10), (-1, -1))
     832          f.grid_configure()
     833          self.root.update()
     834          self.assertEqual(t.grid_location(-10, -10), (-1, -1))
     835          self.assertEqual(t.grid_location(-10, 0), (-1, 0))
     836          self.assertEqual(t.grid_location(-1, 0), (-1, 0))
     837          self.assertEqual(t.grid_location(0, -10), (0, -1))
     838          self.assertEqual(t.grid_location(0, -1), (0, -1))
     839          self.assertEqual(t.grid_location(0, 0), (0, 0))
     840          self.assertEqual(t.grid_location(200, 0), (0, 0))
     841          self.assertEqual(t.grid_location(201, 0), (1, 0))
     842          self.assertEqual(t.grid_location(0, 100), (0, 0))
     843          self.assertEqual(t.grid_location(0, 101), (0, 1))
     844          self.assertEqual(t.grid_location(201, 101), (1, 1))
     845  
     846      def test_grid_propagate(self):
     847          self.assertEqual(self.root.grid_propagate(), True)
     848          with self.assertRaises(TypeError):
     849              self.root.grid_propagate(False, False)
     850          self.root.grid_propagate(False)
     851          self.assertFalse(self.root.grid_propagate())
     852          f = tkinter.Frame(self.root, width=100, height=100, bg='red')
     853          f.grid_configure(row=0, column=0)
     854          self.root.update()
     855          self.assertEqual(f.winfo_width(), 100)
     856          self.assertEqual(f.winfo_height(), 100)
     857          f.grid_propagate(False)
     858          g = tkinter.Frame(self.root, width=75, height=85, bg='green')
     859          g.grid_configure(in_=f, row=0, column=0)
     860          self.root.update()
     861          self.assertEqual(f.winfo_width(), 100)
     862          self.assertEqual(f.winfo_height(), 100)
     863          f.grid_propagate(True)
     864          self.root.update()
     865          self.assertEqual(f.winfo_width(), 75)
     866          self.assertEqual(f.winfo_height(), 85)
     867  
     868      def test_grid_size(self):
     869          with self.assertRaises(TypeError):
     870              self.root.grid_size(0)
     871          self.assertEqual(self.root.grid_size(), (0, 0))
     872          f = tkinter.Scale(self.root)
     873          f.grid_configure(row=0, column=0)
     874          self.assertEqual(self.root.grid_size(), (1, 1))
     875          f.grid_configure(row=4, column=5)
     876          self.assertEqual(self.root.grid_size(), (6, 5))
     877  
     878      def test_grid_slaves(self):
     879          self.assertEqual(self.root.grid_slaves(), [])
     880          a = tkinter.Label(self.root)
     881          a.grid_configure(row=0, column=1)
     882          b = tkinter.Label(self.root)
     883          b.grid_configure(row=1, column=0)
     884          c = tkinter.Label(self.root)
     885          c.grid_configure(row=1, column=1)
     886          d = tkinter.Label(self.root)
     887          d.grid_configure(row=1, column=1)
     888          self.assertEqual(self.root.grid_slaves(), [d, c, b, a])
     889          self.assertEqual(self.root.grid_slaves(row=0), [a])
     890          self.assertEqual(self.root.grid_slaves(row=1), [d, c, b])
     891          self.assertEqual(self.root.grid_slaves(column=0), [b])
     892          self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])
     893          self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])
     894  
     895  
     896  tests_gui = (
     897      PackTest, PlaceTest, GridTest,
     898  )
     899  
     900  if __name__ == '__main__':
     901      unittest.main()