diff options
-rw-r--r-- | src/rebar_prv_common_test.erl | 113 | ||||
-rw-r--r-- | src/rebar_prv_eunit.erl | 210 | ||||
-rw-r--r-- | test/rebar_ct_SUITE.erl | 78 | ||||
-rw-r--r-- | test/rebar_eunit_SUITE.erl | 65 |
4 files changed, 318 insertions, 148 deletions
diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 608261a..05a1dc6 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -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), diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index b754d87..9af2965 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -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. diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index c4fc4dc..267a9ee 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -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) -> diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 262eb92..1b11c5a 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -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.
\ No newline at end of file |