# `Mutare.Report`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/report.ex#L1)

Renders mutation results for the human report.

Diffs are patched against the original source via `Sourceror.patch_string` at the site's recorded range, so untouched source stays byte-identical and a survivor reads as a precise source-range change.

The mutation score and tallies in the report come from `Mutare.Score`, which also implements the CI gates; this module only renders.

# `diff`

```elixir
@spec diff(Mutare.Site.t(), String.t()) :: String.t()
```

A `-`/`+` diff of the lines touched by the mutation.

The diff is line-based within the site's source range. Changed lines are shown
as deletions and insertions; unchanged lines inside a multi-line fragment are
shown as context. This keeps multi-line replacements aligned when a mutation adds
or removes a line in the middle of the fragment.

# `harness_error`

```elixir
@spec harness_error(Mutare.Result.t()) :: String.t()
```

One line for a harness-errored mutant, including a compact diagnostic.

# `header`

```elixir
@spec header(Mutare.Site.t()) :: String.t()
```

Header line for a surviving mutant, e.g.
`lib/x.ex:42  [relational, in-place]  SURVIVED`.

A mutation with a note appends it as a trailing `— note`, matching the ignored
mutant reason format.

# `ignored`

```elixir
@spec ignored(Mutare.Site.t()) :: String.t()
```

One line for an ignored mutant, e.g.
`lib/x.ex:42  [arithmetic]  IGNORED  — off-by-one is intentional`.

The trailing `— reason` is present only when the directive carried one, so a
bare `# mutare:ignore` reads as `… IGNORED` with nothing after it.

# `patch`

```elixir
@spec patch(Mutare.Site.t(), String.t()) :: String.t()
```

Apply a single mutation to the original source string.

# `render`

```elixir
@spec render([Mutare.Result.t()], %{optional(String.t()) =&gt; String.t()}) :: String.t()
```

Render the whole report from results and a `%{file => original_source}` map.

# `render`

```elixir
@spec render([Mutare.Result.t()], %{optional(String.t()) =&gt; String.t()}, keyword()) ::
  String.t()
```

Renders the human report with the same arity as machine reporters.

`opts` is ignored; score gating is handled by the caller.

# `summary`

```elixir
@spec summary([Mutare.Result.t()]) :: String.t()
```

One-line tally, e.g. `mutation score: 66.7%  (2 killed, 1 survived, 3 total)`.

    iex> Mutare.Report.summary([
    ...>   %Mutare.Result{status: :killed},
    ...>   %Mutare.Result{status: :survived}
    ...> ])
    "mutation score: 50.0%  (1 killed, 1 survived, 2 total)"

# `survivor`

```elixir
@spec survivor(Mutare.Site.t(), String.t()) :: String.t()
```

Full diff block (header + diff) for one survivor.

---

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