1
+ """Test tooltip, coverage 100%.
2
+
3
+ Coverage is 100% after excluding 6 lines with "# pragma: no cover".
4
+ They involve TclErrors that either should or should not happen in a
5
+ particular situation, and which are 'pass'ed if they do.
6
+ """
7
+
1
8
from idlelib .tooltip import TooltipBase , Hovertip
2
9
from test .support import requires
3
10
requires ('gui' )
@@ -12,16 +19,13 @@ def setUpModule():
12
19
global root
13
20
root = Tk ()
14
21
15
- def root_update ():
16
- global root
17
- root .update ()
18
-
19
22
def tearDownModule ():
20
23
global root
21
24
root .update_idletasks ()
22
25
root .destroy ()
23
26
del root
24
27
28
+
25
29
def add_call_counting (func ):
26
30
@wraps (func )
27
31
def wrapped_func (* args , ** kwargs ):
@@ -65,82 +69,93 @@ class HovertipTest(unittest.TestCase):
65
69
def setUp (self ):
66
70
self .top , self .button = _make_top_and_button (self )
67
71
72
+ def is_tipwindow_shown (self , tooltip ):
73
+ return tooltip .tipwindow and tooltip .tipwindow .winfo_viewable ()
74
+
68
75
def test_showtip (self ):
69
76
tooltip = Hovertip (self .button , 'ToolTip text' )
70
77
self .addCleanup (tooltip .hidetip )
71
- self .assertFalse (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
78
+ self .assertFalse (self . is_tipwindow_shown ( tooltip ))
72
79
tooltip .showtip ()
73
- self .assertTrue (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
80
+ self .assertTrue (self . is_tipwindow_shown ( tooltip ))
74
81
75
82
def test_showtip_twice (self ):
76
83
tooltip = Hovertip (self .button , 'ToolTip text' )
77
84
self .addCleanup (tooltip .hidetip )
78
- self .assertFalse (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
85
+ self .assertFalse (self . is_tipwindow_shown ( tooltip ))
79
86
tooltip .showtip ()
80
- self .assertTrue (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
87
+ self .assertTrue (self . is_tipwindow_shown ( tooltip ))
81
88
orig_tipwindow = tooltip .tipwindow
82
89
tooltip .showtip ()
83
- self .assertTrue (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
90
+ self .assertTrue (self . is_tipwindow_shown ( tooltip ))
84
91
self .assertIs (tooltip .tipwindow , orig_tipwindow )
85
92
86
93
def test_hidetip (self ):
87
94
tooltip = Hovertip (self .button , 'ToolTip text' )
88
95
self .addCleanup (tooltip .hidetip )
89
96
tooltip .showtip ()
90
97
tooltip .hidetip ()
91
- self .assertFalse (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
98
+ self .assertFalse (self . is_tipwindow_shown ( tooltip ))
92
99
93
100
def test_showtip_on_mouse_enter_no_delay (self ):
94
101
tooltip = Hovertip (self .button , 'ToolTip text' , hover_delay = None )
95
102
self .addCleanup (tooltip .hidetip )
96
103
tooltip .showtip = add_call_counting (tooltip .showtip )
97
- root_update ()
98
- self .assertFalse (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
104
+ root . update ()
105
+ self .assertFalse (self . is_tipwindow_shown ( tooltip ))
99
106
self .button .event_generate ('<Enter>' , x = 0 , y = 0 )
100
- root_update ()
101
- self .assertTrue (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
107
+ root . update ()
108
+ self .assertTrue (self . is_tipwindow_shown ( tooltip ))
102
109
self .assertGreater (len (tooltip .showtip .call_args_list ), 0 )
103
110
104
- def test_showtip_on_mouse_enter_hover_delay (self ):
105
- tooltip = Hovertip (self .button , 'ToolTip text' , hover_delay = 50 )
106
- self .addCleanup (tooltip .hidetip )
107
- tooltip .showtip = add_call_counting (tooltip .showtip )
108
- root_update ()
109
- self .assertFalse (tooltip .tipwindow and tooltip .tipwindow .winfo_viewable ())
111
+ def test_hover_with_delay (self ):
112
+ # Run multiple tests requiring an actual delay simultaneously.
113
+
114
+ # Test #1: A hover tip with a non-zero delay appears after the delay.
115
+ tooltip1 = Hovertip (self .button , 'ToolTip text' , hover_delay = 100 )
116
+ self .addCleanup (tooltip1 .hidetip )
117
+ tooltip1 .showtip = add_call_counting (tooltip1 .showtip )
118
+ root .update ()
119
+ self .assertFalse (self .is_tipwindow_shown (tooltip1 ))
110
120
self .button .event_generate ('<Enter>' , x = 0 , y = 0 )
111
- root_update ()
112
- self .assertFalse (tooltip .tipwindow and tooltip .tipwindow .winfo_viewable ())
113
- time .sleep (0.1 )
114
- root_update ()
115
- self .assertTrue (tooltip .tipwindow and tooltip .tipwindow .winfo_viewable ())
116
- self .assertGreater (len (tooltip .showtip .call_args_list ), 0 )
121
+ root .update ()
122
+ self .assertFalse (self .is_tipwindow_shown (tooltip1 ))
123
+
124
+ # Test #2: A hover tip with a non-zero delay doesn't appear when
125
+ # the mouse stops hovering over the base widget before the delay
126
+ # expires.
127
+ tooltip2 = Hovertip (self .button , 'ToolTip text' , hover_delay = 100 )
128
+ self .addCleanup (tooltip2 .hidetip )
129
+ tooltip2 .showtip = add_call_counting (tooltip2 .showtip )
130
+ root .update ()
131
+ self .button .event_generate ('<Enter>' , x = 0 , y = 0 )
132
+ root .update ()
133
+ self .button .event_generate ('<Leave>' , x = 0 , y = 0 )
134
+ root .update ()
135
+
136
+ time .sleep (0.15 )
137
+ root .update ()
138
+
139
+ # Test #1 assertions.
140
+ self .assertTrue (self .is_tipwindow_shown (tooltip1 ))
141
+ self .assertGreater (len (tooltip1 .showtip .call_args_list ), 0 )
142
+
143
+ # Test #2 assertions.
144
+ self .assertFalse (self .is_tipwindow_shown (tooltip2 ))
145
+ self .assertEqual (tooltip2 .showtip .call_args_list , [])
117
146
118
147
def test_hidetip_on_mouse_leave (self ):
119
148
tooltip = Hovertip (self .button , 'ToolTip text' , hover_delay = None )
120
149
self .addCleanup (tooltip .hidetip )
121
150
tooltip .showtip = add_call_counting (tooltip .showtip )
122
- root_update ()
151
+ root . update ()
123
152
self .button .event_generate ('<Enter>' , x = 0 , y = 0 )
124
- root_update ()
153
+ root . update ()
125
154
self .button .event_generate ('<Leave>' , x = 0 , y = 0 )
126
- root_update ()
127
- self .assertFalse (tooltip . tipwindow and tooltip . tipwindow . winfo_viewable ( ))
155
+ root . update ()
156
+ self .assertFalse (self . is_tipwindow_shown ( tooltip ))
128
157
self .assertGreater (len (tooltip .showtip .call_args_list ), 0 )
129
158
130
- def test_dont_show_on_mouse_leave_before_delay (self ):
131
- tooltip = Hovertip (self .button , 'ToolTip text' , hover_delay = 50 )
132
- self .addCleanup (tooltip .hidetip )
133
- tooltip .showtip = add_call_counting (tooltip .showtip )
134
- root_update ()
135
- self .button .event_generate ('<Enter>' , x = 0 , y = 0 )
136
- root_update ()
137
- self .button .event_generate ('<Leave>' , x = 0 , y = 0 )
138
- root_update ()
139
- time .sleep (0.1 )
140
- root_update ()
141
- self .assertFalse (tooltip .tipwindow and tooltip .tipwindow .winfo_viewable ())
142
- self .assertEqual (tooltip .showtip .call_args_list , [])
143
-
144
159
145
160
if __name__ == '__main__' :
146
161
unittest .main (verbosity = 2 )
0 commit comments