# `Mutare.Mutator.Spec`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/mutator/spec.ex#L1)

A resolved mutator module, report name, and per-instance options.

A bare module uses its `name/0` and receives empty options. A `{module, opts}` entry passes `opts` to context-taking callbacks; the reserved `:as` option changes the report and `# mutare:ignore` name and is removed before the mutator receives the remaining options.

Building a spec also verifies the module's declared environment (`c:Mutare.Mutator.required_modules/0`, when exported — a missing module raises `Mutare.EnvironmentError` here, at resolution time) and then runs the mutator's `c:Mutare.Mutator.init/1` (when exported) on those remaining options, storing the result as the spec's `config` — so environment checking and option parsing happen once per resolved instance, and an invalid option raises here too. Without `init/1`, `config` is the options themselves. Dispatch delivers it to every context-aware callback as `context.config`.

The transform also attaches the enclosing module's `@behaviour` set before invoking a mutator.

# `t`

```elixir
@type t() :: %Mutare.Mutator.Spec{
  behaviours: MapSet.t(module()),
  config: term(),
  disabled_callbacks: MapSet.t({atom(), arity()}),
  module: module(),
  name: atom(),
  opts: term()
}
```

# `coerce`

```elixir
@spec coerce(t() | module()) :: t()
```

Normalize any entry to a spec; a `%Spec{}` passes through unchanged (idempotent).

    iex> spec = Mutare.Mutator.Spec.for_module(Mutare.Mutators.Arithmetic)
    iex> Mutare.Mutator.Spec.coerce(spec) == spec
    true
    iex> Mutare.Mutator.Spec.coerce(Mutare.Mutators.Arithmetic) == spec
    true

# `configured`

```elixir
@spec configured(module(), keyword() | term()) :: t()
```

Builds a spec for `module` with configuration `opts`.

For keyword options, `:as` overrides the recorded family name and is removed
before the remaining options are passed to the mutator. Other option values are
passed through unchanged.

    iex> spec = Mutare.Mutator.Spec.configured(
    ...>   Mutare.Mutators.Arithmetic,
    ...>   as: :strict,
    ...>   threshold: 5
    ...> )
    iex> {spec.name, spec.opts}
    {:strict, [threshold: 5]}

# `find`

```elixir
@spec find([t()], module()) :: t() | nil
```

Returns the spec in `specs` for `module`, or `nil`.

    iex> specs = Mutare.Mutators.resolve([:arithmetic, :relational])
    iex> Mutare.Mutator.Spec.find(specs, Mutare.Mutators.Relational).name
    :relational
    iex> Mutare.Mutator.Spec.find(specs, Enum)
    nil

# `for_module`

```elixir
@spec for_module(module()) :: t()
```

A spec for a bare module (no opts), named by its `name/0`.

    iex> spec = Mutare.Mutator.Spec.for_module(Mutare.Mutators.Arithmetic)
    iex> {spec.module, spec.name, spec.opts}
    {Mutare.Mutators.Arithmetic, :arithmetic, []}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
