python-3.6.zip added from Github

README.cosmo contains the necessary links.
This commit is contained in:
ahgamut 2021-08-08 09:38:33 +05:30 committed by Justine Tunney
parent 75fc601ff5
commit 0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions

View file

@ -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).

View file

View file

@ -0,0 +1,69 @@
"""
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 importlib
import 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'):
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.%s" % (pkg_name, name[:-len(py_ext)]),
"tkinter.test")
except 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.support.run_unittest(*get_tests())

View file

@ -0,0 +1,117 @@
import functools
import re
import tkinter
import unittest
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):
if len(version) <= 2:
return unittest.skipUnless(tcl_version >= version,
'requires Tcl version >= ' + '.'.join(map(str, version)))
def deco(test):
@functools.wraps(test)
def newtest(self):
if get_tk_patchlevel() < version:
self.skipTest('requires Tcl version >= ' +
'.'.join(map(str, version)))
test(self)
return newtest
return deco
_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.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel)
major, minor, releaselevel, serial = m.groups()
major, minor, serial = int(major), int(minor), int(serial)
releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel]
if releaselevel == 'final':
_tk_patchlevel = major, minor, serial, releaselevel, 0
else:
_tk_patchlevel = major, minor, 0, releaselevel, serial
return _tk_patchlevel
units = {
'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

View file

@ -0,0 +1,96 @@
import unittest
import tkinter
from tkinter import font
from test.support import requires, run_unittest
from tkinter.test.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)
def test_measure(self):
self.assertIsInstance(self.font.measure('abc'), int)
def test_metrics(self):
metrics = self.font.metrics()
self.assertGreaterEqual(set(metrics),
{'ascent', 'descent', 'linespace', 'fixed'})
for key in metrics:
self.assertEqual(self.font.metrics(key), metrics[key])
self.assertIsInstance(metrics[key], int)
self.assertIsInstance(self.font.metrics(key), int)
def test_families(self):
families = font.families(self.root)
self.assertIsInstance(families, tuple)
self.assertTrue(families)
for family in families:
self.assertIsInstance(family, str)
self.assertTrue(family)
def test_names(self):
names = font.names(self.root)
self.assertIsInstance(names, tuple)
self.assertTrue(names)
for name in names:
self.assertIsInstance(name, str)
self.assertTrue(name)
self.assertIn(fontname, names)
tests_gui = (FontTest, )
if __name__ == "__main__":
run_unittest(*tests_gui)

View file

@ -0,0 +1,906 @@
import unittest
import re
import tkinter
from tkinter import TclError
from test.support import requires
from tkinter.test.support import pixels_conv, tcl_version, requires_tcl
from tkinter.test.widget_tests import AbstractWidgetTest
requires('gui')
class PackTest(AbstractWidgetTest, unittest.TestCase):
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.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
a.pack_configure(after=b)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(after='.foo')
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
a.pack_configure(after=b)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
a.pack_configure(after=a)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
def test_pack_configure_anchor(self):
pack, a, b, c, d = self.create2()
def check(anchor, geom):
a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20,
expand=True, anchor=anchor)
self.root.update()
self.assertEqual(a.winfo_geometry(), geom)
check('n', '30x70+135+20')
check('ne', '30x70+260+20')
check('e', '30x70+260+65')
check('se', '30x70+260+110')
check('s', '30x70+135+110')
check('sw', '30x70+10+110')
check('w', '30x70+10+65')
check('nw', '30x70+10+20')
check('center', '30x70+135+65')
def test_pack_configure_before(self):
pack, a, b, c, d = self.create2()
with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
a.pack_configure(before=b)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(before='.foo')
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
a.pack_configure(before=d)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
a.pack_configure(before=a)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
def test_pack_configure_expand(self):
pack, a, b, c, d = self.create2()
def check(*geoms):
self.root.update()
self.assertEqual(a.winfo_geometry(), geoms[0])
self.assertEqual(b.winfo_geometry(), geoms[1])
self.assertEqual(c.winfo_geometry(), geoms[2])
self.assertEqual(d.winfo_geometry(), geoms[3])
a.pack_configure(side='left')
b.pack_configure(side='top')
c.pack_configure(side='right')
d.pack_configure(side='bottom')
check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170')
a.pack_configure(side='left', expand='yes')
b.pack_configure(side='top', expand='on')
c.pack_configure(side='right', expand=True)
d.pack_configure(side='bottom', expand=1)
check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135')
a.pack_configure(side='left', expand='yes', fill='both')
b.pack_configure(side='top', expand='on', fill='both')
c.pack_configure(side='right', expand=True, fill='both')
d.pack_configure(side='bottom', expand=1, fill='both')
check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100')
def test_pack_configure_in(self):
pack, a, b, c, d = self.create2()
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
a.pack_configure(in_=pack)
self.assertEqual(pack.pack_slaves(), [b, c, d, a])
a.pack_configure(in_=c)
self.assertEqual(pack.pack_slaves(), [b, c, d])
self.assertEqual(c.pack_slaves(), [a])
with self.assertRaisesRegex(TclError,
'can\'t pack %s inside itself' % (a,)):
a.pack_configure(in_=a)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(in_='.foo')
def test_pack_configure_padx_ipadx_fill(self):
pack, a, b, c, d = self.create2()
def check(geom1, geom2, **kwargs):
a.pack_forget()
b.pack_forget()
a.pack_configure(**kwargs)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('20x40+260+80', '240x200+0+0', side='right', padx=20)
check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30))
check('60x40+240+80', '240x200+0+0', side='right', ipadx=20)
check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10)
check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x')
check('20x40+249+80', '240x200+0+0',
side='right', padx=(9, 31), fill='x')
check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x')
check('30x40+260+80', '250x200+0+0',
side='right', ipadx=5, padx=10, fill='x')
check('30x40+255+80', '250x200+0+0',
side='right', ipadx=5, padx=(5, 15), fill='x')
check('20x40+140+0', '300x160+0+40', side='top', padx=20)
check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40))
check('60x40+120+0', '300x160+0+40', side='top', ipadx=20)
check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10)
check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15))
check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x')
check('260x40+25+0', '300x160+0+40',
side='top', padx=(25, 15), fill='x')
check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x')
check('280x40+10+0', '300x160+0+40',
side='top', ipadx=5, padx=10, fill='x')
check('280x40+5+0', '300x160+0+40',
side='top', ipadx=5, padx=(5, 15), fill='x')
a.pack_configure(padx='1c')
self.assertEqual(a.pack_info()['padx'],
self._str(pack.winfo_pixels('1c')))
a.pack_configure(ipadx='1c')
self.assertEqual(a.pack_info()['ipadx'],
self._str(pack.winfo_pixels('1c')))
def test_pack_configure_pady_ipady_fill(self):
pack, a, b, c, d = self.create2()
def check(geom1, geom2, **kwargs):
a.pack_forget()
b.pack_forget()
a.pack_configure(**kwargs)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('20x40+280+80', '280x200+0+0', side='right', pady=20)
check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30))
check('20x80+280+60', '280x200+0+0', side='right', ipady=20)
check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10)
check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x')
check('20x40+280+69', '280x200+0+0',
side='right', pady=(9, 31), fill='x')
check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x')
check('20x50+280+75', '280x200+0+0',
side='right', ipady=5, pady=10, fill='x')
check('20x50+280+70', '280x200+0+0',
side='right', ipady=5, pady=(5, 15), fill='x')
check('20x40+140+20', '300x120+0+80', side='top', pady=20)
check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40))
check('20x80+140+0', '300x120+0+80', side='top', ipady=20)
check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10)
check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15))
check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x')
check('300x40+0+25', '300x120+0+80',
side='top', pady=(25, 15), fill='x')
check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x')
check('300x50+0+10', '300x130+0+70',
side='top', ipady=5, pady=10, fill='x')
check('300x50+0+5', '300x130+0+70',
side='top', ipady=5, pady=(5, 15), fill='x')
a.pack_configure(pady='1c')
self.assertEqual(a.pack_info()['pady'],
self._str(pack.winfo_pixels('1c')))
a.pack_configure(ipady='1c')
self.assertEqual(a.pack_info()['ipady'],
self._str(pack.winfo_pixels('1c')))
def test_pack_configure_side(self):
pack, a, b, c, d = self.create2()
def check(side, geom1, geom2):
a.pack_configure(side=side)
self.assertEqual(a.pack_info()['side'], side)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('top', '20x40+140+0', '300x160+0+40')
check('bottom', '20x40+140+160', '300x160+0+0')
check('left', '20x40+0+80', '280x200+20+0')
check('right', '20x40+280+80', '280x200+0+0')
def test_pack_forget(self):
pack, a, b, c, d = self.create2()
a.pack_configure()
b.pack_configure()
c.pack_configure()
self.assertEqual(pack.pack_slaves(), [a, b, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
d.pack_forget()
def test_pack_info(self):
pack, a, b, c, d = self.create2()
with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a):
a.pack_info()
a.pack_configure()
b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x',
ipadx=5, padx=10, ipady=2, pady=(5, 15))
info = a.pack_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['anchor'], 'center')
self.assertEqual(info['expand'], self._str(0))
self.assertEqual(info['fill'], 'none')
self.assertEqual(info['in'], pack)
self.assertEqual(info['ipadx'], self._str(0))
self.assertEqual(info['ipady'], self._str(0))
self.assertEqual(info['padx'], self._str(0))
self.assertEqual(info['pady'], self._str(0))
self.assertEqual(info['side'], 'top')
info = b.pack_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['anchor'], 's')
self.assertEqual(info['expand'], self._str(1))
self.assertEqual(info['fill'], 'x')
self.assertEqual(info['in'], a)
self.assertEqual(info['ipadx'], self._str(5))
self.assertEqual(info['ipady'], self._str(2))
self.assertEqual(info['padx'], self._str(10))
self.assertEqual(info['pady'], self._str((5, 15)))
self.assertEqual(info['side'], 'right')
def test_pack_propagate(self):
pack, a, b, c, d = self.create2()
pack.configure(width=300, height=200)
a.pack_configure()
pack.pack_propagate(False)
self.root.update()
self.assertEqual(pack.winfo_reqwidth(), 300)
self.assertEqual(pack.winfo_reqheight(), 200)
pack.pack_propagate(True)
self.root.update()
self.assertEqual(pack.winfo_reqwidth(), 20)
self.assertEqual(pack.winfo_reqheight(), 40)
def test_pack_slaves(self):
pack, a, b, c, d = self.create2()
self.assertEqual(pack.pack_slaves(), [])
a.pack_configure()
self.assertEqual(pack.pack_slaves(), [a])
b.pack_configure()
self.assertEqual(pack.pack_slaves(), [a, b])
class PlaceTest(AbstractWidgetTest, unittest.TestCase):
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.assertRaisesRegex(TclError, "can't place %s relative to "
"itself" % re.escape(str(f2))):
f2.place_configure(in_=f2)
if tcl_version >= (8, 5):
self.assertEqual(f2.winfo_manager(), '')
with self.assertRaisesRegex(TclError, 'bad window path name'):
f2.place_configure(in_='spam')
f2.place_configure(in_=f)
self.assertEqual(f2.winfo_manager(), 'place')
def test_place_configure_x(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['x'], '0')
self.root.update()
self.assertEqual(f2.winfo_x(), 50)
f2.place_configure(x=100)
self.assertEqual(f2.place_info()['x'], '100')
self.root.update()
self.assertEqual(f2.winfo_x(), 150)
f2.place_configure(x=-10, relx=1)
self.assertEqual(f2.place_info()['x'], '-10')
self.root.update()
self.assertEqual(f2.winfo_x(), 190)
with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'):
f2.place_configure(in_=f, x='spam')
def test_place_configure_y(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['y'], '0')
self.root.update()
self.assertEqual(f2.winfo_y(), 40)
f2.place_configure(y=50)
self.assertEqual(f2.place_info()['y'], '50')
self.root.update()
self.assertEqual(f2.winfo_y(), 90)
f2.place_configure(y=-10, rely=1)
self.assertEqual(f2.place_info()['y'], '-10')
self.root.update()
self.assertEqual(f2.winfo_y(), 110)
with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'):
f2.place_configure(in_=f, y='spam')
def test_place_configure_relx(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['relx'], '0')
self.root.update()
self.assertEqual(f2.winfo_x(), 50)
f2.place_configure(relx=0.5)
self.assertEqual(f2.place_info()['relx'], '0.5')
self.root.update()
self.assertEqual(f2.winfo_x(), 125)
f2.place_configure(relx=1)
self.assertEqual(f2.place_info()['relx'], '1')
self.root.update()
self.assertEqual(f2.winfo_x(), 200)
with self.assertRaisesRegex(TclError, 'expected floating-point number '
'but got "spam"'):
f2.place_configure(in_=f, relx='spam')
def test_place_configure_rely(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['rely'], '0')
self.root.update()
self.assertEqual(f2.winfo_y(), 40)
f2.place_configure(rely=0.5)
self.assertEqual(f2.place_info()['rely'], '0.5')
self.root.update()
self.assertEqual(f2.winfo_y(), 80)
f2.place_configure(rely=1)
self.assertEqual(f2.place_info()['rely'], '1')
self.root.update()
self.assertEqual(f2.winfo_y(), 120)
with self.assertRaisesRegex(TclError, 'expected floating-point number '
'but got "spam"'):
f2.place_configure(in_=f, rely='spam')
def test_place_configure_anchor(self):
f = tkinter.Frame(self.root)
with self.assertRaisesRegex(TclError, 'bad anchor "j"'):
f.place_configure(anchor='j')
with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
f.place_configure(anchor='')
for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center':
f.place_configure(anchor=value)
self.assertEqual(f.place_info()['anchor'], value)
def test_place_configure_width(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, width=120)
self.root.update()
self.assertEqual(f2.winfo_width(), 120)
f2.place_configure(width='')
self.root.update()
self.assertEqual(f2.winfo_width(), 30)
with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'):
f2.place_configure(width='abcd')
def test_place_configure_height(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, height=120)
self.root.update()
self.assertEqual(f2.winfo_height(), 120)
f2.place_configure(height='')
self.root.update()
self.assertEqual(f2.winfo_height(), 60)
with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'):
f2.place_configure(height='abcd')
def test_place_configure_relwidth(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, relwidth=0.5)
self.root.update()
self.assertEqual(f2.winfo_width(), 75)
f2.place_configure(relwidth='')
self.root.update()
self.assertEqual(f2.winfo_width(), 30)
with self.assertRaisesRegex(TclError, 'expected floating-point number '
'but got "abcd"'):
f2.place_configure(relwidth='abcd')
def test_place_configure_relheight(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, relheight=0.5)
self.root.update()
self.assertEqual(f2.winfo_height(), 40)
f2.place_configure(relheight='')
self.root.update()
self.assertEqual(f2.winfo_height(), 60)
with self.assertRaisesRegex(TclError, 'expected floating-point number '
'but got "abcd"'):
f2.place_configure(relheight='abcd')
def test_place_configure_bordermode(self):
f = tkinter.Frame(self.root)
with self.assertRaisesRegex(TclError, 'bad bordermode "j"'):
f.place_configure(bordermode='j')
with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'):
f.place_configure(bordermode='')
for value in 'inside', 'outside', 'ignore':
f.place_configure(bordermode=value)
self.assertEqual(f.place_info()['bordermode'], value)
def test_place_forget(self):
foo = tkinter.Frame(self.root)
foo.place_configure(width=50, height=50)
self.root.update()
foo.place_forget()
self.root.update()
self.assertFalse(foo.winfo_ismapped())
with self.assertRaises(TypeError):
foo.place_forget(0)
def test_place_info(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, x=1, y=2, width=3, height=4,
relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4,
anchor='se', bordermode='outside')
info = f2.place_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['x'], '1')
self.assertEqual(info['y'], '2')
self.assertEqual(info['width'], '3')
self.assertEqual(info['height'], '4')
self.assertEqual(info['relx'], '0.1')
self.assertEqual(info['rely'], '0.2')
self.assertEqual(info['relwidth'], '0.3')
self.assertEqual(info['relheight'], '0.4')
self.assertEqual(info['anchor'], 'se')
self.assertEqual(info['bordermode'], 'outside')
self.assertEqual(info['x'], '1')
self.assertEqual(info['x'], '1')
with self.assertRaises(TypeError):
f2.place_info(0)
def test_place_slaves(self):
foo = tkinter.Frame(self.root)
bar = tkinter.Frame(self.root)
self.assertEqual(foo.place_slaves(), [])
bar.place_configure(in_=foo)
self.assertEqual(foo.place_slaves(), [bar])
with self.assertRaises(TypeError):
foo.place_slaves(0)
class GridTest(AbstractWidgetTest, unittest.TestCase):
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)
if tcl_version >= (8, 5):
self.root.grid_anchor('nw')
super().tearDown()
def test_grid_configure(self):
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure()
self.assertEqual(b.grid_info()['in'], self.root)
self.assertEqual(b.grid_info()['column'], self._str(0))
self.assertEqual(b.grid_info()['row'], self._str(0))
b.grid_configure({'column': 1}, row=2)
self.assertEqual(b.grid_info()['column'], self._str(1))
self.assertEqual(b.grid_info()['row'], self._str(2))
def test_grid_configure_column(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad column value "-1": '
'must be a non-negative integer'):
b.grid_configure(column=-1)
b.grid_configure(column=2)
self.assertEqual(b.grid_info()['column'], self._str(2))
def test_grid_configure_columnspan(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad columnspan value "0": '
'must be a positive integer'):
b.grid_configure(columnspan=0)
b.grid_configure(columnspan=2)
self.assertEqual(b.grid_info()['columnspan'], self._str(2))
def test_grid_configure_in(self):
f = tkinter.Frame(self.root)
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure()
self.assertEqual(b.grid_info()['in'], self.root)
b.grid_configure(in_=f)
self.assertEqual(b.grid_info()['in'], f)
b.grid_configure({'in': self.root})
self.assertEqual(b.grid_info()['in'], self.root)
def test_grid_configure_ipadx(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": '
'must be positive screen distance'):
b.grid_configure(ipadx=-1)
b.grid_configure(ipadx=1)
self.assertEqual(b.grid_info()['ipadx'], self._str(1))
b.grid_configure(ipadx='.5c')
self.assertEqual(b.grid_info()['ipadx'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_ipady(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad ipady value "-1": '
'must be positive screen distance'):
b.grid_configure(ipady=-1)
b.grid_configure(ipady=1)
self.assertEqual(b.grid_info()['ipady'], self._str(1))
b.grid_configure(ipady='.5c')
self.assertEqual(b.grid_info()['ipady'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_padx(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
'must be positive screen distance'):
b.grid_configure(padx=-1)
b.grid_configure(padx=1)
self.assertEqual(b.grid_info()['padx'], self._str(1))
b.grid_configure(padx=(10, 5))
self.assertEqual(b.grid_info()['padx'], self._str((10, 5)))
b.grid_configure(padx='.5c')
self.assertEqual(b.grid_info()['padx'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_pady(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
'must be positive screen distance'):
b.grid_configure(pady=-1)
b.grid_configure(pady=1)
self.assertEqual(b.grid_info()['pady'], self._str(1))
b.grid_configure(pady=(10, 5))
self.assertEqual(b.grid_info()['pady'], self._str((10, 5)))
b.grid_configure(pady='.5c')
self.assertEqual(b.grid_info()['pady'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_row(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": '
'must be a non-negative integer'):
b.grid_configure(row=-1)
b.grid_configure(row=2)
self.assertEqual(b.grid_info()['row'], self._str(2))
def test_grid_configure_rownspan(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad rowspan value "0": '
'must be a positive integer'):
b.grid_configure(rowspan=0)
b.grid_configure(rowspan=2)
self.assertEqual(b.grid_info()['rowspan'], self._str(2))
def test_grid_configure_sticky(self):
f = tkinter.Frame(self.root, bg='red')
with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'):
f.grid_configure(sticky='glue')
f.grid_configure(sticky='ne')
self.assertEqual(f.grid_info()['sticky'], 'ne')
f.grid_configure(sticky='n,s,e,w')
self.assertEqual(f.grid_info()['sticky'], 'nesw')
def test_grid_columnconfigure(self):
with self.assertRaises(TypeError):
self.root.grid_columnconfigure()
self.assertEqual(self.root.grid_columnconfigure(0),
{'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
self.root.grid_columnconfigure(0, 'foo')
self.root.grid_columnconfigure((0, 3), weight=2)
with self.assertRaisesRegex(TclError,
'must specify a single element on retrieval'):
self.root.grid_columnconfigure((0, 3))
b = tkinter.Button(self.root)
b.grid_configure(column=0, row=0)
if tcl_version >= (8, 5):
self.root.grid_columnconfigure('all', weight=3)
with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
self.root.grid_columnconfigure('all')
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2)
self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0)
if tcl_version >= (8, 5):
self.root.grid_columnconfigure(b, weight=4)
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4)
def test_grid_columnconfigure_minsize(self):
with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
self.root.grid_columnconfigure(0, minsize='foo')
self.root.grid_columnconfigure(0, minsize=10)
self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10)
self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10)
def test_grid_columnconfigure_weight(self):
with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
self.root.grid_columnconfigure(0, weight='bad')
with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
'should be non-negative'):
self.root.grid_columnconfigure(0, weight=-3)
self.root.grid_columnconfigure(0, weight=3)
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3)
def test_grid_columnconfigure_pad(self):
with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
self.root.grid_columnconfigure(0, pad='foo')
with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
'should be non-negative'):
self.root.grid_columnconfigure(0, pad=-3)
self.root.grid_columnconfigure(0, pad=3)
self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3)
self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3)
def test_grid_columnconfigure_uniform(self):
self.root.grid_columnconfigure(0, uniform='foo')
self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo')
self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo')
def test_grid_rowconfigure(self):
with self.assertRaises(TypeError):
self.root.grid_rowconfigure()
self.assertEqual(self.root.grid_rowconfigure(0),
{'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
self.root.grid_rowconfigure(0, 'foo')
self.root.grid_rowconfigure((0, 3), weight=2)
with self.assertRaisesRegex(TclError,
'must specify a single element on retrieval'):
self.root.grid_rowconfigure((0, 3))
b = tkinter.Button(self.root)
b.grid_configure(column=0, row=0)
if tcl_version >= (8, 5):
self.root.grid_rowconfigure('all', weight=3)
with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
self.root.grid_rowconfigure('all')
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2)
self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0)
if tcl_version >= (8, 5):
self.root.grid_rowconfigure(b, weight=4)
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4)
def test_grid_rowconfigure_minsize(self):
with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
self.root.grid_rowconfigure(0, minsize='foo')
self.root.grid_rowconfigure(0, minsize=10)
self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10)
self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10)
def test_grid_rowconfigure_weight(self):
with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
self.root.grid_rowconfigure(0, weight='bad')
with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
'should be non-negative'):
self.root.grid_rowconfigure(0, weight=-3)
self.root.grid_rowconfigure(0, weight=3)
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3)
def test_grid_rowconfigure_pad(self):
with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'):
self.root.grid_rowconfigure(0, pad='foo')
with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
'should be non-negative'):
self.root.grid_rowconfigure(0, pad=-3)
self.root.grid_rowconfigure(0, pad=3)
self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3)
self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3)
def test_grid_rowconfigure_uniform(self):
self.root.grid_rowconfigure(0, uniform='foo')
self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo')
self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo')
def test_grid_forget(self):
b = tkinter.Button(self.root)
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
b.grid_forget()
c.grid_forget()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
self.assertEqual(info['row'], self._str(0))
self.assertEqual(info['column'], self._str(0))
self.assertEqual(info['rowspan'], self._str(1))
self.assertEqual(info['columnspan'], self._str(1))
self.assertEqual(info['padx'], self._str(0))
self.assertEqual(info['pady'], self._str(0))
self.assertEqual(info['sticky'], '')
def test_grid_remove(self):
b = tkinter.Button(self.root)
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
b.grid_remove()
c.grid_remove()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
self.assertEqual(info['row'], self._str(0))
self.assertEqual(info['column'], self._str(0))
self.assertEqual(info['rowspan'], self._str(2))
self.assertEqual(info['columnspan'], self._str(2))
self.assertEqual(info['padx'], self._str(3))
self.assertEqual(info['pady'], self._str(4))
self.assertEqual(info['sticky'], 'ns')
def test_grid_info(self):
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
info = b.grid_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['in'], self.root)
self.assertEqual(info['row'], self._str(2))
self.assertEqual(info['column'], self._str(2))
self.assertEqual(info['rowspan'], self._str(2))
self.assertEqual(info['columnspan'], self._str(2))
self.assertEqual(info['padx'], self._str(3))
self.assertEqual(info['pady'], self._str(4))
self.assertEqual(info['sticky'], 'ns')
@requires_tcl(8, 5)
def test_grid_anchor(self):
with self.assertRaisesRegex(TclError, 'bad anchor "x"'):
self.root.grid_anchor('x')
with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
self.root.grid_anchor('')
with self.assertRaises(TypeError):
self.root.grid_anchor('se', 'nw')
self.root.grid_anchor('se')
self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se')
def test_grid_bbox(self):
self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0))
self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0))
self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0))
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox('x', 0)
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 'x')
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 0, 'x', 0)
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 0, 0, 'x')
with self.assertRaises(TypeError):
self.root.grid_bbox(0, 0, 0, 0, 0)
t = self.root
# de-maximize
t.wm_geometry('1x1+0+0')
t.wm_geometry('')
f1 = tkinter.Frame(t, width=75, height=75, bg='red')
f2 = tkinter.Frame(t, width=90, height=90, bg='blue')
f1.grid_configure(row=0, column=0)
f2.grid_configure(row=1, column=1)
self.root.update()
self.assertEqual(t.grid_bbox(), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75))
self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90))
self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0))
self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0))
def test_grid_location(self):
with self.assertRaises(TypeError):
self.root.grid_location()
with self.assertRaises(TypeError):
self.root.grid_location(0)
with self.assertRaises(TypeError):
self.root.grid_location(0, 0, 0)
with self.assertRaisesRegex(TclError, 'bad screen distance "x"'):
self.root.grid_location('x', 'y')
with self.assertRaisesRegex(TclError, 'bad screen distance "y"'):
self.root.grid_location('1c', 'y')
t = self.root
# de-maximize
t.wm_geometry('1x1+0+0')
t.wm_geometry('')
f = tkinter.Frame(t, width=200, height=100,
highlightthickness=0, bg='red')
self.assertEqual(f.grid_location(10, 10), (-1, -1))
f.grid_configure()
self.root.update()
self.assertEqual(t.grid_location(-10, -10), (-1, -1))
self.assertEqual(t.grid_location(-10, 0), (-1, 0))
self.assertEqual(t.grid_location(-1, 0), (-1, 0))
self.assertEqual(t.grid_location(0, -10), (0, -1))
self.assertEqual(t.grid_location(0, -1), (0, -1))
self.assertEqual(t.grid_location(0, 0), (0, 0))
self.assertEqual(t.grid_location(200, 0), (0, 0))
self.assertEqual(t.grid_location(201, 0), (1, 0))
self.assertEqual(t.grid_location(0, 100), (0, 0))
self.assertEqual(t.grid_location(0, 101), (0, 1))
self.assertEqual(t.grid_location(201, 101), (1, 1))
def test_grid_propagate(self):
self.assertEqual(self.root.grid_propagate(), True)
with self.assertRaises(TypeError):
self.root.grid_propagate(False, False)
self.root.grid_propagate(False)
self.assertFalse(self.root.grid_propagate())
f = tkinter.Frame(self.root, width=100, height=100, bg='red')
f.grid_configure(row=0, column=0)
self.root.update()
self.assertEqual(f.winfo_width(), 100)
self.assertEqual(f.winfo_height(), 100)
f.grid_propagate(False)
g = tkinter.Frame(self.root, width=75, height=85, bg='green')
g.grid_configure(in_=f, row=0, column=0)
self.root.update()
self.assertEqual(f.winfo_width(), 100)
self.assertEqual(f.winfo_height(), 100)
f.grid_propagate(True)
self.root.update()
self.assertEqual(f.winfo_width(), 75)
self.assertEqual(f.winfo_height(), 85)
def test_grid_size(self):
with self.assertRaises(TypeError):
self.root.grid_size(0)
self.assertEqual(self.root.grid_size(), (0, 0))
f = tkinter.Scale(self.root)
f.grid_configure(row=0, column=0)
self.assertEqual(self.root.grid_size(), (1, 1))
f.grid_configure(row=4, column=5)
self.assertEqual(self.root.grid_size(), (6, 5))
def test_grid_slaves(self):
self.assertEqual(self.root.grid_slaves(), [])
a = tkinter.Label(self.root)
a.grid_configure(row=0, column=1)
b = tkinter.Label(self.root)
b.grid_configure(row=1, column=0)
c = tkinter.Label(self.root)
c.grid_configure(row=1, column=1)
d = tkinter.Label(self.root)
d.grid_configure(row=1, column=1)
self.assertEqual(self.root.grid_slaves(), [d, c, b, a])
self.assertEqual(self.root.grid_slaves(row=0), [a])
self.assertEqual(self.root.grid_slaves(row=1), [d, c, b])
self.assertEqual(self.root.grid_slaves(column=0), [b])
self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])
self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])
tests_gui = (
PackTest, PlaceTest, GridTest,
)
if __name__ == '__main__':
unittest.main()

View file

@ -0,0 +1,327 @@
import unittest
import tkinter
from test import support
from tkinter.test.support import AbstractTkTest, requires_tcl
support.requires('gui')
class MiscTest(AbstractTkTest, unittest.TestCase):
def test_image_types(self):
image_types = self.root.image_types()
self.assertIsInstance(image_types, tuple)
self.assertIn('photo', image_types)
self.assertIn('bitmap', image_types)
def test_image_names(self):
image_names = self.root.image_names()
self.assertIsInstance(image_names, tuple)
class BitmapImageTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.testfile = support.findfile('python.xbm', subdir='imghdrdata')
def test_create_from_file(self):
image = tkinter.BitmapImage('::img::test', master=self.root,
foreground='yellow', background='blue',
file=self.testfile)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'bitmap')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names())
del image
self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_data(self):
with open(self.testfile, 'rb') as f:
data = f.read()
image = tkinter.BitmapImage('::img::test', master=self.root,
foreground='yellow', background='blue',
data=data)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'bitmap')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names())
del image
self.assertNotIn('::img::test', self.root.image_names())
def assertEqualStrList(self, actual, expected):
self.assertIsInstance(actual, str)
self.assertEqual(self.root.splitlist(actual), expected)
def test_configure_data(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['data'], '-data {} {} {} {}')
with open(self.testfile, 'rb') as f:
data = f.read()
image.configure(data=data)
self.assertEqualStrList(image['data'],
('-data', '', '', '', data.decode('ascii')))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['maskdata'], '-maskdata {} {} {} {}')
image.configure(maskdata=data)
self.assertEqualStrList(image['maskdata'],
('-maskdata', '', '', '', data.decode('ascii')))
def test_configure_file(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['file'], '-file {} {} {} {}')
image.configure(file=self.testfile)
self.assertEqualStrList(image['file'],
('-file', '', '', '',self.testfile))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['maskfile'], '-maskfile {} {} {} {}')
image.configure(maskfile=self.testfile)
self.assertEqualStrList(image['maskfile'],
('-maskfile', '', '', '', self.testfile))
def test_configure_background(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['background'], '-background {} {} {} {}')
image.configure(background='blue')
self.assertEqual(image['background'], '-background {} {} {} blue')
def test_configure_foreground(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['foreground'],
'-foreground {} {} #000000 #000000')
image.configure(foreground='yellow')
self.assertEqual(image['foreground'],
'-foreground {} {} #000000 yellow')
class PhotoImageTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.testfile = support.findfile('python.gif', subdir='imghdrdata')
def create(self):
return tkinter.PhotoImage('::img::test', master=self.root,
file=self.testfile)
def colorlist(self, *args):
if tkinter.TkVersion >= 8.6 and self.wantobjects:
return args
else:
return tkinter._join(args)
def check_create_from_file(self, ext):
testfile = support.findfile('python.' + ext, subdir='imghdrdata')
image = tkinter.PhotoImage('::img::test', master=self.root,
file=testfile)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'photo')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['data'], '')
self.assertEqual(image['file'], testfile)
self.assertIn('::img::test', self.root.image_names())
del image
self.assertNotIn('::img::test', self.root.image_names())
def check_create_from_data(self, ext):
testfile = support.findfile('python.' + ext, subdir='imghdrdata')
with open(testfile, 'rb') as f:
data = f.read()
image = tkinter.PhotoImage('::img::test', master=self.root,
data=data)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'photo')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['data'], data if self.wantobjects
else data.decode('latin1'))
self.assertEqual(image['file'], '')
self.assertIn('::img::test', self.root.image_names())
del image
self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_ppm_file(self):
self.check_create_from_file('ppm')
def test_create_from_ppm_data(self):
self.check_create_from_data('ppm')
def test_create_from_pgm_file(self):
self.check_create_from_file('pgm')
def test_create_from_pgm_data(self):
self.check_create_from_data('pgm')
def test_create_from_gif_file(self):
self.check_create_from_file('gif')
def test_create_from_gif_data(self):
self.check_create_from_data('gif')
@requires_tcl(8, 6)
def test_create_from_png_file(self):
self.check_create_from_file('png')
@requires_tcl(8, 6)
def test_create_from_png_data(self):
self.check_create_from_data('png')
def test_configure_data(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['data'], '')
with open(self.testfile, 'rb') as f:
data = f.read()
image.configure(data=data)
self.assertEqual(image['data'], data if self.wantobjects
else data.decode('latin1'))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_format(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['format'], '')
image.configure(file=self.testfile, format='gif')
self.assertEqual(image['format'], ('gif',) if self.wantobjects
else 'gif')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_file(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['file'], '')
image.configure(file=self.testfile)
self.assertEqual(image['file'], self.testfile)
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_gamma(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['gamma'], '1.0')
image.configure(gamma=2.0)
self.assertEqual(image['gamma'], '2.0')
def test_configure_width_height(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['width'], '0')
self.assertEqual(image['height'], '0')
image.configure(width=20)
image.configure(height=10)
self.assertEqual(image['width'], '20')
self.assertEqual(image['height'], '10')
self.assertEqual(image.width(), 20)
self.assertEqual(image.height(), 10)
def test_configure_palette(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['palette'], '')
image.configure(palette=256)
self.assertEqual(image['palette'], '256')
image.configure(palette='3/4/2')
self.assertEqual(image['palette'], '3/4/2')
def test_blank(self):
image = self.create()
image.blank()
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image.get(4, 6), self.colorlist(0, 0, 0))
def test_copy(self):
image = self.create()
image2 = image.copy()
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image.get(4, 6), image.get(4, 6))
def test_subsample(self):
image = self.create()
image2 = image.subsample(2, 3)
self.assertEqual(image2.width(), 8)
self.assertEqual(image2.height(), 6)
self.assertEqual(image2.get(2, 2), image.get(4, 6))
image2 = image.subsample(2)
self.assertEqual(image2.width(), 8)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(2, 3), image.get(4, 6))
def test_zoom(self):
image = self.create()
image2 = image.zoom(2, 3)
self.assertEqual(image2.width(), 32)
self.assertEqual(image2.height(), 48)
self.assertEqual(image2.get(8, 18), image.get(4, 6))
self.assertEqual(image2.get(9, 20), image.get(4, 6))
image2 = image.zoom(2)
self.assertEqual(image2.width(), 32)
self.assertEqual(image2.height(), 32)
self.assertEqual(image2.get(8, 12), image.get(4, 6))
self.assertEqual(image2.get(9, 13), image.get(4, 6))
def test_put(self):
image = self.create()
image.put('{red green} {blue yellow}', to=(4, 6))
self.assertEqual(image.get(4, 6), self.colorlist(255, 0, 0))
self.assertEqual(image.get(5, 6),
self.colorlist(0, 128 if tkinter.TkVersion >= 8.6
else 255, 0))
self.assertEqual(image.get(4, 7), self.colorlist(0, 0, 255))
self.assertEqual(image.get(5, 7), self.colorlist(255, 255, 0))
image.put((('#f00', '#00ff00'), ('#000000fff', '#ffffffff0000')))
self.assertEqual(image.get(0, 0), self.colorlist(255, 0, 0))
self.assertEqual(image.get(1, 0), self.colorlist(0, 255, 0))
self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255))
self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0))
def test_get(self):
image = self.create()
self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162))
self.assertEqual(image.get(0, 0), self.colorlist(0, 0, 0))
self.assertEqual(image.get(15, 15), self.colorlist(0, 0, 0))
self.assertRaises(tkinter.TclError, image.get, -1, 0)
self.assertRaises(tkinter.TclError, image.get, 0, -1)
self.assertRaises(tkinter.TclError, image.get, 16, 15)
self.assertRaises(tkinter.TclError, image.get, 15, 16)
def test_write(self):
image = self.create()
self.addCleanup(support.unlink, support.TESTFN)
image.write(support.TESTFN)
image2 = tkinter.PhotoImage('::img::test2', master=self.root,
format='ppm',
file=support.TESTFN)
self.assertEqual(str(image2), '::img::test2')
self.assertEqual(image2.type(), 'photo')
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(0, 0))
self.assertEqual(image2.get(15, 8), image.get(15, 8))
image.write(support.TESTFN, format='gif', from_coords=(4, 6, 6, 9))
image3 = tkinter.PhotoImage('::img::test3', master=self.root,
format='gif',
file=support.TESTFN)
self.assertEqual(str(image3), '::img::test3')
self.assertEqual(image3.type(), 'photo')
self.assertEqual(image3.width(), 2)
self.assertEqual(image3.height(), 3)
self.assertEqual(image3.get(0, 0), image.get(4, 6))
self.assertEqual(image3.get(1, 2), image.get(5, 8))
tests_gui = (MiscTest, BitmapImageTest, PhotoImageTest,)
if __name__ == "__main__":
support.run_unittest(*tests_gui)

View file

@ -0,0 +1,46 @@
import os
import sys
import unittest
import test.support as 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.
with os.popen('echo $DISPLAY') as pipe:
display = pipe.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)

View file

@ -0,0 +1,163 @@
import unittest
import tkinter
from test import support
from tkinter.test.support import AbstractTkTest
support.requires('gui')
class MiscTest(AbstractTkTest, unittest.TestCase):
def test_repr(self):
t = tkinter.Toplevel(self.root, name='top')
f = tkinter.Frame(t, name='child')
self.assertEqual(repr(f), '<tkinter.Frame object .top.child>')
def test_generated_names(self):
t = tkinter.Toplevel(self.root)
f = tkinter.Frame(t)
f2 = tkinter.Frame(t)
b = tkinter.Button(f2)
for name in str(b).split('.'):
self.assertFalse(name.isidentifier(), msg=repr(name))
def test_tk_setPalette(self):
root = self.root
root.tk_setPalette('black')
self.assertEqual(root['background'], 'black')
root.tk_setPalette('white')
self.assertEqual(root['background'], 'white')
self.assertRaisesRegex(tkinter.TclError,
'^unknown color name "spam"$',
root.tk_setPalette, 'spam')
root.tk_setPalette(background='black')
self.assertEqual(root['background'], 'black')
root.tk_setPalette(background='blue', highlightColor='yellow')
self.assertEqual(root['background'], 'blue')
self.assertEqual(root['highlightcolor'], 'yellow')
root.tk_setPalette(background='yellow', highlightColor='blue')
self.assertEqual(root['background'], 'yellow')
self.assertEqual(root['highlightcolor'], 'blue')
self.assertRaisesRegex(tkinter.TclError,
'^unknown color name "spam"$',
root.tk_setPalette, background='spam')
self.assertRaisesRegex(tkinter.TclError,
'^must specify a background color$',
root.tk_setPalette, spam='white')
self.assertRaisesRegex(tkinter.TclError,
'^must specify a background color$',
root.tk_setPalette, highlightColor='blue')
def test_after(self):
root = self.root
def callback(start=0, step=1):
nonlocal count
count = start + step
# Without function, sleeps for ms.
self.assertIsNone(root.after(1))
# Set up with callback with no args.
count = 0
timer1 = root.after(0, callback)
self.assertIn(timer1, root.tk.call('after', 'info'))
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))
root.update() # Process all pending events.
self.assertEqual(count, 1)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
# Set up with callback with args.
count = 0
timer1 = root.after(0, callback, 42, 11)
root.update() # Process all pending events.
self.assertEqual(count, 53)
# Cancel before called.
timer1 = root.after(1000, callback)
self.assertIn(timer1, root.tk.call('after', 'info'))
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))
root.after_cancel(timer1) # Cancel this event.
self.assertEqual(count, 53)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
def test_after_idle(self):
root = self.root
def callback(start=0, step=1):
nonlocal count
count = start + step
# Set up with callback with no args.
count = 0
idle1 = root.after_idle(callback)
self.assertIn(idle1, root.tk.call('after', 'info'))
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))
root.update_idletasks() # Process all pending events.
self.assertEqual(count, 1)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
# Set up with callback with args.
count = 0
idle1 = root.after_idle(callback, 42, 11)
root.update_idletasks() # Process all pending events.
self.assertEqual(count, 53)
# Cancel before called.
idle1 = root.after_idle(callback)
self.assertIn(idle1, root.tk.call('after', 'info'))
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))
root.after_cancel(idle1) # Cancel this event.
self.assertEqual(count, 53)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
def test_after_cancel(self):
root = self.root
def callback():
nonlocal count
count += 1
timer1 = root.after(5000, callback)
idle1 = root.after_idle(callback)
# No value for id raises a ValueError.
with self.assertRaises(ValueError):
root.after_cancel(None)
# Cancel timer event.
count = 0
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1))
root.tk.call(script)
self.assertEqual(count, 1)
root.after_cancel(timer1)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
self.assertEqual(count, 1)
with self.assertRaises(tkinter.TclError):
root.tk.call('after', 'info', timer1)
# Cancel same event - nothing happens.
root.after_cancel(timer1)
# Cancel idle event.
count = 0
(script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1))
root.tk.call(script)
self.assertEqual(count, 1)
root.after_cancel(idle1)
with self.assertRaises(tkinter.TclError):
root.tk.call(script)
self.assertEqual(count, 1)
with self.assertRaises(tkinter.TclError):
root.tk.call('after', 'info', idle1)
tests_gui = (MiscTest, )
if __name__ == "__main__":
support.run_unittest(*tests_gui)

View file

@ -0,0 +1,47 @@
import unittest
import tkinter
from test.support import requires, run_unittest
from tkinter.test.support import AbstractTkTest
requires('gui')
class TextTest(AbstractTkTest, unittest.TestCase):
def setUp(self):
super().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)

View file

@ -0,0 +1,310 @@
import unittest
import gc
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
class Var(Variable):
_default = "default"
side_effect = False
def set(self, value):
self.side_effect = True
super().set(value)
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.assertRegex(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.globalsetvar(b'var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar('var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar(b'var\x00name', "value")
def test_initialize(self):
v = Var(self.root)
self.assertFalse(v.side_effect)
v.set("value")
self.assertTrue(v.side_effect)
def test_trace_old(self):
# Old interface
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')])
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)
tr1 = v.trace_add('read', read_tracer)
tr2 = v.trace_add(['write', 'unset'], write_tracer)
self.assertEqual(sorted(v.trace_info()), [
(('read',), tr1),
(('write', 'unset'), tr2)])
self.assertEqual(trace, [])
v.set('spam')
self.assertEqual(trace, [('write', vname, '', 'write')])
trace = []
v.get()
self.assertEqual(trace, [('read', vname, '', 'read')])
trace = []
info = sorted(v.trace_info())
v.trace_remove('write', tr1) # Wrong mode
self.assertEqual(sorted(v.trace_info()), info)
with self.assertRaises(TclError):
v.trace_remove('read', 'spam') # Wrong command name
self.assertEqual(sorted(v.trace_info()), info)
v.get()
self.assertEqual(trace, [('read', vname, '', 'read')])
trace = []
v.trace_remove('read', tr1)
self.assertEqual(v.trace_info(), [(('write', 'unset'), tr2)])
v.get()
self.assertEqual(trace, [])
trace = []
del write_tracer
gc.collect()
v.set('eggs')
self.assertEqual(trace, [('write', vname, '', 'write')])
trace = []
del v
gc.collect()
self.assertEqual(trace, [('write', vname, '', 'unset')])
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())
self.root.globalsetvar("name", "876.5")
self.assertEqual(876, v.get())
def test_invalid_value(self):
v = IntVar(self.root, name="name")
self.root.globalsetvar("name", "value")
with self.assertRaises((ValueError, TclError)):
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, TclError)):
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", "on")
self.assertIs(v.get(), True)
def test_set(self):
true = 1 if self.root.wantobjects() else "1"
false = 0 if self.root.wantobjects() else "0"
v = BooleanVar(self.root, name="name")
v.set(True)
self.assertEqual(self.root.globalgetvar("name"), true)
v.set("0")
self.assertEqual(self.root.globalgetvar("name"), false)
v.set(42)
self.assertEqual(self.root.globalgetvar("name"), true)
v.set(0)
self.assertEqual(self.root.globalgetvar("name"), false)
v.set("on")
self.assertEqual(self.root.globalgetvar("name"), true)
def test_invalid_value_domain(self):
false = 0 if self.root.wantobjects() else "0"
v = BooleanVar(self.root, name="name")
with self.assertRaises(TclError):
v.set("value")
self.assertEqual(self.root.globalgetvar("name"), false)
self.root.globalsetvar("name", "value")
with self.assertRaises(ValueError):
v.get()
self.root.globalsetvar("name", "1.0")
with self.assertRaises(ValueError):
v.get()
tests_gui = (TestVariable, TestStringVar, TestIntVar,
TestDoubleVar, TestBooleanVar)
if __name__ == "__main__":
from test.support import run_unittest
run_unittest(*tests_gui)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,323 @@
import sys
import unittest
import tkinter
from tkinter import ttk
from test.support import requires, run_unittest, swap_attr
from tkinter.test.support import AbstractTkTest, destroy_default_root
requires('gui')
class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
def tearDown(self):
self.root.update_idletasks()
super().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.maxsize + 1, sys.maxsize + 1),
(2.5, 2), ('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_=None)
self.assertRaises((ValueError, tkinter.TclError), 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.value, newval)
self.assertEqual(x.label['text'],
newval if self.wantobjects else str(newval))
self.assertEqual(float(x.scale.get()), 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(x.value, newval)
self.assertEqual(conv(x.label['text']), newval)
self.assertEqual(float(x.scale.get()), newval)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
# non-integer value
x.value = newval = newval + 1.5
x.update()
self.assertEqual(x.value, int(newval))
self.assertEqual(conv(x.label['text']), int(newval))
self.assertEqual(float(x.scale.get()), newval)
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().setUp()
self.textvar = tkinter.StringVar(self.root)
def tearDown(self):
del self.textvar
super().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()
def test_unique_radiobuttons(self):
# check that radiobuttons are unique across instances (bpo25684)
items = ('a', 'b', 'c')
default = 'a'
optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items)
textvar2 = tkinter.StringVar(self.root)
optmenu2 = ttk.OptionMenu(self.root, textvar2, default, *items)
optmenu.pack()
optmenu.wait_visibility()
optmenu2.pack()
optmenu2.wait_visibility()
optmenu['menu'].invoke(1)
optmenu2['menu'].invoke(2)
optmenu_stringvar_name = optmenu['menu'].entrycget(0, 'variable')
optmenu2_stringvar_name = optmenu2['menu'].entrycget(0, 'variable')
self.assertNotEqual(optmenu_stringvar_name,
optmenu2_stringvar_name)
self.assertEqual(self.root.tk.globalgetvar(optmenu_stringvar_name),
items[1])
self.assertEqual(self.root.tk.globalgetvar(optmenu2_stringvar_name),
items[2])
optmenu.destroy()
optmenu2.destroy()
tests_gui = (LabeledScaleTest, OptionMenuTest)
if __name__ == "__main__":
run_unittest(*tests_gui)

View file

@ -0,0 +1,461 @@
# -*- encoding: utf-8 -*-
import unittest
from tkinter import ttk
class MockTkApp:
def splitlist(self, arg):
if isinstance(arg, tuple):
return arg
return arg.split(':')
def wantobjects(self):
return True
class MockTclObj(object):
typename = 'test'
def __init__(self, val):
self.val = val
def __str__(self):
return str(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 = {'αβγ': True, 'á': False}
orig_opts = opts.copy()
# check if giving unicode keys is fine
check_against(ttk._format_optdict(opts), {'-αβγ': True, '': 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=('á'))) / 2
self.assertEqual(amount_opts, len(opts) - 1)
# ignore non-existing options
amount_opts = len(ttk._format_optdict(opts, ignore=('á', 'b'))) / 2
self.assertEqual(amount_opts, len(opts) - 1)
# ignore every option
self.assertFalse(ttk._format_optdict(opts, ignore=list(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(list(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 = {'üñíćódè': [('á', 'vãl')]}
result = ttk._format_mapdict(opts)
self.assertEqual(result, ('-üñíćódè', 'á vãl'))
# empty states
valid = {'opt': [('', '', '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 evaluate 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
self.assertEqual(ttk._format_elemcreate('image', False, 'test',
('a', 'b'), a='x'), ("test a b", ("-a", "x")))
# 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], '')
# _format_layoutlist always expects the second item (in every item)
# to act like a dict (except when the value evaluates to False).
self.assertRaises(AttributeError,
ttk._format_layoutlist, [('a', 'b')])
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 by internal functions
# plain wrong format
self.assertRaises(ValueError, ttk._format_layoutlist,
['bad', 'format'])
# will try to use iteritems in the 'bad' string
self.assertRaises(AttributeError, ttk._format_layoutlist,
[('name', 'bad')])
# 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 = {'αβγ': True, 'á': False}
self.assertTrue(
ttk._script_from_settings({'name': {'configure': configdict}}))
mapdict = {'üñíćódè': [('á', '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'), ('áÚ', 'áÚ'), ([], '[]'),
(None, 'None')
)
for orig, expected in tests:
self.assertEqual(ttk._convert_stringval(orig), expected)
class TclObjsToPyTest(unittest.TestCase):
def test_unicode(self):
adict = {'opt': 'välúè'}
self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': 'välúè'})
adict['opt'] = MockTclObj(adict['opt'])
self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': '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'), 'válũè')
self.assertEqual(ttk.tclobjs_to_py(adict),
{'opt': [('a', 'b', '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.support import run_unittest
run_unittest(*tests_nogui)

View file

@ -0,0 +1,92 @@
import unittest
import tkinter
from tkinter import ttk
from test.support import requires, run_unittest
from tkinter.test.support import AbstractTkTest
requires('gui')
class StyleTest(AbstractTkTest, unittest.TestCase):
def setUp(self):
super().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)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,548 @@
# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
import unittest
import sys
import tkinter
from tkinter.ttk import Scale
from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl,
get_tk_patchlevel, pixels_conv, tcl_obj_eq)
import test.support
noconv = False
if get_tk_patchlevel() < (8, 5, 11):
noconv = str
pixels_round = 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, conv=float, **kwargs):
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, errmsg=None, **kwargs):
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,
conv=None, keep_orig=True, **kwargs):
if conv is None:
conv = self._conv_pixels
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 = 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.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:
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.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:
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:
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))
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.support.verbose:
tcl = tkinter.Tcl()
print('patchlevel =', tcl.call('info', 'patchlevel'))