58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
"""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)
|