diff options
-rw-r--r-- | priv/shell-completion/bash/rebar3 | 1 | ||||
-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_common_test.erl | 44 | ||||
-rw-r--r-- | test/rebar_ct_SUITE.erl | 30 |
5 files changed, 60 insertions, 17 deletions
diff --git a/priv/shell-completion/bash/rebar3 b/priv/shell-completion/bash/rebar3 index f436bad..be9af44 100644 --- a/priv/shell-completion/bash/rebar3 +++ b/priv/shell-completion/bash/rebar3 @@ -77,6 +77,7 @@ _rebar3() --multiply_timetraps \ --scale_timetraps \ --create_priv_dir \ + --include \ --verbose \ --auto_compile \ " diff --git a/priv/shell-completion/fish/rebar3.fish b/priv/shell-completion/fish/rebar3.fish index 770feea..fd28c97 100644 --- a/priv/shell-completion/fish/rebar3.fish +++ b/priv/shell-completion/fish/rebar3.fish @@ -110,6 +110,7 @@ complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l abort_if_missing_ complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l multiply_timetraps -d "Multiply timetraps." complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l scale_timetraps -d "Scale timetraps." complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l create_priv_dir -d "Create priv dir (auto_per_run | auto_per_tc | manual_per_tc)." +complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l include -d "Directories containing additional include files." complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -s v -l verbose -d "Enable verbose output. Default: false." complete -f -c 'rebar3' -n '__fish_rebar3_using_command ct' -l auto_compile -d "Let common test compile test suites instead of rebar3." diff --git a/priv/shell-completion/zsh/_rebar3 b/priv/shell-completion/zsh/_rebar3 index a3c9c58..95d1fa0 100644 --- a/priv/shell-completion/zsh/_rebar3 +++ b/priv/shell-completion/zsh/_rebar3 @@ -62,6 +62,7 @@ _rebar3 () { '(--multiply_timetraps)--multiply_timetraps' \ '(--scale_timetraps)--scale_timetraps' \ '(--create_priv_dir)--create_priv_dir' \ + `(--include)--include[Directories containing additional include files]:includes' \ '(-v --verbose)'{-v,--verbose}'[Print coverage analysis]' \ '(--auto_compile)--auto_compile' \ && ret=0 diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index ae0690a..8c5c4fa 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -133,6 +133,8 @@ transform_opts([{testcase, Cases}|Rest], Acc) -> transform_opts(Rest, [{testcase, split_string(Cases)}|Acc]); transform_opts([{config, Configs}|Rest], Acc) -> transform_opts(Rest, [{config, split_string(Configs)}|Acc]); +transform_opts([{include, Includes}|Rest], Acc) -> + transform_opts(Rest, [{include, split_string(Includes)}|Acc]); transform_opts([{logopts, LogOpts}|Rest], Acc) -> transform_opts(Rest, [{logopts, lists:map(fun(P) -> list_to_atom(P) end, split_string(LogOpts))}|Acc]); transform_opts([{force_stop, "true"}|Rest], Acc) -> @@ -247,8 +249,8 @@ application_dirs([App|Rest], Acc) -> end. compile(State, {ok, _} = Tests) -> - %% inject `ct_first_files` and `ct_compile_opts` into the applications - %% to be compiled + %% inject `ct_first_files`, `ct_compile_opts` and `include` (from `ct_opts` + %% and command line options) into the applications to be compiled case inject_ct_state(State, Tests) of {ok, NewState} -> do_compile(NewState); Error -> Error @@ -268,22 +270,22 @@ do_compile(State) -> inject_ct_state(State, {ok, Tests}) -> Apps = rebar_state:project_apps(State), - case inject_ct_state(State, Apps, []) of + case inject_ct_state(State, Tests, 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 +inject_ct_state(State, Tests, [App|Rest], Acc) -> + case inject(rebar_app_info:opts(App), State, Tests) of {error, _} = Error -> Error; NewOpts -> NewApp = rebar_app_info:opts(App, NewOpts), - inject_ct_state(State, Rest, [NewApp|Acc]) + inject_ct_state(State, Tests, Rest, [NewApp|Acc]) end; -inject_ct_state(State, [], Acc) -> - case inject(rebar_state:opts(State), State) of +inject_ct_state(State, Tests, [], Acc) -> + case inject(rebar_state:opts(State), State, Tests) of {error, _} = Error -> Error; NewOpts -> {ok, {rebar_state:opts(State, NewOpts), lists:reverse(Acc)}} @@ -296,24 +298,35 @@ opts(Opts, Key, Default) -> ?PRV_ERROR({badconfig, {"Value `~p' of option `~p' must be a list", {Wrong, Key}}}) end. -inject(Opts, State) -> erl_opts(Opts, State). +inject(Opts, State, Tests) -> erl_opts(Opts, State, Tests). -erl_opts(Opts, State) -> +erl_opts(Opts, State, Tests) -> %% append `ct_compile_opts` to app defined `erl_opts` ErlOpts = opts(Opts, erl_opts, []), CTOpts = opts(Opts, ct_compile_opts, []), case add_transforms(append(CTOpts, ErlOpts), State) of - {error, Error} -> {error, Error}; - NewErlOpts -> first_files(rebar_opts:set(Opts, erl_opts, NewErlOpts)) + {error, _} = Error -> Error; + NewErlOpts -> first_files(rebar_opts:set(Opts, erl_opts, NewErlOpts), Tests) end. -first_files(Opts) -> +first_files(Opts, Tests) -> %% append `ct_first_files` to app defined `erl_first_files` FirstFiles = opts(Opts, erl_first_files, []), CTFirstFiles = opts(Opts, ct_first_files, []), case append(CTFirstFiles, FirstFiles) of {error, _} = Error -> Error; - NewFirstFiles -> rebar_opts:set(Opts, erl_first_files, NewFirstFiles) + NewFirstFiles -> include_files(rebar_opts:set(Opts, erl_first_files, NewFirstFiles), Tests) + end. + +include_files(Opts, Tests) -> + %% append include dirs from command line and `ct_opts` to app defined + %% `erl_opts` + ErlOpts = opts(Opts, erl_opts, []), + Includes = proplists:get_value(include, Tests, []), + Is = lists:map(fun(I) -> {i, I} end, Includes), + case append(Is, ErlOpts) of + {error, _} = Error -> Error; + NewIncludes -> rebar_opts:set(Opts, erl_opts, NewIncludes) end. append({error, _} = Error, _) -> Error; @@ -601,6 +614,7 @@ ct_opts(_State) -> {multiply_timetraps, undefined, "multiply_timetraps", integer, help(multiple_timetraps)}, %% Integer {scale_timetraps, undefined, "scale_timetraps", boolean, help(scale_timetraps)}, {create_priv_dir, undefined, "create_priv_dir", string, help(create_priv_dir)}, + {include, undefined, "include", string, help(include)}, {readable, undefined, "readable", boolean, help(readable)}, {verbose, $v, "verbose", boolean, help(verbose)} ]. @@ -651,6 +665,8 @@ help(scale_timetraps) -> "Scale timetraps"; help(create_priv_dir) -> "Create priv dir (auto_per_run | auto_per_tc | manual_per_tc)"; +help(include) -> + "Directories containing additional include files"; help(readable) -> "Shows test case names and only displays logs to shell on failures"; help(verbose) -> diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index a3785e3..73473b2 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -38,6 +38,7 @@ cmd_multiply_timetraps/1, cmd_scale_timetraps/1, cmd_create_priv_dir/1, + cmd_include_dir/1, cfg_opts/1, cfg_arbitrary_opts/1, cfg_test_spec/1, @@ -96,7 +97,8 @@ groups() -> [{basic_app, [], [basic_app_default_dirs, cmd_abort_if_missing_suites, cmd_multiply_timetraps, cmd_scale_timetraps, - cmd_create_priv_dir]}, + cmd_create_priv_dir, + cmd_include_dir]}, {cover, [], [cover_compiled]}]. init_per_group(basic_app, Config) -> @@ -212,7 +214,7 @@ init_per_group(ct_opts, Config) -> {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return), - [{result, State}|C]; + [{result, State}, {name, Name}|C]; init_per_group(cover, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_opts"), @@ -701,7 +703,6 @@ suite_at_app_root(Config) -> data_dir_correct(Config) -> DataDir = ?config(data_dir, Config), Parts = filename:split(DataDir), - ct:pal(Parts), ["rebar_ct_SUITE_data","test","rebar","lib","test","_build"|_] = lists:reverse(Parts). cmd_label(Config) -> @@ -974,6 +975,29 @@ cmd_create_priv_dir(Config) -> true = lists:member({create_priv_dir, manual_per_tc}, TestOpts). +cmd_include_dir(Config) -> + State = ?config(result, Config), + AppDir = ?config(apps, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--include=foo/bar/baz,qux"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + Tests = rebar_prv_common_test:prepare_tests(NewState), + {ok, _} = rebar_prv_common_test:compile(NewState, Tests), + + Name = ?config(name, Config), + Beam = filename:join([AppDir, "_build", "test", "lib", Name, "ebin", Name ++ ".beam"]), + + {ok, {_, [{compile_info, Info}]}} = beam_lib:chunks(Beam, [compile_info]), + CompileOpts = proplists:get_value(options, Info), + true = lists:member({i, "foo/bar/baz"}, CompileOpts), + true = lists:member({i, "qux"}, CompileOpts). + cfg_opts(Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_opts_"), |