Browse Source

Merge pull request #1984 from mopp/add_eunit_generator_option

Add --generator option for eunit
pull/1987/head
Fred Hebert 6 years ago
committed by GitHub
parent
commit
69812e803e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 7 deletions
  1. +2
    -2
      priv/shell-completion/bash/rebar3
  2. +1
    -0
      priv/shell-completion/fish/rebar3.fish
  3. +1
    -0
      priv/shell-completion/zsh/_rebar3
  4. +28
    -4
      src/rebar_prv_eunit.erl
  5. +34
    -1
      test/rebar_eunit_SUITE.erl

+ 2
- 2
priv/shell-completion/bash/rebar3 View File

@ -93,8 +93,8 @@ _rebar3()
elif [[ ${prev} == escriptize ]] ; then elif [[ ${prev} == escriptize ]] ; then
: :
elif [[ ${prev} == eunit ]] ; then elif [[ ${prev} == eunit ]] ; then
sopts="-c -e -v -d -f -m -s"
lopts="--app --application --cover --dir --error_on_warning --file --module --suite --verbose"
sopts="-c -e -v -d -f -m -s -g"
lopts="--app --application --cover --dir --error_on_warning --file --module --suite --generator --verbose"
elif [[ ${prev} == help ]] ; then elif [[ ${prev} == help ]] ; then
: :
elif [[ ${prev} == new ]] ; then elif [[ ${prev} == new ]] ; then

+ 1
- 0
priv/shell-completion/fish/rebar3.fish View File

@ -136,6 +136,7 @@ complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunut' -s e -l error_on_
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s f -l file -d "Comma separated list of files to load tests from. Equivalent to `[{file, File}]`" complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s f -l file -d "Comma separated list of files to load tests from. Equivalent to `[{file, File}]`"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s m -l module -d "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`" complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s m -l module -d "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s s -l suite -d "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`" complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s s -l suite -d "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s g -l generator -d "Comma separated list of generators (the format is `module:function`) to load tests from. Equivalent to `[{generator, Module, Function}]`"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s v -l verbose -d "Verbose output" complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -s v -l verbose -d "Verbose output"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -l suite -d "Lists of test suites to run" complete -f -c 'rebar3' -n '__fish_rebar3_using_command eunit' -l suite -d "Lists of test suites to run"

+ 1
- 0
priv/shell-completion/zsh/_rebar3 View File

@ -95,6 +95,7 @@ _rebar3 () {
'(-f --file)'{-f,--file}'[Comma separated list of files to load tests from]:files' \ '(-f --file)'{-f,--file}'[Comma separated list of files to load tests from]:files' \
'(-m --module)'{-m,--module}'[Comma separated list of modules to load tests from]:modules' \ '(-m --module)'{-m,--module}'[Comma separated list of modules to load tests from]:modules' \
'(-s --suite)'{-s,--suite}'[Comma separated list of modules to load tests from]:modules' \ '(-s --suite)'{-s,--suite}'[Comma separated list of modules to load tests from]:modules' \
'(-g --generator)'{-g,--generator}'[Comma separated list of generators (the format is `module:function`) to load tests from.]:{generator, Module, Function}' \
'(-v --verbose)'{-v,--verbose}'[Verbose output]' \ '(-v --verbose)'{-v,--verbose}'[Verbose output]' \
&& ret=0 && ret=0
;; ;;

+ 28
- 4
src/rebar_prv_eunit.erl View File

@ -105,6 +105,8 @@ format_error({eunit_test_errors, Errors}) ->
lists:map(fun(Error) -> "~n " ++ Error end, Errors)), []); lists:map(fun(Error) -> "~n " ++ Error end, Errors)), []);
format_error({badconfig, {Msg, {Value, Key}}}) -> format_error({badconfig, {Msg, {Value, Key}}}) ->
io_lib:format(Msg, [Value, Key]); io_lib:format(Msg, [Value, Key]);
format_error({generator, Value}) ->
io_lib:format("Generator ~p has an invalid format", [Value]);
format_error({error, Error}) -> format_error({error, Error}) ->
format_error({error_running_tests, Error}). format_error({error_running_tests, Error}).
@ -134,19 +136,34 @@ resolve_tests(State) ->
Files = resolve(file, RawOpts), Files = resolve(file, RawOpts),
Modules = resolve(module, RawOpts), Modules = resolve(module, RawOpts),
Suites = resolve(suite, module, RawOpts), Suites = resolve(suite, module, RawOpts),
Apps ++ Applications ++ Dirs ++ Files ++ Modules ++ Suites.
Generator = resolve(generator, RawOpts),
Apps ++ Applications ++ Dirs ++ Files ++ Modules ++ Suites ++ Generator.
resolve(Flag, RawOpts) -> resolve(Flag, Flag, RawOpts). resolve(Flag, RawOpts) -> resolve(Flag, Flag, RawOpts).
resolve(Flag, EUnitKey, RawOpts) -> resolve(Flag, EUnitKey, RawOpts) ->
case proplists:get_value(Flag, RawOpts) of case proplists:get_value(Flag, RawOpts) of
undefined -> []; undefined -> [];
Args -> lists:map(fun(Arg) -> normalize(EUnitKey, Arg) end,
Args -> normalize(EUnitKey,
rebar_string:lexemes(Args, [$,])) rebar_string:lexemes(Args, [$,]))
end. end.
normalize(Key, Value) when Key == dir; Key == file -> {Key, Value};
normalize(Key, Value) -> {Key, list_to_atom(Value)}.
normalize(generator, Args) ->
lists:flatmap(fun(Value) -> normalize_(generator, Value) end, Args);
normalize(EUnitKey, Args) ->
lists:map(fun(Arg) -> normalize_(EUnitKey, Arg) end, Args).
normalize_(generator, Value) ->
case string:tokens(Value, [$:]) of
[Module0, Functions] ->
Module = list_to_atom(Module0),
lists:map(fun(F) -> {generator, Module, list_to_atom(F)} end,
string:tokens(Functions, [$;]));
_ ->
?PRV_ERROR({generator, Value})
end;
normalize_(Key, Value) when Key == dir; Key == file -> {Key, Value};
normalize_(Key, Value) -> {Key, list_to_atom(Value)}.
cfg_tests(State) -> cfg_tests(State) ->
case rebar_state:get(State, eunit_tests, []) of case rebar_state:get(State, eunit_tests, []) of
@ -353,6 +370,8 @@ validate(State, {module, Module}) ->
validate_module(State, Module); validate_module(State, Module);
validate(State, {suite, Module}) -> validate(State, {suite, Module}) ->
validate_module(State, Module); validate_module(State, Module);
validate(State, {generator, Module, Function}) ->
validate_generator(State, Module, Function);
validate(State, Module) when is_atom(Module) -> validate(State, Module) when is_atom(Module) ->
validate_module(State, Module); validate_module(State, Module);
validate(State, Path) when is_list(Path) -> validate(State, Path) when is_list(Path) ->
@ -395,6 +414,9 @@ validate_module(_State, Module) ->
_ -> ok _ -> ok
end. end.
validate_generator(State, Module, _Function) ->
validate_module(State, Module).
resolve_eunit_opts(State) -> resolve_eunit_opts(State) ->
{Opts, _} = rebar_state:command_parsed_args(State), {Opts, _} = rebar_state:command_parsed_args(State),
EUnitOpts = rebar_state:get(State, eunit_opts, []), EUnitOpts = rebar_state:get(State, eunit_opts, []),
@ -490,6 +512,7 @@ eunit_opts(_State) ->
{file, $f, "file", string, help(file)}, {file, $f, "file", string, help(file)},
{module, $m, "module", string, help(module)}, {module, $m, "module", string, help(module)},
{suite, $s, "suite", string, help(module)}, {suite, $s, "suite", string, help(module)},
{generator, $g, "generator", string, help(generator)},
{verbose, $v, "verbose", boolean, help(verbose)}, {verbose, $v, "verbose", boolean, help(verbose)},
{name, undefined, "name", atom, help(name)}, {name, undefined, "name", atom, help(name)},
{sname, undefined, "sname", atom, help(sname)}, {sname, undefined, "sname", atom, help(sname)},
@ -501,6 +524,7 @@ help(cover_export_name) -> "Base name of the coverdata file to write";
help(dir) -> "Comma separated list of dirs to load tests from. Equivalent to `[{dir, Dir}]`."; help(dir) -> "Comma separated list of dirs to load tests from. Equivalent to `[{dir, Dir}]`.";
help(file) -> "Comma separated list of files to load tests from. Equivalent to `[{file, File}]`."; 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(module) -> "Comma separated list of modules to load tests from. Equivalent to `[{module, Module}]`.";
help(generator) -> "Comma separated list of generators (the format is `module:function`) to load tests from. Equivalent to `[{generator, Module, Function}]`.";
help(verbose) -> "Verbose output. Defaults to false."; help(verbose) -> "Verbose output. Defaults to false.";
help(name) -> "Gives a long name to the node"; help(name) -> "Gives a long name to the node";
help(sname) -> "Gives a short name to the node"; help(sname) -> "Gives a short name to the node";

+ 34
- 1
test/rebar_eunit_SUITE.erl View File

@ -13,6 +13,7 @@
-export([single_application_arg/1, multi_application_arg/1, missing_application_arg/1]). -export([single_application_arg/1, multi_application_arg/1, missing_application_arg/1]).
-export([single_module_arg/1, multi_module_arg/1, missing_module_arg/1]). -export([single_module_arg/1, multi_module_arg/1, missing_module_arg/1]).
-export([single_suite_arg/1, multi_suite_arg/1, missing_suite_arg/1]). -export([single_suite_arg/1, multi_suite_arg/1, missing_suite_arg/1]).
-export([single_generator_arg/1, multi_generator_arg/1, missing_generator_arg/1]).
-export([single_file_arg/1, multi_file_arg/1, missing_file_arg/1]). -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([single_dir_arg/1, multi_dir_arg/1, missing_dir_arg/1]).
-export([multiple_arg_composition/1, multiple_arg_errors/1]). -export([multiple_arg_composition/1, multiple_arg_errors/1]).
@ -47,6 +48,7 @@ groups() ->
single_application_arg, multi_application_arg, missing_application_arg, single_application_arg, multi_application_arg, missing_application_arg,
single_module_arg, multi_module_arg, missing_module_arg, single_module_arg, multi_module_arg, missing_module_arg,
single_suite_arg, multi_suite_arg, missing_suite_arg, single_suite_arg, multi_suite_arg, missing_suite_arg,
single_generator_arg, multi_generator_arg, missing_generator_arg,
single_file_arg, multi_file_arg, missing_file_arg, single_file_arg, multi_file_arg, missing_file_arg,
single_dir_arg, multi_dir_arg, missing_dir_arg, single_dir_arg, multi_dir_arg, missing_dir_arg,
multiple_arg_composition, multiple_arg_errors]}]. multiple_arg_composition, multiple_arg_errors]}].
@ -239,7 +241,7 @@ multi_app_testset(Config) ->
Set = {ok, [{application, multi_app_baz}, Set = {ok, [{application, multi_app_baz},
{application, multi_app_bar}, {application, multi_app_bar},
{module, multi_app_bar_tests_helper}, {module, multi_app_bar_tests_helper},
{module, multi_app_baz_tests_helper},
{module, multi_app_baz_tests_helper},
{module, multi_app_tests}, {module, multi_app_tests},
{module, multi_app_tests_helper}]}, {module, multi_app_tests_helper}]},
Set = rebar_prv_eunit:prepare_tests(Result). Set = rebar_prv_eunit:prepare_tests(Result).
@ -404,6 +406,37 @@ missing_suite_arg(Config) ->
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}}, Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}},
Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)). Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)).
%% check that the --generator cmd line opt generates the correct test set
single_generator_arg(Config) ->
S = ?config(result, Config),
{ok, Args} = getopt:parse(rebar_prv_eunit:eunit_opts(S), ["--generator=module_name:function_name"]),
State = rebar_state:command_parsed_args(S, Args),
{ok, [{generator, module_name, function_name}]} = rebar_prv_eunit:prepare_tests(State).
multi_generator_arg(Config) ->
S = ?config(result, Config),
{ok, Args} = getopt:parse(rebar_prv_eunit:eunit_opts(S), ["--generator=module1:func1;func2,module2:func1;func2"]),
State = rebar_state:command_parsed_args(S, Args),
Generators = [{generator, module1, func1},
{generator, module1, func2},
{generator, module2, func1},
{generator, module2, func2}],
{ok, Generators} = rebar_prv_eunit:prepare_tests(State).
%% check that an invalid --suite cmd line opt generates an error
missing_generator_arg(Config) ->
S = ?config(result, Config),
{ok, Args} = getopt:parse(rebar_prv_eunit:eunit_opts(S), ["--generator=missing_module:func1"]),
State = rebar_state:command_parsed_args(S, Args),
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_module' not found in project."]}}},
Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)).
%% check that the --file cmd line opt generates the correct test set %% check that the --file cmd line opt generates the correct test set
single_file_arg(Config) -> single_file_arg(Config) ->
S = ?config(result, Config), S = ?config(result, Config),

Loading…
Cancel
Save