diff options
Diffstat (limited to 'lib/python2.7/lib-tk/test')
17 files changed, 6144 insertions, 0 deletions
diff --git a/lib/python2.7/lib-tk/test/README b/lib/python2.7/lib-tk/test/README new file mode 100644 index 0000000..79cd16c --- /dev/null +++ b/lib/python2.7/lib-tk/test/README @@ -0,0 +1,14 @@ +Writing new tests +================= + +Precaution +---------- + + New tests should always use only one Tk window at once, like all the + current tests do. This means that you have to destroy the current window + before creating another one, and clean up after the test. The motivation + behind this is that some tests may depend on having its window focused + while it is running to work properly, and it may be hard to force focus + on your window across platforms (right now only test_traversal at + test_ttk.test_widgets.NotebookTest depends on this). + diff --git a/lib/python2.7/lib-tk/test/runtktests.py b/lib/python2.7/lib-tk/test/runtktests.py new file mode 100644 index 0000000..d4b1893 --- /dev/null +++ b/lib/python2.7/lib-tk/test/runtktests.py @@ -0,0 +1,70 @@ +""" +Use this module to get and run all tk tests. + +Tkinter tests should live in a package inside the directory where this file +lives, like test_tkinter. +Extensions also should live in packages following the same rule as above. +""" + +import os +import sys +import unittest +import importlib +import test.test_support + +this_dir_path = os.path.abspath(os.path.dirname(__file__)) + +def is_package(path): + for name in os.listdir(path): + if name in ('__init__.py', '__init__.pyc', '__init.pyo'): + return True + return False + +def get_tests_modules(basepath=this_dir_path, gui=True, packages=None): + """This will import and yield modules whose names start with test_ + and are inside packages found in the path starting at basepath. + + If packages is specified it should contain package names that want + their tests collected. + """ + py_ext = '.py' + + for dirpath, dirnames, filenames in os.walk(basepath): + for dirname in list(dirnames): + if dirname[0] == '.': + dirnames.remove(dirname) + + if is_package(dirpath) and filenames: + pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.') + if packages and pkg_name not in packages: + continue + + filenames = filter( + lambda x: x.startswith('test_') and x.endswith(py_ext), + filenames) + + for name in filenames: + try: + yield importlib.import_module( + ".%s" % name[:-len(py_ext)], pkg_name) + except test.test_support.ResourceDenied: + if gui: + raise + +def get_tests(text=True, gui=True, packages=None): + """Yield all the tests in the modules found by get_tests_modules. + + If nogui is True, only tests that do not require a GUI will be + returned.""" + attrs = [] + if text: + attrs.append('tests_nogui') + if gui: + attrs.append('tests_gui') + for module in get_tests_modules(gui=gui, packages=packages): + for attr in attrs: + for test in getattr(module, attr, ()): + yield test + +if __name__ == "__main__": + test.test_support.run_unittest(*get_tests()) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/__init__.py b/lib/python2.7/lib-tk/test/test_tkinter/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/__init__.py diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_font.py b/lib/python2.7/lib-tk/test/test_tkinter/test_font.py new file mode 100644 index 0000000..4cbf82e --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_font.py @@ -0,0 +1,97 @@ +import unittest +import Tkinter as tkinter +import tkFont as font +from test.test_support import requires, run_unittest +from test_ttk.support import AbstractTkTest + +requires('gui') + +fontname = "TkDefaultFont" + +class FontTest(AbstractTkTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) + try: + 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) + self.assertNotIn(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, unicode)) + 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, unicode)) + self.assertTrue(name) + self.assertIn(fontname, names) + +tests_gui = (FontTest, ) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_geometry_managers.py b/lib/python2.7/lib-tk/test/test_tkinter/test_geometry_managers.py new file mode 100644 index 0000000..941fb31 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_geometry_managers.py @@ -0,0 +1,893 @@ +import unittest +import re +import Tkinter as tkinter +from Tkinter import TclError +from test.test_support import requires, run_unittest + +from test_ttk.support import pixels_conv, tcl_version, requires_tcl +from widget_tests import AbstractWidgetTest, int_round + +requires('gui') + + +class PackTest(AbstractWidgetTest, unittest.TestCase): + + test_keys = None + + 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.assertRaisesRegexp(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(after=b) + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(before=b) + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, + 'can\'t pack %s inside itself' % (a,)): + a.pack_configure(in_=a) + with self.assertRaisesRegexp(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.assertRaisesRegexp(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): + + test_keys = None + + 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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad anchor "j"'): + f.place_configure(anchor='j') + with self.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad bordermode "j"'): + f.place_configure(bordermode='j') + with self.assertRaisesRegexp(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): + + test_keys = None + + 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) + super(GridTest, self).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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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(int_round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_ipady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegexp(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(int_round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_padx(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegexp(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(int_round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_pady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegexp(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(int_round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_row(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad option "-foo"'): + self.root.grid_columnconfigure(0, 'foo') + self.root.grid_columnconfigure((0, 3), weight=2) + with self.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'expected integer but got "bad"'): + self.root.grid_columnconfigure(0, weight='bad') + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad screen distance "foo"'): + self.root.grid_columnconfigure(0, pad='foo') + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad option "-foo"'): + self.root.grid_rowconfigure(0, 'foo') + self.root.grid_rowconfigure((0, 3), weight=2) + with self.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'expected integer but got "bad"'): + self.root.grid_rowconfigure(0, weight='bad') + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad screen distance "foo"'): + self.root.grid_rowconfigure(0, pad='foo') + with self.assertRaisesRegexp(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') + + 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.assertRaisesRegexp(TclError, 'expected integer but got "x"'): + self.root.grid_bbox('x', 0) + with self.assertRaisesRegexp(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 'x') + with self.assertRaisesRegexp(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 0, 'x', 0) + with self.assertRaisesRegexp(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.assertRaisesRegexp(TclError, 'bad screen distance "x"'): + self.root.grid_location('x', 'y') + with self.assertRaisesRegexp(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__': + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_images.py b/lib/python2.7/lib-tk/test/test_tkinter/test_images.py new file mode 100644 index 0000000..b9f9773 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_images.py @@ -0,0 +1,328 @@ +import unittest +import Tkinter as tkinter +import ttk +import test.test_support as support +from test_ttk.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)) + 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)) + + 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/python2.7/lib-tk/test/test_tkinter/test_loadtk.py b/lib/python2.7/lib-tk/test/test_tkinter/test_loadtk.py new file mode 100644 index 0000000..32c640d --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_loadtk.py @@ -0,0 +1,45 @@ +import os +import sys +import unittest +from test import test_support +from Tkinter import Tcl, TclError + +test_support.requires('gui') + +class TkLoadTest(unittest.TestCase): + + @unittest.skipIf('DISPLAY' not in os.environ, 'No $DISPLAY set.') + def testLoadTk(self): + tcl = Tcl() + self.assertRaises(TclError,tcl.winfo_geometry) + tcl.loadtk() + self.assertEqual('1x1+0+0', tcl.winfo_geometry()) + tcl.destroy() + + def testLoadTkFailure(self): + old_display = None + if sys.platform.startswith(('win', 'darwin', 'cygwin')): + # no failure possible on windows? + + # XXX Maybe on tk older than 8.4.13 it would be possible, + # see tkinter.h. + return + with test_support.EnvironmentVarGuard() as env: + if 'DISPLAY' in os.environ: + del env['DISPLAY'] + # on some platforms, deleting environment variables + # doesn't actually carry through to the process level + # because they don't support unsetenv + # If that's the case, abort. + display = os.popen('echo $DISPLAY').read().strip() + if display: + return + + tcl = Tcl() + self.assertRaises(TclError, tcl.winfo_geometry) + self.assertRaises(TclError, tcl.loadtk) + +tests_gui = (TkLoadTest, ) + +if __name__ == "__main__": + test_support.run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_text.py b/lib/python2.7/lib-tk/test/test_tkinter/test_text.py new file mode 100644 index 0000000..a439b6c --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_text.py @@ -0,0 +1,47 @@ +import unittest +import Tkinter as tkinter +from test.test_support import requires, run_unittest +from test_ttk.support import AbstractTkTest + +requires('gui') + +class TextTest(AbstractTkTest, unittest.TestCase): + + def setUp(self): + super(TextTest, self).setUp() + self.text = tkinter.Text(self.root) + + def test_debug(self): + text = self.text + olddebug = text.debug() + try: + text.debug(0) + self.assertEqual(text.debug(), 0) + text.debug(1) + self.assertEqual(text.debug(), 1) + finally: + text.debug(olddebug) + self.assertEqual(text.debug(), olddebug) + + def test_search(self): + text = self.text + + # pattern and index are obligatory arguments. + self.assertRaises(tkinter.TclError, text.search, None, '1.0') + self.assertRaises(tkinter.TclError, text.search, 'a', None) + self.assertRaises(tkinter.TclError, text.search, None, None) + + # Invalid text index. + self.assertRaises(tkinter.TclError, text.search, '', 0) + + # Check if we are getting the indices as strings -- you are likely + # to get Tcl_Obj under Tk 8.5 if Tkinter doesn't convert it. + text.insert('1.0', 'hi-test') + self.assertEqual(text.search('-test', '1.0', 'end'), '1.2') + self.assertEqual(text.search('test', '1.0', 'end'), '1.3') + + +tests_gui = (TextTest, ) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_variables.py b/lib/python2.7/lib-tk/test/test_tkinter/test_variables.py new file mode 100644 index 0000000..11f9414 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_variables.py @@ -0,0 +1,257 @@ +import unittest +import gc +from Tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, + TclError) + + +class TestBase(unittest.TestCase): + + def setUp(self): + self.root = Tcl() + + def tearDown(self): + del self.root + + +class TestVariable(TestBase): + + def info_exists(self, *args): + return self.root.getboolean(self.root.call("info", "exists", *args)) + + def test_default(self): + v = Variable(self.root) + self.assertEqual("", v.get()) + self.assertRegexpMatches(str(v), r"^PY_VAR(\d+)$") + + def test_name_and_value(self): + v = Variable(self.root, "sample string", "varname") + self.assertEqual("sample string", v.get()) + self.assertEqual("varname", str(v)) + + def test___del__(self): + self.assertFalse(self.info_exists("varname")) + v = Variable(self.root, "sample string", "varname") + self.assertTrue(self.info_exists("varname")) + del v + self.assertFalse(self.info_exists("varname")) + + def test_dont_unset_not_existing(self): + self.assertFalse(self.info_exists("varname")) + v1 = Variable(self.root, name="name") + v2 = Variable(self.root, name="name") + del v1 + self.assertFalse(self.info_exists("name")) + # shouldn't raise exception + del v2 + self.assertFalse(self.info_exists("name")) + + def test___eq__(self): + # values doesn't matter, only class and name are checked + v1 = Variable(self.root, name="abc") + v2 = Variable(self.root, name="abc") + self.assertEqual(v1, v2) + + v3 = Variable(self.root, name="abc") + v4 = StringVar(self.root, name="abc") + self.assertNotEqual(v3, v4) + + def test_invalid_name(self): + with self.assertRaises(TypeError): + Variable(self.root, name=123) + + def test_null_in_name(self): + with self.assertRaises(ValueError): + Variable(self.root, name='var\x00name') + with self.assertRaises(ValueError): + self.root.globalsetvar('var\x00name', "value") + with self.assertRaises(ValueError): + self.root.setvar('var\x00name', "value") + + def test_trace(self): + v = Variable(self.root) + vname = str(v) + trace = [] + def read_tracer(*args): + trace.append(('read',) + args) + def write_tracer(*args): + trace.append(('write',) + args) + cb1 = v.trace_variable('r', read_tracer) + cb2 = v.trace_variable('wu', write_tracer) + self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)]) + self.assertEqual(trace, []) + + v.set('spam') + self.assertEqual(trace, [('write', vname, '', 'w')]) + + trace = [] + v.get() + self.assertEqual(trace, [('read', vname, '', 'r')]) + + trace = [] + info = sorted(v.trace_vinfo()) + v.trace_vdelete('w', cb1) # Wrong mode + self.assertEqual(sorted(v.trace_vinfo()), info) + with self.assertRaises(TclError): + v.trace_vdelete('r', 'spam') # Wrong command name + self.assertEqual(sorted(v.trace_vinfo()), info) + v.trace_vdelete('r', (cb1, 43)) # Wrong arguments + self.assertEqual(sorted(v.trace_vinfo()), info) + v.get() + self.assertEqual(trace, [('read', vname, '', 'r')]) + + trace = [] + v.trace_vdelete('r', cb1) + self.assertEqual(v.trace_vinfo(), [('wu', cb2)]) + v.get() + self.assertEqual(trace, []) + + trace = [] + del write_tracer + gc.collect() + v.set('eggs') + self.assertEqual(trace, [('write', vname, '', 'w')]) + + #trace = [] + #del v + #gc.collect() + #self.assertEqual(trace, [('write', vname, '', 'u')]) + + +class TestStringVar(TestBase): + + def test_default(self): + v = StringVar(self.root) + self.assertEqual("", v.get()) + + def test_get(self): + v = StringVar(self.root, "abc", "name") + self.assertEqual("abc", v.get()) + self.root.globalsetvar("name", "value") + self.assertEqual("value", v.get()) + + def test_get_null(self): + v = StringVar(self.root, "abc\x00def", "name") + self.assertEqual("abc\x00def", v.get()) + self.root.globalsetvar("name", "val\x00ue") + self.assertEqual("val\x00ue", v.get()) + + +class TestIntVar(TestBase): + + def test_default(self): + v = IntVar(self.root) + self.assertEqual(0, v.get()) + + def test_get(self): + v = IntVar(self.root, 123, "name") + self.assertEqual(123, v.get()) + self.root.globalsetvar("name", "345") + self.assertEqual(345, v.get()) + + def test_invalid_value(self): + v = IntVar(self.root, name="name") + self.root.globalsetvar("name", "value") + with self.assertRaises(ValueError): + v.get() + self.root.globalsetvar("name", "345.0") + with self.assertRaises(ValueError): + v.get() + + +class TestDoubleVar(TestBase): + + def test_default(self): + v = DoubleVar(self.root) + self.assertEqual(0.0, v.get()) + + def test_get(self): + v = DoubleVar(self.root, 1.23, "name") + self.assertAlmostEqual(1.23, v.get()) + self.root.globalsetvar("name", "3.45") + self.assertAlmostEqual(3.45, v.get()) + + def test_get_from_int(self): + v = DoubleVar(self.root, 1.23, "name") + self.assertAlmostEqual(1.23, v.get()) + self.root.globalsetvar("name", "3.45") + self.assertAlmostEqual(3.45, v.get()) + self.root.globalsetvar("name", "456") + self.assertAlmostEqual(456, v.get()) + + def test_invalid_value(self): + v = DoubleVar(self.root, name="name") + self.root.globalsetvar("name", "value") + with self.assertRaises(ValueError): + v.get() + + +class TestBooleanVar(TestBase): + + def test_default(self): + v = BooleanVar(self.root) + self.assertIs(v.get(), False) + + def test_get(self): + v = BooleanVar(self.root, True, "name") + self.assertIs(v.get(), True) + self.root.globalsetvar("name", "0") + 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", 42L if self.root.wantobjects() else 1L) + self.assertIs(v.get(), True) + self.root.globalsetvar("name", 0L) + self.assertIs(v.get(), False) + self.root.globalsetvar("name", "on") + self.assertIs(v.get(), True) + self.root.globalsetvar("name", u"0") + self.assertIs(v.get(), False) + self.root.globalsetvar("name", u"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(42L) + self.assertEqual(self.root.globalgetvar("name"), true) + v.set(0L) + self.assertEqual(self.root.globalgetvar("name"), false) + v.set("on") + self.assertEqual(self.root.globalgetvar("name"), true) + v.set(u"0") + self.assertEqual(self.root.globalgetvar("name"), false) + v.set(u"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(TclError): + v.get() + self.root.globalsetvar("name", "1.0") + with self.assertRaises(TclError): + v.get() + + +tests_gui = (TestVariable, TestStringVar, TestIntVar, + TestDoubleVar, TestBooleanVar) + + +if __name__ == "__main__": + from test.support import run_unittest + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_tkinter/test_widgets.py b/lib/python2.7/lib-tk/test/test_tkinter/test_widgets.py new file mode 100644 index 0000000..4da3096 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_tkinter/test_widgets.py @@ -0,0 +1,1199 @@ +import unittest +import Tkinter as tkinter +from Tkinter import TclError +import os +import sys +from test.test_support import requires, run_unittest + +from test_ttk.support import (tcl_version, requires_tcl, get_tk_patchlevel, + widget_eq) +from widget_tests import ( + add_standard_options, noconv, noconv_meth, int_round, pixels_round, + AbstractWidgetTest, StandardOptionsTests, + IntegerSizeTests, PixelSizeTests, + setUpModule) + +requires('gui') + + +class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): + _conv_pad_pixels = noconv_meth + + def test_class(self): + widget = self.create() + self.assertEqual(widget['class'], + widget.__class__.__name__.title()) + self.checkInvalidParam(widget, 'class', 'Foo', + errmsg="can't modify -class option after widget is created") + widget2 = self.create(class_='Foo') + self.assertEqual(widget2['class'], 'Foo') + + def test_colormap(self): + widget = self.create() + self.assertEqual(widget['colormap'], '') + self.checkInvalidParam(widget, 'colormap', 'new', + errmsg="can't modify -colormap option after widget is created") + widget2 = self.create(colormap='new') + self.assertEqual(widget2['colormap'], 'new') + + def test_container(self): + widget = self.create() + self.assertEqual(widget['container'], 0 if self.wantobjects else '0') + self.checkInvalidParam(widget, 'container', 1, + errmsg="can't modify -container option after widget is created") + widget2 = self.create(container=True) + self.assertEqual(widget2['container'], 1 if self.wantobjects else '1') + + def test_visual(self): + widget = self.create() + self.assertEqual(widget['visual'], '') + self.checkInvalidParam(widget, 'visual', 'default', + errmsg="can't modify -visual option after widget is created") + widget2 = self.create(visual='default') + self.assertEqual(widget2['visual'], 'default') + + +@add_standard_options(StandardOptionsTests) +class ToplevelTest(AbstractToplevelTest, unittest.TestCase): + OPTIONS = ( + 'background', 'borderwidth', + 'class', 'colormap', 'container', 'cursor', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'menu', 'padx', 'pady', 'relief', 'screen', + 'takefocus', 'use', 'visual', 'width', + ) + + def create(self, **kwargs): + return tkinter.Toplevel(self.root, **kwargs) + + def test_menu(self): + widget = self.create() + menu = tkinter.Menu(self.root) + self.checkParam(widget, 'menu', menu, eq=widget_eq) + self.checkParam(widget, 'menu', '') + + def test_screen(self): + widget = self.create() + self.assertEqual(widget['screen'], '') + try: + display = os.environ['DISPLAY'] + except KeyError: + self.skipTest('No $DISPLAY set.') + self.checkInvalidParam(widget, 'screen', display, + errmsg="can't modify -screen option after widget is created") + widget2 = self.create(screen=display) + self.assertEqual(widget2['screen'], display) + + def test_use(self): + widget = self.create() + self.assertEqual(widget['use'], '') + parent = self.create(container=True) + wid = parent.winfo_id() + widget2 = self.create(use=wid) + self.assertEqual(int(widget2['use']), wid) + + +@add_standard_options(StandardOptionsTests) +class FrameTest(AbstractToplevelTest, unittest.TestCase): + OPTIONS = ( + 'background', 'borderwidth', + 'class', 'colormap', 'container', 'cursor', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'padx', 'pady', 'relief', 'takefocus', 'visual', 'width', + ) + + def create(self, **kwargs): + return tkinter.Frame(self.root, **kwargs) + + +@add_standard_options(StandardOptionsTests) +class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): + OPTIONS = ( + 'background', 'borderwidth', + 'class', 'colormap', 'container', 'cursor', + 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'labelanchor', 'labelwidget', 'padx', 'pady', 'relief', + 'takefocus', 'text', 'visual', 'width', + ) + + def create(self, **kwargs): + return tkinter.LabelFrame(self.root, **kwargs) + + def test_labelanchor(self): + widget = self.create() + self.checkEnumParam(widget, 'labelanchor', + 'e', 'en', 'es', 'n', 'ne', 'nw', + 's', 'se', 'sw', 'w', 'wn', 'ws') + self.checkInvalidParam(widget, 'labelanchor', 'center') + + def test_labelwidget(self): + widget = self.create() + label = tkinter.Label(self.root, text='Mupp', name='foo') + self.checkParam(widget, 'labelwidget', label, expected='.foo') + label.destroy() + + +class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests): + _conv_pixels = noconv_meth + + def test_highlightthickness(self): + widget = self.create() + self.checkPixelsParam(widget, 'highlightthickness', + 0, 1.3, 2.6, 6, -2, '10p') + + +@add_standard_options(StandardOptionsTests) +class LabelTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', 'compound', 'cursor', + 'disabledforeground', 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'justify', 'padx', 'pady', 'relief', 'state', + 'takefocus', 'text', 'textvariable', + 'underline', 'width', 'wraplength', + ) + + def create(self, **kwargs): + return tkinter.Label(self.root, **kwargs) + + +@add_standard_options(StandardOptionsTests) +class ButtonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', + 'command', 'compound', 'cursor', 'default', + 'disabledforeground', 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'justify', 'overrelief', 'padx', 'pady', 'relief', + 'repeatdelay', 'repeatinterval', + 'state', 'takefocus', 'text', 'textvariable', + 'underline', 'width', 'wraplength') + + def create(self, **kwargs): + return tkinter.Button(self.root, **kwargs) + + def test_default(self): + widget = self.create() + self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal') + + +@add_standard_options(StandardOptionsTests) +class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', + 'command', 'compound', 'cursor', + 'disabledforeground', 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'indicatoron', 'justify', + 'offrelief', 'offvalue', 'onvalue', 'overrelief', + 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state', + 'takefocus', 'text', 'textvariable', + 'tristateimage', 'tristatevalue', + 'underline', 'variable', 'width', 'wraplength', + ) + + def create(self, **kwargs): + return tkinter.Checkbutton(self.root, **kwargs) + + + def test_offvalue(self): + widget = self.create() + self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string') + + def test_onvalue(self): + widget = self.create() + self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string') + + +@add_standard_options(StandardOptionsTests) +class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', + 'command', 'compound', 'cursor', + 'disabledforeground', 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'indicatoron', 'justify', 'offrelief', 'overrelief', + 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state', + 'takefocus', 'text', 'textvariable', + 'tristateimage', 'tristatevalue', + 'underline', 'value', 'variable', 'width', 'wraplength', + ) + + def create(self, **kwargs): + return tkinter.Radiobutton(self.root, **kwargs) + + def test_value(self): + widget = self.create() + self.checkParams(widget, 'value', 1, 2.3, '', 'any string') + + +@add_standard_options(StandardOptionsTests) +class MenubuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', + 'compound', 'cursor', 'direction', + 'disabledforeground', 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'indicatoron', 'justify', 'menu', + 'padx', 'pady', 'relief', 'state', + 'takefocus', 'text', 'textvariable', + 'underline', 'width', 'wraplength', + ) + _conv_pixels = staticmethod(pixels_round) + + def create(self, **kwargs): + return tkinter.Menubutton(self.root, **kwargs) + + def test_direction(self): + widget = self.create() + self.checkEnumParam(widget, 'direction', + 'above', 'below', 'flush', 'left', 'right') + + def test_height(self): + widget = self.create() + self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str) + + test_highlightthickness = StandardOptionsTests.test_highlightthickness.im_func + + @unittest.skipIf(sys.platform == 'darwin', + 'crashes with Cocoa Tk (issue19733)') + def test_image(self): + widget = self.create() + image = tkinter.PhotoImage(master=self.root, name='image1') + self.checkParam(widget, 'image', image, conv=str) + errmsg = 'image "spam" doesn\'t exist' + with self.assertRaises(tkinter.TclError) as cm: + widget['image'] = 'spam' + if errmsg is not None: + self.assertEqual(str(cm.exception), errmsg) + with self.assertRaises(tkinter.TclError) as cm: + widget.configure({'image': 'spam'}) + if errmsg is not None: + self.assertEqual(str(cm.exception), errmsg) + + def test_menu(self): + widget = self.create() + menu = tkinter.Menu(widget, name='menu') + self.checkParam(widget, 'menu', menu, eq=widget_eq) + menu.destroy() + + def test_padx(self): + widget = self.create() + self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m') + self.checkParam(widget, 'padx', -2, expected=0) + + def test_pady(self): + widget = self.create() + self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m') + self.checkParam(widget, 'pady', -2, expected=0) + + def test_width(self): + widget = self.create() + self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str) + + +class OptionMenuTest(MenubuttonTest, unittest.TestCase): + + def create(self, default='b', values=('a', 'b', 'c'), **kwargs): + return tkinter.OptionMenu(self.root, None, default, *values, **kwargs) + + +@add_standard_options(IntegerSizeTests, StandardOptionsTests) +class EntryTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'background', 'borderwidth', 'cursor', + 'disabledbackground', 'disabledforeground', + 'exportselection', 'font', 'foreground', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'insertbackground', 'insertborderwidth', + 'insertofftime', 'insertontime', 'insertwidth', + 'invalidcommand', 'justify', 'readonlybackground', 'relief', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'show', 'state', 'takefocus', 'textvariable', + 'validate', 'validatecommand', 'width', 'xscrollcommand', + ) + + def create(self, **kwargs): + return tkinter.Entry(self.root, **kwargs) + + def test_disabledbackground(self): + widget = self.create() + self.checkColorParam(widget, 'disabledbackground') + + def test_insertborderwidth(self): + widget = self.create(insertwidth=100) + self.checkPixelsParam(widget, 'insertborderwidth', + 0, 1.3, 2.6, 6, -2, '10p') + # insertborderwidth is bounded above by a half of insertwidth. + self.checkParam(widget, 'insertborderwidth', 60, expected=100//2) + + def test_insertwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p') + self.checkParam(widget, 'insertwidth', 0.1, expected=2) + self.checkParam(widget, 'insertwidth', -2, expected=2) + if pixels_round(0.9) <= 0: + self.checkParam(widget, 'insertwidth', 0.9, expected=2) + else: + self.checkParam(widget, 'insertwidth', 0.9, expected=1) + + def test_invalidcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'invalidcommand') + self.checkCommandParam(widget, 'invcmd') + + def test_readonlybackground(self): + widget = self.create() + self.checkColorParam(widget, 'readonlybackground') + + def test_show(self): + widget = self.create() + self.checkParam(widget, 'show', '*') + self.checkParam(widget, 'show', '') + self.checkParam(widget, 'show', ' ') + + def test_state(self): + widget = self.create() + self.checkEnumParam(widget, 'state', + 'disabled', 'normal', 'readonly') + + def test_validate(self): + widget = self.create() + self.checkEnumParam(widget, 'validate', + 'all', 'key', 'focus', 'focusin', 'focusout', 'none') + + def test_validatecommand(self): + widget = self.create() + self.checkCommandParam(widget, 'validatecommand') + self.checkCommandParam(widget, 'vcmd') + + +@add_standard_options(StandardOptionsTests) +class SpinboxTest(EntryTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'background', 'borderwidth', + 'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief', + 'command', 'cursor', 'disabledbackground', 'disabledforeground', + 'exportselection', 'font', 'foreground', 'format', 'from', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'increment', + 'insertbackground', 'insertborderwidth', + 'insertofftime', 'insertontime', 'insertwidth', + 'invalidcommand', 'justify', 'relief', 'readonlybackground', + 'repeatdelay', 'repeatinterval', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'state', 'takefocus', 'textvariable', 'to', + 'validate', 'validatecommand', 'values', + 'width', 'wrap', 'xscrollcommand', + ) + + def create(self, **kwargs): + return tkinter.Spinbox(self.root, **kwargs) + + test_show = None + + def test_buttonbackground(self): + widget = self.create() + self.checkColorParam(widget, 'buttonbackground') + + def test_buttoncursor(self): + widget = self.create() + self.checkCursorParam(widget, 'buttoncursor') + + def test_buttondownrelief(self): + widget = self.create() + self.checkReliefParam(widget, 'buttondownrelief') + + def test_buttonuprelief(self): + widget = self.create() + self.checkReliefParam(widget, 'buttonuprelief') + + def test_format(self): + widget = self.create() + self.checkParam(widget, 'format', '%2f') + self.checkParam(widget, 'format', '%2.2f') + self.checkParam(widget, 'format', '%.2f') + self.checkParam(widget, 'format', '%2.f') + self.checkInvalidParam(widget, 'format', '%2e-1f') + self.checkInvalidParam(widget, 'format', '2.2') + self.checkInvalidParam(widget, 'format', '%2.-2f') + self.checkParam(widget, 'format', '%-2.02f') + self.checkParam(widget, 'format', '% 2.02f') + self.checkParam(widget, 'format', '% -2.200f') + self.checkParam(widget, 'format', '%09.200f') + self.checkInvalidParam(widget, 'format', '%d') + + def test_from(self): + widget = self.create() + self.checkParam(widget, 'to', 100.0) + self.checkFloatParam(widget, 'from', -10, 10.2, 11.7) + self.checkInvalidParam(widget, 'from', 200, + errmsg='-to value must be greater than -from value') + + def test_increment(self): + widget = self.create() + self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0) + + def test_to(self): + widget = self.create() + self.checkParam(widget, 'from', -100.0) + self.checkFloatParam(widget, 'to', -10, 10.2, 11.7) + self.checkInvalidParam(widget, 'to', -200, + errmsg='-to value must be greater than -from value') + + def test_values(self): + # XXX + widget = self.create() + self.assertEqual(widget['values'], '') + self.checkParam(widget, 'values', 'mon tue wed thur') + self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'), + expected='mon tue wed thur') + self.checkParam(widget, 'values', (42, 3.14, '', 'any string'), + expected='42 3.14 {} {any string}') + self.checkParam(widget, 'values', '') + + def test_wrap(self): + widget = self.create() + self.checkBooleanParam(widget, 'wrap') + + def test_bbox(self): + widget = self.create() + self.assertIsBoundingBox(widget.bbox(0)) + self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') + self.assertRaises(tkinter.TclError, widget.bbox, None) + self.assertRaises(TypeError, widget.bbox) + self.assertRaises(TypeError, widget.bbox, 0, 1) + + +@add_standard_options(StandardOptionsTests) +class TextTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'autoseparators', 'background', 'blockcursor', 'borderwidth', + 'cursor', 'endline', 'exportselection', + 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'inactiveselectbackground', 'insertbackground', 'insertborderwidth', + 'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth', + 'maxundo', 'padx', 'pady', 'relief', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state', + 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap', + 'xscrollcommand', 'yscrollcommand', + ) + if tcl_version < (8, 5): + _stringify = True + + def create(self, **kwargs): + return tkinter.Text(self.root, **kwargs) + + def test_autoseparators(self): + widget = self.create() + self.checkBooleanParam(widget, 'autoseparators') + + @requires_tcl(8, 5) + def test_blockcursor(self): + widget = self.create() + self.checkBooleanParam(widget, 'blockcursor') + + @requires_tcl(8, 5) + def test_endline(self): + widget = self.create() + text = '\n'.join('Line %d' for i in range(100)) + widget.insert('end', text) + self.checkParam(widget, 'endline', 200, expected='') + self.checkParam(widget, 'endline', -10, expected='') + self.checkInvalidParam(widget, 'endline', 'spam', + errmsg='expected integer but got "spam"') + self.checkParam(widget, 'endline', 50) + self.checkParam(widget, 'startline', 15) + self.checkInvalidParam(widget, 'endline', 10, + errmsg='-startline must be less than or equal to -endline') + + def test_height(self): + widget = self.create() + self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c') + self.checkParam(widget, 'height', -100, expected=1) + self.checkParam(widget, 'height', 0, expected=1) + + def test_maxundo(self): + widget = self.create() + self.checkIntegerParam(widget, 'maxundo', 0, 5, -1) + + @requires_tcl(8, 5) + def test_inactiveselectbackground(self): + widget = self.create() + self.checkColorParam(widget, 'inactiveselectbackground') + + @requires_tcl(8, 6) + def test_insertunfocussed(self): + widget = self.create() + self.checkEnumParam(widget, 'insertunfocussed', + 'hollow', 'none', 'solid') + + def test_selectborderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'selectborderwidth', + 1.3, 2.6, -2, '10p', conv=noconv, + keep_orig=tcl_version >= (8, 5)) + + def test_spacing1(self): + widget = self.create() + self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c') + self.checkParam(widget, 'spacing1', -5, expected=0) + + def test_spacing2(self): + widget = self.create() + self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c') + self.checkParam(widget, 'spacing2', -1, expected=0) + + def test_spacing3(self): + widget = self.create() + self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c') + self.checkParam(widget, 'spacing3', -10, expected=0) + + @requires_tcl(8, 5) + def test_startline(self): + widget = self.create() + text = '\n'.join('Line %d' for i in range(100)) + widget.insert('end', text) + self.checkParam(widget, 'startline', 200, expected='') + self.checkParam(widget, 'startline', -10, expected='') + self.checkInvalidParam(widget, 'startline', 'spam', + errmsg='expected integer but got "spam"') + self.checkParam(widget, 'startline', 10) + self.checkParam(widget, 'endline', 50) + self.checkInvalidParam(widget, 'startline', 70, + errmsg='-startline must be less than or equal to -endline') + + def test_state(self): + widget = self.create() + if tcl_version < (8, 5): + self.checkParams(widget, 'state', 'disabled', 'normal') + else: + self.checkEnumParam(widget, 'state', 'disabled', 'normal') + + def test_tabs(self): + widget = self.create() + if get_tk_patchlevel() < (8, 5, 11): + self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'), + expected=('10.2', '20.7', '1i', '2i')) + else: + self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) + self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i', + expected=('10.2', '20.7', '1i', '2i')) + self.checkParam(widget, 'tabs', '2c left 4c 6c center', + expected=('2c', 'left', '4c', '6c', 'center')) + self.checkInvalidParam(widget, 'tabs', 'spam', + errmsg='bad screen distance "spam"', + keep_orig=tcl_version >= (8, 5)) + + @requires_tcl(8, 5) + def test_tabstyle(self): + widget = self.create() + self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor') + + def test_undo(self): + widget = self.create() + self.checkBooleanParam(widget, 'undo') + + def test_width(self): + widget = self.create() + self.checkIntegerParam(widget, 'width', 402) + self.checkParam(widget, 'width', -402, expected=1) + self.checkParam(widget, 'width', 0, expected=1) + + def test_wrap(self): + widget = self.create() + if tcl_version < (8, 5): + self.checkParams(widget, 'wrap', 'char', 'none', 'word') + else: + self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') + + def test_bbox(self): + widget = self.create() + 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') + + +@add_standard_options(PixelSizeTests, StandardOptionsTests) +class CanvasTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'background', 'borderwidth', + 'closeenough', 'confine', 'cursor', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'insertbackground', 'insertborderwidth', + 'insertofftime', 'insertontime', 'insertwidth', + 'offset', 'relief', 'scrollregion', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'state', 'takefocus', + 'xscrollcommand', 'xscrollincrement', + 'yscrollcommand', 'yscrollincrement', 'width', + ) + + _conv_pixels = staticmethod(int_round) + _stringify = True + + def create(self, **kwargs): + return tkinter.Canvas(self.root, **kwargs) + + def test_closeenough(self): + widget = self.create() + self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3, + conv=float) + + def test_confine(self): + widget = self.create() + self.checkBooleanParam(widget, 'confine') + + def test_offset(self): + widget = self.create() + self.assertEqual(widget['offset'], '0,0') + self.checkParams(widget, 'offset', + 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center') + self.checkParam(widget, 'offset', '10,20') + self.checkParam(widget, 'offset', '#5,6') + self.checkInvalidParam(widget, 'offset', 'spam') + + def test_scrollregion(self): + widget = self.create() + self.checkParam(widget, 'scrollregion', '0 0 200 150') + self.checkParam(widget, 'scrollregion', (0, 0, 200, 150), + expected='0 0 200 150') + self.checkParam(widget, 'scrollregion', '') + self.checkInvalidParam(widget, 'scrollregion', 'spam', + errmsg='bad scrollRegion "spam"') + self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam')) + self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200)) + self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0)) + + def test_state(self): + widget = self.create() + self.checkEnumParam(widget, 'state', 'disabled', 'normal', + errmsg='bad state value "{}": must be normal or disabled') + + def test_xscrollincrement(self): + widget = self.create() + self.checkPixelsParam(widget, 'xscrollincrement', + 40, 0, 41.2, 43.6, -40, '0.5i') + + def test_yscrollincrement(self): + widget = self.create() + self.checkPixelsParam(widget, 'yscrollincrement', + 10, 0, 11.2, 13.6, -10, '0.1i') + + +@add_standard_options(IntegerSizeTests, StandardOptionsTests) +class ListboxTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'activestyle', 'background', 'borderwidth', 'cursor', + 'disabledforeground', 'exportselection', + 'font', 'foreground', 'height', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'listvariable', 'relief', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'selectmode', 'setgrid', 'state', + 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand', + ) + + def create(self, **kwargs): + return tkinter.Listbox(self.root, **kwargs) + + def test_activestyle(self): + widget = self.create() + self.checkEnumParam(widget, 'activestyle', + 'dotbox', 'none', 'underline') + + def test_listvariable(self): + widget = self.create() + var = tkinter.DoubleVar(self.root) + self.checkVariableParam(widget, 'listvariable', var) + + def test_selectmode(self): + widget = self.create() + self.checkParam(widget, 'selectmode', 'single') + self.checkParam(widget, 'selectmode', 'browse') + self.checkParam(widget, 'selectmode', 'multiple') + self.checkParam(widget, 'selectmode', 'extended') + + def test_state(self): + widget = self.create() + self.checkEnumParam(widget, 'state', 'disabled', 'normal') + + def test_itemconfigure(self): + widget = self.create() + with self.assertRaisesRegexp(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.assertRaisesRegexp(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.assertRaisesRegexp(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 = ( + 'activebackground', 'background', 'bigincrement', 'borderwidth', + 'command', 'cursor', 'digits', 'font', 'foreground', 'from', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'label', 'length', 'orient', 'relief', + 'repeatdelay', 'repeatinterval', + 'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state', + 'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width', + ) + default_orient = 'vertical' + + def create(self, **kwargs): + return tkinter.Scale(self.root, **kwargs) + + def test_bigincrement(self): + widget = self.create() + self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5) + + def test_digits(self): + widget = self.create() + self.checkIntegerParam(widget, 'digits', 5, 0) + + def test_from(self): + widget = self.create() + self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=round) + + def test_label(self): + widget = self.create() + self.checkParam(widget, 'label', 'any string') + self.checkParam(widget, 'label', '') + + def test_length(self): + widget = self.create() + self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i') + + def test_resolution(self): + widget = self.create() + self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2) + + def test_showvalue(self): + widget = self.create() + self.checkBooleanParam(widget, 'showvalue') + + def test_sliderlength(self): + widget = self.create() + self.checkPixelsParam(widget, 'sliderlength', + 10, 11.2, 15.6, -3, '3m') + + def test_sliderrelief(self): + widget = self.create() + self.checkReliefParam(widget, 'sliderrelief') + + def test_tickinterval(self): + widget = self.create() + self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0, + conv=round) + self.checkParam(widget, 'tickinterval', -2, expected=2, + conv=round) + + def test_to(self): + widget = self.create() + self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, + conv=round) + + +@add_standard_options(PixelSizeTests, StandardOptionsTests) +class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'activebackground', 'activerelief', + 'background', 'borderwidth', + 'command', 'cursor', 'elementborderwidth', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'jump', 'orient', 'relief', + 'repeatdelay', 'repeatinterval', + 'takefocus', 'troughcolor', 'width', + ) + _conv_pixels = staticmethod(int_round) + _stringify = True + default_orient = 'vertical' + + def create(self, **kwargs): + return tkinter.Scrollbar(self.root, **kwargs) + + def test_activerelief(self): + widget = self.create() + self.checkReliefParam(widget, 'activerelief') + + def test_elementborderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m') + + def test_orient(self): + widget = self.create() + 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): + OPTIONS = ( + 'background', 'borderwidth', 'cursor', + 'handlepad', 'handlesize', 'height', + 'opaqueresize', 'orient', 'relief', + 'sashcursor', 'sashpad', 'sashrelief', 'sashwidth', + 'showhandle', 'width', + ) + default_orient = 'horizontal' + + def create(self, **kwargs): + return tkinter.PanedWindow(self.root, **kwargs) + + def test_handlepad(self): + widget = self.create() + self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m') + + def test_handlesize(self): + widget = self.create() + self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m', + conv=noconv) + + def test_height(self): + widget = self.create() + self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i', + conv=noconv) + + def test_opaqueresize(self): + widget = self.create() + self.checkBooleanParam(widget, 'opaqueresize') + + def test_sashcursor(self): + widget = self.create() + self.checkCursorParam(widget, 'sashcursor') + + def test_sashpad(self): + widget = self.create() + self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m') + + def test_sashrelief(self): + widget = self.create() + self.checkReliefParam(widget, 'sashrelief') + + def test_sashwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m', + conv=noconv) + + def test_showhandle(self): + widget = self.create() + self.checkBooleanParam(widget, 'showhandle') + + def test_width(self): + widget = self.create() + 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.assertRaisesRegexp(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): + OPTIONS = ( + 'activebackground', 'activeborderwidth', 'activeforeground', + 'background', 'borderwidth', 'cursor', + 'disabledforeground', 'font', 'foreground', + 'postcommand', 'relief', 'selectcolor', 'takefocus', + 'tearoff', 'tearoffcommand', 'title', 'type', + ) + _conv_pixels = noconv_meth + + def create(self, **kwargs): + return tkinter.Menu(self.root, **kwargs) + + def test_postcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'postcommand') + + def test_tearoff(self): + widget = self.create() + self.checkBooleanParam(widget, 'tearoff') + + def test_tearoffcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'tearoffcommand') + + def test_title(self): + widget = self.create() + self.checkParam(widget, 'title', 'any string') + + def test_type(self): + widget = self.create() + 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.assertRaisesRegexp(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): + OPTIONS = ( + 'anchor', 'aspect', 'background', 'borderwidth', + 'cursor', 'font', 'foreground', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'justify', 'padx', 'pady', 'relief', + 'takefocus', 'text', 'textvariable', 'width', + ) + _conv_pad_pixels = noconv_meth + + def create(self, **kwargs): + return tkinter.Message(self.root, **kwargs) + + def test_aspect(self): + widget = self.create() + self.checkIntegerParam(widget, 'aspect', 250, 0, -300) + + +tests_gui = [ + ButtonTest, CanvasTest, CheckbuttonTest, EntryTest, + FrameTest, LabelFrameTest,LabelTest, ListboxTest, + MenubuttonTest, MenuTest, MessageTest, OptionMenuTest, + PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest, + SpinboxTest, TextTest, ToplevelTest, +] + +if __name__ == '__main__': + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_ttk/__init__.py b/lib/python2.7/lib-tk/test/test_ttk/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/__init__.py diff --git a/lib/python2.7/lib-tk/test/test_ttk/support.py b/lib/python2.7/lib-tk/test/test_ttk/support.py new file mode 100644 index 0000000..c4d842a --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/support.py @@ -0,0 +1,105 @@ +import re +import unittest +import Tkinter as tkinter + +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 + like an X server).""" + widget.event_generate('<Enter>', x=0, y=0) + widget.event_generate('<Motion>', x=x, y=y) + widget.event_generate('<ButtonPress-1>', x=x, y=y) + widget.event_generate('<ButtonRelease-1>', x=x, y=y) + + +import _tkinter +tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) + +def requires_tcl(*version): + return unittest.skipUnless(tcl_version >= version, + 'requires Tcl version >= ' + '.'.join(map(str, version))) + +_tk_patchlevel = None +def get_tk_patchlevel(): + global _tk_patchlevel + if _tk_patchlevel is None: + tcl = tkinter.Tcl() + patchlevel = tcl.call('info', 'patchlevel') + m = re.match(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 = { + 'c': 72 / 2.54, # centimeters + 'i': 72, # inches + 'm': 72 / 25.4, # millimeters + 'p': 1, # points +} + +def pixels_conv(value): + return float(value[:-1]) * units[value[-1:]] + +def tcl_obj_eq(actual, expected): + if actual == expected: + return True + if isinstance(actual, _tkinter.Tcl_Obj): + if isinstance(expected, str): + return str(actual) == expected + if isinstance(actual, tuple): + if isinstance(expected, tuple): + return (len(actual) == len(expected) and + all(tcl_obj_eq(act, exp) + for act, exp in zip(actual, expected))) + return False + +def widget_eq(actual, expected): + if actual == expected: + return True + if isinstance(actual, (str, tkinter.Widget)): + if isinstance(expected, (str, tkinter.Widget)): + return str(actual) == str(expected) + return False diff --git a/lib/python2.7/lib-tk/test/test_ttk/test_extensions.py b/lib/python2.7/lib-tk/test/test_ttk/test_extensions.py new file mode 100644 index 0000000..57ffddd --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/test_extensions.py @@ -0,0 +1,291 @@ +import sys +import unittest +import Tkinter as tkinter +import ttk +from test.test_support import requires, run_unittest, swap_attr +from test_ttk.support import AbstractTkTest, destroy_default_root + +requires('gui') + +class LabeledScaleTest(AbstractTkTest, unittest.TestCase): + + def tearDown(self): + self.root.update_idletasks() + super(LabeledScaleTest, self).tearDown() + + def test_widget_destroy(self): + # automatically created variable + 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(self.root) + name = myvar._name + x = ttk.LabeledScale(self.root, variable=myvar) + x.destroy() + if self.wantobjects: + self.assertEqual(x.tk.globalgetvar(name), myvar.get()) + else: + self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) + del myvar + self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) + + # checking that the tracing callback is properly removed + myvar = tkinter.IntVar(self.root) + # LabeledScale will start tracing 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(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 + master = tkinter.Frame(self.root) + x = ttk.LabeledScale(master) + self.assertEqual(x.master, master) + x.destroy() + + # variable initialization/passing + passed_expected = (('0', 0), (0, 0), (10, 10), + (-1, -1), (sys.maxint + 1, sys.maxint + 1)) + if self.wantobjects: + passed_expected += ((2.5, 2),) + for pair in passed_expected: + x = ttk.LabeledScale(self.root, from_=pair[0]) + self.assertEqual(x.value, pair[1]) + x.destroy() + x = ttk.LabeledScale(self.root, from_='2.5') + self.assertRaises(ValueError, x._variable.get) + x.destroy() + 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(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(self.root, variable=myvar, from_=0.5) + self.assertEqual(x.value, 0.5) + self.assertEqual(x._variable._name, myvar._name) + x.destroy() + + # widget positionment + 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(self.root, compound='top') + check_positions(x.scale, 'bottom', x.label, 'n') + x.destroy() + x = ttk.LabeledScale(self.root, compound='bottom') + check_positions(x.scale, 'top', x.label, 's') + x.destroy() + # invert default positions + x = ttk.LabeledScale(self.root, compound='unknown') + check_positions(x.scale, 'top', x.label, 's') + x.destroy() + 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, master, a='b') + + + def test_horizontal_range(self): + lscale = ttk.LabeledScale(self.root, from_=0, to=10) + lscale.pack() + lscale.wait_visibility() + lscale.update() + + linfo_1 = lscale.label.place_info() + prev_xcoord = lscale.scale.coords()[0] + self.assertEqual(prev_xcoord, int(linfo_1['x'])) + # change range to: from -5 to 5. This should change the x coord of + # the scale widget, since 0 is at the middle of the new + # range. + lscale.scale.configure(from_=-5, to=5) + # The following update is needed since the test doesn't use mainloop, + # at the same time this shouldn't affect test outcome + lscale.update() + curr_xcoord = lscale.scale.coords()[0] + 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 self.wantobjects else '0') + self.assertEqual(curr_xcoord, int(linfo_2['x'])) + # change the range back + lscale.scale.configure(from_=0, to=10) + self.assertNotEqual(prev_xcoord, curr_xcoord) + self.assertEqual(prev_xcoord, int(linfo_1['x'])) + + lscale.destroy() + + + def test_variable_change(self): + x = ttk.LabeledScale(self.root) + x.pack() + x.wait_visibility() + x.update() + + curr_xcoord = x.scale.coords()[0] + newval = x.value + 1 + x.value = newval + # The following update is needed since the test doesn't use mainloop, + # at the same time this shouldn't affect test outcome + x.update() + self.assertEqual(x.label['text'], + 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 self.wantobjects: + conv = lambda x: x + else: + conv = int + x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen + x.update() + self.assertEqual(conv(x.label['text']), newval) + self.assertEqual(x.scale.coords()[0], + int(x.label.place_info()['x'])) + + x.destroy() + + + def test_resize(self): + x = ttk.LabeledScale(self.root) + x.pack(expand=True, fill='both') + x.wait_visibility() + x.update() + + width, height = x.master.winfo_width(), x.master.winfo_height() + width_new, height_new = width * 2, height * 2 + + x.value = 3 + x.update() + x.master.wm_geometry("%dx%d" % (width_new, height_new)) + self.assertEqual(int(x.label.place_info()['x']), + x.scale.coords()[0]) + + # Reset geometry + x.master.wm_geometry("%dx%d" % (width, height)) + x.destroy() + + +class OptionMenuTest(AbstractTkTest, unittest.TestCase): + + def setUp(self): + super(OptionMenuTest, self).setUp() + self.textvar = tkinter.StringVar(self.root) + + def tearDown(self): + del self.textvar + super(OptionMenuTest, self).tearDown() + + + def test_widget_destroy(self): + var = tkinter.StringVar(self.root) + optmenu = ttk.OptionMenu(self.root, var) + name = var._name + optmenu.update_idletasks() + optmenu.destroy() + self.assertEqual(optmenu.tk.globalgetvar(name), var.get()) + del var + self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name) + + + def test_initialization(self): + self.assertRaises(tkinter.TclError, + ttk.OptionMenu, self.root, self.textvar, invalid='thing') + + optmenu = ttk.OptionMenu(self.root, self.textvar, 'b', 'a', 'b') + self.assertEqual(optmenu._variable.get(), 'b') + + self.assertTrue(optmenu['menu']) + self.assertTrue(optmenu['textvariable']) + + optmenu.destroy() + + + def test_menu(self): + items = ('a', 'b', 'c') + default = 'a' + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) + found_default = False + for i in range(len(items)): + value = optmenu['menu'].entrycget(i, 'value') + self.assertEqual(value, items[i]) + if value == default: + found_default = True + self.assertTrue(found_default) + optmenu.destroy() + + # default shouldn't be in menu if it is not part of values + default = 'd' + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) + curr = None + i = 0 + while True: + last, curr = curr, optmenu['menu'].entryconfigure(i, 'value') + if last == curr: + # no more menu entries + break + self.assertNotEqual(curr, default) + i += 1 + self.assertEqual(i, len(items)) + + # check that variable is updated correctly + optmenu.pack() + optmenu.wait_visibility() + optmenu['menu'].invoke(0) + self.assertEqual(optmenu._variable.get(), items[0]) + + # changing to an invalid index shouldn't change the variable + self.assertRaises(tkinter.TclError, optmenu['menu'].invoke, -1) + self.assertEqual(optmenu._variable.get(), items[0]) + + optmenu.destroy() + + # specifying a callback + success = [] + def cb_test(item): + self.assertEqual(item, items[1]) + success.append(True) + optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test, + *items) + optmenu['menu'].invoke(1) + if not success: + self.fail("Menu callback not invoked") + + optmenu.destroy() + + +tests_gui = (LabeledScaleTest, OptionMenuTest) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_ttk/test_functions.py b/lib/python2.7/lib-tk/test/test_ttk/test_functions.py new file mode 100644 index 0000000..ea3f81c --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/test_functions.py @@ -0,0 +1,466 @@ +# -*- encoding: utf-8 -*- +import sys +import unittest +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' + + def __init__(self, val): + self.val = val + + def __str__(self): + return unicode(self.val) + + +class MockStateSpec(object): + typename = 'StateSpec' + + def __init__(self, *args): + self.val = args + + def __str__(self): + return ' '.join(self.val) + + +class InternalFunctionsTest(unittest.TestCase): + + def test_format_optdict(self): + def check_against(fmt_opts, result): + for i in range(0, len(fmt_opts), 2): + self.assertEqual(result.pop(fmt_opts[i]), fmt_opts[i + 1]) + if result: + self.fail("result still got elements: %s" % result) + + # passing an empty dict should return an empty object (tuple here) + self.assertFalse(ttk._format_optdict({})) + + # check list formatting + check_against( + ttk._format_optdict({'fg': 'blue', 'padding': [1, 2, 3, 4]}), + {'-fg': 'blue', '-padding': '1 2 3 4'}) + + # check tuple formatting (same as list) + check_against( + ttk._format_optdict({'test': (1, 2, '', 0)}), + {'-test': '1 2 {} 0'}) + + # check untouched values + check_against( + ttk._format_optdict({'test': {'left': 'as is'}}), + {'-test': {'left': 'as is'}}) + + # check script formatting + check_against( + ttk._format_optdict( + {'test': [1, -1, '', '2m', 0], 'test2': 3, + 'test3': '', 'test4': 'abc def', + 'test5': '"abc"', 'test6': '{}', + 'test7': '} -spam {'}, script=True), + {'-test': '{1 -1 {} 2m 0}', '-test2': '3', + '-test3': '{}', '-test4': '{abc def}', + '-test5': '{"abc"}', '-test6': r'\{\}', + '-test7': r'\}\ -spam\ \{'}) + + opts = {u'αβγ': True, u'á': False} + orig_opts = opts.copy() + # check if giving unicode keys is fine + check_against(ttk._format_optdict(opts), {u'-αβγ': True, u'-á': False}) + # opts should remain unchanged + self.assertEqual(opts, orig_opts) + + # passing values with spaces inside a tuple/list + check_against( + ttk._format_optdict( + {'option': ('one two', 'three')}), + {'-option': '{one two} three'}) + check_against( + ttk._format_optdict( + {'option': ('one\ttwo', 'three')}), + {'-option': '{one\ttwo} three'}) + + # passing empty strings inside a tuple/list + check_against( + ttk._format_optdict( + {'option': ('', 'one')}), + {'-option': '{} one'}) + + # passing values with braces inside a tuple/list + check_against( + ttk._format_optdict( + {'option': ('one} {two', 'three')}), + {'-option': r'one\}\ \{two three'}) + + # passing quoted strings inside a tuple/list + check_against( + ttk._format_optdict( + {'option': ('"one"', 'two')}), + {'-option': '{"one"} two'}) + check_against( + ttk._format_optdict( + {'option': ('{one}', 'two')}), + {'-option': r'\{one\} two'}) + + # ignore an option + amount_opts = len(ttk._format_optdict(opts, ignore=(u'á'))) // 2 + self.assertEqual(amount_opts, len(opts) - 1) + + # ignore non-existing options + amount_opts = len(ttk._format_optdict(opts, ignore=(u'á', 'b'))) // 2 + self.assertEqual(amount_opts, len(opts) - 1) + + # ignore every option + self.assertFalse(ttk._format_optdict(opts, ignore=opts.keys())) + + + def test_format_mapdict(self): + opts = {'a': [('b', 'c', 'val'), ('d', 'otherval'), ('', 'single')]} + result = ttk._format_mapdict(opts) + self.assertEqual(len(result), len(opts.keys()) * 2) + self.assertEqual(result, ('-a', '{b c} val d otherval {} single')) + self.assertEqual(ttk._format_mapdict(opts, script=True), + ('-a', '{{b c} val d otherval {} single}')) + + self.assertEqual(ttk._format_mapdict({2: []}), ('-2', '')) + + opts = {u'üñÃćódè': [(u'á', u'vãl')]} + result = ttk._format_mapdict(opts) + self.assertEqual(result, (u'-üñÃćódè', u'á vãl')) + + # empty states + valid = {'opt': [('', u'', 'hi')]} + self.assertEqual(ttk._format_mapdict(valid), ('-opt', '{ } hi')) + + # when passing multiple states, they all must be strings + invalid = {'opt': [(1, 2, 'valid val')]} + self.assertRaises(TypeError, ttk._format_mapdict, invalid) + invalid = {'opt': [([1], '2', 'valid val')]} + self.assertRaises(TypeError, ttk._format_mapdict, invalid) + # but when passing a single state, it can be anything + valid = {'opt': [[1, 'value']]} + self.assertEqual(ttk._format_mapdict(valid), ('-opt', '1 value')) + # special attention to single states which evalute to False + for stateval in (None, 0, False, '', set()): # just some samples + valid = {'opt': [(stateval, 'value')]} + self.assertEqual(ttk._format_mapdict(valid), + ('-opt', '{} value')) + + # values must be iterable + opts = {'a': None} + self.assertRaises(TypeError, ttk._format_mapdict, opts) + + # items in the value must have size >= 2 + self.assertRaises(IndexError, ttk._format_mapdict, + {'a': [('invalid', )]}) + + + def test_format_elemcreate(self): + self.assertTrue(ttk._format_elemcreate(None), (None, ())) + + ## Testing type = image + # image type expects at least an image name, so this should raise + # IndexError since it tries to access the index 0 of an empty tuple + self.assertRaises(IndexError, ttk._format_elemcreate, 'image') + + # don't format returned values as a tcl script + # minimum acceptable for image type + self.assertEqual(ttk._format_elemcreate('image', False, 'test'), + ("test ", ())) + # specifying a state spec + self.assertEqual(ttk._format_elemcreate('image', False, 'test', + ('', 'a')), ("test {} a", ())) + # state spec with multiple states + self.assertEqual(ttk._format_elemcreate('image', False, 'test', + ('a', 'b', 'c')), ("test {a b} c", ())) + # state spec and options + res = ttk._format_elemcreate('image', False, 'test', + ('a', 'b'), a='x', b='y') + self.assertEqual(res[0], "test a b") + self.assertEqual(set(res[1]), {"-a", "x", "-b", "y"}) + # format returned values as a tcl script + # state spec with multiple states and an option with a multivalue + self.assertEqual(ttk._format_elemcreate('image', True, 'test', + ('a', 'b', 'c', 'd'), x=[2, 3]), ("{test {a b c} d}", "-x {2 3}")) + + ## Testing type = vsapi + # vsapi type expects at least a class name and a part_id, so this + # should raise a ValueError since it tries to get two elements from + # an empty tuple + self.assertRaises(ValueError, ttk._format_elemcreate, 'vsapi') + + # don't format returned values as a tcl script + # minimum acceptable for vsapi + self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b'), + ("a b ", ())) + # now with a state spec with multiple states + self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b', + ('a', 'b', 'c')), ("a b {a b} c", ())) + # state spec and option + self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b', + ('a', 'b'), opt='x'), ("a b a b", ("-opt", "x"))) + # format returned values as a tcl script + # state spec with a multivalue and an option + self.assertEqual(ttk._format_elemcreate('vsapi', True, 'a', 'b', + ('a', 'b', [1, 2]), opt='x'), ("{a b {a b} {1 2}}", "-opt x")) + + # Testing type = from + # from type expects at least a type name + self.assertRaises(IndexError, ttk._format_elemcreate, 'from') + + self.assertEqual(ttk._format_elemcreate('from', False, 'a'), + ('a', ())) + self.assertEqual(ttk._format_elemcreate('from', False, 'a', 'b'), + ('a', ('b', ))) + self.assertEqual(ttk._format_elemcreate('from', True, 'a', 'b'), + ('{a}', 'b')) + + + def test_format_layoutlist(self): + def sample(indent=0, indent_size=2): + return ttk._format_layoutlist( + [('a', {'other': [1, 2, 3], 'children': + [('b', {'children': + [('c', {'children': + [('d', {'nice': 'opt'})], 'something': (1, 2) + })] + })] + })], indent=indent, indent_size=indent_size)[0] + + def sample_expected(indent=0, indent_size=2): + spaces = lambda amount=0: ' ' * (amount + indent) + return ( + "%sa -other {1 2 3} -children {\n" + "%sb -children {\n" + "%sc -something {1 2} -children {\n" + "%sd -nice opt\n" + "%s}\n" + "%s}\n" + "%s}" % (spaces(), spaces(indent_size), + spaces(2 * indent_size), spaces(3 * indent_size), + spaces(2 * indent_size), spaces(indent_size), spaces())) + + # empty layout + self.assertEqual(ttk._format_layoutlist([])[0], '') + + # smallest (after an empty one) acceptable layout + smallest = ttk._format_layoutlist([('a', None)], indent=0) + self.assertEqual(smallest, + ttk._format_layoutlist([('a', '')], indent=0)) + self.assertEqual(smallest[0], 'a') + + # testing indentation levels + self.assertEqual(sample(), sample_expected()) + for i in range(4): + self.assertEqual(sample(i), sample_expected(i)) + self.assertEqual(sample(i, i), sample_expected(i, i)) + + # invalid layout format, different kind of exceptions will be + # raised + + # plain wrong format + self.assertRaises(ValueError, ttk._format_layoutlist, + ['bad', 'format']) + self.assertRaises(TypeError, ttk._format_layoutlist, None) + # _format_layoutlist always expects the second item (in every item) + # to act like a dict (except when the value evalutes to False). + self.assertRaises(AttributeError, + ttk._format_layoutlist, [('a', 'b')]) + # bad children formatting + self.assertRaises(ValueError, ttk._format_layoutlist, + [('name', {'children': {'a': None}})]) + + + def test_script_from_settings(self): + # empty options + self.assertFalse(ttk._script_from_settings({'name': + {'configure': None, 'map': None, 'element create': None}})) + + # empty layout + self.assertEqual( + ttk._script_from_settings({'name': {'layout': None}}), + "ttk::style layout name {\nnull\n}") + + configdict = {u'αβγ': True, u'á': False} + self.assertTrue( + ttk._script_from_settings({'name': {'configure': configdict}})) + + mapdict = {u'üñÃćódè': [(u'á', u'vãl')]} + self.assertTrue( + ttk._script_from_settings({'name': {'map': mapdict}})) + + # invalid image element + self.assertRaises(IndexError, + ttk._script_from_settings, {'name': {'element create': ['image']}}) + + # minimal valid image + self.assertTrue(ttk._script_from_settings({'name': + {'element create': ['image', 'name']}})) + + image = {'thing': {'element create': + ['image', 'name', ('state1', 'state2', 'val')]}} + self.assertEqual(ttk._script_from_settings(image), + "ttk::style element create thing image {name {state1 state2} val} ") + + image['thing']['element create'].append({'opt': 30}) + self.assertEqual(ttk._script_from_settings(image), + "ttk::style element create thing image {name {state1 state2} val} " + "-opt 30") + + image['thing']['element create'][-1]['opt'] = [MockTclObj(3), + MockTclObj('2m')] + self.assertEqual(ttk._script_from_settings(image), + "ttk::style element create thing image {name {state1 state2} val} " + "-opt {3 2m}") + + + 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): + def test_it(sspec, value, res_value, states): + self.assertEqual(ttk._list_from_statespec( + (sspec, value)), [states + (res_value, )]) + + states_even = tuple('state%d' % i for i in range(6)) + statespec = MockStateSpec(*states_even) + test_it(statespec, 'val', 'val', states_even) + test_it(statespec, MockTclObj('val'), 'val', states_even) + + states_odd = tuple('state%d' % i for i in range(5)) + statespec = MockStateSpec(*states_odd) + test_it(statespec, 'val', 'val', states_odd) + + test_it(('a', 'b', 'c'), MockTclObj('val'), 'val', ('a', 'b', 'c')) + + + def test_list_from_layouttuple(self): + tk = MockTkApp() + + # empty layout tuple + self.assertFalse(ttk._list_from_layouttuple(tk, ())) + + # shortest layout tuple + self.assertEqual(ttk._list_from_layouttuple(tk, ('name', )), + [('name', {})]) + + # not so interesting ltuple + sample_ltuple = ('name', '-option', 'value') + self.assertEqual(ttk._list_from_layouttuple(tk, sample_ltuple), + [('name', {'option': 'value'})]) + + # empty children + self.assertEqual(ttk._list_from_layouttuple(tk, + ('something', '-children', ())), + [('something', {'children': []})] + ) + + # more interesting ltuple + ltuple = ( + 'name', '-option', 'niceone', '-children', ( + ('otherone', '-children', ( + ('child', )), '-otheropt', 'othervalue' + ) + ) + ) + self.assertEqual(ttk._list_from_layouttuple(tk, ltuple), + [('name', {'option': 'niceone', 'children': + [('otherone', {'otheropt': 'othervalue', 'children': + [('child', {})] + })] + })] + ) + + # bad tuples + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, + ('name', 'no_minus')) + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, + ('name', 'no_minus', 'value')) + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, + ('something', '-children')) # no children + + + def test_val_or_dict(self): + def func(res, opt=None, val=None): + if opt is None: + return res + if val is None: + return "test val" + return (opt, 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') + + self.assertEqual(ttk._val_or_dict(tk, {'test': 3}, 'x:y'), + {'test': 3}) + + + def test_convert_stringval(self): + tests = ( + (0, 0), ('09', 9), ('a', 'a'), (u'áÚ', u'áÚ'), ([], '[]'), + (None, 'None') + ) + for orig, expected in tests: + self.assertEqual(ttk._convert_stringval(orig), expected) + + if sys.getdefaultencoding() == 'ascii': + self.assertRaises(UnicodeDecodeError, + ttk._convert_stringval, 'á') + + +class TclObjsToPyTest(unittest.TestCase): + + def test_unicode(self): + adict = {'opt': u'välúè'} + self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': u'välúè'}) + + adict['opt'] = MockTclObj(adict['opt']) + self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': u'välúè'}) + + def test_multivalues(self): + adict = {'opt': [1, 2, 3, 4]} + self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': [1, 2, 3, 4]}) + + adict['opt'] = [1, 'xm', 3] + self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': [1, 'xm', 3]}) + + adict['opt'] = (MockStateSpec('a', 'b'), u'válũè') + self.assertEqual(ttk.tclobjs_to_py(adict), + {'opt': [('a', 'b', u'válũè')]}) + + self.assertEqual(ttk.tclobjs_to_py({'x': ['y z']}), + {'x': ['y z']}) + + def test_nosplit(self): + self.assertEqual(ttk.tclobjs_to_py({'text': 'some text'}), + {'text': 'some text'}) + +tests_nogui = (InternalFunctionsTest, TclObjsToPyTest) + +if __name__ == "__main__": + from test.test_support import run_unittest + run_unittest(*tests_nogui) diff --git a/lib/python2.7/lib-tk/test/test_ttk/test_style.py b/lib/python2.7/lib-tk/test/test_ttk/test_style.py new file mode 100644 index 0000000..fe122e7 --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/test_style.py @@ -0,0 +1,92 @@ +import unittest +import Tkinter as tkinter +import ttk +from test.test_support import requires, run_unittest +from test_ttk.support import AbstractTkTest + +requires('gui') + +class StyleTest(AbstractTkTest, unittest.TestCase): + + def setUp(self): + super(StyleTest, self).setUp() + self.style = ttk.Style(self.root) + + + def test_configure(self): + style = self.style + style.configure('TButton', background='yellow') + self.assertEqual(style.configure('TButton', 'background'), + 'yellow') + self.assertIsInstance(style.configure('TButton'), dict) + + + def test_map(self): + style = self.style + style.map('TButton', background=[('active', 'background', 'blue')]) + self.assertEqual(style.map('TButton', 'background'), + [('active', 'background', 'blue')] if self.wantobjects else + [('active background', 'blue')]) + self.assertIsInstance(style.map('TButton'), dict) + + + def test_lookup(self): + style = self.style + style.configure('TButton', background='yellow') + style.map('TButton', background=[('active', 'background', 'blue')]) + + self.assertEqual(style.lookup('TButton', 'background'), 'yellow') + self.assertEqual(style.lookup('TButton', 'background', + ['active', 'background']), 'blue') + self.assertEqual(style.lookup('TButton', 'optionnotdefined', + default='iknewit'), 'iknewit') + + + def test_layout(self): + style = self.style + self.assertRaises(tkinter.TclError, style.layout, 'NotALayout') + tv_style = style.layout('Treeview') + + # "erase" Treeview layout + style.layout('Treeview', '') + self.assertEqual(style.layout('Treeview'), + [('null', {'sticky': 'nswe'})] + ) + + # restore layout + style.layout('Treeview', tv_style) + self.assertEqual(style.layout('Treeview'), tv_style) + + # should return a list + self.assertIsInstance(style.layout('TButton'), list) + + # correct layout, but "option" doesn't exist as option + self.assertRaises(tkinter.TclError, style.layout, 'Treeview', + [('name', {'option': 'inexistent'})]) + + + def test_theme_use(self): + self.assertRaises(tkinter.TclError, self.style.theme_use, + 'nonexistingname') + + curr_theme = self.style.theme_use() + new_theme = None + for theme in self.style.theme_names(): + if theme != curr_theme: + new_theme = theme + self.style.theme_use(theme) + break + else: + # just one theme available, can't go on with tests + return + + self.assertFalse(curr_theme == new_theme) + self.assertFalse(new_theme != self.style.theme_use()) + + self.style.theme_use(curr_theme) + + +tests_gui = (StyleTest, ) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/test_ttk/test_widgets.py b/lib/python2.7/lib-tk/test/test_ttk/test_widgets.py new file mode 100644 index 0000000..a84960d --- /dev/null +++ b/lib/python2.7/lib-tk/test/test_ttk/test_widgets.py @@ -0,0 +1,1674 @@ +import unittest +import Tkinter as tkinter +from Tkinter import TclError +import ttk +from test.test_support import requires, run_unittest, have_unicode, u +import sys + +from test_functions import MockTclObj +from support import (AbstractTkTest, tcl_version, get_tk_patchlevel, + simulate_mouse_click) +from widget_tests import (add_standard_options, noconv, noconv_meth, + AbstractWidgetTest, StandardOptionsTests, + IntegerSizeTests, PixelSizeTests, + setUpModule) + +requires('gui') + + +class StandardTtkOptionsTests(StandardOptionsTests): + + def test_class(self): + widget = self.create() + self.assertEqual(widget['class'], '') + errmsg='attempt to change read-only option' + 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') + self.assertEqual(widget2['class'], 'Foo') + + def test_padding(self): + widget = self.create() + self.checkParam(widget, 'padding', 0, expected=('0',)) + self.checkParam(widget, 'padding', 5, expected=('5',)) + self.checkParam(widget, 'padding', (5, 6), expected=('5', '6')) + self.checkParam(widget, 'padding', (5, 6, 7), + expected=('5', '6', '7')) + self.checkParam(widget, 'padding', (5, 6, 7, 8), + expected=('5', '6', '7', '8')) + self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p')) + self.checkParam(widget, 'padding', (), expected='') + + def test_style(self): + widget = self.create() + self.assertEqual(widget['style'], '') + errmsg = 'Layout Foo not found' + if hasattr(self, 'default_orient'): + errmsg = ('Layout %s.Foo not found' % + getattr(self, 'default_orient').title()) + self.checkInvalidParam(widget, 'style', 'Foo', + errmsg=errmsg) + widget2 = self.create(class_='Foo') + self.assertEqual(widget2['class'], 'Foo') + # XXX + pass + + +class WidgetTest(AbstractTkTest, unittest.TestCase): + """Tests methods available in every ttk widget.""" + + def setUp(self): + super(WidgetTest, self).setUp() + self.widget = ttk.Button(self.root, width=0, text="Text") + self.widget.pack() + self.widget.wait_visibility() + + + def test_identify(self): + self.widget.update_idletasks() + self.assertEqual(self.widget.identify( + self.widget.winfo_width() // 2, + self.widget.winfo_height() // 2 + ), "label") + self.assertEqual(self.widget.identify(-1, -1), "") + + self.assertRaises(tkinter.TclError, self.widget.identify, None, 5) + self.assertRaises(tkinter.TclError, self.widget.identify, 5, None) + self.assertRaises(tkinter.TclError, self.widget.identify, 5, '') + + + def test_widget_state(self): + # XXX not sure about the portability of all these tests + self.assertEqual(self.widget.state(), ()) + self.assertEqual(self.widget.instate(['!disabled']), True) + + # changing from !disabled to disabled + self.assertEqual(self.widget.state(['disabled']), ('!disabled', )) + # no state change + self.assertEqual(self.widget.state(['disabled']), ()) + # change back to !disable but also active + self.assertEqual(self.widget.state(['!disabled', 'active']), + ('!active', 'disabled')) + # no state changes, again + self.assertEqual(self.widget.state(['!disabled', 'active']), ()) + self.assertEqual(self.widget.state(['active', '!disabled']), ()) + + def test_cb(arg1, **kw): + return arg1, kw + self.assertEqual(self.widget.instate(['!disabled'], + test_cb, "hi", **{"msg": "there"}), + ('hi', {'msg': 'there'})) + + # attempt to set invalid statespec + currstate = self.widget.state() + self.assertRaises(tkinter.TclError, self.widget.instate, + ['badstate']) + self.assertRaises(tkinter.TclError, self.widget.instate, + ['disabled', 'badstate']) + # verify that widget didn't change its state + self.assertEqual(currstate, self.widget.state()) + + # ensuring that passing None as state doesn't modify current state + self.widget.state(['active', '!disabled']) + self.assertEqual(self.widget.state(), ('active', )) + + +class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): + _conv_pixels = noconv_meth + + +@add_standard_options(StandardTtkOptionsTests) +class FrameTest(AbstractToplevelTest, unittest.TestCase): + OPTIONS = ( + 'borderwidth', 'class', 'cursor', 'height', + 'padding', 'relief', 'style', 'takefocus', + 'width', + ) + + def create(self, **kwargs): + return ttk.Frame(self.root, **kwargs) + + +@add_standard_options(StandardTtkOptionsTests) +class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): + OPTIONS = ( + 'borderwidth', 'class', 'cursor', 'height', + 'labelanchor', 'labelwidget', + 'padding', 'relief', 'style', 'takefocus', + 'text', 'underline', 'width', + ) + + def create(self, **kwargs): + return ttk.LabelFrame(self.root, **kwargs) + + def test_labelanchor(self): + widget = self.create() + self.checkEnumParam(widget, 'labelanchor', + 'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws', + errmsg='Bad label anchor specification {}') + self.checkInvalidParam(widget, 'labelanchor', 'center') + + def test_labelwidget(self): + widget = self.create() + label = ttk.Label(self.root, text='Mupp', name='foo') + self.checkParam(widget, 'labelwidget', label, expected='.foo') + label.destroy() + + +class AbstractLabelTest(AbstractWidgetTest): + + def checkImageParam(self, widget, name): + 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',)) + self.checkParam(widget, name, (image, 'active', image2), + expected=('image1', 'active', 'image2')) + self.checkParam(widget, name, 'image1 active image2', + expected=('image1', 'active', 'image2')) + self.checkInvalidParam(widget, name, 'spam', + errmsg='image "spam" doesn\'t exist') + + def test_compound(self): + widget = self.create() + self.checkEnumParam(widget, 'compound', + 'none', 'text', 'image', 'center', + 'top', 'bottom', 'left', 'right') + + def test_state(self): + widget = self.create() + self.checkParams(widget, 'state', 'active', 'disabled', 'normal') + + def test_width(self): + widget = self.create() + self.checkParams(widget, 'width', 402, -402, 0) + + +@add_standard_options(StandardTtkOptionsTests) +class LabelTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'anchor', 'background', 'borderwidth', + 'class', 'compound', 'cursor', 'font', 'foreground', + 'image', 'justify', 'padding', 'relief', 'state', 'style', + 'takefocus', 'text', 'textvariable', + 'underline', 'width', 'wraplength', + ) + _conv_pixels = noconv_meth + + def create(self, **kwargs): + return ttk.Label(self.root, **kwargs) + + def test_font(self): + widget = self.create() + self.checkParam(widget, 'font', + '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*') + + +@add_standard_options(StandardTtkOptionsTests) +class ButtonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'class', 'command', 'compound', 'cursor', 'default', + 'image', 'padding', 'state', 'style', + 'takefocus', 'text', 'textvariable', + 'underline', 'width', + ) + + def create(self, **kwargs): + return ttk.Button(self.root, **kwargs) + + def test_default(self): + widget = self.create() + self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled') + + def test_invoke(self): + success = [] + btn = ttk.Button(self.root, command=lambda: success.append(1)) + btn.invoke() + self.assertTrue(success) + + +@add_standard_options(StandardTtkOptionsTests) +class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'class', 'command', 'compound', 'cursor', + 'image', + 'offvalue', 'onvalue', + 'padding', 'state', 'style', + 'takefocus', 'text', 'textvariable', + 'underline', 'variable', 'width', + ) + + def create(self, **kwargs): + return ttk.Checkbutton(self.root, **kwargs) + + def test_offvalue(self): + widget = self.create() + self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string') + + def test_onvalue(self): + widget = self.create() + self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string') + + def test_invoke(self): + success = [] + def cb_test(): + success.append(1) + return "cb test called" + + 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', )) + self.assertRaises(tkinter.TclError, cbtn.tk.globalgetvar, + cbtn['variable']) + + res = cbtn.invoke() + self.assertEqual(res, "cb test called") + self.assertEqual(cbtn['onvalue'], + cbtn.tk.globalgetvar(cbtn['variable'])) + self.assertTrue(success) + + cbtn['command'] = '' + res = cbtn.invoke() + self.assertFalse(str(res)) + self.assertLessEqual(len(success), 1) + self.assertEqual(cbtn['offvalue'], + cbtn.tk.globalgetvar(cbtn['variable'])) + + +@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) +class EntryTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'background', 'class', 'cursor', + 'exportselection', 'font', 'foreground', + 'invalidcommand', 'justify', + 'show', 'state', 'style', 'takefocus', 'textvariable', + 'validate', 'validatecommand', 'width', 'xscrollcommand', + ) + + def setUp(self): + super(EntryTest, self).setUp() + self.entry = self.create() + + def create(self, **kwargs): + return ttk.Entry(self.root, **kwargs) + + def test_invalidcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'invalidcommand') + + def test_show(self): + widget = self.create() + self.checkParam(widget, 'show', '*') + self.checkParam(widget, 'show', '') + self.checkParam(widget, 'show', ' ') + + def test_state(self): + widget = self.create() + self.checkParams(widget, 'state', + 'disabled', 'normal', 'readonly') + + def test_validate(self): + widget = self.create() + self.checkEnumParam(widget, 'validate', + 'all', 'key', 'focus', 'focusin', 'focusout', 'none') + + def test_validatecommand(self): + widget = self.create() + self.checkCommandParam(widget, 'validatecommand') + + + def test_bbox(self): + self.assertIsBoundingBox(self.entry.bbox(0)) + self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') + self.assertRaises(tkinter.TclError, self.entry.bbox, None) + + + def test_identify(self): + self.entry.pack() + self.entry.wait_visibility() + self.entry.update_idletasks() + + self.assertEqual(self.entry.identify(5, 5), "textarea") + self.assertEqual(self.entry.identify(-1, -1), "") + + self.assertRaises(tkinter.TclError, self.entry.identify, None, 5) + self.assertRaises(tkinter.TclError, self.entry.identify, 5, None) + self.assertRaises(tkinter.TclError, self.entry.identify, 5, '') + + + def test_validation_options(self): + success = [] + test_invalid = lambda: success.append(True) + + self.entry['validate'] = 'none' + self.entry['validatecommand'] = lambda: False + + self.entry['invalidcommand'] = test_invalid + self.entry.validate() + self.assertTrue(success) + + self.entry['invalidcommand'] = '' + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['invalidcommand'] = test_invalid + self.entry['validatecommand'] = lambda: True + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['validatecommand'] = '' + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['validatecommand'] = True + self.assertRaises(tkinter.TclError, self.entry.validate) + + + def test_validation(self): + validation = [] + def validate(to_insert): + if not 'a' <= to_insert.lower() <= 'z': + validation.append(False) + return False + validation.append(True) + return True + + self.entry['validate'] = 'key' + self.entry['validatecommand'] = self.entry.register(validate), '%S' + + self.entry.insert('end', 1) + self.entry.insert('end', 'a') + self.assertEqual(validation, [False, True]) + self.assertEqual(self.entry.get(), 'a') + + + def test_revalidation(self): + def validate(content): + for letter in content: + if not 'a' <= letter.lower() <= 'z': + return False + return True + + self.entry['validatecommand'] = self.entry.register(validate), '%P' + + self.entry.insert('end', 'avocado') + self.assertEqual(self.entry.validate(), True) + self.assertEqual(self.entry.state(), ()) + + self.entry.delete(0, 'end') + self.assertEqual(self.entry.get(), '') + + self.entry.insert('end', 'a1b') + self.assertEqual(self.entry.validate(), False) + self.assertEqual(self.entry.state(), ('invalid', )) + + self.entry.delete(1) + self.assertEqual(self.entry.validate(), True) + self.assertEqual(self.entry.state(), ()) + + +@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) +class ComboboxTest(EntryTest, unittest.TestCase): + OPTIONS = ( + 'background', 'class', 'cursor', 'exportselection', + 'font', 'foreground', 'height', 'invalidcommand', + 'justify', 'postcommand', 'show', 'state', 'style', + 'takefocus', 'textvariable', + 'validate', 'validatecommand', 'values', + 'width', 'xscrollcommand', + ) + + def setUp(self): + super(ComboboxTest, self).setUp() + self.combo = self.create() + + def create(self, **kwargs): + return ttk.Combobox(self.root, **kwargs) + + def test_height(self): + widget = self.create() + self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i') + + def _show_drop_down_listbox(self): + width = self.combo.winfo_width() + self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5) + self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5) + self.combo.update_idletasks() + + + def test_virtual_event(self): + success = [] + + self.combo['values'] = [1] + self.combo.bind('<<ComboboxSelected>>', + lambda evt: success.append(True)) + self.combo.pack() + self.combo.wait_visibility() + + height = self.combo.winfo_height() + self._show_drop_down_listbox() + self.combo.update() + self.combo.event_generate('<Return>') + self.combo.update() + + self.assertTrue(success) + + + def test_postcommand(self): + success = [] + + self.combo['postcommand'] = lambda: success.append(True) + self.combo.pack() + self.combo.wait_visibility() + + self._show_drop_down_listbox() + self.assertTrue(success) + + # testing postcommand removal + self.combo['postcommand'] = '' + self._show_drop_down_listbox() + self.assertEqual(len(success), 1) + + + def test_values(self): + def check_get_current(getval, currval): + self.assertEqual(self.combo.get(), getval) + self.assertEqual(self.combo.current(), currval) + + self.assertEqual(self.combo['values'], + () if tcl_version < (8, 5) else '') + check_get_current('', -1) + + self.checkParam(self.combo, 'values', 'mon tue wed thur', + 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', () if tcl_version < (8, 5) else '') + + self.combo['values'] = ['a', 1, 'c'] + + self.combo.set('c') + check_get_current('c', 2) + + self.combo.current(0) + check_get_current('a', 0) + + self.combo.set('d') + check_get_current('d', -1) + + # testing values with empty string + self.combo.set('') + self.combo['values'] = (1, 2, '', 3) + check_get_current('', 2) + + # testing values with empty string set through configure + self.combo.configure(values=[1, '', 2]) + self.assertEqual(self.combo['values'], + ('1', '', '2') if self.wantobjects else + '1 {} 2') + + # testing values with spaces + self.combo['values'] = ['a b', 'a\tb', 'a\nb'] + self.assertEqual(self.combo['values'], + ('a b', 'a\tb', 'a\nb') if self.wantobjects else + '{a b} {a\tb} {a\nb}') + + # testing values with special characters + self.combo['values'] = [r'a\tb', '"a"', '} {'] + self.assertEqual(self.combo['values'], + (r'a\tb', '"a"', '} {') if self.wantobjects else + r'a\\tb {"a"} \}\ \{') + + # out of range + self.assertRaises(tkinter.TclError, self.combo.current, + len(self.combo['values'])) + # it expects an integer (or something that can be converted to int) + self.assertRaises(tkinter.TclError, self.combo.current, '') + + # testing creating combobox with empty string in values + combo2 = ttk.Combobox(self.root, values=[1, 2, '']) + self.assertEqual(combo2['values'], + ('1', '2', '') if self.wantobjects else '1 2 {}') + combo2.destroy() + + +@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) +class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'cursor', 'height', + 'orient', 'style', 'takefocus', 'width', + ) + + def setUp(self): + super(PanedWindowTest, self).setUp() + self.paned = self.create() + + 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, 'beta', 3): + errmsg='Attempt to change read-only option' + self.checkInvalidParam(widget, 'orient', 'horizontal', + errmsg=errmsg) + widget2 = self.create(orient='horizontal') + self.assertEqual(str(widget2['orient']), 'horizontal') + + def test_add(self): + # attempt to add a child that is not a direct child of the paned window + label = ttk.Label(self.paned) + child = ttk.Label(label) + self.assertRaises(tkinter.TclError, self.paned.add, child) + label.destroy() + child.destroy() + # another attempt + 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(self.root) + self.paned.add(good_child) + # re-adding a child is not accepted + self.assertRaises(tkinter.TclError, self.paned.add, good_child) + + other_child = ttk.Label(self.paned) + self.paned.add(other_child) + self.assertEqual(self.paned.pane(0), self.paned.pane(1)) + self.assertRaises(tkinter.TclError, self.paned.pane, 2) + good_child.destroy() + other_child.destroy() + self.assertRaises(tkinter.TclError, self.paned.pane, 0) + + + def test_forget(self): + self.assertRaises(tkinter.TclError, self.paned.forget, None) + self.assertRaises(tkinter.TclError, self.paned.forget, 0) + + self.paned.add(ttk.Label(self.root)) + self.paned.forget(0) + self.assertRaises(tkinter.TclError, self.paned.forget, 0) + + + def test_insert(self): + self.assertRaises(tkinter.TclError, self.paned.insert, None, 0) + self.assertRaises(tkinter.TclError, self.paned.insert, 0, None) + self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0) + + child = ttk.Label(self.root) + child2 = ttk.Label(self.root) + child3 = ttk.Label(self.root) + + self.assertRaises(tkinter.TclError, self.paned.insert, 0, child) + + self.paned.insert('end', child2) + self.paned.insert(0, child) + self.assertEqual(self.paned.panes(), (str(child), str(child2))) + + self.paned.insert(0, child2) + self.assertEqual(self.paned.panes(), (str(child2), str(child))) + + self.paned.insert('end', child3) + self.assertEqual(self.paned.panes(), + (str(child2), str(child), str(child3))) + + # reinserting a child should move it to its current position + panes = self.paned.panes() + self.paned.insert('end', child3) + self.assertEqual(panes, self.paned.panes()) + + # moving child3 to child2 position should result in child2 ending up + # in previous child position and child ending up in previous child3 + # position + self.paned.insert(child2, child3) + self.assertEqual(self.paned.panes(), + (str(child3), str(child2), str(child))) + + + def test_pane(self): + self.assertRaises(tkinter.TclError, self.paned.pane, 0) + + child = ttk.Label(self.root) + self.paned.add(child) + self.assertIsInstance(self.paned.pane(0), dict) + self.assertEqual(self.paned.pane(0, weight=None), + 0 if self.wantobjects else '0') + # newer form for querying a single option + self.assertEqual(self.paned.pane(0, 'weight'), + 0 if self.wantobjects else '0') + self.assertEqual(self.paned.pane(0), self.paned.pane(str(child))) + + self.assertRaises(tkinter.TclError, self.paned.pane, 0, + badoption='somevalue') + + + def test_sashpos(self): + self.assertRaises(tkinter.TclError, self.paned.sashpos, None) + self.assertRaises(tkinter.TclError, self.paned.sashpos, '') + self.assertRaises(tkinter.TclError, self.paned.sashpos, 0) + + child = ttk.Label(self.paned, text='a') + self.paned.add(child, weight=1) + self.assertRaises(tkinter.TclError, self.paned.sashpos, 0) + child2 = ttk.Label(self.paned, text='b') + self.paned.add(child2) + self.assertRaises(tkinter.TclError, self.paned.sashpos, 1) + + self.paned.pack(expand=True, fill='both') + self.paned.wait_visibility() + + curr_pos = self.paned.sashpos(0) + self.paned.sashpos(0, 1000) + self.assertNotEqual(curr_pos, self.paned.sashpos(0)) + self.assertIsInstance(self.paned.sashpos(0), int) + + +@add_standard_options(StandardTtkOptionsTests) +class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'class', 'command', 'compound', 'cursor', + 'image', + 'padding', 'state', 'style', + 'takefocus', 'text', 'textvariable', + 'underline', 'value', 'variable', 'width', + ) + + def create(self, **kwargs): + return ttk.Radiobutton(self.root, **kwargs) + + def test_value(self): + widget = self.create() + self.checkParams(widget, 'value', 1, 2.3, '', 'any string') + + def test_invoke(self): + success = [] + def cb_test(): + success.append(1) + return "cb test called" + + 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 + else: + conv = int + + res = cbtn.invoke() + self.assertEqual(res, "cb test called") + self.assertEqual(conv(cbtn['value']), myvar.get()) + self.assertEqual(myvar.get(), + conv(cbtn.tk.globalgetvar(cbtn['variable']))) + self.assertTrue(success) + + cbtn2['command'] = '' + res = cbtn2.invoke() + self.assertEqual(str(res), '') + self.assertLessEqual(len(success), 1) + self.assertEqual(conv(cbtn2['value']), myvar.get()) + self.assertEqual(myvar.get(), + conv(cbtn.tk.globalgetvar(cbtn['variable']))) + + self.assertEqual(str(cbtn['variable']), str(cbtn2['variable'])) + + +class MenubuttonTest(AbstractLabelTest, unittest.TestCase): + OPTIONS = ( + 'class', 'compound', 'cursor', 'direction', + 'image', 'menu', 'padding', 'state', 'style', + 'takefocus', 'text', 'textvariable', + 'underline', 'width', + ) + + def create(self, **kwargs): + return ttk.Menubutton(self.root, **kwargs) + + def test_direction(self): + widget = self.create() + self.checkEnumParam(widget, 'direction', + 'above', 'below', 'left', 'right', 'flush') + + def test_menu(self): + widget = self.create() + menu = tkinter.Menu(widget, name='menu') + self.checkParam(widget, 'menu', menu, conv=str) + menu.destroy() + + +@add_standard_options(StandardTtkOptionsTests) +class ScaleTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'command', 'cursor', 'from', 'length', + 'orient', 'style', 'takefocus', 'to', 'value', 'variable', + ) + _conv_pixels = noconv_meth + default_orient = 'horizontal' + + def setUp(self): + super(ScaleTest, self).setUp() + self.scale = self.create() + self.scale.pack() + self.scale.update() + + def create(self, **kwargs): + return ttk.Scale(self.root, **kwargs) + + def test_from(self): + widget = self.create() + self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False) + + def test_length(self): + widget = self.create() + self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i') + + def test_to(self): + widget = self.create() + self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False) + + def test_value(self): + widget = self.create() + self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False) + + def test_custom_event(self): + failure = [1, 1, 1] # will need to be empty + + funcid = self.scale.bind('<<RangeChanged>>', lambda evt: failure.pop()) + + self.scale['from'] = 10 + self.scale['from_'] = 10 + self.scale['to'] = 3 + + self.assertFalse(failure) + + failure = [1, 1, 1] + self.scale.configure(from_=2, to=5) + self.scale.configure(from_=0, to=-2) + self.scale.configure(to=10) + + self.assertFalse(failure) + + + def test_get(self): + if self.wantobjects: + conv = lambda x: x + else: + conv = float + + scale_width = self.scale.winfo_width() + self.assertEqual(self.scale.get(scale_width, 0), self.scale['to']) + + self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from'])) + self.assertEqual(self.scale.get(), self.scale['value']) + self.scale['value'] = 30 + self.assertEqual(self.scale.get(), self.scale['value']) + + self.assertRaises(tkinter.TclError, self.scale.get, '', 0) + self.assertRaises(tkinter.TclError, self.scale.get, 0, '') + + + def test_set(self): + if self.wantobjects: + conv = lambda x: x + else: + conv = float + + # set restricts the max/min values according to the current range + max = conv(self.scale['to']) + new_max = max + 10 + self.scale.set(new_max) + self.assertEqual(conv(self.scale.get()), max) + min = conv(self.scale['from']) + self.scale.set(min - 1) + self.assertEqual(conv(self.scale.get()), min) + + # changing directly the variable doesn't impose this limitation tho + var = tkinter.DoubleVar(self.root) + self.scale['variable'] = var + var.set(max + 5) + self.assertEqual(conv(self.scale.get()), var.get()) + self.assertEqual(conv(self.scale.get()), max + 5) + del var + + # the same happens with the value option + self.scale['value'] = max + 10 + self.assertEqual(conv(self.scale.get()), max + 10) + self.assertEqual(conv(self.scale.get()), conv(self.scale['value'])) + + # nevertheless, note that the max/min values we can get specifying + # x, y coords are the ones according to the current range + self.assertEqual(conv(self.scale.get(0, 0)), min) + self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max) + + self.assertRaises(tkinter.TclError, self.scale.set, None) + + +@add_standard_options(StandardTtkOptionsTests) +class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'cursor', 'orient', 'length', + 'mode', 'maximum', 'phase', + 'style', 'takefocus', 'value', 'variable', + ) + _conv_pixels = noconv_meth + default_orient = 'horizontal' + + def create(self, **kwargs): + return ttk.Progressbar(self.root, **kwargs) + + def test_length(self): + widget = self.create() + self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i') + + def test_maximum(self): + widget = self.create() + self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False) + + def test_mode(self): + widget = self.create() + self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate') + + def test_phase(self): + # XXX + pass + + def test_value(self): + widget = self.create() + self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10, + conv=False) + + +@unittest.skipIf(sys.platform == 'darwin', + 'ttk.Scrollbar is special on MacOSX') +@add_standard_options(StandardTtkOptionsTests) +class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'command', 'cursor', 'orient', 'style', 'takefocus', + ) + default_orient = 'vertical' + + def create(self, **kwargs): + return ttk.Scrollbar(self.root, **kwargs) + + +@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) +class NotebookTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width', + ) + + def setUp(self): + super(NotebookTest, self).setUp() + self.nb = self.create(padding=0) + 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 create(self, **kwargs): + return ttk.Notebook(self.root, **kwargs) + + def test_tab_identifiers(self): + self.nb.forget(0) + self.nb.hide(self.child2) + self.assertRaises(tkinter.TclError, self.nb.tab, self.child1) + self.assertEqual(self.nb.index('end'), 1) + self.nb.add(self.child2) + self.assertEqual(self.nb.index('end'), 1) + self.nb.select(self.child2) + + self.assertTrue(self.nb.tab('current')) + self.nb.add(self.child1, text='a') + + self.nb.pack() + self.nb.wait_visibility() + if sys.platform == 'darwin': + tb_idx = "@20,5" + else: + tb_idx = "@5,5" + self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current')) + + for i in range(5, 100, 5): + try: + if self.nb.tab('@%d, 5' % i, text=None) == 'a': + break + except tkinter.TclError: + pass + + else: + self.fail("Tab with text 'a' not found") + + + def test_add_and_hidden(self): + self.assertRaises(tkinter.TclError, self.nb.hide, -1) + 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.root), + unknown='option') + + tabs = self.nb.tabs() + self.nb.hide(self.child1) + self.nb.add(self.child1) + self.assertEqual(self.nb.tabs(), tabs) + + child = ttk.Label(self.root) + self.nb.add(child, text='c') + tabs = self.nb.tabs() + + curr = self.nb.index('current') + # verify that the tab gets readded at its previous position + child2_index = self.nb.index(self.child2) + self.nb.hide(self.child2) + self.nb.add(self.child2) + self.assertEqual(self.nb.tabs(), tabs) + self.assertEqual(self.nb.index(self.child2), child2_index) + self.assertEqual(str(self.child2), self.nb.tabs()[child2_index]) + # but the tab next to it (not hidden) is the one selected now + self.assertEqual(self.nb.index('current'), curr + 1) + + + def test_forget(self): + self.assertRaises(tkinter.TclError, self.nb.forget, -1) + self.assertRaises(tkinter.TclError, self.nb.forget, 'hi') + self.assertRaises(tkinter.TclError, self.nb.forget, None) + + tabs = self.nb.tabs() + child1_index = self.nb.index(self.child1) + self.nb.forget(self.child1) + self.assertNotIn(str(self.child1), self.nb.tabs()) + self.assertEqual(len(tabs) - 1, len(self.nb.tabs())) + + self.nb.add(self.child1) + self.assertEqual(self.nb.index(self.child1), 1) + self.assertNotEqual(child1_index, self.nb.index(self.child1)) + + + def test_index(self): + self.assertRaises(tkinter.TclError, self.nb.index, -1) + self.assertRaises(tkinter.TclError, self.nb.index, None) + + self.assertIsInstance(self.nb.index('end'), int) + self.assertEqual(self.nb.index(self.child1), 0) + self.assertEqual(self.nb.index(self.child2), 1) + self.assertEqual(self.nb.index('end'), 2) + + + def test_insert(self): + # moving tabs + tabs = self.nb.tabs() + self.nb.insert(1, tabs[0]) + self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0])) + self.nb.insert(self.child1, self.child2) + self.assertEqual(self.nb.tabs(), tabs) + self.nb.insert('end', self.child1) + self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0])) + self.nb.insert('end', 0) + self.assertEqual(self.nb.tabs(), tabs) + # bad moves + self.assertRaises(tkinter.TclError, self.nb.insert, 2, tabs[0]) + self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0]) + + # new tab + 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) + self.assertEqual(self.nb.tabs(), tabs) + self.nb.insert(self.child1, child3) + self.assertEqual(self.nb.tabs(), (str(child3), ) + tabs) + self.nb.forget(child3) + self.assertRaises(tkinter.TclError, self.nb.insert, 2, child3) + self.assertRaises(tkinter.TclError, self.nb.insert, -1, child3) + + # bad inserts + self.assertRaises(tkinter.TclError, self.nb.insert, 'end', None) + self.assertRaises(tkinter.TclError, self.nb.insert, None, 0) + self.assertRaises(tkinter.TclError, self.nb.insert, None, None) + + + def test_select(self): + self.nb.pack() + self.nb.wait_visibility() + + success = [] + tab_changed = [] + + self.child1.bind('<Unmap>', lambda evt: success.append(True)) + self.nb.bind('<<NotebookTabChanged>>', + lambda evt: tab_changed.append(True)) + + self.assertEqual(self.nb.select(), str(self.child1)) + self.nb.select(self.child2) + self.assertTrue(success) + self.assertEqual(self.nb.select(), str(self.child2)) + + self.nb.update() + self.assertTrue(tab_changed) + + + def test_tab(self): + self.assertRaises(tkinter.TclError, self.nb.tab, -1) + self.assertRaises(tkinter.TclError, self.nb.tab, 'notab') + self.assertRaises(tkinter.TclError, self.nb.tab, None) + + self.assertIsInstance(self.nb.tab(self.child1), dict) + self.assertEqual(self.nb.tab(self.child1, text=None), 'a') + # newer form for querying a single option + self.assertEqual(self.nb.tab(self.child1, 'text'), 'a') + self.nb.tab(self.child1, text='abc') + self.assertEqual(self.nb.tab(self.child1, text=None), 'abc') + self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc') + + + def test_tabs(self): + self.assertEqual(len(self.nb.tabs()), 2) + + self.nb.forget(self.child1) + self.nb.forget(self.child2) + + self.assertEqual(self.nb.tabs(), ()) + + + def test_traversal(self): + self.nb.pack() + self.nb.wait_visibility() + + self.nb.select(0) + + 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)) + self.nb.focus_force() + self.nb.event_generate('<Shift-Control-Tab>') + self.assertEqual(self.nb.select(), str(self.child1)) + self.nb.focus_force() + self.nb.event_generate('<Shift-Control-Tab>') + self.assertEqual(self.nb.select(), str(self.child2)) + + self.nb.tab(self.child1, text='a', underline=0) + self.nb.enable_traversal() + self.nb.focus_force() + simulate_mouse_click(self.nb, 5, 5) + if sys.platform == 'darwin': + self.nb.event_generate('<Option-a>') + else: + self.nb.event_generate('<Alt-a>') + self.assertEqual(self.nb.select(), str(self.child1)) + + +@add_standard_options(StandardTtkOptionsTests) +class TreeviewTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'columns', 'cursor', 'displaycolumns', + 'height', 'padding', 'selectmode', 'show', + 'style', 'takefocus', 'xscrollcommand', 'yscrollcommand', + ) + + def setUp(self): + super(TreeviewTest, self).setUp() + self.tv = self.create(padding=0) + + def create(self, **kwargs): + return ttk.Treeview(self.root, **kwargs) + + def test_columns(self): + widget = self.create() + self.checkParam(widget, 'columns', 'a b c', + expected=('a', 'b', 'c')) + self.checkParam(widget, 'columns', ('a', 'b', 'c')) + self.checkParam(widget, 'columns', () if tcl_version < (8, 5) else '') + + def test_displaycolumns(self): + widget = self.create() + widget['columns'] = ('a', 'b', 'c') + self.checkParam(widget, 'displaycolumns', 'b a c', + expected=('b', 'a', 'c')) + self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c')) + self.checkParam(widget, 'displaycolumns', '#all', + expected=('#all',)) + self.checkParam(widget, 'displaycolumns', (2, 1, 0)) + self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'), + errmsg='Invalid column index d') + self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3), + errmsg='Column index 3 out of bounds') + self.checkInvalidParam(widget, 'displaycolumns', (1, -2), + errmsg='Column index -2 out of bounds') + + def test_height(self): + widget = self.create() + self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False) + self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv) + + def test_selectmode(self): + widget = self.create() + self.checkEnumParam(widget, 'selectmode', + 'none', 'browse', 'extended') + + def test_show(self): + widget = self.create() + self.checkParam(widget, 'show', 'tree headings', + expected=('tree', 'headings')) + self.checkParam(widget, 'show', ('tree', 'headings')) + self.checkParam(widget, 'show', ('headings', 'tree')) + self.checkParam(widget, 'show', 'tree', expected=('tree',)) + self.checkParam(widget, 'show', 'headings', expected=('headings',)) + + def test_bbox(self): + self.tv.pack() + self.assertEqual(self.tv.bbox(''), '') + self.tv.wait_visibility() + self.tv.update() + + item_id = self.tv.insert('', 'end') + children = self.tv.get_children() + self.assertTrue(children) + + bbox = self.tv.bbox(children[0]) + self.assertIsBoundingBox(bbox) + + # compare width in bboxes + self.tv['columns'] = ['test'] + self.tv.column('test', width=50) + bbox_column0 = self.tv.bbox(children[0], 0) + root_width = self.tv.column('#0', width=None) + if not self.wantobjects: + root_width = int(root_width) + self.assertEqual(bbox_column0[0], bbox[0] + root_width) + + # verify that bbox of a closed item is the empty string + child1 = self.tv.insert(item_id, 'end') + self.assertEqual(self.tv.bbox(child1), '') + + + def test_children(self): + # no children yet, should get an empty tuple + self.assertEqual(self.tv.get_children(), ()) + + item_id = self.tv.insert('', 'end') + self.assertIsInstance(self.tv.get_children(), tuple) + self.assertEqual(self.tv.get_children()[0], item_id) + + # add item_id and child3 as children of child2 + child2 = self.tv.insert('', 'end') + child3 = self.tv.insert('', 'end') + self.tv.set_children(child2, item_id, child3) + self.assertEqual(self.tv.get_children(child2), (item_id, child3)) + + # child3 has child2 as parent, thus trying to set child2 as a children + # of child3 should result in an error + self.assertRaises(tkinter.TclError, + self.tv.set_children, child3, child2) + + # remove child2 children + self.tv.set_children(child2) + self.assertEqual(self.tv.get_children(child2), ()) + + # remove root's children + self.tv.set_children('') + self.assertEqual(self.tv.get_children(), ()) + + + def test_column(self): + # return a dict with all options/values + self.assertIsInstance(self.tv.column('#0'), dict) + # return a single value of the given option + if self.wantobjects: + self.assertIsInstance(self.tv.column('#0', width=None), int) + # set a new value for an option + self.tv.column('#0', width=10) + # testing new way to get option value + self.assertEqual(self.tv.column('#0', 'width'), + 10 if self.wantobjects else '10') + self.assertEqual(self.tv.column('#0', width=None), + 10 if self.wantobjects else '10') + # check read-only option + self.assertRaises(tkinter.TclError, self.tv.column, '#0', id='X') + + self.assertRaises(tkinter.TclError, self.tv.column, 'invalid') + invalid_kws = [ + {'unknown_option': 'some value'}, {'stretch': 'wrong'}, + {'anchor': 'wrong'}, {'width': 'wrong'}, {'minwidth': 'wrong'} + ] + for kw in invalid_kws: + self.assertRaises(tkinter.TclError, self.tv.column, '#0', + **kw) + + + def test_delete(self): + self.assertRaises(tkinter.TclError, self.tv.delete, '#0') + + item_id = self.tv.insert('', 'end') + item2 = self.tv.insert(item_id, 'end') + self.assertEqual(self.tv.get_children(), (item_id, )) + self.assertEqual(self.tv.get_children(item_id), (item2, )) + + self.tv.delete(item_id) + self.assertFalse(self.tv.get_children()) + + # reattach should fail + self.assertRaises(tkinter.TclError, + self.tv.reattach, item_id, '', 'end') + + # test multiple item delete + item1 = self.tv.insert('', 'end') + item2 = self.tv.insert('', 'end') + self.assertEqual(self.tv.get_children(), (item1, item2)) + + self.tv.delete(item1, item2) + self.assertFalse(self.tv.get_children()) + + + def test_detach_reattach(self): + item_id = self.tv.insert('', 'end') + item2 = self.tv.insert(item_id, 'end') + + # calling detach without items is valid, although it does nothing + prev = self.tv.get_children() + self.tv.detach() # this should do nothing + self.assertEqual(prev, self.tv.get_children()) + + self.assertEqual(self.tv.get_children(), (item_id, )) + self.assertEqual(self.tv.get_children(item_id), (item2, )) + + # detach item with children + self.tv.detach(item_id) + self.assertFalse(self.tv.get_children()) + + # reattach item with children + self.tv.reattach(item_id, '', 'end') + self.assertEqual(self.tv.get_children(), (item_id, )) + self.assertEqual(self.tv.get_children(item_id), (item2, )) + + # move a children to the root + self.tv.move(item2, '', 'end') + self.assertEqual(self.tv.get_children(), (item_id, item2)) + self.assertEqual(self.tv.get_children(item_id), ()) + + # bad values + self.assertRaises(tkinter.TclError, + self.tv.reattach, 'nonexistent', '', 'end') + self.assertRaises(tkinter.TclError, + self.tv.detach, 'nonexistent') + self.assertRaises(tkinter.TclError, + self.tv.reattach, item2, 'otherparent', 'end') + self.assertRaises(tkinter.TclError, + self.tv.reattach, item2, '', 'invalid') + + # multiple detach + self.tv.detach(item_id, item2) + self.assertEqual(self.tv.get_children(), ()) + self.assertEqual(self.tv.get_children(item_id), ()) + + + def test_exists(self): + self.assertEqual(self.tv.exists('something'), False) + self.assertEqual(self.tv.exists(''), True) + self.assertEqual(self.tv.exists({}), False) + + # the following will make a tk.call equivalent to + # tk.call(treeview, "exists") which should result in an error + # in the tcl interpreter since tk requires an item. + self.assertRaises(tkinter.TclError, self.tv.exists, None) + + + def test_focus(self): + # nothing is focused right now + self.assertEqual(self.tv.focus(), '') + + item1 = self.tv.insert('', 'end') + self.tv.focus(item1) + self.assertEqual(self.tv.focus(), item1) + + self.tv.delete(item1) + self.assertEqual(self.tv.focus(), '') + + # try focusing inexistent item + self.assertRaises(tkinter.TclError, self.tv.focus, 'hi') + + + def test_heading(self): + # check a dict is returned + self.assertIsInstance(self.tv.heading('#0'), dict) + + # check a value is returned + self.tv.heading('#0', text='hi') + self.assertEqual(self.tv.heading('#0', 'text'), 'hi') + self.assertEqual(self.tv.heading('#0', text=None), 'hi') + + # invalid option + self.assertRaises(tkinter.TclError, self.tv.heading, '#0', + background=None) + # invalid value + self.assertRaises(tkinter.TclError, self.tv.heading, '#0', + anchor=1) + + def test_heading_callback(self): + def simulate_heading_click(x, y): + simulate_mouse_click(self.tv, x, y) + self.tv.update() + + success = [] # no success for now + + self.tv.pack() + self.tv.wait_visibility() + self.tv.heading('#0', command=lambda: success.append(True)) + self.tv.column('#0', width=100) + self.tv.update() + + # assuming that the coords (5, 5) fall into heading #0 + simulate_heading_click(5, 5) + if not success: + self.fail("The command associated to the treeview heading wasn't " + "invoked.") + + success = [] + commands = self.tv.master._tclCommands + self.tv.heading('#0', command=str(self.tv.heading('#0', command=None))) + self.assertEqual(commands, self.tv.master._tclCommands) + simulate_heading_click(5, 5) + if not success: + self.fail("The command associated to the treeview heading wasn't " + "invoked.") + + # XXX The following raises an error in a tcl interpreter, but not in + # Python + #self.tv.heading('#0', command='I dont exist') + #simulate_heading_click(5, 5) + + + def test_index(self): + # item 'what' doesn't exist + self.assertRaises(tkinter.TclError, self.tv.index, 'what') + + self.assertEqual(self.tv.index(''), 0) + + item1 = self.tv.insert('', 'end') + item2 = self.tv.insert('', 'end') + c1 = self.tv.insert(item1, 'end') + c2 = self.tv.insert(item1, 'end') + self.assertEqual(self.tv.index(item1), 0) + self.assertEqual(self.tv.index(c1), 0) + self.assertEqual(self.tv.index(c2), 1) + self.assertEqual(self.tv.index(item2), 1) + + self.tv.move(item2, '', 0) + self.assertEqual(self.tv.index(item2), 0) + self.assertEqual(self.tv.index(item1), 1) + + # check that index still works even after its parent and siblings + # have been detached + self.tv.detach(item1) + self.assertEqual(self.tv.index(c2), 1) + self.tv.detach(c1) + self.assertEqual(self.tv.index(c2), 0) + + # but it fails after item has been deleted + self.tv.delete(item1) + self.assertRaises(tkinter.TclError, self.tv.index, c2) + + + def test_insert_item(self): + # parent 'none' doesn't exist + self.assertRaises(tkinter.TclError, self.tv.insert, 'none', 'end') + + # open values + self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', + open='') + self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', + open='please') + self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=True))) + self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=False))) + + # invalid index + self.assertRaises(tkinter.TclError, self.tv.insert, '', 'middle') + + # trying to duplicate item id is invalid + itemid = self.tv.insert('', 'end', 'first-item') + self.assertEqual(itemid, 'first-item') + self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', + 'first-item') + self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', + MockTclObj('first-item')) + + # unicode values + value = u'\xe1ba' + item = self.tv.insert('', 'end', values=(value, )) + self.assertEqual(self.tv.item(item, 'values'), + (value,) if self.wantobjects else value) + self.assertEqual(self.tv.item(item, values=None), + (value,) if self.wantobjects else value) + + self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None))) + self.assertEqual(self.tv.item(item, values=None), + (value,) if self.wantobjects else value) + + self.assertIsInstance(self.tv.item(item), dict) + + # erase item values + self.tv.item(item, values='') + self.assertFalse(self.tv.item(item, values=None)) + + # item tags + item = self.tv.insert('', 'end', tags=[1, 2, value]) + self.assertEqual(self.tv.item(item, tags=None), + ('1', '2', value) if self.wantobjects else + '1 2 %s' % value) + self.tv.item(item, tags=[]) + self.assertFalse(self.tv.item(item, tags=None)) + self.tv.item(item, tags=(1, 2)) + self.assertEqual(self.tv.item(item, tags=None), + ('1', '2') if self.wantobjects else '1 2') + + # values with spaces + item = self.tv.insert('', 'end', values=('a b c', + '%s %s' % (value, value))) + self.assertEqual(self.tv.item(item, values=None), + ('a b c', '%s %s' % (value, value)) if self.wantobjects else + '{a b c} {%s %s}' % (value, value)) + + # text + self.assertEqual(self.tv.item( + self.tv.insert('', 'end', text="Label here"), text=None), + "Label here") + self.assertEqual(self.tv.item( + self.tv.insert('', 'end', text=value), text=None), + value) + + + def test_selection(self): + # item 'none' doesn't exist + self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none') + self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none') + self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none') + self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none') + + item1 = self.tv.insert('', 'end') + item2 = self.tv.insert('', 'end') + c1 = self.tv.insert(item1, 'end') + c2 = self.tv.insert(item1, 'end') + c3 = self.tv.insert(item1, 'end') + self.assertEqual(self.tv.selection(), ()) + + self.tv.selection_set((c1, item2)) + self.assertEqual(self.tv.selection(), (c1, item2)) + self.tv.selection_set(c2) + self.assertEqual(self.tv.selection(), (c2,)) + + self.tv.selection_add((c1, item2)) + self.assertEqual(self.tv.selection(), (c1, c2, item2)) + self.tv.selection_add(item1) + self.assertEqual(self.tv.selection(), (item1, c1, c2, item2)) + + self.tv.selection_remove((item1, c3)) + self.assertEqual(self.tv.selection(), (c1, c2, item2)) + self.tv.selection_remove(c2) + self.assertEqual(self.tv.selection(), (c1, item2)) + + self.tv.selection_toggle((c1, c3)) + self.assertEqual(self.tv.selection(), (c3, item2)) + self.tv.selection_toggle(item2) + self.assertEqual(self.tv.selection(), (c3,)) + + self.tv.insert('', 'end', id='with spaces') + self.tv.selection_set('with spaces') + self.assertEqual(self.tv.selection(), ('with spaces',)) + + self.tv.insert('', 'end', id='{brace') + self.tv.selection_set('{brace') + self.assertEqual(self.tv.selection(), ('{brace',)) + + if have_unicode: + self.tv.insert('', 'end', id=u(r'unicode\u20ac')) + self.tv.selection_set(u(r'unicode\u20ac')) + self.assertEqual(self.tv.selection(), (u(r'unicode\u20ac'),)) + + self.tv.insert('', 'end', id='bytes\xe2\x82\xac') + self.tv.selection_set('bytes\xe2\x82\xac') + self.assertEqual(self.tv.selection(), + (u(r'bytes\u20ac') if have_unicode else + 'bytes\xe2\x82\xac',)) + + + def test_set(self): + self.tv['columns'] = ['A', 'B'] + item = self.tv.insert('', 'end', values=['a', 'b']) + self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'}) + + self.tv.set(item, 'B', 'a') + self.assertEqual(self.tv.item(item, values=None), + ('a', 'a') if self.wantobjects else 'a a') + + self.tv['columns'] = ['B'] + self.assertEqual(self.tv.set(item), {'B': 'a'}) + + self.tv.set(item, 'B', 'b') + self.assertEqual(self.tv.set(item, column='B'), 'b') + self.assertEqual(self.tv.item(item, values=None), + ('b', 'a') if self.wantobjects else 'b a') + + self.tv.set(item, 'B', 123) + self.assertEqual(self.tv.set(item, 'B'), + 123 if self.wantobjects else '123') + self.assertEqual(self.tv.item(item, values=None), + (123, 'a') if self.wantobjects else '123 a') + self.assertEqual(self.tv.set(item), + {'B': 123} if self.wantobjects else {'B': '123'}) + + # inexistent column + self.assertRaises(tkinter.TclError, self.tv.set, item, 'A') + self.assertRaises(tkinter.TclError, self.tv.set, item, 'A', 'b') + + # inexistent item + self.assertRaises(tkinter.TclError, self.tv.set, 'notme') + + + def test_tag_bind(self): + events = [] + item1 = self.tv.insert('', 'end', tags=['call']) + item2 = self.tv.insert('', 'end', tags=['call']) + self.tv.tag_bind('call', '<ButtonPress-1>', + lambda evt: events.append(1)) + self.tv.tag_bind('call', '<ButtonRelease-1>', + lambda evt: events.append(2)) + + self.tv.pack() + self.tv.wait_visibility() + self.tv.update() + + pos_y = set() + found = set() + for i in range(0, 100, 10): + if len(found) == 2: # item1 and item2 already found + break + item_id = self.tv.identify_row(i) + if item_id and item_id not in found: + pos_y.add(i) + found.add(item_id) + + self.assertEqual(len(pos_y), 2) # item1 and item2 y pos + for y in pos_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 + self.assertEqual(len(events), 4) + for evt in zip(events[::2], events[1::2]): + self.assertEqual(evt, (1, 2)) + + + def test_tag_configure(self): + # Just testing parameter passing for now + self.assertRaises(TypeError, self.tv.tag_configure) + self.assertRaises(tkinter.TclError, self.tv.tag_configure, + 'test', sky='blue') + self.tv.tag_configure('test', foreground='blue') + self.assertEqual(str(self.tv.tag_configure('test', 'foreground')), + 'blue') + self.assertEqual(str(self.tv.tag_configure('test', foreground=None)), + '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): + OPTIONS = ( + 'class', 'cursor', 'orient', 'style', 'takefocus', + # 'state'? + ) + default_orient = 'horizontal' + + def create(self, **kwargs): + return ttk.Separator(self.root, **kwargs) + + +@add_standard_options(StandardTtkOptionsTests) +class SizegripTest(AbstractWidgetTest, unittest.TestCase): + OPTIONS = ( + 'class', 'cursor', 'style', 'takefocus', + # 'state'? + ) + + def create(self, **kwargs): + return ttk.Sizegrip(self.root, **kwargs) + + +tests_gui = ( + ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest, + FrameTest, LabelFrameTest, LabelTest, MenubuttonTest, + NotebookTest, PanedWindowTest, ProgressbarTest, + RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest, + SizegripTest, TreeviewTest, WidgetTest, + ) + +tests_gui = ( + TreeviewTest, + ) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/lib/python2.7/lib-tk/test/widget_tests.py b/lib/python2.7/lib-tk/test/widget_tests.py new file mode 100644 index 0000000..33f716f --- /dev/null +++ b/lib/python2.7/lib-tk/test/widget_tests.py @@ -0,0 +1,566 @@ +# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py + +import unittest +import sys +import Tkinter as tkinter +from ttk import Scale +from test_ttk.support import (AbstractTkTest, tcl_version, requires_tcl, + get_tk_patchlevel, pixels_conv, tcl_obj_eq) +import test.test_support + + +noconv = noconv_meth = False +if get_tk_patchlevel() < (8, 5, 11): + noconv = str +noconv_meth = noconv and staticmethod(noconv) + +def int_round(x): + return int(round(x)) + +pixels_round = int_round +if get_tk_patchlevel()[:3] == (8, 5, 11): + # Issue #19085: Workaround a bug in Tk + # http://core.tcl.tk/tk/info/3497848 + pixels_round = int + + +_sentinel = object() + +class AbstractWidgetTest(AbstractTkTest): + _conv_pixels = staticmethod(pixels_round) + _conv_pad_pixels = None + _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): + return + self.assertEqual(actual, expected, msg) + + def checkParam(self, widget, name, value, expected=_sentinel, + conv=False, eq=None): + widget[name] = value + if expected is _sentinel: + expected = value + if conv: + expected = conv(expected) + if self._stringify or not self.wantobjects: + if isinstance(expected, tuple): + expected = tkinter._join(expected) + else: + expected = str(expected) + if eq is None: + eq = tcl_obj_eq + self.assertEqual2(widget[name], expected, eq=eq) + self.assertEqual2(widget.cget(name), expected, eq=eq) + # XXX + if not isinstance(widget, Scale): + t = widget.configure(name) + self.assertEqual(len(t), 5) + self.assertEqual2(t[4], expected, eq=eq) + + def checkInvalidParam(self, widget, name, value, errmsg=None, + keep_orig=True): + orig = widget[name] + if errmsg is not None: + errmsg = errmsg.format(value) + with self.assertRaises(tkinter.TclError) as cm: + widget[name] = value + if errmsg is not None: + self.assertEqual(str(cm.exception), errmsg) + if keep_orig: + self.assertEqual(widget[name], orig) + else: + widget[name] = orig + with self.assertRaises(tkinter.TclError) as cm: + widget.configure({name: value}) + if errmsg is not None: + self.assertEqual(str(cm.exception), errmsg) + if keep_orig: + self.assertEqual(widget[name], orig) + else: + widget[name] = orig + + def checkParams(self, widget, name, *values, **kwargs): + for value in values: + self.checkParam(widget, name, value, **kwargs) + + def checkIntegerParam(self, widget, name, *values, **kwargs): + self.checkParams(widget, name, *values, **kwargs) + self.checkInvalidParam(widget, name, '', + errmsg='expected integer but got ""') + self.checkInvalidParam(widget, name, '10p', + errmsg='expected integer but got "10p"') + self.checkInvalidParam(widget, name, 3.2, + errmsg='expected integer but got "3.2"') + + def checkFloatParam(self, widget, name, *values, **kwargs): + if 'conv' in kwargs: + conv = kwargs.pop('conv') + else: + conv = float + for value in values: + self.checkParam(widget, name, value, conv=conv, **kwargs) + self.checkInvalidParam(widget, name, '', + errmsg='expected floating-point number but got ""') + self.checkInvalidParam(widget, name, 'spam', + errmsg='expected floating-point number but got "spam"') + + def checkBooleanParam(self, widget, name): + for value in (False, 0, 'false', 'no', 'off'): + self.checkParam(widget, name, value, expected=0) + for value in (True, 1, 'true', 'yes', 'on'): + self.checkParam(widget, name, value, expected=1) + self.checkInvalidParam(widget, name, '', + errmsg='expected boolean value but got ""') + self.checkInvalidParam(widget, name, 'spam', + errmsg='expected boolean value but got "spam"') + + def checkColorParam(self, widget, name, allow_empty=None, **kwargs): + self.checkParams(widget, name, + '#ff0000', '#00ff00', '#0000ff', '#123456', + 'red', 'green', 'blue', 'white', 'black', 'grey', + **kwargs) + self.checkInvalidParam(widget, name, 'spam', + errmsg='unknown color name "spam"') + + def checkCursorParam(self, widget, name, **kwargs): + self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs) + if tcl_version >= (8, 5): + self.checkParam(widget, name, 'none') + self.checkInvalidParam(widget, name, 'spam', + errmsg='bad cursor spec "spam"') + + def checkCommandParam(self, widget, name): + def command(*args): + pass + widget[name] = command + self.assertTrue(widget[name]) + self.checkParams(widget, name, '') + + def checkEnumParam(self, widget, name, *values, **kwargs): + if 'errmsg' in kwargs: + errmsg = kwargs.pop('errmsg') + else: + errmsg = None + self.checkParams(widget, name, *values, **kwargs) + if errmsg is None: + errmsg2 = ' %s "{}": must be %s%s or %s' % ( + name, + ', '.join(values[:-1]), + ',' if len(values) > 2 else '', + values[-1]) + self.checkInvalidParam(widget, name, '', + errmsg='ambiguous' + errmsg2) + errmsg = 'bad' + errmsg2 + self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) + + def checkPixelsParam(self, widget, name, *values, **kwargs): + if 'conv' in kwargs: + conv = kwargs.pop('conv') + else: + conv = None + if conv is None: + conv = self._conv_pixels + if 'keep_orig' in kwargs: + keep_orig = kwargs.pop('keep_orig') + else: + keep_orig = True + for value in values: + expected = _sentinel + conv1 = conv + if isinstance(value, str): + if conv1 and conv1 is not str: + expected = pixels_conv(value) * self.scaling + conv1 = int_round + self.checkParam(widget, name, value, expected=expected, + conv=conv1, **kwargs) + self.checkInvalidParam(widget, name, '6x', + errmsg='bad screen distance "6x"', keep_orig=keep_orig) + self.checkInvalidParam(widget, name, 'spam', + errmsg='bad screen distance "spam"', keep_orig=keep_orig) + + def checkReliefParam(self, widget, name): + self.checkParams(widget, name, + 'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken') + errmsg='bad relief "spam": must be '\ + 'flat, groove, raised, ridge, solid, or sunken' + if tcl_version < (8, 6): + errmsg = None + self.checkInvalidParam(widget, name, 'spam', + errmsg=errmsg) + + def checkImageParam(self, widget, name): + 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') + widget[name] = '' + + 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 + + def test_keys(self): + widget = self.create() + keys = widget.keys() + # XXX + if not isinstance(widget, Scale): + self.assertEqual(sorted(keys), sorted(widget.configure())) + for k in keys: + widget[k] + # Test if OPTIONS contains all keys + if test.test_support.verbose: + aliases = { + 'bd': 'borderwidth', + 'bg': 'background', + 'fg': 'foreground', + 'invcmd': 'invalidcommand', + 'vcmd': 'validatecommand', + } + keys = set(keys) + expected = set(self.OPTIONS) + for k in sorted(keys - expected): + if not (k in aliases and + aliases[k] in keys and + aliases[k] in expected): + print('%s.OPTIONS doesn\'t contain "%s"' % + (self.__class__.__name__, k)) + + +class StandardOptionsTests(object): + STANDARD_OPTIONS = ( + 'activebackground', 'activeborderwidth', 'activeforeground', 'anchor', + 'background', 'bitmap', 'borderwidth', 'compound', 'cursor', + 'disabledforeground', 'exportselection', 'font', 'foreground', + 'highlightbackground', 'highlightcolor', 'highlightthickness', + 'image', 'insertbackground', 'insertborderwidth', + 'insertofftime', 'insertontime', 'insertwidth', + 'jump', 'justify', 'orient', 'padx', 'pady', 'relief', + 'repeatdelay', 'repeatinterval', + 'selectbackground', 'selectborderwidth', 'selectforeground', + 'setgrid', 'takefocus', 'text', 'textvariable', 'troughcolor', + 'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand', + ) + + def test_activebackground(self): + widget = self.create() + self.checkColorParam(widget, 'activebackground') + + def test_activeborderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'activeborderwidth', + 0, 1.3, 2.9, 6, -2, '10p') + + def test_activeforeground(self): + widget = self.create() + self.checkColorParam(widget, 'activeforeground') + + def test_anchor(self): + widget = self.create() + self.checkEnumParam(widget, 'anchor', + 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center') + + def test_background(self): + widget = self.create() + self.checkColorParam(widget, 'background') + if 'bg' in self.OPTIONS: + self.checkColorParam(widget, 'bg') + + def test_bitmap(self): + widget = self.create() + self.checkParam(widget, 'bitmap', 'questhead') + self.checkParam(widget, 'bitmap', 'gray50') + filename = test.test_support.findfile('python.xbm', subdir='imghdrdata') + self.checkParam(widget, 'bitmap', '@' + filename) + # Cocoa Tk widgets don't detect invalid -bitmap values + # See https://core.tcl.tk/tk/info/31cd33dbf0 + if not ('aqua' in self.root.tk.call('tk', 'windowingsystem') and + 'AppKit' in self.root.winfo_server()): + self.checkInvalidParam(widget, 'bitmap', 'spam', + errmsg='bitmap "spam" not defined') + + def test_borderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'borderwidth', + 0, 1.3, 2.6, 6, -2, '10p') + if 'bd' in self.OPTIONS: + self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, -2, '10p') + + def test_compound(self): + widget = self.create() + self.checkEnumParam(widget, 'compound', + 'bottom', 'center', 'left', 'none', 'right', 'top') + + def test_cursor(self): + widget = self.create() + self.checkCursorParam(widget, 'cursor') + + def test_disabledforeground(self): + widget = self.create() + self.checkColorParam(widget, 'disabledforeground') + + def test_exportselection(self): + widget = self.create() + self.checkBooleanParam(widget, 'exportselection') + + def test_font(self): + widget = self.create() + self.checkParam(widget, 'font', + '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*') + self.checkInvalidParam(widget, 'font', '', + errmsg='font "" doesn\'t exist') + + def test_foreground(self): + widget = self.create() + self.checkColorParam(widget, 'foreground') + if 'fg' in self.OPTIONS: + self.checkColorParam(widget, 'fg') + + def test_highlightbackground(self): + widget = self.create() + self.checkColorParam(widget, 'highlightbackground') + + def test_highlightcolor(self): + widget = self.create() + self.checkColorParam(widget, 'highlightcolor') + + def test_highlightthickness(self): + widget = self.create() + self.checkPixelsParam(widget, 'highlightthickness', + 0, 1.3, 2.6, 6, '10p') + self.checkParam(widget, 'highlightthickness', -2, expected=0, + conv=self._conv_pixels) + + @unittest.skipIf(sys.platform == 'darwin', + 'crashes with Cocoa Tk (issue19733)') + def test_image(self): + widget = self.create() + self.checkImageParam(widget, 'image') + + def test_insertbackground(self): + widget = self.create() + self.checkColorParam(widget, 'insertbackground') + + def test_insertborderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'insertborderwidth', + 0, 1.3, 2.6, 6, -2, '10p') + + def test_insertofftime(self): + widget = self.create() + self.checkIntegerParam(widget, 'insertofftime', 100) + + def test_insertontime(self): + widget = self.create() + self.checkIntegerParam(widget, 'insertontime', 100) + + def test_insertwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p') + + def test_jump(self): + widget = self.create() + self.checkBooleanParam(widget, 'jump') + + def test_justify(self): + widget = self.create() + self.checkEnumParam(widget, 'justify', 'left', 'right', 'center', + errmsg='bad justification "{}": must be ' + 'left, right, or center') + self.checkInvalidParam(widget, 'justify', '', + errmsg='ambiguous justification "": must be ' + 'left, right, or center') + + def test_orient(self): + widget = self.create() + self.assertEqual(str(widget['orient']), self.default_orient) + self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical') + + def test_padx(self): + widget = self.create() + self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m', + conv=self._conv_pad_pixels) + + def test_pady(self): + widget = self.create() + self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m', + conv=self._conv_pad_pixels) + + def test_relief(self): + widget = self.create() + self.checkReliefParam(widget, 'relief') + + def test_repeatdelay(self): + widget = self.create() + self.checkIntegerParam(widget, 'repeatdelay', -500, 500) + + def test_repeatinterval(self): + widget = self.create() + self.checkIntegerParam(widget, 'repeatinterval', -500, 500) + + def test_selectbackground(self): + widget = self.create() + self.checkColorParam(widget, 'selectbackground') + + def test_selectborderwidth(self): + widget = self.create() + self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p') + + def test_selectforeground(self): + widget = self.create() + self.checkColorParam(widget, 'selectforeground') + + def test_setgrid(self): + widget = self.create() + self.checkBooleanParam(widget, 'setgrid') + + def test_state(self): + widget = self.create() + self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal') + + def test_takefocus(self): + widget = self.create() + self.checkParams(widget, 'takefocus', '0', '1', '') + + def test_text(self): + widget = self.create() + self.checkParams(widget, 'text', '', 'any string') + + def test_textvariable(self): + widget = self.create() + var = tkinter.StringVar(self.root) + self.checkVariableParam(widget, 'textvariable', var) + + def test_troughcolor(self): + widget = self.create() + self.checkColorParam(widget, 'troughcolor') + + def test_underline(self): + widget = self.create() + self.checkIntegerParam(widget, 'underline', 0, 1, 10) + + def test_wraplength(self): + widget = self.create() + self.checkPixelsParam(widget, 'wraplength', 100) + + def test_xscrollcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'xscrollcommand') + + def test_yscrollcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'yscrollcommand') + + # non-standard but common options + + def test_command(self): + widget = self.create() + self.checkCommandParam(widget, 'command') + + def test_indicatoron(self): + widget = self.create() + self.checkBooleanParam(widget, 'indicatoron') + + def test_offrelief(self): + widget = self.create() + self.checkReliefParam(widget, 'offrelief') + + def test_overrelief(self): + widget = self.create() + self.checkReliefParam(widget, 'overrelief') + + def test_selectcolor(self): + widget = self.create() + self.checkColorParam(widget, 'selectcolor') + + def test_selectimage(self): + widget = self.create() + self.checkImageParam(widget, 'selectimage') + + @requires_tcl(8, 5) + def test_tristateimage(self): + widget = self.create() + self.checkImageParam(widget, 'tristateimage') + + @requires_tcl(8, 5) + def test_tristatevalue(self): + widget = self.create() + self.checkParam(widget, 'tristatevalue', 'unknowable') + + def test_variable(self): + widget = self.create() + var = tkinter.DoubleVar(self.root) + self.checkVariableParam(widget, 'variable', var) + + +class IntegerSizeTests(object): + def test_height(self): + widget = self.create() + self.checkIntegerParam(widget, 'height', 100, -100, 0) + + def test_width(self): + widget = self.create() + self.checkIntegerParam(widget, 'width', 402, -402, 0) + + +class PixelSizeTests(object): + def test_height(self): + widget = self.create() + self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c') + + def test_width(self): + widget = self.create() + self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i') + + +def add_standard_options(*source_classes): + # This decorator adds test_xxx methods from source classes for every xxx + # option in the OPTIONS class attribute if they are not defined explicitly. + def decorator(cls): + for option in cls.OPTIONS: + methodname = 'test_' + option + if not hasattr(cls, methodname): + for source_class in source_classes: + if hasattr(source_class, methodname): + setattr(cls, methodname, + getattr(source_class, methodname).im_func) + break + else: + def test(self, option=option): + widget = self.create() + widget[option] + raise AssertionError('Option "%s" is not tested in %s' % + (option, cls.__name__)) + test.__name__ = methodname + setattr(cls, methodname, test) + return cls + return decorator + +def setUpModule(): + if test.test_support.verbose: + tcl = tkinter.Tcl() + print 'patchlevel =', tcl.call('info', 'patchlevel') |