1%%% -*- erlang-indent-level: 2 -*- 2%%%------------------------------------------------------------------- 3%%% Author: Kostis Sagonas 4%%% 5%%% Tests for correct handling of funs. 6%%%------------------------------------------------------------------- 7-module(basic_fun). 8 9-export([test/0]). 10 11-export([dummy_foo/4, add1/1, test_fun03/0]). 12 13test() -> 14 ok = test_calls(), 15 ok = test_is_function(), 16 ok = test_is_function2(), 17 ok. 18 19%%-------------------------------------------------------------------- 20%% Tests function and fun calls. 21 22test_calls() -> 23 ok = test_apply_call(?MODULE, dummy_foo), 24 ok = test_fun_call(fun dummy_foo/4), 25 ok = test_fun_call(fun ?MODULE:dummy_foo/4), 26 ok. 27 28test_apply_call(M, F) -> 29 M:F(bar, 42, foo, 17). 30 31test_fun_call(Fun) -> 32 Fun(bar, 42, foo, 17). 33 34dummy_foo(_, _, foo, _) -> ok. 35 36%%-------------------------------------------------------------------- 37%% Tests handling of funs out of exported functions and 2-tuple funs. 38 39test_fun03() -> 40 MFPair = add1_as_2tuple(), 41 4712 = do_call(add1_as_export(), 4711), 42 {badfun, MFPair} = try do_call(MFPair, 88) catch error:Err -> Err end, 43 true = do_guard(add1_as_export()), 44 false = do_guard(MFPair), % 2-tuples do not satisfy is_function/1 45 ok. 46 47do_call(F, X) -> F(X). 48 49do_guard(F) when is_function(F) -> true; 50do_guard(_) -> false. 51 52add1_as_export() -> fun ?MODULE:add1/1. 53 54add1_as_2tuple() -> {?MODULE, add1}. 55 56add1(X) -> X+1. 57 58%%-------------------------------------------------------------------- 59%% Tests the is_function guard and BIF. 60 61test_is_function() -> 62 Fun = fun (X, foo) -> dummy_foo(X, mnesia_lib, foo, [X]) end, 63 ok = test_when_guard(Fun), 64 ok = test_if_guard(Fun), 65 ok. 66 67test_when_guard(X) when is_function(X) -> ok. 68 69test_if_guard(X) -> 70 if is_function(X) -> ok; 71 true -> weird 72 end. 73 74%%-------------------------------------------------------------------- 75%% Tests the is_function2 guard and BIF. 76 77test_is_function2() -> 78 ok = test_guard(), 79 ok = test_guard2(), 80 ok = test_call(), 81 ok. 82 83test_guard() -> 84 zero_fun = test_f2(fun () -> ok end), 85 unary_fun = test_f2(fun(X) -> X end), 86 binary_fun = test_f2(fun (X, Y) -> {X, Y} end), 87 no_fun = test_f2(gazonk), 88 ok. 89 90test_f2(Fun) when is_function(Fun, 0) -> 91 zero_fun; 92test_f2(Fun) when is_function(Fun, 1) -> 93 unary_fun; 94test_f2(Fun) when is_function(Fun, 2) -> 95 binary_fun; 96test_f2(_) -> 97 no_fun. 98 99test_guard2() -> 100 zero_fun = test_f2_n(fun () -> ok end, 0), 101 unary_fun = test_f2_n(fun (X) -> X end, 1), 102 binary_fun = test_f2_n(fun (X, Y) -> {X, Y} end, 2), 103 no_fun = test_f2_n(gazonk, 0), 104 ok. 105 106test_f2_n(F, N) when is_function(F, N) -> 107 case N of 108 0 -> zero_fun; 109 1 -> unary_fun; 110 2 -> binary_fun 111 end; 112test_f2_n(_, _) -> 113 no_fun. 114 115test_call() -> 116 true = test_fn2(fun (X, Y) -> {X,Y} end, 2), 117 false = test_fn2(fun (X, Y) -> {X,Y} end, 3), 118 false = test_fn2(gazonk, 2), 119 {'EXIT', {badarg, _TR1}} = (catch test_fn2(gazonk, gazonk)), 120 {'EXIT', {badarg, _TR2}} = (catch test_fn2(fun (X, Y) -> {X, Y} end, gazonk)), 121 ok. 122 123test_fn2(F, N) -> 124 is_function(F, N). 125