Skip to content

Commit ab8322f

Browse files
miss-islingtonserhiy-storchakaclaude
authored
[3.13] gh-151678: Add tests for tkinter font, image, variable, Misc and Wm methods (GH-151751) (GH-151756)
* font: copy(), the config alias, the displayof argument of measure and metrics, and the errors raised for invalid options and a wrong number of arguments; * image: the cget method and the config alias, and the errors raised by transparency_get and transparency_set; * variable: that initialize is an alias of set and the deprecated trace is an alias of trace_variable; * Misc: tk_focusNext, tk_focusPrev, tk_strictMotif, tk_bisque and option_readfile; * Wm: wm_iconphoto. (cherry picked from commit 66cc048) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 87a349e commit ab8322f

4 files changed

Lines changed: 102 additions & 0 deletions

File tree

Lib/test/test_tkinter/test_font.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def setUpClass(cls):
2020
cls.font = font.Font(root=cls.root, name=fontname, exists=False)
2121

2222
def test_configure(self):
23+
self.assertEqual(self.font.config, self.font.configure)
2324
options = self.font.configure()
2425
self.assertGreaterEqual(set(options),
2526
{'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})
@@ -35,6 +36,26 @@ def test_configure(self):
3536
self.assertIsInstance(options[key], sizetype)
3637
self.assertIsInstance(self.font.cget(key), sizetype)
3738
self.assertIsInstance(self.font[key], sizetype)
39+
self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
40+
self.font.cget, 'spam')
41+
self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
42+
self.font.configure, spam='x')
43+
self.assertRaises(TypeError, self.font.cget)
44+
self.assertRaises(TypeError, self.font.cget, 'size', 'weight')
45+
46+
def test_copy(self):
47+
f = font.Font(root=self.root, family='Times', size=10, weight='bold')
48+
copied = f.copy()
49+
self.assertIsInstance(copied, font.Font)
50+
self.assertIsNot(copied, f)
51+
self.assertNotEqual(copied.name, f.name)
52+
self.assertEqual(copied.actual(), f.actual())
53+
# The copy is independent of the original.
54+
sizetype = int if self.wantobjects else str
55+
copied.configure(size=20)
56+
self.assertEqual(f.cget('size'), sizetype(10))
57+
self.assertEqual(copied.cget('size'), sizetype(20))
58+
self.assertRaises(TypeError, f.copy, 'x')
3859

3960
def test_unicode_family(self):
4061
family = 'MS \u30b4\u30b7\u30c3\u30af'
@@ -59,6 +80,9 @@ def test_actual(self):
5980
for key in 'size', 'underline', 'overstrike':
6081
self.assertIsInstance(options[key], sizetype)
6182
self.assertIsInstance(self.font.actual(key), sizetype)
83+
self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
84+
self.font.actual, 'spam')
85+
self.assertRaises(TypeError, self.font.actual, 'size', 'weight', 'slant')
6286

6387
def test_name(self):
6488
self.assertEqual(self.font.name, fontname)
@@ -82,15 +106,24 @@ def test_equality(self):
82106

83107
def test_measure(self):
84108
self.assertIsInstance(self.font.measure('abc'), int)
109+
self.assertEqual(self.font.measure(''), 0)
110+
self.assertIsInstance(
111+
self.font.measure('abc', displayof=self.root), int)
112+
self.assertRaises(TypeError, self.font.measure)
113+
self.assertRaises(TypeError, self.font.measure, 'a', 'b', 'c')
85114

86115
def test_metrics(self):
87116
metrics = self.font.metrics()
88117
self.assertGreaterEqual(set(metrics),
89118
{'ascent', 'descent', 'linespace', 'fixed'})
90119
for key in metrics:
91120
self.assertEqual(self.font.metrics(key), metrics[key])
121+
self.assertEqual(self.font.metrics(key, displayof=self.root),
122+
metrics[key])
92123
self.assertIsInstance(metrics[key], int)
93124
self.assertIsInstance(self.font.metrics(key), int)
125+
self.assertRaisesRegex(tkinter.TclError, 'bad metric "-spam"',
126+
self.font.metrics, 'spam')
94127

95128
def test_families(self):
96129
families = font.families(self.root)

Lib/test/test_tkinter/test_images.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ def test_configure_width_height(self):
272272
image.configure(height=10)
273273
self.assertEqual(image['width'], '20')
274274
self.assertEqual(image['height'], '10')
275+
self.assertEqual(image.cget('width'), image['width'])
276+
self.assertEqual(image.cget('height'), image['height'])
277+
self.assertRaises(TypeError, image.cget)
278+
self.assertRaises(TypeError, image.cget, 'width', 'height')
279+
self.assertEqual(image.config, image.configure)
275280
self.assertEqual(image.width(), 20)
276281
self.assertEqual(image.height(), 10)
277282

@@ -648,6 +653,14 @@ def test_transparency(self):
648653
self.assertEqual(image.transparency_get(4, 6), True)
649654
image.transparency_set(4, 6, False)
650655
self.assertEqual(image.transparency_get(4, 6), False)
656+
self.assertRaises(tkinter.TclError, image.transparency_get, -1, 0)
657+
self.assertRaises(tkinter.TclError, image.transparency_get, 16, 0)
658+
self.assertRaises(tkinter.TclError, image.transparency_set, -1, 0, True)
659+
self.assertRaises(tkinter.TclError, image.transparency_set, 16, 0, True)
660+
self.assertRaises(TypeError, image.transparency_get, 0)
661+
self.assertRaises(TypeError, image.transparency_get, 0, 0, 0)
662+
self.assertRaises(TypeError, image.transparency_set, 0, 0)
663+
self.assertRaises(TypeError, image.transparency_set, 0, 0, True, 0)
651664

652665

653666
if __name__ == "__main__":

Lib/test/test_tkinter/test_misc.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from tkinter import TclError
55
import enum
66
from test import support
7+
from test.support import os_helper
78
from test.test_tkinter.support import setUpModule # noqa: F401
89
from test.test_tkinter.support import (AbstractTkTest, AbstractDefaultRootTest,
910
requires_tk, get_tk_patchlevel)
@@ -340,6 +341,19 @@ def test_option(self):
340341
self.root.option_clear()
341342
self.assertEqual(b.option_get('background', 'Background'), '')
342343

344+
def test_option_readfile(self):
345+
self.addCleanup(self.root.option_clear)
346+
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
347+
with open(os_helper.TESTFN, 'w') as f:
348+
f.write('*Button.background: red\n')
349+
self.root.option_readfile(os_helper.TESTFN)
350+
b = tkinter.Button(self.root)
351+
self.assertEqual(b.option_get('background', 'Background'), 'red')
352+
self.assertRaises(TclError, self.root.option_readfile,
353+
os_helper.TESTFN + '.nonexistent')
354+
self.assertRaises(TypeError, self.root.option_readfile)
355+
self.assertRaises(TypeError, self.root.option_readfile, 'a', 'b', 'c')
356+
343357
def test_nametowidget(self):
344358
b = tkinter.Button(self.root, name='btn')
345359
self.assertIs(self.root.nametowidget('btn'), b)
@@ -400,6 +414,38 @@ def test_bell(self):
400414
self.root.bell() # No exception.
401415
self.root.bell(displayof=self.root)
402416

417+
def test_tk_focusNext_focusPrev(self):
418+
f = tkinter.Frame(self.root)
419+
f.pack()
420+
entries = [tkinter.Entry(f) for _ in range(3)]
421+
for entry in entries:
422+
entry.pack()
423+
# tk_focusNext skips widgets that are not viewable.
424+
entries[-1].wait_visibility()
425+
self.assertIs(entries[0].tk_focusNext(), entries[1])
426+
self.assertIs(entries[1].tk_focusNext(), entries[2])
427+
self.assertIs(entries[2].tk_focusPrev(), entries[1])
428+
self.assertIs(entries[1].tk_focusPrev(), entries[0])
429+
self.assertRaises(TypeError, entries[0].tk_focusNext, 'x')
430+
self.assertRaises(TypeError, entries[0].tk_focusPrev, 'x')
431+
432+
def test_tk_strictMotif(self):
433+
self.addCleanup(self.root.tk_strictMotif, False)
434+
self.assertIs(self.root.tk_strictMotif(), False)
435+
self.assertIs(self.root.tk_strictMotif(True), True)
436+
self.assertIs(self.root.tk_strictMotif(), True)
437+
self.assertIs(self.root.tk_strictMotif(False), False)
438+
self.assertRaises(TypeError, self.root.tk_strictMotif, 1, 2)
439+
440+
def test_tk_bisque(self):
441+
# tk_bisque resets the color palette; use a separate root so that
442+
# the shared one is not affected.
443+
root = tkinter.Tk()
444+
self.addCleanup(root.destroy)
445+
root.tk_bisque()
446+
self.assertEqual(root['background'], '#ffe4c4')
447+
self.assertRaises(TypeError, root.tk_bisque, 'x')
448+
403449
def test_event_repr_defaults(self):
404450
e = tkinter.Event()
405451
e.serial = 12345
@@ -776,6 +822,13 @@ def test_wm_iconbitmap(self):
776822

777823
t.destroy()
778824

825+
def test_wm_iconphoto(self):
826+
t = tkinter.Toplevel(self.root)
827+
img = tkinter.PhotoImage(master=t, width=16, height=16)
828+
t.wm_iconphoto(False, img) # No exception.
829+
t.wm_iconphoto(True, img)
830+
self.assertRaises(tkinter.TclError, t.wm_iconphoto, False, 'spam')
831+
779832
def test_wm_title(self):
780833
t = tkinter.Toplevel(self.root)
781834
t.title('Hello')

Lib/test/test_tkinter/test_variables.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,15 @@ def test_initialize(self):
111111
self.assertFalse(v.side_effect)
112112
v.set("value")
113113
self.assertTrue(v.side_effect)
114+
self.assertEqual(Variable.initialize, Variable.set)
114115

115116
def test_trace_old(self):
116117
if tcl_version >= (9, 0):
117118
self.skipTest('requires Tcl version < 9.0')
118119
# Old interface
119120
v = Variable(self.root)
120121
vname = str(v)
122+
self.assertEqual(v.trace, v.trace_variable)
121123
trace = []
122124
def read_tracer(*args):
123125
trace.append(('read',) + args)
@@ -313,6 +315,7 @@ def test_set(self):
313315
self.assertEqual(self.root.globalgetvar("name"), false)
314316
v.set("on")
315317
self.assertEqual(self.root.globalgetvar("name"), true)
318+
self.assertEqual(BooleanVar.initialize, BooleanVar.set)
316319

317320
def test_invalid_value_domain(self):
318321
false = 0 if self.root.wantobjects() else "0"

0 commit comments

Comments
 (0)