# `Mutare.Mutators.IntegerLiteral`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/mutators/integer_literal.ex#L1)

Integer-literal mutations: `n` → `n + 1`, `n - 1`, and `0` (the "off-by-one" boundary plus the zero sentinel), deduplicated and never equal to `n`.

Only literals in *runtime* positions are mutated, never pattern literals. Mutations that would reproduce the original value are dropped (`0` is not re-emitted for the literal `0`; `n - 1` and `0` collapse for `n = 1`).

An integer literal in a known **timeout/duration position** (`Process.sleep/1`, the third argument of `Process.send_after/3`, the `GenServer.call/3` timeout, `Task.async_stream`'s `:timeout` option, …) is left unmutated — a near-unkillable equivalent mutant that also risks minting false `:timeout` kills. This family defines those positions in `c:Mutare.Mutator.argument_marks/1`. The transform marks them `:timeout`, and `mutate/2` skips integer literals with that mark. A *computed* duration (`base * 2`) is not a literal at the marked node, so it still mutates. (`Mutare.Mutators.AtomLiteral` reuses the same table to leave `:infinity` alone there.)

**Configuring extra positions.** Add project-specific timeout positions with the `argument_marks:`
option in `.mutare.exs` — entries have the declaration shape this table is written in
(`{module, function, arity, positions, label}`; `positions` lists effective argument indices and
`{:keyword, key}` option keys), and the `:timeout` label gives them exactly this family's reaction:

    [argument_marks: [
      {MyApp.Cache, :put, 3, [2], :timeout},                       # a TTL argument
      {MyApp.Http, :get, 2, [{:keyword, :recv_timeout}], :timeout}
    ]]

`Mutare.Mutators.AtomLiteral` reacts to the same label, so a configured position also keeps its
`:infinity` alone. To leave a position alone for *every* family regardless of value, route it
`:raw` in `call_routes:` instead (see `Mutare.CallRouting`).

Integer literals are pervasive, so this is the highest-volume built-in — the cost is paid in the denominator, the benefit is catching constants the suite never pins down. The integer sibling of `Mutare.Mutators.FloatLiteral` (`step` 1, `zero` 0); the boolean flip that used to share this family now lives in `Mutare.Mutators.BooleanLiteral`.

Filterable variants — qualify a `# mutare:ignore` filter with `:label` to suppress just one kind (`c:Mutare.Mutator.variants/0`): `zero`, `succ`, `pred`.

# `timeout_marks`

```elixir
@spec timeout_marks() :: [
  {module(), atom(), arity(), [non_neg_integer() | {:keyword, atom()}], atom()}
]
```

The built-in timeout/duration argument marks (the `:timeout` label), config-independent. Public so
`Mutare.Mutators.AtomLiteral` can declare the identical positions — keeping the two value families'
view of "an opaque timeout literal" in one place.

---

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