@@ -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+
374677class 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+
429736if __name__ == "__main__" :
430737 unittest .main ()
0 commit comments