defmodule Dexcord.EnvSandbox do @moduledoc false # A single, bulletproof application-env fixture for the test suite. # # Many tests tune `:dexcord` application env (timing knobs, budgets, rate-limit # clocks, base URLs, ...) to exercise real logic quickly. Any key a test forgets # to restore leaks into whatever test runs next and produces order-dependent, # seed-sensitive failures. Rather than have every file maintain its own hand-rolled # save/restore list (and get it subtly wrong), tests call `sandbox_env/0` once in # `setup`: it snapshots the ENTIRE `:dexcord` env up front and, via `on_exit`, # restores it wholesale afterwards - deleting any key the test introduced and # resetting every pre-existing key to its captured value. Tests then `put_env` # freely with no per-key bookkeeping. import ExUnit.Callbacks, only: [on_exit: 1] @doc """ Snapshots all `:dexcord` application env and registers wholesale restoration on test exit. Call once from a test's `setup`. """ @spec sandbox_env :: :ok def sandbox_env do before = Application.get_all_env(:dexcord) before_keys = MapSet.new(before, fn {k, _v} -> k end) on_exit(fn -> # Drop any key the test introduced that wasn't there before. for {key, _val} <- Application.get_all_env(:dexcord), not MapSet.member?(before_keys, key) do Application.delete_env(:dexcord, key) end # Restore every snapshotted key to exactly its captured value. for {key, val} <- before do Application.put_env(:dexcord, key, val) end end) :ok end end