diff options
Diffstat (limited to 'test/rebar_xref_eunit.erl')
-rw-r--r-- | test/rebar_xref_eunit.erl | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/test/rebar_xref_eunit.erl b/test/rebar_xref_eunit.erl new file mode 100644 index 0000000..45ec283 --- /dev/null +++ b/test/rebar_xref_eunit.erl @@ -0,0 +1,203 @@ +-module(rebar_xref_eunit). + +-compile(export_all). + +-include_lib("eunit/include/eunit.hrl"). + +-define(REBAR_SCRIPT, "../rebar"). + +-define(TMP_DIR, "tmp_xref_eunit/"). + +xref_test_() -> + {"Test the various xref warnings", + setup, fun() -> setup_project(false), rebar("compile"), rebar("skip_deps=true xref") end, + fun teardown/1, + fun(RebarOut) -> + [ + {"Undefined function", ?_assert(string:str(RebarOut, + "myapp_somemod:notavailable/1 is undefined function") =/= 0)}, + {"Undefined function call", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 calls undefined function myapp_somemod:notavailable/1") =/= 0)}, + {"Deprecated function", ?_assert(string:str(RebarOut, + "myapp_mymod:fdeprecated/0 is deprecated function") =/= 0)}, + {"Deprecated function call", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 calls deprecated function myapp_mymod:fdeprecated/0") =/= 0)}, + {"Unused local", ?_assert(string:str(RebarOut, + "myapp_mymod:localfunc2/0 is unused local function") =/= 0)}, + {"Unused export 1", ?_assert(string:str(RebarOut, + "myapp_behaviour1:behaviour_info/1 is unused export") =/= 0)}, + {"Unused export 2", ?_assert(string:str(RebarOut, + "myapp_behaviour2:behaviour_info/1 is unused export") =/= 0)}, + {"Unused export 3", ?_assert(string:str(RebarOut, + "myapp_mymod:other2/1 is unused export") =/= 0)}, + {"Unused export 4", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 is unused export") =/= 0)}, + {"Suppressed behaviour export 1", ?_assert(string:str(RebarOut, + "myapp_mymod:bh1_a/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 2", ?_assert(string:str(RebarOut, + "myapp_mymod:bh1_b/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 3", ?_assert(string:str(RebarOut, + "myapp_mymod:bh2_a/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 4", ?_assert(string:str(RebarOut, + "myapp_mymod:bh2_b/1 is unused export") =:= 0)} + ] + end}. + +xref_ignore_test_() -> + {"Test the suppression of xref warnings", + setup, fun() -> setup_project(ignore_xref), rebar("compile"), rebar("skip_deps=true xref") end, + fun teardown/1, + fun(RebarOut) -> + [ + {"Undefined function can not be suppressed.", ?_assert(string:str(RebarOut, + "myapp_somemod:notavailable/1 is undefined function") =/= 0)}, + {"Supppressed undefined function call", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 calls undefined function myapp_somemod:notavailable/1") =:= 0)}, + {"Supppressed deprecated function", ?_assert(string:str(RebarOut, + "myapp_mymod:fdeprecated/0 is deprecated function") =:= 0)}, + {"Supppressed deprecated function call", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 calls deprecated function myapp_mymod:fdeprecated/0") =:= 0)}, + {"Supppressed unused local", ?_assert(string:str(RebarOut, + "myapp_mymod:localfunc2/0 is unused local function") =:= 0)}, + {"Supppressed unused export 1", ?_assert(string:str(RebarOut, + "myapp_behaviour1:behaviour_info/1 is unused export") =:= 0)}, + {"Supppressed unused export 2", ?_assert(string:str(RebarOut, + "myapp_behaviour2:behaviour_info/1 is unused export") =:= 0)}, + {"Supppressed unused export 3", ?_assert(string:str(RebarOut, + "myapp_mymod:other2/1 is unused export") =:= 0)}, + {"Supppressed unused export 4", ?_assert(string:str(RebarOut, + "myapp_othermod:somefunc/0 is unused export") =:= 0)}, + {"Suppressed behaviour export 1", ?_assert(string:str(RebarOut, + "myapp_mymod:bh1_a/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 2", ?_assert(string:str(RebarOut, + "myapp_mymod:bh1_b/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 3", ?_assert(string:str(RebarOut, + "myapp_mymod:bh2_a/1 is unused export") =:= 0)}, + {"Suppressed behaviour export 4", ?_assert(string:str(RebarOut, + "myapp_mymod:bh2_b/1 is unused export") =:= 0)} + ] + + end}. + + +%% ==================================================================== +%% Setup and Teardown +%% ==================================================================== + +-define(myapp_behaviour1, + ["-module(myapp_behaviour1).\n", + "-export([behaviour_info/1]).\n"]). +-define(myapp_behaviour1_body, + ["behaviour_info(callbacks) -> [{bh1_a,1},{bh1_b,1}];\n", + "behaviour_info(_Other) -> undefined.\n"]). +-define(myapp_behaviour1_ignorexref, + ["-ignore_xref({behaviour_info,1}).\n"]). + +-define(myapp_behaviour2, + ["-module(myapp_behaviour2).\n", + "-export([behaviour_info/1]).\n"]). +-define(myapp_behaviour2_body, + ["behaviour_info(callbacks) -> [{bh2_a,1},{bh2_b,1}];\n", + "behaviour_info(_Other) -> undefined.\n"]). +-define(myapp_behaviour2_ignorexref, + ["-ignore_xref({behaviour_info,1}).\n"]). + +-define(myapp_mymod, + ["-module(myapp_mymod).\n", + "-export([bh1_a/1,bh1_b/1,bh2_a/1,bh2_b/1,other1/1,other2/1,fdeprecated/0]).\n", + "-behaviour(myapp_behaviour1).\n", % 2 behaviours + "-behaviour(myapp_behaviour2).\n", + "-deprecated({fdeprecated,0}).\n"]). % deprecated function +-define(myapp_mymod_body, + ["bh1_a(A) -> localfunc1(bh1_a, A).\n", % behaviour functions + "bh1_b(A) -> localfunc1(bh1_b, A).\n", + "bh2_a(A) -> localfunc1(bh2_a, A).\n", + "bh2_b(A) -> localfunc1(bh2_b, A).\n", + "other1(A) -> localfunc1(other1, A).\n", % regular exported functions + "other2(A) -> localfunc1(other2, A).\n", + "localfunc1(A, B) -> {A, B}.\n", % used local + "localfunc2() -> ok.\n", % unused local + "fdeprecated() -> ok.\n" % deprecated function + ]). +-define(myapp_mymod_ignorexref, + ["-ignore_xref([{other2,1},{localfunc2,0},{fdeprecated,0}]).\n"]). + + + +-define(myapp_othermod, + ["-module(myapp_othermod).\n", + "-export([somefunc/0]).\n"]). +-define(myapp_othermod_body, + ["somefunc() ->\n", + " myapp_mymod:other1(arg),\n", + " myapp_somemod:notavailable(arg),\n", + " myapp_mymod:fdeprecated().\n" + ]). +-define(myapp_othermod_ignorexref, + ["-ignore_xref([{myapp_somemod,notavailable,1},{somefunc,0}]).\n", + "-ignore_xref({myapp_mymod,fdeprecated,0}).\n"]). + + +-define(myapp_rebarconfig, + ["{erl_opts, [debug_info]}.\n", + "{xref_checks, [deprecated_function_calls,deprecated_functions,\n", + " undefined_function_calls,undefined_functions,\n", + " exports_not_used,locals_not_used]}.\n" + ]). + +setup_environment() -> + ok = file:make_dir(?TMP_DIR), + prepare_rebar_script(), + ok = file:set_cwd(?TMP_DIR). + +prepare_project() -> + setup_environment(), + rebar("create-app appid=myapp"), + ok = file:make_dir("ebin"). + +setup_project(ignore_xref) -> + prepare_project(), + ok = file:write_file("src/myapp_behaviour1.erl", ?myapp_behaviour1 ++ ?myapp_behaviour1_ignorexref ++ ?myapp_behaviour1_body), + ok = file:write_file("src/myapp_behaviour2.erl", ?myapp_behaviour2 ++ ?myapp_behaviour2_ignorexref++ ?myapp_behaviour2_body), + ok = file:write_file("src/myapp_mymod.erl", ?myapp_mymod ++ ?myapp_mymod_ignorexref ++ ?myapp_mymod_body), + ok = file:write_file("src/myapp_othermod.erl", ?myapp_othermod ++ ?myapp_othermod_ignorexref ++ ?myapp_othermod_body), + ok = file:write_file("rebar.config", ?myapp_rebarconfig); + +setup_project(_) -> + prepare_project(), + ok = file:write_file("src/myapp_behaviour1.erl", ?myapp_behaviour1 ++ ?myapp_behaviour1_body), + ok = file:write_file("src/myapp_behaviour2.erl", ?myapp_behaviour2 ++ ?myapp_behaviour2_body), + ok = file:write_file("src/myapp_mymod.erl", ?myapp_mymod ++ ?myapp_mymod_body), + ok = file:write_file("src/myapp_othermod.erl", ?myapp_othermod ++ ?myapp_othermod_body), + ok = file:write_file("rebar.config", ?myapp_rebarconfig). + + +teardown(_) -> + ok = file:set_cwd(".."), + ok = remove_tmp_dir(). + +remove_tmp_dir() -> + ok = rebar_file_utils:rm_rf(?TMP_DIR). + +%% ==================================================================== +%% Helper Functions +%% ==================================================================== + +prepare_rebar_script() -> + Rebar = ?TMP_DIR ++ "rebar", + {ok, _} = file:copy(?REBAR_SCRIPT, Rebar), + case os:type() of + {unix, _} -> + [] = os:cmd("chmod u+x " ++ Rebar); + {win32, _} -> + {ok, _} = file:copy(?REBAR_SCRIPT ++ ".bat", + ?TMP_DIR ++ "rebar.bat") + end. + +rebar() -> + rebar([]). + +rebar(Args) when is_list(Args) -> + Out = os:cmd(filename:nativename("./rebar") ++ " " ++ Args), + %% ?debugMsg("**** Begin"), ?debugMsg(Out), ?debugMsg("**** End"), + Out. |