# pyright: reportGeneralTypeIssues=false from collections.abc import Generator from importlib.resources import files import dearpygui.dearpygui as dpg import pytest import dpg_gauges as dpgg from dpg_gauges.exceptions import GaugeConfigError, GaugeNotFoundError from dpg_gauges.gauges import DigitalGaugeConfig from dpg_gauges.state import clear_registry, get_gauge_state, register_gauge from dpg_gauges.types import AnimationConfig @pytest.fixture(autouse=True) def clean_registry() -> Generator[None]: clear_registry() dpgg.configure() yield clear_registry() @pytest.fixture def dpg_context() -> Generator[None]: dpg.create_context() try: yield finally: dpg.destroy_context() def test_public_exports_and_version() -> None: assert dpgg.__version__ == "1.0.2" assert files("dpg_gauges").joinpath("py.typed").is_file() for name in dpgg.__all__: assert hasattr(dpgg, name) def test_gauge_creation_supports_explicit_parent(dpg_context: None) -> None: dpg.add_window(tag="late_parent", label="Late Parent") dpgg.analog_gauge(tag="late_gauge", parent="late_parent", width=180, height=180) state = get_gauge_state("late_gauge") assert state.config.parent == "late_parent" assert dpg.get_item_parent(state.container_tag) == "late_parent" def test_unknown_duplicate_and_deleted_gauge_errors() -> None: with pytest.raises(GaugeNotFoundError): dpgg.set_value("missing", 1) dpgg.digital_gauge(tag="speed") with pytest.raises(GaugeConfigError): register_gauge("digital", DigitalGaugeConfig(tag="speed")) dpgg.delete_gauge("speed") with pytest.raises(GaugeNotFoundError): dpgg.update_gauge("speed", value=2) def test_invalid_range_threshold_marker_and_non_finite_value() -> None: with pytest.raises(GaugeConfigError): dpgg.digital_gauge(tag="bad", min_value=10, max_value=0) dpgg.bar_gauge(tag="bar", min_value=0, max_value=100) with pytest.raises(GaugeConfigError): dpgg.set_thresholds("bar", [dpgg.ThresholdBand(float("nan"), 10, (255, 0, 0))]) with pytest.raises(GaugeConfigError): dpgg.set_markers("bar", [dpgg.GaugeMarker(float("nan"), (255, 255, 255))]) dpgg.set_value("bar", float("inf")) state = get_gauge_state("bar") assert state.invalid_value is True assert state.clamped_value is None def test_hidden_layout_sizing_survives_show_later(dpg_context: None) -> None: with dpg.window(label="Hidden"): dpgg.digital_gauge(tag="hidden", value=1, width=180, height=80, show=False) state = get_gauge_state("hidden") assert state.last_nonzero_width == 180 assert state.last_nonzero_height == 80 dpgg.set_show("hidden", True) assert state.config.show is True assert state.last_nonzero_width == 180 def test_animation_disabled_and_enabled_modes() -> None: dpgg.digital_gauge(tag="instant", value=0, animation=False) dpgg.set_value("instant", 100) instant = get_gauge_state("instant") assert instant.animation_state.active is False assert instant.displayed_value == 100 dpgg.digital_gauge( tag="animated", value=0, animation=AnimationConfig(enabled=True, duration=1.0) ) dpgg.set_value("animated", 100) animated = get_gauge_state("animated") assert animated.animation_state.active is True assert animated.animation_state.target_value == 100