Account for corio import changes and add tests for pydantic models

This commit is contained in:
Edward Brown 2026-05-08 09:20:06 +01:00
parent bf87c83251
commit 107e62081d
5 changed files with 92 additions and 8 deletions

View file

@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Type, ClassVar
from pydantic import Field
from corio.iterator_tools import strip_none
from corio.iterator import strip_none
from haco.base import Base
from haco.topics import AnnounceTopicState, AnnounceTopicCommand

View file

@ -6,7 +6,7 @@ from pydantic import Field
from corio import Constants
from corio import Path
from corio.json_tools import to_json
from corio.jsn import to_json
from haco.base import Base
from haco.capabilities import Capability

View file

@ -3,13 +3,13 @@
Observability and logging setup for the haco library.
"""
from corio import logging, debug, Constants
from corio import logs, debug, Constants
from haco.paths import paths
debug.trace()
logger = logging.get_logger(
logger = logs.get_logger(
name=paths.name_ns,
stream=Constants.DEVELOPMENT,
version=paths.metadata.version,

View file

@ -0,0 +1,84 @@
from __future__ import annotations
from types import SimpleNamespace
import pytest
from corio import Path
from haco.climate import Climate
from haco.device import Device
from haco.switch import Switch
@pytest.fixture
def client_stub():
return SimpleNamespace(
topic=Path("root/client"),
will=SimpleNamespace(topic="root/status"),
)
def test_switch_announce_payload_matches_expected(client_stub):
switch = Switch(name="Main", icon="power")
device = Device(name="Dev", controls=[switch])
device.set_parent(client_stub)
data = switch.get_announce()
assert data == {
"platform": "switch",
"name": "Main",
"icon": "mdi:power",
"unique_id": "dev-main",
"availability_topic": "root/status",
"state_topic": "root/client/dev/main/default/state",
"command_topic": "root/client/dev/main/default/command",
}
def test_climate_announce_payload_has_expected_ha_keys(client_stub):
climate = Climate(name="Cl")
device = Device(name="Dev", controls=[climate])
device.set_parent(client_stub)
data = climate.get_announce()
expected_subset = {
"platform",
"name",
"unique_id",
"availability_topic",
"temperature_unit",
"temperature_min",
"temperature_max",
"mode_command_topic",
"mode_state_topic",
"temperature_command_topic",
"temperature_state_topic",
"power_command_topic",
"power_state_topic",
}
assert expected_subset.issubset(set(data))
assert not any(key in data for key in {"capabilities", "subscriptions", "device", "parent"})
assert not any(callable(value) for value in data.values())
def test_model_dump_excludes_runtime_extra_attributes():
switch = Switch(name="Main")
switch.dynamic_callback = lambda value: value
dumped = switch.model_dump()
assert "dynamic_callback" not in dumped
def test_parent_wiring_sets_control_subscriptions(client_stub):
switch = Switch(name="Main")
device = Device(name="Dev", controls=[switch])
device.set_parent(client_stub)
assert switch.unique_id == "dev-main"
assert switch.availability_topic == "root/status"
assert device.subscriptions is not None
assert "root/client/dev/main/default/command" in device.subscriptions
handler = device.subscriptions["root/client/dev/main/default/command"]
assert hasattr(handler, "handle")

View file

@ -1,8 +1,8 @@
import string
from typing import Callable
from corio import json
from corio.datatype_tools import to_bool
from corio import jsn
from corio.datatype import to_bool
CHARS_ALLOWED = string.ascii_lowercase + string.digits
SEPS = '_- /'
@ -76,8 +76,8 @@ class ConvertersNumeric(Converters):
Converters for numeric values.
"""
command: Callable = json.from_json
state: Callable = json.to_json
command: Callable = jsn.from_json
state: Callable = jsn.to_json
def get_prefix(io: str) -> str:
"""