Detect non-atomic side effects while the current process is inside an Ecto transaction.

Install

{:ecto_isolator, "~> 0.1.0", only: [:dev, :test], runtime: false}

Configure

config :ecto_isolator,
  repos: [MyApp.Repo],
  mode: :raise

Modes:

  • :raise raises EctoIsolator.Error.
  • :log logs a warning and continues.
  • :collect records offenses for later assertion.

Use the ExUnit helper to collect offenses during each test and fail at teardown:

defmodule MyApp.DataCase do
  use ExUnit.CaseTemplate

  using do
    quote do
      use EctoIsolator.ExUnit
    end
  end
end

Adapters

Req is the only built-in adapter:

Req.new()
|> EctoIsolator.Adapters.Req.attach()
|> Req.get!(url: "https://example.com")

For other libraries, keep the package-specific wrapper or adapter in the consuming application and call EctoIsolator.check!/3 before the side effect:

EctoIsolator.check!(:swoosh, :deliver, details: %{mailer: MyApp.Mailer})
MyApp.Mailer.deliver(email)

Ignores

Ignore rules receive an EctoIsolator.Offense:

config :ecto_isolator,
  ignore: [
    {:req, fn offense -> offense.details.url =~ "localhost" end}
  ]

Development

Run the package checks with Mix:

mix check