Mutare.InvariantError exception (mutare v0.3.1)

Copy Markdown View Source

Raised under verify_invariants: true (mix mutare --verify-invariants) when a rendered metamutant breaks a property the run's results depend on.

Every violation is a bug in Mutare or in a custom mutator, host, or extension enabled for the run — never a problem with the project under test. Most would otherwise corrupt the report silently: a recorded mutant that the metamutant cannot select runs the unmutated code, so it survives whatever the suite checks, and one that no coverage record lists is reported as uncovered and never tested.

file is the transformed file; violations lists what the checks found, in this order:

  • {:unparseable_metamutant, message} — the rendered metamutant is not valid Elixir, so no other readback check could run.
  • {:missing_branch, site} — no generated code selects the mutant.
  • {:unreachable_branch, site, enclosing} — the mutant's only branches sit inside the branches of other mutants (enclosing), which never run while this one is the only active mutant.
  • {:stray_branch, subject} — generated code selects an id that the transform did not deliver.
  • {:missing_record, site} — no coverage record outside every mutant branch lists the mutant.
  • {:stray_record, subject} — a coverage record lists an id that the transform did not deliver.
  • {:unchanged_mutant, site} — the mutant renders identically to its original code, so no test can kill it.
  • {:nondeterministic_render, differences} — emitting the same source again gave a different result, so report-time diffs (which re-render) may describe other mutants than the ones that ran.

A subject is {local_id, site}: the integer the generated code selects on, and the Site the transform recorded under it (nil when there is none — then the id belongs to no mutant).

Summary

Types

An id the generated code names, and the Site recorded under it, if any.

t()

Types

subject()

@type subject() :: {non_neg_integer(), Mutare.Site.t() | nil}

An id the generated code names, and the Site recorded under it, if any.

t()

@type t() :: %Mutare.InvariantError{
  __exception__: true,
  file: String.t(),
  message: String.t(),
  violations: [violation()]
}

violation()

@type violation() ::
  {:unparseable_metamutant, String.t()}
  | {:missing_branch, Mutare.Site.t()}
  | {:unreachable_branch, Mutare.Site.t(), [subject()]}
  | {:stray_branch, subject()}
  | {:missing_record, Mutare.Site.t()}
  | {:stray_record, subject()}
  | {:unchanged_mutant, Mutare.Site.t()}
  | {:nondeterministic_render, [String.t()]}