diff options
Diffstat (limited to 'Lib/tkinter/test')
| -rw-r--r-- | Lib/tkinter/test/runtktests.py | 1 | ||||
| -rw-r--r-- | Lib/tkinter/test/support.py | 124 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_font.py | 91 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_geometry_managers.py | 900 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_images.py | 327 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_misc.py | 7 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_text.py | 9 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_variables.py | 40 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_tkinter/test_widgets.py | 310 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_ttk/test_extensions.py | 105 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_ttk/test_functions.py | 81 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_ttk/test_style.py | 10 | ||||
| -rw-r--r-- | Lib/tkinter/test/test_ttk/test_widgets.py | 177 | ||||
| -rw-r--r-- | Lib/tkinter/test/widget_tests.py | 54 |
14 files changed, 1876 insertions, 360 deletions
diff --git a/Lib/tkinter/test/runtktests.py b/Lib/tkinter/test/runtktests.py index e21eca4..ccb3755 100644 --- a/Lib/tkinter/test/runtktests.py +++ b/Lib/tkinter/test/runtktests.py @@ -68,5 +68,4 @@ def get_tests(text=True, gui=True, packages=None): yield test if __name__ == "__main__": - test.support.use_resources = ['gui'] test.support.run_unittest(*get_tests()) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py index fcd9ffc..dd155fa 100644 --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -1,74 +1,45 @@ -import sys +import re import tkinter import unittest -_tk_unavailable = None - -def check_tk_availability(): - """Check that Tk is installed and available.""" - global _tk_unavailable - - if _tk_unavailable is None: - _tk_unavailable = False - if sys.platform == 'darwin': - # The Aqua Tk implementations on OS X can abort the process if - # being called in an environment where a window server connection - # cannot be made, for instance when invoked by a buildbot or ssh - # process not running under the same user id as the current console - # user. To avoid that, raise an exception if the window manager - # connection is not available. - from ctypes import cdll, c_int, pointer, Structure - from ctypes.util import find_library - - app_services = cdll.LoadLibrary(find_library("ApplicationServices")) - - if app_services.CGMainDisplayID() == 0: - _tk_unavailable = "cannot run without OS X window manager" - else: - class ProcessSerialNumber(Structure): - _fields_ = [("highLongOfPSN", c_int), - ("lowLongOfPSN", c_int)] - psn = ProcessSerialNumber() - psn_p = pointer(psn) - if ( (app_services.GetCurrentProcess(psn_p) < 0) or - (app_services.SetFrontProcess(psn_p) < 0) ): - _tk_unavailable = "cannot run without OS X gui process" - else: # not OS X - import tkinter - try: - tkinter.Button() - except tkinter.TclError as msg: - # assuming tk is not available - _tk_unavailable = "tk not available: %s" % msg - - if _tk_unavailable: - raise unittest.SkipTest(_tk_unavailable) - return - -def get_tk_root(): - check_tk_availability() # raise exception if tk unavailable - try: - root = tkinter._default_root - except AttributeError: - # it is possible to disable default root in Tkinter, although - # I haven't seen people doing it (but apparently someone did it - # here). - root = None - - if root is None: - # create a new master only if there isn't one already - root = tkinter.Tk() - - return root - -def root_deiconify(): - root = get_tk_root() - root.deiconify() - -def root_withdraw(): - root = get_tk_root() - root.withdraw() - +class AbstractTkTest: + + @classmethod + def setUpClass(cls): + cls._old_support_default_root = tkinter._support_default_root + destroy_default_root() + tkinter.NoDefaultRoot() + cls.root = tkinter.Tk() + cls.wantobjects = cls.root.wantobjects() + # De-maximize main window. + # Some window managers can maximize new windows. + cls.root.wm_state('normal') + try: + cls.root.wm_attributes('-zoomed', False) + except tkinter.TclError: + pass + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + cls.root.destroy() + del cls.root + tkinter._default_root = None + tkinter._support_default_root = cls._old_support_default_root + + def setUp(self): + self.root.deiconify() + + def tearDown(self): + for w in self.root.winfo_children(): + w.destroy() + self.root.withdraw() + +def destroy_default_root(): + if getattr(tkinter, '_default_root', None): + tkinter._default_root.update_idletasks() + tkinter._default_root.destroy() + tkinter._default_root = None def simulate_mouse_click(widget, x, y): """Generate proper events to click at the x, y position (tries to act @@ -91,14 +62,15 @@ def get_tk_patchlevel(): global _tk_patchlevel if _tk_patchlevel is None: tcl = tkinter.Tcl() - patchlevel = [] - for x in tcl.call('info', 'patchlevel').split('.'): - try: - x = int(x, 10) - except ValueError: - x = -1 - patchlevel.append(x) - _tk_patchlevel = tuple(patchlevel) + patchlevel = tcl.call('info', 'patchlevel') + m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel) + major, minor, releaselevel, serial = m.groups() + major, minor, serial = int(major), int(minor), int(serial) + releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel] + if releaselevel == 'final': + _tk_patchlevel = major, minor, serial, releaselevel, 0 + else: + _tk_patchlevel = major, minor, 0, releaselevel, serial return _tk_patchlevel units = { diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py index dfd630b..c094c61 100644 --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -2,31 +2,94 @@ import unittest import tkinter from tkinter import font from test.support import requires, run_unittest -import tkinter.test.support as support +from tkinter.test.support import AbstractTkTest requires('gui') -class FontTest(unittest.TestCase): +fontname = "TkDefaultFont" - def setUp(self): - support.root_deiconify() +class FontTest(AbstractTkTest, unittest.TestCase): - def tearDown(self): - support.root_withdraw() - - def test_font_eq(self): - fontname = "TkDefaultFont" + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) try: - f = font.Font(name=fontname, exists=True) - except tkinter._tkinter.TclError: - f = font.Font(name=fontname, exists=False) - font1 = font.nametofont(fontname) - font2 = font.nametofont(fontname) + cls.font = font.Font(root=cls.root, name=fontname, exists=True) + except tkinter.TclError: + cls.font = font.Font(root=cls.root, name=fontname, exists=False) + + def test_configure(self): + options = self.font.configure() + self.assertGreaterEqual(set(options), + {'family', 'size', 'weight', 'slant', 'underline', 'overstrike'}) + for key in options: + self.assertEqual(self.font.cget(key), options[key]) + self.assertEqual(self.font[key], options[key]) + for key in 'family', 'weight', 'slant': + self.assertIsInstance(options[key], str) + self.assertIsInstance(self.font.cget(key), str) + self.assertIsInstance(self.font[key], str) + sizetype = int if self.wantobjects else str + for key in 'size', 'underline', 'overstrike': + self.assertIsInstance(options[key], sizetype) + self.assertIsInstance(self.font.cget(key), sizetype) + self.assertIsInstance(self.font[key], sizetype) + + def test_actual(self): + options = self.font.actual() + self.assertGreaterEqual(set(options), + {'family', 'size', 'weight', 'slant', 'underline', 'overstrike'}) + for key in options: + self.assertEqual(self.font.actual(key), options[key]) + for key in 'family', 'weight', 'slant': + self.assertIsInstance(options[key], str) + self.assertIsInstance(self.font.actual(key), str) + sizetype = int if self.wantobjects else str + for key in 'size', 'underline', 'overstrike': + self.assertIsInstance(options[key], sizetype) + self.assertIsInstance(self.font.actual(key), sizetype) + + def test_name(self): + self.assertEqual(self.font.name, fontname) + self.assertEqual(str(self.font), fontname) + + def test_eq(self): + font1 = font.Font(root=self.root, name=fontname, exists=True) + font2 = font.Font(root=self.root, name=fontname, exists=True) self.assertIsNot(font1, font2) self.assertEqual(font1, font2) self.assertNotEqual(font1, font1.copy()) self.assertNotEqual(font1, 0) + def test_measure(self): + self.assertIsInstance(self.font.measure('abc'), int) + + def test_metrics(self): + metrics = self.font.metrics() + self.assertGreaterEqual(set(metrics), + {'ascent', 'descent', 'linespace', 'fixed'}) + for key in metrics: + self.assertEqual(self.font.metrics(key), metrics[key]) + self.assertIsInstance(metrics[key], int) + self.assertIsInstance(self.font.metrics(key), int) + + def test_families(self): + families = font.families(self.root) + self.assertIsInstance(families, tuple) + self.assertTrue(families) + for family in families: + self.assertIsInstance(family, str) + self.assertTrue(family) + + def test_names(self): + names = font.names(self.root) + self.assertIsInstance(names, tuple) + self.assertTrue(names) + for name in names: + self.assertIsInstance(name, str) + self.assertTrue(name) + self.assertIn(fontname, names) + tests_gui = (FontTest, ) if __name__ == "__main__": diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py new file mode 100644 index 0000000..e42b1be --- /dev/null +++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py @@ -0,0 +1,900 @@ +import unittest +import re +import tkinter +from tkinter import TclError +from test.support import requires + +from tkinter.test.support import pixels_conv, tcl_version, requires_tcl +from tkinter.test.widget_tests import AbstractWidgetTest + +requires('gui') + + +class PackTest(AbstractWidgetTest, unittest.TestCase): + + def create2(self): + pack = tkinter.Toplevel(self.root, name='pack') + pack.wm_geometry('300x200+0+0') + pack.wm_minsize(1, 1) + a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red') + b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue') + c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green') + d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow') + return pack, a, b, c, d + + def test_pack_configure_after(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(after=b) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(after='.foo') + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + self.assertEqual(pack.pack_slaves(), [a, b, c, d]) + a.pack_configure(after=b) + self.assertEqual(pack.pack_slaves(), [b, a, c, d]) + a.pack_configure(after=a) + self.assertEqual(pack.pack_slaves(), [b, a, c, d]) + + def test_pack_configure_anchor(self): + pack, a, b, c, d = self.create2() + def check(anchor, geom): + a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20, + expand=True, anchor=anchor) + self.root.update() + self.assertEqual(a.winfo_geometry(), geom) + check('n', '30x70+135+20') + check('ne', '30x70+260+20') + check('e', '30x70+260+65') + check('se', '30x70+260+110') + check('s', '30x70+135+110') + check('sw', '30x70+10+110') + check('w', '30x70+10+65') + check('nw', '30x70+10+20') + check('center', '30x70+135+65') + + def test_pack_configure_before(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(before=b) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(before='.foo') + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + self.assertEqual(pack.pack_slaves(), [a, b, c, d]) + a.pack_configure(before=d) + self.assertEqual(pack.pack_slaves(), [b, c, a, d]) + a.pack_configure(before=a) + self.assertEqual(pack.pack_slaves(), [b, c, a, d]) + + def test_pack_configure_expand(self): + pack, a, b, c, d = self.create2() + def check(*geoms): + self.root.update() + self.assertEqual(a.winfo_geometry(), geoms[0]) + self.assertEqual(b.winfo_geometry(), geoms[1]) + self.assertEqual(c.winfo_geometry(), geoms[2]) + self.assertEqual(d.winfo_geometry(), geoms[3]) + a.pack_configure(side='left') + b.pack_configure(side='top') + c.pack_configure(side='right') + d.pack_configure(side='bottom') + check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170') + a.pack_configure(side='left', expand='yes') + b.pack_configure(side='top', expand='on') + c.pack_configure(side='right', expand=True) + d.pack_configure(side='bottom', expand=1) + check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135') + a.pack_configure(side='left', expand='yes', fill='both') + b.pack_configure(side='top', expand='on', fill='both') + c.pack_configure(side='right', expand=True, fill='both') + d.pack_configure(side='bottom', expand=1, fill='both') + check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100') + + def test_pack_configure_in(self): + pack, a, b, c, d = self.create2() + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + a.pack_configure(in_=pack) + self.assertEqual(pack.pack_slaves(), [b, c, d, a]) + a.pack_configure(in_=c) + self.assertEqual(pack.pack_slaves(), [b, c, d]) + self.assertEqual(c.pack_slaves(), [a]) + with self.assertRaisesRegex(TclError, + 'can\'t pack %s inside itself' % (a,)): + a.pack_configure(in_=a) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(in_='.foo') + + def test_pack_configure_padx_ipadx_fill(self): + pack, a, b, c, d = self.create2() + def check(geom1, geom2, **kwargs): + a.pack_forget() + b.pack_forget() + a.pack_configure(**kwargs) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('20x40+260+80', '240x200+0+0', side='right', padx=20) + check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30)) + check('60x40+240+80', '240x200+0+0', side='right', ipadx=20) + check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10) + check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x') + check('20x40+249+80', '240x200+0+0', + side='right', padx=(9, 31), fill='x') + check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x') + check('30x40+260+80', '250x200+0+0', + side='right', ipadx=5, padx=10, fill='x') + check('30x40+255+80', '250x200+0+0', + side='right', ipadx=5, padx=(5, 15), fill='x') + check('20x40+140+0', '300x160+0+40', side='top', padx=20) + check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40)) + check('60x40+120+0', '300x160+0+40', side='top', ipadx=20) + check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10) + check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15)) + check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x') + check('260x40+25+0', '300x160+0+40', + side='top', padx=(25, 15), fill='x') + check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x') + check('280x40+10+0', '300x160+0+40', + side='top', ipadx=5, padx=10, fill='x') + check('280x40+5+0', '300x160+0+40', + side='top', ipadx=5, padx=(5, 15), fill='x') + a.pack_configure(padx='1c') + self.assertEqual(a.pack_info()['padx'], + self._str(pack.winfo_pixels('1c'))) + a.pack_configure(ipadx='1c') + self.assertEqual(a.pack_info()['ipadx'], + self._str(pack.winfo_pixels('1c'))) + + def test_pack_configure_pady_ipady_fill(self): + pack, a, b, c, d = self.create2() + def check(geom1, geom2, **kwargs): + a.pack_forget() + b.pack_forget() + a.pack_configure(**kwargs) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('20x40+280+80', '280x200+0+0', side='right', pady=20) + check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30)) + check('20x80+280+60', '280x200+0+0', side='right', ipady=20) + check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10) + check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x') + check('20x40+280+69', '280x200+0+0', + side='right', pady=(9, 31), fill='x') + check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x') + check('20x50+280+75', '280x200+0+0', + side='right', ipady=5, pady=10, fill='x') + check('20x50+280+70', '280x200+0+0', + side='right', ipady=5, pady=(5, 15), fill='x') + check('20x40+140+20', '300x120+0+80', side='top', pady=20) + check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40)) + check('20x80+140+0', '300x120+0+80', side='top', ipady=20) + check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10) + check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15)) + check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x') + check('300x40+0+25', '300x120+0+80', + side='top', pady=(25, 15), fill='x') + check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x') + check('300x50+0+10', '300x130+0+70', + side='top', ipady=5, pady=10, fill='x') + check('300x50+0+5', '300x130+0+70', + side='top', ipady=5, pady=(5, 15), fill='x') + a.pack_configure(pady='1c') + self.assertEqual(a.pack_info()['pady'], + self._str(pack.winfo_pixels('1c'))) + a.pack_configure(ipady='1c') + self.assertEqual(a.pack_info()['ipady'], + self._str(pack.winfo_pixels('1c'))) + + def test_pack_configure_side(self): + pack, a, b, c, d = self.create2() + def check(side, geom1, geom2): + a.pack_configure(side=side) + self.assertEqual(a.pack_info()['side'], side) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('top', '20x40+140+0', '300x160+0+40') + check('bottom', '20x40+140+160', '300x160+0+0') + check('left', '20x40+0+80', '280x200+20+0') + check('right', '20x40+280+80', '280x200+0+0') + + def test_pack_forget(self): + pack, a, b, c, d = self.create2() + a.pack_configure() + b.pack_configure() + c.pack_configure() + self.assertEqual(pack.pack_slaves(), [a, b, c]) + b.pack_forget() + self.assertEqual(pack.pack_slaves(), [a, c]) + b.pack_forget() + self.assertEqual(pack.pack_slaves(), [a, c]) + d.pack_forget() + + def test_pack_info(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a): + a.pack_info() + a.pack_configure() + b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x', + ipadx=5, padx=10, ipady=2, pady=(5, 15)) + info = a.pack_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['anchor'], 'center') + self.assertEqual(info['expand'], self._str(0)) + self.assertEqual(info['fill'], 'none') + self.assertEqual(info['in'], pack) + self.assertEqual(info['ipadx'], self._str(0)) + self.assertEqual(info['ipady'], self._str(0)) + self.assertEqual(info['padx'], self._str(0)) + self.assertEqual(info['pady'], self._str(0)) + self.assertEqual(info['side'], 'top') + info = b.pack_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['anchor'], 's') + self.assertEqual(info['expand'], self._str(1)) + self.assertEqual(info['fill'], 'x') + self.assertEqual(info['in'], a) + self.assertEqual(info['ipadx'], self._str(5)) + self.assertEqual(info['ipady'], self._str(2)) + self.assertEqual(info['padx'], self._str(10)) + self.assertEqual(info['pady'], self._str((5, 15))) + self.assertEqual(info['side'], 'right') + + def test_pack_propagate(self): + pack, a, b, c, d = self.create2() + pack.configure(width=300, height=200) + a.pack_configure() + pack.pack_propagate(False) + self.root.update() + self.assertEqual(pack.winfo_reqwidth(), 300) + self.assertEqual(pack.winfo_reqheight(), 200) + pack.pack_propagate(True) + self.root.update() + self.assertEqual(pack.winfo_reqwidth(), 20) + self.assertEqual(pack.winfo_reqheight(), 40) + + def test_pack_slaves(self): + pack, a, b, c, d = self.create2() + self.assertEqual(pack.pack_slaves(), []) + a.pack_configure() + self.assertEqual(pack.pack_slaves(), [a]) + b.pack_configure() + self.assertEqual(pack.pack_slaves(), [a, b]) + + +class PlaceTest(AbstractWidgetTest, unittest.TestCase): + + def create2(self): + t = tkinter.Toplevel(self.root, width=300, height=200, bd=0) + t.wm_geometry('300x200+0+0') + f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised') + f.place_configure(x=48, y=38) + f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised') + self.root.update() + return t, f, f2 + + def test_place_configure_in(self): + t, f, f2 = self.create2() + self.assertEqual(f2.winfo_manager(), '') + with self.assertRaisesRegex(TclError, "can't place %s relative to " + "itself" % re.escape(str(f2))): + f2.place_configure(in_=f2) + if tcl_version >= (8, 5): + self.assertEqual(f2.winfo_manager(), '') + with self.assertRaisesRegex(TclError, 'bad window path name'): + f2.place_configure(in_='spam') + f2.place_configure(in_=f) + self.assertEqual(f2.winfo_manager(), 'place') + + def test_place_configure_x(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['x'], '0') + self.root.update() + self.assertEqual(f2.winfo_x(), 50) + f2.place_configure(x=100) + self.assertEqual(f2.place_info()['x'], '100') + self.root.update() + self.assertEqual(f2.winfo_x(), 150) + f2.place_configure(x=-10, relx=1) + self.assertEqual(f2.place_info()['x'], '-10') + self.root.update() + self.assertEqual(f2.winfo_x(), 190) + with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): + f2.place_configure(in_=f, x='spam') + + def test_place_configure_y(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['y'], '0') + self.root.update() + self.assertEqual(f2.winfo_y(), 40) + f2.place_configure(y=50) + self.assertEqual(f2.place_info()['y'], '50') + self.root.update() + self.assertEqual(f2.winfo_y(), 90) + f2.place_configure(y=-10, rely=1) + self.assertEqual(f2.place_info()['y'], '-10') + self.root.update() + self.assertEqual(f2.winfo_y(), 110) + with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): + f2.place_configure(in_=f, y='spam') + + def test_place_configure_relx(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['relx'], '0') + self.root.update() + self.assertEqual(f2.winfo_x(), 50) + f2.place_configure(relx=0.5) + self.assertEqual(f2.place_info()['relx'], '0.5') + self.root.update() + self.assertEqual(f2.winfo_x(), 125) + f2.place_configure(relx=1) + self.assertEqual(f2.place_info()['relx'], '1') + self.root.update() + self.assertEqual(f2.winfo_x(), 200) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "spam"'): + f2.place_configure(in_=f, relx='spam') + + def test_place_configure_rely(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['rely'], '0') + self.root.update() + self.assertEqual(f2.winfo_y(), 40) + f2.place_configure(rely=0.5) + self.assertEqual(f2.place_info()['rely'], '0.5') + self.root.update() + self.assertEqual(f2.winfo_y(), 80) + f2.place_configure(rely=1) + self.assertEqual(f2.place_info()['rely'], '1') + self.root.update() + self.assertEqual(f2.winfo_y(), 120) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "spam"'): + f2.place_configure(in_=f, rely='spam') + + def test_place_configure_anchor(self): + f = tkinter.Frame(self.root) + with self.assertRaisesRegex(TclError, 'bad anchor "j"'): + f.place_configure(anchor='j') + with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): + f.place_configure(anchor='') + for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center': + f.place_configure(anchor=value) + self.assertEqual(f.place_info()['anchor'], value) + + def test_place_configure_width(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, width=120) + self.root.update() + self.assertEqual(f2.winfo_width(), 120) + f2.place_configure(width='') + self.root.update() + self.assertEqual(f2.winfo_width(), 30) + with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): + f2.place_configure(width='abcd') + + def test_place_configure_height(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, height=120) + self.root.update() + self.assertEqual(f2.winfo_height(), 120) + f2.place_configure(height='') + self.root.update() + self.assertEqual(f2.winfo_height(), 60) + with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): + f2.place_configure(height='abcd') + + def test_place_configure_relwidth(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, relwidth=0.5) + self.root.update() + self.assertEqual(f2.winfo_width(), 75) + f2.place_configure(relwidth='') + self.root.update() + self.assertEqual(f2.winfo_width(), 30) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "abcd"'): + f2.place_configure(relwidth='abcd') + + def test_place_configure_relheight(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, relheight=0.5) + self.root.update() + self.assertEqual(f2.winfo_height(), 40) + f2.place_configure(relheight='') + self.root.update() + self.assertEqual(f2.winfo_height(), 60) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "abcd"'): + f2.place_configure(relheight='abcd') + + def test_place_configure_bordermode(self): + f = tkinter.Frame(self.root) + with self.assertRaisesRegex(TclError, 'bad bordermode "j"'): + f.place_configure(bordermode='j') + with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'): + f.place_configure(bordermode='') + for value in 'inside', 'outside', 'ignore': + f.place_configure(bordermode=value) + self.assertEqual(f.place_info()['bordermode'], value) + + def test_place_forget(self): + foo = tkinter.Frame(self.root) + foo.place_configure(width=50, height=50) + self.root.update() + foo.place_forget() + self.root.update() + self.assertFalse(foo.winfo_ismapped()) + with self.assertRaises(TypeError): + foo.place_forget(0) + + def test_place_info(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, x=1, y=2, width=3, height=4, + relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4, + anchor='se', bordermode='outside') + info = f2.place_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['x'], '1') + self.assertEqual(info['y'], '2') + self.assertEqual(info['width'], '3') + self.assertEqual(info['height'], '4') + self.assertEqual(info['relx'], '0.1') + self.assertEqual(info['rely'], '0.2') + self.assertEqual(info['relwidth'], '0.3') + self.assertEqual(info['relheight'], '0.4') + self.assertEqual(info['anchor'], 'se') + self.assertEqual(info['bordermode'], 'outside') + self.assertEqual(info['x'], '1') + self.assertEqual(info['x'], '1') + with self.assertRaises(TypeError): + f2.place_info(0) + + def test_place_slaves(self): + foo = tkinter.Frame(self.root) + bar = tkinter.Frame(self.root) + self.assertEqual(foo.place_slaves(), []) + bar.place_configure(in_=foo) + self.assertEqual(foo.place_slaves(), [bar]) + with self.assertRaises(TypeError): + foo.place_slaves(0) + + +class GridTest(AbstractWidgetTest, unittest.TestCase): + + def tearDown(self): + cols, rows = self.root.grid_size() + for i in range(cols + 1): + self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='') + for i in range(rows + 1): + self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='') + self.root.grid_propagate(1) + if tcl_version >= (8, 5): + self.root.grid_anchor('nw') + super().tearDown() + + def test_grid_configure(self): + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure() + self.assertEqual(b.grid_info()['in'], self.root) + self.assertEqual(b.grid_info()['column'], self._str(0)) + self.assertEqual(b.grid_info()['row'], self._str(0)) + b.grid_configure({'column': 1}, row=2) + self.assertEqual(b.grid_info()['column'], self._str(1)) + self.assertEqual(b.grid_info()['row'], self._str(2)) + + def test_grid_configure_column(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad column value "-1": ' + 'must be a non-negative integer'): + b.grid_configure(column=-1) + b.grid_configure(column=2) + self.assertEqual(b.grid_info()['column'], self._str(2)) + + def test_grid_configure_columnspan(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad columnspan value "0": ' + 'must be a positive integer'): + b.grid_configure(columnspan=0) + b.grid_configure(columnspan=2) + self.assertEqual(b.grid_info()['columnspan'], self._str(2)) + + def test_grid_configure_in(self): + f = tkinter.Frame(self.root) + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure() + self.assertEqual(b.grid_info()['in'], self.root) + b.grid_configure(in_=f) + self.assertEqual(b.grid_info()['in'], f) + b.grid_configure({'in': self.root}) + self.assertEqual(b.grid_info()['in'], self.root) + + def test_grid_configure_ipadx(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": ' + 'must be positive screen distance'): + b.grid_configure(ipadx=-1) + b.grid_configure(ipadx=1) + self.assertEqual(b.grid_info()['ipadx'], self._str(1)) + b.grid_configure(ipadx='.5c') + self.assertEqual(b.grid_info()['ipadx'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_ipady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad ipady value "-1": ' + 'must be positive screen distance'): + b.grid_configure(ipady=-1) + b.grid_configure(ipady=1) + self.assertEqual(b.grid_info()['ipady'], self._str(1)) + b.grid_configure(ipady='.5c') + self.assertEqual(b.grid_info()['ipady'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_padx(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' + 'must be positive screen distance'): + b.grid_configure(padx=-1) + b.grid_configure(padx=1) + self.assertEqual(b.grid_info()['padx'], self._str(1)) + b.grid_configure(padx=(10, 5)) + self.assertEqual(b.grid_info()['padx'], self._str((10, 5))) + b.grid_configure(padx='.5c') + self.assertEqual(b.grid_info()['padx'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_pady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' + 'must be positive screen distance'): + b.grid_configure(pady=-1) + b.grid_configure(pady=1) + self.assertEqual(b.grid_info()['pady'], self._str(1)) + b.grid_configure(pady=(10, 5)) + self.assertEqual(b.grid_info()['pady'], self._str((10, 5))) + b.grid_configure(pady='.5c') + self.assertEqual(b.grid_info()['pady'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_row(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": ' + 'must be a non-negative integer'): + b.grid_configure(row=-1) + b.grid_configure(row=2) + self.assertEqual(b.grid_info()['row'], self._str(2)) + + def test_grid_configure_rownspan(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad rowspan value "0": ' + 'must be a positive integer'): + b.grid_configure(rowspan=0) + b.grid_configure(rowspan=2) + self.assertEqual(b.grid_info()['rowspan'], self._str(2)) + + def test_grid_configure_sticky(self): + f = tkinter.Frame(self.root, bg='red') + with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'): + f.grid_configure(sticky='glue') + f.grid_configure(sticky='ne') + self.assertEqual(f.grid_info()['sticky'], 'ne') + f.grid_configure(sticky='n,s,e,w') + self.assertEqual(f.grid_info()['sticky'], 'nesw') + + def test_grid_columnconfigure(self): + with self.assertRaises(TypeError): + self.root.grid_columnconfigure() + self.assertEqual(self.root.grid_columnconfigure(0), + {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) + with self.assertRaisesRegex(TclError, 'bad option "-foo"'): + self.root.grid_columnconfigure(0, 'foo') + self.root.grid_columnconfigure((0, 3), weight=2) + with self.assertRaisesRegex(TclError, + 'must specify a single element on retrieval'): + self.root.grid_columnconfigure((0, 3)) + b = tkinter.Button(self.root) + b.grid_configure(column=0, row=0) + if tcl_version >= (8, 5): + self.root.grid_columnconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_columnconfigure('all') + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2) + self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0) + if tcl_version >= (8, 5): + self.root.grid_columnconfigure(b, weight=4) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) + + def test_grid_columnconfigure_minsize(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_columnconfigure(0, minsize='foo') + self.root.grid_columnconfigure(0, minsize=10) + self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10) + self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10) + + def test_grid_columnconfigure_weight(self): + with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): + self.root.grid_columnconfigure(0, weight='bad') + with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' + 'should be non-negative'): + self.root.grid_columnconfigure(0, weight=-3) + self.root.grid_columnconfigure(0, weight=3) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3) + + def test_grid_columnconfigure_pad(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_columnconfigure(0, pad='foo') + with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' + 'should be non-negative'): + self.root.grid_columnconfigure(0, pad=-3) + self.root.grid_columnconfigure(0, pad=3) + self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3) + self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3) + + def test_grid_columnconfigure_uniform(self): + self.root.grid_columnconfigure(0, uniform='foo') + self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo') + self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo') + + def test_grid_rowconfigure(self): + with self.assertRaises(TypeError): + self.root.grid_rowconfigure() + self.assertEqual(self.root.grid_rowconfigure(0), + {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) + with self.assertRaisesRegex(TclError, 'bad option "-foo"'): + self.root.grid_rowconfigure(0, 'foo') + self.root.grid_rowconfigure((0, 3), weight=2) + with self.assertRaisesRegex(TclError, + 'must specify a single element on retrieval'): + self.root.grid_rowconfigure((0, 3)) + b = tkinter.Button(self.root) + b.grid_configure(column=0, row=0) + if tcl_version >= (8, 5): + self.root.grid_rowconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_rowconfigure('all') + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2) + self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0) + if tcl_version >= (8, 5): + self.root.grid_rowconfigure(b, weight=4) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) + + def test_grid_rowconfigure_minsize(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_rowconfigure(0, minsize='foo') + self.root.grid_rowconfigure(0, minsize=10) + self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10) + self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10) + + def test_grid_rowconfigure_weight(self): + with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): + self.root.grid_rowconfigure(0, weight='bad') + with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' + 'should be non-negative'): + self.root.grid_rowconfigure(0, weight=-3) + self.root.grid_rowconfigure(0, weight=3) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3) + + def test_grid_rowconfigure_pad(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_rowconfigure(0, pad='foo') + with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' + 'should be non-negative'): + self.root.grid_rowconfigure(0, pad=-3) + self.root.grid_rowconfigure(0, pad=3) + self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3) + self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3) + + def test_grid_rowconfigure_uniform(self): + self.root.grid_rowconfigure(0, uniform='foo') + self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo') + self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo') + + def test_grid_forget(self): + b = tkinter.Button(self.root) + c = tkinter.Button(self.root) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + self.assertEqual(self.root.grid_slaves(), [b]) + b.grid_forget() + c.grid_forget() + self.assertEqual(self.root.grid_slaves(), []) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=0, column=0) + info = b.grid_info() + self.assertEqual(info['row'], self._str(0)) + self.assertEqual(info['column'], self._str(0)) + self.assertEqual(info['rowspan'], self._str(1)) + self.assertEqual(info['columnspan'], self._str(1)) + self.assertEqual(info['padx'], self._str(0)) + self.assertEqual(info['pady'], self._str(0)) + self.assertEqual(info['sticky'], '') + + def test_grid_remove(self): + b = tkinter.Button(self.root) + c = tkinter.Button(self.root) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + self.assertEqual(self.root.grid_slaves(), [b]) + b.grid_remove() + c.grid_remove() + self.assertEqual(self.root.grid_slaves(), []) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=0, column=0) + info = b.grid_info() + self.assertEqual(info['row'], self._str(0)) + self.assertEqual(info['column'], self._str(0)) + self.assertEqual(info['rowspan'], self._str(2)) + self.assertEqual(info['columnspan'], self._str(2)) + self.assertEqual(info['padx'], self._str(3)) + self.assertEqual(info['pady'], self._str(4)) + self.assertEqual(info['sticky'], 'ns') + + def test_grid_info(self): + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + info = b.grid_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['in'], self.root) + self.assertEqual(info['row'], self._str(2)) + self.assertEqual(info['column'], self._str(2)) + self.assertEqual(info['rowspan'], self._str(2)) + self.assertEqual(info['columnspan'], self._str(2)) + self.assertEqual(info['padx'], self._str(3)) + self.assertEqual(info['pady'], self._str(4)) + self.assertEqual(info['sticky'], 'ns') + + @requires_tcl(8, 5) + def test_grid_anchor(self): + with self.assertRaisesRegex(TclError, 'bad anchor "x"'): + self.root.grid_anchor('x') + with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): + self.root.grid_anchor('') + with self.assertRaises(TypeError): + self.root.grid_anchor('se', 'nw') + self.root.grid_anchor('se') + self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se') + + def test_grid_bbox(self): + self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0)) + self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0)) + self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0)) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox('x', 0) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 'x') + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 0, 'x', 0) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 0, 0, 'x') + with self.assertRaises(TypeError): + self.root.grid_bbox(0, 0, 0, 0, 0) + t = self.root + # de-maximize + t.wm_geometry('1x1+0+0') + t.wm_geometry('') + f1 = tkinter.Frame(t, width=75, height=75, bg='red') + f2 = tkinter.Frame(t, width=90, height=90, bg='blue') + f1.grid_configure(row=0, column=0) + f2.grid_configure(row=1, column=1) + self.root.update() + self.assertEqual(t.grid_bbox(), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75)) + self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90)) + self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0)) + self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0)) + + def test_grid_location(self): + with self.assertRaises(TypeError): + self.root.grid_location() + with self.assertRaises(TypeError): + self.root.grid_location(0) + with self.assertRaises(TypeError): + self.root.grid_location(0, 0, 0) + with self.assertRaisesRegex(TclError, 'bad screen distance "x"'): + self.root.grid_location('x', 'y') + with self.assertRaisesRegex(TclError, 'bad screen distance "y"'): + self.root.grid_location('1c', 'y') + t = self.root + # de-maximize + t.wm_geometry('1x1+0+0') + t.wm_geometry('') + f = tkinter.Frame(t, width=200, height=100, + highlightthickness=0, bg='red') + self.assertEqual(f.grid_location(10, 10), (-1, -1)) + f.grid_configure() + self.root.update() + self.assertEqual(t.grid_location(-10, -10), (-1, -1)) + self.assertEqual(t.grid_location(-10, 0), (-1, 0)) + self.assertEqual(t.grid_location(-1, 0), (-1, 0)) + self.assertEqual(t.grid_location(0, -10), (0, -1)) + self.assertEqual(t.grid_location(0, -1), (0, -1)) + self.assertEqual(t.grid_location(0, 0), (0, 0)) + self.assertEqual(t.grid_location(200, 0), (0, 0)) + self.assertEqual(t.grid_location(201, 0), (1, 0)) + self.assertEqual(t.grid_location(0, 100), (0, 0)) + self.assertEqual(t.grid_location(0, 101), (0, 1)) + self.assertEqual(t.grid_location(201, 101), (1, 1)) + + def test_grid_propagate(self): + self.assertEqual(self.root.grid_propagate(), True) + with self.assertRaises(TypeError): + self.root.grid_propagate(False, False) + self.root.grid_propagate(False) + self.assertFalse(self.root.grid_propagate()) + f = tkinter.Frame(self.root, width=100, height=100, bg='red') + f.grid_configure(row=0, column=0) + self.root.update() + self.assertEqual(f.winfo_width(), 100) + self.assertEqual(f.winfo_height(), 100) + f.grid_propagate(False) + g = tkinter.Frame(self.root, width=75, height=85, bg='green') + g.grid_configure(in_=f, row=0, column=0) + self.root.update() + self.assertEqual(f.winfo_width(), 100) + self.assertEqual(f.winfo_height(), 100) + f.grid_propagate(True) + self.root.update() + self.assertEqual(f.winfo_width(), 75) + self.assertEqual(f.winfo_height(), 85) + + def test_grid_size(self): + with self.assertRaises(TypeError): + self.root.grid_size(0) + self.assertEqual(self.root.grid_size(), (0, 0)) + f = tkinter.Scale(self.root) + f.grid_configure(row=0, column=0) + self.assertEqual(self.root.grid_size(), (1, 1)) + f.grid_configure(row=4, column=5) + self.assertEqual(self.root.grid_size(), (6, 5)) + + def test_grid_slaves(self): + self.assertEqual(self.root.grid_slaves(), []) + a = tkinter.Label(self.root) + a.grid_configure(row=0, column=1) + b = tkinter.Label(self.root) + b.grid_configure(row=1, column=0) + c = tkinter.Label(self.root) + c.grid_configure(row=1, column=1) + d = tkinter.Label(self.root) + d.grid_configure(row=1, column=1) + self.assertEqual(self.root.grid_slaves(), [d, c, b, a]) + self.assertEqual(self.root.grid_slaves(row=0), [a]) + self.assertEqual(self.root.grid_slaves(row=1), [d, c, b]) + self.assertEqual(self.root.grid_slaves(column=0), [b]) + self.assertEqual(self.root.grid_slaves(column=1), [d, c, a]) + self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c]) + + +tests_gui = ( + PackTest, PlaceTest, GridTest, +) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/tkinter/test/test_tkinter/test_images.py new file mode 100644 index 0000000..85a8cd0 --- /dev/null +++ b/Lib/tkinter/test/test_tkinter/test_images.py @@ -0,0 +1,327 @@ +import unittest +import tkinter +from test import support +from tkinter.test.support import AbstractTkTest, requires_tcl + +support.requires('gui') + + +class MiscTest(AbstractTkTest, unittest.TestCase): + + def test_image_types(self): + image_types = self.root.image_types() + self.assertIsInstance(image_types, tuple) + self.assertIn('photo', image_types) + self.assertIn('bitmap', image_types) + + def test_image_names(self): + image_names = self.root.image_names() + self.assertIsInstance(image_names, tuple) + + +class BitmapImageTest(AbstractTkTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) + cls.testfile = support.findfile('python.xbm', subdir='imghdrdata') + + def test_create_from_file(self): + image = tkinter.BitmapImage('::img::test', master=self.root, + foreground='yellow', background='blue', + file=self.testfile) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'bitmap') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def test_create_from_data(self): + with open(self.testfile, 'rb') as f: + data = f.read() + image = tkinter.BitmapImage('::img::test', master=self.root, + foreground='yellow', background='blue', + data=data) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'bitmap') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def assertEqualStrList(self, actual, expected): + self.assertIsInstance(actual, str) + self.assertEqual(self.root.splitlist(actual), expected) + + def test_configure_data(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['data'], '-data {} {} {} {}') + with open(self.testfile, 'rb') as f: + data = f.read() + image.configure(data=data) + self.assertEqualStrList(image['data'], + ('-data', '', '', '', data.decode('ascii'))) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + self.assertEqual(image['maskdata'], '-maskdata {} {} {} {}') + image.configure(maskdata=data) + self.assertEqualStrList(image['maskdata'], + ('-maskdata', '', '', '', data.decode('ascii'))) + + def test_configure_file(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['file'], '-file {} {} {} {}') + image.configure(file=self.testfile) + self.assertEqualStrList(image['file'], + ('-file', '', '', '',self.testfile)) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + self.assertEqual(image['maskfile'], '-maskfile {} {} {} {}') + image.configure(maskfile=self.testfile) + self.assertEqualStrList(image['maskfile'], + ('-maskfile', '', '', '', self.testfile)) + + def test_configure_background(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['background'], '-background {} {} {} {}') + image.configure(background='blue') + self.assertEqual(image['background'], '-background {} {} {} blue') + + def test_configure_foreground(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['foreground'], + '-foreground {} {} #000000 #000000') + image.configure(foreground='yellow') + self.assertEqual(image['foreground'], + '-foreground {} {} #000000 yellow') + + +class PhotoImageTest(AbstractTkTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) + cls.testfile = support.findfile('python.gif', subdir='imghdrdata') + + def create(self): + return tkinter.PhotoImage('::img::test', master=self.root, + file=self.testfile) + + def colorlist(self, *args): + if tkinter.TkVersion >= 8.6 and self.wantobjects: + return args + else: + return tkinter._join(args) + + def check_create_from_file(self, ext): + testfile = support.findfile('python.' + ext, subdir='imghdrdata') + image = tkinter.PhotoImage('::img::test', master=self.root, + file=testfile) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'photo') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image['data'], '') + self.assertEqual(image['file'], testfile) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def check_create_from_data(self, ext): + testfile = support.findfile('python.' + ext, subdir='imghdrdata') + with open(testfile, 'rb') as f: + data = f.read() + image = tkinter.PhotoImage('::img::test', master=self.root, + data=data) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'photo') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image['data'], data if self.wantobjects + else data.decode('latin1')) + self.assertEqual(image['file'], '') + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def test_create_from_ppm_file(self): + self.check_create_from_file('ppm') + + def test_create_from_ppm_data(self): + self.check_create_from_data('ppm') + + def test_create_from_pgm_file(self): + self.check_create_from_file('pgm') + + def test_create_from_pgm_data(self): + self.check_create_from_data('pgm') + + def test_create_from_gif_file(self): + self.check_create_from_file('gif') + + def test_create_from_gif_data(self): + self.check_create_from_data('gif') + + @requires_tcl(8, 6) + def test_create_from_png_file(self): + self.check_create_from_file('png') + + @requires_tcl(8, 6) + def test_create_from_png_data(self): + self.check_create_from_data('png') + + def test_configure_data(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['data'], '') + with open(self.testfile, 'rb') as f: + data = f.read() + image.configure(data=data) + self.assertEqual(image['data'], data if self.wantobjects + else data.decode('latin1')) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_format(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['format'], '') + image.configure(file=self.testfile, format='gif') + self.assertEqual(image['format'], ('gif',) if self.wantobjects + else 'gif') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_file(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['file'], '') + image.configure(file=self.testfile) + self.assertEqual(image['file'], self.testfile) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_gamma(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['gamma'], '1.0') + image.configure(gamma=2.0) + self.assertEqual(image['gamma'], '2.0') + + def test_configure_width_height(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['width'], '0') + self.assertEqual(image['height'], '0') + image.configure(width=20) + image.configure(height=10) + self.assertEqual(image['width'], '20') + self.assertEqual(image['height'], '10') + self.assertEqual(image.width(), 20) + self.assertEqual(image.height(), 10) + + def test_configure_palette(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['palette'], '') + image.configure(palette=256) + self.assertEqual(image['palette'], '256') + image.configure(palette='3/4/2') + self.assertEqual(image['palette'], '3/4/2') + + def test_blank(self): + image = self.create() + image.blank() + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image.get(4, 6), self.colorlist(0, 0, 0)) + + def test_copy(self): + image = self.create() + image2 = image.copy() + self.assertEqual(image2.width(), 16) + self.assertEqual(image2.height(), 16) + self.assertEqual(image.get(4, 6), image.get(4, 6)) + + def test_subsample(self): + image = self.create() + image2 = image.subsample(2, 3) + self.assertEqual(image2.width(), 8) + self.assertEqual(image2.height(), 6) + self.assertEqual(image2.get(2, 2), image.get(4, 6)) + + image2 = image.subsample(2) + self.assertEqual(image2.width(), 8) + self.assertEqual(image2.height(), 8) + self.assertEqual(image2.get(2, 3), image.get(4, 6)) + + def test_zoom(self): + image = self.create() + image2 = image.zoom(2, 3) + self.assertEqual(image2.width(), 32) + self.assertEqual(image2.height(), 48) + self.assertEqual(image2.get(8, 18), image.get(4, 6)) + self.assertEqual(image2.get(9, 20), image.get(4, 6)) + + image2 = image.zoom(2) + self.assertEqual(image2.width(), 32) + self.assertEqual(image2.height(), 32) + self.assertEqual(image2.get(8, 12), image.get(4, 6)) + self.assertEqual(image2.get(9, 13), image.get(4, 6)) + + def test_put(self): + image = self.create() + image.put('{red green} {blue yellow}', to=(4, 6)) + self.assertEqual(image.get(4, 6), self.colorlist(255, 0, 0)) + self.assertEqual(image.get(5, 6), + self.colorlist(0, 128 if tkinter.TkVersion >= 8.6 + else 255, 0)) + self.assertEqual(image.get(4, 7), self.colorlist(0, 0, 255)) + self.assertEqual(image.get(5, 7), self.colorlist(255, 255, 0)) + + image.put((('#f00', '#00ff00'), ('#000000fff', '#ffffffff0000'))) + self.assertEqual(image.get(0, 0), self.colorlist(255, 0, 0)) + self.assertEqual(image.get(1, 0), self.colorlist(0, 255, 0)) + self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255)) + self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0)) + + def test_get(self): + image = self.create() + self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162)) + self.assertEqual(image.get(0, 0), self.colorlist(0, 0, 0)) + self.assertEqual(image.get(15, 15), self.colorlist(0, 0, 0)) + self.assertRaises(tkinter.TclError, image.get, -1, 0) + self.assertRaises(tkinter.TclError, image.get, 0, -1) + self.assertRaises(tkinter.TclError, image.get, 16, 15) + self.assertRaises(tkinter.TclError, image.get, 15, 16) + + def test_write(self): + image = self.create() + self.addCleanup(support.unlink, support.TESTFN) + + image.write(support.TESTFN) + image2 = tkinter.PhotoImage('::img::test2', master=self.root, + format='ppm', + file=support.TESTFN) + self.assertEqual(str(image2), '::img::test2') + self.assertEqual(image2.type(), 'photo') + self.assertEqual(image2.width(), 16) + self.assertEqual(image2.height(), 16) + self.assertEqual(image2.get(0, 0), image.get(0, 0)) + self.assertEqual(image2.get(15, 8), image.get(15, 8)) + + image.write(support.TESTFN, format='gif', from_coords=(4, 6, 6, 9)) + image3 = tkinter.PhotoImage('::img::test3', master=self.root, + format='gif', + file=support.TESTFN) + self.assertEqual(str(image3), '::img::test3') + self.assertEqual(image3.type(), 'photo') + self.assertEqual(image3.width(), 2) + self.assertEqual(image3.height(), 3) + self.assertEqual(image3.get(0, 0), image.get(4, 6)) + self.assertEqual(image3.get(1, 2), image.get(5, 8)) + + +tests_gui = (MiscTest, BitmapImageTest, PhotoImageTest,) + +if __name__ == "__main__": + support.run_unittest(*tests_gui) diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index d325b31..d8de949 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -1,14 +1,11 @@ import unittest import tkinter -from tkinter import ttk from test import support +from tkinter.test.support import AbstractTkTest support.requires('gui') -class MiscTest(unittest.TestCase): - - def setUp(self): - self.root = ttk.setup_master() +class MiscTest(AbstractTkTest, unittest.TestCase): def test_tk_setPalette(self): root = self.root diff --git a/Lib/tkinter/test/test_tkinter/test_text.py b/Lib/tkinter/test/test_tkinter/test_text.py index 4c3fa04..13b7c56 100644 --- a/Lib/tkinter/test/test_tkinter/test_text.py +++ b/Lib/tkinter/test/test_tkinter/test_text.py @@ -1,19 +1,16 @@ import unittest import tkinter from test.support import requires, run_unittest -from tkinter.ttk import setup_master +from tkinter.test.support import AbstractTkTest requires('gui') -class TextTest(unittest.TestCase): +class TextTest(AbstractTkTest, unittest.TestCase): def setUp(self): - self.root = setup_master() + super().setUp() self.text = tkinter.Text(self.root) - def tearDown(self): - self.text.destroy() - def test_debug(self): text = self.text olddebug = text.debug() diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/tkinter/test/test_tkinter/test_variables.py index 9d910ac..4b72943 100644 --- a/Lib/tkinter/test/test_tkinter/test_variables.py +++ b/Lib/tkinter/test/test_tkinter/test_variables.py @@ -1,6 +1,7 @@ import unittest -from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk +from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, + TclError) class Var(Variable): @@ -16,10 +17,10 @@ class Var(Variable): class TestBase(unittest.TestCase): def setUp(self): - self.root = Tk() + self.root = Tcl() def tearDown(self): - self.root.destroy() + del self.root class TestVariable(TestBase): @@ -81,7 +82,7 @@ class TestVariable(TestBase): self.root.setvar(b'var\x00name', "value") def test_initialize(self): - v = Var() + v = Var(self.root) self.assertFalse(v.side_effect) v.set("value") self.assertTrue(v.side_effect) @@ -159,16 +160,41 @@ class TestBooleanVar(TestBase): def test_default(self): v = BooleanVar(self.root) - self.assertEqual(False, v.get()) + self.assertIs(v.get(), False) def test_get(self): v = BooleanVar(self.root, True, "name") - self.assertAlmostEqual(True, v.get()) + self.assertIs(v.get(), True) self.root.globalsetvar("name", "0") - self.assertAlmostEqual(False, v.get()) + self.assertIs(v.get(), False) + self.root.globalsetvar("name", 42 if self.root.wantobjects() else 1) + self.assertIs(v.get(), True) + self.root.globalsetvar("name", 0) + self.assertIs(v.get(), False) + self.root.globalsetvar("name", "on") + self.assertIs(v.get(), True) + + def test_set(self): + true = 1 if self.root.wantobjects() else "1" + false = 0 if self.root.wantobjects() else "0" + v = BooleanVar(self.root, name="name") + v.set(True) + self.assertEqual(self.root.globalgetvar("name"), true) + v.set("0") + self.assertEqual(self.root.globalgetvar("name"), false) + v.set(42) + self.assertEqual(self.root.globalgetvar("name"), true) + v.set(0) + self.assertEqual(self.root.globalgetvar("name"), false) + v.set("on") + self.assertEqual(self.root.globalgetvar("name"), true) def test_invalid_value_domain(self): + false = 0 if self.root.wantobjects() else "0" v = BooleanVar(self.root, name="name") + with self.assertRaises(TclError): + v.set("value") + self.assertEqual(self.root.globalgetvar("name"), false) self.root.globalsetvar("name", "value") with self.assertRaises(ValueError): v.get() diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index 6ef7750..8be0371 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -1,5 +1,6 @@ import unittest import tkinter +from tkinter import TclError import os import sys from test.support import requires @@ -65,7 +66,7 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase): 'takefocus', 'use', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Toplevel(self.root, **kwargs) def test_menu(self): @@ -104,7 +105,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase): 'relief', 'takefocus', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Frame(self.root, **kwargs) @@ -119,7 +120,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 'takefocus', 'text', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.LabelFrame(self.root, **kwargs) def test_labelanchor(self): @@ -157,7 +158,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Label(self.root, **kwargs) @@ -174,7 +175,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): 'state', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength') - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Button(self.root, **kwargs) def test_default(self): @@ -198,7 +199,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'variable', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Checkbutton(self.root, **kwargs) @@ -226,7 +227,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'value', 'variable', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Radiobutton(self.root, **kwargs) def test_value(self): @@ -249,7 +250,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): ) _conv_pixels = staticmethod(pixels_round) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Menubutton(self.root, **kwargs) def test_direction(self): @@ -267,7 +268,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'crashes with Cocoa Tk (issue19733)') def test_image(self): widget = self.create() - image = tkinter.PhotoImage('image1') + image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, 'image', image, conv=str) errmsg = 'image "spam" doesn\'t exist' with self.assertRaises(tkinter.TclError) as cm: @@ -302,7 +303,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): class OptionMenuTest(MenubuttonTest, unittest.TestCase): - def _create(self, default='b', values=('a', 'b', 'c'), **kwargs): + def create(self, default='b', values=('a', 'b', 'c'), **kwargs): return tkinter.OptionMenu(self.root, None, default, *values, **kwargs) @@ -321,7 +322,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): 'validate', 'validatecommand', 'width', 'xscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Entry(self.root, **kwargs) def test_disabledbackground(self): @@ -395,7 +396,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): 'width', 'wrap', 'xscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Spinbox(self.root, **kwargs) test_show = None @@ -466,11 +467,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): def test_bbox(self): widget = self.create() - bbox = widget.bbox(0) - self.assertEqual(len(bbox), 4) - for item in bbox: - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(widget.bbox(0)) self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') self.assertRaises(tkinter.TclError, widget.bbox, None) self.assertRaises(TypeError, widget.bbox) @@ -493,9 +490,9 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): 'xscrollcommand', 'yscrollcommand', ) if tcl_version < (8, 5): - wantobjects = False + _stringify = True - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Text(self.root, **kwargs) def test_autoseparators(self): @@ -623,16 +620,12 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): def test_bbox(self): widget = self.create() - bbox = widget.bbox('1.1') - self.assertEqual(len(bbox), 4) - for item in bbox: - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(widget.bbox('1.1')) self.assertIsNone(widget.bbox('end')) self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') self.assertRaises(tkinter.TclError, widget.bbox, None) - self.assertRaises(tkinter.TclError, widget.bbox) - self.assertRaises(tkinter.TclError, widget.bbox, '1.1', 'end') + self.assertRaises(TypeError, widget.bbox) + self.assertRaises(TypeError, widget.bbox, '1.1', 'end') @add_standard_options(PixelSizeTests, StandardOptionsTests) @@ -651,9 +644,9 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pixels = round - wantobjects = False + _stringify = True - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Canvas(self.root, **kwargs) def test_closeenough(self): @@ -706,7 +699,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Listbox(self.root, **kwargs) def test_activestyle(self): @@ -716,7 +709,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): def test_listvariable(self): widget = self.create() - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.checkVariableParam(widget, 'listvariable', var) def test_selectmode(self): @@ -730,6 +723,101 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkEnumParam(widget, 'state', 'disabled', 'normal') + def test_itemconfigure(self): + widget = self.create() + with self.assertRaisesRegex(TclError, 'item number "0" out of range'): + widget.itemconfigure(0) + colors = 'red orange yellow green blue white violet'.split() + widget.insert('end', *colors) + for i, color in enumerate(colors): + widget.itemconfigure(i, background=color) + with self.assertRaises(TypeError): + widget.itemconfigure() + with self.assertRaisesRegex(TclError, 'bad listbox index "red"'): + widget.itemconfigure('red') + self.assertEqual(widget.itemconfigure(0, 'background'), + ('background', 'background', 'Background', '', 'red')) + self.assertEqual(widget.itemconfigure('end', 'background'), + ('background', 'background', 'Background', '', 'violet')) + self.assertEqual(widget.itemconfigure('@0,0', 'background'), + ('background', 'background', 'Background', '', 'red')) + + d = widget.itemconfigure(0) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertIn(len(v), (2, 5)) + if len(v) == 5: + self.assertEqual(v, widget.itemconfigure(0, k)) + self.assertEqual(v[4], widget.itemcget(0, k)) + + def check_itemconfigure(self, name, value): + widget = self.create() + widget.insert('end', 'a', 'b', 'c', 'd') + widget.itemconfigure(0, **{name: value}) + self.assertEqual(widget.itemconfigure(0, name)[4], value) + self.assertEqual(widget.itemcget(0, name), value) + with self.assertRaisesRegex(TclError, 'unknown color name "spam"'): + widget.itemconfigure(0, **{name: 'spam'}) + + def test_itemconfigure_background(self): + self.check_itemconfigure('background', '#ff0000') + + def test_itemconfigure_bg(self): + self.check_itemconfigure('bg', '#ff0000') + + def test_itemconfigure_fg(self): + self.check_itemconfigure('fg', '#110022') + + def test_itemconfigure_foreground(self): + self.check_itemconfigure('foreground', '#110022') + + def test_itemconfigure_selectbackground(self): + self.check_itemconfigure('selectbackground', '#110022') + + def test_itemconfigure_selectforeground(self): + self.check_itemconfigure('selectforeground', '#654321') + + def test_box(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + lb.pack() + self.assertIsBoundingBox(lb.bbox(0)) + self.assertIsNone(lb.bbox(-1)) + self.assertIsNone(lb.bbox(10)) + self.assertRaises(TclError, lb.bbox, 'noindex') + self.assertRaises(TclError, lb.bbox, None) + self.assertRaises(TypeError, lb.bbox) + self.assertRaises(TypeError, lb.bbox, 0, 1) + + def test_curselection(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + lb.selection_clear(0, tkinter.END) + lb.selection_set(2, 4) + lb.selection_set(6) + self.assertEqual(lb.curselection(), (2, 3, 4, 6)) + self.assertRaises(TypeError, lb.curselection, 0) + + def test_get(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + self.assertEqual(lb.get(0), 'el0') + self.assertEqual(lb.get(3), 'el3') + self.assertEqual(lb.get('end'), 'el7') + self.assertEqual(lb.get(8), '') + self.assertEqual(lb.get(-1), '') + self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5')) + self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7')) + self.assertEqual(lb.get(5, 0), ()) + self.assertEqual(lb.get(0, 0), ('el0',)) + self.assertRaises(TclError, lb.get, 'noindex') + self.assertRaises(TclError, lb.get, None) + self.assertRaises(TypeError, lb.get) + self.assertRaises(TclError, lb.get, 'end', 'noindex') + self.assertRaises(TypeError, lb.get, 1, 2, 3) + self.assertRaises(TclError, lb.get, 2.4) + + @add_standard_options(PixelSizeTests, StandardOptionsTests) class ScaleTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( @@ -743,7 +831,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Scale(self.root, **kwargs) def test_bigincrement(self): @@ -809,10 +897,10 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): 'takefocus', 'troughcolor', 'width', ) _conv_pixels = round - wantobjects = False + _stringify = True default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Scrollbar(self.root, **kwargs) def test_activerelief(self): @@ -828,6 +916,24 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal', errmsg='bad orientation "{}": must be vertical or horizontal') + def test_activate(self): + sb = self.create() + for e in ('arrow1', 'slider', 'arrow2'): + sb.activate(e) + sb.activate('') + self.assertRaises(TypeError, sb.activate) + self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2') + + def test_set(self): + sb = self.create() + sb.set(0.2, 0.4) + self.assertEqual(sb.get(), (0.2, 0.4)) + self.assertRaises(TclError, sb.set, 'abc', 'def') + self.assertRaises(TclError, sb.set, 0.6, 'def') + self.assertRaises(TclError, sb.set, 0.6, None) + self.assertRaises(TclError, sb.set, 0.6) + self.assertRaises(TclError, sb.set, 0.6, 0.7, 0.8) + @add_standard_options(StandardOptionsTests) class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): @@ -840,7 +946,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.PanedWindow(self.root, **kwargs) def test_handlepad(self): @@ -887,6 +993,105 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', conv=noconv) + def create2(self): + p = self.create() + b = tkinter.Button(p) + c = tkinter.Button(p) + p.add(b) + p.add(c) + return p, b, c + + def test_paneconfigure(self): + p, b, c = self.create2() + self.assertRaises(TypeError, p.paneconfigure) + d = p.paneconfigure(b) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertEqual(len(v), 5) + self.assertEqual(v, p.paneconfigure(b, k)) + self.assertEqual(v[4], p.panecget(b, k)) + + def check_paneconfigure(self, p, b, name, value, expected, stringify=False): + conv = lambda x: x + if not self.wantobjects or stringify: + expected = str(expected) + if self.wantobjects and stringify: + conv = str + p.paneconfigure(b, **{name: value}) + self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected) + self.assertEqual(conv(p.panecget(b, name)), expected) + + def check_paneconfigure_bad(self, p, b, name, msg): + with self.assertRaisesRegex(TclError, msg): + p.paneconfigure(b, **{name: 'badValue'}) + + def test_paneconfigure_after(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'after', c, str(c)) + self.check_paneconfigure_bad(p, b, 'after', + 'bad window path name "badValue"') + + def test_paneconfigure_before(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'before', c, str(c)) + self.check_paneconfigure_bad(p, b, 'before', + 'bad window path name "badValue"') + + def test_paneconfigure_height(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'height', 10, 10, + stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure_bad(p, b, 'height', + 'bad screen distance "badValue"') + + @requires_tcl(8, 5) + def test_paneconfigure_hide(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'hide', False, 0) + self.check_paneconfigure_bad(p, b, 'hide', + 'expected boolean value but got "badValue"') + + def test_paneconfigure_minsize(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'minsize', 10, 10) + self.check_paneconfigure_bad(p, b, 'minsize', + 'bad screen distance "badValue"') + + def test_paneconfigure_padx(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'padx', 1.3, 1) + self.check_paneconfigure_bad(p, b, 'padx', + 'bad screen distance "badValue"') + + def test_paneconfigure_pady(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'pady', 1.3, 1) + self.check_paneconfigure_bad(p, b, 'pady', + 'bad screen distance "badValue"') + + def test_paneconfigure_sticky(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw') + self.check_paneconfigure_bad(p, b, 'sticky', + 'bad stickyness value "badValue": must ' + 'be a string containing zero or more of ' + 'n, e, s, and w') + + @requires_tcl(8, 5) + def test_paneconfigure_stretch(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'stretch', 'alw', 'always') + self.check_paneconfigure_bad(p, b, 'stretch', + 'bad stretch "badValue": must be ' + 'always, first, last, middle, or never') + + def test_paneconfigure_width(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'width', 10, 10, + stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure_bad(p, b, 'width', + 'bad screen distance "badValue"') + @add_standard_options(StandardOptionsTests) class MenuTest(AbstractWidgetTest, unittest.TestCase): @@ -899,7 +1104,7 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) def test_postcommand(self): @@ -923,6 +1128,39 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): self.checkEnumParam(widget, 'type', 'normal', 'tearoff', 'menubar') + def test_entryconfigure(self): + m1 = self.create() + m1.add_command(label='test') + self.assertRaises(TypeError, m1.entryconfigure) + with self.assertRaisesRegex(TclError, 'bad menu entry index "foo"'): + m1.entryconfigure('foo') + d = m1.entryconfigure(1) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertIsInstance(k, str) + self.assertIsInstance(v, tuple) + self.assertEqual(len(v), 5) + self.assertEqual(v[0], k) + self.assertEqual(m1.entrycget(1, k), v[4]) + m1.destroy() + + def test_entryconfigure_label(self): + m1 = self.create() + m1.add_command(label='test') + self.assertEqual(m1.entrycget(1, 'label'), 'test') + m1.entryconfigure(1, label='changed') + self.assertEqual(m1.entrycget(1, 'label'), 'changed') + + def test_entryconfigure_variable(self): + m1 = self.create() + v1 = tkinter.BooleanVar(self.root) + v2 = tkinter.BooleanVar(self.root) + m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False, + label='Nonsense') + self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1)) + m1.entryconfigure(1, variable=v2) + self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2)) + @add_standard_options(PixelSizeTests, StandardOptionsTests) class MessageTest(AbstractWidgetTest, unittest.TestCase): @@ -935,7 +1173,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pad_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) def test_aspect(self): diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py index d699546..c3af06c 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/tkinter/test/test_ttk/test_extensions.py @@ -2,34 +2,30 @@ import sys import unittest import tkinter from tkinter import ttk -from test.support import requires, run_unittest - -import tkinter.test.support as support +from test.support import requires, run_unittest, swap_attr +from tkinter.test.support import AbstractTkTest, destroy_default_root requires('gui') -class LabeledScaleTest(unittest.TestCase): - - def setUp(self): - support.root_deiconify() +class LabeledScaleTest(AbstractTkTest, unittest.TestCase): def tearDown(self): - support.root_withdraw() - + self.root.update_idletasks() + super().tearDown() def test_widget_destroy(self): # automatically created variable - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) var = x._variable._name x.destroy() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var) # manually created variable - myvar = tkinter.DoubleVar() + myvar = tkinter.DoubleVar(self.root) name = myvar._name - x = ttk.LabeledScale(variable=myvar) + x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() - if x.tk.wantobjects(): + if self.wantobjects: self.assertEqual(x.tk.globalgetvar(name), myvar.get()) else: self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) @@ -37,26 +33,36 @@ class LabeledScaleTest(unittest.TestCase): self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) # checking that the tracing callback is properly removed - myvar = tkinter.IntVar() + myvar = tkinter.IntVar(self.root) # LabeledScale will start tracing myvar - x = ttk.LabeledScale(variable=myvar) + x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() # Unless the tracing callback was removed, creating a new # LabeledScale with the same var will cause an error now. This # happens because the variable will be set to (possibly) a new # value which causes the tracing callback to be called and then # it tries calling instance attributes not yet defined. - ttk.LabeledScale(variable=myvar) + ttk.LabeledScale(self.root, variable=myvar) if hasattr(sys, 'last_type'): self.assertNotEqual(sys.last_type, tkinter.TclError) + def test_initialization_no_master(self): + # no master passing + with swap_attr(tkinter, '_default_root', None), \ + swap_attr(tkinter, '_support_default_root', True): + try: + x = ttk.LabeledScale() + self.assertIsNotNone(tkinter._default_root) + self.assertEqual(x.master, tkinter._default_root) + self.assertEqual(x.tk, tkinter._default_root.tk) + x.destroy() + finally: + destroy_default_root() + def test_initialization(self): # master passing - x = ttk.LabeledScale() - self.assertEqual(x.master, tkinter._default_root) - x.destroy() - master = tkinter.Frame() + master = tkinter.Frame(self.root) x = ttk.LabeledScale(master) self.assertEqual(x.master, master) x.destroy() @@ -64,25 +70,25 @@ class LabeledScaleTest(unittest.TestCase): # variable initialization/passing passed_expected = (('0', 0), (0, 0), (10, 10), (-1, -1), (sys.maxsize + 1, sys.maxsize + 1)) - if x.tk.wantobjects(): + if self.wantobjects: passed_expected += ((2.5, 2),) for pair in passed_expected: - x = ttk.LabeledScale(from_=pair[0]) + x = ttk.LabeledScale(self.root, from_=pair[0]) self.assertEqual(x.value, pair[1]) x.destroy() - x = ttk.LabeledScale(from_='2.5') + x = ttk.LabeledScale(self.root, from_='2.5') self.assertRaises(ValueError, x._variable.get) x.destroy() - x = ttk.LabeledScale(from_=None) + x = ttk.LabeledScale(self.root, from_=None) self.assertRaises(ValueError, x._variable.get) x.destroy() # variable should have its default value set to the from_ value - myvar = tkinter.DoubleVar(value=20) - x = ttk.LabeledScale(variable=myvar) + myvar = tkinter.DoubleVar(self.root, value=20) + x = ttk.LabeledScale(self.root, variable=myvar) self.assertEqual(x.value, 0) x.destroy() # check that it is really using a DoubleVar - x = ttk.LabeledScale(variable=myvar, from_=0.5) + x = ttk.LabeledScale(self.root, variable=myvar, from_=0.5) self.assertEqual(x.value, 0.5) self.assertEqual(x._variable._name, myvar._name) x.destroy() @@ -91,25 +97,26 @@ class LabeledScaleTest(unittest.TestCase): def check_positions(scale, scale_pos, label, label_pos): self.assertEqual(scale.pack_info()['side'], scale_pos) self.assertEqual(label.place_info()['anchor'], label_pos) - x = ttk.LabeledScale(compound='top') + x = ttk.LabeledScale(self.root, compound='top') check_positions(x.scale, 'bottom', x.label, 'n') x.destroy() - x = ttk.LabeledScale(compound='bottom') + x = ttk.LabeledScale(self.root, compound='bottom') check_positions(x.scale, 'top', x.label, 's') x.destroy() - x = ttk.LabeledScale(compound='unknown') # invert default positions + # invert default positions + x = ttk.LabeledScale(self.root, compound='unknown') check_positions(x.scale, 'top', x.label, 's') x.destroy() - x = ttk.LabeledScale() # take default positions + x = ttk.LabeledScale(self.root) # take default positions check_positions(x.scale, 'bottom', x.label, 'n') x.destroy() # extra, and invalid, kwargs - self.assertRaises(tkinter.TclError, ttk.LabeledScale, a='b') + self.assertRaises(tkinter.TclError, ttk.LabeledScale, master, a='b') def test_horizontal_range(self): - lscale = ttk.LabeledScale(from_=0, to=10) + lscale = ttk.LabeledScale(self.root, from_=0, to=10) lscale.pack() lscale.wait_visibility() lscale.update() @@ -128,7 +135,7 @@ class LabeledScaleTest(unittest.TestCase): self.assertNotEqual(prev_xcoord, curr_xcoord) # the label widget should have been repositioned too linfo_2 = lscale.label.place_info() - self.assertEqual(lscale.label['text'], 0 if lscale.tk.wantobjects() else '0') + self.assertEqual(lscale.label['text'], 0 if self.wantobjects else '0') self.assertEqual(curr_xcoord, int(linfo_2['x'])) # change the range back lscale.scale.configure(from_=0, to=10) @@ -139,7 +146,7 @@ class LabeledScaleTest(unittest.TestCase): def test_variable_change(self): - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) x.pack() x.wait_visibility() x.update() @@ -151,13 +158,13 @@ class LabeledScaleTest(unittest.TestCase): # at the same time this shouldn't affect test outcome x.update() self.assertEqual(x.label['text'], - newval if x.tk.wantobjects() else str(newval)) + newval if self.wantobjects else str(newval)) self.assertGreater(x.scale.coords()[0], curr_xcoord) self.assertEqual(x.scale.coords()[0], int(x.label.place_info()['x'])) # value outside range - if x.tk.wantobjects(): + if self.wantobjects: conv = lambda x: x else: conv = int @@ -171,7 +178,7 @@ class LabeledScaleTest(unittest.TestCase): def test_resize(self): - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) x.pack(expand=True, fill='both') x.wait_visibility() x.update() @@ -190,20 +197,20 @@ class LabeledScaleTest(unittest.TestCase): x.destroy() -class OptionMenuTest(unittest.TestCase): +class OptionMenuTest(AbstractTkTest, unittest.TestCase): def setUp(self): - support.root_deiconify() - self.textvar = tkinter.StringVar() + super().setUp() + self.textvar = tkinter.StringVar(self.root) def tearDown(self): del self.textvar - support.root_withdraw() + super().tearDown() def test_widget_destroy(self): - var = tkinter.StringVar() - optmenu = ttk.OptionMenu(None, var) + var = tkinter.StringVar(self.root) + optmenu = ttk.OptionMenu(self.root, var) name = var._name optmenu.update_idletasks() optmenu.destroy() @@ -214,9 +221,9 @@ class OptionMenuTest(unittest.TestCase): def test_initialization(self): self.assertRaises(tkinter.TclError, - ttk.OptionMenu, None, self.textvar, invalid='thing') + ttk.OptionMenu, self.root, self.textvar, invalid='thing') - optmenu = ttk.OptionMenu(None, self.textvar, 'b', 'a', 'b') + optmenu = ttk.OptionMenu(self.root, self.textvar, 'b', 'a', 'b') self.assertEqual(optmenu._variable.get(), 'b') self.assertTrue(optmenu['menu']) @@ -228,7 +235,7 @@ class OptionMenuTest(unittest.TestCase): def test_menu(self): items = ('a', 'b', 'c') default = 'a' - optmenu = ttk.OptionMenu(None, self.textvar, default, *items) + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) found_default = False for i in range(len(items)): value = optmenu['menu'].entrycget(i, 'value') @@ -240,7 +247,7 @@ class OptionMenuTest(unittest.TestCase): # default shouldn't be in menu if it is not part of values default = 'd' - optmenu = ttk.OptionMenu(None, self.textvar, default, *items) + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) curr = None i = 0 while True: @@ -269,7 +276,7 @@ class OptionMenuTest(unittest.TestCase): def cb_test(item): self.assertEqual(item, items[1]) success.append(True) - optmenu = ttk.OptionMenu(None, self.textvar, 'a', command=cb_test, + optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test, *items) optmenu['menu'].invoke(1) if not success: diff --git a/Lib/tkinter/test/test_ttk/test_functions.py b/Lib/tkinter/test/test_ttk/test_functions.py index 1986e66..c9dcf97 100644 --- a/Lib/tkinter/test/test_ttk/test_functions.py +++ b/Lib/tkinter/test/test_ttk/test_functions.py @@ -1,7 +1,19 @@ # -*- encoding: utf-8 -*- import unittest +import tkinter from tkinter import ttk +class MockTkApp: + + def splitlist(self, arg): + if isinstance(arg, tuple): + return arg + return arg.split(':') + + def wantobjects(self): + return True + + class MockTclObj(object): typename = 'test' @@ -312,26 +324,13 @@ class InternalFunctionsTest(unittest.TestCase): "-opt {3 2m}") - def test_dict_from_tcltuple(self): - fakettuple = ('-a', '{1 2 3}', '-something', 'foo') - - self.assertEqual(ttk._dict_from_tcltuple(fakettuple, False), - {'-a': '{1 2 3}', '-something': 'foo'}) - - self.assertEqual(ttk._dict_from_tcltuple(fakettuple), - {'a': '{1 2 3}', 'something': 'foo'}) - - # passing a tuple with a single item should return an empty dict, - # since it tries to break the tuple by pairs. - self.assertFalse(ttk._dict_from_tcltuple(('single', ))) - - sspec = MockStateSpec('a', 'b') - self.assertEqual(ttk._dict_from_tcltuple(('-a', (sspec, 'val'))), - {'a': [('a', 'b', 'val')]}) - - self.assertEqual(ttk._dict_from_tcltuple((MockTclObj('-padding'), - [MockTclObj('1'), 2, MockTclObj('3m')])), - {'padding': [1, 2, '3m']}) + def test_tclobj_to_py(self): + self.assertEqual( + ttk._tclobj_to_py((MockStateSpec('a', 'b'), 'val')), + [('a', 'b', 'val')]) + self.assertEqual( + ttk._tclobj_to_py([MockTclObj('1'), 2, MockTclObj('3m')]), + [1, 2, '3m']) def test_list_from_statespec(self): @@ -352,20 +351,22 @@ class InternalFunctionsTest(unittest.TestCase): def test_list_from_layouttuple(self): + tk = MockTkApp() + # empty layout tuple - self.assertFalse(ttk._list_from_layouttuple(())) + self.assertFalse(ttk._list_from_layouttuple(tk, ())) # shortest layout tuple - self.assertEqual(ttk._list_from_layouttuple(('name', )), + self.assertEqual(ttk._list_from_layouttuple(tk, ('name', )), [('name', {})]) # not so interesting ltuple sample_ltuple = ('name', '-option', 'value') - self.assertEqual(ttk._list_from_layouttuple(sample_ltuple), + self.assertEqual(ttk._list_from_layouttuple(tk, sample_ltuple), [('name', {'option': 'value'})]) # empty children - self.assertEqual(ttk._list_from_layouttuple( + self.assertEqual(ttk._list_from_layouttuple(tk, ('something', '-children', ())), [('something', {'children': []})] ) @@ -378,7 +379,7 @@ class InternalFunctionsTest(unittest.TestCase): ) ) ) - self.assertEqual(ttk._list_from_layouttuple(ltuple), + self.assertEqual(ttk._list_from_layouttuple(tk, ltuple), [('name', {'option': 'niceone', 'children': [('otherone', {'otheropt': 'othervalue', 'children': [('child', {})] @@ -387,29 +388,35 @@ class InternalFunctionsTest(unittest.TestCase): ) # bad tuples - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('name', 'no_minus')) - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('name', 'no_minus', 'value')) - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('something', '-children')) # no children - import tkinter - if not tkinter._default_root or tkinter._default_root.wantobjects(): - self.assertRaises(ValueError, ttk._list_from_layouttuple, - ('something', '-children', 'value')) # invalid children def test_val_or_dict(self): - def func(opt, val=None): + def func(res, opt=None, val=None): + if opt is None: + return res if val is None: return "test val" return (opt, val) - options = {'test': None} - self.assertEqual(ttk._val_or_dict(options, func), "test val") + tk = MockTkApp() + tk.call = func + + self.assertEqual(ttk._val_or_dict(tk, {}, '-test:3'), + {'test': '3'}) + self.assertEqual(ttk._val_or_dict(tk, {}, ('-test', 3)), + {'test': 3}) + + self.assertEqual(ttk._val_or_dict(tk, {'test': None}, 'x:y'), + 'test val') - options = {'test': 3} - self.assertEqual(ttk._val_or_dict(options, func), options) + self.assertEqual(ttk._val_or_dict(tk, {'test': 3}, 'x:y'), + {'test': 3}) def test_convert_stringval(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/tkinter/test/test_ttk/test_style.py index 0da0e5d..3537536 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/tkinter/test/test_ttk/test_style.py @@ -2,15 +2,15 @@ import unittest import tkinter from tkinter import ttk from test.support import requires, run_unittest - -import tkinter.test.support as support +from tkinter.test.support import AbstractTkTest requires('gui') -class StyleTest(unittest.TestCase): +class StyleTest(AbstractTkTest, unittest.TestCase): def setUp(self): - self.style = ttk.Style() + super().setUp() + self.style = ttk.Style(self.root) def test_configure(self): @@ -25,7 +25,7 @@ class StyleTest(unittest.TestCase): style = self.style style.map('TButton', background=[('active', 'background', 'blue')]) self.assertEqual(style.map('TButton', 'background'), - [('active', 'background', 'blue')] if style.tk.wantobjects() else + [('active', 'background', 'blue')] if self.wantobjects else [('active background', 'blue')]) self.assertIsInstance(style.map('TButton'), dict) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py index 3ac14be..afd3230 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -1,12 +1,12 @@ import unittest import tkinter -from tkinter import ttk +from tkinter import ttk, TclError from test.support import requires import sys -import tkinter.test.support as support from tkinter.test.test_ttk.test_functions import MockTclObj -from tkinter.test.support import tcl_version, get_tk_patchlevel +from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, + simulate_mouse_click) from tkinter.test.widget_tests import (add_standard_options, noconv, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -20,7 +20,7 @@ class StandardTtkOptionsTests(StandardOptionsTests): widget = self.create() self.assertEqual(widget['class'], '') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3 + if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg) widget2 = self.create(class_='Foo') @@ -53,19 +53,15 @@ class StandardTtkOptionsTests(StandardOptionsTests): pass -class WidgetTest(unittest.TestCase): +class WidgetTest(AbstractTkTest, unittest.TestCase): """Tests methods available in every ttk widget.""" def setUp(self): - support.root_deiconify() - self.widget = ttk.Button(width=0, text="Text") + super().setUp() + self.widget = ttk.Button(self.root, width=0, text="Text") self.widget.pack() self.widget.wait_visibility() - def tearDown(self): - self.widget.destroy() - support.root_withdraw() - def test_identify(self): self.widget.update_idletasks() @@ -128,7 +124,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase): 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Frame(self.root, **kwargs) @@ -141,7 +137,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 'text', 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.LabelFrame(self.root, **kwargs) def test_labelanchor(self): @@ -161,8 +157,8 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): class AbstractLabelTest(AbstractWidgetTest): def checkImageParam(self, widget, name): - image = tkinter.PhotoImage('image1') - image2 = tkinter.PhotoImage('image2') + image = tkinter.PhotoImage(master=self.root, name='image1') + image2 = tkinter.PhotoImage(master=self.root, name='image2') self.checkParam(widget, name, image, expected=('image1',)) self.checkParam(widget, name, 'image1', expected=('image1',)) self.checkParam(widget, name, (image,), expected=('image1',)) @@ -199,7 +195,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): ) _conv_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Label(self.root, **kwargs) def test_font(self): @@ -216,7 +212,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Button(self.root, **kwargs) def test_default(self): @@ -225,7 +221,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): def test_invoke(self): success = [] - btn = ttk.Button(command=lambda: success.append(1)) + btn = ttk.Button(self.root, command=lambda: success.append(1)) btn.invoke() self.assertTrue(success) @@ -241,7 +237,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'variable', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Checkbutton(self.root, **kwargs) def test_offvalue(self): @@ -258,7 +254,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): success.append(1) return "cb test called" - cbtn = ttk.Checkbutton(command=cb_test) + cbtn = ttk.Checkbutton(self.root, command=cb_test) # the variable automatically created by ttk.Checkbutton is actually # undefined till we invoke the Checkbutton self.assertEqual(cbtn.state(), ('alternate', )) @@ -289,15 +285,9 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.combo = self.create() - def tearDown(self): - self.combo.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Combobox(self.root, **kwargs) def test_height(self): @@ -362,7 +352,8 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase): expected=('mon', 'tue', 'wed', 'thur')) self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur')) self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string')) - self.checkParam(self.combo, 'values', '', expected=()) + self.checkParam(self.combo, 'values', '', + expected='' if get_tk_patchlevel() < (8, 5, 10) else ()) self.combo['values'] = ['a', 1, 'c'] @@ -405,7 +396,7 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase): self.assertRaises(tkinter.TclError, self.combo.current, '') # testing creating combobox with empty string in values - combo2 = ttk.Combobox(values=[1, 2, '']) + combo2 = ttk.Combobox(self.root, values=[1, 2, '']) self.assertEqual(combo2['values'], ('1', '2', '') if self.wantobjects else '1 2 {}') combo2.destroy() @@ -423,15 +414,9 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.entry = self.create() - def tearDown(self): - self.entry.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Entry(self.root, **kwargs) def test_invalidcommand(self): @@ -460,10 +445,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): def test_bbox(self): - self.assertEqual(len(self.entry.bbox(0)), 4) - for item in self.entry.bbox(0): - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(self.entry.bbox(0)) self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') self.assertRaises(tkinter.TclError, self.entry.bbox, None) @@ -561,22 +543,16 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.paned = self.create() - def tearDown(self): - self.paned.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.PanedWindow(self.root, **kwargs) def test_orient(self): widget = self.create() self.assertEqual(str(widget['orient']), 'vertical') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3 + if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'orient', 'horizontal', errmsg=errmsg) @@ -591,13 +567,13 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): label.destroy() child.destroy() # another attempt - label = ttk.Label() + label = ttk.Label(self.root) child = ttk.Label(label) self.assertRaises(tkinter.TclError, self.paned.add, child) child.destroy() label.destroy() - good_child = ttk.Label() + good_child = ttk.Label(self.root) self.paned.add(good_child) # re-adding a child is not accepted self.assertRaises(tkinter.TclError, self.paned.add, good_child) @@ -615,7 +591,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): self.assertRaises(tkinter.TclError, self.paned.forget, None) self.assertRaises(tkinter.TclError, self.paned.forget, 0) - self.paned.add(ttk.Label()) + self.paned.add(ttk.Label(self.root)) self.paned.forget(0) self.assertRaises(tkinter.TclError, self.paned.forget, 0) @@ -625,9 +601,9 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): self.assertRaises(tkinter.TclError, self.paned.insert, 0, None) self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0) - child = ttk.Label() - child2 = ttk.Label() - child3 = ttk.Label() + child = ttk.Label(self.root) + child2 = ttk.Label(self.root) + child3 = ttk.Label(self.root) self.assertRaises(tkinter.TclError, self.paned.insert, 0, child) @@ -658,7 +634,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_pane(self): self.assertRaises(tkinter.TclError, self.paned.pane, 0) - child = ttk.Label() + child = ttk.Label(self.root) self.paned.add(child) self.assertIsInstance(self.paned.pane(0), dict) self.assertEqual(self.paned.pane(0, weight=None), @@ -703,7 +679,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'value', 'variable', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Radiobutton(self.root, **kwargs) def test_value(self): @@ -716,9 +692,11 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): success.append(1) return "cb test called" - myvar = tkinter.IntVar() - cbtn = ttk.Radiobutton(command=cb_test, variable=myvar, value=0) - cbtn2 = ttk.Radiobutton(command=cb_test, variable=myvar, value=1) + myvar = tkinter.IntVar(self.root) + cbtn = ttk.Radiobutton(self.root, command=cb_test, + variable=myvar, value=0) + cbtn2 = ttk.Radiobutton(self.root, command=cb_test, + variable=myvar, value=1) if self.wantobjects: conv = lambda x: x @@ -751,7 +729,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Menubutton(self.root, **kwargs) def test_direction(self): @@ -777,17 +755,11 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.scale = self.create() self.scale.pack() self.scale.update() - def tearDown(self): - self.scale.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Scale(self.root, **kwargs) def test_from(self): @@ -859,7 +831,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): self.assertEqual(conv(self.scale.get()), min) # changing directly the variable doesn't impose this limitation tho - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.scale['variable'] = var var.set(max + 5) self.assertEqual(conv(self.scale.get()), var.get()) @@ -889,7 +861,7 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): _conv_pixels = noconv default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Progressbar(self.root, **kwargs) def test_length(self): @@ -923,7 +895,7 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Scrollbar(self.root, **kwargs) @@ -935,21 +907,13 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.nb = self.create(padding=0) - self.child1 = ttk.Label() - self.child2 = ttk.Label() + self.child1 = ttk.Label(self.root) + self.child2 = ttk.Label(self.root) self.nb.add(self.child1, text='a') self.nb.add(self.child2, text='b') - def tearDown(self): - self.child1.destroy() - self.child2.destroy() - self.nb.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Notebook(self.root, **kwargs) def test_tab_identifiers(self): @@ -988,7 +952,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): self.assertRaises(tkinter.TclError, self.nb.hide, 'hi') self.assertRaises(tkinter.TclError, self.nb.hide, None) self.assertRaises(tkinter.TclError, self.nb.add, None) - self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(), + self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root), unknown='option') tabs = self.nb.tabs() @@ -996,7 +960,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): self.nb.add(self.child1) self.assertEqual(self.nb.tabs(), tabs) - child = ttk.Label() + child = ttk.Label(self.root) self.nb.add(child, text='c') tabs = self.nb.tabs() @@ -1054,7 +1018,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0]) # new tab - child3 = ttk.Label() + child3 = ttk.Label(self.root) self.nb.insert(1, child3) self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1])) self.nb.forget(child3) @@ -1120,7 +1084,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): self.nb.select(0) - support.simulate_mouse_click(self.nb, 5, 5) + simulate_mouse_click(self.nb, 5, 5) self.nb.focus_force() self.nb.event_generate('<Control-Tab>') self.assertEqual(self.nb.select(), str(self.child2)) @@ -1134,7 +1098,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): self.nb.tab(self.child1, text='a', underline=0) self.nb.enable_traversal() self.nb.focus_force() - support.simulate_mouse_click(self.nb, 5, 5) + simulate_mouse_click(self.nb, 5, 5) if sys.platform == 'darwin': self.nb.event_generate('<Option-a>') else: @@ -1152,15 +1116,9 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.tv = self.create(padding=0) - def tearDown(self): - self.tv.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Treeview(self.root, **kwargs) def test_columns(self): @@ -1168,7 +1126,8 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): self.checkParam(widget, 'columns', 'a b c', expected=('a', 'b', 'c')) self.checkParam(widget, 'columns', ('a', 'b', 'c')) - self.checkParam(widget, 'columns', ()) + self.checkParam(widget, 'columns', (), + expected='' if get_tk_patchlevel() < (8, 5, 10) else ()) def test_displaycolumns(self): widget = self.create() @@ -1216,12 +1175,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): self.assertTrue(children) bbox = self.tv.bbox(children[0]) - self.assertEqual(len(bbox), 4) - self.assertIsInstance(bbox, tuple) - for item in bbox: - if not isinstance(item, int): - self.fail("Invalid bounding box: %s" % bbox) - break + self.assertIsBoundingBox(bbox) # compare width in bboxes self.tv['columns'] = ['test'] @@ -1401,7 +1355,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): def test_heading_callback(self): def simulate_heading_click(x, y): - support.simulate_mouse_click(self.tv, x, y) + simulate_mouse_click(self.tv, x, y) self.tv.update() success = [] # no success for now @@ -1590,7 +1544,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): self.assertEqual(len(pos_y), 2) # item1 and item2 y pos for y in pos_y: - support.simulate_mouse_click(self.tv, 0, y) + simulate_mouse_click(self.tv, 0, y) # by now there should be 4 things in the events list, since each # item had a bind for two events that were simulated above @@ -1611,6 +1565,21 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): 'blue') self.assertIsInstance(self.tv.tag_configure('test'), dict) + def test_tag_has(self): + item1 = self.tv.insert('', 'end', text='Item 1', tags=['tag1']) + item2 = self.tv.insert('', 'end', text='Item 2', tags=['tag2']) + self.assertRaises(TypeError, self.tv.tag_has) + self.assertRaises(TclError, self.tv.tag_has, 'tag1', 'non-existing') + self.assertTrue(self.tv.tag_has('tag1', item1)) + self.assertFalse(self.tv.tag_has('tag1', item2)) + self.assertFalse(self.tv.tag_has('tag2', item1)) + self.assertTrue(self.tv.tag_has('tag2', item2)) + self.assertFalse(self.tv.tag_has('tag3', item1)) + self.assertFalse(self.tv.tag_has('tag3', item2)) + self.assertEqual(self.tv.tag_has('tag1'), (item1,)) + self.assertEqual(self.tv.tag_has('tag2'), (item2,)) + self.assertEqual(self.tv.tag_has('tag3'), ()) + @add_standard_options(StandardTtkOptionsTests) class SeparatorTest(AbstractWidgetTest, unittest.TestCase): @@ -1620,7 +1589,7 @@ class SeparatorTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Separator(self.root, **kwargs) @@ -1631,7 +1600,7 @@ class SizegripTest(AbstractWidgetTest, unittest.TestCase): # 'state'? ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Sizegrip(self.root, **kwargs) tests_gui = ( diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/tkinter/test/widget_tests.py index a9820a7..779538d 100644 --- a/Lib/tkinter/test/widget_tests.py +++ b/Lib/tkinter/test/widget_tests.py @@ -3,9 +3,9 @@ import unittest import sys import tkinter -from tkinter.ttk import setup_master, Scale -from tkinter.test.support import (tcl_version, requires_tcl, get_tk_patchlevel, - pixels_conv, tcl_obj_eq) +from tkinter.ttk import Scale +from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl, + get_tk_patchlevel, pixels_conv, tcl_obj_eq) import test.support @@ -22,21 +22,25 @@ if get_tk_patchlevel()[:3] == (8, 5, 11): _sentinel = object() -class AbstractWidgetTest: +class AbstractWidgetTest(AbstractTkTest): _conv_pixels = staticmethod(pixels_round) _conv_pad_pixels = None - wantobjects = True - - def setUp(self): - self.root = setup_master() - self.scaling = float(self.root.call('tk', 'scaling')) - if not self.root.wantobjects(): - self.wantobjects = False - - def create(self, **kwargs): - widget = self._create(**kwargs) - self.addCleanup(widget.destroy) - return widget + _stringify = False + + @property + def scaling(self): + try: + return self._scaling + except AttributeError: + self._scaling = float(self.root.call('tk', 'scaling')) + return self._scaling + + def _str(self, value): + if not self._stringify and self.wantobjects and tcl_version >= (8, 6): + return value + if isinstance(value, tuple): + return ' '.join(map(self._str, value)) + return str(value) def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__): if eq(actual, expected): @@ -50,7 +54,7 @@ class AbstractWidgetTest: expected = value if conv: expected = conv(expected) - if not self.wantobjects: + if self._stringify or not self.wantobjects: if isinstance(expected, tuple): expected = tkinter._join(expected) else: @@ -182,7 +186,7 @@ class AbstractWidgetTest: errmsg=errmsg) def checkImageParam(self, widget, name): - image = tkinter.PhotoImage('image1') + image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, name, image, conv=str) self.checkInvalidParam(widget, name, 'spam', errmsg='image "spam" doesn\'t exist') @@ -191,6 +195,16 @@ class AbstractWidgetTest: def checkVariableParam(self, widget, name, var): self.checkParam(widget, name, var, conv=str) + def assertIsBoundingBox(self, bbox): + self.assertIsNotNone(bbox) + self.assertIsInstance(bbox, tuple) + if len(bbox) != 4: + self.fail('Invalid bounding box: %r' % (bbox,)) + for item in bbox: + if not isinstance(item, int): + self.fail('Invalid bounding box: %r' % (bbox,)) + break + class StandardOptionsTests: STANDARD_OPTIONS = ( @@ -393,7 +407,7 @@ class StandardOptionsTests: def test_textvariable(self): widget = self.create() - var = tkinter.StringVar() + var = tkinter.StringVar(self.root) self.checkVariableParam(widget, 'textvariable', var) def test_troughcolor(self): @@ -454,7 +468,7 @@ class StandardOptionsTests: def test_variable(self): widget = self.create() - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.checkVariableParam(widget, 'variable', var) |
