@@ -66,6 +66,52 @@ test "100 seconds completes instantly" do
6666end
6767```
6868
69+ ### Test state machines with virtual time
70+
71+ ``` elixir
72+ defmodule SwitchStateMachine do
73+ use VirtualTimeGenStateMachine , callback_mode: :handle_event_function
74+
75+ def start_link (opts) do
76+ GenStateMachine .start_link (__MODULE__ , :off , opts)
77+ end
78+
79+ def init (_ ) do
80+ {:ok , :off , %{flip_count: 0 }}
81+ end
82+
83+ def handle_event (:cast , :flip , :off , data) do
84+ # Schedule timeout for 100ms
85+ VirtualTimeGenStateMachine .send_after (self (), :timeout , 100 )
86+ {:next_state , :on , %{data | flip_count: data.flip_count + 1 }}
87+ end
88+
89+ def handle_event (:cast , :flip , :on , data) do
90+ {:next_state , :off , data}
91+ end
92+
93+ def handle_event (:info , :timeout , state, data) do
94+ {:keep_state , %{data | timeout_fired: true }}
95+ end
96+ end
97+
98+ test " state machine transitions and timers" do
99+ {:ok , clock} = VirtualClock .start_link ()
100+ VirtualTimeGenStateMachine .set_virtual_clock (clock)
101+
102+ {:ok , sm} = SwitchStateMachine .start_link ([])
103+
104+ # Trigger transition and schedule timeout
105+ GenStateMachine .cast (sm, :flip )
106+
107+ # Advance virtual time - timeout fires instantly
108+ VirtualClock .advance (clock, 100 ) # ~10ms real time ⚡
109+
110+ # Check timeout fired
111+ assert get_state (sm).timeout_fired == true
112+ end
113+ ```
114+
69115### Simulate message-passing systems
70116
71117``` elixir
277323- All standard callbacks: ` handle_call ` , ` handle_cast ` , ` handle_info `
278324- Fast: simulate hours in seconds
279325
326+ ** VirtualTimeGenStateMachine** - Test state machines with virtual time
327+
328+ - Drop-in replacement: ` use VirtualTimeGenStateMachine ` instead of ` use GenStateMachine `
329+ - All standard callbacks: ` handle_event ` , state transitions, timeouts
330+ - Fast: simulate complex state transitions instantly
331+
280332** Actor Simulation DSL** - Prototype distributed systems
281333
282334- Pattern matching: declarative message handlers
@@ -310,6 +362,11 @@ use VirtualTimeGenServer
310362VirtualTimeGenServer .set_virtual_clock (clock)
311363VirtualTimeGenServer .send_after (pid, msg, delay)
312364
365+ # Virtual Time GenStateMachine
366+ use VirtualTimeGenStateMachine , callback_mode: :handle_event_function
367+ VirtualTimeGenStateMachine .set_virtual_clock (clock)
368+ VirtualTimeGenStateMachine .send_after (pid, msg, delay)
369+
313370# Actor Simulation (import for clean DSL)
314371import ActorSimulation
315372
0 commit comments