Current section
Files
Jump to
Current section
Files
src/rebar3_shine.erl
-module(rebar3_shine).
-export([init/1, do/1, format_error/1, extract_test_modules/1, extract_tests/1]).
-define(PROVIDER, shine).
-define(DEPS, [app_discovery]).
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider =
providers:create([{name, ?PROVIDER},
{module, ?MODULE},
{bare, true},
{deps, ?DEPS},
{example, "rebar3 shine"},
{opts, []},
{short_desc, "Run tests with Shine"},
{desc, "Run tests with Shine"},
{profiles, [test]}]),
{ok, rebar_state:add_provider(State, Provider)}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
{ok, State1} = rebar_prv_compile:do(State),
code:add_pathsa(
rebar_state:code_paths(State1, all_deps)),
Paths = filelib:wildcard("gen/test/**/*.erl") ++ filelib:wildcard("test/**/*.erl"),
Suite = extract_test_modules(Paths),
halt(provider_do(State1, fun(_) -> shine:start(Suite) end)).
provider_do(State, Fun) ->
case code:ensure_loaded(rebar_gleam) of
{module, rebar_gleam} ->
rebar_gleam:provider_do(State, Fun);
{error, _} ->
Fun(State)
end.
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
extract_test_modules(Paths) ->
lists:map(fun(Path) ->
ModuleName = filename:basename(Path, ".erl"),
Module = list_to_atom(ModuleName),
{test_module, ModuleName, extract_tests(Module)}
end,
Paths).
extract_tests(Module) ->
lists:filtermap(fun({Function, Arity}) ->
case is_test(Function, Arity) of
true -> {true, to_test(Module, Function, Arity)};
false -> false
end
end,
Module:module_info(exports)).
is_test(Name, 0) ->
string:find(atom_to_list(Name), "_", trailing) =:= "_test";
is_test(_Name, _Arity) ->
false.
to_test(Module, FunctionName, 0) ->
shine@test:new(atom_to_list(Module),
atom_to_list(FunctionName),
fun() -> erlang:apply(Module, FunctionName, []) end).