Files
esphome/tests/unit_tests/components/light/test_automation.py
T
2026-09-26 08:47:25 +10:00

59 lines
2.0 KiB
Python

"""Tests for validate_light_state -- a light on/off value that prioritizes ON/OFF
string forms over generic boolean forms, while still accepting the latter."""
import pytest
import yaml
from esphome.components.light.automation import validate_light_state
import esphome.config_validation as cv
from esphome.schema_extractors import SCHEMA_EXTRACT
@pytest.mark.parametrize(
("value", "expected"),
[
("ON", True),
("on", True),
("On", True),
("OFF", False),
("off", False),
("Off", False),
(True, True),
(False, False),
("true", True),
("false", False),
("yes", True),
("no", False),
],
)
def test_validate_light_state_accepts_on_off_and_booleans(
value: str | bool, expected: bool
) -> None:
assert validate_light_state(value) is expected
def test_validate_light_state_rejects_invalid_string() -> None:
# The error must mention both accepted forms (ON/OFF and boolean), not just
# whichever validator happened to run last.
with pytest.raises(cv.Invalid, match="ON.*OFF.*boolean"):
validate_light_state("maybe")
def test_validate_light_state_schema_extractor_reports_on_off() -> None:
assert validate_light_state(SCHEMA_EXTRACT) == ("ON", "OFF")
def test_validate_light_state_quoted_on_off_survive_yaml_parsing() -> None:
"""The default PyYAML resolver treats bareword on/off/yes/no as booleans, so a real
YAML config must quote 'ON'/'OFF' for validate_light_state's string-matching branch
to ever see a string at all -- an unquoted `state: on` already arrives as a native
bool. Both forms must still validate to the same result.
"""
quoted = yaml.safe_load('state: "ON"')["state"]
assert quoted == "ON"
assert validate_light_state(quoted) is True
unquoted = yaml.safe_load("state: on")["state"]
assert unquoted is True # PyYAML already converted it before validation runs
assert validate_light_state(unquoted) is True