diff options
| -rw-r--r-- | priv/shell-completion/bash/rebar3 | 4 | ||||
| -rw-r--r-- | priv/shell-completion/fish/rebar3.fish | 1 | ||||
| -rw-r--r-- | priv/shell-completion/zsh/_rebar3 | 1 | ||||
| -rw-r--r-- | src/rebar_prv_eunit.erl | 32 | ||||
| -rw-r--r-- | test/rebar_eunit_SUITE.erl | 35 | 
5 files changed, 66 insertions, 7 deletions
| diff --git a/priv/shell-completion/bash/rebar3 b/priv/shell-completion/bash/rebar3 index be9af44..41c45f2 100644 --- a/priv/shell-completion/bash/rebar3 +++ b/priv/shell-completion/bash/rebar3 @@ -93,8 +93,8 @@ _rebar3()      elif [[ ${prev} == escriptize ]] ; 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} == new ]] ; then diff --git a/priv/shell-completion/fish/rebar3.fish b/priv/shell-completion/fish/rebar3.fish index 9cd2c82..e578b96 100644 --- a/priv/shell-completion/fish/rebar3.fish +++ b/priv/shell-completion/fish/rebar3.fish @@ -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 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 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' -l suite -d "Lists of test suites to run" diff --git a/priv/shell-completion/zsh/_rebar3 b/priv/shell-completion/zsh/_rebar3 index 490a824..8ae8777 100644 --- a/priv/shell-completion/zsh/_rebar3 +++ b/priv/shell-completion/zsh/_rebar3 @@ -95,6 +95,7 @@ _rebar3 () {                          '(-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' \                          '(-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]' \                      && ret=0                  ;; diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index f120926..0b00e89 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -105,6 +105,8 @@ format_error({eunit_test_errors, Errors}) ->                                 lists:map(fun(Error) -> "~n  " ++ Error end, Errors)), []);  format_error({badconfig, {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_running_tests, Error}). @@ -134,19 +136,34 @@ resolve_tests(State) ->      Files        = resolve(file, RawOpts),      Modules      = resolve(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, EUnitKey, RawOpts) ->      case proplists:get_value(Flag, RawOpts) of          undefined -> []; -        Args      -> lists:map(fun(Arg) -> normalize(EUnitKey, Arg) end, +        Args      -> normalize(EUnitKey,                                 rebar_string:lexemes(Args, [$,]))      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) ->      case rebar_state:get(State, eunit_tests, []) of @@ -353,6 +370,8 @@ validate(State, {module, Module}) ->      validate_module(State, Module);  validate(State, {suite, Module}) ->      validate_module(State, Module); +validate(State, {generator, Module, Function}) -> +    validate_generator(State, Module, Function);  validate(State, Module) when is_atom(Module) ->      validate_module(State, Module);  validate(State, Path) when is_list(Path) -> @@ -395,6 +414,9 @@ validate_module(_State, Module) ->          _            -> ok      end. +validate_generator(State, Module, _Function) -> +    validate_module(State, Module). +  resolve_eunit_opts(State) ->      {Opts, _} = rebar_state:command_parsed_args(State),      EUnitOpts = rebar_state:get(State, eunit_opts, []), @@ -490,6 +512,7 @@ eunit_opts(_State) ->       {file, $f, "file", string, help(file)},       {module, $m, "module", string, help(module)},       {suite, $s, "suite", string, help(module)}, +     {generator, $g, "generator", string, help(generator)},       {verbose, $v, "verbose", boolean, help(verbose)},       {name, undefined, "name", atom, help(name)},       {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(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(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(name)      -> "Gives a long name to the node";  help(sname)     -> "Gives a short name to the node"; diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 1a8bade..87dd3ed 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -13,6 +13,7 @@  -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_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_dir_arg/1, multi_dir_arg/1, missing_dir_arg/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_module_arg, multi_module_arg, missing_module_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_dir_arg, multi_dir_arg, missing_dir_arg,                            multiple_arg_composition, multiple_arg_errors]}]. @@ -239,7 +241,7 @@ multi_app_testset(Config) ->      Set = {ok, [{application, multi_app_baz},                  {application, multi_app_bar},                  {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_helper}]},      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 = 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  single_file_arg(Config) ->      S = ?config(result, Config), | 
