Skip to content

Commit c905fab

Browse files
[3.11] gh-75666: Tkinter: add tests for binding (GH-111202) (GH-111256)
(cherry picked from commit 9bb202a) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 10376a1 commit c905fab

File tree

1 file changed

+307
-0
lines changed

1 file changed

+307
-0
lines changed

Lib/tkinter/test/test_tkinter/test_misc.py

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,309 @@ def test_info_patchlevel(self):
371371
self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}'))
372372

373373

374+
class BindTest(AbstractTkTest, unittest.TestCase):
375+
376+
def setUp(self):
377+
super().setUp()
378+
root = self.root
379+
self.frame = tkinter.Frame(self.root, class_='Test',
380+
width=150, height=100)
381+
self.frame.pack()
382+
383+
def assertCommandExist(self, funcid):
384+
self.assertEqual(_info_commands(self.root, funcid), (funcid,))
385+
386+
def assertCommandNotExist(self, funcid):
387+
self.assertEqual(_info_commands(self.root, funcid), ())
388+
389+
def test_bind(self):
390+
event = '<Control-Alt-Key-a>'
391+
f = self.frame
392+
self.assertEqual(f.bind(), ())
393+
self.assertEqual(f.bind(event), '')
394+
def test1(e): pass
395+
def test2(e): pass
396+
397+
funcid = f.bind(event, test1)
398+
self.assertEqual(f.bind(), (event,))
399+
script = f.bind(event)
400+
self.assertIn(funcid, script)
401+
self.assertCommandExist(funcid)
402+
403+
funcid2 = f.bind(event, test2, add=True)
404+
script = f.bind(event)
405+
self.assertIn(funcid, script)
406+
self.assertIn(funcid2, script)
407+
self.assertCommandExist(funcid)
408+
self.assertCommandExist(funcid2)
409+
410+
def test_unbind(self):
411+
event = '<Control-Alt-Key-b>'
412+
f = self.frame
413+
self.assertEqual(f.bind(), ())
414+
self.assertEqual(f.bind(event), '')
415+
def test1(e): pass
416+
def test2(e): pass
417+
418+
funcid = f.bind(event, test1)
419+
funcid2 = f.bind(event, test2, add=True)
420+
421+
self.assertRaises(TypeError, f.unbind)
422+
f.unbind(event)
423+
self.assertEqual(f.bind(event), '')
424+
self.assertEqual(f.bind(), ())
425+
426+
def test_unbind2(self):
427+
f = self.frame
428+
event = '<Control-Alt-Key-c>'
429+
self.assertEqual(f.bind(), ())
430+
self.assertEqual(f.bind(event), '')
431+
def test1(e): pass
432+
def test2(e): pass
433+
434+
funcid = f.bind(event, test1)
435+
funcid2 = f.bind(event, test2, add=True)
436+
437+
f.unbind(event, funcid)
438+
script = f.bind(event)
439+
self.assertNotIn(funcid, script)
440+
self.assertCommandNotExist(funcid)
441+
self.assertCommandExist(funcid2)
442+
443+
f.unbind(event, funcid2)
444+
self.assertEqual(f.bind(event), '')
445+
self.assertEqual(f.bind(), ())
446+
self.assertCommandNotExist(funcid)
447+
self.assertCommandNotExist(funcid2)
448+
449+
# non-idempotent
450+
self.assertRaises(tkinter.TclError, f.unbind, event, funcid2)
451+
452+
def test_bind_rebind(self):
453+
event = '<Control-Alt-Key-d>'
454+
f = self.frame
455+
self.assertEqual(f.bind(), ())
456+
self.assertEqual(f.bind(event), '')
457+
def test1(e): pass
458+
def test2(e): pass
459+
def test3(e): pass
460+
461+
funcid = f.bind(event, test1)
462+
funcid2 = f.bind(event, test2, add=True)
463+
script = f.bind(event)
464+
self.assertIn(funcid2, script)
465+
self.assertIn(funcid, script)
466+
self.assertCommandExist(funcid)
467+
self.assertCommandExist(funcid2)
468+
469+
funcid3 = f.bind(event, test3)
470+
script = f.bind(event)
471+
self.assertNotIn(funcid, script)
472+
self.assertNotIn(funcid2, script)
473+
self.assertIn(funcid3, script)
474+
self.assertCommandExist(funcid3)
475+
476+
def test_bind_class(self):
477+
event = '<Control-Alt-Key-e>'
478+
bind_class = self.root.bind_class
479+
unbind_class = self.root.unbind_class
480+
self.assertRaises(TypeError, bind_class)
481+
self.assertEqual(bind_class('Test'), ())
482+
self.assertEqual(bind_class('Test', event), '')
483+
self.addCleanup(unbind_class, 'Test', event)
484+
def test1(e): pass
485+
def test2(e): pass
486+
487+
funcid = bind_class('Test', event, test1)
488+
self.assertEqual(bind_class('Test'), (event,))
489+
script = bind_class('Test', event)
490+
self.assertIn(funcid, script)
491+
self.assertCommandExist(funcid)
492+
493+
funcid2 = bind_class('Test', event, test2, add=True)
494+
script = bind_class('Test', event)
495+
self.assertIn(funcid, script)
496+
self.assertIn(funcid2, script)
497+
self.assertCommandExist(funcid)
498+
self.assertCommandExist(funcid2)
499+
500+
def test_unbind_class(self):
501+
event = '<Control-Alt-Key-f>'
502+
bind_class = self.root.bind_class
503+
unbind_class = self.root.unbind_class
504+
self.assertEqual(bind_class('Test'), ())
505+
self.assertEqual(bind_class('Test', event), '')
506+
self.addCleanup(unbind_class, 'Test', event)
507+
def test1(e): pass
508+
def test2(e): pass
509+
510+
funcid = bind_class('Test', event, test1)
511+
funcid2 = bind_class('Test', event, test2, add=True)
512+
513+
self.assertRaises(TypeError, unbind_class)
514+
self.assertRaises(TypeError, unbind_class, 'Test')
515+
unbind_class('Test', event)
516+
self.assertEqual(bind_class('Test', event), '')
517+
self.assertEqual(bind_class('Test'), ())
518+
self.assertCommandExist(funcid)
519+
self.assertCommandExist(funcid2)
520+
521+
unbind_class('Test', event) # idempotent
522+
523+
def test_bind_class_rebind(self):
524+
event = '<Control-Alt-Key-g>'
525+
bind_class = self.root.bind_class
526+
unbind_class = self.root.unbind_class
527+
self.assertEqual(bind_class('Test'), ())
528+
self.assertEqual(bind_class('Test', event), '')
529+
self.addCleanup(unbind_class, 'Test', event)
530+
def test1(e): pass
531+
def test2(e): pass
532+
def test3(e): pass
533+
534+
funcid = bind_class('Test', event, test1)
535+
funcid2 = bind_class('Test', event, test2, add=True)
536+
script = bind_class('Test', event)
537+
self.assertIn(funcid2, script)
538+
self.assertIn(funcid, script)
539+
self.assertCommandExist(funcid)
540+
self.assertCommandExist(funcid2)
541+
542+
funcid3 = bind_class('Test', event, test3)
543+
script = bind_class('Test', event)
544+
self.assertNotIn(funcid, script)
545+
self.assertNotIn(funcid2, script)
546+
self.assertIn(funcid3, script)
547+
self.assertCommandExist(funcid)
548+
self.assertCommandExist(funcid2)
549+
self.assertCommandExist(funcid3)
550+
551+
def test_bind_all(self):
552+
event = '<Control-Alt-Key-h>'
553+
bind_all = self.root.bind_all
554+
unbind_all = self.root.unbind_all
555+
self.assertNotIn(event, bind_all())
556+
self.assertEqual(bind_all(event), '')
557+
self.addCleanup(unbind_all, event)
558+
def test1(e): pass
559+
def test2(e): pass
560+
561+
funcid = bind_all(event, test1)
562+
self.assertIn(event, bind_all())
563+
script = bind_all(event)
564+
self.assertIn(funcid, script)
565+
self.assertCommandExist(funcid)
566+
567+
funcid2 = bind_all(event, test2, add=True)
568+
script = bind_all(event)
569+
self.assertIn(funcid, script)
570+
self.assertIn(funcid2, script)
571+
self.assertCommandExist(funcid)
572+
self.assertCommandExist(funcid2)
573+
574+
def test_unbind_all(self):
575+
event = '<Control-Alt-Key-i>'
576+
bind_all = self.root.bind_all
577+
unbind_all = self.root.unbind_all
578+
self.assertNotIn(event, bind_all())
579+
self.assertEqual(bind_all(event), '')
580+
self.addCleanup(unbind_all, event)
581+
def test1(e): pass
582+
def test2(e): pass
583+
584+
funcid = bind_all(event, test1)
585+
funcid2 = bind_all(event, test2, add=True)
586+
587+
unbind_all(event)
588+
self.assertEqual(bind_all(event), '')
589+
self.assertNotIn(event, bind_all())
590+
self.assertCommandExist(funcid)
591+
self.assertCommandExist(funcid2)
592+
593+
unbind_all(event) # idempotent
594+
595+
def test_bind_all_rebind(self):
596+
event = '<Control-Alt-Key-j>'
597+
bind_all = self.root.bind_all
598+
unbind_all = self.root.unbind_all
599+
self.assertNotIn(event, bind_all())
600+
self.assertEqual(bind_all(event), '')
601+
self.addCleanup(unbind_all, event)
602+
def test1(e): pass
603+
def test2(e): pass
604+
def test3(e): pass
605+
606+
funcid = bind_all(event, test1)
607+
funcid2 = bind_all(event, test2, add=True)
608+
script = bind_all(event)
609+
self.assertIn(funcid2, script)
610+
self.assertIn(funcid, script)
611+
self.assertCommandExist(funcid)
612+
self.assertCommandExist(funcid2)
613+
614+
funcid3 = bind_all(event, test3)
615+
script = bind_all(event)
616+
self.assertNotIn(funcid, script)
617+
self.assertNotIn(funcid2, script)
618+
self.assertIn(funcid3, script)
619+
self.assertCommandExist(funcid)
620+
self.assertCommandExist(funcid2)
621+
self.assertCommandExist(funcid3)
622+
623+
def test_bindtags(self):
624+
f = self.frame
625+
self.assertEqual(self.root.bindtags(), ('.', 'Tk', 'all'))
626+
self.assertEqual(f.bindtags(), (str(f), 'Test', '.', 'all'))
627+
f.bindtags(('a', 'b c'))
628+
self.assertEqual(f.bindtags(), ('a', 'b c'))
629+
630+
def test_bind_events(self):
631+
event = '<Enter>'
632+
root = self.root
633+
t = tkinter.Toplevel(root)
634+
f = tkinter.Frame(t, class_='Test', width=150, height=100)
635+
f.pack()
636+
root.wait_visibility() # needed on Windows
637+
root.update_idletasks()
638+
self.addCleanup(root.unbind_class, 'Test', event)
639+
self.addCleanup(root.unbind_class, 'Toplevel', event)
640+
self.addCleanup(root.unbind_class, 'tag', event)
641+
self.addCleanup(root.unbind_class, 'tag2', event)
642+
self.addCleanup(root.unbind_all, event)
643+
def test(what):
644+
return lambda e: events.append((what, e.widget))
645+
646+
root.bind_all(event, test('all'))
647+
root.bind_class('Test', event, test('frame class'))
648+
root.bind_class('Toplevel', event, test('toplevel class'))
649+
root.bind_class('tag', event, test('tag'))
650+
root.bind_class('tag2', event, test('tag2'))
651+
f.bind(event, test('frame'))
652+
t.bind(event, test('toplevel'))
653+
654+
events = []
655+
f.event_generate(event)
656+
self.assertEqual(events, [
657+
('frame', f),
658+
('frame class', f),
659+
('toplevel', f),
660+
('all', f),
661+
])
662+
663+
events = []
664+
t.event_generate(event)
665+
self.assertEqual(events, [
666+
('toplevel', t),
667+
('toplevel class', t),
668+
('all', t),
669+
])
670+
671+
f.bindtags(('tag', 'tag3'))
672+
events = []
673+
f.event_generate(event)
674+
self.assertEqual(events, [('tag', f)])
675+
676+
374677
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
375678

376679
def test_default_root(self):
@@ -426,5 +729,9 @@ def test_mainloop(self):
426729
self.assertRaises(RuntimeError, tkinter.mainloop)
427730

428731

732+
def _info_commands(widget, pattern=None):
733+
return widget.tk.splitlist(widget.tk.call('info', 'commands', pattern))
734+
735+
429736
if __name__ == "__main__":
430737
unittest.main()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy