summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-03-24 22:16:55 -0700
committerFred Hebert <mononcqc@ferd.ca>2015-03-24 22:16:55 -0700
commitab53164afbebada296c74dba0870d372e63c3f53 (patch)
tree802add27d843e4d0e4a2a965192ed52fb378fc3d
parentdeebd23a88e1c89647c864846dfc6a69df02b045 (diff)
parentefb859f15acad73cfe2f0510a3d9bcd7958c649f (diff)
Merge pull request #296 from talentdeficit/eunit_test_suite
eunit refactor and test suite
-rw-r--r--src/rebar_prv_eunit.erl220
-rw-r--r--test/rebar_eunit_SUITE.erl373
-rw-r--r--test/rebar_profiles_SUITE.erl8
-rw-r--r--test/rebar_test_utils.erl30
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"