View Source Finitomata.ExUnit (Finitomata v0.14.5)
Helpers and assertions to make Finitomata
implementation easily testable.
Link to this section Summary
Functions
Convenience macro to assert a transition initiated by event_payload
argument on the FSM defined by the test context previously setup
with a call to setup_finitomata/1
.
Convenience macro to assert a transition initiated by event_payload
argument on the FSM defined by first three arguments.
This macro initiates the FSM implementation specified by arguments passed.
Setups Finitomata
for testing in the case and/or in ExUnit.Case.describe/2
block.
Convenience macro to test the whole Finitomata path, from starting to ending state.
Link to this section Functions
Convenience macro to assert a transition initiated by event_payload
argument on the FSM defined by the test context previously setup
with a call to setup_finitomata/1
.
Last regular argument in a call to assert_transition/3
would be an
event_payload
in a form of {event, payload}
, or just event
for no payload.
to_state
argument would be matched to the resulting state of the transition,
and block
accepts validation of the payload
after transition in a form of
test "some", ctx do
assert_transition ctx, {:increase, 1} do
:counted ->
assert_payload do
user_data.counter ~> 2
internals.pid ~> ^parent
end
# or: assert_payload %{user_data: %{counter: 2}, internals: %{pid: ^parent}}
assert_receive {:increased, 2}
end
end
assert_transition(id \\ nil, impl, name, event_payload, list)
View Source (macro)Convenience macro to assert a transition initiated by event_payload
argument on the FSM defined by first three arguments.
NB it’s not recommended to use low-level helpers, normally one should
define an FSM in setup_finitomata/1
block and use assert_transition/3
or even better test_path/3
.
Last regular argument in a call to assert_transition/3
would be an
event_payload
in a form of {event, payload}
, or just event
for no payload.
to_state
argument would be matched to the resulting state of the transition,
and block
accepts validation of the payload
after transition in a form of
parent = self()
assert_transition id, impl, name, {:increase, 1} do
:counted ->
assert_payload do
user_data.counter ~> 2
internals.pid ~> ^parent
end
# or: assert_payload %{user_data: %{counter: 2}, internals: %{pid: ^parent}}
assert_receive {:increased, 2}
end
init_finitomata(id \\ nil, impl, name, payload, options \\ [])
View Source (macro)This macro initiates the FSM implementation specified by arguments passed.
NB it’s not recommended to use low-level helpers, normally one should
define an FSM in setup_finitomata/1
block, which would initiate
the FSM amongs other things.
Arguments:
id
— aFinitomata
instance, carrying multiple _FSM_simpl
— the module implementing FSM (havinguse Finitomata
clause)name
— the name of the FSMpayload
— the initial payload for this FSMoptions
— the options to control the test, such astransition_count
— the number of expectations to declare (defaults to number of states)
Once called, this macro will start Finitomata.Suprevisor
with the id
given,
define a mox for impl
unless already efined,
Mox.allow/3
the FSM to call testing process,
and expectations as a listener to after_transition/3
callback,
sending a message of a shape {:on_transition, id, state, payload}
to test process.
Then it’ll start FSM and ensure it has entered Finitomata.Transition.entry/2
state.
Setups Finitomata
for testing in the case and/or in ExUnit.Case.describe/2
block.
It would effectively init the FSM with an underlying call to init_finitomata/5
,
and put finitomata
key into context
, assigning :test_pid
subkey to the pid
of the running test process, and mixing :context
content into test context.
Although one might pass the name, it’s more convenient to avoid doing it, in this case the name would be assigned from the test name, which guarantees uniqueness of _FSM_s running in concurrent environment.
It should return the keyword which would be validated with NimbleOptions
schema
:fsm
(non-emptykeyword/0
) - Required. The FSM declaration to be used in tests.:id
(term/0
) - The ID of theFinitomata
tree. The default value isnil
.:implementation
- Required. The implementatoin ofFinitomata
(the module withuse Finitomata
.):name
(String.t/0
) - The name of theFinitomata
instance.:payload
(term/0
) - Required. The initial payload for the FSM to start with.:options
(keyword/0
) - Additional options to use in FSM initialization. The default value is[]
.:transition_count
(non_neg_integer/0
) - The expected byMox
number of transitions to handle.
:context
(keyword/0
) - The additional context to be passed to actualExUnit.Callbacks.setup/2
call.
Example:
describe "MyFSM tests" do
setup_finitomata do
parent = self()
[
fsm: [implementation: MyFSM, payload: %{}],
context: [parent: parent]
]
end
…
Convenience macro to test the whole Finitomata path, from starting to ending state.
Must be used with a setup_finitomata/1
callback.
Example:
test_path "The only path", %{finitomata: %{test_pid: parent}} do
{:start, self()} ->
assert_state :started do
assert_payload do
internals.counter ~> 1
pid ~> ^parent
end
assert_receive {:on_start, ^parent}
end
:do ->
assert_state :done do
assert_receive :on_do
end
assert_state :* do
assert_receive :on_end
end
end