@ -155,12 +155,10 @@ run_eunit(Config, CodePath, SrcErls) ->
[ filename : rootname ( N ) ++ " _tests.beam " | | N < - AllBeamFiles ] ,
ModuleBeamFiles = randomize_suites ( Config , BeamFiles ++ OtherBeamFiles ) ,
% % Get modules to be run in eunit
% % Get matching tests and modules
AllModules = [ rebar_utils : beam_to_mod ( ? EUNIT_DIR , N ) | | N < - AllBeamFiles ] ,
{ SuitesProvided , FilteredModules } = filter_suites ( Config , AllModules ) ,
% % Get matching tests
Tests = get_tests ( Config , SuitesProvided , ModuleBeamFiles , FilteredModules ) ,
{ Tests , CoverageModules } =
get_tests_and_modules ( Config , ModuleBeamFiles , AllModules ) ,
SrcModules = [ rebar_utils : erl_to_mod ( M ) | | M < - SrcErls ] ,
@ -169,7 +167,7 @@ run_eunit(Config, CodePath, SrcErls) ->
StatusBefore = status_before_eunit ( ) ,
EunitResult = perform_eunit ( Config , Tests ) ,
perform_cover ( Config , Filtered Modules, SrcModules ) ,
perform_cover ( Config , Coverage Modules, SrcModules ) ,
cover_close ( CoverLog ) ,
case proplists : get_value ( reset_after_eunit , get_eunit_opts ( Config ) ,
@ -214,18 +212,23 @@ setup_code_path() ->
CodePath .
% %
% % == filter suite s ==
% % == get matching test s ==
% %
get_tests_and_modules ( Config , ModuleBeamFiles , AllModules ) - >
SelectedSuites = get_selected_suites ( Config , AllModules ) ,
{ Tests , QualifiedTests } = get_qualified_and_unqualified_tests ( Config ) ,
Modules = get_test_modules ( SelectedSuites , Tests ,
QualifiedTests , ModuleBeamFiles ) ,
CoverageModules = get_coverage_modules ( AllModules , Modules , QualifiedTests ) ,
MatchedTests = get_matching_tests ( Modules , Tests , QualifiedTests ) ,
{ MatchedTests , CoverageModules } .
filter_suites ( Config , Modules ) - >
% %
% % == get suites specified via 'suites' option ==
% %
get_selected_suites ( Config , Modules ) - >
RawSuites = get_suites ( Config ) ,
SuitesProvided = RawSuites =/= " " ,
Suites = [ list_to_atom ( Suite ) | | Suite < - string : tokens ( RawSuites , " , " ) ] ,
{ SuitesProvided , filter_suites1 ( Modules , Suites ) } .
filter_suites1 ( Modules , [ ] ) - >
Modules ;
filter_suites1 ( Modules , Suites ) - >
[ M | | M < - Suites , lists : member ( M , Modules ) ] .
get_suites ( Config ) - >
@ -236,6 +239,32 @@ get_suites(Config) ->
Suites
end .
get_qualified_and_unqualified_tests ( Config ) - >
RawFunctions = rebar_utils : get_experimental_global ( Config , tests , " " ) ,
FunctionNames = [ FunctionName | |
FunctionName < - string : tokens ( RawFunctions , " , " ) ] ,
get_qualified_and_unqualified_tests1 ( FunctionNames , [ ] , [ ] ) .
get_qualified_and_unqualified_tests1 ( [ ] , Functions , QualifiedFunctions ) - >
{ Functions , QualifiedFunctions } ;
get_qualified_and_unqualified_tests1 ( [ TestName | TestNames ] , Functions ,
QualifiedFunctions ) - >
case string : tokens ( TestName , " : " ) of
[ TestName ] - >
Function = list_to_atom ( TestName ) ,
get_qualified_and_unqualified_tests1 (
TestNames , [ Function | Functions ] , QualifiedFunctions ) ;
[ ModuleName , FunctionName ] - >
M = list_to_atom ( ModuleName ) ,
F = list_to_atom ( FunctionName ) ,
get_qualified_and_unqualified_tests1 ( TestNames , Functions ,
[ { M , F } | QualifiedFunctions ] ) ;
_ - >
? ABORT ( " Unsupported test function specification: ~s ~n " , [ TestName ] )
end .
% % Provide modules which are to be searched for tests .
% % Several scenarios are possible :
% %
% % == randomize suites ==
% %
@ -265,60 +294,66 @@ randomize_suites1(Modules, Seed) ->
% %
% % == get matching tests ==
% % 1 ) Specific tests have been provided and / or
% % no unqualified tests have been specified and
% % there were some qualified tests , then we can search for
% % functions in specified suites ( or in empty set of suites ) .
% %
get_tests ( Config , SuitesProvided , ModuleBeamFiles , FilteredModules ) - >
Modules = case SuitesProvided of
false - >
% % No specific suites have been provided , use
% % ModuleBeamFiles which filters out " *_tests " modules
% % so eunit won ' t doubly run them and cover only
% % calculates coverage on production code . However ,
% % keep " *_tests " modules that are not automatically
% % included by eunit .
% %
% % From 'Primitives' in the EUnit User ' s Guide
% % http : / / www . erlang . org / doc / apps / eunit / chapter . html
% % " In addition, EUnit will also look for another
% % module whose name is ModuleName plus the suffix
% % _ tests , and if it exists , all the tests from that
% % module will also be added . ( If ModuleName already
% % contains the suffix _ tests , this is not done . ) E . g . ,
% % the specification { module , mymodule } will run all
% % tests in the modules mymodule and mymodule_tests .
% % Typically , the _ tests module should only contain
% % test cases that use the public interface of the main
% % module ( and no other code ) . "
[ rebar_utils : beam_to_mod ( ? EUNIT_DIR , N ) | |
N < - ModuleBeamFiles ] ;
true - >
% % Specific suites have been provided , return the
% % filtered modules
FilteredModules
end ,
get_matching_tests ( Config , Modules ) .
get_tests ( Config ) - >
case rebar_config : get_global ( Config , tests , " " ) of
" " - >
rebar_config : get_global ( Config , test , " " ) ;
Suites - >
Suites
% % 2 ) Neither specific suites nor qualified test names have been
% % provided use ModuleBeamFiles which filters out " *_tests "
% % modules so EUnit won ' t doubly run them and cover only
% % calculates coverage on production code . However ,
% % keep " *_tests " modules that are not automatically
% % included by EUnit .
% %
% % From 'Primitives' in the EUnit User ' s Guide
% % http : / / www . erlang . org / doc / apps / eunit / chapter . html
% % " In addition, EUnit will also look for another
% % module whose name is ModuleName plus the suffix
% % _ tests , and if it exists , all the tests from that
% % module will also be added . ( If ModuleName already
% % contains the suffix _ tests , this is not done . ) E . g . ,
% % the specification { module , mymodule } will run all
% % tests in the modules mymodule and mymodule_tests .
% % Typically , the _ tests module should only contain
% % test cases that use the public interface of the main
% % module ( and no other code ) . "
get_test_modules ( SelectedSuites , Tests , QualifiedTests , ModuleBeamFiles ) - >
SuitesProvided = SelectedSuites =/= [ ] ,
OnlyQualifiedTestsProvided = QualifiedTests =/= [ ] andalso Tests =:= [ ] ,
if
SuitesProvided orelse OnlyQualifiedTestsProvided - >
SelectedSuites ;
true - >
[ rebar_utils : beam_to_mod ( ? EUNIT_DIR , N ) | |
N < - ModuleBeamFiles ]
end .
get_matching_tests ( Config , Modules ) - >
RawFunctions = get_tests ( Config ) ,
Tests = [ list_to_atom ( F1 ) | | F1 < - string : tokens ( RawFunctions , " , " ) ] ,
case Tests of
[ ] - >
Modules ;
Functions - >
case get_matching_tests1 ( Modules , Functions , [ ] ) of
[ ] - >
[ ] ;
RawTests - >
make_test_primitives ( RawTests )
end
end .
get_coverage_modules ( AllModules , Modules , QualifiedTests ) - >
ModuleFilterMapper =
fun ( { M , _ } ) - >
case lists : member ( M , AllModules ) of
true - > { true , M } ;
_ - > false
end
end ,
ModulesFromQualifiedTests = lists : zf ( ModuleFilterMapper , QualifiedTests ) ,
lists : usort ( Modules ++ ModulesFromQualifiedTests ) .
get_matching_tests ( Modules , [ ] , [ ] ) - >
Modules ;
get_matching_tests ( Modules , [ ] , QualifiedTests ) - >
FilteredQualifiedTests = filter_qualified_tests ( Modules , QualifiedTests ) ,
lists : merge ( Modules , make_test_primitives ( FilteredQualifiedTests ) ) ;
get_matching_tests ( Modules , Tests , QualifiedTests ) - >
AllTests = lists : merge ( QualifiedTests ,
get_matching_tests1 ( Modules , Tests , [ ] ) ) ,
make_test_primitives ( AllTests ) .
filter_qualified_tests ( Modules , QualifiedTests ) - >
TestsFilter = fun ( { Module , _ Function } ) - >
lists : all ( fun ( M ) - > M =/= Module end , Modules ) end ,
lists : filter ( TestsFilter , QualifiedTests ) .
get_matching_tests1 ( [ ] , _ Functions , TestFunctions ) - >
TestFunctions ;
@ -608,9 +643,9 @@ align_notcovered_count(Module, Covered, NotCovered, true) ->
cover_write_index ( Coverage , SrcModules ) - >
{ ok , F } = file : open ( filename : join ( [ ? EUNIT_DIR , " index.html " ] ) , [ write ] ) ,
ok = file : write ( F , " <!DOCTYPE HTML><html> \n "
" <head><meta charset= \" utf-8 \" > "
" <title>Coverage Summary</title></head> \n "
" <body> \n " ) ,
" <head><meta charset= \" utf-8 \" > "
" <title>Coverage Summary</title></head> \n "
" <body> \n " ) ,
IsSrcCoverage = fun ( { Mod , _ C , _ N } ) - > lists : member ( Mod , SrcModules ) end ,
{ SrcCoverage , TestCoverage } = lists : partition ( IsSrcCoverage , Coverage ) ,
cover_write_index_section ( F , " Source " , SrcCoverage ) ,