summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/rebar_compile_SUITE.erl144
-rw-r--r--test/rebar_edoc_SUITE.erl22
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src16
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl9
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl26
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl35
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src16
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl12
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl26
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl35
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src17
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl19
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl26
-rw-r--r--test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl35
-rw-r--r--test/rebar_file_utils_SUITE.erl190
15 files changed, 619 insertions, 9 deletions
diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl
index 3e4d5b9..9f01496 100644
--- a/test/rebar_compile_SUITE.erl
+++ b/test/rebar_compile_SUITE.erl
@@ -44,10 +44,13 @@
include_file_in_src/1,
include_file_relative_to_working_directory_test/1,
include_file_in_src_test/1,
+ dont_recompile_when_erl_compiler_options_env_does_not_change/1,
+ recompile_when_erl_compiler_options_env_changes/1,
always_recompile_when_erl_compiler_options_set/1,
recompile_when_parse_transform_inline_changes/1,
recompile_when_parse_transform_as_opt_changes/1,
- recursive/1,no_recursive/1]).
+ recursive/1,no_recursive/1,
+ regex_filter_skip/1, regex_filter_regression/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -74,10 +77,21 @@ all() ->
include_file_relative_to_working_directory_test, include_file_in_src_test,
recompile_when_parse_transform_as_opt_changes,
recompile_when_parse_transform_inline_changes,
- recursive, no_recursive] ++
- case erlang:function_exported(os, unsetenv, 1) of
- true -> [always_recompile_when_erl_compiler_options_set];
- false -> []
+ regex_filter_skip, regex_filter_regression,
+ %% recompile behaviour when `ERL_COMPILER_OPTIONS` differs prior to 19.x
+ recursive, no_recursive] ++ recompile_when_env_changes_test().
+
+recompile_when_env_changes_test() ->
+ _ = code:ensure_loaded(os),
+ UnSetEnv = erlang:function_exported(os, unsetenv, 1),
+ _ = code:ensure_loaded(compile),
+ EnvOpts = erlang:function_exported(compile, env_compiler_options, 0),
+ case {UnSetEnv, EnvOpts} of
+ {true, true} ->
+ [dont_recompile_when_erl_compiler_options_env_does_not_change,
+ recompile_when_erl_compiler_options_env_changes];
+ {true, false} -> [always_recompile_when_erl_compiler_options_set];
+ {false, _} -> []
end.
groups() ->
@@ -1385,7 +1399,51 @@ include_file_in_src_test(Config) ->
["as", "test", "compile"],
{ok, [{app, Name}]}).
-always_recompile_when_erl_compiler_options_set(Config) ->
+%% this test sets the env var, compiles, records the file last modified timestamp,
+%% recompiles and compares the file last modified timestamp to ensure it hasn't
+%% changed. this test should run on 19.x+
+dont_recompile_when_erl_compiler_options_env_does_not_change(Config) ->
+ %% save existing env to restore after test
+ ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
+
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ true = os:unsetenv("ERL_COMPILER_OPTIONS"),
+
+ true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
+
+ rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
+
+ EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
+
+ {ok, Files} = rebar_utils:list_dir(EbinDir),
+ ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
+ || F <- Files, filename:extension(F) == ".beam"],
+
+ timer:sleep(1000),
+
+ rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
+
+ {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
+ NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
+ || F <- NewFiles, filename:extension(F) == ".beam"],
+
+ ?assert(ModTime == NewModTime),
+
+ %% restore existing env
+ case ExistingEnv of
+ false -> ok;
+ _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
+ end.
+
+%% this test compiles, records the file last modified timestamp, sets the env
+%% var, recompiles and compares the file last modified timestamp to ensure it
+%% has changed. this test should run on 19.x+
+recompile_when_erl_compiler_options_env_changes(Config) ->
%% save existing env to restore after test
ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
@@ -1423,6 +1481,47 @@ always_recompile_when_erl_compiler_options_set(Config) ->
_ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
end.
+%% this test sets the env var, compiles, records the file last modified
+%% timestamp, recompiles and compares the file last modified timestamp to
+%% ensure it has changed. this test should run on 18.x
+always_recompile_when_erl_compiler_options_set(Config) ->
+ %% save existing env to restore after test
+ ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
+
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ true = os:unsetenv("ERL_COMPILER_OPTIONS"),
+
+ true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
+
+ rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
+
+ EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
+
+ {ok, Files} = rebar_utils:list_dir(EbinDir),
+ ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
+ || F <- Files, filename:extension(F) == ".beam"],
+
+ timer:sleep(1000),
+
+ rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
+
+ {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
+ NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
+ || F <- NewFiles, filename:extension(F) == ".beam"],
+
+ ?assert(ModTime =/= NewModTime),
+
+ %% restore existing env
+ case ExistingEnv of
+ false -> ok;
+ _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
+ end.
+
recompile_when_parse_transform_inline_changes(Config) ->
AppDir = ?config(apps, Config),
@@ -1556,5 +1655,38 @@ no_recursive(Config) ->
{ok, [{app, Name}]}),
{ok, Files2} = rebar_utils:list_dir(EbinDir),
?assert(false==lists:member("rec.beam",Files2)),
+ ok.
+
+regex_filter_skip(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = rebar_test_utils:create_random_name("regex_skip"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+ rebar_test_utils:write_src_file(filename:join(AppDir,src),"._rec.erl"),
+ Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","._rec.beam"]),
+
+ RebarConfig = [],
+ try
+ rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"],
+ {ok, [{file, Expected}]}),
+ throw(should_not_be_found)
+ catch
+ %% the file was not found, as desired!
+ error:{assertion_failed,_} -> %% OTP =< 17
+ ok;
+ error:{assert,_} -> %% OTP >= 18
+ ok
+ end.
+regex_filter_regression(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = rebar_test_utils:create_random_name("regex_regression"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+ rebar_test_utils:write_src_file(filename:join(AppDir,src),"r_f.erl"),
+ Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","r_f.beam"]),
+ RebarConfig = [],
+ rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"],
+ {ok, [{file, Expected}]}),
ok.
+
diff --git a/test/rebar_edoc_SUITE.erl b/test/rebar_edoc_SUITE.erl
index fded2b0..2c4aba5 100644
--- a/test/rebar_edoc_SUITE.erl
+++ b/test/rebar_edoc_SUITE.erl
@@ -3,7 +3,7 @@
-include_lib("eunit/include/eunit.hrl").
-compile(export_all).
-all() -> [multiapp].
+all() -> [multiapp, error_survival].
init_per_testcase(multiapp, Config) ->
application:load(rebar),
@@ -16,6 +16,18 @@ init_per_testcase(multiapp, Config) ->
rebar_log:init(command_line, Verbosity),
State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
,{root_dir, AppsDir}]),
+ [{apps, AppsDir}, {state, State}, {name, Name} | Config];
+init_per_testcase(error_survival, Config) ->
+ application:load(rebar),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Name = rebar_test_utils:create_random_name("error_survival"),
+ AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]),
+ ec_file:copy(filename:join([DataDir, "bad"]), AppsDir, [recursive]),
+ Verbosity = rebar3:log_level(),
+ rebar_log:init(command_line, Verbosity),
+ State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
+ ,{root_dir, AppsDir}]),
[{apps, AppsDir}, {state, State}, {name, Name} | Config].
end_per_testcase(_, Config) ->
@@ -42,6 +54,14 @@ multiapp(Config) ->
filename:join([AppsDir, "apps", "foo", "doc", "foo.html"]),
"apps/bar1/doc/bar1.html")).
+error_survival(Config) ->
+ RebarConfig = [],
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["edoc"],
+ {error,{rebar_prv_edoc,{app_failed,"bar2"}}}
+ ),
+ ok.
+
file_content_matches(Path, Regex) ->
case file:read_file(Path) of
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src
new file mode 100644
index 0000000..6e7ec24
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src
@@ -0,0 +1,16 @@
+{application, bar1,
+ [{description, "An OTP application"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {mod, { bar1_app, []}},
+ {applications,
+ [kernel,
+ stdlib
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {maintainers, []},
+ {licenses, []},
+ {links, []}
+ ]}.
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl
new file mode 100644
index 0000000..2700aef
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl
@@ -0,0 +1,9 @@
+-module(bar1).
+-export([bar1/0]).
+-export_type([barer1/0]).
+
+-type barer1() :: string().
+
+% @doc Bar1 bars the bar.
+-spec bar1() -> barer1().
+bar1() -> "Barer1". \ No newline at end of file
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl
new file mode 100644
index 0000000..414ac30
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl
@@ -0,0 +1,26 @@
+%%%-------------------------------------------------------------------
+%% @doc bar1 public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(bar1_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ bar1_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl
new file mode 100644
index 0000000..f9d6670
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc bar1 top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(bar1_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_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src
new file mode 100644
index 0000000..58de8bc
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src
@@ -0,0 +1,16 @@
+{application, bar2,
+ [{description, "An OTP application"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {mod, { bar2_app, []}},
+ {applications,
+ [kernel,
+ stdlib
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {maintainers, []},
+ {licenses, []},
+ {links, []}
+ ]}.
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl
new file mode 100644
index 0000000..2afb745
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl
@@ -0,0 +1,12 @@
+%% @doc one docline is fine
+%% @doc a second docline causes a failure
+%% @doc if not, then a & causes a bad ref error.
+-module(bar2).
+-export([bar2/0]).
+-export_type([barer2/0]).
+
+-type barer2() :: string().
+
+% @doc Bar2 bars the bar2.
+-spec bar2() -> barer2().
+bar2() -> "Barer2".
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl
new file mode 100644
index 0000000..d0058a0
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl
@@ -0,0 +1,26 @@
+%%%-------------------------------------------------------------------
+%% @doc bar2 public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(bar2_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ bar2_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl
new file mode 100644
index 0000000..0bdaf4a
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc bar2 top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(bar2_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_edoc_SUITE_data/bad/apps/foo/src/foo.app.src b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src
new file mode 100644
index 0000000..9987fd5
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src
@@ -0,0 +1,17 @@
+{application, foo,
+ [{description, "An OTP application"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {mod, { foo_app, []}},
+ {applications,
+ [kernel,
+ stdlib,
+ bar1, bar2
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {maintainers, []},
+ {licenses, []},
+ {links, []}
+ ]}.
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl
new file mode 100644
index 0000000..52e3d0a
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl
@@ -0,0 +1,19 @@
+-module(foo).
+
+-export([foo/0, bar1/0, bar2/0]).
+
+-export_type([fooer/0]).
+
+-type fooer() :: string().
+
+% @doc Foo function returns fooer.
+-spec foo() -> fooer().
+foo() -> "fooer".
+
+% @doc Bar1 function returns barer1.
+-spec bar1() -> bar1:barer1().
+bar1() -> bar1:bar1().
+
+% @doc Bar2 functions returns barer2.
+-spec bar2() -> bar2:barer2().
+bar2() -> bar2:bar2(). \ No newline at end of file
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl
new file mode 100644
index 0000000..d0158d7
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl
@@ -0,0 +1,26 @@
+%%%-------------------------------------------------------------------
+%% @doc foo public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(foo_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ foo_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl
new file mode 100644
index 0000000..67e88b4
--- /dev/null
+++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc foo top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(foo_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_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl
index 7285e13..4cc6a93 100644
--- a/test/rebar_file_utils_SUITE.erl
+++ b/test/rebar_file_utils_SUITE.erl
@@ -4,6 +4,8 @@
groups/0,
init_per_group/2,
end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
raw_tmpdir/1,
empty_tmpdir/1,
simple_tmpdir/1,
@@ -15,7 +17,13 @@
canonical_path/1,
resolve_link/1,
split_dirname/1,
- mv_warning_is_ignored/1]).
+ mv_warning_is_ignored/1,
+ mv_dir/1,
+ mv_file_same/1,
+ mv_file_diff/1,
+ mv_file_dir_same/1,
+ mv_file_dir_diff/1,
+ mv_no_clobber/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -25,6 +33,7 @@
all() ->
[{group, tmpdir},
{group, reset_dir},
+ {group, mv},
path_from_ancestor,
canonical_path,
resolve_link,
@@ -33,7 +42,9 @@ all() ->
groups() ->
[{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]},
- {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]}].
+ {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]},
+ {mv, [], [mv_dir, mv_file_same, mv_file_diff,
+ mv_file_dir_same, mv_file_dir_diff, mv_no_clobber]}].
init_per_group(reset_dir, Config) ->
TmpDir = rebar_file_utils:system_tmpdir(["rebar_file_utils_SUITE", "resetable"]),
@@ -41,6 +52,20 @@ init_per_group(reset_dir, Config) ->
init_per_group(_, Config) -> Config.
end_per_group(_, Config) -> Config.
+init_per_testcase(Test, Config) ->
+ case os:type() of
+ {win32, _} ->
+ case lists:member(Test, [resolve_link, mv_warning_is_ignored]) of
+ true -> {skip, "broken in windows"};
+ false -> Config
+ end;
+ _ ->
+ Config
+ end.
+
+end_per_testcase(_Test, Config) ->
+ Config.
+
raw_tmpdir(_Config) ->
case rebar_file_utils:system_tmpdir() of
"/tmp" -> ok;
@@ -143,3 +168,164 @@ mv_warning_is_ignored(_Config) ->
meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end),
ok = rebar_file_utils:mv("ding", "dong"),
meck:unload(rebar_utils).
+
+%%% Ensure Windows & Unix operations to move files
+
+mv_dir(Config) ->
+ %% Move a directory to another one location
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_dir),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ %% empty dir movement
+ DstDir1 = filename:join(BaseDir, "dst1/"),
+ ?assertNot(filelib:is_dir(DstDir1)),
+ ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir1)),
+ ?assert(filelib:is_dir(DstDir1)),
+
+ %% move files from dir to empty dir
+ F1 = filename:join(SrcDir, "file1"),
+ F2 = filename:join(SrcDir, "subdir/file2"),
+ filelib:ensure_dir(F2),
+ file:write_file(F1, "hello"),
+ file:write_file(F2, "world"),
+ DstDir2 = filename:join(BaseDir, "dst2/"),
+ D2F1 = filename:join(DstDir2, "file1"),
+ D2F2 = filename:join(DstDir2, "subdir/file2"),
+ ?assertNot(filelib:is_dir(DstDir2)),
+ ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)),
+ ?assert(filelib:is_file(D2F1)),
+ ?assert(filelib:is_file(D2F2)),
+
+ %% move files from dir to existing dir moves it to
+ %% a subdir
+ filelib:ensure_dir(F2),
+ file:write_file(F1, "hello"),
+ file:write_file(F2, "world"),
+ DstDir3 = filename:join(BaseDir, "dst3/"),
+ D3F1 = filename:join(DstDir3, "src/file1"),
+ D3F2 = filename:join(DstDir3, "src/subdir/file2"),
+ ec_file:mkdir_p(DstDir3),
+ ?assert(filelib:is_dir(DstDir3)),
+ ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)),
+ ?assertNot(filelib:is_file(F1)),
+ ?assertNot(filelib:is_file(F2)),
+ ?assert(filelib:is_file(D3F1)),
+ ?assert(filelib:is_file(D3F2)),
+ ?assertNot(filelib:is_dir(SrcDir)),
+ ok.
+
+mv_file_same(Config) ->
+ %% Move a file from a directory to the other without renaming
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_file_same),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ F = filename:join(SrcDir, "file"),
+ file:write_file(F, "hello"),
+ DstDir = filename:join(BaseDir, "dst/"),
+ ec_file:mkdir_p(DstDir),
+ Dst = filename:join(DstDir, "file"),
+ ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
+ ?assert(filelib:is_file(Dst)),
+ ?assertNot(filelib:is_file(F)),
+ ok.
+
+mv_file_diff(Config) ->
+ %% Move a file from a directory to another one while renaming
+ %% into a pre-existing file
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_file_diff),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ F = filename:join(SrcDir, "file"),
+ file:write_file(F, "hello"),
+ DstDir = filename:join(BaseDir, "dst/"),
+ ec_file:mkdir_p(DstDir),
+ Dst = filename:join(DstDir, "file-rename"),
+ file:write_file(Dst, "not-the-right-content"),
+ ?assert(filelib:is_file(Dst)),
+ ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
+ ?assert(filelib:is_file(Dst)),
+ ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
+ ?assertNot(filelib:is_file(F)),
+ ok.
+
+mv_file_dir_same(Config) ->
+ %% Move a file to a directory without renaming
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_file_dir_same),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ F = filename:join(SrcDir, "file"),
+ file:write_file(F, "hello"),
+ DstDir = filename:join(BaseDir, "dst/"),
+ ec_file:mkdir_p(DstDir),
+ Dst = filename:join(DstDir, "file"),
+ ?assert(filelib:is_dir(DstDir)),
+ ?assertEqual(ok, rebar_file_utils:mv(F, DstDir)),
+ ?assert(filelib:is_file(Dst)),
+ ?assertNot(filelib:is_file(F)),
+ ok.
+
+mv_file_dir_diff(Config) ->
+ %% Move a file to a directory while renaming
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_file_dir_diff),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ F = filename:join(SrcDir, "file"),
+ file:write_file(F, "hello"),
+ DstDir = filename:join(BaseDir, "dst/"),
+ ec_file:mkdir_p(DstDir),
+ Dst = filename:join(DstDir, "file-rename"),
+ ?assert(filelib:is_dir(DstDir)),
+ ?assertNot(filelib:is_file(Dst)),
+ ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
+ ?assert(filelib:is_file(Dst)),
+ ?assertNot(filelib:is_file(F)),
+ ok.
+
+mv_no_clobber(Config) ->
+ %% Moving a file while renaming does not clobber other files
+ PrivDir = ?config(priv_dir, Config),
+ BaseDir = mk_base_dir(PrivDir, mv_no_clobber),
+ SrcDir = filename:join(BaseDir, "src/"),
+ ec_file:mkdir_p(SrcDir),
+ ?assert(filelib:is_dir(SrcDir)),
+ F = filename:join(SrcDir, "file"),
+ file:write_file(F, "hello"),
+ FBad = filename:join(SrcDir, "file-alt"),
+ file:write_file(FBad, "wrong-data"),
+ DstDir = filename:join(BaseDir, "dst/"),
+ ec_file:mkdir_p(DstDir),
+ Dst = filename:join(DstDir, "file-alt"),
+ DstBad = filename:join(DstDir, "file"),
+ file:write_file(DstBad, "wrong-data"),
+ ?assert(filelib:is_file(F)),
+ ?assert(filelib:is_file(FBad)),
+ ?assert(filelib:is_dir(DstDir)),
+ ?assertNot(filelib:is_file(Dst)),
+ ?assert(filelib:is_file(DstBad)),
+ ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
+ ?assert(filelib:is_file(Dst)),
+ ?assertNot(filelib:is_file(F)),
+ ?assert(filelib:is_file(DstBad)),
+ ?assert(filelib:is_file(FBad)),
+ ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
+ ?assertEqual({ok, <<"wrong-data">>}, file:read_file(FBad)),
+ ?assertEqual({ok, <<"wrong-data">>}, file:read_file(DstBad)),
+ ok.
+
+
+mk_base_dir(BasePath, Name) ->
+ {_,_,Micro} = os:timestamp(),
+ Index = integer_to_list(Micro),
+ Path = filename:join(BasePath, atom_to_list(Name) ++ Index),
+ ec_file:mkdir_p(Path),
+ Path.