summaryrefslogtreecommitdiff
path: root/src/rebar_eunit.erl
diff options
context:
space:
mode:
authorChris Bernard <cebernard@gmail.com>2010-05-15 15:09:45 -0400
committerChris Bernard <cebernard@gmail.com>2010-05-15 15:09:45 -0400
commit4825353a237b8cfe0ba0e1a9e6001de756af1189 (patch)
tree570c144abf1bfda5e4ec57bb6c4f73c722d15d4b /src/rebar_eunit.erl
parent35a928ecf2e0736dad345f644108141eabbbbee8 (diff)
Fix incorrect coverage count when prod modules include EUnit header.
Modules that include the EUnit header get an implicit test/0 fun, which cover considers a runnable line, but eunit:(TestRepresentation) never calls. Result: prod modules with tests can never reach 100% coverage. Ironic. In this case, fix it by decrementing the NotCovered counter returned by cover:analyze/3.
Diffstat (limited to 'src/rebar_eunit.erl')
-rw-r--r--src/rebar_eunit.erl32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/rebar_eunit.erl b/src/rebar_eunit.erl
index c4740a7..bd93a48 100644
--- a/src/rebar_eunit.erl
+++ b/src/rebar_eunit.erl
@@ -238,13 +238,43 @@ cover_init(Config, BeamFiles) ->
cover_analyze_mod(Module) ->
case cover:analyze(Module, coverage, module) of
{ok, {Module, {Covered, NotCovered}}} ->
- {Module, Covered, NotCovered};
+ %% Modules that include the eunit header get an implicit
+ %% test/0 fun, which cover considers a runnable line, but
+ %% eunit:test(TestRepresentation) never calls. Decrement
+ %% NotCovered in this case.
+ align_notcovered_count(Module, Covered, NotCovered,
+ is_eunitized(Module));
{error, Reason} ->
?ERROR("Cover analyze failed for ~p: ~p ~p\n",
[Module, Reason, code:which(Module)]),
{0,0}
end.
+is_eunitized(Mod) ->
+ has_eunit_test_fun(Mod) andalso
+ has_eunit_header(Mod).
+
+has_eunit_test_fun(Mod) ->
+ length([F || {exports, Funs} <- Mod:module_info(),
+ {F, 0} <- Funs,
+ F == test]) =/= 0.
+
+has_eunit_header(Mod) ->
+ OrigEnv = set_proc_env(),
+ try has_header(Mod, "include/eunit.hrl")
+ after restore_proc_env(OrigEnv)
+ end.
+
+has_header(Mod, Header) ->
+ {ok, {_, [{abstract_code, {_, AC}}]}} = beam_lib:chunks(Mod, [abstract_code]),
+ length([F || {attribute, 1, file, {F, 1}} <- AC,
+ string:str(F, Header) =/= 0]) =/= 0.
+
+align_notcovered_count(Module, Covered, NotCovered, false) ->
+ {Module, Covered, NotCovered};
+align_notcovered_count(Module, Covered, NotCovered, true) ->
+ {Module, Covered, NotCovered - 1}.
+
cover_write_index(Coverage, SrcModules) ->
{ok, F} = file:open(filename:join([?EUNIT_DIR, "index.html"]), [write]),
ok = file:write(F, "<html><head><title>Coverage Summary</title></head>\n"),