Current section
Files
Jump to
Current section
Files
src/scamper@testing.erl
-module(scamper@testing).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/scamper/testing.gleam").
-export([assert_transition/3, assert_final/1, reachable_states/2, run_events/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Test helpers for scamper FSMs.\n"
"\n"
" Provides convenience functions for testing state machine behavior.\n"
" These functions use `let assert` which panics on failure — they are\n"
" designed for test code only, not for library or application code.\n"
).
-file("src/scamper/testing.gleam", 16).
?DOC(
" Attempt a transition and assert the machine reaches the expected state.\n"
" Panics if the transition fails or the machine is not in the expected state.\n"
" Returns the new machine for chaining.\n"
).
-spec assert_transition(scamper:machine(IYE, IYF, IYG), IYG, IYE) -> scamper:machine(IYE, IYF, IYG).
assert_transition(Machine, Event, Expected_state) ->
New_machine@1 = case scamper:transition(Machine, Event) of
{ok, New_machine} -> New_machine;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"scamper/testing"/utf8>>,
function => <<"assert_transition"/utf8>>,
line => 21,
value => _assert_fail,
start => 763,
'end' => 826,
pattern_start => 774,
pattern_end => 789})
end,
case scamper:current_state(New_machine@1) =:= Expected_state of
true -> nil;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"scamper/testing"/utf8>>,
function => <<"assert_transition"/utf8>>,
line => 22,
value => _assert_fail@1,
start => 829,
'end' => 899,
pattern_start => 840,
pattern_end => 844})
end,
New_machine@1.
-file("src/scamper/testing.gleam", 29).
?DOC(
" Assert that the machine is in a final state.\n"
" Panics if the machine is not in a final state.\n"
" Returns the machine for chaining.\n"
).
-spec assert_final(scamper:machine(IYN, IYO, IYP)) -> scamper:machine(IYN, IYO, IYP).
assert_final(Machine) ->
case scamper:is_final(Machine) of
true -> nil;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"scamper/testing"/utf8>>,
function => <<"assert_final"/utf8>>,
line => 32,
value => _assert_fail,
start => 1159,
'end' => 1202,
pattern_start => 1170,
pattern_end => 1174})
end,
Machine.
-file("src/scamper/testing.gleam", 38).
?DOC(
" Find all states reachable from the initial state via transition rules.\n"
" Delegates to validation.reachable_states.\n"
).
-spec reachable_states(scamper@config:config(IYW, any(), any()), IYW) -> list(IYW).
reachable_states(Config, Initial_state) ->
scamper@validation:reachable_states(Config, Initial_state).
-file("src/scamper/testing.gleam", 48).
?DOC(
" Run a sequence of events against the machine.\n"
" Returns the final machine if all transitions succeed,\n"
" or the first TransitionError encountered.\n"
).
-spec run_events(scamper:machine(IZD, IZE, IZF), list(IZF)) -> {ok,
scamper:machine(IZD, IZE, IZF)} |
{error, scamper@error:transition_error(IZD, IZF)}.
run_events(Machine, Events) ->
gleam@list:try_fold(
Events,
Machine,
fun(M, Evt) -> scamper:transition(M, Evt) end
).