@@ -318,27 +318,30 @@ def test_finished_state_displays_banner(self):
318318 self .assertTrue (self .display .contains_text ("PROFILING COMPLETE" ))
319319 self .assertTrue (self .display .contains_text ("Press 'q' to Quit" ))
320320
321- def test_finished_state_ignores_most_input (self ):
322- """Test that finished state only responds to 'q' key ."""
321+ def test_finished_state_allows_ui_controls (self ):
322+ """Test that finished state allows UI controls but prioritizes quit ."""
323323 self .collector .finished = True
324324 self .collector .running = True
325325
326- # Try pressing 's' (sort) - should be ignored
326+ # Try pressing 's' (sort) - should work and trigger display update
327+ original_sort = self .collector .sort_by
327328 self .display .simulate_input (ord ("s" ))
328329 self .collector ._handle_input ()
329330 self .assertTrue (self .collector .running ) # Still running
331+ self .assertNotEqual (self .collector .sort_by , original_sort ) # Sort changed
330332
331- # Try pressing 'p' (pause) - should be ignored
333+ # Try pressing 'p' (pause) - should work
332334 self .display .simulate_input (ord ("p" ))
333335 self .collector ._handle_input ()
334336 self .assertTrue (self .collector .running ) # Still running
335- self .assertFalse (self .collector .paused ) # Not paused
337+ self .assertTrue (self .collector .paused ) # Now paused
336338
337- # Try pressing 'r' (reset) - should be ignored
338- old_total = self .collector .total_samples = 100
339+ # Try pressing 'r' (reset) - should be ignored when finished
340+ self .collector .total_samples = 100
339341 self .display .simulate_input (ord ("r" ))
340342 self .collector ._handle_input ()
341- self .assertEqual (self .collector .total_samples , old_total ) # Not reset
343+ self .assertTrue (self .collector .running ) # Still running
344+ self .assertEqual (self .collector .total_samples , 100 ) # NOT reset when finished
342345
343346 # Press 'q' - should stop
344347 self .display .simulate_input (ord ("q" ))
@@ -365,6 +368,35 @@ def test_finished_state_footer_message(self):
365368 # Check that footer contains finished message
366369 self .assertTrue (self .display .contains_text ("PROFILING FINISHED" ))
367370
371+ def test_finished_state_freezes_time (self ):
372+ """Test that time displays are frozen when finished."""
373+ import time as time_module
374+
375+ # Set up collector with known start time
376+ self .collector .start_time = time_module .perf_counter () - 10.0 # 10 seconds ago
377+
378+ # Mark as finished - this should freeze the time
379+ self .collector .mark_finished ()
380+
381+ # Get the frozen elapsed time
382+ frozen_elapsed = self .collector .elapsed_time
383+ frozen_time_display = self .collector .current_time_display
384+
385+ # Wait a bit to ensure time would advance
386+ time_module .sleep (0.1 )
387+
388+ # Time should remain frozen
389+ self .assertEqual (self .collector .elapsed_time , frozen_elapsed )
390+ self .assertEqual (self .collector .current_time_display , frozen_time_display )
391+
392+ # Verify finish timestamp was set
393+ self .assertIsNotNone (self .collector .finish_timestamp )
394+
395+ # Reset should clear the frozen state
396+ self .collector .reset_stats ()
397+ self .assertFalse (self .collector .finished )
398+ self .assertIsNone (self .collector .finish_timestamp )
399+
368400
369401class TestLiveCollectorFiltering (unittest .TestCase ):
370402 """Tests for filtering functionality."""
@@ -1131,5 +1163,63 @@ def test_function_counts_are_per_thread_in_per_thread_mode(self):
11311163 self .assertEqual (thread_222_funcs , {"func4" , "func5" })
11321164
11331165
1166+ class TestLiveCollectorNewFeatures (unittest .TestCase ):
1167+ """Tests for new features added to live collector."""
1168+
1169+ def setUp (self ):
1170+ """Set up test fixtures."""
1171+ self .display = MockDisplay ()
1172+ self .collector = LiveStatsCollector (1000 , display = self .display )
1173+ self .collector .start_time = time .perf_counter ()
1174+
1175+ def test_filter_input_takes_precedence_over_commands (self ):
1176+ """Test that filter input mode blocks command keys like 'h' and 'p'."""
1177+ # Enter filter input mode
1178+ self .collector .filter_input_mode = True
1179+ self .collector .filter_input_buffer = ""
1180+
1181+ # Press 'h' - should add to filter buffer, not show help
1182+ self .display .simulate_input (ord ("h" ))
1183+ self .collector ._handle_input ()
1184+
1185+ self .assertFalse (self .collector .show_help ) # Help not triggered
1186+ self .assertEqual (self .collector .filter_input_buffer , "h" ) # Added to filter
1187+ self .assertTrue (self .collector .filter_input_mode ) # Still in filter mode
1188+
1189+ def test_reset_blocked_when_finished (self ):
1190+ """Test that reset command is blocked when profiling is finished."""
1191+ # Set up some sample data and mark as finished
1192+ self .collector .total_samples = 100
1193+ self .collector .finished = True
1194+
1195+ # Press 'r' for reset
1196+ self .display .simulate_input (ord ("r" ))
1197+ self .collector ._handle_input ()
1198+
1199+ # Should NOT have been reset
1200+ self .assertEqual (self .collector .total_samples , 100 )
1201+ self .assertTrue (self .collector .finished )
1202+
1203+ def test_time_display_fix_when_finished (self ):
1204+ """Test that time display shows correct frozen time when finished."""
1205+ import time as time_module
1206+
1207+ # Mark as finished to freeze time
1208+ self .collector .mark_finished ()
1209+
1210+ # Should have set both timestamps correctly
1211+ self .assertIsNotNone (self .collector .finish_timestamp )
1212+ self .assertIsNotNone (self .collector .finish_wall_time )
1213+
1214+ # Get the frozen time display
1215+ frozen_time = self .collector .current_time_display
1216+
1217+ # Wait a bit
1218+ time_module .sleep (0.1 )
1219+
1220+ # Should still show the same frozen time (not jump to wrong time)
1221+ self .assertEqual (self .collector .current_time_display , frozen_time )
1222+
1223+
11341224if __name__ == "__main__" :
11351225 unittest .main ()
0 commit comments