Procházet zdrojové kódy

error on ct/eunit argument errors instead of warning

pull/922/head
alisdair sullivan před 9 roky
rodič
revize
25914c3508
4 změnil soubory, kde provedl 318 přidání a 148 odebrání
  1. +71
    -42
      src/rebar_prv_common_test.erl
  2. +115
    -95
      src/rebar_prv_eunit.erl
  3. +68
    -10
      test/rebar_ct_SUITE.erl
  4. +64
    -1
      test/rebar_eunit_SUITE.erl

+ 71
- 42
src/rebar_prv_common_test.erl Zobrazit soubor

@ -91,6 +91,10 @@ format_error({error_running_tests, Reason}) ->
format_error({error, Reason});
format_error({failures_running_tests, {Failed, AutoSkipped}}) ->
io_lib:format("Failures occured running tests: ~b", [Failed+AutoSkipped]);
format_error({badconfig, {Msg, {Value, Key}}}) ->
io_lib:format(Msg, [Value, Key]);
format_error({badconfig, Msg}) ->
io_lib:format(Msg, []);
format_error({multiple_errors, Errors}) ->
io_lib:format(lists:concat(["Error running tests:"] ++
lists:map(fun(Error) -> "~n " ++ Error end, Errors)), []).
@ -153,29 +157,31 @@ split_string(String) ->
cfgopts(State) ->
case rebar_state:get(State, ct_opts, []) of
Opts when is_list(Opts) ->
add_hooks(rebar_utils:filtermap(fun filter_opts/1, Opts), State);
ensure_opts(add_hooks(Opts, State), []);
Wrong ->
%% probably a single non list term, try wrapping it in a list and
%% continuing
?WARN("Value `~p' of option `ct_opts' is not a list, trying to adjust and continue", [Wrong]),
add_hooks(rebar_utils:filtermap(fun filter_opts/1, [Wrong]), State)
%% probably a single non list term
?PRV_ERROR({badconfig, {"Value `~p' of option `~p' must be a list", {Wrong, ct_opts}}})
end.
filter_opts({test_spec, _}) ->
?WARN("Test specs not supported", []),
false;
filter_opts({auto_compile, _}) ->
?WARN("Auto compile not supported", []),
false;
filter_opts({suite, Suite}) when is_integer(hd(Suite)) -> true;
filter_opts({suite, Suite}) when is_atom(Suite) ->
{true, {suite, atom_to_list(Suite)}};
filter_opts({suite, Suites}) ->
{true, {suite, lists:map(fun(S) when is_atom(S) -> atom_to_list(S);
(S) when is_list(S) -> S
end,
Suites)}};
filter_opts(_) -> true.
ensure_opts([], Acc) -> lists:reverse(Acc);
ensure_opts([{test_spec, _}|_Rest], _Acc) ->
?PRV_ERROR({badconfig, "Test specs not supported"});
ensure_opts([{auto_compile, _}|_Rest], _Acc) ->
?PRV_ERROR({badconfig, "Auto compile not supported"});
ensure_opts([{suite, Suite}|Rest], Acc) when is_integer(hd(Suite)) ->
ensure_opts(Rest, [{suite, Suite}|Acc]);
ensure_opts([{suite, Suite}|Rest], Acc) when is_atom(Suite) ->
ensure_opts(Rest, [{suite, atom_to_list(Suite)}|Acc]);
ensure_opts([{suite, Suites}|Rest], Acc) ->
NewSuites = {suite, lists:map(fun(S) when is_atom(S) -> atom_to_list(S);
(S) when is_list(S) -> S
end,
Suites)},
ensure_opts(Rest, [NewSuites|Acc]);
ensure_opts([{K, V}|Rest], Acc) ->
ensure_opts(Rest, [{K, V}|Acc]);
ensure_opts([V|_Rest], _Acc) ->
?PRV_ERROR({badconfig, {"Member `~p' of option `~p' must be a 2-tuple", {V, ct_opts}}}).
add_hooks(Opts, State) ->
case {readable(State), lists:keyfind(ct_hooks, 1, Opts)} of
@ -190,11 +196,12 @@ add_hooks(Opts, State) ->
lists:keyreplace(ct_hooks, 1, Opts, {ct_hooks, NewHooks})
end.
select_tests(_, _, {error, _} = Error, _) -> Error;
select_tests(_, _, _, {error, _} = Error) -> Error;
select_tests(State, ProjectApps, CmdOpts, CfgOpts) ->
FixedOpts = lists:filter(fun({_, _}) -> true; (V) -> ?WARN("`~p` is not a valid option for `ct_opts`", [V]) end, CfgOpts),
Merged = lists:ukeymerge(1,
lists:ukeysort(1, CmdOpts),
lists:ukeysort(1, FixedOpts)),
lists:ukeysort(1, CfgOpts)),
%% make sure `dir` and/or `suite` from command line go in as
%% a pair overriding both `dir` and `suite` from config if
%% they exist
@ -235,7 +242,7 @@ application_dirs([App|Rest], Acc) ->
false -> application_dirs(Rest, Acc)
end.
compile(State, {ok, Tests}) ->
compile(State, {ok, _} = Tests) ->
%% inject `ct_first_files` and `ct_compile_opts` into the applications
%% to be compiled
case inject_ct_state(State, Tests) of
@ -255,46 +262,68 @@ do_compile(State) ->
Error -> Error
end.
inject_ct_state(State, Tests) ->
inject_ct_state(State, {ok, Tests}) ->
Apps = rebar_state:project_apps(State),
ModdedApps = lists:map(fun(App) ->
NewOpts = inject(rebar_app_info:opts(App), State),
rebar_app_info:opts(App, NewOpts)
end, Apps),
NewOpts = inject(rebar_state:opts(State), State),
NewState = rebar_state:opts(State, NewOpts),
test_dirs(NewState, ModdedApps, Tests).
case inject_ct_state(State, Apps, []) of
{ok, {NewState, ModdedApps}} ->
test_dirs(NewState, ModdedApps, Tests);
{error, _} = Error -> Error
end;
inject_ct_state(_State, Error) -> Error.
inject_ct_state(State, [App|Rest], Acc) ->
case inject(rebar_app_info:opts(App), State) of
{error, _} = Error -> Error;
NewOpts ->
NewApp = rebar_app_info:opts(App, NewOpts),
inject_ct_state(State, Rest, [NewApp|Acc])
end;
inject_ct_state(State, [], Acc) ->
case inject(rebar_state:opts(State), State) of
{error, _} = Error -> Error;
NewOpts -> {ok, {rebar_state:opts(State, NewOpts), lists:reverse(Acc)}}
end.
opts(Opts, Key, Default) ->
case rebar_opts:get(Opts, Key, Default) of
Vs when is_list(Vs) -> Vs;
Wrong ->
?WARN("Value `~p' of option `~p' is not a list, trying to adjust and continue", [Wrong, Key]),
[Wrong]
?PRV_ERROR({badconfig, {"Value `~p' of option `~p' must be a list", {Wrong, Key}}})
end.
inject(Opts, State) ->
inject(Opts, State) -> erl_opts(Opts, State).
erl_opts(Opts, State) ->
%% append `ct_compile_opts` to app defined `erl_opts`
ErlOpts = opts(Opts, erl_opts, []),
CTOpts = opts(Opts, ct_compile_opts, []),
NewErlOpts = add_transforms(CTOpts, State) ++ ErlOpts,
case add_transforms(append(CTOpts, ErlOpts), State) of
{error, Error} -> {error, Error};
NewErlOpts -> first_files(rebar_opts:set(Opts, erl_opts, NewErlOpts))
end.
first_files(Opts) ->
%% append `ct_first_files` to app defined `erl_first_files`
FirstFiles = opts(Opts, erl_first_files, []),
CTFirstFiles = opts(Opts, ct_first_files, []),
NewFirstFiles = CTFirstFiles ++ FirstFiles,
%% insert the new keys into the opts
lists:foldl(fun({K, V}, NewOpts) -> rebar_opts:set(NewOpts, K, V) end,
Opts,
[{erl_opts, NewErlOpts}, {erl_first_files, NewFirstFiles}]).
case append(CTFirstFiles, FirstFiles) of
{error, _} = Error -> Error;
NewFirstFiles -> rebar_opts:set(Opts, erl_first_files, NewFirstFiles)
end.
append({error, _} = Error, _) -> Error;
append(_, {error, _} = Error) -> Error;
append(A, B) -> A ++ B.
add_transforms(CTOpts, State) ->
add_transforms(CTOpts, State) when is_list(CTOpts) ->
case readable(State) of
true ->
ReadableTransform = [{parse_transform, cth_readable_transform}],
(CTOpts -- ReadableTransform) ++ ReadableTransform;
false ->
CTOpts
end.
end;
add_transforms({error, _} = Error, _State) -> Error.
readable(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),

+ 115
- 95
src/rebar_prv_eunit.erl Zobrazit soubor

@ -9,7 +9,7 @@
do/1,
format_error/1]).
%% exported solely for tests
-export([compile/2, prepare_tests/1, eunit_opts/1, validate_tests/2]).
-export([prepare_tests/1, eunit_opts/1, validate_tests/2]).
-include("rebar.hrl").
-include_lib("providers/include/providers.hrl").
@ -39,10 +39,12 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
Tests = prepare_tests(State),
case compile(State, Tests) of
%% inject `eunit_first_files`, `eunit_compile_opts` and any
%% directories required by tests into the applications
NewState = inject_eunit_state(State, Tests),
case compile(NewState) of
%% successfully compiled apps
{ok, S} -> do(S, Tests);
%% this should look like a compiler error, not an eunit error
Error -> Error
end.
@ -95,6 +97,8 @@ format_error({error_running_tests, 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({badconfig, {Msg, {Value, Key}}}) ->
io_lib:format(Msg, [Value, Key]);
format_error({error, Error}) ->
format_error({error_running_tests, Error}).
@ -102,53 +106,120 @@ format_error({error, Error}) ->
%% Internal functions
%% ===================================================================
compile(State, {ok, Tests}) ->
%% inject `eunit_first_files`, `eunit_compile_opts` and any
%% directories required by tests into the applications
NewState = inject_eunit_state(State, Tests),
prepare_tests(State) ->
%% parse and translate command line tests
CmdTests = resolve_tests(State),
CfgTests = cfg_tests(State),
ProjectApps = rebar_state:project_apps(State),
%% prioritize tests to run first trying any command line specified
%% tests falling back to tests specified in the config file finally
%% running a default set if no other tests are present
select_tests(State, ProjectApps, CmdTests, CfgTests).
case rebar_prv_compile:do(NewState) of
%% successfully compiled apps
{ok, S} ->
ok = maybe_cover_compile(S),
{ok, S};
%% this should look like a compiler error, not an eunit error
Error -> Error
end;
%% maybe compile even in the face of errors?
compile(_State, Error) -> Error.
resolve_tests(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),
Apps = resolve(app, application, RawOpts),
Applications = resolve(application, RawOpts),
Dirs = resolve(dir, RawOpts),
Files = resolve(file, RawOpts),
Modules = resolve(module, RawOpts),
Suites = resolve(suite, module, RawOpts),
Apps ++ Applications ++ Dirs ++ Files ++ Modules ++ Suites.
resolve(Flag, RawOpts) -> resolve(Flag, Flag, RawOpts).
resolve(Flag, EUnitKey, RawOpts) ->
case proplists:get_value(Flag, RawOpts) of
undefined -> [];
Args -> lists:map(fun(Arg) -> normalize(EUnitKey, Arg) end, string:tokens(Args, [$,]))
end.
normalize(Key, Value) when Key == dir; Key == file -> {Key, Value};
normalize(Key, Value) -> {Key, list_to_atom(Value)}.
cfg_tests(State) ->
case rebar_state:get(State, eunit_tests, []) of
Tests when is_list(Tests) -> Tests;
Wrong ->
%% probably a single non list term
?PRV_ERROR({badconfig, {"Value `~p' of option `~p' must be a list", {Wrong, eunit_tests}}})
end.
select_tests(_State, _ProjectApps, {error, _} = Error, _) -> Error;
select_tests(_State, _ProjectApps, _, {error, _} = Error) -> Error;
select_tests(State, ProjectApps, [], []) -> {ok, default_tests(State, ProjectApps)};
select_tests(_State, _ProjectApps, [], Tests) -> {ok, Tests};
select_tests(_State, _ProjectApps, Tests, _) -> {ok, Tests}.
default_tests(State, Apps) ->
Tests = set_apps(Apps, []),
BareTest = filename:join([rebar_state:dir(State), "test"]),
F = fun(App) -> rebar_app_info:dir(App) == rebar_state:dir(State) end,
case filelib:is_dir(BareTest) andalso not lists:any(F, Apps) of
%% `test` dir at root of project is already scheduled to be
%% included or `test` does not exist
false -> lists:reverse(Tests);
%% need to add `test` dir at root to dirs to be included
true -> lists:reverse([{dir, BareTest}|Tests])
end.
set_apps([], Acc) -> Acc;
set_apps([App|Rest], Acc) ->
AppName = list_to_atom(binary_to_list(rebar_app_info:name(App))),
set_apps(Rest, [{application, AppName}|Acc]).
inject_eunit_state(State, Tests) ->
inject_eunit_state(State, {ok, Tests}) ->
Apps = rebar_state:project_apps(State),
ModdedApps = lists:map(fun(App) ->
NewOpts = inject(rebar_app_info:opts(App)),
rebar_app_info:opts(App, NewOpts)
end, Apps),
NewOpts = inject(rebar_state:opts(State)),
NewState = rebar_state:opts(State, NewOpts),
test_dirs(NewState, ModdedApps, Tests).
case inject_eunit_state(State, Apps, []) of
{ok, {NewState, ModdedApps}} ->
test_dirs(NewState, ModdedApps, Tests);
{error, _} = Error -> Error
end;
inject_eunit_state(_State, Error) -> Error.
inject_eunit_state(State, [App|Rest], Acc) ->
case inject(rebar_app_info:opts(App)) of
{error, _} = Error -> Error;
NewOpts ->
NewApp = rebar_app_info:opts(App, NewOpts),
inject_eunit_state(State, Rest, [NewApp|Acc])
end;
inject_eunit_state(State, [], Acc) ->
case inject(rebar_state:opts(State)) of
{error, _} = Error -> Error;
NewOpts -> {ok, {rebar_state:opts(State, NewOpts), lists:reverse(Acc)}}
end.
opts(Opts, Key, Default) ->
case rebar_opts:get(Opts, Key, Default) of
Vs when is_list(Vs) -> Vs;
Wrong ->
?WARN("Value ~p of option `~p' is not a list, trying to adjust and continue", [Wrong, Key]),
[Wrong]
?PRV_ERROR({badconfig, {"Value `~p' of option `~p' must be a list", {Wrong, Key}}})
end.
inject(Opts) ->
inject(Opts) -> erl_opts(Opts).
erl_opts(Opts) ->
%% append `eunit_compile_opts` to app defined `erl_opts`
ErlOpts = opts(Opts, erl_opts, []),
EUnitOpts = opts(Opts, eunit_compile_opts, []),
NewErlOpts = EUnitOpts ++ ErlOpts,
case append(EUnitOpts, ErlOpts) of
{error, _} = Error -> Error;
NewErlOpts -> first_files(rebar_opts:set(Opts, erl_opts, NewErlOpts))
end.
first_files(Opts) ->
%% append `eunit_first_files` to app defined `erl_first_files`
FirstFiles = opts(Opts, erl_first_files, []),
EUnitFirstFiles = opts(Opts, eunit_first_files, []),
NewFirstFiles = EUnitFirstFiles ++ FirstFiles,
%% insert the new keys into the opts
lists:foldl(fun({K, V}, NewOpts) -> rebar_opts:set(NewOpts, K, V) end,
Opts,
[{erl_opts, NewErlOpts}, {erl_first_files, NewFirstFiles}]).
case append(EUnitFirstFiles, FirstFiles) of
{error, _} = Error -> Error;
NewFirstFiles -> rebar_opts:set(Opts, erl_first_files, NewFirstFiles)
end.
append({error, _} = Error, _) -> Error;
append(_, {error, _} = Error) -> Error;
append(A, B) -> A ++ B.
test_dirs(State, Apps, []) -> rebar_state:project_apps(State, Apps);
test_dirs(State, Apps, [{dir, Dir}|Rest]) ->
@ -182,71 +253,20 @@ maybe_inject_test_dir(State, AppAcc, [], Dir) ->
inject_test_dir(Opts, Dir) ->
%% append specified test targets to app defined `extra_src_dirs`
ExtraSrcDirs = rebar_opts:get(Opts, extra_src_dirs, []),
ExtraSrcDirs = rebar_dir:extra_src_dirs(Opts),
rebar_opts:set(Opts, extra_src_dirs, ExtraSrcDirs ++ [Dir]).
prepare_tests(State) ->
%% parse and translate command line tests
CmdTests = resolve_tests(State),
CfgTests = cfg_tests(State),
ProjectApps = rebar_state:project_apps(State),
%% prioritize tests to run first trying any command line specified
%% tests falling back to tests specified in the config file finally
%% running a default set if no other tests are present
select_tests(State, ProjectApps, CmdTests, CfgTests).
cfg_tests(State) ->
case rebar_state:get(State, eunit_tests, []) of
Tests when is_list(Tests) -> Tests;
Wrong ->
%% probably a single non list term, try wrapping it in a list and
%% continuing
?WARN("Value `~p' of option `eunit_tests' is not a list, trying to adjust and continue", [Wrong]),
[Wrong]
end.
resolve_tests(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),
Apps = resolve(app, application, RawOpts),
Applications = resolve(application, RawOpts),
Dirs = resolve(dir, RawOpts),
Files = resolve(file, RawOpts),
Modules = resolve(module, RawOpts),
Suites = resolve(suite, module, RawOpts),
Apps ++ Applications ++ Dirs ++ Files ++ Modules ++ Suites.
resolve(Flag, RawOpts) -> resolve(Flag, Flag, RawOpts).
resolve(Flag, EUnitKey, RawOpts) ->
case proplists:get_value(Flag, RawOpts) of
undefined -> [];
Args -> lists:map(fun(Arg) -> normalize(EUnitKey, Arg) end, string:tokens(Args, [$,]))
end.
normalize(Key, Value) when Key == dir; Key == file -> {Key, Value};
normalize(Key, Value) -> {Key, list_to_atom(Value)}.
select_tests(State, ProjectApps, [], []) -> {ok, default_tests(State, ProjectApps)};
select_tests(_State, _ProjectApps, [], Tests) -> {ok, Tests};
select_tests(_State, _ProjectApps, Tests, _) -> {ok, Tests}.
default_tests(State, Apps) ->
Tests = set_apps(Apps, []),
BareTest = filename:join([rebar_state:dir(State), "test"]),
F = fun(App) -> rebar_app_info:dir(App) == rebar_state:dir(State) end,
case filelib:is_dir(BareTest) andalso not lists:any(F, Apps) of
%% `test` dir at root of project is already scheduled to be
%% included or `test` does not exist
false -> lists:reverse(Tests);
%% need to add `test` dir at root to dirs to be included
true -> lists:reverse([{dir, BareTest}|Tests])
compile({error, _} = Error) -> Error;
compile(State) ->
case rebar_prv_compile:do(State) of
%% successfully compiled apps
{ok, S} ->
ok = maybe_cover_compile(S),
{ok, S};
%% this should look like a compiler error, not an eunit error
Error -> Error
end.
set_apps([], Acc) -> Acc;
set_apps([App|Rest], Acc) ->
AppName = list_to_atom(binary_to_list(rebar_app_info:name(App))),
set_apps(Rest, [{application, AppName}|Acc]).
validate_tests(State, {ok, Tests}) ->
gather_tests(fun(Elem) -> validate(State, Elem) end, Tests, []);
validate_tests(_State, Error) -> Error.

+ 68
- 10
test/rebar_ct_SUITE.erl Zobrazit soubor

@ -38,9 +38,12 @@
cmd_create_priv_dir/1,
cfg_opts/1,
cfg_arbitrary_opts/1,
cfg_test_spec_filtered/1,
cfg_test_spec/1,
cfg_atom_suites/1,
cover_compiled/1]).
cover_compiled/1,
misspecified_ct_opts/1,
misspecified_ct_compile_opts/1,
misspecified_ct_first_files/1]).
-include_lib("common_test/include/ct.hrl").
@ -51,8 +54,11 @@ all() -> [{group, basic_app},
{group, ct_opts},
{group, cover},
cfg_opts, cfg_arbitrary_opts,
cfg_test_spec_filtered,
cfg_atom_suites].
cfg_test_spec,
cfg_atom_suites,
misspecified_ct_opts,
misspecified_ct_compile_opts,
misspecified_ct_first_files].
groups() -> [{basic_app, [], [basic_app_default_dirs,
basic_app_default_beams]},
@ -911,12 +917,12 @@ cfg_arbitrary_opts(Config) ->
true = lists:member({bar, 2}, TestOpts),
true = lists:member({baz, 3}, TestOpts).
cfg_test_spec_filtered(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_test_spec_filtered_opts_"),
cfg_test_spec(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_test_spec_opts_"),
AppDir = ?config(apps, C),
Name = rebar_test_utils:create_random_name("ct_cfg_test_spec_filtered_opts_"),
Name = rebar_test_utils:create_random_name("ct_cfg_test_spec_opts_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
@ -924,9 +930,9 @@ cfg_test_spec_filtered(Config) ->
{ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
{ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
{error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:prepare_tests(State),
false = lists:keysearch(test_spec, 1, TestOpts).
{badconfig, "Test specs not supported"} = Error.
cfg_atom_suites(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
@ -962,7 +968,59 @@ cover_compiled(Config) ->
Name = ?config(name, Config),
Mod = list_to_atom(Name),
{file, _} = cover:is_compiled(Mod).
misspecified_ct_opts(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
AppDir = ?config(apps, C),
Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
RebarConfig = [{ct_opts, {basic_html, false}}],
{ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
{error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:prepare_tests(State),
{badconfig, {"Value `~p' of option `~p' must be a list", {{basic_html, false}, ct_opts}}} = Error.
misspecified_ct_compile_opts(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
AppDir = ?config(apps, C),
Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
RebarConfig = [{ct_compile_opts, {d, whatever}}],
{ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
Tests = rebar_prv_common_test:prepare_tests(State),
{error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests),
{badconfig, {"Value `~p' of option `~p' must be a list", {{d, whatever}, ct_compile_opts}}} = Error.
misspecified_ct_first_files(Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"),
AppDir = ?config(apps, C),
Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
RebarConfig = [{ct_first_files, some_file}],
{ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
Tests = rebar_prv_common_test:prepare_tests(State),
{error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests),
{badconfig, {"Value `~p' of option `~p' must be a list", {some_file, ct_first_files}}} = Error.
%% helper for generating test data
test_suite(Name) ->

+ 64
- 1
test/rebar_eunit_SUITE.erl Zobrazit soubor

@ -11,13 +11,19 @@
-export([single_file_arg/1, multi_file_arg/1, missing_file_arg/1]).
-export([single_dir_arg/1, multi_dir_arg/1, missing_dir_arg/1]).
-export([multiple_arg_composition/1, multiple_arg_errors/1]).
-export([misspecified_eunit_tests/1]).
-export([misspecified_eunit_compile_opts/1]).
-export([misspecified_eunit_first_files/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("kernel/include/file.hrl").
all() ->
[{group, basic_app}, {group, multi_app}, {group, cmd_line_args}].
[{group, basic_app}, {group, multi_app}, {group, cmd_line_args},
misspecified_eunit_tests,
misspecified_eunit_compile_opts,
misspecified_eunit_first_files].
groups() ->
[{basic_app, [sequence], [basic_app_compiles, {group, basic_app_results}]},
@ -484,3 +490,60 @@ multiple_arg_errors(Config) ->
{error, {rebar_prv_eunit, {eunit_test_errors, Expect}}} = Tests.
misspecified_eunit_tests(Config) ->
State = rebar_test_utils:init_rebar_state(Config, "basic_app_"),
AppDir = ?config(apps, State),
PrivDir = ?config(priv_dir, State),
AppDirs = ["src", "include", "test"],
lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]),
filename:join([AppDir, F]),
[recursive]) end, AppDirs),
BaseConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, [{d, eunit_compile_define}]}],
RebarConfig = [{eunit_tests, {dir, "test"}}|BaseConfig],
{error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return),
{badconfig, {"Value `~p' of option `~p' must be a list", {{dir, "test"}, eunit_tests}}} = Error.
misspecified_eunit_compile_opts(Config) ->
State = rebar_test_utils:init_rebar_state(Config, "basic_app_"),
AppDir = ?config(apps, State),
PrivDir = ?config(priv_dir, State),
AppDirs = ["src", "include", "test"],
lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]),
filename:join([AppDir, F]),
[recursive]) end, AppDirs),
RebarConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, {d, eunit_compile_define}}],
{error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return),
{badconfig, {"Value `~p' of option `~p' must be a list", {{d, eunit_compile_define}, eunit_compile_opts}}} = Error.
misspecified_eunit_first_files(Config) ->
State = rebar_test_utils:init_rebar_state(Config, "basic_app_"),
AppDir = ?config(apps, State),
PrivDir = ?config(priv_dir, State),
AppDirs = ["src", "include", "test"],
lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]),
filename:join([AppDir, F]),
[recursive]) end, AppDirs),
BaseConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, [{d, eunit_compile_define}]}],
RebarConfig = [{eunit_first_files, some_file}|BaseConfig],
{error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return),
{badconfig, {"Value `~p' of option `~p' must be a list", {some_file, eunit_first_files}}} = Error.

Načítá se…
Zrušit
Uložit