Mutare.Mutator.Spec (mutare v0.1.2)

Copy Markdown View Source

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 (Mutare.Mutator.required_modules/0, when exported — a missing module raises Mutare.EnvironmentError here, at resolution time) and then runs the mutator's 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.

Summary

Functions

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

Builds a spec for module with configuration opts.

Returns the spec in specs for module, or nil.

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

Types

t()

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

Functions

coerce(spec)

@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(module, opts)

@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(specs, module)

@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(module)

@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, []}