summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorHeinz N. Gies <heinz@licenser.net>2016-02-08 11:15:59 -0500
committerHeinz N. Gies <heinz@licenser.net>2016-02-08 11:15:59 -0500
commit2f563041cb248ba0cac27b92da5dcc3e7be27f80 (patch)
treee27ecaf59cfeb0e6406f1f4ce753842ff52855d5 /test
parent91c47db27a3c63fc04940c7c72433062dbadf042 (diff)
parent7fab47dfa05754242790a748bbd303ffe9703e5c (diff)
Merge master
Diffstat (limited to 'test')
-rw-r--r--test/rebar_as_SUITE.erl22
-rw-r--r--test/rebar_compile_SUITE.erl116
-rw-r--r--test/rebar_cover_SUITE.erl25
-rw-r--r--test/rebar_ct_SUITE.erl860
-rw-r--r--test/rebar_dialyzer_SUITE.erl34
-rw-r--r--test/rebar_dir_SUITE.erl43
-rw-r--r--test/rebar_eunit_SUITE.erl104
-rw-r--r--test/rebar_file_utils_SUITE.erl21
-rw-r--r--test/rebar_new_SUITE.erl68
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl29
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl9
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl27
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template13
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl18
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl12
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl2
-rw-r--r--test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl35
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore19
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl2
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template7
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config2
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src15
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl8
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl32
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/rebar.config3
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src15
-rw-r--r--test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl13
-rw-r--r--test/rebar_pkg_SUITE.erl45
-rw-r--r--test/rebar_pkg_alias_SUITE.erl4
-rw-r--r--test/rebar_plugins_SUITE.erl77
-rw-r--r--test/rebar_release_SUITE.erl146
-rw-r--r--test/rebar_test_utils.erl15
-rw-r--r--test/rebar_utils_SUITE.erl78
33 files changed, 1697 insertions, 222 deletions
diff --git a/test/rebar_as_SUITE.erl b/test/rebar_as_SUITE.erl
index 99c7e30..0f37dc8 100644
--- a/test/rebar_as_SUITE.erl
+++ b/test/rebar_as_SUITE.erl
@@ -13,7 +13,8 @@
as_comma_then_space/1,
as_dir_name/1,
as_with_task_args/1,
- warn_on_empty_profile/1]).
+ warn_on_empty_profile/1,
+ clean_as_profile/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -32,7 +33,7 @@ all() -> [as_basic, as_multiple_profiles, as_multiple_tasks,
as_multiple_profiles_multiple_tasks,
as_comma_placement, as_comma_then_space,
as_dir_name, as_with_task_args,
- warn_on_empty_profile].
+ warn_on_empty_profile, clean_as_profile].
as_basic(Config) ->
AppDir = ?config(apps, Config),
@@ -166,3 +167,20 @@ warn_match(App, History) ->
false
end,
History).
+
+clean_as_profile(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("clean_as_profile_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "foo", "compile"],
+ {ok, [{app, Name, valid}]}),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["clean", "-a", "-p", "foo"],
+ {ok, [{app, Name, invalid}]}).
diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl
index 1c2c527..76a3de5 100644
--- a/test/rebar_compile_SUITE.erl
+++ b/test/rebar_compile_SUITE.erl
@@ -37,7 +37,10 @@
only_default_transitive_deps/1,
clean_all/1,
override_deps/1,
- profile_override_deps/1]).
+ profile_override_deps/1,
+ deps_build_in_prod/1,
+ include_file_relative_to_working_directory/1,
+ include_file_in_src/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -58,7 +61,8 @@ all() ->
deps_in_path, checkout_priority, highest_version_of_pkg_dep,
parse_transform_test, erl_first_files_test, mib_test,
umbrella_mib_first_test, only_default_transitive_deps,
- clean_all, override_deps, profile_override_deps].
+ clean_all, override_deps, profile_override_deps, deps_build_in_prod,
+ include_file_relative_to_working_directory, include_file_in_src].
groups() ->
[{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]},
@@ -89,7 +93,7 @@ init_per_group(basic_app, Config) ->
Name = rebar_test_utils:create_random_name("app1"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
-
+
[{app_names, [Name]}, {vsns, [Vsn]}|NewConfig];
init_per_group(release_apps, Config) ->
@@ -103,7 +107,7 @@ init_per_group(release_apps, Config) ->
Name2 = rebar_test_utils:create_random_name("relapp2_"),
Vsn2 = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2, [kernel, stdlib]),
-
+
[{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
init_per_group(checkout_apps, Config) ->
@@ -415,7 +419,7 @@ paths_basic_app(Config) ->
[Vsn] = ?config(vsns, Config),
{ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
-
+
code:add_paths(rebar_state:code_paths(State, all_deps)),
ok = application:load(list_to_atom(Name)),
Loaded = application:loaded_applications(),
@@ -1018,11 +1022,14 @@ mib_test(Config) ->
rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
- %% check a beam corresponding to the src in the extra src_dir exists in ebin
+ %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
PrivMibsDir = filename:join([AppDir, "_build", "default", "lib", Name, "priv", "mibs"]),
true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])),
- %% check the extra src_dir was linked into the _build dir
+ %% check a hrl corresponding to the mib in the mibs dir exists in include
+ true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])),
+
+ %% check the mibs dir was linked into the _build dir
true = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name, "mibs"])).
umbrella_mib_first_test(Config) ->
@@ -1065,11 +1072,14 @@ umbrella_mib_first_test(Config) ->
rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
- %% check a beam corresponding to the src in the extra src_dir exists in ebin
+ %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
PrivMibsDir = filename:join([AppsDir, "_build", "default", "lib", Name, "priv", "mibs"]),
true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])),
- %% check the extra src_dir was linked into the _build dir
+ %% check a hrl corresponding to the mib in the mibs dir exists in include
+ true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])),
+
+ %% check the mibs dir was linked into the _build dir
true = filelib:is_dir(filename:join([AppsDir, "_build", "default", "lib", Name, "mibs"])).
only_default_transitive_deps(Config) ->
@@ -1167,3 +1177,91 @@ profile_override_deps(Config) ->
{ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]}
).
+%% verify a deps prod profile is used
+%% tested by checking prod hooks run and outputs to default profile dir for dep
+%% and prod deps are installed for dep
+deps_build_in_prod(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ GitDeps = rebar_test_utils:expand_deps(git, [{"asdf", "1.0.0", []}]),
+ PkgName = rebar_test_utils:create_random_name("pkg1_"),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
+ mock_git_resource:mock([{deps, SrcDeps},
+ {config, [{profiles, [{prod, [{pre_hooks, [{compile, "echo whatsup > randomfile"}]},
+ {deps, [list_to_atom(PkgName)]}]}]}]}]),
+
+ mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
+
+ Deps = rebar_test_utils:top_level_deps(GitDeps),
+ RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]),
+ {ok, RConf} = file:consult(RConfFile),
+
+ %% Build with deps.
+ rebar_test_utils:run_and_check(
+ Config, RConf, ["compile"],
+ {ok, [{app, Name}, {dep, "asdf", <<"1.0.0">>}, {dep, PkgName},
+ {file, filename:join([AppDir, "_build", "default", "lib", "asdf", "randomfile"])}]}
+ ).
+
+%% verify that the proper include path is defined
+%% according the erlang doc which states:
+%% If the filename File is absolute (possibly after variable substitution),
+%% the include file with that name is included. Otherwise, the specified file
+%% is searched for in the following directories, and in this order:
+%% * The current working directory
+%% * The directory where the module is being compiled
+%% * The directories given by the include option
+include_file_relative_to_working_directory(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ Src = <<"-module(test).\n"
+"\n"
+"-include(\"include/test.hrl\").\n"
+"\n"
+"test() -> ?TEST_MACRO.\n"
+"\n">>,
+ Include = <<"-define(TEST_MACRO, test).\n">>,
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
+ ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
+ ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include),
+
+ RebarConfig = [],
+ rebar_test_utils:run_and_check(Config, RebarConfig,
+ ["compile"],
+ {ok, [{app, Name}]}).
+
+include_file_in_src(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ Src = <<"-module(test).\n"
+"\n"
+"-include(\"test.hrl\").\n"
+"\n"
+"test() -> ?TEST_MACRO.\n"
+"\n">>,
+ Include = <<"-define(TEST_MACRO, test).\n">>,
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
+ ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
+
+ ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include),
+
+ RebarConfig = [],
+ rebar_test_utils:run_and_check(Config, RebarConfig,
+ ["compile"],
+ {ok, [{app, Name}]}).
diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl
index ba078c2..a838d7d 100644
--- a/test/rebar_cover_SUITE.erl
+++ b/test/rebar_cover_SUITE.erl
@@ -72,7 +72,7 @@ basic_extra_src_dirs(Config) ->
Name = rebar_test_utils:create_random_name("cover_extra_"),
Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
ExtraSrc = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name]),
@@ -86,8 +86,11 @@ basic_extra_src_dirs(Config) ->
["eunit", "--cover"],
{ok, [{app, Name}]}),
- Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
- {file, _} = cover:is_compiled(Mod).
+ Mod = list_to_atom(Name),
+ {file, _} = cover:is_compiled(Mod),
+
+ ExtraMod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
+ {file, _} = cover:is_compiled(ExtraMod).
release_extra_src_dirs(Config) ->
AppDir = ?config(apps, Config),
@@ -120,10 +123,15 @@ release_extra_src_dirs(Config) ->
["eunit", "--cover"],
{ok, [{app, Name1}, {app, Name2}]}),
- Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
+ Mod1 = list_to_atom(Name1),
{file, _} = cover:is_compiled(Mod1),
- Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
- {file, _} = cover:is_compiled(Mod2).
+ Mod2 = list_to_atom(Name2),
+ {file, _} = cover:is_compiled(Mod2),
+
+ ExtraMod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
+ {file, _} = cover:is_compiled(ExtraMod1),
+ ExtraMod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
+ {file, _} = cover:is_compiled(ExtraMod2).
root_extra_src_dirs(Config) ->
AppDir = ?config(apps, Config),
@@ -147,6 +155,11 @@ root_extra_src_dirs(Config) ->
["eunit", "--cover"],
{ok, [{app, Name1}, {app, Name2}]}),
+ Mod1 = list_to_atom(Name1),
+ {file, _} = cover:is_compiled(Mod1),
+ Mod2 = list_to_atom(Name2),
+ {file, _} = cover:is_compiled(Mod2),
+
{file, _} = cover:is_compiled(extra).
index_written(Config) ->
diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl
index cdd3774..94ab690 100644
--- a/test/rebar_ct_SUITE.erl
+++ b/test/rebar_ct_SUITE.erl
@@ -17,15 +17,50 @@
multi_suite/1,
all_suite/1,
single_dir_and_single_suite/1,
- symlinked_dir_overwritten_fix/1,
- data_dir_correct/1]).
+ suite_at_root/1,
+ suite_at_app_root/1,
+ data_dir_correct/1,
+ cmd_label/1,
+ cmd_config/1,
+ cmd_allow_user_terms/1,
+ cmd_logdir/1,
+ cmd_logopts/1,
+ cmd_verbosity/1,
+ cmd_repeat/1,
+ cmd_duration/1,
+ cmd_until/1,
+ cmd_force_stop/1,
+ cmd_basic_html/1,
+ cmd_stylesheet/1,
+ cmd_decrypt_key/1,
+ cmd_decrypt_file/1,
+ cmd_abort_if_missing_suites/1,
+ cmd_multiply_timetraps/1,
+ cmd_scale_timetraps/1,
+ cmd_create_priv_dir/1,
+ cfg_opts/1,
+ cfg_arbitrary_opts/1,
+ cfg_test_spec/1,
+ cfg_atom_suites/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").
all() -> [{group, basic_app},
{group, multi_app},
{group, dirs_and_suites},
- {group, data_dirs}].
+ {group, data_dirs},
+ {group, ct_opts},
+ {group, cover},
+ cfg_opts, cfg_arbitrary_opts,
+ 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]},
@@ -40,8 +75,28 @@ groups() -> [{basic_app, [], [basic_app_default_dirs,
multi_suite,
all_suite,
single_dir_and_single_suite,
- symlinked_dir_overwritten_fix]},
- {data_dirs, [], [data_dir_correct]}].
+ suite_at_root,
+ suite_at_app_root]},
+ {data_dirs, [], [data_dir_correct]},
+ {ct_opts, [], [cmd_label,
+ cmd_config,
+ cmd_allow_user_terms,
+ cmd_logdir,
+ cmd_logopts,
+ cmd_verbosity,
+ cmd_repeat,
+ cmd_duration,
+ cmd_until,
+ cmd_force_stop,
+ cmd_basic_html,
+ cmd_stylesheet,
+ cmd_decrypt_key,
+ cmd_decrypt_file,
+ cmd_abort_if_missing_suites,
+ cmd_multiply_timetraps,
+ cmd_scale_timetraps,
+ cmd_create_priv_dir]},
+ {cover, [], [cover_compiled]}].
init_per_group(basic_app, Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_"),
@@ -56,22 +111,14 @@ init_per_group(basic_app, Config) ->
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite(Name)),
- {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "compile"], return),
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
- LibDirs = rebar_dir:lib_dirs(State),
- State1 = rebar_app_discover:do(State, LibDirs),
-
- Providers = rebar_state:providers(State1),
- Namespace = rebar_state:namespace(State1),
- CommandProvider = providers:get_provider(ct, Providers, Namespace),
- GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec, []),
-
- State2 = rebar_state:command_parsed_args(State1, GetOptResult),
+ Tests = rebar_prv_common_test:prepare_tests(State),
+ {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- [{result, Result}, {appnames, [Name]}|C];
+ [{result, Opts}, {appnames, [Name]}|C];
init_per_group(multi_app, Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_"),
@@ -99,22 +146,14 @@ init_per_group(multi_app, Config) ->
ok = filelib:ensure_dir(Suite3),
ok = file:write_file(Suite3, test_suite("extras")),
- {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "compile"], return),
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
- LibDirs = rebar_dir:lib_dirs(State),
- State1 = rebar_app_discover:do(State, LibDirs),
+ Tests = rebar_prv_common_test:prepare_tests(State),
+ {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Providers = rebar_state:providers(State1),
- Namespace = rebar_state:namespace(State1),
- CommandProvider = providers:get_provider(ct, Providers, Namespace),
- GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec, []),
-
- State2 = rebar_state:command_parsed_args(State1, GetOptResult),
-
- Result = rebar_prv_common_test:setup_ct(State2),
-
- [{result, Result}, {appnames, [Name1, Name2]}|C];
+ [{result, Opts}, {appnames, [Name1, Name2]}|C];
init_per_group(dirs_and_suites, Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_"),
@@ -142,7 +181,49 @@ init_per_group(dirs_and_suites, Config) ->
ok = filelib:ensure_dir(Suite3),
ok = file:write_file(Suite3, test_suite("extras")),
- [{appnames, [Name1, Name2]}|C];
+ Suite4 = filename:join([AppDir, "root_SUITE.erl"]),
+ ok = file:write_file(Suite4, test_suite("root")),
+
+ ok = file:write_file(filename:join([AppDir, "root_SUITE.hrl"]), <<>>),
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "root_SUITE_data", "dummy.txt"])),
+ ok = file:write_file(filename:join([AppDir, "root_SUITE_data", "some_data.txt"]), <<>>),
+
+ Suite5 = filename:join([AppDir, "apps", Name2, "app_root_SUITE.erl"]),
+ ok = file:write_file(Suite5, test_suite("app_root")),
+
+ ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE.hrl"]), <<>>),
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "dummy.txt"])),
+ ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "some_data.txt"]), <<>>),
+
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
+
+ [{s, State}, {appnames, [Name1, Name2]}|C];
+init_per_group(ct_opts, Config) ->
+ C = rebar_test_utils:init_rebar_state(Config, "ct_opts"),
+
+ AppDir = ?config(apps, C),
+
+ Name = rebar_test_utils:create_random_name("ct_opts_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
+
+ [{result, State}|C];
+init_per_group(cover, Config) ->
+ C = rebar_test_utils:init_rebar_state(Config, "ct_opts"),
+
+ AppDir = ?config(apps, C),
+
+ Name = rebar_test_utils:create_random_name("ct_opts_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
+
+ [{result, State}, {name, Name}|C];
init_per_group(_, Config) -> Config.
end_per_group(_Group, _Config) -> ok.
@@ -152,10 +233,10 @@ basic_app_default_dirs(Config) ->
[Name] = ?config(appnames, Config),
Result = ?config(result, Config),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name, "test"])),
+ Expect = filename:join([AppDir, "_build", "test", "lib", Name, "test"]),
Dir = proplists:get_value(dir, Result),
- Expect = Dir.
+ [Expect] = Dir.
basic_app_default_beams(Config) ->
AppDir = ?config(apps, Config),
@@ -178,7 +259,7 @@ multi_app_default_dirs(Config) ->
Expect1 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1, "test"])),
Expect2 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name2, "test"])),
- Expect3 = filename:absname(filename:join([AppDir, "_build", "test", "test"])),
+ Expect3 = filename:absname(filename:join([AppDir, "_build", "test", "extras", "test"])),
Dirs = proplists:get_value(dir, Result),
true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Dirs)).
@@ -215,8 +296,7 @@ multi_app_default_beams(Config) ->
single_app_dir(Config) ->
AppDir = ?config(apps, Config),
[Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -233,17 +313,19 @@ single_app_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1, "test"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([AppDir, "_build", "test", "lib", Name1, "test"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_extra_dir(Config) ->
AppDir = ?config(apps, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -257,22 +339,24 @@ single_extra_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "test"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([AppDir, "_build", "test", "extras", "test"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_unmanaged_dir(Config) ->
PrivDir = ?config(priv_dir, Config),
+ State = ?config(s, Config),
Suite = filename:join([PrivDir, "unmanaged_dir", "unmanaged_dir_SUITE.erl"]),
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite("unmanaged_dir")),
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
-
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -285,18 +369,20 @@ single_unmanaged_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([PrivDir, "unmanaged_dir"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([PrivDir, "unmanaged_dir"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -314,24 +400,26 @@ single_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Suite = proplists:get_value(suite, Opts),
- Expect = Suite.
+ [Expect] = Suite.
single_extra_suite(Config) ->
AppDir = ?config(apps, Config),
[_Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -347,27 +435,30 @@ single_extra_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test",
+ "extra_SUITE"]),
+ Suite = proplists:get_value(suite, Opts),
- Expect = Suite.
+ [Expect] = Suite.
single_unmanaged_suite(Config) ->
PrivDir = ?config(priv_dir, Config),
[_Name1, _Name2] = ?config(appnames, Config),
+ State = ?config(s, Config),
Suite = filename:join([PrivDir, "unmanaged", "unmanaged_SUITE.erl"]),
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite("unmanaged")),
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
-
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -382,20 +473,22 @@ single_unmanaged_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([PrivDir,
- "unmanaged",
- "unmanaged_SUITE"]))],
- SuitePath = proplists:get_value(suite, Result),
+ Expect = filename:join([PrivDir,
+ "unmanaged",
+ "unmanaged_SUITE"]),
+ SuitePath = proplists:get_value(suite, Opts),
- Expect = SuitePath.
+ [Expect] = SuitePath.
multi_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -417,31 +510,33 @@ multi_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect1 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"])),
- Expect2 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name2,
- "test",
- Name2 ++ "_SUITE"])),
- Suites = proplists:get_value(suite, Result),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Expect1 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Expect2 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name2,
+ "test",
+ Name2 ++ "_SUITE"]),
+ Suites = proplists:get_value(suite, Opts),
true = (lists:sort([Expect1, Expect2]) == lists:sort(Suites)).
all_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -465,36 +560,39 @@ all_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect1 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"])),
- Expect2 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name2,
- "test",
- Name2 ++ "_SUITE"])),
- Expect3 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"])),
- Suites = proplists:get_value(suite, Result),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Expect1 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Expect2 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name2,
+ "test",
+ Name2 ++ "_SUITE"]),
+ Expect3 = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test",
+ "extra_SUITE"]),
+ Suites = proplists:get_value(suite, Opts),
true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Suites)).
single_dir_and_single_suite(Config) ->
AppDir = ?config(apps, Config),
[_Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -509,22 +607,62 @@ single_dir_and_single_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test"]),
+ Dir = proplists:get_value(dir, Opts),
+ [Expect] = Dir,
- Expect = Suite.
+ Suite = proplists:get_value(suite, Opts),
+ ["extra_SUITE"] = Suite.
-symlinked_dir_overwritten_fix(Config) ->
+suite_at_root(Config) ->
AppDir = ?config(apps, Config),
- [Name1, _Name2] = ?config(appnames, Config),
+ State = ?config(s, Config),
+
+ LibDirs = rebar_dir:lib_dirs(State),
+ State1 = rebar_app_discover:do(State, LibDirs),
+
+ Providers = rebar_state:providers(State1),
+ Namespace = rebar_state:namespace(State1),
+ CommandProvider = providers:get_provider(ct, Providers, Namespace),
+ GetOptSpec = providers:opts(CommandProvider),
+ {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join([AppDir, "root_SUITE"])]),
+
+ State2 = rebar_state:command_parsed_args(State1, GetOptResult),
+
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Suite = proplists:get_value(suite, Opts),
+ Expected = filename:join([AppDir, "_build", "test", "extras", "root_SUITE"]),
+ [Expected] = Suite,
+
+ TestHrl = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.hrl"]),
+ true = filelib:is_file(TestHrl),
+
+ TestBeam = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.beam"]),
+ true = filelib:is_file(TestBeam),
+
+ DataDir = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data"]),
+ true = filelib:is_dir(DataDir),
+
+ DataFile = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data", "some_data.txt"]),
+ true = filelib:is_file(DataFile).
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+suite_at_app_root(Config) ->
+ AppDir = ?config(apps, Config),
+ [_Name1, Name2] = ?config(appnames, Config),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -533,28 +671,450 @@ symlinked_dir_overwritten_fix(Config) ->
Namespace = rebar_state:namespace(State1),
CommandProvider = providers:get_provider(ct, Providers, Namespace),
GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec,
- ["--dir=" ++ filename:join([AppDir,
- "apps",
- Name1])]),
+ {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join([AppDir, "apps", Name2, "app_root_SUITE"])]),
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1])),
- Dir = proplists:get_value(dir, Result),
+ Suite = proplists:get_value(suite, Opts),
+ Expected = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE"]),
+ [Expected] = Suite,
- Expect = Dir,
+ TestHrl = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.hrl"]),
+ true = filelib:is_file(TestHrl),
- {ok, _} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return).
+ TestBeam = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.beam"]),
+ true = filelib:is_file(TestBeam),
+
+ DataDir = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE_data"]),
+ true = filelib:is_dir(DataDir),
+
+ DataFile = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE_data", "some_data.txt"]),
+ true = filelib:is_file(DataFile).
%% this test probably only fails when this suite is run via rebar3 with the --cover flag
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) ->
+ State = ?config(result, 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, ["--label=this_is_a_label"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({label, "this_is_a_label"}, TestOpts).
+
+cmd_config(Config) ->
+ State = ?config(result, 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, ["--config=config/foo,config/bar,config/baz"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({config, ["config/foo", "config/bar", "config/baz"]}, TestOpts).
+
+cmd_allow_user_terms(Config) ->
+ State = ?config(result, 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, ["--allow_user_terms=true"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({allow_user_terms, true}, TestOpts).
+
+cmd_logdir(Config) ->
+ State = ?config(result, 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, ["--logdir=/tmp/ct_logs"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({logdir, "/tmp/ct_logs"}, TestOpts).
+
+cmd_logopts(Config) ->
+ State = ?config(result, 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, ["--logopts=no_src,no_nl"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({logopts, [no_src, no_nl]}, TestOpts).
+
+cmd_verbosity(Config) ->
+ State = ?config(result, 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, ["--verbosity=43"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({verbosity, 43}, TestOpts).
+
+cmd_repeat(Config) ->
+ State = ?config(result, 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, ["--repeat=3"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({repeat, 3}, TestOpts).
+
+cmd_duration(Config) ->
+ State = ?config(result, 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, ["--duration=001500"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({duration, "001500"}, TestOpts).
+
+cmd_until(Config) ->
+ State = ?config(result, 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, ["--until=001500"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({until, "001500"}, TestOpts).
+
+cmd_force_stop(Config) ->
+ State = ?config(result, 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, ["--force_stop=skip_rest"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({force_stop, skip_rest}, TestOpts).
+
+cmd_basic_html(Config) ->
+ State = ?config(result, 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, ["--basic_html"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({basic_html, true}, TestOpts).
+
+cmd_stylesheet(Config) ->
+ State = ?config(result, 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, ["--stylesheet=resources/tests.css"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({stylesheet, "resources/tests.css"}, TestOpts).
+
+cmd_decrypt_key(Config) ->
+ State = ?config(result, 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, ["--decrypt_key==ac467e30"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({decrypt_key, "=ac467e30"}, TestOpts).
+
+cmd_decrypt_file(Config) ->
+ State = ?config(result, 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, ["--decrypt_file=../keyfile.pem"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts).
+
+cmd_abort_if_missing_suites(Config) ->
+ State = ?config(result, 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, ["--abort_if_missing_suites"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({abort_if_missing_suites, true}, TestOpts).
+
+cmd_multiply_timetraps(Config) ->
+ State = ?config(result, 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, ["--multiply_timetraps=3"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({multiply_timetraps, 3}, TestOpts).
+
+cmd_scale_timetraps(Config) ->
+ State = ?config(result, 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, ["--scale_timetraps"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({scale_timetraps, true}, TestOpts).
+
+cmd_create_priv_dir(Config) ->
+ State = ?config(result, 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, ["--create_priv_dir=manual_per_tc"]),
+
+ NewState = rebar_state:command_parsed_args(State, GetOptResult),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState),
+
+ true = lists:member({create_priv_dir, manual_per_tc}, TestOpts).
+
+cfg_opts(Config) ->
+ C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_opts_"),
+
+ AppDir = ?config(apps, C),
+
+ Name = rebar_test_utils:create_random_name("ct_cfg_opts_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ RebarConfig = [{ct_opts, [{label, "this_is_a_label"}, {decrypt_file, "../keyfile.pem"}]}],
+
+ {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
+
+ true = lists:member({label, "this_is_a_label"}, TestOpts),
+ true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts).
+
+%% allow even nonsensical opts to be passed to ct_run for futureproofing
+cfg_arbitrary_opts(Config) ->
+ C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_arbitrary_opts_"),
+
+ AppDir = ?config(apps, C),
+
+ Name = rebar_test_utils:create_random_name("ct_cfg_arbitrary_opts_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ RebarConfig = [{ct_opts, [{foo, 1}, {bar, 2}, {baz, 3}]}],
+
+ {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
+
+ true = lists:member({foo, 1}, TestOpts),
+ true = lists:member({bar, 2}, TestOpts),
+ true = lists:member({baz, 3}, TestOpts).
+
+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_opts_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ RebarConfig = [{ct_opts, [{test_spec, "spec/foo.spec"}]}],
+
+ {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, "Test specs not supported"} = Error.
+
+cfg_atom_suites(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, [{suite, [foo, bar, baz]}]}],
+
+ {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return),
+
+ {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State),
+
+ true = lists:member({suite, ["foo", "bar", "baz"]}, TestOpts).
+
+cover_compiled(Config) ->
+ State = ?config(result, 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, ["--cover"]),
+
+ 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),
+ 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_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl
index 31e02d9..22a4894 100644
--- a/test/rebar_dialyzer_SUITE.erl
+++ b/test/rebar_dialyzer_SUITE.erl
@@ -69,7 +69,16 @@ update_base_plt(Config) ->
?assertEqual(ErtsFiles, BasePltFiles2),
{ok, PltFiles} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles).
+ ?assertEqual(ErtsFiles, PltFiles),
+
+ add_missing_file(BasePlt),
+ ok = file:delete(Plt),
+
+ rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
+ {ok, [{app, Name}]}),
+
+ {ok, BasePltFiles3} = plt_files(BasePlt),
+ ?assertEqual(ErtsFiles, BasePltFiles3).
update_app_plt(Config) ->
@@ -103,7 +112,15 @@ update_app_plt(Config) ->
{ok, [{app, Name}]}),
{ok, PltFiles3} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles3).
+ ?assertEqual(ErtsFiles, PltFiles3),
+
+ add_missing_file(Plt),
+
+ rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
+ {ok, [{app, Name}]}),
+
+ {ok, PltFiles4} = plt_files(Plt),
+ ?assertEqual(ErtsFiles, PltFiles4).
build_release_plt(Config) ->
AppDir = ?config(apps, Config),
@@ -211,6 +228,19 @@ alter_plt(Plt) ->
{files, [code:which(dialyzer)]}]),
ok.
+add_missing_file(Plt) ->
+ Source = code:which(dialyzer),
+ Dest = filename:join(filename:dirname(Plt), "dialyzer.beam"),
+ {ok, _} = file:copy(Source, Dest),
+ _ = try
+ dialyzer:run([{analysis_type, plt_add},
+ {init_plt, Plt},
+ {files, [Dest]}])
+ after
+ ok = file:delete(Dest)
+ end,
+ ok.
+
-spec merge_config(Config, Config) -> Config when
Config :: [{term(), term()}].
merge_config(NewConfig, OldConfig) ->
diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl
index 526f827..1221db7 100644
--- a/test/rebar_dir_SUITE.erl
+++ b/test/rebar_dir_SUITE.erl
@@ -5,7 +5,7 @@
-export([default_src_dirs/1, default_extra_src_dirs/1, default_all_src_dirs/1]).
-export([src_dirs/1, extra_src_dirs/1, all_src_dirs/1]).
-export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]).
--export([retarget_path/1]).
+-export([retarget_path/1, alt_base_dir_abs/1, alt_base_dir_rel/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -15,7 +15,7 @@
all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs,
src_dirs, extra_src_dirs, all_src_dirs,
profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs,
- retarget_path].
+ retarget_path, alt_base_dir_abs, alt_base_dir_rel].
init_per_testcase(_, Config) ->
C = rebar_test_utils:init_rebar_state(Config),
@@ -124,4 +124,41 @@ retarget_path(Config) ->
?assertEqual(filename:join([BaseDir, "some_other_dir"]),
rebar_dir:retarget_path(State, filename:join([rebar_dir:root_dir(State), "some_other_dir"]))),
?assertEqual("/somewhere/outside/the/project",
- rebar_dir:retarget_path(State, "/somewhere/outside/the/project")). \ No newline at end of file
+ rebar_dir:retarget_path(State, "/somewhere/outside/the/project")).
+
+alt_base_dir_abs(Config) ->
+ AltName = lists:flatten(io_lib:format("~p", [os:timestamp()])),
+ AltBaseDir = filename:join(?config(priv_dir, Config), AltName),
+ RebarConfig = [{base_dir, AltBaseDir}],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
+
+ BaseDir = rebar_dir:base_dir(State),
+ ?assertEqual(filename:join(AltBaseDir, "default"), BaseDir),
+
+ Name1 = ?config(app_one, Config),
+ Name2 = ?config(app_two, Config),
+
+ ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name1, "ebin"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".app"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".beam"]))),
+ ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name2, "ebin"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".app"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".beam"]))).
+
+alt_base_dir_rel(Config) ->
+ AltName = lists:flatten(io_lib:format("~p", [os:timestamp()])),
+ AltBaseDir = filename:join("..", AltName),
+ RebarConfig = [{base_dir, AltBaseDir}],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
+
+ BaseDir = rebar_dir:base_dir(State),
+
+ Name1 = ?config(app_one, Config),
+ Name2 = ?config(app_two, Config),
+
+ ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name1, "ebin"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".app"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".beam"]))),
+ ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name2, "ebin"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".app"]))),
+ ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".beam"]))).
diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl
index 609be51..cb2c911 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}]},
@@ -36,13 +42,10 @@ groups() ->
init_per_suite(Config) ->
PrivDir = ?config(priv_dir, Config),
DataDir = ?config(data_dir, Config),
- {ok, Cwd} = file:get_cwd(),
- file:set_cwd(PrivDir),
ok = ec_file:copy(filename:join([DataDir, "basic_app.zip"]), filename:join([PrivDir, "basic_app.zip"])),
- {ok, _} = zip:extract(filename:join([PrivDir, "basic_app.zip"])),
+ {ok, _} = zip:extract(filename:join([PrivDir, "basic_app.zip"]), [{cwd, PrivDir}]),
ok = ec_file:copy(filename:join([DataDir, "multi_app.zip"]), filename:join([PrivDir, "multi_app.zip"])),
- {ok, _} = zip:extract(filename:join([PrivDir, "multi_app.zip"])),
- file:set_cwd(Cwd),
+ {ok, _} = zip:extract(filename:join([PrivDir, "multi_app.zip"]), [{cwd, PrivDir}]),
Config.
init_per_group(basic_app, Config) ->
@@ -153,7 +156,9 @@ basic_app_exports(_Config) ->
basic_app_testset(Config) ->
Result = ?config(result, Config),
- {ok, [{application, basic_app}]} = rebar_prv_eunit:prepare_tests(Result).
+ Set = {ok, [{application, basic_app},
+ {module, basic_app_tests_helper}]},
+ Set = rebar_prv_eunit:prepare_tests(Result).
@@ -205,12 +210,14 @@ multi_app_exports(_Config) ->
%% check that the correct tests are schedule to run for project
multi_app_testset(Config) ->
- AppDir = ?config(apps, Config),
Result = ?config(result, Config),
- Set = {ok, [{application, multi_app_bar},
- {application, multi_app_baz},
- {dir, filename:join([AppDir, "test"])}]},
+ 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_tests},
+ {module, multi_app_tests_helper}]},
Set = rebar_prv_eunit:prepare_tests(Result).
@@ -268,7 +275,7 @@ missing_application_arg(Config) ->
State = rebar_state:command_parsed_args(S, Args),
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Application `missing_app' not found in project."]}}},
- Error = rebar_prv_eunit:prepare_tests(State).
+ Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)).
%% check that the --module cmd line opt generates the correct test set
single_module_arg(Config) ->
@@ -311,8 +318,11 @@ missing_module_arg(Config) ->
{ok, Args} = getopt:parse(rebar_prv_eunit:eunit_opts(S), ["--module=missing_app"]),
State = rebar_state:command_parsed_args(S, Args),
+ T = rebar_prv_eunit:prepare_tests(State),
+ Tests = rebar_prv_eunit:validate_tests(S, T),
+
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}},
- Error = rebar_prv_eunit:prepare_tests(State).
+ Error = Tests.
%% check that the --suite cmd line opt generates the correct test set
single_suite_arg(Config) ->
@@ -356,7 +366,7 @@ missing_suite_arg(Config) ->
State = rebar_state:command_parsed_args(S, Args),
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}},
- Error = rebar_prv_eunit:prepare_tests(State).
+ 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) ->
@@ -390,7 +400,7 @@ missing_file_arg(Config) ->
State = rebar_state:command_parsed_args(S, Args),
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["File `" ++ Path ++"' not found."]}}},
- Error = rebar_prv_eunit:prepare_tests(State).
+ Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)).
%% check that the --dir cmd line opt generates the correct test set
single_dir_arg(Config) ->
@@ -424,7 +434,7 @@ missing_dir_arg(Config) ->
State = rebar_state:command_parsed_args(S, Args),
Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Directory `" ++ Path ++"' not found."]}}},
- Error = rebar_prv_eunit:prepare_tests(State).
+ Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)).
%% check that multiple args are composed
multiple_arg_composition(Config) ->
@@ -470,11 +480,71 @@ multiple_arg_errors(Config) ->
"--dir=" ++ DirPath]),
State = rebar_state:command_parsed_args(S, Args),
+ T = rebar_prv_eunit:prepare_tests(State),
+ Tests = rebar_prv_eunit:validate_tests(S, T),
+
Expect = ["Application `missing_app' not found in project.",
"Directory `" ++ DirPath ++ "' not found.",
"File `" ++ FilePath ++ "' not found.",
"Module `missing_app' not found in project.",
"Module `missing_app' not found in project."],
- {error, {rebar_prv_eunit, {eunit_test_errors, Expect}}} = rebar_prv_eunit:prepare_tests(State).
+ {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.
diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl
index a061325..c1f85b3 100644
--- a/test/rebar_file_utils_SUITE.erl
+++ b/test/rebar_file_utils_SUITE.erl
@@ -97,10 +97,17 @@ path_from_ancestor(_Config) ->
?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo/bar/baz/qux")).
canonical_path(_Config) ->
- ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/")),
- ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/../../..")),
- ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/bar/..")),
- ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/../foo")),
- ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/.")),
- ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/./.")),
- ?assertEqual("/foo/bar", rebar_file_utils:canonical_path("/foo/./bar")). \ No newline at end of file
+ %% We find the root so that the name works both on unix-likes and
+ %% with Windows.
+ Root = case os:type() of
+ {win32, _} -> filename:nativename(filename:absname("/")); % C:\, with proper drive
+ _ -> "/"
+ end,
+ ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/")),
+ ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/../../..")),
+ ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/bar/..")),
+ ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/../foo")),
+ ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/.")),
+ ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")),
+ ?assertEqual(filename:nativename(Root ++ "foo/bar"),
+ rebar_file_utils:canonical_path("/foo/./bar")).
diff --git a/test/rebar_new_SUITE.erl b/test/rebar_new_SUITE.erl
index 3cee6f2..1971be6 100644
--- a/test/rebar_new_SUITE.erl
+++ b/test/rebar_new_SUITE.erl
@@ -6,9 +6,26 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-all() -> [app_git_user, app_hg_user, app_with_fallbacks].
+all() -> [app_git_user, app_hg_user, app_with_fallbacks,
+ app_with_flags1, app_with_flags2, plugin_tpl].
+init_per_testcase(plugin_tpl, Config) ->
+ application:load(rebar),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Name = rebar_test_utils:create_random_name("plugin_tpl"),
+ AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]),
+ ec_file:copy(filename:join([DataDir, "plugin_tpl"]), AppsDir, [recursive]),
+ Verbosity = rebar3:log_level(),
+ rebar_log:init(command_line, Verbosity),
+ GlobalDir = filename:join([DataDir, "cache"]),
+ State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
+ ,{global_rebar_dir, GlobalDir}
+ ,{root_dir, AppsDir}]),
+ mock_home_dir(DataDir),
+ mock_empty_escript_templates(),
+ [{apps, AppsDir}, {state, State}, {name, Name} | Config];
init_per_testcase(Case, Config0) ->
Config = rebar_test_utils:init_rebar_state(Config0),
Name = rebar_test_utils:create_random_name(atom_to_list(Case)),
@@ -95,11 +112,60 @@ app_hg_user(Config) ->
{filename:join(["src", Name++"_app.erl"]), [Name]}
]).
+app_with_flags1(Config) ->
+ Name = ?config(name, Config),
+ rebar_test_utils:run_and_check(
+ Config, [],
+ ["new", "test_app", "-f", Name],
+ {ok, []}
+ ),
+ validate_files(
+ Config, Name,
+ [{"LICENSE", []},
+ {"README.md", []},
+ {".gitignore", []},
+ {"rebar.config", []},
+ {filename:join(["src", Name++".app.src"]), [Name]},
+ {filename:join(["src", Name++"_sup.erl"]), [Name]},
+ {filename:join(["src", Name++"_app.erl"]), [Name]}
+ ]).
+
+app_with_flags2(Config) ->
+ Name = ?config(name, Config),
+ rebar_test_utils:run_and_check(
+ Config, [],
+ ["new", "-f", "test_app", Name],
+ {ok, []}
+ ),
+ validate_files(
+ Config, Name,
+ [{"LICENSE", []},
+ {"README.md", []},
+ {".gitignore", []},
+ {"rebar.config", []},
+ {filename:join(["src", Name++".app.src"]), [Name]},
+ {filename:join(["src", Name++"_sup.erl"]), [Name]},
+ {filename:join(["src", Name++"_app.erl"]), [Name]}
+ ]).
+
+plugin_tpl(Config) ->
+ Name = ?config(name, Config),
+ rebar_test_utils:run_and_check(
+ Config, [],
+ ["new", "-f", "tpl", Name],
+ {ok, []}
+ ),
+ Result = filename:join(["src", Name++".erl"]), % In CWD
+ {ok, Bin} = file:read_file(Result),
+ {match, _} = re:run(Bin, Name, [multiline,global]).
+
validate_files(_Config, Name, Checks) ->
[begin
Path = filename:join([Name, File]),
+ ct:pal("validating ~s for content", [Path]),
{ok, Bin} = file:read_file(Path),
[{match, _} = re:run(Bin, Pattern, [multiline,global])
|| Pattern <- Patterns]
end || {File, Patterns} <- Checks],
ok.
+
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl
new file mode 100644
index 0000000..41588ab
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl
@@ -0,0 +1,29 @@
+Copyright (c) {{copyright_year}}, {{author_name}} <{{author_email}}>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl
new file mode 100644
index 0000000..5507536
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl
@@ -0,0 +1,9 @@
+{{name}}
+=====
+
+{{desc}}
+
+Build
+-----
+
+ $ rebar3 compile
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl
new file mode 100644
index 0000000..83eb9a3
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl
@@ -0,0 +1,27 @@
+%%%-------------------------------------------------------------------
+%% @doc {{name}} public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module({{name}}_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2
+ ,stop/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ {{name}}_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template
new file mode 100644
index 0000000..50998cc
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template
@@ -0,0 +1,13 @@
+{description, "OTP Application"}.
+{variables, [
+ {name, "mylib", "Name of the OTP application"},
+ {desc, "An OTP application", "Short description of the app"}
+]}.
+bad_term,
+{template, "app.erl.dtl", "{{name}}/src/{{name}}_app.erl"}.
+{template, "sup.erl.dtl", "{{name}}/src/{{name}}_sup.erl"}.
+{template, "otp_app.app.src.dtl", "{{name}}/src/{{name}}.app.src"}.
+{template, "rebar.config.dtl", "{{name}}/rebar.config"}.
+{template, "gitignore.dtl", "{{name}}/.gitignore"}.
+{template, "LICENSE.dtl", "{{name}}/LICENSE"}.
+{template, "README.md.dtl", "{{name}}/README.md"}.
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl
new file mode 100644
index 0000000..40a1d4f
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl
@@ -0,0 +1,18 @@
+.rebar3
+_*
+.eunit
+*.o
+*.beam
+*.plt
+*.swp
+*.swo
+.erlang.cookie
+ebin
+log
+erl_crash.dump
+.rebar
+_rel
+_deps
+_plugins
+_tdeps
+logs
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl
new file mode 100644
index 0000000..5188f56
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl
@@ -0,0 +1,12 @@
+{application, {{name}},
+ [{description, "{{desc}}"}
+ ,{vsn, "0.1.0"}
+ ,{registered, []}
+ ,{mod, {'{{name}}_app', []}}
+ ,{applications,
+ [kernel
+ ,stdlib
+ ]}
+ ,{env,[]}
+ ,{modules, []}
+ ]}.
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl
new file mode 100644
index 0000000..f618f3e
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl
@@ -0,0 +1,2 @@
+{erl_opts, [debug_info]}.
+{deps, []}. \ No newline at end of file
diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl
new file mode 100644
index 0000000..a2e7209
--- /dev/null
+++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc {{name}} top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module({{name}}_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%====================================================================
+%% Supervisor callbacks
+%%====================================================================
+
+%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
+init([]) ->
+ {ok, { {one_for_all, 0, 1}, []} }.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore
new file mode 100644
index 0000000..a939dce
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore
@@ -0,0 +1,19 @@
+.rebar3
+_*
+.eunit
+*.o
+*.beam
+*.plt
+*.swp
+*.swo
+.erlang.cookie
+ebin
+log
+erl_crash.dump
+.rebar
+_rel
+_deps
+_plugins
+_tdeps
+logs
+_build \ No newline at end of file
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl
new file mode 100644
index 0000000..9129961
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl
@@ -0,0 +1,2 @@
+-module({{name}}).
+
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template
new file mode 100644
index 0000000..7fa4caf
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template
@@ -0,0 +1,7 @@
+{description, "A basic template"}.
+{variables, [
+ {name, "mod", "Name of the module"}
+]}.
+
+{dir, "test"}.
+{template, "module.erl.dtl", "src/{{name}}.erl"}.
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config
new file mode 100644
index 0000000..f618f3e
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config
@@ -0,0 +1,2 @@
+{erl_opts, [debug_info]}.
+{deps, []}. \ No newline at end of file
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src
new file mode 100644
index 0000000..6c6d811
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src
@@ -0,0 +1,15 @@
+{application, 'tpl',
+ [{description, "A rebar plugin"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {applications,
+ [kernel,
+ stdlib
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {contributors, []},
+ {licenses, []},
+ {links, []}
+ ]}.
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl
new file mode 100644
index 0000000..529bcb8
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl
@@ -0,0 +1,8 @@
+-module('tpl').
+
+-export([init/1]).
+
+-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
+init(State) ->
+ {ok, State1} = 'tpl_prv':init(State),
+ {ok, State1}.
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl
new file mode 100644
index 0000000..c68ffa3
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl
@@ -0,0 +1,32 @@
+-module('tpl_prv').
+
+-export([init/1, do/1, format_error/1]).
+
+-define(PROVIDER, 'tpl').
+-define(DEPS, [app_discovery]).
+
+%% ===================================================================
+%% Public API
+%% ===================================================================
+-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
+init(State) ->
+ Provider = providers:create([
+ {name, ?PROVIDER}, % The 'user friendly' name of the task
+ {module, ?MODULE}, % The module implementation of the task
+ {bare, true}, % The task can be run by the user, always true
+ {deps, ?DEPS}, % The list of dependencies
+ {example, "rebar3 tpl"}, % How to use the plugin
+ {opts, []}, % list of options understood by the plugin
+ {short_desc, "A rebar plugin"},
+ {desc, "A rebar plugin"}
+ ]),
+ {ok, rebar_state:add_provider(State, Provider)}.
+
+
+-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
+do(State) ->
+ {ok, State}.
+
+-spec format_error(any()) -> iolist().
+format_error(Reason) ->
+ io_lib:format("~p", [Reason]).
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/rebar.config b/test/rebar_new_SUITE_data/plugin_tpl/rebar.config
new file mode 100644
index 0000000..74d1fc5
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/rebar.config
@@ -0,0 +1,3 @@
+{erl_opts, [debug_info]}.
+{deps, []}.
+{plugins, [tpl]}.
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src
new file mode 100644
index 0000000..8f18874
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src
@@ -0,0 +1,15 @@
+{application, 'plugin_tpl',
+ [{description, "An OTP library"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {applications,
+ [kernel,
+ stdlib
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {contributors, []},
+ {licenses, []},
+ {links, []}
+ ]}.
diff --git a/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl
new file mode 100644
index 0000000..406bd97
--- /dev/null
+++ b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl
@@ -0,0 +1,13 @@
+-module('plugin_tpl').
+
+%% API exports
+-export([]).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl
index b3201ad..9f19e0d 100644
--- a/test/rebar_pkg_SUITE.erl
+++ b/test/rebar_pkg_SUITE.erl
@@ -11,7 +11,8 @@
-define(good_checksum, <<"1C6CE379D191FBAB41B7905075E0BF87CBBE23C77CECE775C5A0B786B2244C35">>).
all() -> [good_uncached, good_cached, badindexchk, badpkg,
- bad_to_good, good_disconnect, bad_disconnect, pkgs_provider].
+ bad_to_good, good_disconnect, bad_disconnect, pkgs_provider,
+ find_highest_matching].
init_per_suite(Config) ->
application:start(meck),
@@ -20,7 +21,19 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
application:stop(meck).
-init_per_testcase(pkgs_provider, Config) ->
+init_per_testcase(pkgs_provider=Name, Config) ->
+ %% Need to mock out a registry for this test now because it will try to update it automatically
+ Priv = ?config(priv_dir, Config),
+ Tid = ets:new(registry_table, [public]),
+ ets:insert_new(Tid, []),
+ CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]),
+ CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]),
+ filelib:ensure_dir(filename:join([CacheDir, "registry"])),
+ ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])),
+ meck:new(rebar_packages, [passthrough]),
+ meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end),
+ meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end),
+ rebar_prv_update:hex_to_index(rebar_state:new()),
Config;
init_per_testcase(good_uncached=Name, Config0) ->
Config = [{good_cache, false},
@@ -74,10 +87,13 @@ init_per_testcase(bad_disconnect=Name, Config0) ->
meck:unload(httpc),
meck:new(httpc, [passthrough, unsticky]),
meck:expect(httpc, request, fun(_, _, _, _, _) -> {error, econnrefused} end),
- Config.
-
-end_per_testcase(pkgs_provider, Config) ->
Config;
+init_per_testcase(Name, Config0) ->
+ Config = [{good_cache, false},
+ {pkg, {<<"goodpkg">>, <<"1.0.0">>}}
+ | Config0],
+ mock_config(Name, Config).
+
end_per_testcase(_, Config) ->
unmock_config(Config),
Config.
@@ -162,6 +178,16 @@ pkgs_provider(Config) ->
{ok, []}
).
+find_highest_matching(_Config) ->
+ State = rebar_state:new(),
+ {ok, Vsn} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"1.0.0">>, package_index, State),
+ ?assertEqual(<<"1.0.1">>, Vsn),
+ {ok, Vsn1} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"1.0">>, package_index, State),
+ ?assertEqual(<<"1.1.1">>, Vsn1),
+ {ok, Vsn2} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"2.0">>, package_index, State),
+ ?assertEqual(<<"2.0.0">>, Vsn2).
+
+
%%%%%%%%%%%%%%%
%%% Helpers %%%
%%%%%%%%%%%%%%%
@@ -172,10 +198,13 @@ mock_config(Name, Config) ->
Tid = ets:new(registry_table, [public]),
ets:insert_new(Tid, [
{<<"badindexchk">>,[[<<"1.0.0">>]]},
- {<<"goodpkg">>,[[<<"1.0.0">>]]},
+ {<<"goodpkg">>,[[<<"1.0.0">>, <<"1.0.1">>, <<"1.1.1">>, <<"2.0.0">>]]},
{<<"badpkg">>,[[<<"1.0.0">>]]},
{{<<"badindexchk">>,<<"1.0.0">>}, [[], ?bad_checksum, [<<"rebar3">>]]},
{{<<"goodpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]},
+ {{<<"goodpkg">>,<<"1.0.1">>}, [[], ?good_checksum, [<<"rebar3">>]]},
+ {{<<"goodpkg">>,<<"1.1.1">>}, [[], ?good_checksum, [<<"rebar3">>]]},
+ {{<<"goodpkg">>,<<"2.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]},
{{<<"badpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}
]),
CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]),
@@ -193,8 +222,8 @@ mock_config(Name, Config) ->
meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end),
meck:new(rebar_packages, [passthrough]),
- meck:expect(rebar_packages, registry_dir, fun(_) -> CacheDir end),
- meck:expect(rebar_packages, package_dir, fun(_) -> CacheDir end),
+ meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end),
+ meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end),
rebar_prv_update:hex_to_index(rebar_state:new()),
%% Cache fetches are mocked -- we assume the server and clients are
diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl
index f7fa5d4..fef2310 100644
--- a/test/rebar_pkg_alias_SUITE.erl
+++ b/test/rebar_pkg_alias_SUITE.erl
@@ -98,8 +98,8 @@ mock_config(Name, Config) ->
meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end),
meck:new(rebar_packages, [passthrough, no_link]),
- meck:expect(rebar_packages, registry_dir, fun(_) -> CacheDir end),
- meck:expect(rebar_packages, package_dir, fun(_) -> CacheDir end),
+ meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end),
+ meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end),
rebar_prv_update:hex_to_index(rebar_state:new()),
%% Cache fetches are mocked -- we assume the server and clients are
diff --git a/test/rebar_plugins_SUITE.erl b/test/rebar_plugins_SUITE.erl
index 3df3c0e..c1a98de 100644
--- a/test/rebar_plugins_SUITE.erl
+++ b/test/rebar_plugins_SUITE.erl
@@ -10,7 +10,9 @@
compile_global_plugins/1,
complex_plugins/1,
list/1,
- upgrade/1]).
+ upgrade/1,
+ sub_app_plugins/1,
+ sub_app_plugin_overrides/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -32,7 +34,7 @@ end_per_testcase(_, _Config) ->
catch meck:unload().
all() ->
- [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade].
+ [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade, sub_app_plugins, sub_app_plugin_overrides].
%% Tests that compiling a project installs and compiles the plugins of deps
compile_plugins(Config) ->
@@ -208,3 +210,74 @@ upgrade(Config) ->
Config, RConf, ["plugins", "upgrade", PkgName],
{ok, [{app, Name}, {plugin, PkgName, <<"0.1.3">>}]}
).
+
+sub_app_plugins(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("sub_app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+
+ DepName = rebar_test_utils:create_random_name("dep1_"),
+ PluginName = rebar_test_utils:create_random_name("plugin1_"),
+
+ mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []},
+ {{list_to_binary(PluginName), list_to_binary(Vsn)}, []}]}]),
+
+ SubAppsDir = filename:join([AppDir, "apps", Name]),
+
+ rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]),
+ rebar_test_utils:create_config(SubAppsDir, [{deps, [{list_to_binary(DepName), list_to_binary(Vsn)}]},
+ {plugins, [list_to_atom(PluginName)]}]),
+
+ RConfFile =
+ rebar_test_utils:create_config(AppDir,
+ [{deps, [
+ list_to_atom(DepName)
+ ]}]),
+ {ok, RConf} = file:consult(RConfFile),
+
+ %% Build with deps.
+ rebar_test_utils:run_and_check(
+ Config, RConf, ["compile"],
+ {ok, [{app, Name}, {dep, DepName}, {plugin, PluginName}]}
+ ).
+
+%% Tests that overrides in a dep that includes a plugin are applied to plugin fetching
+sub_app_plugin_overrides(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("sub_app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ Dep2Name = rebar_test_utils:create_random_name("dep2_"),
+
+ DepName = rebar_test_utils:create_random_name("dep1_"),
+ PluginName = rebar_test_utils:create_random_name("plugin1_"),
+ Vsn2 = rebar_test_utils:create_random_vsn(),
+
+ Deps = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, [{DepName, Vsn, []}]},
+ {DepName, Vsn, []}]),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+
+ mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(Dep2Name), list_to_binary(Vsn)}, []}]},
+ {config, [{plugins, [{list_to_atom(PluginName),
+ {git, "http://site.com/user/"++PluginName++".git",
+ {tag, Vsn}}}]},
+ %% Dep2 overrides the plugin's deps to have vsn2 of dep1
+ {overrides, [{override, list_to_atom(PluginName),
+ [{deps, [{list_to_atom(DepName),
+ {git, "http://site.com/user/"++DepName++".git",
+ {tag, Vsn2}}}]}]}]}]}]),
+
+ SubAppsDir = filename:join([AppDir, "apps", Name]),
+
+ rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]),
+
+ RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [{list_to_binary(Dep2Name), list_to_binary(Vsn)}]}]),
+ {ok, RConf} = file:consult(RConfFile),
+
+ %% Build with deps.
+ rebar_test_utils:run_and_check(
+ Config, RConf, ["compile"],
+ {ok, [{app, Name}, {dep, Dep2Name, Vsn}, {plugin, DepName, Vsn2}, {plugin, PluginName}]}
+ ).
diff --git a/test/rebar_release_SUITE.erl b/test/rebar_release_SUITE.erl
index f6fe8ff..1125a7e 100644
--- a/test/rebar_release_SUITE.erl
+++ b/test/rebar_release_SUITE.erl
@@ -4,11 +4,14 @@
-include_lib("eunit/include/eunit.hrl").
all() -> [release,
- dev_mode_release,
- profile_dev_mode_override_release,
- tar,
- extend_release,
- user_output_dir].
+ dev_mode_release,
+ profile_dev_mode_override_release,
+ tar,
+ profile_ordering_sys_config_extend,
+ profile_ordering_sys_config_extend_3_tuple_merge,
+ extend_release,
+ user_output_dir, profile_overlays,
+ overlay_vars].
init_per_testcase(Case, Config0) ->
Config = rebar_test_utils:init_rebar_state(Config0),
@@ -111,6 +114,63 @@ extend_release(Config) ->
{ok, [{release, extended, Vsn, false}]}
).
+%% Ensure proper ordering of sys_config and extended releases in profiles
+profile_ordering_sys_config_extend(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = ?config(name, Config),
+ Vsn = "1.0.0",
+ TestSysConfig = filename:join(AppDir, "test.config"),
+ OtherSysConfig = filename:join(AppDir, "other.config"),
+ ok = file:write_file(TestSysConfig, "[]."),
+ ok = file:write_file(OtherSysConfig, "[{some, content}]."),
+ {ok, RebarConfig} =
+ file:consult(rebar_test_utils:create_config(AppDir,
+ [{relx, [{release, {list_to_atom(Name), Vsn},
+ [list_to_atom(Name)]},
+ {sys_config, OtherSysConfig},
+ {lib_dirs, [AppDir]}]},
+ {profiles, [{extended,
+ [{relx, [
+ {sys_config, TestSysConfig}]}]}]}])),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig,
+ ["as", "extended", "release"],
+ {ok, [{release, list_to_atom(Name), Vsn, false}]}
+ ),
+
+ ReleaseDir = filename:join([AppDir, "./_build/extended/rel/", Name, "releases", Vsn]),
+ {ok, [[]]} = file:consult(filename:join(ReleaseDir, "sys.config")).
+
+%% test that tup_umerge works with tuples of different sizes
+profile_ordering_sys_config_extend_3_tuple_merge(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = ?config(name, Config),
+ Vsn = "1.0.0",
+ TestSysConfig = filename:join(AppDir, "test.config"),
+ OtherSysConfig = filename:join(AppDir, "other.config"),
+ ok = file:write_file(TestSysConfig, "[]."),
+ ok = file:write_file(OtherSysConfig, "[{some, content}]."),
+ {ok, RebarConfig} =
+ file:consult(rebar_test_utils:create_config(AppDir,
+ [{relx, [{release, {list_to_atom(Name), Vsn},
+ [list_to_atom(Name)]},
+ {sys_config, OtherSysConfig},
+ {lib_dirs, [AppDir]}]},
+ {profiles, [{extended,
+ [{relx, [
+ {release, {extended, Vsn, {extend, list_to_atom(Name)}},
+ []},
+ {sys_config, TestSysConfig}]}]}]}])),
+
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig,
+ ["as", "extended", "release", "-n", Name],
+ {ok, [{release, list_to_atom(Name), Vsn, false}]}
+ ),
+
+ ReleaseDir = filename:join([AppDir, "./_build/extended/rel/", Name, "releases", Vsn]),
+ {ok, [[]]} = file:consult(filename:join(ReleaseDir, "sys.config")).
+
user_output_dir(Config) ->
AppDir = ?config(apps, Config),
Name = ?config(name, Config),
@@ -134,3 +194,79 @@ user_output_dir(Config) ->
{ok, RelxState2} = rlx_prv_app_discover:do(RelxState1),
{ok, RelxState3} = rlx_prv_rel_discover:do(RelxState2),
rlx_state:get_realized_release(RelxState3, list_to_atom(Name), Vsn).
+
+profile_overlays(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = ?config(name, Config),
+ Vsn = "1.0.0",
+ {ok, RebarConfig} =
+ file:consult(rebar_test_utils:create_config(AppDir,
+ [{relx, [{release, {list_to_atom(Name), Vsn},
+ [list_to_atom(Name)]},
+ {overlay, [{mkdir, "randomdir"}]},
+ {lib_dirs, [AppDir]}]},
+ {profiles, [{prod, [{relx, [{overlay, [{mkdir, "otherrandomdir"}]}]}]}]}])),
+
+ ReleaseDir = filename:join([AppDir, "./_build/prod/rel/", Name]),
+
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig,
+ ["as", "prod", "release"],
+ {ok, [{release, list_to_atom(Name), Vsn, false},
+ {dir, filename:join(ReleaseDir, "otherrandomdir")},
+ {dir, filename:join(ReleaseDir, "randomdir")}]}
+ ).
+
+overlay_vars(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = ?config(name, Config),
+ Vsn = "1.0.0",
+ {ok, RebarConfig} =
+ file:consult(rebar_test_utils:create_config(AppDir,
+ [{relx, [{release, {list_to_atom(Name), Vsn},
+ [list_to_atom(Name)]},
+ {overlay, [
+ {template, filename:join([AppDir, "config/app.config"]),
+ "releases/{{release_version}}/sys.config"}
+ ]},
+ {overlay_vars, filename:join([AppDir, "config/vars.config"])},
+ {lib_dirs, [AppDir]}]}
+ ])),
+
+ ok = filelib:ensure_dir(filename:join([AppDir, "config", "dummy"])),
+
+ OverlayVars = [{var_int, 1},
+ {var_string, "\"test\""},
+ {var_bin_string, "<<\"test\">>"},
+ {var_tuple, "{t, ['atom']}"},
+ {var_list, "[a, b, c, 'd']"},
+ {var_bin, "<<23, 24, 25>>"}],
+ rebar_test_utils:create_config(AppDir,
+ filename:join([AppDir, "config", "vars.config"]),
+ OverlayVars),
+
+ AppConfig = [[{var_int, {{var_int}}},
+ {var_string, {{{var_string}}}},
+ {var_bin_string, {{{var_bin_string}}}},
+ {var_tuple, {{{var_tuple}}}},
+ {var_list, {{{var_list}}}},
+ {var_bin, {{{var_bin}}}}]],
+ rebar_test_utils:create_config(AppDir,
+ filename:join([AppDir, "config", "app.config"]),
+ AppConfig),
+
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig,
+ ["release"],
+ {ok, [{release, list_to_atom(Name), Vsn, false}]}),
+
+ %% now consult the sys.config file to make sure that is has the expected
+ %% format
+ ExpectedSysconfig = [{var_int, 1},
+ {var_string, "test"},
+ {var_bin_string, <<"test">>},
+ {var_tuple, {t, ['atom']}},
+ {var_list, [a, b, c, 'd']},
+ {var_bin, <<23, 24, 25>>}],
+ {ok, [ExpectedSysconfig]} = file:consult(filename:join([AppDir, "_build/default/rel",
+ Name, "releases", Vsn, "sys.config"])).
diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl
index 3943db7..5187bda 100644
--- a/test/rebar_test_utils.erl
+++ b/test/rebar_test_utils.erl
@@ -3,8 +3,8 @@
-include_lib("eunit/include/eunit.hrl").
-export([init_rebar_state/1, init_rebar_state/2, run_and_check/4, check_results/3]).
-export([expand_deps/2, flat_deps/1, top_level_deps/1]).
--export([create_app/4, create_eunit_app/4, create_empty_app/4, create_config/2,
- package_app/3]).
+-export([create_app/4, create_eunit_app/4, create_empty_app/4,
+ create_config/2, create_config/3, package_app/3]).
-export([create_random_name/1, create_random_vsn/0, write_src_file/2]).
%%%%%%%%%%%%%%
@@ -104,11 +104,14 @@ create_empty_app(AppDir, Name, Vsn, Deps) ->
%% each of which will be dumped as a consult file. For example, the list
%% `[a, b, c]' will return the consult file `a. b. c.'.
create_config(AppDir, Contents) ->
- Conf = filename:join([AppDir, "rebar.config"]),
- ok = filelib:ensure_dir(Conf),
+ ConfFilename = filename:join([AppDir, "rebar.config"]),
+ create_config(AppDir, ConfFilename, Contents).
+
+create_config(_AppDir, ConfFilename, Contents) ->
+ ok = filelib:ensure_dir(ConfFilename),
Config = lists:flatten([io_lib:fwrite("~p.~n", [Term]) || Term <- Contents]),
- ok = ec_file:write(Conf, Config),
- Conf.
+ ok = ec_file:write(ConfFilename, Config),
+ ConfFilename.
%% @doc Util to create a random variation of a given name.
create_random_name(Name) ->
diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl
index 24e8afe..b32992d 100644
--- a/test/rebar_utils_SUITE.erl
+++ b/test/rebar_utils_SUITE.erl
@@ -30,7 +30,8 @@
invalid_otp_version/1,
nonblacklisted_otp_version/1,
blacklisted_otp_version/1,
- sh_does_not_miss_messages/1]).
+ sh_does_not_miss_messages/1,
+ tup_merge/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -44,7 +45,8 @@ end_per_testcase(_, _Config) ->
all() ->
[{group, args_to_tasks},
- sh_does_not_miss_messages].
+ sh_does_not_miss_messages,
+ tup_merge].
groups() ->
[{args_to_tasks, [], [empty_arglist,
@@ -198,3 +200,75 @@ sh_does_not_miss_messages(_Config) ->
false
end,
AnyMessageRemained = false.
+
+tup_merge(_Config) ->
+ ?assertEqual(
+ [a,{a,a},{a,a,a},{a,b},{a,b,b},b,{b,a},{b,a,a},{b,b},{b,b,b},z,{z,a},{z,a,a},{z,b},{z,b,b}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}]),
+ rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}])
+ )
+ ),
+ ?assertEqual(
+ [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}]),
+ rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}])
+ )
+ ),
+ ?assertEqual(
+ [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([a,b,z,{a,b},{b,b},{z,b},{a,b,b},{b,b,b},{z,b,b}]),
+ rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}])
+ )
+ ),
+ ?assertEqual(
+ [{a,b},a,{a,b,b},{a,a},{a,a,a},{b,b},b,{b,b,b},{b,a},{b,a,a},{z,b},z,{z,b,b},{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{a,b},{b,b},{z,b},a,b,z,{a,b,b},{b,b,b},{z,b,b}]),
+ rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}])
+ )
+ ),
+ ?assertEqual(
+ [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}]),
+ rebar_utils:tup_sort([{a,a},a,{a,a,a},{b,a},b,{b,a,a},{z,a},z,{z,a,a}])
+ )
+ ),
+ ?assertEqual(
+ [{a,b},a,{a,b,b},{a,a},{a,a,a},{b,b},b,{b,b,b},{b,a},{b,a,a},{z,b},z,{z,b,b},{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{a,b},{b,b},{z,b},a,b,z,{a,b,b},{b,b,b},{z,b,b}]),
+ rebar_utils:tup_sort([{a,a},a,{a,a,a},{b,a},b,{b,a,a},{z,a},z,{z,a,a}])
+ )
+ ),
+ ?assertEqual(
+ [{a,b},{a,b,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a},{b,a,a},{z,b},{z,b,b},z,{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{a,b},{a,b,b},{b,b},{b,b,b},{z,b},{z,b,b},a,b,z]),
+ rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a},{b,a,a},b,{z,a},{z,a,a},z])
+ )
+ ),
+ ?assertEqual(
+ [{a,b},{a,b,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a},{b,a,a},{z,b},{z,b,b},z,{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{a,b},{a,b,b},{b,b},{b,b,b},{z,b},{z,b,b},a,b,z]),
+ rebar_utils:tup_sort([{a,a},{a,b},{a,a,a},{a,b,b},a,{b,a},{b,a,a},b,{z,a},{z,a,a},z])
+ )
+ ),
+ ?assertEqual(
+ [{l, a}, {r, a, b}, {s, a}, {s, b}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{r, a, b}, {s, a}, {l, a}]),
+ rebar_utils:tup_sort([{s, b}])
+ )
+ ),
+ ?assertEqual(
+ [{a,b,b},{a,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a,a},{b,a},{z,b},{z,b,b},z,{z,a},{z,a,a}],
+ rebar_utils:tup_umerge(
+ rebar_utils:tup_sort([{a,b,b},{b,b},{a,b},{b,b,b},{z,b},{z,b,b},a,b,z]),
+ rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a,a},b,{z,a},{z,a,a},{b,a},z])
+ )
+ ).