# pyright: reportGeneralTypeIssues=false from collections.abc import Generator import dearpygui.dearpygui as dpg import pytest import dpg_gauges as dpgg from dpg_gauges.animation import advance_animation from dpg_gauges.state import clear_registry, get_gauge_state, set_runtime_value from dpg_gauges.types import AnimationConfig, SmoothingConfig @pytest.fixture def dpg_context() -> Generator[None]: clear_registry() dpgg.configure() dpg.create_context() try: yield finally: clear_registry() dpg.destroy_context() @pytest.fixture(autouse=True) def clean_registry() -> Generator[None]: clear_registry() dpgg.configure() yield clear_registry() def test_animation_converges_to_latest_target() -> None: dpgg.digital_gauge(tag="anim", value=0, animation=AnimationConfig(enabled=True, duration=1.0)) set_runtime_value("anim", 100, now=10.0) state = get_gauge_state("anim") config = state.config.animation assert isinstance(config, AnimationConfig) value, active = advance_animation(state.animation_state, config, now=10.5) assert value == 50 assert active is True value, active = advance_animation(state.animation_state, config, now=11.0) assert value == 100 assert active is False def test_smoothing_progresses_and_resets_on_range_change() -> None: dpgg.digital_gauge( tag="smooth", value=0, smoothing=SmoothingConfig(enabled=True, alpha=0.5), ) set_runtime_value("smooth", 100, now=1.0) state = get_gauge_state("smooth") assert state.displayed_value == 0 assert state.smoothing_state.active is True dpgg.configure_gauge("smooth", max_value=50) assert state.displayed_value == 50 assert state.smoothing_state.value == 50 def test_latest_target_wins_without_queue_growth() -> None: dpgg.digital_gauge(tag="latest", value=0, animation=AnimationConfig(enabled=True, duration=1.0)) set_runtime_value("latest", 25, now=1.0) set_runtime_value("latest", 75, now=1.1) set_runtime_value("latest", 50, now=1.2) state = get_gauge_state("latest") assert state.target_value == 50 assert state.clamped_value == 50 assert state.animation_state.target_value == 50 assert state.value_revision == 3 def test_attached_renderer_schedules_only_while_animation_active(dpg_context: None) -> None: with dpg.window(label="Animation"): dpgg.digital_gauge( tag="attached", value=0, width=180, height=80, animation=AnimationConfig(enabled=True, duration=1.0), ) dpgg.set_value("attached", 100) debug = dpgg.get_gauge_debug_state("attached") assert debug["renderer"]["scheduled"] is True assert debug["animation"]["target_value"] == 100 state = get_gauge_state("attached") state.animation_state.active = False state.smoothing_state.active = False state.renderer._scheduled = False state.renderer.render() assert dpgg.get_gauge_debug_state("attached")["renderer"]["scheduled"] is False