feat(mix eunit): add support for filtering test cases

This commit is contained in:
Thales Macedo Garitezi 2024-07-11 15:28:01 -03:00
parent bbd51bdf18
commit 9a003ee3cf
1 changed files with 74 additions and 4 deletions

View File

@ -1,7 +1,11 @@
defmodule Mix.Tasks.Emqx.Eunit do
use Mix.Task
# Code.require_file("emqx.ct.ex", __DIR__)
alias EMQXUmbrella.MixProject, as: UMP
if UMP.new_mix_build?() do
Code.require_file("emqx.ct.ex", __DIR__)
end
alias Mix.Tasks.Emqx.Ct, as: ECt
@ -29,7 +33,9 @@ defmodule Mix.Tasks.Emqx.Eunit do
|> String.replace_suffix("-test", "")
|> then(& System.put_env("PROFILE", &1))
discover_tests()
args
|> parse_args!()
|> discover_tests()
|> :eunit.test(
verbose: true,
print_depth: 100
@ -50,9 +56,73 @@ defmodule Mix.Tasks.Emqx.Eunit do
|> :code.add_path(:cache)
end
## TODO: allow filtering modules and test names
defp discover_tests() do
defp parse_args!(args) do
{opts, _rest} = OptionParser.parse!(
args,
strict: [
cases: :string,
modules: :string,
]
)
cases =
opts
|> get_name_list(:cases)
|> Enum.flat_map(&resolve_test_fns!/1)
modules =
opts
|> get_name_list(:modules)
|> Enum.map(&String.to_atom/1)
%{
cases: cases,
modules: modules,
}
end
defp get_name_list(opts, key) do
opts
|> Keyword.get(key, "")
|> String.split(",", trim: true)
end
defp resolve_test_fns!(mod_fn_str) do
{mod, fun} = case String.split(mod_fn_str, ":") do
[mod, fun] ->
{String.to_atom(mod), String.to_atom(fun)}
_ ->
Mix.raise("Bad test case spec; must of `MOD:FUN` form. Got: #{mod_fn_str}`")
end
if not has_test_case?(mod, fun) do
Mix.raise("Module #{mod} does not export test case #{fun}")
end
if to_string(fun) =~ ~r/_test_$/ do
apply(mod, fun, [])
else
[Function.capture(mod, fun, 0)]
end
end
defp has_test_case?(mod, fun) do
try do
mod.module_info(:functions)
|> Enum.find(& &1 == {fun, 0})
|> then(& !! &1)
rescue
UndefinedFunctionError -> false
end
end
defp discover_tests(%{cases: [], modules: []} = _opts) do
Mix.Dep.Umbrella.cached()
|> Enum.map(& {:application, &1.app})
end
defp discover_tests(%{cases: cases, modules: modules}) do
Enum.concat(
[
cases,
Enum.map(modules, & {:module, &1})
]
)
end
end