/ eqc_test / src / eqc_test_enabled_tests.erl
eqc_test_enabled_tests.erl
 1  -module(eqc_test_enabled_tests).
 2  -include_lib("eunit/include/eunit.hrl").
 3  
 4  -define(DISABLED_PROPS_MODS,
 5          [ aec_sync_eqc
 6          , fate_compiler_eqc
 7          , txs_eqc
 8          , txs_ga_eqc
 9          , txs_glue_eqc
10          , txs_sign_eqc
11          , txs_sign_meta_eqc
12          ]).
13  
14  -define(REBAR3_BUILD_DIR, "_build").
15  -define(REBAR3_PROFILE_DIR, "test+eqc").
16  -define(BEAM_SUFFIX, ".beam").
17  
18  each_eqc_mod_is_hooked_unless_whitelisted_test() ->
19      Path = [_|_] = code:get_path(),
20      PropsPath = [_|_] = props_path(Path),
21      TestsPath = [_|_] = tests_path(Path),
22      PropsMods       = [_|_] = lists:filter(fun is_props_mod/1, mods_from_beam_files([_|_] = find_beam_files_in_path(PropsPath))),
23      ActualTestsMods = [_|_] = lists:filter(fun is_tests_mod/1, mods_from_beam_files([_|_] = find_beam_files_in_path(TestsPath))),
24      ExpectedTestsMods = lists:map(fun tests_mod/1, PropsMods),
25      ExpectedMissingTestsMods = lists:map(fun tests_mod/1, ?DISABLED_PROPS_MODS),
26      ?assertEqual(ExpectedMissingTestsMods, lists:sort(ExpectedTestsMods -- ActualTestsMods)). %% This prints missing `*_tests` modules: error message would be clearer if it printed properties (`*_eqc`) modules.
27  
28  props_path(Path) ->
29      lists:filter(fun is_props_dir/1, Path).
30  
31  is_props_dir(Dir) ->
32      shallow_path_prefix(?REBAR3_BUILD_DIR, [?REBAR3_PROFILE_DIR, "extras", "eqc"], Dir).
33  
34  tests_path(Path) ->
35      lists:filter(fun is_tests_dir/1, Path).
36  
37  is_tests_dir(Dir) ->
38      shallow_path_prefix(?REBAR3_BUILD_DIR, [?REBAR3_PROFILE_DIR, "lib", "eqc_test"], Dir).
39  
40  shallow_path_prefix(ShallowSplittingComponent = [_|_], Prefix = [[_|_]|_], Dir) ->
41      Components = lists:map(fun filename_to_string/1, filename:split(Dir)),
42      shallow_prefix(ShallowSplittingComponent, Prefix, Components).
43  
44  shallow_prefix(ShallowSplittingElem, Prefix, List) ->
45      case
46          lists:splitwith(
47            fun(El) -> El =/= ShallowSplittingElem end,
48            lists:reverse(List))
49      of
50          {_, []} ->
51              false;
52          {RevT, [X|_]} when X =:= ShallowSplittingElem ->
53              lists:prefix(Prefix, lists:reverse(RevT))
54      end.
55  
56  find_beam_files_in_path(Path) ->
57      lists:flatmap(fun find_beam_files_in_dir/1, Path).
58  
59  find_beam_files_in_dir(Dir) ->
60      filelib:wildcard("**/*" ++ ?BEAM_SUFFIX, Dir).
61  
62  mods_from_beam_files(Fs) ->
63      lists:map(fun mod_from_beam_file/1, Fs).
64  
65  mod_from_beam_file(F) ->
66      ModS = filename_to_string(filename:basename(F, ?BEAM_SUFFIX)),
67      list_to_atom(ModS).
68  
69  is_props_mod(Mod) ->
70      aeeqc_props:is_props_mod(atom_to_list(Mod)).
71  
72  is_tests_mod(Mod) ->
73      aeeqc_eunit:is_tests_mod(atom_to_list(Mod)).
74  
75  tests_mod(Mod) ->
76      list_to_atom(aeeqc_eunit:tests_mod(atom_to_list(Mod))).
77  
78  -spec filename_to_string(file:filename_all() | file:name_all()) -> string().
79  filename_to_string(Filename) ->
80      lists:flatten(io_lib:format("~s", [Filename])).