Mutare.Result.Status (mutare v0.1.0)

Copy Markdown View Source

The single descriptor registry for the Mutare.Result status vocabulary.

A result status carries the same handful of facts at every surface that touches it: is it a kill (score numerator), is it scored (in the denominator), did it run (launched a mix test), what is its mutation-testing-elements / Stryker name, how is it labelled in the one-line Mutare.Report.summary/1 and the live counter, does it leave a permanent line behind in Mutare.Report.Live (and how --verbose labels its always-emitted line). Those facts used to be re-listed inline in five places — Mutare.Result (classification lists), Mutare.Report (the summary tally), Mutare.Report.Json (the schema map), and Mutare.Report.Live (@leave_behind + the counter extras) — which drift apart silently when a status is added (see CLAUDE.md "Result statuses"). They live here once: one descriptor map per status, ordered as the summary/counter render them, the consumers reading fields off all/0/fetch!/1 rather than re-enumerating the vocabulary.

Adding a status is two edits — a row here and the @type status union in Mutare.Result — and Mutare.Result.StatusTest pins the registry to that type so the two cannot diverge unnoticed. A descriptor is a plain map (a struct can't be built in its own module's compile-time attributes), but the rows are validated at compile time against the schema below, so a missing required key or a typo'd field name fails the build rather than silently producing a wrong descriptor.

Per-field defaults are chosen so a row states only what is unusual about a status: a status is scored?/ran? and not a kill? unless it says otherwise (the common in-the-denominator, reached-a-verdict, didn't-detect shape), and it is not pinned into the summary nor surfaced as a live extra/leave-behind unless it opts in.

Summary

Types

An IO.ANSI colour name for a leave-behind label.

t()

Functions

Every status descriptor, in summary/counter render order.

The descriptor for status, raising on an unregistered name. Loud by design — the same fail-fast a missing Map.fetch! key gave the JSON map: a status with no row is a bug, surfaced rather than silently rendered blank.

The descriptor for status, or nil for an unregistered name.

Every status name, in render order.

The status names whose descriptor field field is truthy, in render order.

Types

colour()

@type colour() :: atom()

An IO.ANSI colour name for a leave-behind label.

t()

@type t() :: %{
  name: Mutare.Result.status(),
  kill?: boolean(),
  scored?: boolean(),
  ran?: boolean(),
  json: String.t(),
  summary_label: String.t(),
  always_in_summary?: boolean(),
  extra_label: String.t() | nil,
  leave_behind: {String.t(), colour()} | nil,
  verbose_label: {String.t(), colour()}
}

Functions

all()

@spec all() :: [t()]

Every status descriptor, in summary/counter render order.

Examples

iex> Mutare.Result.Status.all() |> Enum.map(& &1.name) |> Enum.take(3)
[:killed, :timeout, :atom_exhausted]

fetch!(status)

@spec fetch!(Mutare.Result.status()) :: t()

The descriptor for status, raising on an unregistered name. Loud by design — the same fail-fast a missing Map.fetch! key gave the JSON map: a status with no row is a bug, surfaced rather than silently rendered blank.

Examples

iex> Mutare.Result.Status.fetch!(:survived).json
"Survived"

get(status)

@spec get(atom()) :: t() | nil

The descriptor for status, or nil for an unregistered name.

Examples

iex> Mutare.Result.Status.get(:not_a_status)
nil

names()

@spec names() :: [Mutare.Result.status()]

Every status name, in render order.

Examples

iex> Mutare.Result.Status.names()
[:killed, :timeout, :atom_exhausted, :survived, :no_coverage, :ignored, :poisoned, :harness_error]

where(field)

@spec where(atom()) :: [Mutare.Result.status()]

The status names whose descriptor field field is truthy, in render order.

Examples

iex> Mutare.Result.Status.where(:kill?)
[:killed, :timeout, :atom_exhausted]