"""Tests for DriverChip.get_sequence's reset-delay handling.""" from collections.abc import Generator import pytest from esphome.components.mipi import ( BRIGHTNESS, CONF_INVERT_COLORS, CONF_PIXEL_MODE, DriverChip, ) from esphome.const import CONF_BRIGHTNESS # A minimal config with no reset pin: enough for get_sequence(add_madctl=False) to run # without needing a full display configuration. _BASE_CONFIG = {CONF_PIXEL_MODE: "16bit", CONF_INVERT_COLORS: False} @pytest.fixture(autouse=True) def _remove_test_models() -> Generator[None]: """Unregister chips created by a test.""" existing = set(DriverChip.models) yield for name in set(DriverChip.models) - existing: del DriverChip.models[name] def test_get_sequence_defaults_to_10ms_reset_delay() -> None: """A model with no reset_delay default falls back to a 10ms settling delay.""" chip = DriverChip("TEST-GET-SEQUENCE-DEFAULT") sequence = chip.get_sequence(_BASE_CONFIG, add_madctl=False, add_reset=True) # SWRESET ({1, 0}) is prepended (no reset pin configured), followed by the # 10ms settling delay, flattened to {10, 255}. assert sequence[:4] == (1, 0, 10, 255) def test_get_sequence_uses_model_reset_delay_default() -> None: """A model's own reset_delay default overrides the base 10ms default.""" chip = DriverChip("TEST-GET-SEQUENCE-CUSTOM-DELAY", reset_delay=99) sequence = chip.get_sequence(_BASE_CONFIG, add_madctl=False, add_reset=True) assert sequence[:4] == (1, 0, 99, 255) @pytest.mark.parametrize("reset_delay", [0, 256]) def test_get_sequence_rejects_out_of_range_reset_delay(reset_delay: int) -> None: """reset_delay outside 1-255ms is rejected. This matches the 1-255ms range map_sequence() already allows for a "delay N" entry in a custom init sequence. """ chip = DriverChip("TEST-GET-SEQUENCE-BAD-DELAY", reset_delay=reset_delay) with pytest.raises(ValueError, match="reset_delay must be between 1 and 255ms"): chip.get_sequence(_BASE_CONFIG, add_madctl=False, add_reset=True) def test_get_sequence_skips_reset_delay_validation_without_add_reset() -> None: """An out-of-range reset_delay is only checked when add_reset is requested. mipi_dsi calls get_sequence with add_reset=False and never uses reset_delay, so an invalid default there should not raise. """ chip = DriverChip("TEST-GET-SEQUENCE-NO-RESET", reset_delay=999) chip.get_sequence(_BASE_CONFIG, add_madctl=False, add_reset=False) def _has_brightness_command(sequence: tuple[int, ...], value: int) -> bool: """True if the flattened sequence holds a one-byte brightness (0x51) command.""" return any( sequence[i : i + 3] == (BRIGHTNESS, 1, value) for i in range(len(sequence) - 2) ) @pytest.mark.parametrize("brightness", [0, 0x80]) def test_get_sequence_adds_configured_brightness(brightness: int) -> None: """A configured brightness is sent at startup, including zero.""" chip = DriverChip("TEST-GET-SEQUENCE-BRIGHTNESS") sequence = chip.get_sequence( {**_BASE_CONFIG, CONF_BRIGHTNESS: brightness}, add_madctl=False ) assert _has_brightness_command(sequence, brightness) def test_get_sequence_omits_brightness_when_not_set() -> None: """No brightness command is sent when neither config nor model sets one.""" chip = DriverChip("TEST-GET-SEQUENCE-NO-BRIGHTNESS") sequence = chip.get_sequence(_BASE_CONFIG, add_madctl=False) assert not any(_has_brightness_command(sequence, v) for v in range(256))