Files
abogen/tests/contracts/test_host_context_contract.py
T
Artem Akymenko 0f568120f4 feat: add contract test suite for Plugin API
Create reusable contract tests for TTS Plugin Architecture:
- conftest.py: shared fixtures and stubs (FakeEngine, FakeSession, etc.)
- test_types_contract.py: value object contracts (frozen, immutability, equality)
- test_errors_contract.py: error hierarchy contracts
- test_manifest_contract.py: manifest type contracts
- test_engine_contract.py: Engine protocol contracts (lifecycle, dispose)
- test_session_contract.py: EngineSession protocol contracts
- test_capabilities_contract.py: capability protocol contracts
- test_host_context_contract.py: HostContext contracts
- test_plugin_contract.py: plugin contract (exports, create_engine)

124 tests covering all public API contracts.
2026-07-12 16:20:05 +03:00

90 lines
2.6 KiB
Python

"""Contract tests for HostContext.
These tests verify that HostContext satisfies the architectural requirements:
- Minimal (3 fields maximum)
- Frozen dataclass
- config_dir: Path
- logger: Logger
- http_client: HttpClient protocol
"""
import logging
from pathlib import Path
import pytest
from abogen.tts_plugin.host_context import HttpClient, HostContext
class TestHostContextContract:
"""Contract tests for HostContext dataclass."""
def test_is_frozen_dataclass(self) -> None:
assert hasattr(HostContext, "__dataclass_params__")
assert HostContext.__dataclass_params__.frozen is True
def test_required_fields(self, tmp_path: Path) -> None:
logger = logging.getLogger("test")
class FakeClient:
def get(self, url: str, **kwargs: object) -> object:
return None
def post(self, url: str, **kwargs: object) -> object:
return None
ctx = HostContext(
config_dir=tmp_path,
logger=logger,
http_client=FakeClient(),
)
assert ctx.config_dir == tmp_path
assert ctx.logger is logger
def test_immutability(self, tmp_path: Path) -> None:
class FakeClient:
def get(self, url: str, **kwargs: object) -> object:
return None
def post(self, url: str, **kwargs: object) -> object:
return None
ctx = HostContext(
config_dir=tmp_path,
logger=logging.getLogger("test"),
http_client=FakeClient(),
)
with pytest.raises(AttributeError):
ctx.config_dir = Path("/other") # type: ignore[misc]
def test_max_three_fields(self) -> None:
"""Architecture spec: HostContext is minimal (3 fields max)."""
import dataclasses
fields = dataclasses.fields(HostContext)
assert len(fields) <= 3
class TestHttpClientProtocolContract:
"""Contract tests for HttpClient protocol."""
def test_http_client_is_protocol(self) -> None:
assert hasattr(HttpClient, "__protocol_attrs__")
def test_http_client_has_get(self) -> None:
assert hasattr(HttpClient, "get")
def test_http_client_has_post(self) -> None:
assert hasattr(HttpClient, "post")
def test_http_client_satisfied(self) -> None:
class FakeClient:
def get(self, url: str, **kwargs: object) -> object:
return None
def post(self, url: str, **kwargs: object) -> object:
return None
client = FakeClient()
assert isinstance(client, HttpClient)