""" Unit tests for corelibs.debug_handling.timer module """ import time from datetime import datetime, timedelta from corelibs.debug_handling.timer import Timer class TestTimerInitialization: """Test Timer class initialization""" def test_timer_initialization(self): """Test that Timer initializes with correct default values""" timer = Timer() # Check that start times are set assert isinstance(timer.get_overall_start_time(), datetime) assert isinstance(timer.get_start_time(), datetime) # Check that end times are None assert timer.get_overall_end_time() is None assert timer.get_end_time() is None # Check that run times are None assert timer.get_overall_run_time() is None assert timer.get_run_time() is None def test_timer_start_times_are_recent(self): """Test that start times are set to current time on initialization""" before_init = datetime.now() timer = Timer() after_init = datetime.now() overall_start = timer.get_overall_start_time() start = timer.get_start_time() assert before_init <= overall_start <= after_init assert before_init <= start <= after_init def test_timer_start_times_are_same(self): """Test that overall_start_time and start_time are initialized to the same time""" timer = Timer() overall_start = timer.get_overall_start_time() start = timer.get_start_time() # They should be very close (within a few microseconds) time_diff = abs((overall_start - start).total_seconds()) assert time_diff < 0.001 # Less than 1 millisecond class TestOverallRunTime: """Test overall run time functionality""" def test_overall_run_time_returns_timedelta(self): """Test that overall_run_time returns a timedelta object""" timer = Timer() time.sleep(0.01) # Sleep for 10ms result = timer.overall_run_time() assert isinstance(result, timedelta) def test_overall_run_time_sets_end_time(self): """Test that calling overall_run_time sets the end time""" timer = Timer() assert timer.get_overall_end_time() is None timer.overall_run_time() assert isinstance(timer.get_overall_end_time(), datetime) def test_overall_run_time_sets_run_time(self): """Test that calling overall_run_time sets the run time""" timer = Timer() assert timer.get_overall_run_time() is None timer.overall_run_time() assert isinstance(timer.get_overall_run_time(), timedelta) def test_overall_run_time_accuracy(self): """Test that overall_run_time calculates time difference accurately""" timer = Timer() sleep_duration = 0.05 # 50ms time.sleep(sleep_duration) result = timer.overall_run_time() # Allow for some variance (10ms tolerance) assert sleep_duration - 0.01 <= result.total_seconds() <= sleep_duration + 0.01 def test_overall_run_time_multiple_calls(self): """Test that calling overall_run_time multiple times updates the values""" timer = Timer() time.sleep(0.01) first_result = timer.overall_run_time() first_end_time = timer.get_overall_end_time() time.sleep(0.01) second_result = timer.overall_run_time() second_end_time = timer.get_overall_end_time() # Second call should have longer runtime assert second_result > first_result assert second_end_time is not None assert first_end_time is not None # End time should be updated assert second_end_time > first_end_time def test_overall_run_time_consistency(self): """Test that get_overall_run_time returns the same value as overall_run_time""" timer = Timer() time.sleep(0.01) calculated_time = timer.overall_run_time() retrieved_time = timer.get_overall_run_time() assert calculated_time == retrieved_time class TestRunTime: """Test run time functionality""" def test_run_time_returns_timedelta(self): """Test that run_time returns a timedelta object""" timer = Timer() time.sleep(0.01) result = timer.run_time() assert isinstance(result, timedelta) def test_run_time_sets_end_time(self): """Test that calling run_time sets the end time""" timer = Timer() assert timer.get_end_time() is None timer.run_time() assert isinstance(timer.get_end_time(), datetime) def test_run_time_sets_run_time(self): """Test that calling run_time sets the run time""" timer = Timer() assert timer.get_run_time() is None timer.run_time() assert isinstance(timer.get_run_time(), timedelta) def test_run_time_accuracy(self): """Test that run_time calculates time difference accurately""" timer = Timer() sleep_duration = 0.05 # 50ms time.sleep(sleep_duration) result = timer.run_time() # Allow for some variance (10ms tolerance) assert sleep_duration - 0.01 <= result.total_seconds() <= sleep_duration + 0.01 def test_run_time_multiple_calls(self): """Test that calling run_time multiple times updates the values""" timer = Timer() time.sleep(0.01) first_result = timer.run_time() first_end_time = timer.get_end_time() time.sleep(0.01) second_result = timer.run_time() second_end_time = timer.get_end_time() # Second call should have longer runtime assert second_result > first_result assert second_end_time is not None assert first_end_time is not None # End time should be updated assert second_end_time > first_end_time def test_run_time_consistency(self): """Test that get_run_time returns the same value as run_time""" timer = Timer() time.sleep(0.01) calculated_time = timer.run_time() retrieved_time = timer.get_run_time() assert calculated_time == retrieved_time class TestResetRunTime: """Test reset_run_time functionality""" def test_reset_run_time_resets_start_time(self): """Test that reset_run_time updates the start time""" timer = Timer() original_start = timer.get_start_time() time.sleep(0.02) timer.reset_run_time() new_start = timer.get_start_time() assert new_start > original_start def test_reset_run_time_clears_end_time(self): """Test that reset_run_time clears the end time""" timer = Timer() timer.run_time() assert timer.get_end_time() is not None timer.reset_run_time() assert timer.get_end_time() is None def test_reset_run_time_clears_run_time(self): """Test that reset_run_time clears the run time""" timer = Timer() timer.run_time() assert timer.get_run_time() is not None timer.reset_run_time() assert timer.get_run_time() is None def test_reset_run_time_does_not_affect_overall_times(self): """Test that reset_run_time does not affect overall times""" timer = Timer() overall_start = timer.get_overall_start_time() timer.overall_run_time() overall_end = timer.get_overall_end_time() overall_run = timer.get_overall_run_time() timer.reset_run_time() # Overall times should remain unchanged assert timer.get_overall_start_time() == overall_start assert timer.get_overall_end_time() == overall_end assert timer.get_overall_run_time() == overall_run def test_reset_run_time_allows_new_measurement(self): """Test that reset_run_time allows for new time measurements""" timer = Timer() time.sleep(0.02) timer.run_time() first_run_time = timer.get_run_time() timer.reset_run_time() time.sleep(0.01) timer.run_time() second_run_time = timer.get_run_time() assert second_run_time is not None assert first_run_time is not None # Second measurement should be shorter since we reset assert second_run_time < first_run_time class TestTimerIntegration: """Integration tests for Timer class""" def test_independent_timers(self): """Test that multiple Timer instances are independent""" timer1 = Timer() time.sleep(0.01) timer2 = Timer() # timer1 should have earlier start time assert timer1.get_start_time() < timer2.get_start_time() assert timer1.get_overall_start_time() < timer2.get_overall_start_time() def test_overall_and_run_time_independence(self): """Test that overall time and run time are independent""" timer = Timer() time.sleep(0.02) # Reset run time but not overall timer.reset_run_time() time.sleep(0.01) run_time = timer.run_time() overall_time = timer.overall_run_time() # Overall time should be longer than run time assert overall_time > run_time def test_typical_usage_pattern(self): """Test a typical usage pattern of the Timer class""" timer = Timer() # Measure first operation time.sleep(0.01) first_operation = timer.run_time() assert first_operation.total_seconds() > 0 # Reset and measure second operation timer.reset_run_time() time.sleep(0.01) second_operation = timer.run_time() assert second_operation.total_seconds() > 0 # Get overall time overall = timer.overall_run_time() # Overall should be greater than individual operations assert overall > first_operation assert overall > second_operation def test_zero_sleep_timer(self): """Test timer with minimal sleep (edge case)""" timer = Timer() # Call run_time immediately result = timer.run_time() # Should still return a valid timedelta (very small) assert isinstance(result, timedelta) assert result.total_seconds() >= 0 def test_getter_methods_before_calculation(self): """Test that getter methods return None before calculation methods are called""" timer = Timer() # Before calling run_time() assert timer.get_end_time() is None assert timer.get_run_time() is None # Before calling overall_run_time() assert timer.get_overall_end_time() is None assert timer.get_overall_run_time() is None # But start times should always be set assert timer.get_start_time() is not None assert timer.get_overall_start_time() is not None class TestTimerEdgeCases: """Test edge cases and boundary conditions""" def test_rapid_consecutive_calls(self): """Test rapid consecutive calls to run_time""" timer = Timer() results: list[timedelta] = [] for _ in range(5): results.append(timer.run_time()) # Each result should be greater than or equal to the previous for i in range(1, len(results)): assert results[i] >= results[i - 1] def test_very_short_duration(self): """Test timer with very short duration""" timer = Timer() result = timer.run_time() # Should be a very small positive timedelta assert isinstance(result, timedelta) assert result.total_seconds() >= 0 assert result.total_seconds() < 0.1 # Less than 100ms def test_reset_multiple_times(self): """Test resetting the timer multiple times""" timer = Timer() for _ in range(3): timer.reset_run_time() time.sleep(0.01) result = timer.run_time() assert isinstance(result, timedelta) assert result.total_seconds() > 0 def test_overall_time_persists_through_resets(self): """Test that overall time continues even when run_time is reset""" timer = Timer() time.sleep(0.01) timer.reset_run_time() time.sleep(0.01) timer.reset_run_time() overall = timer.overall_run_time() # Overall time should reflect total elapsed time assert overall.total_seconds() >= 0.02 # __END__