aboutsummaryrefslogtreecommitdiff
path: root/learn-you-some-erlang/reminder/src/tests/evserv_tests.erl
diff options
context:
space:
mode:
Diffstat (limited to 'learn-you-some-erlang/reminder/src/tests/evserv_tests.erl')
-rw-r--r--learn-you-some-erlang/reminder/src/tests/evserv_tests.erl203
1 files changed, 203 insertions, 0 deletions
diff --git a/learn-you-some-erlang/reminder/src/tests/evserv_tests.erl b/learn-you-some-erlang/reminder/src/tests/evserv_tests.erl
new file mode 100644
index 0000000..b093a58
--- /dev/null
+++ b/learn-you-some-erlang/reminder/src/tests/evserv_tests.erl
@@ -0,0 +1,203 @@
+-module(evserv_tests).
+-include_lib("eunit/include/eunit.hrl").
+-define(FUTURE_DATE, {{2100,1,1},{0,0,0}}).
+%% all the tests in this module would be much easier with property-based testing.
+%% see Triq, Quvic Quickcheck or Proper for libraries to download that let you
+%% do this.
+-test_warnings([start/0]).
+
+valid_time_test_() ->
+ [?_assert(evserv:valid_time({0,0,0})),
+ ?_assert(evserv:valid_time({23,59,59})),
+ ?_assert(not evserv:valid_time({23,59,60})),
+ ?_assert(not evserv:valid_time({23,60,59})),
+ ?_assert(not evserv:valid_time({24,59,59})),
+ ?_assert(not evserv:valid_time({-1,0,0})),
+ ?_assert(not evserv:valid_time({0,-1,0})),
+ ?_assert(not evserv:valid_time({0,0,-1}))].
+
+valid_datetime_test_() ->
+ [?_assert(evserv:valid_datetime({{0,1,1},{0,0,0}})),
+ ?_assert(evserv:valid_datetime({{2004,2,29},{23,59,59}})),
+ ?_assert(evserv:valid_datetime({{2004,12,31},{23,59,59}})),
+ ?_assert(not evserv:valid_datetime({{2004,12,31},{23,60,60}})),
+ ?_assert(not evserv:valid_datetime({{2003,2,29},{23,59,59}})),
+ ?_assert(not evserv:valid_datetime({{0,0,0},{0,0,0}})),
+ ?_assert(not evserv:valid_datetime(1209312303))].
+
+loop_test_() ->
+ {"Testing all server events on a protocol level",
+ [{"Subscribe Tests",
+ [{spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun subscribe/1}},
+ {spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun subscribe2/1}},
+ {spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun down/1}}]},
+ {"Adding event integration tests",
+ [{spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun add/1}},
+ {spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun addremove/1}},
+ {spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun done/1}}]}]}.
+
+interface_test_() ->
+ {"Testing all server events via the interface functions",
+ [{spawn,
+ {setup,
+ fun evserv:start_link/0,
+ fun terminate/1,
+ fun interface/1}}]}.
+
+subscribe(Pid) ->
+ Ref = make_ref(),
+ S = self(),
+ Pid ! {S, Ref, {subscribe, S}},
+ {ok, M1} = read(),
+ Pid ! {S, debug},
+ {ok, M2} = read(),
+ [?_assertEqual({Ref, ok}, M1),
+ ?_assertMatch({state,[], [{_, S}]}, M2)].
+
+subscribe2(Pid) ->
+ Ref1 = make_ref(),
+ Ref2 = make_ref(),
+ S = self(),
+ Pid ! {S, Ref1, {subscribe, S}},
+ {ok, M1} = read(),
+ Pid ! {S, Ref2, {subscribe, S}},
+ {ok, M2} = read(),
+ Pid ! {S, debug},
+ {ok, M3} = read(),
+ [?_assertEqual({Ref1, ok}, M1),
+ ?_assertEqual({Ref2, ok}, M2),
+ ?_assertMatch({state,[], [{_,S},{_,S}]}, M3)].
+
+down(Pid) ->
+ Ref = make_ref(),
+ ClientPid = spawn(fun() -> timer:sleep(50000) end),
+ Pid ! {self(), debug},
+ {ok, S1} = read(),
+ Pid ! {self(), Ref, {subscribe, ClientPid}},
+ {ok, M1} = read(),
+ Pid ! {self(), debug},
+ {ok, S2} = read(),
+ exit(ClientPid, testkill),
+ timer:sleep(100),
+ Pid ! {self(), debug},
+ {ok, S3} = read(),
+ [?_assertMatch({state, _, []}, S1),
+ ?_assertEqual({Ref, ok}, M1),
+ ?_assertMatch({state, _, [{_,ClientPid}]}, S2),
+ ?_assertEqual(S1, S3)].
+
+add(Pid) ->
+ Ref1 = make_ref(),
+ Ref2 = make_ref(),
+ Pid ! {self(), Ref1, {add, "test", "a test event", ?FUTURE_DATE}},
+ {ok, M1} = read(),
+ Pid ! {self(), Ref2, {add, "test", "a test event2", wrong_date}},
+ {ok, M2} = read(),
+ [?_assertEqual({Ref1, ok}, M1),
+ ?_assertEqual({Ref2, {error, bad_timeout}}, M2)].
+
+addremove(Pid) ->
+ Ref1 = make_ref(),
+ Ref2 = make_ref(),
+ Ref3 = make_ref(),
+ %% ask for useless deletion, check the state
+ Pid ! {self(), Ref1, {cancel, "nonexist"}},
+ {ok, M1} = read(),
+ Pid ! {self(), debug},
+ {ok, State1} = read(),
+ %% add an event, check the state
+ Pid ! {self(), Ref2, {add, "test", "a test event", ?FUTURE_DATE}},
+ {ok, M2} = read(),
+ Pid ! {self(), debug},
+ {ok, State2} = read(),
+ %% remove the event, check the state
+ Pid ! {self(), Ref3, {cancel, "test"}},
+ {ok, M3} = read(),
+ Pid ! {self(), debug},
+ {ok, State3} = read(),
+ [?_assertEqual({Ref1, ok}, M1),
+ ?_assertEqual({Ref2, ok}, M2),
+ ?_assertEqual({Ref3, ok}, M3),
+ ?_assertEqual(State1, State3),
+ ?_assert(State2 =/= State3),
+ ?_assertMatch({state,[{"test", {event,"test",_,_,?FUTURE_DATE}}],_}, State2)].
+
+done(Pid) ->
+ Ref = make_ref(),
+ {ok, _} = evserv:subscribe(self()),
+ Pid ! {self(), debug},
+ {ok, S1} = read(),
+ {Date,{H,Min,S}} = calendar:local_time(),
+ DateTime = {Date,{H,Min,S+1}},
+ Pid ! {self(), Ref, {add, "test", "a test event", DateTime}},
+ {ok, M1} = read(),
+ Pid ! {self(), debug},
+ {ok, S2} = read(),
+ X = read(),
+ timer:sleep(750),
+ {ok, M2} = read(),
+ Pid ! {self(), debug},
+ {ok, S3} = read(),
+ [?_assertMatch({state, [], _}, S1),
+ ?_assertEqual({Ref, ok}, M1),
+ ?_assertMatch({state, [{"test",_}], _}, S2),
+ ?_assertEqual(timeout, X),
+ ?_assertEqual({done, "test", "a test event"}, M2),
+ ?_assertEqual(S1,S3)].
+
+interface(_Pid) ->
+ Ref = evserv:subscribe(self()),
+ {Date,{H,Min,S}} = calendar:local_time(),
+ M1 = evserv:add_event("test", "desc", {Date,{H,Min,S+1}}),
+ M2 = evserv:cancel("test"),
+ M3 = evserv:add_event("test1", "desc1", calendar:local_time()),
+ M4 = evserv:add_event2("test2", "desc2", calendar:local_time()),
+ timer:sleep(100),
+ M5 = evserv:listen(2),
+ M6 = evserv:add_event("test3", "desc3", some_atom),
+ M7 = (catch evserv:add_event2("test4", "desc4", some_atom)),
+ [?_assertMatch({ok, _}, Ref),
+ ?_assert(is_reference(element(2, Ref))),
+ ?_assertEqual(ok, M1),
+ ?_assertEqual(ok, M2),
+ ?_assertEqual(ok, M3),
+ ?_assertEqual(ok, M4),
+ ?_assertEqual([{done,"test1","desc1"},{done,"test2","desc2"}], M5),
+ ?_assertEqual({error, bad_timeout}, M6),
+ ?_assertMatch({'EXIT', {bad_timeout,_}}, M7)].
+
+
+%% helpers
+terminate(Pid) -> Pid ! shutdown.
+
+read() ->
+ receive
+ M -> {ok, M}
+ after 500 ->
+ timeout
+ end.
+