Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Async-first, high-level Python client for Home Assistant with REST and WebSocket
## Features

- Async context manager with automatic WebSocket connection and state priming
- Typed domain accessors: light, switch, climate, cover, sensor, binary sensor, media player, scene, timer
- Typed domain accessors: air quality, binary sensor, climate, cover, event, fan, humidifier, light, lock, media player, scene, sensor, switch, timer, vacuum, valve
- Intent-specific methods over raw service calls (e.g. `light.set_brightness(200)` instead of `light.turn_on(brightness=200)`)
- Real-time state change listeners with granular attribute and state-transition filtering
- Synchronous blocking wrapper for scripts, REPL, and Jupyter
Expand Down
6 changes: 4 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ WebSocket support.
ship via the `haclient.domains` entry-point group.
- Async context manager with automatic WebSocket connect, race-free
state priming, and reconnect-aware refresh.
- Typed domain accessors: `light`, `switch`, `climate`, `cover`,
`sensor`, `binary_sensor`, `media_player`, `scene`, `timer`.
- Typed domain accessors: `air_quality`, `binary_sensor`, `climate`,
`cover`, `event`, `fan`, `humidifier`, `light`, `lock`,
`media_player`, `scene`, `sensor`, `switch`, `timer`, `vacuum`,
`valve`.
- Real-time state-change listeners with attribute and transition
filtering.
- Synchronous blocking wrapper for scripts, REPL, and Jupyter.
Expand Down
3 changes: 3 additions & 0 deletions docs/reference/domains/air_quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Air Quality

::: haclient.domains.air_quality
3 changes: 3 additions & 0 deletions docs/reference/domains/event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Event

::: haclient.domains.event
3 changes: 3 additions & 0 deletions docs/reference/domains/fan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Fan

::: haclient.domains.fan
3 changes: 3 additions & 0 deletions docs/reference/domains/humidifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Humidifier

::: haclient.domains.humidifier
3 changes: 3 additions & 0 deletions docs/reference/domains/lock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Lock

::: haclient.domains.lock
3 changes: 3 additions & 0 deletions docs/reference/domains/vacuum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Vacuum

::: haclient.domains.vacuum
3 changes: 3 additions & 0 deletions docs/reference/domains/valve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Valve

::: haclient.domains.valve
15 changes: 11 additions & 4 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,22 @@ nav:
- REST adapter: reference/infra/rest_aiohttp.md
- WebSocket adapter: reference/infra/ws_aiohttp.md
- Domains:
- Light: reference/domains/light.md
- Switch: reference/domains/switch.md
- Air Quality: reference/domains/air_quality.md
- Binary Sensor: reference/domains/binary_sensor.md
- Climate: reference/domains/climate.md
- Cover: reference/domains/cover.md
- Sensor: reference/domains/sensor.md
- Binary Sensor: reference/domains/binary_sensor.md
- Event: reference/domains/event.md
- Fan: reference/domains/fan.md
- Humidifier: reference/domains/humidifier.md
- Light: reference/domains/light.md
- Lock: reference/domains/lock.md
- Media Player: reference/domains/media_player.md
- Scene: reference/domains/scene.md
- Sensor: reference/domains/sensor.md
- Switch: reference/domains/switch.md
- Timer: reference/domains/timer.md
- Vacuum: reference/domains/vacuum.md
- Valve: reference/domains/valve.md

hooks:
- tools/mkdocs_hooks.py
Expand Down
43 changes: 43 additions & 0 deletions tests/test_docs_completeness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Documentation completeness tests.

Guards against drift between registered built-in domains and the
documentation surface (MkDocs nav and reference pages). See issue #90.
"""

from __future__ import annotations

from pathlib import Path

import haclient.domains # noqa: F401 -- registers built-in domains
from haclient.core.plugins import DomainRegistry

REPO_ROOT = Path(__file__).resolve().parents[1]
DOMAINS_DIR = REPO_ROOT / "docs" / "reference" / "domains"
MKDOCS_YML = REPO_ROOT / "mkdocs.yml"


def _registered_builtin_domains() -> set[str]:
"""Return the set of built-in domain names registered at import time.

Returns
-------
set of str
Names registered via ``haclient.domains.__init__`` imports.
"""
return set(DomainRegistry.shared().names())


def test_every_builtin_domain_has_reference_page() -> None:
"""Every registered built-in domain must have a Markdown reference page."""
expected = _registered_builtin_domains()
existing = {p.stem for p in DOMAINS_DIR.glob("*.md")}
missing = expected - existing
assert not missing, f"Missing domain reference pages: {sorted(missing)}"


def test_every_builtin_domain_listed_in_mkdocs_nav() -> None:
"""Every registered built-in domain must appear in the MkDocs nav."""
nav_text = MKDOCS_YML.read_text(encoding="utf-8")
expected = _registered_builtin_domains()
missing = {name for name in expected if f"reference/domains/{name}.md" not in nav_text}
assert not missing, f"Domains missing from mkdocs.yml nav: {sorted(missing)}"
Loading