"""Tests des festen Zeitschritts (Akkumulator).""" import pytest from sandbox.physics import FixedTimestep STEP = 1 / 120 def test_a_60_fps_frame_runs_two_physics_steps() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=8) assert timestep.advance(1 / 60) == 2 assert timestep.alpha == pytest.approx(0, abs=1e-6) def test_short_frames_accumulate() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=8) assert timestep.advance(1 / 240) == 0 assert timestep.alpha == pytest.approx(0.5) assert timestep.advance(1 / 240) == 1 def test_no_steps_are_lost_through_rounding() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=8) total = sum(timestep.advance(1 / 60) for _ in range(1000)) assert total == 2000 def test_alpha_stays_in_the_unit_interval() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=8) for frame in (0.003, 0.011, 0.017, 0.0001, 0.02): timestep.advance(frame) assert 0 <= timestep.alpha < 1 def test_huge_frames_are_capped_to_avoid_the_spiral_of_death() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=5) assert timestep.advance(2.0) == 5 assert timestep.alpha == 0 # der Rückstand wurde verworfen assert timestep.advance(1 / 60) == 2 def test_reset_discards_accumulated_time() -> None: timestep = FixedTimestep(STEP, max_steps_per_frame=8) timestep.advance(STEP * 0.9) timestep.reset() assert timestep.alpha == 0 assert timestep.advance(STEP * 0.5) == 0 def test_invalid_arguments_are_rejected() -> None: with pytest.raises(ValueError, match="positiv"): FixedTimestep(0, 8) with pytest.raises(ValueError, match="mindestens"): FixedTimestep(STEP, 0) with pytest.raises(ValueError, match="negativ"): FixedTimestep(STEP, 8).advance(-0.1)