diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2015-03-24 22:16:55 -0700 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2015-03-24 22:16:55 -0700 |
commit | ab53164afbebada296c74dba0870d372e63c3f53 (patch) | |
tree | 802add27d843e4d0e4a2a965192ed52fb378fc3d | |
parent | deebd23a88e1c89647c864846dfc6a69df02b045 (diff) | |
parent | efb859f15acad73cfe2f0510a3d9bcd7958c649f (diff) |
Merge pull request #296 from talentdeficit/eunit_test_suite
eunit refactor and test suite
-rw-r--r-- | src/rebar_prv_eunit.erl | 220 | ||||
-rw-r--r-- | test/rebar_eunit_SUITE.erl | 373 | ||||
-rw-r--r-- | test/rebar_profiles_SUITE.erl | 8 | ||||
-rw-r--r-- | test/rebar_test_utils.erl | 30 |
4 files changed, 541 insertions, 90 deletions
diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index 0e0e937..6872c99 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -37,13 +37,14 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> ?INFO("Performing EUnit tests...", []), - {Opts, _} = rebar_state:command_parsed_args(State), - EUnitOpts = resolve_eunit_opts(State, Opts), - TestApps = filter_checkouts(rebar_state:project_apps(State)), - ok = compile_tests(State, TestApps), - ok = maybe_cover_compile(State, Opts), - AppsToTest = test_dirs(State, TestApps), - Result = eunit:test(AppsToTest, EUnitOpts), + case prepare_tests(State) of + {ok, Tests} -> do_tests(State, Tests); + Error -> Error + end. + +do_tests(State, Tests) -> + EUnitOpts = resolve_eunit_opts(State), + Result = eunit:test(Tests, EUnitOpts), ok = rebar_prv_cover:maybe_write_coverdata(State, ?PROVIDER), case handle_results(Result) of {error, Reason} -> @@ -58,45 +59,9 @@ format_error(unknown_error) -> format_error({error_running_tests, Reason}) -> io_lib:format("Error running tests: ~p", [Reason]). -eunit_opts(_State) -> - [{cover, $c, "cover", boolean, help(cover)}, - {verbose, $v, "verbose", boolean, help(verbose)}]. - -help(cover) -> "Generate cover data"; -help(verbose) -> "Verbose output". - -filter_checkouts(Apps) -> filter_checkouts(Apps, []). - -filter_checkouts([], Acc) -> lists:reverse(Acc); -filter_checkouts([App|Rest], Acc) -> - AppDir = filename:absname(rebar_app_info:dir(App)), - CheckoutsDir = filename:absname("_checkouts"), - case lists:prefix(CheckoutsDir, AppDir) of - true -> filter_checkouts(Rest, Acc); - false -> filter_checkouts(Rest, [App|Acc]) - end. - -resolve_eunit_opts(State, Opts) -> - EUnitOpts = rebar_state:get(State, eunit_opts, []), - case proplists:get_value(verbose, Opts, false) of - true -> set_verbose(EUnitOpts); - false -> EUnitOpts - end. - -test_dirs(State, TestApps) -> - %% we need to add "./ebin" if it exists but only if it's not already - %% due to be added - F = fun(App) -> rebar_app_info:dir(App) =/= rebar_dir:get_cwd() end, - BareEbin = filename:join([rebar_dir:base_dir(State), "ebin"]), - case lists:any(F, TestApps) andalso filelib:is_dir(BareEbin) of - false -> application_dirs(TestApps, []); - true -> [{dir, BareEbin}|application_dirs(TestApps, [])] - end. - -application_dirs([], Acc) -> lists:reverse(Acc); -application_dirs([App|Rest], Acc) -> - AppName = list_to_atom(binary_to_list(rebar_app_info:name(App))), - application_dirs(Rest, [{application, AppName}|Acc]). +%% =================================================================== +%% Internal functions +%% =================================================================== test_state(State) -> ErlOpts = rebar_state:get(State, eunit_compile_opts, []), @@ -120,14 +85,33 @@ first_files(State) -> EUnitFirst = rebar_state:get(State, eunit_first_files, []), [{erl_first_files, EUnitFirst}]. -set_verbose(Opts) -> - %% if `verbose` is already set don't set it again - case lists:member(verbose, Opts) of - true -> Opts; - false -> [verbose] ++ Opts +prepare_tests(State) -> + {RawOpts, _} = rebar_state:command_parsed_args(State), + resolve_apps(State, RawOpts). + +resolve_apps(State, RawOpts) -> + case proplists:get_value(app, RawOpts) of + undefined -> resolve_suites(State, project_apps(State), RawOpts); + %% convert app name strings to `rebar_app_info` objects + Apps -> AppNames = string:tokens(Apps, [$,]), + ProjectApps = project_apps(State), + case filter_apps_by_name(AppNames, ProjectApps) of + {ok, TestApps} -> resolve_suites(State, TestApps, RawOpts); + Error -> Error + end + end. + +resolve_suites(State, Apps, RawOpts) -> + case proplists:get_value(suite, RawOpts) of + undefined -> compile_tests(State, Apps, all, RawOpts); + Suites -> SuiteNames = string:tokens(Suites, [$,]), + case filter_suites_by_apps(SuiteNames, Apps) of + {ok, S} -> compile_tests(State, Apps, S, RawOpts); + Error -> Error + end end. -compile_tests(State, TestApps) -> +compile_tests(State, TestApps, Suites, RawOpts) -> F = fun(AppInfo) -> AppDir = rebar_app_info:dir(AppInfo), S = case rebar_app_info:state(AppInfo) of @@ -141,24 +125,80 @@ compile_tests(State, TestApps) -> ec_cnv:to_list(rebar_app_info:out_dir(AppInfo))) end, lists:foreach(F, TestApps), - case filelib:is_dir(filename:join([rebar_dir:get_cwd(), "test"])) of - true -> compile_bare_tests(State, TestApps); - false -> ok + ok = maybe_cover_compile(State, RawOpts), + {ok, test_set(TestApps, Suites)}. + +maybe_cover_compile(State, Opts) -> + State1 = case proplists:get_value(cover, Opts, false) of + true -> rebar_state:set(State, cover_enabled, true); + false -> State + end, + rebar_prv_cover:maybe_cover_compile(State1). + +project_apps(State) -> + filter_checkouts(rebar_state:project_apps(State)). + +filter_checkouts(Apps) -> filter_checkouts(Apps, []). + +filter_checkouts([], Acc) -> lists:reverse(Acc); +filter_checkouts([App|Rest], Acc) -> + case rebar_app_info:is_checkout(App) of + true -> filter_checkouts(Rest, Acc); + false -> filter_checkouts(Rest, [App|Acc]) + end. + +%% make sure applications specified actually exist +filter_apps_by_name(AppNames, ProjectApps) -> + filter_apps_by_name(AppNames, ProjectApps, []). + +filter_apps_by_name([], _ProjectApps, Acc) -> {ok, lists:reverse(Acc)}; +filter_apps_by_name([Name|Rest], ProjectApps, Acc) -> + case find_app_by_name(Name, ProjectApps) of + {error, app_not_found} -> + ?PRV_ERROR({error_running_tests, + "Application `" ++ Name ++ "' not found in project."}); + App -> + filter_apps_by_name(Rest, ProjectApps, [App|Acc]) + end. + +find_app_by_name(_, []) -> {error, app_not_found}; +find_app_by_name(Name, [App|Rest]) -> + case Name == binary_to_list(rebar_app_info:name(App)) of + true -> App; + false -> find_app_by_name(Name, Rest) + end. + +%% ensure specified suites are in the applications included +filter_suites_by_apps(Suites, ProjectApps) -> + filter_suites_by_apps(Suites, ProjectApps, []). + +filter_suites_by_apps([], _ProjectApps, Acc) -> {ok, lists:reverse(Acc)}; +filter_suites_by_apps([Suite|Rest], Apps, Acc) -> + Modules = app_modules([binary_to_atom(rebar_app_info:name(A), unicode) || A <- Apps], []), + case lists:member(list_to_atom(Suite), Modules) of + false -> + ?PRV_ERROR({error_running_tests, + "Module `" ++ Suite ++ "' not found in applications."}); + true -> + filter_suites_by_apps(Rest, Apps, [Suite|Acc]) end. -compile_bare_tests(State, TestApps) -> - F = fun(App) -> rebar_app_info:dir(App) == rebar_dir:get_cwd() end, - case lists:filter(F, TestApps) of - %% compile and link just the `test` directory of the base dir - [] -> - Source = filename:join([rebar_dir:get_cwd(), "test"]), - Target = filename:join([rebar_dir:base_dir(State), "test"]), - ok = rebar_file_utils:symlink_or_copy(Source, Target), - rebar_erlc_compiler:compile(replace_src_dirs(State), - rebar_dir:base_dir(State), - filename:join([rebar_dir:base_dir(State), "ebin"])); - %% already compiled `./test` so do nothing - _ -> ok +app_modules([], Acc) -> Acc; +app_modules([App|Rest], Acc) -> + Unload = case application:load(App) of + ok -> true; + {error, {already_loaded, _}} -> false + end, + NewAcc = case application:get_key(App, modules) of + {ok, Modules} -> Modules ++ Acc; + undefined -> Acc + end, + case Unload of + true -> + application:unload(App), + app_modules(Rest, NewAcc); + false -> + app_modules(Rest, NewAcc) end. replace_src_dirs(State) -> @@ -167,15 +207,47 @@ replace_src_dirs(State) -> StrippedOpts = lists:keydelete(src_dirs, 1, ErlOpts), rebar_state:set(State, erl_opts, [{src_dirs, ["test"]}|StrippedOpts]). -maybe_cover_compile(State, Opts) -> - State1 = case proplists:get_value(cover, Opts, false) of - true -> rebar_state:set(State, cover_enabled, true); - false -> State - end, - rebar_prv_cover:maybe_cover_compile(State1). +test_set(Apps, all) -> set_apps(Apps, []); +test_set(_Apps, Suites) -> set_suites(Suites, []). + +set_apps([], Acc) -> lists:reverse(Acc); +set_apps([App|Rest], Acc) -> + AppName = list_to_atom(binary_to_list(rebar_app_info:name(App))), + set_apps(Rest, [{application, AppName}|Acc]). + +set_suites([], Acc) -> lists:reverse(Acc); +set_suites([Suite|Rest], Acc) -> + set_suites(Rest, [{module, list_to_atom(Suite)}|Acc]). + +resolve_eunit_opts(State) -> + {Opts, _} = rebar_state:command_parsed_args(State), + EUnitOpts = rebar_state:get(State, eunit_opts, []), + case proplists:get_value(verbose, Opts, false) of + true -> set_verbose(EUnitOpts); + false -> EUnitOpts + end. + +set_verbose(Opts) -> + %% if `verbose` is already set don't set it again + case lists:member(verbose, Opts) of + true -> Opts; + false -> [verbose] ++ Opts + end. handle_results(ok) -> ok; handle_results(error) -> {error, unknown_error}; handle_results({error, Reason}) -> {error, {error_running_tests, Reason}}. + +eunit_opts(_State) -> + [{app, undefined, "app", string, help(app)}, + {cover, $c, "cover", boolean, help(cover)}, + {suite, undefined, "suite", string, help(suite)}, + {verbose, $v, "verbose", boolean, help(verbose)}]. + +help(app) -> "List of application test suites to run"; +help(cover) -> "Generate cover data"; +help(suite) -> "List of test suites to run"; +help(verbose) -> "Verbose output". + diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index bf6b8ec..4ec92f2 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -4,9 +4,21 @@ init_per_suite/1, end_per_suite/1, init_per_testcase/2, - all/0, - test_basic_app/1, - test_profile/1]). + all/0]). +-export([test_basic_app/1, + test_multi_app/1, + test_profile/1, + test_basic_exports/1, + test_multi_exports/1, + test_basic_defines/1, + test_multi_defines/1, + test_single_app_flag/1, + test_multiple_app_flag/1, + test_nonexistent_app_flag/1, + test_single_suite_flag/1, + test_suite_in_app_flag/1, + test_suite_in_wrong_app_flag/1, + test_nonexistent_suite_flag/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -25,25 +37,372 @@ init_per_testcase(_, Config) -> rebar_test_utils:init_rebar_state(Config, "eunit_"). all() -> - [test_basic_app, test_profile]. + [test_basic_app, test_multi_app, test_profile, + test_basic_exports, test_multi_exports, + test_basic_defines, test_multi_defines, + test_single_app_flag, test_multiple_app_flag, test_nonexistent_app_flag, + test_single_suite_flag, test_suite_in_app_flag, + test_suite_in_wrong_app_flag, test_nonexistent_suite_flag]. test_basic_app(Config) -> AppDir = ?config(apps, Config), Name = rebar_test_utils:create_random_name("basic_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}). +test_multi_app(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name1}, {app, Name2}]}). + test_profile(Config) -> AppDir = ?config(apps, Config), - Name = rebar_test_utils:create_random_name("basic_"), + Name = rebar_test_utils:create_random_name("profile_"), Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}, {profiles, [{test, [{erl_opts, [debug_info]}]}]}], - rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "test", "eunit"], {ok, [{app, Name}]}). + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["as", "test", "eunit"], + {ok, [{app, Name}]}). + +test_basic_exports(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("basic_exports_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name}]}), + + App = list_to_atom("not_a_real_src_" ++ Name), + Suite = list_to_atom("not_a_real_src_" ++ Name ++ "_tests"), + AppExports = App:module_info(exports), + SuiteExports = Suite:module_info(exports), + AppExpect = [{some_test_, 0}], + SuiteExpect = [{some_test_, 0}, {define_test_, 0}], + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppExports) end, AppExpect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteExports) end, SuiteExpect). + +test_multi_exports(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name1}, {app, Name2}]}), + + App1 = list_to_atom("not_a_real_src_" ++ Name1), + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + AppExports1 = App1:module_info(exports), + SuiteExports1 = Suite1:module_info(exports), + App2 = list_to_atom("not_a_real_src_" ++ Name2), + Suite2 = list_to_atom("not_a_real_src_" ++ Name2 ++ "_tests"), + AppExports2 = App2:module_info(exports), + SuiteExports2 = Suite2:module_info(exports), + AppExpect = [{some_test_, 0}], + SuiteExpect = [{some_test_, 0}, {define_test_, 0}], + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppExports1) end, AppExpect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteExports1) end, SuiteExpect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppExports2) end, AppExpect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteExports2) end, SuiteExpect). + +test_basic_defines(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("basic_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}), + + App = list_to_atom("not_a_real_src_" ++ Name), + Suite = list_to_atom("not_a_real_src_" ++ Name ++ "_tests"), + AppOpts = proplists:get_value(options, App:module_info(compile), []), + SuiteOpts = proplists:get_value(options, Suite:module_info(compile), []), + Expect = [{d, some_define}], + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppOpts) end, Expect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteOpts) end, Expect). + +test_multi_defines(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name1}, {app, Name2}]}), + + App1 = list_to_atom("not_a_real_src_" ++ Name1), + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + AppOpts1 = proplists:get_value(options, App1:module_info(compile), []), + SuiteOpts1 = proplists:get_value(options, Suite1:module_info(compile), []), + App2 = list_to_atom("not_a_real_src_" ++ Name2), + Suite2 = list_to_atom("not_a_real_src_" ++ Name2 ++ "_tests"), + AppOpts2 = proplists:get_value(options, App2:module_info(compile), []), + SuiteOpts2 = proplists:get_value(options, Suite2:module_info(compile), []), + Expect = [{d, some_define}], + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppOpts1) end, Expect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteOpts1) end, Expect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, AppOpts2) end, Expect), + lists:foreach(fun(Expect) -> true = lists:member(Expect, SuiteOpts2) end, Expect). + +test_single_app_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + BareSuite = io_lib:format("-module(all_tests).\n" + "-compile(export_all).\n" + "-include_lib(\"eunit/include/eunit.hrl\").\n" + "some_test_() -> ?_assert(true).\n" + "define_test_() -> ?_assertEqual(true, ?some_define).\n", []), + FileName = filename:join([AppDir, "test", "all_tests.erl"]), + ok = filelib:ensure_dir(FileName), + ok = ec_file:write(FileName, BareSuite), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--app=" ++ Name1], + {ok, [{app, Name1}, {app, Name2}]}), + + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + {module, Suite1} = code:ensure_loaded(Suite1), + Suite2 = list_to_atom("not_a_real_src_" ++ Name2 ++ "_tests"), + {error, nofile} = code:ensure_loaded(Suite2), + {error, nofile} = code:ensure_loaded(all_tests). + +test_multiple_app_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + BareSuite = io_lib:format("-module(all_tests).\n" + "-compile(export_all).\n" + "-include_lib(\"eunit/include/eunit.hrl\").\n" + "some_test_() -> ?_assert(true).\n" + "define_test_() -> ?_assertEqual(true, ?some_define).\n", []), + FileName = filename:join([AppDir, "test", "all_tests.erl"]), + ok = filelib:ensure_dir(FileName), + ok = ec_file:write(FileName, BareSuite), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--app=" ++ Name1 ++ "," ++ Name2], + {ok, [{app, Name1}, {app, Name2}]}), + + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + {module, Suite1} = code:ensure_loaded(Suite1), + Suite2 = list_to_atom("not_a_real_src_" ++ Name2 ++ "_tests"), + {module, Suite2} = code:ensure_loaded(Suite2), + {error, nofile} = code:ensure_loaded(all_tests). + +test_nonexistent_app_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + {error, {_, Error}} = rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--app=not_a_real_app"], + return), + + Error = {error_running_tests, "Application `not_a_real_app' not found in project."}. + +test_single_suite_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--suite=not_a_real_src_" ++ Name1], + {ok, [{app, Name1}, {app, Name2}]}), + + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + {module, Suite1} = code:ensure_loaded(Suite1). + +test_suite_in_app_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", + "--app=" ++ Name1, + "--suite=not_a_real_src_" ++ Name1], + {ok, [{app, Name1}, {app, Name2}]}), + + Suite1 = list_to_atom("not_a_real_src_" ++ Name1 ++ "_tests"), + {module, Suite1} = code:ensure_loaded(Suite1), + Suite2 = list_to_atom("not_a_real_src_" ++ Name2 ++ "_tests"), + {error, nofile} = code:ensure_loaded(Suite2). + +test_suite_in_wrong_app_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + {error, {_, Error}} = rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", + "--app=" ++ Name1, + "--suite=not_a_real_src_" ++ Name2], + return), + + Error = {error_running_tests, "Module `not_a_real_src_" ++ + Name2 ++ + "' not found in applications."}. + +test_nonexistent_suite_flag(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("multi_exports_app1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name1]), + Name1, + Vsn1, + [kernel, stdlib]), + Name2 = rebar_test_utils:create_random_name("multi_exports_app2_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(filename:join([AppDir,Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + {error, {_, Error}} = rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--suite=not_a_real_module"], + return), + + Error = {error_running_tests, "Module `not_a_real_module' not found in applications."}. diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index ab37255..6288053 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -172,7 +172,7 @@ test_profile_applied_at_completion(Config) -> Name = rebar_test_utils:create_random_name("test_profile_at_completion_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), @@ -191,7 +191,7 @@ test_profile_applied_before_compile(Config) -> Name = rebar_test_utils:create_random_name("test_profile_before_compile_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), @@ -206,7 +206,7 @@ test_profile_applied_before_eunit(Config) -> Name = rebar_test_utils:create_random_name("test_profile_before_eunit_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), @@ -221,7 +221,7 @@ test_profile_applied_to_apps(Config) -> Name = rebar_test_utils:create_random_name("test_profile_applied_to_apps_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{d, some_define}]}], rebar_test_utils:create_config(AppDir, RebarConfig), diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 7d57e0d..2eb14ac 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -3,7 +3,7 @@ -include_lib("eunit/include/eunit.hrl"). -export([init_rebar_state/1, init_rebar_state/2, run_and_check/4]). -export([expand_deps/2, flat_deps/1, flat_pkgdeps/1, top_level_deps/1]). --export([create_app/4, create_empty_app/4, create_config/2]). +-export([create_app/4, create_eunit_app/4, create_empty_app/4, create_config/2]). -export([create_random_name/1, create_random_vsn/0]). %%%%%%%%%%%%%% @@ -70,7 +70,17 @@ run_and_check(Config, RebarConfig, Command, Expect) -> %% And returns a `rebar_app_info' object. create_app(AppDir, Name, Vsn, Deps) -> write_src_file(AppDir, Name), - write_test_file(AppDir, Name), + write_app_src_file(AppDir, Name, Vsn, Deps), + rebar_app_info:new(Name, Vsn, AppDir, Deps). + +%% @doc Creates a dummy application including: +%% - src/<file>.erl +%% - src/<file>.app.src +%% - test/<file>_tests.erl +%% And returns a `rebar_app_info' object. +create_eunit_app(AppDir, Name, Vsn, Deps) -> + write_eunitized_src_file(AppDir, Name), + write_eunit_suite_file(AppDir, Name), write_app_src_file(AppDir, Name, Vsn, Deps), rebar_app_info:new(Name, Vsn, AppDir, Deps). @@ -260,10 +270,15 @@ write_src_file(Dir, Name) -> ok = filelib:ensure_dir(Erl), ok = ec_file:write(Erl, erl_src_file("not_a_real_src_" ++ Name ++ ".erl")). -write_test_file(Dir, Name) -> +write_eunitized_src_file(Dir, Name) -> + Erl = filename:join([Dir, "src", "not_a_real_src_" ++ Name ++ ".erl"]), + ok = filelib:ensure_dir(Erl), + ok = ec_file:write(Erl, erl_eunitized_src_file("not_a_real_src_" ++ Name ++ ".erl")). + +write_eunit_suite_file(Dir, Name) -> Erl = filename:join([Dir, "test", "not_a_real_src_" ++ Name ++ "_tests.erl"]), ok = filelib:ensure_dir(Erl), - ok = ec_file:write(Erl, erl_test_file("not_a_real_src_" ++ Name ++ ".erl")). + ok = ec_file:write(Erl, erl_eunit_suite_file("not_a_real_src_" ++ Name ++ ".erl")). write_app_file(Dir, Name, Version, Deps) -> Filename = filename:join([Dir, "ebin", Name ++ ".app"]), @@ -278,13 +293,18 @@ write_app_src_file(Dir, Name, Version, Deps) -> erl_src_file(Name) -> io_lib:format("-module(~s).\n" "-export([main/0]).\n" + "main() -> ok.\n", [filename:basename(Name, ".erl")]). + +erl_eunitized_src_file(Name) -> + io_lib:format("-module(~s).\n" + "-export([main/0]).\n" "main() -> ok.\n" "-ifdef(TEST).\n" "-include_lib(\"eunit/include/eunit.hrl\").\n" "some_test_() -> ?_assertEqual(ok, main()).\n" "-endif.\n", [filename:basename(Name, ".erl")]). -erl_test_file(Name) -> +erl_eunit_suite_file(Name) -> BaseName = filename:basename(Name, ".erl"), io_lib:format("-module(~s_tests).\n" "-compile(export_all).\n" |