1%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- 2%% ex: ts=4 sw=4 et 3-module(rebar_xref_eunit). 4 5-include_lib("eunit/include/eunit.hrl"). 6 7-define(REBAR_SCRIPT, "../rebar"). 8 9-define(TMP_DIR, "tmp_xref_eunit/"). 10 11xref_test_() -> 12 {"Test the various xref warnings", 13 setup, fun() -> setup_project(false), rebar("compile"), rebar("skip_deps=true xref") end, 14 fun teardown/1, 15 fun(RebarOut) -> 16 [ 17 {"Undefined function", ?_assert(string:str(RebarOut, 18 "myapp_somemod:notavailable/1 is undefined function") =/= 0)}, 19 {"Undefined function call", ?_assert(string:str(RebarOut, 20 "myapp_othermod:somefunc/0 calls undefined function myapp_somemod:notavailable/1") =/= 0)}, 21 {"Deprecated function", ?_assert(string:str(RebarOut, 22 "myapp_mymod:fdeprecated/0 is deprecated function") =/= 0)}, 23 {"Deprecated function call", ?_assert(string:str(RebarOut, 24 "myapp_othermod:somefunc/0 calls deprecated function myapp_mymod:fdeprecated/0") =/= 0)}, 25 {"Unused local", ?_assert(string:str(RebarOut, 26 "myapp_mymod:localfunc2/0 is unused local function") =/= 0)}, 27 {"Unused export 1", ?_assert(string:str(RebarOut, 28 "myapp_behaviour1:behaviour_info/1 is unused export") =/= 0)}, 29 {"Unused export 2", ?_assert(string:str(RebarOut, 30 "myapp_behaviour2:behaviour_info/1 is unused export") =/= 0)}, 31 {"Unused export 3", ?_assert(string:str(RebarOut, 32 "myapp_mymod:other2/1 is unused export") =/= 0)}, 33 {"Unused export 4", ?_assert(string:str(RebarOut, 34 "myapp_othermod:somefunc/0 is unused export") =/= 0)}, 35 {"Suppressed behaviour export 1", ?_assert(string:str(RebarOut, 36 "myapp_mymod:bh1_a/1 is unused export") =:= 0)}, 37 {"Suppressed behaviour export 2", ?_assert(string:str(RebarOut, 38 "myapp_mymod:bh1_b/1 is unused export") =:= 0)}, 39 {"Suppressed behaviour export 3", ?_assert(string:str(RebarOut, 40 "myapp_mymod:bh2_a/1 is unused export") =:= 0)}, 41 {"Suppressed behaviour export 4", ?_assert(string:str(RebarOut, 42 "myapp_mymod:bh2_b/1 is unused export") =:= 0)} 43 ] 44 end}. 45 46xref_ignore_test_() -> 47 {"Test the suppression of xref warnings", 48 setup, fun() -> setup_project(ignore_xref), rebar("compile"), rebar("skip_deps=true xref") end, 49 fun teardown/1, 50 fun(RebarOut) -> 51 [ 52 {"Undefined function can not be suppressed.", ?_assert(string:str(RebarOut, 53 "myapp_somemod:notavailable/1 is undefined function") =/= 0)}, 54 {"Supppressed undefined function call", ?_assert(string:str(RebarOut, 55 "myapp_othermod:somefunc/0 calls undefined function myapp_somemod:notavailable/1") =:= 0)}, 56 {"Supppressed deprecated function", ?_assert(string:str(RebarOut, 57 "myapp_mymod:fdeprecated/0 is deprecated function") =:= 0)}, 58 {"Supppressed deprecated function call", ?_assert(string:str(RebarOut, 59 "myapp_othermod:somefunc/0 calls deprecated function myapp_mymod:fdeprecated/0") =:= 0)}, 60 {"Supppressed unused local", ?_assert(string:str(RebarOut, 61 "myapp_mymod:localfunc2/0 is unused local function") =:= 0)}, 62 {"Supppressed unused export 1", ?_assert(string:str(RebarOut, 63 "myapp_behaviour1:behaviour_info/1 is unused export") =:= 0)}, 64 {"Supppressed unused export 2", ?_assert(string:str(RebarOut, 65 "myapp_behaviour2:behaviour_info/1 is unused export") =:= 0)}, 66 {"Supppressed unused export 3", ?_assert(string:str(RebarOut, 67 "myapp_mymod:other2/1 is unused export") =:= 0)}, 68 {"Supppressed unused export 4", ?_assert(string:str(RebarOut, 69 "myapp_othermod:somefunc/0 is unused export") =:= 0)}, 70 {"Suppressed behaviour export 1", ?_assert(string:str(RebarOut, 71 "myapp_mymod:bh1_a/1 is unused export") =:= 0)}, 72 {"Suppressed behaviour export 2", ?_assert(string:str(RebarOut, 73 "myapp_mymod:bh1_b/1 is unused export") =:= 0)}, 74 {"Suppressed behaviour export 3", ?_assert(string:str(RebarOut, 75 "myapp_mymod:bh2_a/1 is unused export") =:= 0)}, 76 {"Suppressed behaviour export 4", ?_assert(string:str(RebarOut, 77 "myapp_mymod:bh2_b/1 is unused export") =:= 0)} 78 ] 79 80 end}. 81 82 83%% ==================================================================== 84%% Setup and Teardown 85%% ==================================================================== 86 87-define(myapp_behaviour1, 88 ["-module(myapp_behaviour1).\n", 89 "-export([behaviour_info/1]).\n"]). 90-define(myapp_behaviour1_body, 91 ["behaviour_info(callbacks) -> [{bh1_a,1},{bh1_b,1}];\n", 92 "behaviour_info(_Other) -> undefined.\n"]). 93-define(myapp_behaviour1_ignorexref, 94 ["-ignore_xref({behaviour_info,1}).\n"]). 95 96-define(myapp_behaviour2, 97 ["-module(myapp_behaviour2).\n", 98 "-export([behaviour_info/1]).\n"]). 99-define(myapp_behaviour2_body, 100 ["behaviour_info(callbacks) -> [{bh2_a,1},{bh2_b,1}];\n", 101 "behaviour_info(_Other) -> undefined.\n"]). 102-define(myapp_behaviour2_ignorexref, 103 ["-ignore_xref({behaviour_info,1}).\n"]). 104 105-define(myapp_mymod, 106 ["-module(myapp_mymod).\n", 107 "-export([bh1_a/1,bh1_b/1,bh2_a/1,bh2_b/1,other1/1,other2/1,fdeprecated/0]).\n", 108 "-behaviour(myapp_behaviour1).\n", % 2 behaviours 109 "-behaviour(myapp_behaviour2).\n", 110 "-deprecated({fdeprecated,0}).\n"]). % deprecated function 111-define(myapp_mymod_body, 112 ["bh1_a(A) -> localfunc1(bh1_a, A).\n", % behaviour functions 113 "bh1_b(A) -> localfunc1(bh1_b, A).\n", 114 "bh2_a(A) -> localfunc1(bh2_a, A).\n", 115 "bh2_b(A) -> localfunc1(bh2_b, A).\n", 116 "other1(A) -> localfunc1(other1, A).\n", % regular exported functions 117 "other2(A) -> localfunc1(other2, A).\n", 118 "localfunc1(A, B) -> {A, B}.\n", % used local 119 "localfunc2() -> ok.\n", % unused local 120 "fdeprecated() -> ok.\n" % deprecated function 121 ]). 122-define(myapp_mymod_ignorexref, 123 ["-ignore_xref([{other2,1},{localfunc2,0},{fdeprecated,0}]).\n"]). 124 125 126 127-define(myapp_othermod, 128 ["-module(myapp_othermod).\n", 129 "-export([somefunc/0]).\n"]). 130-define(myapp_othermod_body, 131 ["somefunc() ->\n", 132 " myapp_mymod:other1(arg),\n", 133 " myapp_somemod:notavailable(arg),\n", 134 " myapp_mymod:fdeprecated().\n" 135 ]). 136-define(myapp_othermod_ignorexref, 137 ["-ignore_xref([{myapp_somemod,notavailable,1},{somefunc,0}]).\n", 138 "-ignore_xref({myapp_mymod,fdeprecated,0}).\n"]). 139 140 141-define(myapp_rebarconfig, 142 ["{erl_opts, [debug_info]}.\n", 143 "{xref_checks, [deprecated_function_calls,deprecated_functions,\n", 144 " undefined_function_calls,undefined_functions,\n", 145 " exports_not_used,locals_not_used]}.\n" 146 ]). 147 148setup_environment() -> 149 ok = file:make_dir(?TMP_DIR), 150 prepare_rebar_script(), 151 ok = file:set_cwd(?TMP_DIR). 152 153prepare_project() -> 154 setup_environment(), 155 rebar("create-app appid=myapp"), 156 ok = file:make_dir("ebin"). 157 158setup_project(ignore_xref) -> 159 prepare_project(), 160 ok = file:write_file("src/myapp_behaviour1.erl", ?myapp_behaviour1 ++ ?myapp_behaviour1_ignorexref ++ ?myapp_behaviour1_body), 161 ok = file:write_file("src/myapp_behaviour2.erl", ?myapp_behaviour2 ++ ?myapp_behaviour2_ignorexref++ ?myapp_behaviour2_body), 162 ok = file:write_file("src/myapp_mymod.erl", ?myapp_mymod ++ ?myapp_mymod_ignorexref ++ ?myapp_mymod_body), 163 ok = file:write_file("src/myapp_othermod.erl", ?myapp_othermod ++ ?myapp_othermod_ignorexref ++ ?myapp_othermod_body), 164 ok = file:write_file("rebar.config", ?myapp_rebarconfig); 165 166setup_project(_) -> 167 prepare_project(), 168 ok = file:write_file("src/myapp_behaviour1.erl", ?myapp_behaviour1 ++ ?myapp_behaviour1_body), 169 ok = file:write_file("src/myapp_behaviour2.erl", ?myapp_behaviour2 ++ ?myapp_behaviour2_body), 170 ok = file:write_file("src/myapp_mymod.erl", ?myapp_mymod ++ ?myapp_mymod_body), 171 ok = file:write_file("src/myapp_othermod.erl", ?myapp_othermod ++ ?myapp_othermod_body), 172 ok = file:write_file("rebar.config", ?myapp_rebarconfig). 173 174 175teardown(_) -> 176 ok = file:set_cwd(".."), 177 ok = remove_tmp_dir(). 178 179remove_tmp_dir() -> 180 ok = rebar_file_utils:rm_rf(?TMP_DIR). 181 182%% ==================================================================== 183%% Helper Functions 184%% ==================================================================== 185 186prepare_rebar_script() -> 187 Rebar = ?TMP_DIR ++ "rebar", 188 {ok, _} = file:copy(?REBAR_SCRIPT, Rebar), 189 case os:type() of 190 {unix, _} -> 191 [] = os:cmd("chmod u+x " ++ Rebar); 192 {win32, _} -> 193 {ok, _} = file:copy(?REBAR_SCRIPT ++ ".cmd", 194 ?TMP_DIR ++ "rebar.cmd") 195 end. 196 197rebar(Args) when is_list(Args) -> 198 Out = os:cmd(filename:nativename("./rebar") ++ " " ++ Args), 199 %% ?debugMsg("**** Begin"), ?debugMsg(Out), ?debugMsg("**** End"), 200 Out. 201