Adds [tool.ruff] and [tool.ty] config to pyproject.toml with a curated ruff rule set (E, F, W, I, UP, B, C4, SIM, RUF, ASYNC, LOG, G, PIE, RET, PERF, N), pins ruff/ty in requirements-dev.txt, reformats the whole tree with `ruff format`, and fixes the pre-existing lint and type-check debt those tools surfaced so both run clean. Production-code type fixes include: HA's ConfigFlowResult vs. the generic FlowResult in config_flow.py, narrowing BoundEntity.desc to its platform-specific subclass (SelectDesc/NumberDesc/SensorDesc/etc.) via cast() instead of an unchecked annotation, converting HA device_class strings to their proper enum types, a resolve_registry callback typed as `object` instead of `DeviceRegistry | None`, and a couple of other narrow correctness fixes (CA key type validation, an index-out-of-bounds false positive from an empty-tuple fallback, a bool/dict argument swap). Test-file fixes are mechanical: narrowing SamsungEntityDescription to the correct subclass via isinstance()/cast() before accessing subclass-only fields, and asserting Optional write_fn/unit_fn fields are set before calling them.
50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
from custom_components.localthings.registry.entities import (
|
|
PLATFORM_OF,
|
|
BinarySensorDesc,
|
|
ButtonDesc,
|
|
ClimateDesc,
|
|
FanDesc,
|
|
NumberDesc,
|
|
SelectDesc,
|
|
SensorDesc,
|
|
SwitchDesc,
|
|
TimeDesc,
|
|
)
|
|
|
|
|
|
def test_value_fn_defaults_to_identity():
|
|
d = SensorDesc(key="power", field="x.com.samsung.da.instantaneousPower")
|
|
assert d.value_fn(42) == 42
|
|
|
|
|
|
def test_descriptions_are_frozen():
|
|
d = SensorDesc(key="power", field="f")
|
|
try:
|
|
d.key = "other"
|
|
except Exception as e:
|
|
assert "frozen" in str(type(e)).lower() or "cannot" in str(e).lower()
|
|
else:
|
|
raise AssertionError("expected frozen dataclass")
|
|
|
|
|
|
def test_platform_mapping_covers_all_subclasses():
|
|
assert PLATFORM_OF[SensorDesc] == "sensor"
|
|
assert PLATFORM_OF[BinarySensorDesc] == "binary_sensor"
|
|
assert PLATFORM_OF[SelectDesc] == "select"
|
|
assert PLATFORM_OF[SwitchDesc] == "switch"
|
|
assert PLATFORM_OF[ButtonDesc] == "button"
|
|
assert PLATFORM_OF[NumberDesc] == "number"
|
|
assert PLATFORM_OF[TimeDesc] == "time"
|
|
assert PLATFORM_OF[ClimateDesc] == "climate"
|
|
assert PLATFORM_OF[FanDesc] == "fan"
|
|
|
|
|
|
def test_select_carries_options_and_write_fn():
|
|
d = SelectDesc(
|
|
key="sound",
|
|
field="mode",
|
|
options=("voice", "tone", "mute"),
|
|
write_fn=lambda p, rep: (["settings", "sound", "mode", "vs", "0"], {"mode": p}),
|
|
)
|
|
assert d.write_fn("tone", {}) == (["settings", "sound", "mode", "vs", "0"], {"mode": "tone"})
|