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) -> | 
