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.
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
"""Tests for the /wind/oscillation/vs/0 swing fallback helper in climate.py
|
|
(issue #126).
|
|
|
|
`_oscillation_swing` is a pure module-level function, like `_temps_vs_item`
|
|
in test_climate_temperature_fallback.py -- testable directly without a
|
|
coordinator/entity. This covers the fallback-selection logic that the
|
|
registry-level "no unbound hrefs" test in test_golden_regression.py doesn't
|
|
reach: newer WindFree firmware reports no /wind/direction/vs/0 at all, so
|
|
swing_mode/swing_modes would silently be None/empty without this fallback.
|
|
"""
|
|
|
|
from custom_components.localthings.climate import _oscillation_swing
|
|
|
|
|
|
def test_oscillation_swing_off_when_both_fixed():
|
|
assert _oscillation_swing({"vertical": "Fix", "horizontal": "Fix"}) == "off"
|
|
|
|
|
|
def test_oscillation_swing_vertical_only():
|
|
assert _oscillation_swing({"vertical": "Swing", "horizontal": "Fix"}) == "vertical"
|
|
|
|
|
|
def test_oscillation_swing_horizontal_only():
|
|
assert _oscillation_swing({"vertical": "Fix", "horizontal": "Swing"}) == "horizontal"
|
|
|
|
|
|
def test_oscillation_swing_both():
|
|
assert _oscillation_swing({"vertical": "Swing", "horizontal": "Swing"}) == "both"
|
|
|
|
|
|
def test_oscillation_swing_none_when_resource_absent():
|
|
"""Boards with /wind/direction/vs/0 instead don't populate this
|
|
resource at all -- callers must fall through cleanly, not raise."""
|
|
assert _oscillation_swing({}) is None
|