Packages

Mix and match reusable test context by using tags

Current section

Files

Jump to
setup_tag lib setup_tag.ex
Raw

lib/setup_tag.ex

defmodule SetupTag do
@moduledoc """
SetupTag allows you to create a test context by easily mix and match
test setup functions selected by the tags applied to your test or module.
Well, it's actually a feature of ExUnit, but this module lets you
reuse and mix functions over different modules.
See setup_tag_test.exs for a more real example usage.
"""
@doc false
defmacro __using__(_opts) do
quote do
def setup_tag(_, ctx), do: {:ok, ctx}
defoverridable [setup_tag: 2]
end
end
@doc """
Creates a new test context by applying
the provided context to setup_tag functions
selected by the test or module tags.
Returns {:ok, new_context}
"""
def setup(tags = %{case: module}, context) do
{:ok, Enum.reduce(tags, context,
&setup_tag(module, &1, &2))}
end
defp setup_tag(module, {name, true}, context) do
if setup_tag?(name) do
setup_tag(module, {name, {module, [{name, []}]}}, context)
else
context
end
end
defp setup_tag(_, {name, module}, context) when is_atom(module) do
if setup_tag?(name) do
setup_tag(module, {name, {module, [{name, []}]}}, context)
else
context
end
end
defp setup_tag(_, {name, {module, [{fname, args}]}}, context) do
{:ok, new_context} = apply(module, fname, [context] ++ args)
new_context
end
defp setup_tag(module, tag, context) do
{:ok, new_context} = apply(module, :setup_tag, [tag, context])
new_context
end
defp setup_tag?(name) do
Atom.to_string(name) |> String.starts_with?("setup_")
end
end