summaryrefslogtreecommitdiff
path: root/src/rebar_prv_eunit.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_prv_eunit.erl')
-rw-r--r--src/rebar_prv_eunit.erl73
1 files changed, 51 insertions, 22 deletions
diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl
index 309f417..eb19838 100644
--- a/src/rebar_prv_eunit.erl
+++ b/src/rebar_prv_eunit.erl
@@ -79,6 +79,9 @@ format_error(unknown_error) ->
io_lib:format("Error running tests", []);
format_error({error_running_tests, Reason}) ->
io_lib:format("Error running tests: ~p", [Reason]);
+format_error({eunit_test_errors, Errors}) ->
+ io_lib:format(lists:concat(["Error Running EUnit Tests:"] ++
+ lists:map(fun(Error) -> "~n " ++ Error end, Errors)), []);
format_error({error, Error}) ->
format_error({error_running_tests, Error}).
@@ -141,22 +144,39 @@ select_tests(ProjectApps, [], []) -> default_tests(ProjectApps);
select_tests(_ProjectApps, A, B) -> A ++ B.
validate_tests(State, ProjectApps, Tests) ->
- {ok, lists:filter(fun(Elem) -> validate(State, ProjectApps, Elem) end, Tests)}.
+ gather_tests(fun(Elem) -> validate(State, ProjectApps, Elem) end, Tests, []).
+
+gather_tests(_F, [], Acc) -> {ok, lists:reverse(Acc)};
+gather_tests(F, [Test|Rest], Acc) ->
+ case F(Test) of
+ true -> gather_tests(F, Rest, [Test|Acc]);
+ false -> gather_tests(F, Rest, Acc);
+ %% failure mode, switch to gathering errors
+ Error -> gather_errors(F, Rest, [Error])
+ end.
+
+gather_errors(_F, [], Acc) -> ?PRV_ERROR({eunit_test_errors, lists:reverse(Acc)});
+gather_errors(F, [Test|Rest], Acc) ->
+ case F(Test) of
+ true -> gather_errors(F, Rest, Acc);
+ false -> gather_errors(F, Rest, Acc);
+ Error -> gather_errors(F, Rest, [Error|Acc])
+ end.
-validate(_State, ProjectApps, {application, App}) ->
- validate_app(App, ProjectApps);
+validate(State, ProjectApps, {application, App}) ->
+ validate_app(State, ProjectApps, App);
validate(State, _ProjectApps, {dir, Dir}) ->
ok = maybe_compile_dir(State, Dir),
- validate_dir(Dir);
+ validate_dir(State, Dir);
validate(State, _ProjectApps, {file, File}) ->
ok = maybe_compile_file(State, File),
- validate_file(File);
-validate(_State, ProjectApps, {module, Module}) ->
- validate_module(Module, ProjectApps);
-validate(_State, ProjectApps, {suite, Module}) ->
- validate_module(Module, ProjectApps);
-validate(_State, ProjectApps, Module) when is_atom(Module) ->
- validate_module(Module, ProjectApps);
+ validate_file(State, File);
+validate(State, ProjectApps, {module, Module}) ->
+ validate_module(State, ProjectApps, Module);
+validate(State, ProjectApps, {suite, Module}) ->
+ validate_module(State, ProjectApps, Module);
+validate(State, ProjectApps, Module) when is_atom(Module) ->
+ validate_module(State, ProjectApps, Module);
validate(State, ProjectApps, Path) when is_list(Path) ->
case ec_file:is_dir(Path) of
true -> validate(State, ProjectApps, {dir, Path});
@@ -167,32 +187,39 @@ validate(State, ProjectApps, Path) when is_list(Path) ->
%% unvalidatable
validate(_State, _ProjectApps, _Test) -> true.
-validate_app(AppName, []) ->
- ?WARN(lists:concat(["Application `", AppName, "' not found in project."]), []),
- false;
-validate_app(AppName, [App|Rest]) ->
+validate_app(State, [], AppName) ->
+ warn_or_error(State, lists:concat(["Application `", AppName, "' not found in project."]));
+validate_app(State, [App|Rest], AppName) ->
case AppName == binary_to_atom(rebar_app_info:name(App), unicode) of
true -> true;
- false -> validate_app(AppName, Rest)
+ false -> validate_app(State, Rest, AppName)
end.
-validate_dir(Dir) ->
+validate_dir(State, Dir) ->
case ec_file:is_dir(Dir) of
true -> true;
- false -> ?WARN(lists:concat(["Directory `", Dir, "' not found."]), []), false
+ false -> warn_or_error(State, lists:concat(["Directory `", Dir, "' not found."]))
end.
-validate_file(File) ->
+validate_file(State, File) ->
case ec_file:exists(File) of
true -> true;
- false -> ?WARN(lists:concat(["File `", File, "' not found."]), []), false
+ false -> warn_or_error(State, lists:concat(["File `", File, "' not found."]))
end.
-validate_module(Module, Apps) ->
+validate_module(State, Apps, Module) ->
AppModules = app_modules([binary_to_atom(rebar_app_info:name(A), unicode) || A <- Apps], []),
case lists:member(Module, AppModules) of
true -> true;
- false -> ?WARN(lists:concat(["Module `", Module, "' not found in applications."]), []), false
+ false -> warn_or_error(State, lists:concat(["Module `", Module, "' not found in applications."]))
+ end.
+
+warn_or_error(State, Msg) ->
+ {RawOpts, _} = rebar_state:command_parsed_args(State),
+ Error = proplists:get_value(error_on_warning, RawOpts, false),
+ case Error of
+ true -> Msg;
+ false -> ?WARN(Msg, []), false
end.
project_apps(State) ->
@@ -267,6 +294,7 @@ eunit_opts(_State) ->
[{app, undefined, "app", string, help(app)},
{cover, $c, "cover", boolean, help(cover)},
{dir, undefined, "dir", string, help(dir)},
+ {error_on_warning, $e, "error_on_warning", boolean, help(error)},
{file, undefined, "file", string, help(file)},
{module, undefined, "module", string, help(module)},
{suite, undefined, "suite", string, help(suite)},
@@ -275,6 +303,7 @@ eunit_opts(_State) ->
help(app) -> "Comma separated list of application test suites to run. Equivalent to `[{application, App}]`.";
help(cover) -> "Generate cover data. Defaults to false.";
help(dir) -> "Comma separated list of dirs to load tests from. Equivalent to `[{dir, Dir}]`.";
+help(error) -> "Error on invalid test specifications instead of warning.";
help(file) -> "Comma separated list of files to load tests from. Equivalent to `[{file, File}]`.";
help(module) -> "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`.";
help(suite) -> "Comma separated list of test suites to run. Equivalent to `[{module, Suite}]`.";