Initial commit
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
-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}.
|
||||
Reference in New Issue
Block a user