feat(s52): Notifier protocol + console notifier + MAF-free registration
This commit is contained in:
parent
4ecd571961
commit
d5b583349a
4 changed files with 196 additions and 1 deletions
42
tests/test_notify.py
Normal file
42
tests/test_notify.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"""S5.2 — Varsling: unit/contract tests for ``notify.py`` (Notifier protocol + notifiers).
|
||||
|
||||
Detach-seam (RED-when-detached) twins live in ``tests/test_notify_loadbearing.py``. Tests may
|
||||
import MAF-tainted modules freely (``verdicts``) — only ``notify.py`` itself must stay MAF-free.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
|
||||
from portfolio_optimiser.notify import ConsoleNotifier, Notifier
|
||||
from portfolio_optimiser.verdicts import ProposalFeatures, Verdict, capture_verdict
|
||||
|
||||
|
||||
def _verdict() -> Verdict:
|
||||
return capture_verdict(
|
||||
ProposalFeatures(
|
||||
affected_codes=frozenset({"05.2", "03.1"}),
|
||||
measure_type="scope_reduction",
|
||||
claimed_saving_nok=200_000.0,
|
||||
description="LED retrofit",
|
||||
),
|
||||
"approved",
|
||||
"feasible within range",
|
||||
)
|
||||
|
||||
|
||||
def test_plain_callable_satisfies_notifier() -> None:
|
||||
"""The seam promise: any plain callable satisfies the runtime-checkable ``Notifier`` protocol,
|
||||
so ``run_project(notify=lambda v: ...)`` stays valid — a structural superset of
|
||||
``Callable[[Verdict], None]``, not a new ABC (needs ``@runtime_checkable``)."""
|
||||
assert isinstance(lambda v: None, Notifier)
|
||||
|
||||
|
||||
def test_console_emits_id_and_decision() -> None:
|
||||
"""ConsoleNotifier writes the verdict id + decision to the injected stream (never a URL)."""
|
||||
stream = io.StringIO()
|
||||
verdict = _verdict()
|
||||
ConsoleNotifier(stream=stream)(verdict)
|
||||
out = stream.getvalue()
|
||||
assert verdict.id in out
|
||||
assert verdict.decision in out
|
||||
Loading…
Add table
Add a link
Reference in a new issue