2323import pytest
2424
2525from ardupilot_methodic_configurator .frontend_tkinter_show import (
26- TOOLTIP_HIDE_DELAY_MS ,
2726 TOOLTIP_SHOW_DELAY_MS ,
2827 MonitorBounds ,
2928 Tooltip ,
@@ -747,19 +746,15 @@ def test_tooltip_initialization_non_macos(self, mock_widget: MagicMock, mock_top
747746 with (
748747 patch ("ardupilot_methodic_configurator.frontend_tkinter_show.platform_system" , return_value = "Linux" ),
749748 patch ("tkinter.Toplevel" , return_value = mock_toplevel ),
750- patch ("tkinter.ttk.Label" ) as mock_label ,
749+ patch ("tkinter.ttk.Label" ),
751750 ):
752751 tooltip = Tooltip (mock_widget , "Test text" )
753752
754- # Check that Toplevel was created
755- assert tooltip .tooltip == mock_toplevel
753+ # Check that Toplevel was NOT created yet (Lazy Loading)
754+ assert tooltip .tooltip is None
756755 # Check bindings
757- mock_widget .bind .assert_any_call ("<Enter>" , tooltip .show , "+" )
758- mock_widget .bind .assert_any_call ("<Leave>" , tooltip .hide , "+" )
759- # Check tooltip setup
760- mock_toplevel .wm_overrideredirect .assert_called_with (boolean = True )
761- mock_label .assert_called_once ()
762- mock_toplevel .withdraw .assert_called_once ()
756+ mock_widget .bind .assert_any_call ("<Enter>" , tooltip .schedule_show , "+" )
757+ mock_widget .bind .assert_any_call ("<Leave>" , tooltip .destroy_hide , "+" )
763758
764759 def test_tooltip_initialization_macos (self , mock_widget : MagicMock ) -> None :
765760 """
@@ -822,10 +817,10 @@ def test_tooltip_position_tooltip(self, mock_widget, mock_toplevel) -> None:
822817 ),
823818 ):
824819 tooltip = Tooltip (mock_widget , "Test text" )
820+ mock_widget .winfo_containing .return_value = mock_widget # Tell the test the mouse is hovering
821+ tooltip .create_show ()
825822
826- tooltip .position_tooltip ()
827-
828- # Check that geometry was set
823+ # Check that geometry was set (create_show did this automatically!)
829824 mock_toplevel .geometry .assert_called_once ()
830825 # The call should be with calculated position
831826 call_args = mock_toplevel .geometry .call_args [0 ][0 ]
@@ -844,9 +839,10 @@ def test_tooltip_show_non_macos(self, mock_widget, mock_toplevel) -> None:
844839 patch ("tkinter.ttk.Label" ),
845840 patch ("ardupilot_methodic_configurator.frontend_tkinter_show.platform_system" , return_value = "Linux" ),
846841 ):
842+ mock_widget .winfo_containing .return_value = mock_widget
847843 tooltip = Tooltip (mock_widget , "Test text" )
848844
849- tooltip .show ()
845+ tooltip .create_show ()
850846
851847 mock_toplevel .deiconify .assert_called_once ()
852848
@@ -864,10 +860,12 @@ def test_tooltip_hide(self, mock_widget, mock_toplevel) -> None:
864860 patch ("ardupilot_methodic_configurator.frontend_tkinter_show.platform_system" , return_value = "Linux" ),
865861 ):
866862 tooltip = Tooltip (mock_widget , "Test text" )
863+ tooltip .tooltip = mock_toplevel # Mock that it was created
864+ tooltip .destroy_hide ()
867865
868- tooltip . hide ()
869-
870- mock_widget . after . assert_called_once_with ( TOOLTIP_HIDE_DELAY_MS , tooltip . _do_hide )
866+ # As it destroys immediately, check if active_tooltip is cleared
867+ assert Tooltip . _active_tooltip is None
868+ mock_toplevel . destroy . assert_called_once ( )
871869
872870 def test_tooltip_cancel_hide (self , mock_widget ) -> None :
873871 """
@@ -990,24 +988,27 @@ def test_tooltip_no_position_when_tooltip_none(self, mock_widget) -> None:
990988
991989 # Assert: No exception, no positioning attempted
992990
993- def test_tooltip_do_hide_withdraws_on_non_macos (self , mock_widget , mock_toplevel ) -> None :
991+ def test_tooltip_force_hide_destroys_globally (self , mock_widget , mock_toplevel ) -> None :
994992 """
995- Test tooltip _do_hide withdraws tooltip on non-macOS .
993+ Test tooltip force_hide destroys the tooltip globally across all OSs and clears the active tooltip .
996994
997- GIVEN: Tooltip on non-macOS platform
998- WHEN: _do_hide is called
999- THEN: Tooltip is withdrawn
995+ GIVEN: Tooltip on any platform
996+ WHEN: force_hide is called
997+ THEN: Tooltip is destroyed and active tooltip is cleared
1000998 """
1001999 with (
10021000 patch ("tkinter.Toplevel" , return_value = mock_toplevel ),
10031001 patch ("tkinter.ttk.Label" ),
10041002 patch ("ardupilot_methodic_configurator.frontend_tkinter_show.platform_system" , return_value = "Linux" ),
10051003 ):
1004+ mock_widget .winfo_containing .return_value = mock_widget
10061005 tooltip = Tooltip (mock_widget , "Test text" )
1006+ tooltip .create_show () # Must create it before we can destroy it
10071007
1008- tooltip ._do_hide ()
1008+ tooltip .force_hide ()
10091009
1010- mock_toplevel .withdraw .assert_called ()
1010+ mock_toplevel .destroy .assert_called_once ()
1011+ assert tooltip .tooltip is None
10111012
10121013 def test_tooltip_create_show_avoids_redundant_creation (self , mock_widget , mock_toplevel ) -> None :
10131014 """
@@ -1067,10 +1068,13 @@ def test_tooltip_with_custom_toplevel_class(self, mock_widget, mock_toplevel) ->
10671068 patch ("ardupilot_methodic_configurator.frontend_tkinter_show.platform_system" , return_value = "Linux" ),
10681069 patch ("tkinter.ttk.Label" ),
10691070 ):
1071+ mock_widget .winfo_containing .return_value = mock_widget
10701072 tooltip = Tooltip (mock_widget , "Test text" , toplevel_class = custom_toplevel_class )
10711073
1074+ tooltip .create_show () # Trigger lazy load
1075+
10721076 # Assert: Custom class was used
1073- custom_toplevel_class .assert_called_once_with (mock_widget )
1077+ custom_toplevel_class .assert_called_once_with (mock_widget , bg = "#ffffe0" )
10741078 assert tooltip .tooltip == mock_toplevel
10751079
10761080 def test_tooltip_position_below_false (self , mock_widget , mock_toplevel ) -> None :
@@ -1091,9 +1095,10 @@ def test_tooltip_position_below_false(self, mock_widget, mock_toplevel) -> None:
10911095 ),
10921096 ):
10931097 tooltip = Tooltip (mock_widget , "Test text" , position_below = False )
1094- tooltip .position_tooltip ()
1098+ mock_widget .winfo_containing .return_value = mock_widget # Tell the test the mouse is hovering
1099+ tooltip .create_show ()
10951100
1096- # Assert: Geometry set (indicates positioning occurred)
1101+ # Assert: Geometry set
10971102 mock_toplevel .geometry .assert_called_once ()
10981103
10991104 def test_tooltip_create_show_uses_macos_styling (self , mock_widget , mock_toplevel ) -> None :
0 commit comments