-
Notifications
You must be signed in to change notification settings - Fork 132
/
runtest
executable file
·98 lines (91 loc) · 3.4 KB
/
runtest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#! /usr/bin/env escript
%% vim: ft=erlang
%%! -pa ../erlport -pa .eunit
main(Args) ->
Options = case Args of
[] ->
[];
["verbose"] ->
[verbose];
_ ->
io:format("Usage: runtest [verbose]~n"),
halt(2)
end,
start_cover(),
eunit:test(get_modules(".eunit"), Options),
analyse(proplists:get_bool(verbose, Options)).
get_modules(Dir) ->
case file:list_dir(Dir) of
{ok, Filenames} ->
[list_to_existing_atom(filename:basename(F, ".beam"))
|| F <- Filenames, filename:extension(F) =:= ".beam"];
{error, Reason} ->
io:format("Can't list files in ~p: ~p", [Dir, Reason]),
halt(1)
end.
start_cover() ->
{ok, _} = cover:start(),
cover_compile_beam_directory(".eunit").
cover_compile_beam_directory(Dir) ->
Result = case cover:compile_beam_directory(Dir) of
{error, Reason} ->
io:format("Cover compile error in ~p: ~p~n", [Dir, Reason]),
halt(1);
R -> R
end,
lists:foreach(fun
({ok, _}) ->
ok;
({error, Reason}) ->
io:format("Cover compile error in ~p: ~p~n", [Dir, Reason]),
halt(1)
end, Result).
analyse(Verbose) ->
IndexName = filename:join(".eunit", "index.html"),
{ok, Index} = file:open(IndexName, [write, raw]),
ok = file:write(Index, "<html>\n<head>\n<title>Coverage report</title>\n"
"<body>\n<h1>Coverage report</h1>\n<table>\n<tr>"
"<th>Module</th><th>Statements</th><th>Missing</th>"
"<th>Coverage</th></tr>\n"),
io:format("~-30s~7s~7s~7s~n~s~n",
["Name", "Stmts", "Miss", "Cover", lists:duplicate(51, "-")]),
{TotalCov, TotalNotCov} = lists:foldl(fun (Mod, {CovA, NotCovA}) ->
{Cov, NotCov} = cover_analyse(Mod, Index),
cover_analyse_to_file(Mod, Verbose),
{CovA + Cov, NotCovA + NotCov}
end, {0, 0}, cover:modules()),
Stmts = TotalCov + TotalNotCov,
Cover = (TotalCov * 100) div Stmts,
ok = file:write(Index, io_lib:format("<tr><td>TOTAL</td>"
"<td>~b</td><td>~b</td><td>~b%</td></tr>\n</body>\n</html>\n",
[Stmts, TotalNotCov, Cover])),
ok = file:close(Index),
io:format("~s~n~-30s~7b~7b~6b%~n", [lists:duplicate(51, "-"),
"TOTAL", Stmts, TotalNotCov, Cover]).
cover_analyse(Mod, Index) ->
case cover:analyse(Mod, coverage, module) of
{ok, {Mod, {Cov, NotCov}}} ->
Stmts = Cov + NotCov,
Cover = (Cov * 100) div Stmts,
ok = file:write(Index, io_lib:format(
"<tr><td><a href=\"~s\">~s</a>"
"</td><td>~b</td><td>~b</td><td>~b%</td></tr>\n",
[lists:concat([Mod, ".cover.html"]), Mod,
Stmts, NotCov, Cover])),
io:format("~-30s~7b~7b~6b%~n", [Mod, Stmts, NotCov,Cover]),
{Cov, NotCov};
{error, Reason} ->
io:format("Coverage analyse error ~p: ~p~n", [Mod, Reason]),
halt(1)
end.
cover_analyse_to_file(Mod, true) ->
Out = filename:join(".eunit", lists:concat([Mod, ".cover.html"])),
case cover:analyse_to_file(Mod, Out, [html]) of
{ok, _} ->
ok;
{error, Reason} ->
io:format("Coverage analyse error ~p: ~p~n", [Mod, Reason]),
halt(1)
end;
cover_analyse_to_file(_Mod, false) ->
ok.