Files
gm_ctflow/test/gm_ctflow_SUITE.erl
T
2026-05-24 12:41:26 +02:00

135 lines
3.6 KiB
Erlang

-module(gm_ctflow_SUITE).
-export([ all/0
, groups/0
, init_per_suite/1
, end_per_suite/1
, init_per_group/2
, end_per_group/2
, init_per_testcase/2
, end_per_testcase/2
]).
%% test cases
-export([ init_counter/1
, incr/1
, check1/1
, check2/1
, check3/1
, init_worker/1
, append/1
, checkl1/1
, checkl2/1
, checkl3/1
]).
-include_lib("stdlib/include/assert.hrl").
all() ->
[
{group, statefuns}
, {group, workers}
].
groups() ->
[ {statefuns, [sequence], [ init_counter
, incr
, check1 %% state = 1
, incr
, check2 %% state = 2
, incr
, check3 %% state = 3
]}
, {workers, [sequence], [ init_counter
, init_worker
, append
, checkl1 %% [A0]
, append
, checkl2 %% [A0, A1]
, append
, checkl3 %% [A0, A1, A2]
]}
].
init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
ok.
init_per_group(_Grp, Config) ->
ok = application:start(gm_ctflow, permanent),
Config.
end_per_group(_Grp, _Config) ->
ok = application:stop(gm_ctflow),
ok.
init_per_testcase(_Case, Config) ->
Config.
end_per_testcase(_Case, _Config) ->
ok.
%% ======================================================================
%% This is our 'ctflow_fun' instance, which floats above some simple
%% test cases. In this test suite, we only exercise the flow funs, but
%% in a normal test suite, we would use them for information that isn't
%% easily threaded through the sequence of cases otherwise.
%%
init_counter(_Cfg) ->
gm_ctflow_fun:new(my_counter, fun ctr/2, 0),
ok.
incr(_Cfg) ->
Res = gm_ctflow_fun:call(my_counter, incr),
?assert(is_integer(Res)),
ok.
check1(_Cfg) -> check_(1).
check2(_Cfg) -> check_(2).
check3(_Cfg) -> check_(3).
check_(N) ->
?assertEqual(N, gm_ctflow_fun:get_state(my_counter)),
ok.
%% This is the actual fun
ctr(incr, N) ->
NewN = N+1,
{ok, NewN, NewN}.
%% ======================================================================
%% Here, we make use of the `gm_ctflow_worker` it's a complete process
%% (a gen_server, whose logic we instrument with the fun we provice).
%% For a bit of variety, we re-use the `ctr` fun, and at the same time,
%% ensure that stopping and restarting the `gm_ctflow` app clears the state.
%% (See `init_per_group/2` and `end_per_group/2`).
%%
%% Note that the worker is initiated using a fun/0, which in its turn is
%% expected to provide the fun/3 for the gen_server callback logic.
%% This is so that we can actually perform some actions at init time.
%%
init_worker(_Cfg) ->
{ok, Pid} = gm_ctflow_worker:start(my_list, fun() -> {ok, fun lfun/3, []} end),
true = is_pid(Pid),
ok.
append(_Cfg) ->
C = gm_ctflow_fun:call(my_counter, incr),
Res = gm_ctflow_worker:call(my_list, {append, {a, C}}),
?assert(is_list(Res)),
ok.
checkl1(_Cfg) -> checkl_([{a,1}]).
checkl2(_Cfg) -> checkl_([{a,1},{a,2}]).
checkl3(_Cfg) -> checkl_([{a,1},{a,2},{a,3}]).
checkl_(L) ->
?assertEqual(L, gm_ctflow_worker:get_state(my_list)),
ok.
lfun({call,_From}, {append, Item}, L) ->
NewL = L ++ [Item],
{reply, NewL, NewL}.