Files
bambuddy/spoolbuddy/tests/test_display_control.py
T

177 lines
5.7 KiB
Python

"""Tests for daemon.display_control — DisplayControl brightness and blanking."""
import time
import pytest
class TestDisplayControlNoBacklight:
"""DisplayControl behavior when no backlight is present."""
def test_no_backlight_detected(self, monkeypatch, tmp_path):
# Point BACKLIGHT_BASE to an empty directory (no backlight entries)
import daemon.display_control as dc_mod
empty_dir = tmp_path / "backlight"
empty_dir.mkdir()
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", empty_dir)
dc = dc_mod.DisplayControl()
assert dc.has_backlight is False
def test_no_backlight_dir_missing(self, monkeypatch, tmp_path):
import daemon.display_control as dc_mod
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", tmp_path / "nonexistent")
dc = dc_mod.DisplayControl()
assert dc.has_backlight is False
def test_set_brightness_noop_without_backlight(self, monkeypatch, tmp_path):
import daemon.display_control as dc_mod
empty_dir = tmp_path / "backlight"
empty_dir.mkdir()
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", empty_dir)
dc = dc_mod.DisplayControl()
# Should not raise
dc.set_brightness(50)
dc.set_brightness(0)
dc.set_brightness(100)
class TestDisplayControlWithBacklight:
"""DisplayControl behavior with a mock sysfs backlight."""
@pytest.fixture
def display(self, monkeypatch, tmp_path):
import daemon.display_control as dc_mod
bl_dir = tmp_path / "backlight" / "rpi_backlight"
bl_dir.mkdir(parents=True)
(bl_dir / "brightness").write_text("200")
(bl_dir / "max_brightness").write_text("255")
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", tmp_path / "backlight")
return dc_mod.DisplayControl(), bl_dir
def test_has_backlight_true(self, display):
dc, _ = display
assert dc.has_backlight is True
def test_set_brightness_100(self, display):
dc, bl_dir = display
dc.set_brightness(100)
assert (bl_dir / "brightness").read_text() == "255"
def test_set_brightness_0(self, display):
dc, bl_dir = display
dc.set_brightness(0)
assert (bl_dir / "brightness").read_text() == "0"
def test_set_brightness_50(self, display):
dc, bl_dir = display
dc.set_brightness(50)
value = int((bl_dir / "brightness").read_text())
# 50% of 255 = 127 or 128 depending on rounding
assert value == round(255 * 50 / 100)
def test_set_brightness_clamped_above_100(self, display):
dc, bl_dir = display
dc.set_brightness(200)
assert (bl_dir / "brightness").read_text() == "255"
def test_set_brightness_clamped_below_0(self, display):
dc, bl_dir = display
dc.set_brightness(-50)
assert (bl_dir / "brightness").read_text() == "0"
def test_max_brightness_fallback_on_missing_file(self, monkeypatch, tmp_path):
"""If max_brightness file doesn't exist, defaults to 255."""
import daemon.display_control as dc_mod
bl_dir = tmp_path / "backlight" / "rpi_backlight"
bl_dir.mkdir(parents=True)
(bl_dir / "brightness").write_text("100")
# No max_brightness file
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", tmp_path / "backlight")
dc = dc_mod.DisplayControl()
assert dc._max_brightness == 255
class TestDisplayControlBlanking:
"""Blanking logic: timeout, wake, tick."""
@pytest.fixture
def display(self, monkeypatch, tmp_path):
import daemon.display_control as dc_mod
empty_dir = tmp_path / "backlight"
empty_dir.mkdir()
monkeypatch.setattr(dc_mod, "BACKLIGHT_BASE", empty_dir)
return dc_mod.DisplayControl()
def test_blank_timeout_default_disabled(self, display):
assert display._blank_timeout == 0
def test_set_blank_timeout(self, display):
display.set_blank_timeout(30)
assert display._blank_timeout == 30
def test_set_blank_timeout_negative_clamped(self, display):
display.set_blank_timeout(-10)
assert display._blank_timeout == 0
def test_tick_does_not_blank_when_disabled(self, display):
display.set_blank_timeout(0)
display.tick()
assert display._blanked is False
def test_tick_blanks_after_timeout(self, display, monkeypatch):
display.set_blank_timeout(5)
# Simulate idle for 10 seconds by backdating last_activity
display._last_activity = time.monotonic() - 10
display.tick()
assert display._blanked is True
def test_tick_does_not_blank_before_timeout(self, display):
display.set_blank_timeout(60)
display.wake() # Reset activity
display.tick()
assert display._blanked is False
def test_wake_unblanks(self, display):
display.set_blank_timeout(5)
display._last_activity = time.monotonic() - 10
display.tick()
assert display._blanked is True
display.wake()
assert display._blanked is False
def test_tick_unblanks_when_timeout_disabled_while_blanked(self, display):
"""If timeout is disabled while screen is blanked, tick should unblank."""
display.set_blank_timeout(5)
display._last_activity = time.monotonic() - 10
display.tick()
assert display._blanked is True
display.set_blank_timeout(0)
display.tick()
assert display._blanked is False
def test_wake_resets_activity_timer(self, display):
display.set_blank_timeout(5)
old_time = display._last_activity
time.sleep(0.01)
display.wake()
assert display._last_activity > old_time