Skip to content

Commit 05c3f1c

Browse files
committed
test: cover remaining patch coverage gaps
- Test done_invoke_ prefix with Event() objects (factory.py L290-291) - Test visit/async_visit early return for missing registry keys (callbacks.py) - Test async_visit with awaitable visitor function (callbacks.py L378)
1 parent a87e670 commit 05c3f1c

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ repos:
3333
pass_filenames: false
3434
- id: pytest
3535
name: Pytest
36-
entry: uv run pytest -n auto
36+
entry: uv run pytest -n auto --cov-fail-under=100
3737
types: [python]
3838
language: system
3939
pass_filenames: false

tests/test_invoke.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from statemachine.invoke import InvokeContext
88
from statemachine.invoke import invoke_group
99

10+
from statemachine import Event
1011
from statemachine import State
1112
from statemachine import StateChart
1213

@@ -717,3 +718,59 @@ def on_cancel(self):
717718
wrapper = _InvokeCallableWrapper(MyHandler)
718719
# _instance is None, _is_class is True → early return
719720
wrapper.on_cancel() # should not raise
721+
722+
723+
class TestDoneInvokeEventFactory:
724+
"""done_invoke_ prefix works with both TransitionList and Event."""
725+
726+
async def test_done_invoke_with_event_object(self, sm_runner):
727+
"""Event() object with done_invoke_ prefix should match done.invoke events."""
728+
729+
class SM(StateChart):
730+
loading = State(initial=True, invoke=lambda: "result")
731+
ready = State(final=True)
732+
done_invoke_loading = Event(loading.to(ready))
733+
734+
sm = await sm_runner.start(SM)
735+
await sm_runner.sleep(0.15)
736+
await sm_runner.processing_loop(sm)
737+
738+
assert "ready" in sm.configuration_values
739+
740+
741+
class TestVisitNoCallbacks:
742+
"""visit/async_visit with no registered callbacks is a no-op."""
743+
744+
def test_visit_missing_key(self):
745+
from statemachine.callbacks import CallbacksRegistry
746+
747+
registry = CallbacksRegistry()
748+
# Should not raise — just returns
749+
registry.visit("nonexistent_key", lambda cb, **kw: None)
750+
751+
async def test_async_visit_missing_key(self):
752+
from statemachine.callbacks import CallbacksRegistry
753+
754+
registry = CallbacksRegistry()
755+
await registry.async_visit("nonexistent_key", lambda cb, **kw: None)
756+
757+
758+
class TestAsyncVisitAwaitable:
759+
"""async_visit should await the visitor_fn result when it is awaitable."""
760+
761+
async def test_async_visitor_fn_is_awaited(self):
762+
from statemachine.callbacks import CallbackGroup
763+
from statemachine.callbacks import CallbacksExecutor
764+
from statemachine.callbacks import CallbackSpec
765+
766+
visited = []
767+
768+
async def async_visitor(callback, **kwargs):
769+
visited.append(str(callback))
770+
771+
executor = CallbacksExecutor()
772+
spec = CallbackSpec("dummy", group=CallbackGroup.INVOKE, is_convention=True)
773+
executor.add("test_key", spec, lambda: lambda **kw: True)
774+
775+
await executor.async_visit(async_visitor)
776+
assert visited == ["dummy"]

0 commit comments

Comments
 (0)