1%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
2%% ex: ts=4 sw=4 et
3%% -------------------------------------------------------------------
4%%
5%% rebar: Erlang Build Tools
6%%
7%% Copyright (c) 2014 Vlad Dumitrescu (vladdu55@gmail.com)
8%%
9%% Permission is hereby granted, free of charge, to any person obtaining a copy
10%% of this software and associated documentation files (the "Software"), to deal
11%% in the Software without restriction, including without limitation the rights
12%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13%% copies of the Software, and to permit persons to whom the Software is
14%% furnished to do so, subject to the following conditions:
15%%
16%% The above copyright notice and this permission notice shall be included in
17%% all copies or substantial portions of the Software.
18%%
19%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25%% THE SOFTWARE.
26%% -------------------------------------------------------------------
27%% @author Vlad Dumitrescu <vladdu55@gmail.com>
28%% @author Chris Bernard <cebernard@gmail.com>
29%% @doc This tests functionality provided by the rebar command 'compile'.
30%% -------------------------------------------------------------------
31-module(rebar_compiler_tests).
32
33-compile(export_all).
34
35-include_lib("eunit/include/eunit.hrl").
36
37%% Assuming this test is run inside the rebar 'eunit'
38%% command, the current working directory will be '.eunit'
39-define(REBAR_SCRIPT, "../rebar").
40
41-define(TMP_DIR, "tmp_eunit/").
42
43%% ====================================================================
44%% Rebar compiler tests
45%% ====================================================================
46
47keep_going_test_() ->
48    {"Ensure compiler keeps going after finding errors, when --keep-going is requested",
49     setup,
50     fun() ->
51             setup_basic_project(),
52             rebar("-k compile")
53     end,
54     fun teardown/1,
55     fun(RebarOut)->
56             [
57              {"Continue after error",
58               ?_assert(string:str(RebarOut, "Continuing after build error") =/= 0)},
59              ?_assert(string:str(RebarOut, "ERROR: compile failed") == 0)
60             ] ++ assert_files_in("ebin", ["ebin/myapp_mymod2.beam"])
61     end
62    }.
63
64keep_going_firstfiles_test_() ->
65    {"Ensure compiler keeps going after finding errors in erl_first_files, when --keep-going is requested",
66     setup,
67     fun() ->
68             setup_basic_project(),
69             setup_rebar_config(),
70             rebar("-k compile")
71     end,
72     fun teardown/1,
73     fun(RebarOut)->
74             [
75              {"Continue after error",
76               ?_assert(string:str(RebarOut, "Continuing after build error") =/= 0)},
77              ?_assert(string:str(RebarOut, "ERROR: compile failed") == 0)
78             ] ++ assert_files_in("ebin", ["ebin/myapp_mymod2.beam"])
79     end
80    }.
81
82not_keep_going_test_() ->
83    {"Ensure compiler stops after finding errors",
84     setup,
85     fun() ->
86             setup_basic_project(),
87             setup_rebar_config()
88     end,
89     fun teardown/1,
90     fun()->
91             RebarOut = rebar("compile"),
92             [
93              {"Exit after error",
94               ?_assert(string:str(RebarOut, "ERROR: compile failed") =/= 0)}
95             ] ++ assert_files_not_in("ebin", ["ebin/myapp_mymod2.beam"])
96     end
97    }.
98
99%% ====================================================================
100%% Setup and Teardown
101%% ====================================================================
102
103-define(rebar_config,
104        ["{erl_first_files, [\"src/myapp_mymod1.erl\"]}."
105        ]).
106
107%% this file has a syntax error
108-define(myapp_mymod1,
109        ["-module(myapp_mymod1).\n",
110         "-export([myfunc/0]).\n",
111         "my func() -> [4], ok.\n"]).
112
113-define(myapp_mymod2,
114        ["-module(myapp_mymod2).\n",
115         "-export([myfunc/0]).\n",
116         "myfunc() -> [4], ok.\n"]).
117
118
119make_tmp_dir() ->
120    case file:make_dir(?TMP_DIR) of
121        ok ->
122            ok;
123        {error, eexist} ->
124            remove_tmp_dir(),
125            make_tmp_dir();
126        Error ->
127            throw(Error)
128    end.
129
130setup_environment() ->
131    ok = make_tmp_dir(),
132    prepare_rebar_script(),
133    ok = file:set_cwd(?TMP_DIR).
134
135setup_rebar_config() ->
136    ok = file:write_file("rebar.config", ?rebar_config).
137
138setup_basic_project() ->
139    setup_environment(),
140    rebar("create-app appid=myapp"),
141    ok = file:make_dir("ebin"),
142    ok = file:write_file("src/myapp_mymod1.erl", ?myapp_mymod1),
143    ok = file:write_file("src/myapp_mymod2.erl", ?myapp_mymod2).
144
145teardown(_) ->
146    ok = file:set_cwd(".."),
147    ok = remove_tmp_dir().
148
149remove_tmp_dir() ->
150    remove_tmp_dir(arg_for_eunit).
151
152remove_tmp_dir(_) ->
153    ok = rebar_file_utils:rm_rf(?TMP_DIR).
154
155%% ====================================================================
156%% Helper Functions
157%% ====================================================================
158
159prepare_rebar_script() ->
160    Rebar = ?TMP_DIR ++ "rebar",
161    {ok, _} = file:copy(?REBAR_SCRIPT, Rebar),
162    case os:type() of
163        {unix, _} ->
164            [] = os:cmd("chmod u+x " ++ Rebar);
165        {win32, _} ->
166            {ok, _} = file:copy(?REBAR_SCRIPT ++ ".cmd",
167                                ?TMP_DIR ++ "rebar.cmd")
168    end.
169
170rebar() ->
171    rebar([]).
172
173rebar(Args) when is_list(Args) ->
174    Out = os:cmd(filename:nativename("./rebar") ++ " " ++ Args),
175    %% ?debugMsg("**** Begin"), ?debugMsg(Out), ?debugMsg("**** End"),
176    Out.
177
178assert_dirs_in(Name, [Dir|T]) ->
179    [{Name ++ " has directory: " ++ Dir, ?_assert(filelib:is_dir(Dir))} |
180         assert_dirs_in(Name, T)];
181assert_dirs_in(_, []) -> [].
182
183assert_files_in(Name, [File|T]) ->
184    [{Name ++ " has file: " ++ File, ?_assert(filelib:is_regular(File))} |
185         assert_files_in(Name, T)];
186assert_files_in(_, []) -> [].
187
188assert_files_not_in(Name, [File|T]) ->
189    [{Name ++ " does not have file: " ++ File,
190      ?_assertNot(filelib:is_regular(File))} | assert_files_not_in(Name, T)];
191assert_files_not_in(_, []) -> [].
192
193