Browse Source

inject `eunit_compile_opts`, `eunit_first_files` and `TEST` macro

prior to running compile and compile prehooks
pull/805/head
alisdair sullivan 9 years ago
parent
commit
2a1e0dd07e
3 changed files with 114 additions and 16 deletions
  1. +36
    -11
      src/rebar_prv_eunit.erl
  2. +76
    -3
      test/rebar_eunit_SUITE.erl
  3. +2
    -2
      test/rebar_profiles_SUITE.erl

+ 36
- 11
src/rebar_prv_eunit.erl View File

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

+ 76
- 3
test/rebar_eunit_SUITE.erl View File

@ -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."]}.
"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).

+ 2
- 2
test/rebar_profiles_SUITE.erl View File

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

Loading…
Cancel
Save