@@ -425,6 +425,309 @@ def test_info_patchlevel(self):
425425 self .assertTrue (str (vi ).startswith (f'{ vi .major } .{ vi .minor } ' ))
426426
427427
428+ class BindTest (AbstractTkTest , unittest .TestCase ):
429+
430+ def setUp (self ):
431+ super ().setUp ()
432+ root = self .root
433+ self .frame = tkinter .Frame (self .root , class_ = 'Test' ,
434+ width = 150 , height = 100 )
435+ self .frame .pack ()
436+
437+ def assertCommandExist (self , funcid ):
438+ self .assertEqual (_info_commands (self .root , funcid ), (funcid ,))
439+
440+ def assertCommandNotExist (self , funcid ):
441+ self .assertEqual (_info_commands (self .root , funcid ), ())
442+
443+ def test_bind (self ):
444+ event = '<Control-Alt-Key-a>'
445+ f = self .frame
446+ self .assertEqual (f .bind (), ())
447+ self .assertEqual (f .bind (event ), '' )
448+ def test1 (e ): pass
449+ def test2 (e ): pass
450+
451+ funcid = f .bind (event , test1 )
452+ self .assertEqual (f .bind (), (event ,))
453+ script = f .bind (event )
454+ self .assertIn (funcid , script )
455+ self .assertCommandExist (funcid )
456+
457+ funcid2 = f .bind (event , test2 , add = True )
458+ script = f .bind (event )
459+ self .assertIn (funcid , script )
460+ self .assertIn (funcid2 , script )
461+ self .assertCommandExist (funcid )
462+ self .assertCommandExist (funcid2 )
463+
464+ def test_unbind (self ):
465+ event = '<Control-Alt-Key-b>'
466+ f = self .frame
467+ self .assertEqual (f .bind (), ())
468+ self .assertEqual (f .bind (event ), '' )
469+ def test1 (e ): pass
470+ def test2 (e ): pass
471+
472+ funcid = f .bind (event , test1 )
473+ funcid2 = f .bind (event , test2 , add = True )
474+
475+ self .assertRaises (TypeError , f .unbind )
476+ f .unbind (event )
477+ self .assertEqual (f .bind (event ), '' )
478+ self .assertEqual (f .bind (), ())
479+
480+ def test_unbind2 (self ):
481+ f = self .frame
482+ event = '<Control-Alt-Key-c>'
483+ self .assertEqual (f .bind (), ())
484+ self .assertEqual (f .bind (event ), '' )
485+ def test1 (e ): pass
486+ def test2 (e ): pass
487+
488+ funcid = f .bind (event , test1 )
489+ funcid2 = f .bind (event , test2 , add = True )
490+
491+ f .unbind (event , funcid )
492+ script = f .bind (event )
493+ self .assertNotIn (funcid , script )
494+ self .assertCommandNotExist (funcid )
495+ self .assertCommandExist (funcid2 )
496+
497+ f .unbind (event , funcid2 )
498+ self .assertEqual (f .bind (event ), '' )
499+ self .assertEqual (f .bind (), ())
500+ self .assertCommandNotExist (funcid )
501+ self .assertCommandNotExist (funcid2 )
502+
503+ # non-idempotent
504+ self .assertRaises (tkinter .TclError , f .unbind , event , funcid2 )
505+
506+ def test_bind_rebind (self ):
507+ event = '<Control-Alt-Key-d>'
508+ f = self .frame
509+ self .assertEqual (f .bind (), ())
510+ self .assertEqual (f .bind (event ), '' )
511+ def test1 (e ): pass
512+ def test2 (e ): pass
513+ def test3 (e ): pass
514+
515+ funcid = f .bind (event , test1 )
516+ funcid2 = f .bind (event , test2 , add = True )
517+ script = f .bind (event )
518+ self .assertIn (funcid2 , script )
519+ self .assertIn (funcid , script )
520+ self .assertCommandExist (funcid )
521+ self .assertCommandExist (funcid2 )
522+
523+ funcid3 = f .bind (event , test3 )
524+ script = f .bind (event )
525+ self .assertNotIn (funcid , script )
526+ self .assertNotIn (funcid2 , script )
527+ self .assertIn (funcid3 , script )
528+ self .assertCommandExist (funcid3 )
529+
530+ def test_bind_class (self ):
531+ event = '<Control-Alt-Key-e>'
532+ bind_class = self .root .bind_class
533+ unbind_class = self .root .unbind_class
534+ self .assertRaises (TypeError , bind_class )
535+ self .assertEqual (bind_class ('Test' ), ())
536+ self .assertEqual (bind_class ('Test' , event ), '' )
537+ self .addCleanup (unbind_class , 'Test' , event )
538+ def test1 (e ): pass
539+ def test2 (e ): pass
540+
541+ funcid = bind_class ('Test' , event , test1 )
542+ self .assertEqual (bind_class ('Test' ), (event ,))
543+ script = bind_class ('Test' , event )
544+ self .assertIn (funcid , script )
545+ self .assertCommandExist (funcid )
546+
547+ funcid2 = bind_class ('Test' , event , test2 , add = True )
548+ script = bind_class ('Test' , event )
549+ self .assertIn (funcid , script )
550+ self .assertIn (funcid2 , script )
551+ self .assertCommandExist (funcid )
552+ self .assertCommandExist (funcid2 )
553+
554+ def test_unbind_class (self ):
555+ event = '<Control-Alt-Key-f>'
556+ bind_class = self .root .bind_class
557+ unbind_class = self .root .unbind_class
558+ self .assertEqual (bind_class ('Test' ), ())
559+ self .assertEqual (bind_class ('Test' , event ), '' )
560+ self .addCleanup (unbind_class , 'Test' , event )
561+ def test1 (e ): pass
562+ def test2 (e ): pass
563+
564+ funcid = bind_class ('Test' , event , test1 )
565+ funcid2 = bind_class ('Test' , event , test2 , add = True )
566+
567+ self .assertRaises (TypeError , unbind_class )
568+ self .assertRaises (TypeError , unbind_class , 'Test' )
569+ unbind_class ('Test' , event )
570+ self .assertEqual (bind_class ('Test' , event ), '' )
571+ self .assertEqual (bind_class ('Test' ), ())
572+ self .assertCommandExist (funcid )
573+ self .assertCommandExist (funcid2 )
574+
575+ unbind_class ('Test' , event ) # idempotent
576+
577+ def test_bind_class_rebind (self ):
578+ event = '<Control-Alt-Key-g>'
579+ bind_class = self .root .bind_class
580+ unbind_class = self .root .unbind_class
581+ self .assertEqual (bind_class ('Test' ), ())
582+ self .assertEqual (bind_class ('Test' , event ), '' )
583+ self .addCleanup (unbind_class , 'Test' , event )
584+ def test1 (e ): pass
585+ def test2 (e ): pass
586+ def test3 (e ): pass
587+
588+ funcid = bind_class ('Test' , event , test1 )
589+ funcid2 = bind_class ('Test' , event , test2 , add = True )
590+ script = bind_class ('Test' , event )
591+ self .assertIn (funcid2 , script )
592+ self .assertIn (funcid , script )
593+ self .assertCommandExist (funcid )
594+ self .assertCommandExist (funcid2 )
595+
596+ funcid3 = bind_class ('Test' , event , test3 )
597+ script = bind_class ('Test' , event )
598+ self .assertNotIn (funcid , script )
599+ self .assertNotIn (funcid2 , script )
600+ self .assertIn (funcid3 , script )
601+ self .assertCommandExist (funcid )
602+ self .assertCommandExist (funcid2 )
603+ self .assertCommandExist (funcid3 )
604+
605+ def test_bind_all (self ):
606+ event = '<Control-Alt-Key-h>'
607+ bind_all = self .root .bind_all
608+ unbind_all = self .root .unbind_all
609+ self .assertNotIn (event , bind_all ())
610+ self .assertEqual (bind_all (event ), '' )
611+ self .addCleanup (unbind_all , event )
612+ def test1 (e ): pass
613+ def test2 (e ): pass
614+
615+ funcid = bind_all (event , test1 )
616+ self .assertIn (event , bind_all ())
617+ script = bind_all (event )
618+ self .assertIn (funcid , script )
619+ self .assertCommandExist (funcid )
620+
621+ funcid2 = bind_all (event , test2 , add = True )
622+ script = bind_all (event )
623+ self .assertIn (funcid , script )
624+ self .assertIn (funcid2 , script )
625+ self .assertCommandExist (funcid )
626+ self .assertCommandExist (funcid2 )
627+
628+ def test_unbind_all (self ):
629+ event = '<Control-Alt-Key-i>'
630+ bind_all = self .root .bind_all
631+ unbind_all = self .root .unbind_all
632+ self .assertNotIn (event , bind_all ())
633+ self .assertEqual (bind_all (event ), '' )
634+ self .addCleanup (unbind_all , event )
635+ def test1 (e ): pass
636+ def test2 (e ): pass
637+
638+ funcid = bind_all (event , test1 )
639+ funcid2 = bind_all (event , test2 , add = True )
640+
641+ unbind_all (event )
642+ self .assertEqual (bind_all (event ), '' )
643+ self .assertNotIn (event , bind_all ())
644+ self .assertCommandExist (funcid )
645+ self .assertCommandExist (funcid2 )
646+
647+ unbind_all (event ) # idempotent
648+
649+ def test_bind_all_rebind (self ):
650+ event = '<Control-Alt-Key-j>'
651+ bind_all = self .root .bind_all
652+ unbind_all = self .root .unbind_all
653+ self .assertNotIn (event , bind_all ())
654+ self .assertEqual (bind_all (event ), '' )
655+ self .addCleanup (unbind_all , event )
656+ def test1 (e ): pass
657+ def test2 (e ): pass
658+ def test3 (e ): pass
659+
660+ funcid = bind_all (event , test1 )
661+ funcid2 = bind_all (event , test2 , add = True )
662+ script = bind_all (event )
663+ self .assertIn (funcid2 , script )
664+ self .assertIn (funcid , script )
665+ self .assertCommandExist (funcid )
666+ self .assertCommandExist (funcid2 )
667+
668+ funcid3 = bind_all (event , test3 )
669+ script = bind_all (event )
670+ self .assertNotIn (funcid , script )
671+ self .assertNotIn (funcid2 , script )
672+ self .assertIn (funcid3 , script )
673+ self .assertCommandExist (funcid )
674+ self .assertCommandExist (funcid2 )
675+ self .assertCommandExist (funcid3 )
676+
677+ def test_bindtags (self ):
678+ f = self .frame
679+ self .assertEqual (self .root .bindtags (), ('.' , 'Tk' , 'all' ))
680+ self .assertEqual (f .bindtags (), (str (f ), 'Test' , '.' , 'all' ))
681+ f .bindtags (('a' , 'b c' ))
682+ self .assertEqual (f .bindtags (), ('a' , 'b c' ))
683+
684+ def test_bind_events (self ):
685+ event = '<Enter>'
686+ root = self .root
687+ t = tkinter .Toplevel (root )
688+ f = tkinter .Frame (t , class_ = 'Test' , width = 150 , height = 100 )
689+ f .pack ()
690+ root .wait_visibility () # needed on Windows
691+ root .update_idletasks ()
692+ self .addCleanup (root .unbind_class , 'Test' , event )
693+ self .addCleanup (root .unbind_class , 'Toplevel' , event )
694+ self .addCleanup (root .unbind_class , 'tag' , event )
695+ self .addCleanup (root .unbind_class , 'tag2' , event )
696+ self .addCleanup (root .unbind_all , event )
697+ def test (what ):
698+ return lambda e : events .append ((what , e .widget ))
699+
700+ root .bind_all (event , test ('all' ))
701+ root .bind_class ('Test' , event , test ('frame class' ))
702+ root .bind_class ('Toplevel' , event , test ('toplevel class' ))
703+ root .bind_class ('tag' , event , test ('tag' ))
704+ root .bind_class ('tag2' , event , test ('tag2' ))
705+ f .bind (event , test ('frame' ))
706+ t .bind (event , test ('toplevel' ))
707+
708+ events = []
709+ f .event_generate (event )
710+ self .assertEqual (events , [
711+ ('frame' , f ),
712+ ('frame class' , f ),
713+ ('toplevel' , f ),
714+ ('all' , f ),
715+ ])
716+
717+ events = []
718+ t .event_generate (event )
719+ self .assertEqual (events , [
720+ ('toplevel' , t ),
721+ ('toplevel class' , t ),
722+ ('all' , t ),
723+ ])
724+
725+ f .bindtags (('tag' , 'tag3' ))
726+ events = []
727+ f .event_generate (event )
728+ self .assertEqual (events , [('tag' , f )])
729+
730+
428731class DefaultRootTest (AbstractDefaultRootTest , unittest .TestCase ):
429732
430733 def test_default_root (self ):
@@ -480,5 +783,9 @@ def test_mainloop(self):
480783 self .assertRaises (RuntimeError , tkinter .mainloop )
481784
482785
786+ def _info_commands (widget , pattern = None ):
787+ return widget .tk .splitlist (widget .tk .call ('info' , 'commands' , pattern ))
788+
789+
483790if __name__ == "__main__" :
484791 unittest .main ()
0 commit comments