diff options
-rw-r--r-- | src/rebar_prv_eunit.erl | 47 | ||||
-rw-r--r-- | test/rebar_eunit_SUITE.erl | 79 | ||||
-rw-r--r-- | test/rebar_profiles_SUITE.erl | 4 |
3 files changed, 114 insertions, 16 deletions
diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index b1c78b3..d744204 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -13,7 +13,8 @@ -include_lib("providers/include/providers.hrl"). -define(PROVIDER, eunit). --define(DEPS, [compile]). +%% we need to modify app_info state before compile +-define(DEPS, [lock]). %% =================================================================== %% Public API @@ -36,10 +37,21 @@ init(State) -> -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> + %% inject the `TEST` macro, `eunit_first_files` and `eunit_compile_opts` + %% into the applications to be compiled + NewState = inject_eunit_state(State), + + case rebar_prv_compile:do(NewState) of + {ok, S} -> do_tests(S); + %% this should look like a compiler error, not an eunit error + Error -> Error + end. + +do_tests(State) -> ?INFO("Performing EUnit tests...", []), rebar_utils:update_code(rebar_state:code_paths(State, all_deps)), - %% Run eunit provider prehooks + %% Run compile provider prehooks Providers = rebar_state:providers(State), Cwd = rebar_dir:get_cwd(), rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), @@ -89,11 +101,28 @@ format_error({error, Error}) -> %% Internal functions %% =================================================================== -test_state(State) -> - ErlOpts = rebar_state:get(State, eunit_compile_opts, []), - TestOpts = safe_define_test_macro(ErlOpts), - TestDir = [{extra_src_dirs, ["test"]}], - first_files(State) ++ [{erl_opts, TestOpts ++ TestDir}]. +%% currently only add the `extra_drc_dirs` on provider init +test_state(_State) -> [{extra_src_dirs, ["test"]}]. + +inject_eunit_state(State) -> + Apps = project_apps(State), + ModdedApps = lists:map(fun(App) -> inject(State, App) end, Apps), + rebar_state:project_apps(State, ModdedApps). + +inject(State, App) -> + %% append `eunit_compile_opts` to app defined `erl_opts` and define + %% the `TEST` macro if not already compiled + ErlOpts = rebar_app_info:get(App, erl_opts, []), + EUnitOpts = rebar_state:get(State, eunit_compile_opts, []), + NewOpts = safe_define_test_macro(EUnitOpts ++ ErlOpts), + %% append `eunit_first_files` to app defined `erl_first_files` + FirstFiles = rebar_app_info:get(App, erl_first_files, []), + EUnitFirstFiles = rebar_state:get(State, eunit_first_files, []), + NewFirstFiles = EUnitFirstFiles ++ FirstFiles, + %% insert the new keys into the app + lists:foldl(fun({K, V}, NewApp) -> rebar_app_info:set(NewApp, K, V) end, + App, + [{erl_opts, NewOpts}, {erl_first_files, NewFirstFiles}]). safe_define_test_macro(Opts) -> %% defining a compile macro twice results in an exception so @@ -108,10 +137,6 @@ test_defined([{d, 'TEST', true}|_]) -> true; test_defined([_|Rest]) -> test_defined(Rest); test_defined([]) -> false. -first_files(State) -> - EUnitFirst = rebar_state:get(State, eunit_first_files, []), - [{erl_first_files, EUnitFirst}]. - prepare_tests(State) -> {RawOpts, _} = rebar_state:command_parsed_args(State), ok = maybe_cover_compile(State, RawOpts), diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 69ffaf5..6b2bb0f 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -23,7 +23,9 @@ test_multiple_dir_flag/1, test_nonexistent_dir_flag/1, test_config_tests/1, - test_nonexistent_tests/1]). + test_nonexistent_tests/1, + eunit_compile_opts/1, + eunit_first_files/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -49,7 +51,8 @@ all() -> test_single_module_flag, test_nonexistent_module_flag, test_single_file_flag, test_multiple_file_flag, test_nonexistent_file_flag, test_single_dir_flag, test_multiple_dir_flag, test_nonexistent_dir_flag, - test_config_tests, test_nonexistent_tests]. + test_config_tests, test_nonexistent_tests, + eunit_compile_opts, eunit_first_files]. test_basic_app(Config) -> AppDir = ?config(apps, Config), @@ -522,4 +525,74 @@ test_nonexistent_tests(Config) -> "Directory `not_a_real_dir' not found.", "File `not_a_real_file.beam' not found.", "Module `not_a_real_module' not found in applications.", - "Module `not_a_real_suite' not found in applications."]}.
\ No newline at end of file + "Module `not_a_real_suite' not found in applications."]}. + +eunit_compile_opts(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,"apps",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,"apps",Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}, {eunit_compile_opts, [{d, some_other_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_other_define}, {d, some_define}], + lists:foreach(fun(E) -> true = lists:member(E, AppOpts1) end, Expect), + lists:foreach(fun(E) -> true = lists:member(E, SuiteOpts1) end, Expect), + lists:foreach(fun(E) -> true = lists:member(E, AppOpts2) end, Expect), + lists:foreach(fun(E) -> true = lists:member(E, SuiteOpts2) end, Expect). + +eunit_first_files(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,"apps",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,"apps",Name2]), + Name2, + Vsn2, + [kernel, stdlib]), + + ErlFirstFiles = ["not_a_real_src_" ++ Name1, "not_a_real_src_" ++ Name2], + EUnitFirstFiles = ["not_a_real_src_" ++ Name1 ++ "_tests", "not_a_real_src_" ++ Name2 ++ "_tests"], + + RebarConfig = [{erl_opts, [{d, some_define}]}, + {erl_first_files, ErlFirstFiles}, + {eunit_first_files, EUnitFirstFiles}], + {ok, State} = rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name1}, {app, Name2}]}), + + AllFirstFiles = EUnitFirstFiles ++ ErlFirstFiles, + Apps = rebar_state:project_apps(State), + lists:foreach(fun(App) -> AllFirstFiles = rebar_app_info:get(App, erl_first_files) end, + Apps).
\ No newline at end of file diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index d4c10c5..a31a4c9 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -375,8 +375,8 @@ test_profile_applied_at_completion(Config) -> ["eunit"], return), - Opts = rebar_state:opts(State), - ErlOpts = dict:fetch(erl_opts, Opts), + [App] = rebar_state:project_apps(State), + ErlOpts = rebar_app_info:get(App, erl_opts), true = lists:member({d, 'TEST'}, ErlOpts). test_profile_applied_before_compile(Config) -> |