mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 16:36:28 +00:00
88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
"""Tests for container_schema() memoization and lazy build."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Generator
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from esphome import config_validation as cv
|
|
import esphome.components.lvgl # noqa: F401
|
|
from esphome.components.lvgl import schemas as lvgl_schemas
|
|
from esphome.components.lvgl.schemas import WIDGET_TYPES, container_schema
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _clear_container_schema_cache() -> Generator[None]:
|
|
cache = getattr(lvgl_schemas, "_CONTAINER_SCHEMA_CACHE", None)
|
|
if cache is not None:
|
|
cache.clear()
|
|
yield
|
|
if cache is not None:
|
|
cache.clear()
|
|
|
|
|
|
def _widget_type(name: str = "obj"):
|
|
wt = WIDGET_TYPES.get(name)
|
|
assert wt is not None, f"widget type {name!r} not registered"
|
|
return wt
|
|
|
|
|
|
def test_same_args_return_same_validator() -> None:
|
|
wt = _widget_type("obj")
|
|
assert container_schema(wt) is container_schema(wt)
|
|
|
|
|
|
def test_extras_none_vs_truthy_get_different_validators() -> None:
|
|
wt = _widget_type("obj")
|
|
no_extras = container_schema(wt)
|
|
extras = {cv.Optional("custom_extra"): cv.string}
|
|
assert no_extras is not container_schema(wt, extras)
|
|
|
|
|
|
def test_different_widget_types_get_different_validators() -> None:
|
|
assert container_schema(_widget_type("obj")) is not container_schema(
|
|
_widget_type("label")
|
|
)
|
|
|
|
|
|
def test_schema_build_is_deferred_until_first_validation() -> None:
|
|
wt = _widget_type("obj")
|
|
with patch.object(
|
|
lvgl_schemas, "obj_schema", wraps=lvgl_schemas.obj_schema
|
|
) as obj_schema_mock:
|
|
validator = container_schema(wt)
|
|
assert obj_schema_mock.call_count == 0
|
|
validator({})
|
|
assert obj_schema_mock.call_count == 1
|
|
validator({})
|
|
assert obj_schema_mock.call_count == 1
|
|
|
|
|
|
def test_cached_validator_produces_equivalent_output() -> None:
|
|
wt = _widget_type("obj")
|
|
cached = container_schema(wt)
|
|
cached_result = cached({})
|
|
lvgl_schemas._CONTAINER_SCHEMA_CACHE.clear()
|
|
reference = container_schema(wt)
|
|
assert cached is not reference
|
|
assert cached_result == reference({})
|
|
|
|
|
|
def test_id_recycling_is_caught_by_identity_guard() -> None:
|
|
wt = _widget_type("obj")
|
|
real_extras = {cv.Optional("a"): cv.int_}
|
|
validator_a = container_schema(wt, real_extras)
|
|
|
|
cache_key = (id(wt), id(real_extras))
|
|
cached_entry = lvgl_schemas._CONTAINER_SCHEMA_CACHE[cache_key]
|
|
sentinel = {cv.Optional("a"): cv.int_}
|
|
lvgl_schemas._CONTAINER_SCHEMA_CACHE[cache_key] = (
|
|
cached_entry[0],
|
|
sentinel,
|
|
cached_entry[2],
|
|
)
|
|
|
|
assert container_schema(wt, real_extras) is not validator_a
|