33 lines
1.2 KiB
Python
33 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from sync_state_machine.engine import StateMachineConfig, StateMachineRuntime
|
|
|
|
|
|
CFG_PATH = Path(__file__).resolve().parents[2] / "sync_state_machine" / "config" / "node_state_machine.yaml"
|
|
|
|
|
|
def test_all_event_outcomes_are_dispatchable() -> None:
|
|
cfg = StateMachineConfig.load(CFG_PATH)
|
|
runtime = StateMachineRuntime(cfg)
|
|
|
|
covered_events: set[str] = set()
|
|
|
|
for event_id, transition in cfg.transitions.items():
|
|
if not transition.outcomes:
|
|
continue
|
|
|
|
for idx, outcome in enumerate(transition.outcomes):
|
|
if outcome.to is None:
|
|
continue
|
|
|
|
src = next((s for s in transition.from_states if s != "*"), "*")
|
|
decision = runtime.dispatch(current_state=src, event_id=event_id, context=dict(outcome.when))
|
|
assert decision is not None, f"{event_id}[{idx}] did not dispatch"
|
|
assert decision.to_state == outcome.to, f"{event_id}[{idx}] target mismatch"
|
|
assert decision.outcome_index == idx, f"{event_id}[{idx}] wrong branch matched"
|
|
covered_events.add(event_id)
|
|
|
|
assert covered_events == set(cfg.transitions.keys())
|