diff options
Diffstat (limited to 'learn-you-some-erlang/tests')
24 files changed, 1059 insertions, 0 deletions
diff --git a/learn-you-some-erlang/tests/calc_tests.erl b/learn-you-some-erlang/tests/calc_tests.erl new file mode 100644 index 0000000..4f6f530 --- /dev/null +++ b/learn-you-some-erlang/tests/calc_tests.erl @@ -0,0 +1,6 @@ +-module(calc_tests). +-include_lib("eunit/include/eunit.hrl"). + +%% runs the unit test function defined in calc.erl +all_test() -> + ?assert(ok =:= calc:rpn_test()). diff --git a/learn-you-some-erlang/tests/cases_tests.erl b/learn-you-some-erlang/tests/cases_tests.erl new file mode 100644 index 0000000..5b7bd0b --- /dev/null +++ b/learn-you-some-erlang/tests/cases_tests.erl @@ -0,0 +1,24 @@ +-module(cases_tests). +-include_lib("eunit/include/eunit.hrl"). + +insert_test_() -> + [?_assertEqual([1], cases:insert(1,[])), + ?_assertEqual([1], cases:insert(1,[1])), + ?_assertEqual([1,2], cases:insert(1,[2]))]. + +beach_test_() -> + [?_assertEqual('favorable', cases:beach({celsius, 20})), + ?_assertEqual('favorable', cases:beach({celsius, 45})), + ?_assertEqual('avoid beach', cases:beach({celsius, 46})), + ?_assertEqual('avoid beach', cases:beach({celsius, 19})), + ?_assertEqual('scientifically favorable', cases:beach({kelvin, 293})), + ?_assertEqual('scientifically favorable', cases:beach({kelvin, 318})), + ?_assertEqual('avoid beach', cases:beach({kelvin, 292})), + ?_assertEqual('avoid beach', cases:beach({celsius, 319})), + ?_assertEqual('favorable in the US', + cases:beach({fahrenheit, 68})), + ?_assertEqual('favorable in the US', + cases:beach({fahrenheit, 113})), + ?_assertEqual('avoid beach', cases:beach({fahrenheit, 67})), + ?_assertEqual('avoid beach', cases:beach({fahrenheit, 114})), + ?_assertEqual('avoid beach', cases:beach(cat))]. diff --git a/learn-you-some-erlang/tests/cat_fsm_tests.erl b/learn-you-some-erlang/tests/cat_fsm_tests.erl new file mode 100644 index 0000000..aa4b940 --- /dev/null +++ b/learn-you-some-erlang/tests/cat_fsm_tests.erl @@ -0,0 +1,21 @@ +-module(cat_fsm_tests). +-include_lib("eunit/include/eunit.hrl"). + +cat_fsm_test_() -> + {setup, fun setup/0, fun teardown/1, fun state_test_/1}. + +setup() -> + cat_fsm:start(). + +teardown(Pid) -> + exit(Pid, end_test). + +state_test_(Pid) -> + [?_assertEqual(dont_give_crap, get_state(Pid)), + ?_assertEqual({ok, meh}, cat_fsm:event(Pid, event)), + ?_assertEqual(dont_give_crap, get_state(Pid))]. + +get_state(Pid) -> + List = erlang:process_info(Pid), + {_, {_Mod, Fn, _Arity}} = lists:keyfind(current_function, 1, List), + Fn. diff --git a/learn-you-some-erlang/tests/dog_fsm_tests.erl b/learn-you-some-erlang/tests/dog_fsm_tests.erl new file mode 100644 index 0000000..7217244 --- /dev/null +++ b/learn-you-some-erlang/tests/dog_fsm_tests.erl @@ -0,0 +1,81 @@ +-module(dog_fsm_tests). +-include_lib("eunit/include/eunit.hrl"). + +bark_test_() -> + {foreach, + fun setup_bark/0, + fun teardown/1, + [fun bark_pet_test_/1, fun bark_other_test_/1]}. + +wag_tail_test_() -> + {foreach, + fun setup_wag_tail/0, + fun teardown/1, + [fun wag_pet_test_/1, fun wag_other_test_/1]}. + +sit_test_() -> + {foreach, + fun setup_sit/0, + fun teardown/1, + [fun sit_squirrel_test_/1, fun sit_other_test_/1]}. + +setup_bark() -> + Pid = dog_fsm:start(), + timer:sleep(100), + Pid. + +setup_wag_tail() -> + Pid = dog_fsm:start(), + dog_fsm:pet(Pid), + timer:sleep(100), + Pid. + +setup_sit() -> + Pid = dog_fsm:start(), + dog_fsm:pet(Pid), + dog_fsm:pet(Pid), + timer:sleep(100), + Pid. + +teardown(Pid) -> + exit(Pid, end_test). + +init_test() -> + Pid = dog_fsm:start(), + timer:sleep(100), + ?assertEqual(bark, get_state(Pid)). + +bark_pet_test_(Pid) -> + [?_assertEqual(bark, get_state(Pid)), + ?_assertEqual(pet, dog_fsm:pet(Pid)), + begin timer:sleep(100), ?_assertEqual(wag_tail, get_state(Pid)) end]. + +bark_other_test_(Pid) -> + [?_assertEqual(bark, get_state(Pid)), + ?_assertEqual(squirrel, dog_fsm:squirrel(Pid)), + begin timer:sleep(100), ?_assertEqual(bark, get_state(Pid)) end]. + +wag_pet_test_(Pid) -> + [?_assertEqual(wag_tail, get_state(Pid)), + ?_assertEqual(pet, dog_fsm:pet(Pid)), + begin timer:sleep(100), ?_assertEqual(sit, get_state(Pid)) end]. + +wag_other_test_(Pid) -> + [?_assertEqual(wag_tail, get_state(Pid)), + ?_assertEqual(squirrel, dog_fsm:squirrel(Pid)), + begin timer:sleep(100), ?_assertEqual(wag_tail, get_state(Pid)) end]. + +sit_squirrel_test_(Pid) -> + [?_assertEqual(sit, get_state(Pid)), + ?_assertEqual(squirrel, dog_fsm:squirrel(Pid)), + begin timer:sleep(100), ?_assertEqual(bark, get_state(Pid)) end]. + +sit_other_test_(Pid) -> + [?_assertEqual(sit, get_state(Pid)), + ?_assertEqual(pet, dog_fsm:pet(Pid)), + begin timer:sleep(100), ?_assertEqual(sit, get_state(Pid)) end]. + +get_state(Pid) -> + List = erlang:process_info(Pid), + {_, {_Mod, Fn, _Arity}} = lists:keyfind(current_function, 1, List), + Fn. diff --git a/learn-you-some-erlang/tests/dolphins_tests.erl b/learn-you-some-erlang/tests/dolphins_tests.erl new file mode 100644 index 0000000..670f6a2 --- /dev/null +++ b/learn-you-some-erlang/tests/dolphins_tests.erl @@ -0,0 +1,87 @@ +-module(dolphins_tests). +-include_lib("eunit/include/eunit.hrl"). +%% sorry, this test library is a bit dirty, but it should do +%% the job. + +%% cannot test dolphin1/0 for lack of any results outside of I/O. +-test_warnings([dolphin1/0]). + +dolphin2_test_() -> + [?_assertEqual("How about no?", d2_do_a_flip()), + ?_assertEqual("So long and thanks for all the fish!", + d2_fish())]. + +d2_do_a_flip() -> + Pid = spawn(dolphins, dolphin2, []), + Pid ! Pid ! {self(), do_a_flip}, + %% this function receives a message and that's it + F = fun() -> + receive + M -> M + after 500 -> + error + end + end, + %% receive the first message + Msg1 = F(), + %% only one message should be received. If the second one + %% is anything except 'error' (no message), return an error. + %% otherwise send the message for validation. + case F() of + error -> Msg1; + _ -> error + end. + +d2_fish() -> + Pid = spawn(dolphins, dolphin2, []), + Pid ! Pid ! {self(), fish}, + %% this function receives a message and that's it + F = fun() -> + receive + M -> M + after 500 -> + error + end + end, + %% receive the first message + Msg1 = F(), + %% only one message should be received. If the second one + %% is anything except 'error' (no message), return an error. + %% otherwise send the message for validation. + case F() of + error -> Msg1; + _ -> error + end. + +dolphin3_test_() -> + [?_assertEqual(["How about no?", + "How about no?", + "So long and thanks for all the fish!"], + d3())]. + +d3() -> + Pid = spawn(dolphins, dolphin3, []), + Pid ! Pid ! {self(), do_a_flip}, % both should be received + Pid ! invalid, % should be ignored, but keep the process going + Pid ! {self(), fish}, % should terminate the process + Pid ! {self(), do_a_flip}, % should return nothing + %% this function receives a message and that's it + F = fun() -> + receive + M -> M + after 500 -> + error + end + end, + %% receive the expected messages + Msg1 = F(), + Msg2 = F(), + Msg3 = F(), + Msgs = [Msg1, Msg2, Msg3], + %% Additional messages should now fail. If a message is + %% received, add it to the list and let the test fail, + %% otherwise send the normal message list. + case F() of + error -> Msgs; + M -> Msgs ++ [M] + end. diff --git a/learn-you-some-erlang/tests/exceptions_tests.erl b/learn-you-some-erlang/tests/exceptions_tests.erl new file mode 100644 index 0000000..6adfd24 --- /dev/null +++ b/learn-you-some-erlang/tests/exceptions_tests.erl @@ -0,0 +1,61 @@ +-module(exceptions_tests). +-include_lib("eunit/include/eunit.hrl"). + +throws_test_() -> + [?_assertEqual(ok, exceptions:throws(fun() -> a end)), + ?_assertException(error, {badfun, _} , exceptions:throws(a)), + ?_assertEqual({throw, caught, a}, + exceptions:throws(fun() -> throw(a) end))]. + +errors_test_() -> + [?_assertEqual(ok, exceptions:errors(fun() -> a end)), + ?_assertException(throw, + a, + exceptions:errors(fun() -> throw(a) end)), + ?_assertEqual({error, caught, a}, + exceptions:errors(fun() -> erlang:error(a) end))]. +exits_test_() -> + [?_assertEqual(ok, exceptions:exits(fun() -> a end)), + ?_assertException(error, {badfun, _}, exceptions:exits(a)), + ?_assertEqual({exit, caught, a}, + exceptions:exits(fun() -> exit(a) end))]. + +talk_test() -> + ?assertEqual("blah blah", exceptions:talk()). + +sword_test_() -> + [?_assertException(throw, slice, exceptions:sword(1)), + ?_assertException(error, cut_arm, exceptions:sword(2)), + ?_assertException(exit, cut_leg, exceptions:sword(3)), + ?_assertException(throw, punch, exceptions:sword(4)), + ?_assertException(exit, cross_bridge, exceptions:sword(5))]. + +black_knight_test_() -> + [?_assertEqual("None shall pass.", + exceptions:black_knight(fun exceptions:talk/0)), + ?_assertEqual("It is but a scratch.", + exceptions:black_knight(fun() -> exceptions:sword(1) end)), + ?_assertEqual("I've had worse.", + exceptions:black_knight(fun() -> exceptions:sword(2) end)), + ?_assertEqual("Come on you pansy!", + exceptions:black_knight(fun() -> exceptions:sword(3) end)), + ?_assertEqual("Just a flesh wound.", + exceptions:black_knight(fun() -> exceptions:sword(4) end)), + ?_assertEqual("Just a flesh wound.", + exceptions:black_knight(fun() -> exceptions:sword(5) end))]. + +whoa_test() -> + ?assertEqual({caught, throw, up}, exceptions:whoa()). + +im_impressed_test() -> + ?assertEqual({caught, throw, up}, exceptions:im_impressed()). + +catcher_test_() -> + [?_assertEqual("uh oh", exceptions:catcher(1,0)), + ?_assertEqual(1.0, exceptions:catcher(3,3)), + ?_assertEqual(2.0, exceptions:catcher(6,3))]. + +one_or_two_test_() -> + [?_assertEqual(return, exceptions:one_or_two(1)), + ?_assertEqual(return, catch exceptions:one_or_two(2)), + ?_assertException(throw, return, exceptions:one_or_two(2))]. diff --git a/learn-you-some-erlang/tests/fifo_tests.erl b/learn-you-some-erlang/tests/fifo_tests.erl new file mode 100644 index 0000000..1252a1b --- /dev/null +++ b/learn-you-some-erlang/tests/fifo_tests.erl @@ -0,0 +1,22 @@ +-module(fifo_tests). +-include_lib("eunit/include/eunit.hrl"). + +new_test() -> ?assertEqual({fifo,[],[]}, fifo:new()). + +push_test_() -> + [?_assertEqual({fifo,[1,3],[2,4]}, fifo:push({fifo,[3],[2,4]},1)), + ?_assertEqual({fifo,[2],[]}, fifo:push({fifo,[],[]},2))]. + +pop_test_() -> + [?_assertEqual({3,{fifo,[],[2]}}, fifo:pop({fifo,[],[3,2]})), + ?_assertEqual({3,{fifo,[],[2]}}, fifo:pop({fifo,[2,3],[]})), + ?_assertEqual({3,{fifo,[2,1],[]}},fifo:pop({fifo,[2,1],[3]})), + ?_assertEqual({1,{fifo,[],[2,3]}}, + fifo:pop(fifo:push(fifo:push(fifo:push(fifo:new(),1),2),3))), + ?_assertError('empty fifo', fifo:pop({fifo,[],[]}))]. + +empty_test_() -> + [?_assertEqual(true, fifo:empty(fifo:new())), + ?_assertEqual(false, fifo:empty({fifo,[1],[]})), + ?_assertEqual(false, fifo:empty({fifo,[],[1]})), + ?_assertEqual(false, fifo:empty({fifo,[1],[2]}))]. diff --git a/learn-you-some-erlang/tests/functions_tests.erl b/learn-you-some-erlang/tests/functions_tests.erl new file mode 100644 index 0000000..7973b9e --- /dev/null +++ b/learn-you-some-erlang/tests/functions_tests.erl @@ -0,0 +1,27 @@ +-module(functions_tests). +-include_lib("eunit/include/eunit.hrl"). +-test_warnings([valid_time_test/0]). + +head_test() -> ?assertEqual(1, functions:head([1,2,3,4])). + +second_test() -> ?assertEqual(2, functions:second([1,2,3,4])). + +same_test_() -> + [?_assertEqual(true, functions:same(a,a)), + ?_assertEqual(true, functions:same(12,12)), + ?_assertEqual(false, functions:same(a,b)), + ?_assertEqual(false, functions:same(12.0, 12))]. + +%% no clean way to test valid_time's io stuff, so this one is p. much the +%% same thing as the main objective was to test pattern matching. +%% io:format should be used as least as possible to do testing :( +valid_time({_Date = {_Y,_M,_D}, _Time = {_H,_Min,_S}}) -> + matches; +valid_time(_) -> + nomatch. + +valid_time_test_() -> + [?_assertEqual(matches, valid_time({{2011,09,06},{09,04,43}})), + ?_assertEqual(nomatch, valid_time({{2011,09,06},{09,04}}))]. + + diff --git a/learn-you-some-erlang/tests/guards_tests.erl b/learn-you-some-erlang/tests/guards_tests.erl new file mode 100644 index 0000000..d908bcf --- /dev/null +++ b/learn-you-some-erlang/tests/guards_tests.erl @@ -0,0 +1,22 @@ +-module(guards_tests). +-include_lib("eunit/include/eunit.hrl"). + +old_enough_test_() -> + [?_assertEqual(true, guards:old_enough(16)), + ?_assertEqual(false, guards:old_enough(15)), + ?_assertEqual(false, guards:old_enough(-16))]. + +right_age_test_() -> + [?_assertEqual(true, guards:right_age(16)), + ?_assertEqual(true, guards:right_age(104)), + ?_assertEqual(true, guards:right_age(50)), + ?_assertEqual(false, guards:right_age(15)), + ?_assertEqual(false, guards:right_age(105))]. + +wrong_age_test_() -> + [?_assertEqual(false, guards:wrong_age(16)), + ?_assertEqual(false, guards:wrong_age(104)), + ?_assertEqual(false, guards:wrong_age(50)), + ?_assertEqual(true, guards:wrong_age(15)), + ?_assertEqual(true, guards:wrong_age(105))]. + diff --git a/learn-you-some-erlang/tests/hhfuns_tests.erl b/learn-you-some-erlang/tests/hhfuns_tests.erl new file mode 100644 index 0000000..c5c27cf --- /dev/null +++ b/learn-you-some-erlang/tests/hhfuns_tests.erl @@ -0,0 +1,95 @@ +-module(hhfuns_tests). +-include_lib("eunit/include/eunit.hrl"). + +one_test() -> + ?assertEqual(1, hhfuns:one()). + +two_test() -> + ?assertEqual(2, hhfuns:two()). + +add_test_() -> + [?_assertEqual(3, hhfuns:add(fun hhfuns:one/0, fun hhfuns:two/0)), + ?_assertError({badfun, _}, hhfuns:add(1,2)), + ?_assertEqual(2, hhfuns:add(fun hhfuns:one/0, fun hhfuns:one/0))]. + +increment_test() -> + ?assertEqual([1,2,3], hhfuns:increment([0,1,2])). + +decrement_test() -> + ?assertEqual([1,2,3], hhfuns:decrement([2,3,4])). + +map_test_() -> + [?_assertEqual([1,2,3], hhfuns:map(fun hhfuns:incr/1, [0,1,2])), + ?_assertEqual([1,2,3], hhfuns:map(fun hhfuns:decr/1, [2,3,4]))]. + +bases_test_() -> + [?_assertEqual(12, hhfuns:base1(3)), + ?_assertError({badmatch, _}, hhfuns:base2()), + ?_assertEqual(2, hhfuns:base3())]. + +closure_test() -> + ?assertEqual("a/0's password is pony", hhfuns:b(hhfuns:a())). + +even_test_() -> + [?_assertEqual([], hhfuns:even([])), + ?_assertEqual([], hhfuns:even([3,5,7])), + ?_assertEqual([2,4], hhfuns:even([1,2,3,4]))]. + +old_test_() -> + L = [{male,45},{female,67},{male,66},{female,12},{unkown,174},{male,74}], + [?_assertEqual([{male,66},{male,74}], hhfuns:old_men(L)), + ?_assertEqual([], hhfuns:old_men([{male,45}, {female, -54}])), + ?_assertEqual([], hhfuns:old_men([]))]. + +filter_test_() -> + L = [{male,45},{female,67},{male,66},{female,12},{unkown,174},{male,74}], + IsEven = fun(X) -> X rem 2 == 0 end, + IsOldMale = fun({Gender, Age}) -> Gender == male andalso Age > 60 end, + [?_assertEqual([], hhfuns:filter(IsEven, [])), + ?_assertEqual([], hhfuns:filter(IsEven, [3,5,7])), + ?_assertEqual([2,4], hhfuns:filter(IsEven, [1,2,3,4])), + ?_assertEqual([{male,66},{male,74}], hhfuns:filter(IsOldMale, L)), + ?_assertEqual([], hhfuns:filter(IsOldMale, [{male,45}, {female, -54}])), + ?_assertEqual([], hhfuns:filter(IsOldMale, []))]. + +max_test_() -> + [?_assertEqual(3, hhfuns:max([1,2,3])), + ?_assertEqual(-1, hhfuns:max([-10,-1,-5.5])), + ?_assertError(function_clause, hhfuns:max([]))]. + +min_test_() -> + [?_assertEqual(0, hhfuns:min([1,2,0,3])), + ?_assertEqual(-10, hhfuns:min([-10,-1,-5.5])), + ?_assertError(function_clause, hhfuns:min([]))]. + +sum_test_() -> + [?_assertEqual(0, hhfuns:sum([])), + ?_assertEqual(6, hhfuns:sum([1,2,3]))]. + +fold_test_() -> + [H|T] = [1,7,3,5,9,0,2,3], + [?_assertEqual(9, + hhfuns:fold(fun(A,B) when A > B -> A; (_,B) -> B end, H, T)), + ?_assertEqual(0, + hhfuns:fold(fun(A,B) when A < B -> A; (_,B) -> B end, H, T)), + ?_assertEqual(21, hhfuns:fold(fun(A,B) -> A + B end, 0, lists:seq(1,6)))]. + +reverse_test_() -> + [?_assertEqual([3,2,1], hhfuns:reverse([1,2,3])), + ?_assertEqual([], hhfuns:reverse([]))]. + +map2_test_() -> + [?_assertEqual([1,2,3], hhfuns:map2(fun hhfuns:incr/1, [0,1,2])), + ?_assertEqual([1,2,3], hhfuns:map2(fun hhfuns:decr/1, [2,3,4]))]. + + +filter2_test_() -> + L = [{male,45},{female,67},{male,66},{female,12},{unkown,174},{male,74}], + IsEven = fun(X) -> X rem 2 == 0 end, + IsOldMale = fun({Gender, Age}) -> Gender == male andalso Age > 60 end, + [?_assertEqual([], hhfuns:filter2(IsEven, [])), + ?_assertEqual([], hhfuns:filter2(IsEven, [3,5,7])), + ?_assertEqual([2,4], hhfuns:filter2(IsEven, [1,2,3,4])), + ?_assertEqual([{male,66},{male,74}], hhfuns:filter2(IsOldMale, L)), + ?_assertEqual([], hhfuns:filter2(IsOldMale, [{male,45}, {female, -54}])), + ?_assertEqual([], hhfuns:filter2(IsOldMale, []))]. diff --git a/learn-you-some-erlang/tests/kitchen_tests.erl b/learn-you-some-erlang/tests/kitchen_tests.erl new file mode 100644 index 0000000..821f60c --- /dev/null +++ b/learn-you-some-erlang/tests/kitchen_tests.erl @@ -0,0 +1,118 @@ +-module(kitchen_tests). +-include_lib("eunit/include/eunit.hrl"). + +fridge1_test_() -> + {"Tests fridge1 although the function is never run in the text", + {foreach, + fun() -> spawn(kitchen, fridge1, []) end, + fun(Pid) -> exit(Pid, kill) end, + [fun fridge1_store/1, + fun fridge1_take/1] + } + }. + +fridge1_store(Pid) -> + Pid ! {self(), {store, item}}, + Reply = receive_or_timeout(), + [?_assertEqual({Pid, ok}, Reply)]. + +fridge1_take(Pid) -> + Pid ! {self(), {take, item}}, + Reply = receive_or_timeout(), + [?_assertEqual({Pid, not_found}, Reply)]. + + +fridge2_test_() -> + {"Tests fridge2", + {foreach, + fun() -> spawn(kitchen, fridge2, [[]]) end, + fun(Pid) -> exit(Pid, kill) end, + [fun fridge2_store/1, + fun fridge2_take_nostore/1, + fun fridge2_take_stored/1] + } + }. + +fridge2_store(Pid) -> + Pid ! {self(), {store, item}}, + Pid ! {self(), {store, item2}}, + Reply1 = receive_or_timeout(), + Reply2 = receive_or_timeout(), + [?_assertEqual({Pid, ok}, Reply1), + ?_assertEqual({Pid, ok}, Reply2)]. + +fridge2_take_nostore(Pid) -> + Pid ! {self(), {take, item}}, + Reply = receive_or_timeout(), + [?_assertEqual({Pid, not_found}, Reply)]. + +fridge2_take_stored(Pid) -> + Pid ! {self(), {store, item}}, + _ = receive_or_timeout(), % flush the 'ok' msg + Pid ! {self(), {take, item}}, + Pid ! {self(), {take, item}}, % check if the food is removed + R1 = receive_or_timeout(), + R2 = receive_or_timeout(), + [?_assertEqual({Pid, {ok, item}}, R1), + ?_assertEqual({Pid, not_found}, R2)]. + + +abstractions_test_() -> + {"Tests the abstraction function we added to the script", + [{"Basic take/2 and store/2 abstractions. Can't test the hanging.", + {foreach, + fun() -> spawn(kitchen, fridge2, [[]]) end, + fun(Pid) -> exit(Pid, kill) end, + [fun store/1, + fun take/1] + }}, + {"Start/1 abstraction tests. Reuses the take/2 and store/2 tests.", + {foreach, + fun() -> kitchen:start([]) end, + fun(Pid) -> exit(Pid, kill) end, + [fun store/1, + fun take/1] + }}, + {"take2/2 and store2/2 tests.", + {timeout, 10, + {foreach, + fun() -> kitchen:start([]) end, + fun(Pid) -> exit(Pid, kill) end, + [fun store2/1, + fun take2/1] + } + }} + ] + }. + +store(Pid) -> + [?_assertEqual(ok, kitchen:store(Pid, item))]. + +take(Pid) -> + kitchen:store(Pid, item), + R1 = kitchen:take(Pid, item), + R2 = kitchen:take(Pid, item), + [?_assertEqual({ok, item}, R1), + ?_assertEqual(not_found, R2)]. + +store2(Pid) -> + R1 = kitchen:store2(c:pid(0,7,0), item), + R2 = kitchen:store2(Pid, item), + [?_assertEqual(timeout, R1), + ?_assertEqual(ok, R2)]. + +take2(Pid) -> + kitchen:store2(Pid, item), + R1 = kitchen:take2(c:pid(0,7,0), item), + R2 = kitchen:take2(Pid, item), + R3 = kitchen:take2(Pid, item), + [?_assertEqual(timeout, R1), + ?_assertEqual({ok, item}, R2), + ?_assertEqual(not_found, R3)]. + +receive_or_timeout() -> + receive + M -> M + after 1000 -> + timeout + end. diff --git a/learn-you-some-erlang/tests/kitty_gen_server_tests.erl b/learn-you-some-erlang/tests/kitty_gen_server_tests.erl new file mode 100644 index 0000000..e167158 --- /dev/null +++ b/learn-you-some-erlang/tests/kitty_gen_server_tests.erl @@ -0,0 +1,19 @@ +-module(kitty_gen_server_tests). +-record(cat, {name, color=green, description}). % stolen from kitty_gen_server.erl +-include_lib("eunit/include/eunit.hrl"). +-define(CAT1, #cat{name=a, color=b, description=c}). +-define(CAT2, #cat{name=d, color=e, description=f}). + +order_test() -> + {ok, Pid} = kitty_gen_server:start_link(), + ?assertEqual(?CAT1, kitty_gen_server:order_cat(Pid, a, b, c)), + ?assertEqual(?CAT2, kitty_gen_server:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_gen_server:close_shop(Pid)). + +return_test() -> + {ok, Pid} = kitty_gen_server:start_link(), + ?assertEqual(ok, kitty_gen_server:return_cat(Pid, ?CAT1)), + ?assertEqual(?CAT1, kitty_gen_server:order_cat(Pid, d, e, f)), + ?assertEqual(?CAT2, kitty_gen_server:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_gen_server:close_shop(Pid)). + diff --git a/learn-you-some-erlang/tests/kitty_server2_tests.erl b/learn-you-some-erlang/tests/kitty_server2_tests.erl new file mode 100644 index 0000000..a41594a --- /dev/null +++ b/learn-you-some-erlang/tests/kitty_server2_tests.erl @@ -0,0 +1,23 @@ +-module(kitty_server2_tests). +-record(cat, {name, color=green, description}). % stolen from kitty_server2.erl +-include_lib("eunit/include/eunit.hrl"). +-define(CAT1, #cat{name=a, color=b, description=c}). +-define(CAT2, #cat{name=d, color=e, description=f}). + +order_test() -> + Pid = kitty_server2:start_link(), + ?assertEqual(?CAT1, kitty_server2:order_cat(Pid, a, b, c)), + ?assertEqual(?CAT2, kitty_server2:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_server2:close_shop(Pid)). + +return_test() -> + Pid = kitty_server2:start_link(), + ?assertEqual(ok, kitty_server2:return_cat(Pid, ?CAT1)), + ?assertEqual(?CAT1, kitty_server2:order_cat(Pid, d, e, f)), + ?assertEqual(?CAT2, kitty_server2:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_server2:close_shop(Pid)). + +close_noproc_test() -> + DeadPid = spawn_link(fun() -> ok end), + timer:sleep(100), + ?assertError(noproc, kitty_server2:close_shop(DeadPid)). diff --git a/learn-you-some-erlang/tests/kitty_server_tests.erl b/learn-you-some-erlang/tests/kitty_server_tests.erl new file mode 100644 index 0000000..47b2561 --- /dev/null +++ b/learn-you-some-erlang/tests/kitty_server_tests.erl @@ -0,0 +1,23 @@ +-module(kitty_server_tests). +-record(cat, {name, color=green, description}). % stolen from kitty_server.erl +-include_lib("eunit/include/eunit.hrl"). +-define(CAT1, #cat{name=a, color=b, description=c}). +-define(CAT2, #cat{name=d, color=e, description=f}). + +order_test() -> + Pid = kitty_server:start_link(), + ?assertEqual(?CAT1, kitty_server:order_cat(Pid, a, b, c)), + ?assertEqual(?CAT2, kitty_server:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_server:close_shop(Pid)). + +return_test() -> + Pid = kitty_server:start_link(), + ?assertEqual(ok, kitty_server:return_cat(Pid, ?CAT1)), + ?assertEqual(?CAT1, kitty_server:order_cat(Pid, d, e, f)), + ?assertEqual(?CAT2, kitty_server:order_cat(Pid, d, e, f)), + ?assertEqual(ok, kitty_server:close_shop(Pid)). + +close_noproc_test() -> + DeadPid = spawn_link(fun() -> ok end), + timer:sleep(100), + ?assertError(noproc, kitty_server:close_shop(DeadPid)). diff --git a/learn-you-some-erlang/tests/linkmon_tests.erl b/learn-you-some-erlang/tests/linkmon_tests.erl new file mode 100644 index 0000000..a04ee27 --- /dev/null +++ b/learn-you-some-erlang/tests/linkmon_tests.erl @@ -0,0 +1,43 @@ +-module(linkmon_tests). +-include_lib("eunit/include/eunit.hrl"). + +myproc_test_() -> + {timeout, + 7, + ?_assertEqual({'EXIT', reason}, + catch linkmon:myproc())}. + +chain_test_() -> + {timeout, + 3, + ?_assertEqual(ok, chain_proc())}. + +chain_proc() -> + process_flag(trap_exit, true), + link(spawn(linkmon, chain, [3])), + receive + {'EXIT', _, "chain dies here"} -> ok + end. + +critic1_test_() -> + Critic = linkmon:start_critic(), + A = linkmon:judge(Critic, "Genesis", "The Lambda Lies Down on Broadway"), + exit(Critic, solar_storm), + B = linkmon:judge(Critic, "Genesis", "A trick of the Tail Recursion"), + [?_assertEqual("They are terrible!", A), + ?_assertEqual(timeout, B)]. + +critic2_test_() -> + catch unregister(critic), + linkmon:start_critic2(), + timer:sleep(200), + A = linkmon:judge2("The Doors", "Light my Firewall"), + exit(whereis(critic), kill), + timer:sleep(200), + B = linkmon:judge2("Rage Against the Turing Machine", "Unit Testify"), + exit(whereis(critic), shutdown), + timer:sleep(200), + C = (catch linkmon:judge2("a", "b")), + [?_assertEqual("They are terrible!", A), + ?_assertEqual("They are great!", B), + ?_assertMatch({'EXIT', {badarg, _}}, C)]. diff --git a/learn-you-some-erlang/tests/multiproc_tests.erl b/learn-you-some-erlang/tests/multiproc_tests.erl new file mode 100644 index 0000000..1020324 --- /dev/null +++ b/learn-you-some-erlang/tests/multiproc_tests.erl @@ -0,0 +1,28 @@ +-module(multiproc_tests). +-include_lib("eunit/include/eunit.hrl"). + +%% sleep's implementation is copy/pasted from the timer module. +%% not much to test to be safe. +sleep_test_() -> + [?_assertEqual(ok, multiproc:sleep(10))]. + +flush_test_() -> + {spawn, + [fun() -> + self() ! a, + self() ! b, + ok = multiproc:flush(), + self() ! c, + [?assertEqual(receive M -> M end, c)] + end]}. + +priority_test_() -> + {spawn, + [fun() -> + self() ! {15, high}, + self() ! {7, low}, + self() ! {1, low}, + self() ! {17, high}, + [?assertEqual([high, high, low, low], + multiproc:important())] + end]}. diff --git a/learn-you-some-erlang/tests/musicians_tests.erl b/learn-you-some-erlang/tests/musicians_tests.erl new file mode 100644 index 0000000..b1b4254 --- /dev/null +++ b/learn-you-some-erlang/tests/musicians_tests.erl @@ -0,0 +1,56 @@ +%% WARNING: THESE TESTS TAKE A LONG TIME TO RUN +-module(musicians_tests). +-include_lib("eunit/include/eunit.hrl"). +-define(INSTRUMENTS, [a,b,c,d,e,f,g,h]). + +rand_name_test_() -> + {"Make sure that random names are generated", + {setup, + fun setup_many_good/0, + fun teardown_many/1, + fun test_names/1}}. + +eventual_crash_test_() -> + {"Checks that bad musicians die at some point, while" + "good ones don't", + {inparallel, + [{timeout, 20000, crash()}, + {timeout, 20000, nocrash()}]}}. + +crash() -> + {ok, Pid} = musicians:start_link(drum, bad), + Ref = erlang:monitor(process, Pid), + unlink(Pid), + Rec = receive + {'DOWN', Ref, process, Pid, _R} -> ok + after 19000 -> timeout + end, + ?_assertEqual(ok, Rec). + +nocrash() -> + {ok, Pid} = musicians:start_link(carhorn, good), + Ref = erlang:monitor(process, Pid), + unlink(Pid), + Rec = receive + {'DOWN', Ref, process, Pid, _R} -> ok + after 19000 -> musicians:stop(carhorn), timeout + end, + ?_assertEqual(timeout, Rec). + +setup_many_good() -> + [element(2,musicians:start_link(X, good)) || + X <- ?INSTRUMENTS]. + +teardown_many(_) -> + [musicians:stop(X) || X <- ?INSTRUMENTS]. + +test_names(Musicians) -> + Names = [find_name(M) || M <- Musicians], + SetNames = ordsets:to_list(ordsets:from_list(Names)), + ?_assert(2 < length(SetNames)). % totally arbitrary ratio + +find_name(Inst) -> + {status, _Pid, _, [_Dict, _Status, _Ancestor, _, + [_Header, _, + {data, [{"State", {state, Name, _, _}}]}]]} = sys:get_status(Inst), + Name. diff --git a/learn-you-some-erlang/tests/oop_tests.erl b/learn-you-some-erlang/tests/oop_tests.erl new file mode 100644 index 0000000..6ea444a --- /dev/null +++ b/learn-you-some-erlang/tests/oop_tests.erl @@ -0,0 +1,16 @@ +-module(oop_tests). +-include_lib("eunit/include/eunit.hrl"). + +shell_test_() -> + Bird = oop:animal("Bird"), + Dog = oop:dog("Raptor-Dog"), + Cat = oop:cat("Sgt. McMittens"), + [?_assertEqual("living thing", Bird(type)), + ?_assertEqual("Bird eats worm", Bird({eat, "worm"})), + ?_assertEqual("Raptor-Dog says: Woof!", Dog(talk)), + ?_assertEqual("Raptor-Dog", Dog(name)), + ?_assertEqual("cat", Cat(type)), + ?_assertEqual("Raptor-Dog chases a cat named Sgt. McMittens around", + Dog({chase, Cat})), + ?_assertEqual("I'm sorry Dave, I can't do that.", Cat({play, "yarn"}))]. + diff --git a/learn-you-some-erlang/tests/records_tests.erl b/learn-you-some-erlang/tests/records_tests.erl new file mode 100644 index 0000000..327120f --- /dev/null +++ b/learn-you-some-erlang/tests/records_tests.erl @@ -0,0 +1,46 @@ +-module(records_tests). +-include_lib("eunit/include/eunit.hrl"). + +first_robot_test_() -> + ?_assertEqual(records:first_robot(), + {robot, + "Mechatron", + handmade, + undefined, + ["Moved by a small man inside"]}). + +car_factory_test_() -> + ?_assertEqual(records:car_factory("Jokeswagen"), + {robot, + "Jokeswagen", + industrial, + "building cars", + []}). + +repairman_test_() -> + ?_assertEqual(records:repairman({robot, + "Ulbert", + industrial, + ["trying to have feelings"], + []}), + {repaired, {robot, + "Ulbert", + industrial, + ["trying to have feelings"], + ["Repaired by repairman"]}}). + +admin_panel_test_() -> + [?_assertEqual(records:admin_panel({user, 1, "ferd", admin, 96}), + "ferd is allowed!"), + ?_assertEqual(records:admin_panel({user, 2, "you", users, 66}), + "you is not allowed")]. + +adult_section_test_() -> + [?_assertEqual(records:adult_section({user, 21, "Bill", users, 72}), + allowed), + ?_assertEqual(records:adult_section({user, 22, "Noah", users, 13}), + forbidden)]. + +included_test_() -> + ?_assertEqual(records:included(), + {included, "Some value", "yeah!", undefined}). diff --git a/learn-you-some-erlang/tests/recursive_tests.erl b/learn-you-some-erlang/tests/recursive_tests.erl new file mode 100644 index 0000000..554c691 --- /dev/null +++ b/learn-you-some-erlang/tests/recursive_tests.erl @@ -0,0 +1,109 @@ +-module(recursive_tests). +-include_lib("eunit/include/eunit.hrl"). + +%% those were not in the module, but yeah + +fac_test_() -> + [?_assert(24 == recursive:fac(4)), + ?_assert(1 == recursive:fac(0)), + ?_assert(1 == recursive:fac(1)), + ?_assertError(function_clause, recursive:fac(-1))]. + +tail_fac_test_() -> + [?_assert(recursive:fac(4) == recursive:tail_fac(4)), + ?_assert(recursive:fac(0) == recursive:tail_fac(0)), + ?_assert(recursive:fac(1) == recursive:tail_fac(1)), + ?_assertError(function_clause, recursive:tail_fac(-1))]. + +len_test_() -> + [?_assert(1 == recursive:len([a])), + ?_assert(0 == recursive:len([])), + ?_assert(5 == recursive:len([1,2,3,4,5]))]. + +tail_len_test_() -> + [?_assert(recursive:len([a]) == recursive:tail_len([a])), + ?_assert(recursive:len([]) == recursive:tail_len([])), + ?_assert(recursive:len([1,2,3,4,5]) == recursive:tail_len([1,2,3,4,5]))]. + +duplicate_test_() -> + [?_assert([] == recursive:duplicate(0,a)), + ?_assert([a] == recursive:duplicate(1,a)), + ?_assert([a,a,a] == recursive:duplicate(3,a))]. + +tail_duplicate_test_() -> + [?_assert(recursive:tail_duplicate(0,a) == recursive:duplicate(0,a)), + ?_assert(recursive:tail_duplicate(1,a) == recursive:duplicate(1,a)), + ?_assert(recursive:tail_duplicate(3,a) == recursive:duplicate(3,a))]. + +reverse_test_() -> + [?_assert([] == recursive:reverse([])), + ?_assert([1] == recursive:reverse([1])), + ?_assert([3,2,1] == recursive:reverse([1,2,3]))]. + +tail_reverse_test_() -> + [?_assertEqual(recursive:tail_reverse([]), + recursive:reverse([])), + ?_assertEqual(recursive:tail_reverse([1]), + recursive:reverse([1])), + ?_assertEqual(recursive:tail_reverse([1,2,3]), + recursive:reverse([1,2,3]))]. + +sublist_test_() -> + [?_assert([] == recursive:sublist([1,2,3],0)), + ?_assert([1,2] == recursive:sublist([1,2,3],2)), + ?_assert([] == recursive:sublist([], 4))]. + +tail_sublist_test_() -> + [?_assertEqual(recursive:tail_sublist([1,2,3],0), + recursive:sublist([1,2,3],0)), + ?_assertEqual(recursive:tail_sublist([1,2,3],2), + recursive:sublist([1,2,3],2)), + ?_assertEqual(recursive:tail_sublist([], 4), + recursive:sublist([], 4))]. + +zip_test_() -> + [?_assert([{a,1},{b,2},{c,3}] == recursive:zip([a,b,c],[1,2,3])), + ?_assert([] == recursive:zip([],[])), + ?_assertError(function_clause, recursive:zip([1],[1,2]))]. + +lenient_zip_test_() -> + [?_assertEqual([{a,1},{b,2},{c,3}], + recursive:lenient_zip([a,b,c],[1,2,3])), + ?_assert([] == recursive:lenient_zip([],[])), + ?_assert([{a,1}] == recursive:lenient_zip([a],[1,2]))]. + +%% exercises! +tail_zip_test_() -> + [?_assertEqual(recursive:tail_zip([a,b,c],[1,2,3]), + recursive:zip([a,b,c],[1,2,3])), + ?_assertEqual(recursive:tail_zip([],[]), + recursive:zip([],[])), + ?_assertError(function_clause, recursive:tail_zip([1],[1,2]))]. + +tail_lenient_zip_test_() -> + [?_assertEqual(recursive:tail_lenient_zip([a,b,c],[1,2,3]), + recursive:lenient_zip([a,b,c],[1,2,3])), + ?_assertEqual(recursive:tail_lenient_zip([],[]), + recursive:lenient_zip([],[])), + ?_assertEqual(recursive:tail_lenient_zip([a],[1,2]), + recursive:lenient_zip([a],[1,2]))]. + +%% quick, sort! +quicksort_test_() -> + [?_assert([] == recursive:quicksort([])), + ?_assert([1] == recursive:quicksort([1])), + ?_assert([1,2,2,4,6] == recursive:quicksort([4,2,6,2,1])), + ?_assert(" JRaceeinqqsuu" == recursive:quicksort("Jacques Requin"))]. + +lc_quicksort_test_() -> + [?_assert([] == recursive:lc_quicksort([])), + ?_assert([1] == recursive:lc_quicksort([1])), + ?_assert([1,2,2,4,6] == recursive:lc_quicksort([4,2,6,2,1])), + ?_assert(" JRaceeinqqsuu" == recursive:lc_quicksort("Jacques Requin"))]. + +bestest_qsort_test_() -> + [?_assert([] == recursive:bestest_qsort([])), + ?_assert([1] == recursive:bestest_qsort([1])), + ?_assert([1,2,2,4,6] == recursive:bestest_qsort([4,2,6,2,1])), + ?_assert(" JRaceeinqqsuu" == recursive:bestest_qsort("Jacques Requin"))]. + diff --git a/learn-you-some-erlang/tests/road_tests.erl b/learn-you-some-erlang/tests/road_tests.erl new file mode 100644 index 0000000..e99eeff --- /dev/null +++ b/learn-you-some-erlang/tests/road_tests.erl @@ -0,0 +1,33 @@ +-module(road_tests). +-include_lib("eunit/include/eunit.hrl"). +-test_warnings([main/1]). + +group_vals_test_() -> + [?_assertEqual([{a,b,x},{a,b,x}], road:group_vals([a,b,x,a,b,x],[])), + ?_assertEqual([], road:group_vals([],[])), + ?_assertError(function_clause, road:group_vals([a,b,x,a],[]))]. + +parse_map_test_() -> + [?_assertEqual([], road:parse_map("")), + ?_assertEqual([], road:parse_map(<<"">>)), + ?_assertEqual([{10,5,4}], road:parse_map("10 5 4")), + ?_assertEqual([{10,5,4},{1,2,3}], road:parse_map("10 5 4 1 2 3")), + ?_assertEqual([{10,5,4}], road:parse_map(<<"10 5 4">>)), + ?_assertEqual([{10,5,4}], road:parse_map("10\t5\n4")), + ?_assertEqual([{10,5,4},{1,2,3}], + road:parse_map("10\r\n5 4 1\t\t2\r3"))]. + +%% little testing required on this one, the optimal_path tests will +%% do it in a hidden manner. +shortest_step_test_() -> + [?_assertEqual({{1,[{a,1}]},{2,[{x,1},{a,1}]}}, + road:shortest_step({1,8,1},{{0,[]},{0,[]}}))]. + +optimal_path_test_() -> + [?_assertEqual([{b,10},{x,30},{a,5},{x,20},{b,2},{b,8}], + road:optimal_path( + road:parse_map("50 10 30 5 90 20 40 2 24 10 8 0"))), + ?_assertEqual([{a,1},{a,1},{a,1}], + road:optimal_path([{1,10,2},{1,3,3},{1,2,0}])), + ?_assertEqual([{a,1},{x,1},{b,1},{x,1},{a,1}], + road:optimal_path([{1,3,1},{4,1,1},{1,6,1}]))]. diff --git a/learn-you-some-erlang/tests/tree_tests.erl b/learn-you-some-erlang/tests/tree_tests.erl new file mode 100644 index 0000000..5a2633b --- /dev/null +++ b/learn-you-some-erlang/tests/tree_tests.erl @@ -0,0 +1,64 @@ +-module(tree_tests). +-include_lib("eunit/include/eunit.hrl"). + +empty_test() -> + ?assert({node, 'nil'} =:= tree:empty()). + +%% oh god this gets ugly +insert_test_() -> + T1 = tree:insert(a, "a", tree:empty()), + T2 = tree:insert(c, "c", T1), + T3 = tree:insert(n, "n", + tree:insert(z, "z", + tree:insert(t, "t", + tree:insert(x, "x", T2)))), + [?_assertEqual(T1, {node, {a,"a",{node,nil},{node,nil}}}), + ?_assertEqual(T2, {node, {a,"a", + {node,nil}, + {node, {c,"c",{node,nil},{node,nil}}}}}), + ?_assertEqual(T3, {node, {a,"a", + {node, nil}, + {node, {c,"c", + {node, nil}, + {node, {x,"x", + {node, {t,"t", + {node, {n,"n", + {node,nil}, + {node,nil}}}, + {node, nil}}}, + {node, {z,"z", + {node,nil}, + {node,nil}}}}}}}}})]. +%% not as bad! +lookup_test_() -> + T = tree:insert(x, "x", + tree:insert(t, "t", + tree:insert(z, "z", + tree:insert(n, "n", + tree:insert(c, "c", + tree:insert(a, "a", tree:empty())))))), + [?_assert({ok,"t"} == tree:lookup(t,T)), + ?_assert(undefined == tree:lookup(21, T)), + ?_assert(undefined == tree:lookup(a, tree:empty()))]. + +%% done with both insert and lookup +update_test_() -> + T1 = tree:insert(x, "x", + tree:insert(t, "t", + tree:insert(z, "z", + tree:insert(n, "n", + tree:insert(c, "c", + tree:insert(a, "a", tree:empty())))))), + T2 = tree:insert(x, "X", T1), + [?_assertEqual({ok, "x"}, tree:lookup(x, T1)), + ?_assertEqual({ok, "X"}, tree:lookup(x, T2))]. + +has_value_test_() -> + T1 = tree:insert(x, "x", + tree:insert(t, "t", + tree:insert(z, "z", + tree:insert(n, "n", + tree:insert(c, "c", + tree:insert(a, "a", tree:empty())))))), + [?_assertEqual(true, tree:has_value("z", T1)), + ?_assertEqual(false,tree:has_value("Z", T1))]. diff --git a/learn-you-some-erlang/tests/useless_tests.erl b/learn-you-some-erlang/tests/useless_tests.erl new file mode 100644 index 0000000..8f174be --- /dev/null +++ b/learn-you-some-erlang/tests/useless_tests.erl @@ -0,0 +1,18 @@ +-module(useless_tests). +-include_lib("eunit/include/eunit.hrl"). +-test_warnings([hello_test/0]). + +add_test_() -> + [?_assertEqual(-5, useless:add(-3, -2)), + ?_assertEqual(4, useless:add(2, 2)), + ?_assertEqual(2.5, useless:add(2.0, 0.5)), + ?_assertEqual(1, useless:add(-3, 4))]. + +hello_test() -> + ok. % no test possible for I/O. Curse you, side effects! + +greet_and_add_test_() -> + [?_assertEqual(useless:greet_and_add_two(-3), useless:add(-3, 2)), + ?_assertEqual(useless:greet_and_add_two(2), useless:add(2, 2)), + ?_assertEqual(useless:greet_and_add_two(0.5), useless:add(2, 0.5)), + ?_assertEqual(useless:greet_and_add_two(-3), useless:add(-3, 2))]. diff --git a/learn-you-some-erlang/tests/what_the_if_tests.erl b/learn-you-some-erlang/tests/what_the_if_tests.erl new file mode 100644 index 0000000..13465e9 --- /dev/null +++ b/learn-you-some-erlang/tests/what_the_if_tests.erl @@ -0,0 +1,17 @@ +-module(what_the_if_tests). +-include_lib("eunit/include/eunit.hrl"). + +heh_fine_test() -> + ?assertException(error, if_clause, what_the_if:heh_fine()). + +oh_god_test_() -> + [?_assertEqual(might_succeed, what_the_if:oh_god(2)), + ?_assertEqual(always_does, what_the_if:oh_god(3))]. + +help_me_test_() -> + [?_assertEqual({cat, "says meow!"}, what_the_if:help_me(cat)), + ?_assertEqual({beef, "says mooo!"}, what_the_if:help_me(beef)), + ?_assertEqual({dog, "says bark!"}, what_the_if:help_me(dog)), + ?_assertEqual({tree, "says bark!"}, what_the_if:help_me(tree)), + ?_assertEqual({"other", "says fgdadfgna!"}, what_the_if:help_me("other")), + ?_assertEqual({5, "says fgdadfgna!"}, what_the_if:help_me(5))]. |