import sys import os import time # Ensure project root is in path sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))) from performance_monitor import PerformanceMonitor def test_perf_monitor_basic_timing() -> None: pm = PerformanceMonitor() pm.start_frame() time.sleep(0.02) # 20ms pm.end_frame() metrics = pm.get_metrics() assert metrics['last_frame_time_ms'] >= 20.0 pm.stop() def test_perf_monitor_component_timing() -> None: pm = PerformanceMonitor() pm.enabled = True pm.start_component("test_comp") time.sleep(0.01) pm.end_component("test_comp") metrics = pm.get_metrics() assert metrics['time_test_comp_ms'] >= 10.0 pm.stop() def test_perf_monitor_scope_context_manager() -> None: pm = PerformanceMonitor() pm.enabled = True # Test normal usage with pm.scope("test_scope"): time.sleep(0.01) metrics = pm.get_metrics() assert metrics['time_test_scope_ms'] >= 10.0 # Test exception handling try: with pm.scope("test_error"): time.sleep(0.01) raise ValueError("test error") except ValueError: pass metrics = pm.get_metrics() # Component should still be finished, so timing should be recorded assert metrics['time_test_error_ms'] >= 10.0 pm.stop() def test_perf_monitor_extended_metrics() -> None: pm = PerformanceMonitor() pm.enabled = True # 1st call: 10ms pm.start_component("test_comp") time.sleep(0.01) pm.end_component("test_comp") # 2nd call: 30ms pm.start_component("test_comp") time.sleep(0.03) pm.end_component("test_comp") # 3rd call: 20ms pm.start_component("test_comp") time.sleep(0.02) pm.end_component("test_comp") metrics = pm.get_metrics() assert metrics['count_test_comp'] == 3.0 assert metrics['max_test_comp_ms'] >= 30.0 assert metrics['min_test_comp_ms'] >= 10.0 assert metrics['min_test_comp_ms'] < 20.0 pm.stop()