63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""Tests for time-windowed MetricHistory (force plot buffer)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from orisys_app_shared.force.history import MetricHistory
|
|
|
|
|
|
def _push_at_rate(hist: MetricHistory, *, fps: float, duration_sec: float, t0: float = 1000.0) -> None:
|
|
dt = 1.0 / fps
|
|
n = int(round(duration_sec * fps)) + 1
|
|
for i in range(n):
|
|
hist.push(t0 + i * dt, 1.0, 0.0, -1.0)
|
|
|
|
|
|
def test_fill_phase_x_range_is_fixed_window():
|
|
hist = MetricHistory(window_sec=4.0, sample_rate_hz=30.0, lowpass_cutoff_hz=0.0, max_fps=90.0)
|
|
_push_at_rate(hist, fps=30.0, duration_sec=2.0)
|
|
state = hist.state()
|
|
assert state is not None
|
|
assert state.x_range == pytest.approx((0.0, 4.0))
|
|
assert float(state.times[-1]) < 4.0
|
|
|
|
|
|
def test_high_fps_after_scroll_covers_x_range():
|
|
window = 4.0
|
|
hist = MetricHistory(window_sec=window, sample_rate_hz=30.0, lowpass_cutoff_hz=0.0, max_fps=90.0)
|
|
_push_at_rate(hist, fps=60.0, duration_sec=window + 1.0)
|
|
state = hist.state()
|
|
assert state is not None
|
|
x0, x1 = state.x_range
|
|
assert x1 - x0 == pytest.approx(window)
|
|
assert float(state.times[0]) == pytest.approx(x0)
|
|
assert float(state.times[-1]) == pytest.approx(x1)
|
|
|
|
|
|
def test_nominal_30hz_after_scroll_covers_x_range():
|
|
window = 4.0
|
|
hist = MetricHistory(window_sec=window, sample_rate_hz=30.0, lowpass_cutoff_hz=0.0, max_fps=90.0)
|
|
_push_at_rate(hist, fps=30.0, duration_sec=window + 2.0)
|
|
state = hist.state()
|
|
assert state is not None
|
|
x0, x1 = state.x_range
|
|
assert x1 - x0 == pytest.approx(window)
|
|
assert float(state.times[0]) == pytest.approx(x0)
|
|
|
|
|
|
def test_set_window_sec_prunes_older_samples():
|
|
hist = MetricHistory(window_sec=4.0, sample_rate_hz=30.0, lowpass_cutoff_hz=0.0, max_fps=90.0)
|
|
_push_at_rate(hist, fps=30.0, duration_sec=5.0)
|
|
before = hist.state()
|
|
assert before is not None
|
|
assert float(before.times[-1]) >= 4.0
|
|
|
|
hist.set_window_sec(1.0)
|
|
after = hist.state()
|
|
assert after is not None
|
|
assert after.x_range[1] - after.x_range[0] == pytest.approx(1.0)
|
|
assert float(after.times[0]) == pytest.approx(after.x_range[0])
|
|
# All retained samples must lie within the new window ending at t_end.
|
|
t_end = float(after.times[-1])
|
|
assert float(after.times[0]) >= t_end - 1.0 - 1e-9
|