@@ -628,66 +628,54 @@ def _impl_test_interactive_timers():
628628import matplotlib .pyplot as plt
629629
630630fig = plt .figure ()
631- event_loop_time = 0.5 # in seconds
631+ event_loop_time = 1 # in seconds
632+ expected_200ms_calls = int (event_loop_time / 0.2 )
632633
633- # A timer with <1 millisecond gets converted to int and therefore 0
634- # milliseconds, which the mac framework interprets as singleshot.
635- # We only want singleshot if we specify that ourselves, otherwise we want
636- # a repeating timer
637- timer_repeating = fig .canvas .new_timer (0.1 )
634+ # Start at 2s interval (would only get one firing), then update to 200ms
635+ timer_repeating = fig .canvas .new_timer (2000 )
638636mock_repeating = Mock ()
639637timer_repeating .add_callback (mock_repeating )
640638
641639timer_single_shot = fig .canvas .new_timer (100 )
642640mock_single_shot = Mock ()
643641timer_single_shot .add_callback (mock_single_shot )
644642
645- # 100ms timer triggers and the callback takes 75ms to run
646- # Test that we don't drift and that we get called on every 100ms
647- # interval and not every 175ms
648- mock_slow_callback = Mock ()
649- mock_slow_callback .side_effect = lambda :time .sleep (0.075 )
650- timer_slow_callback = fig .canvas .new_timer (100 )
651- timer_slow_callback .add_callback (mock_slow_callback )
652-
653643timer_repeating .start ()
644+ # Test updating the interval updates a running timer
645+ timer_repeating .interval = 200
654646# Start as a repeating timer then change to singleshot via the attribute
655647timer_single_shot .start ()
656648timer_single_shot .single_shot = True
657- timer_slow_callback . start ()
649+
658650fig .canvas .start_event_loop (event_loop_time )
659- # NOTE: The timer is as fast as possible, but this is different between backends
660- # so we can't assert on the exact number but it should be faster than 100ms
661- expected_100ms_calls = int (event_loop_time / 0.1 )
662- assert mock_repeating .call_count > expected_100ms_calls , \
663- f"Expected more than{ expected_100ms_calls } calls, " \
651+ assert 1 < mock_repeating .call_count <= expected_200ms_calls + 1 , \
652+ f"Interval update: Expected between 2 and{ expected_200ms_calls + 1 } calls, " \
664653f"got{ mock_repeating .call_count } "
665654assert mock_single_shot .call_count == 1 , \
666- f"Expected 1 call, got{ mock_single_shot .call_count } "
667- assert mock_slow_callback .call_count >= expected_100ms_calls - 1 , \
668- f"Expected at least{ expected_100ms_calls - 1 } calls, " \
669- f"got{ mock_slow_callback .call_count } "
655+ f"Singleshot: Expected 1 call, got{ mock_single_shot .call_count } "
670656
671- # Test updating the interval updates a running timer
672- timer_repeating .interval = 100
657+ # 200ms timer triggers and the callback takes 100ms to run
658+ # Test that we don't drift and that we get called on every 200ms
659+ # interval and not every 300ms
660+ mock_repeating .side_effect = lambda :time .sleep (0.1 )
673661mock_repeating .call_count = 0
674662# Make sure we can start the timer after stopping a singleshot timer
675663timer_single_shot .stop ()
676664timer_single_shot .start ()
677665
678666fig .canvas .start_event_loop (event_loop_time )
679- assert 1 < mock_repeating .call_count <= expected_100ms_calls + 1 , \
680- f"Expected less than{ expected_100ms_calls + 1 } calls, " \
681- "got {mock.call_count}"
667+ # Not exact timers, so add a little slop. We really want to make sure we are
668+ # getting more than 3 (every 300ms).
669+ assert mock_repeating .call_count >= expected_200ms_calls - 1 , \
670+ f"Slow callback: Expected at least{ expected_200ms_calls - 1 } calls, " \
671+ f"got{ mock_repeating .call_count } "
682672assert mock_single_shot .call_count == 2 , \
683- f"Expected 2 calls, got{ mock_single_shot .call_count } "
673+ f"Singleshot: Expected 2 calls, got{ mock_single_shot .call_count } "
684674plt .close ("all" )
685675
686676
687677@pytest .mark .parametrize ("env" ,_get_testable_interactive_backends ())
688678def test_interactive_timers (env ):
689- if env ["MPLBACKEND" ]== "gtk3cairo" and os .getenv ("CI" ):
690- pytest .skip ("gtk3cairo timers do not work in remote CI" )
691679if env ["MPLBACKEND" ]== "wx" :
692680pytest .skip ("wx backend is deprecated; tests failed on appveyor" )
693681_run_helper (_impl_test_interactive_timers ,