mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
a82935f326
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: pharmacomaniac <blittle65@gmail.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
143 lines
5.3 KiB
Python
143 lines
5.3 KiB
Python
import pyray as rl
|
|
import pytest
|
|
|
|
from openpilot.system.ui.lib.application import gui_app
|
|
from openpilot.common.filter_simple import BounceFilter
|
|
from openpilot.system.ui.widgets.nav_widget import NavBar, NavWidget, NAV_BAR_MARGIN, NAV_BAR_HEIGHT
|
|
|
|
|
|
class NavScreen(NavWidget):
|
|
def _render(self, _):
|
|
pass
|
|
|
|
|
|
@pytest.fixture
|
|
def viewport():
|
|
return rl.Rectangle(0, 0, gui_app.width, gui_app.height)
|
|
|
|
|
|
@pytest.fixture
|
|
def screen(monkeypatch, viewport):
|
|
monkeypatch.setattr(rl, "draw_rectangle_rec", lambda *_: None)
|
|
monkeypatch.setattr(rl, "get_time", lambda: 10.0)
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 1 / 60)
|
|
monkeypatch.setattr(gui_app, "_target_fps", 60)
|
|
monkeypatch.setattr(gui_app, "_show_touches", False)
|
|
monkeypatch.setattr(gui_app, "_mouse_events", [])
|
|
screen = NavScreen()
|
|
screen.set_rect(viewport)
|
|
monkeypatch.setattr(screen._nav_bar, "render", lambda: None)
|
|
return screen
|
|
|
|
|
|
@pytest.mark.parametrize("fps", [20, 30, 60])
|
|
def test_show_animation_duration_tracks_elapsed_time(monkeypatch, screen, viewport, fps):
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 1 / fps)
|
|
shown = []
|
|
screen.set_shown_callback(lambda: shown.append(True))
|
|
screen.show_event()
|
|
for _frames in range(1, fps * 3):
|
|
screen.render(viewport)
|
|
if shown:
|
|
break
|
|
|
|
assert shown == [True]
|
|
assert screen._y_pos_filter.x == screen._y_pos_filter.velocity.x == 0
|
|
assert _frames / fps == pytest.approx(35 / 60, abs=1 / fps)
|
|
|
|
|
|
@pytest.mark.parametrize("fps", [20, 30, 60])
|
|
def test_dismiss_animation_duration_tracks_elapsed_time(monkeypatch, screen, viewport, fps):
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 1 / fps)
|
|
popped, dismissed, backed = [], [], []
|
|
monkeypatch.setattr(gui_app, "pop_widget", lambda: popped.append(True))
|
|
screen.set_back_callback(lambda: backed.append(True))
|
|
screen.dismiss(lambda: dismissed.append(True))
|
|
for _frames in range(1, fps * 3):
|
|
screen.render(viewport)
|
|
if popped:
|
|
break
|
|
|
|
assert _frames / fps == pytest.approx(13 / 60, abs=1 / fps)
|
|
assert popped == dismissed == [True]
|
|
assert not backed
|
|
|
|
|
|
def test_show_animation_retains_original_sixty_fps_motion(screen):
|
|
reference = BounceFilter(gui_app.height, 0.1, 1 / 60, bounce=1)
|
|
screen.show_event()
|
|
for _ in range(20):
|
|
reference.update(0.0)
|
|
screen._update_state()
|
|
assert screen._y_pos_filter.x == pytest.approx(reference.x)
|
|
assert screen._y_pos_filter.velocity.x == pytest.approx(reference.velocity.x)
|
|
|
|
|
|
@pytest.mark.parametrize("fps", [20, 30, 60])
|
|
def test_navigation_bar_fade_tracks_elapsed_time(monkeypatch, screen, fps):
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 1 / fps)
|
|
monkeypatch.setattr(rl, "draw_rectangle_rounded", lambda *_: None)
|
|
monkeypatch.setattr(rl, "draw_rectangle_rounded_lines_ex", lambda *_: None)
|
|
bar = NavBar()
|
|
bar.set_alpha(0.0)
|
|
for _ in range(fps // 2):
|
|
bar._render(bar.rect)
|
|
assert bar._alpha_filter.x == pytest.approx((1 - bar._alpha_filter.alpha) ** 30)
|
|
|
|
|
|
@pytest.mark.parametrize("fps", [20, 30, 60])
|
|
def test_navigation_bar_slide_tracks_elapsed_time(monkeypatch, screen, viewport, fps):
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 1 / fps)
|
|
screen._nav_bar_y_filter.x = -NAV_BAR_MARGIN - NAV_BAR_HEIGHT
|
|
for _ in range(fps // 2):
|
|
screen.render(viewport)
|
|
remaining = (1 - screen._nav_bar_y_filter.alpha) ** 30
|
|
assert screen._nav_bar_y_filter.x == pytest.approx(NAV_BAR_MARGIN - (2 * NAV_BAR_MARGIN + NAV_BAR_HEIGHT) * remaining)
|
|
|
|
|
|
def test_long_frame_uses_bounded_spring_steps(monkeypatch, screen):
|
|
screen.show_event()
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 0.1)
|
|
screen._update_state()
|
|
expected = screen._y_pos_filter.x, screen._y_pos_filter.velocity.x
|
|
|
|
screen.show_event()
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: 5.0)
|
|
screen._update_state()
|
|
assert (screen._y_pos_filter.x, screen._y_pos_filter.velocity.x) == pytest.approx(expected)
|
|
|
|
|
|
@pytest.mark.parametrize("elapsed", [0.0, -1.0, float("nan"), float("inf")])
|
|
def test_invalid_frame_duration_uses_default_step(monkeypatch, screen, elapsed):
|
|
screen.show_event()
|
|
screen._update_state()
|
|
expected = screen._y_pos_filter.x, screen._y_pos_filter.velocity.x
|
|
|
|
screen.show_event()
|
|
monkeypatch.setattr(rl, "get_frame_time", lambda: elapsed)
|
|
screen._update_state()
|
|
assert (screen._y_pos_filter.x, screen._y_pos_filter.velocity.x) == pytest.approx(expected)
|
|
|
|
|
|
@pytest.mark.parametrize("gesture_end", ["release", "horizontal_cancel"])
|
|
def test_drag_reveal_does_not_rehide_during_initial_delay(monkeypatch, screen, viewport, gesture_end):
|
|
from openpilot.system.ui.lib.application import MousePos, MouseEvent
|
|
now = [10.0]
|
|
monkeypatch.setattr(rl, "get_time", lambda: now[0])
|
|
screen.show_event()
|
|
start = MousePos(100, 20)
|
|
screen._handle_mouse_event(MouseEvent(start, 0, True, False, True, now[0]))
|
|
screen.render(viewport)
|
|
assert screen._nav_bar_y_filter.x > 0
|
|
now[0] += 0.05
|
|
if gesture_end == "release":
|
|
screen._handle_mouse_event(MouseEvent(start, 0, False, True, False, now[0]))
|
|
else:
|
|
screen._handle_mouse_event(MouseEvent(MousePos(180, 20), 0, False, False, True, now[0]))
|
|
assert screen._drag_start_pos is None
|
|
screen.render(viewport)
|
|
assert screen._nav_bar_y_filter.x >= NAV_BAR_MARGIN
|
|
screen.show_event()
|
|
screen.render(viewport)
|
|
assert screen._nav_bar_y_filter.x == -NAV_BAR_MARGIN - NAV_BAR_HEIGHT
|