Packages

Manage the Elixir application environment within a context

Current section

Files

Jump to
with_env lib with_env.ex
Raw

lib/with_env.ex

defmodule WithEnv do
defmacro __using__(_) do
quote do
import WithEnv
test "ensure WithEnv is synchronous", context do
refute context.async, """
WithEnv cannot be used in async tests.
To make this test case synchronous, modify your use of
ExUnit.Case like so:
use ExUnit.Case, async: false
"""
end
end
end
@type opts :: {:put, list} | {:delete, list}
@spec with_env([opts], do: term) :: no_return
defmacro with_env(actions, do: block) do
quote do
put_actions = unquote(actions) |> Keyword.get(:put, [])
delete_actions = unquote(actions) |> Keyword.get(:delete, [])
apps = (Keyword.keys(put_actions) ++ Keyword.keys(delete_actions)) |> Enum.uniq()
previous_app_envs =
apps
|> Enum.reduce(
[],
fn app, acc ->
Keyword.put(acc, app, Application.get_all_env(app))
end
)
put_actions
|> Enum.each(fn {app, attributes} ->
attributes
|> Enum.each(fn {k, v} ->
Application.put_env(app, k, v)
end)
end)
delete_actions
|> Enum.each(fn {app, attribute_names} ->
attribute_names
|> Enum.each(fn k ->
Application.delete_env(app, k)
end)
end)
unquote(block)
apps
|> Enum.each(fn app ->
app
|> Application.get_all_env()
|> Enum.each(fn {k, v} ->
Application.delete_env(app, k)
end)
end)
previous_app_envs
|> Enum.each(fn {app, attributes} ->
attributes
|> Enum.each(fn {k, v} ->
Application.put_env(app, k, v)
end)
end)
end
end
end