# mutare_ecto v0.1.1 - Table of Contents

> Mutare mutators for Ecto

## Pages

- [mutare_ecto](readme.md)
- [Changelog](changelog.md)
- [LICENSE](license.md)

## Modules

- [Mutare.Ecto.Dynamic](Mutare.Ecto.Dynamic.md): In-fragment SQL mutations for a **free-standing** `dynamic/1,2` call — the condition a user
builds ahead of time and splices later

- Mutator front
  - [Mutare.Ecto](Mutare.Ecto.md): A mutation-testing plugin for Ecto — a `Mutare.Mutator` that mutates the Ecto
surface (Repo calls, changeset pipelines, and the query DSL) while respecting
SQL semantics.

- Repo &amp; changeset mutators
  - [Mutare.Ecto.Changeset](Mutare.Ecto.Changeset.md): Drop a transparent step from a changeset pipeline — the changeset equivalent of removing a
guard. `cs |> validate_required([:name])` → `cs`. A surviving mutant means **no test
exercises** the behaviour that step contributes. Matched by resolving the call to
`Ecto.Changeset` (direct, aliased, or the common `import Ecto.Changeset`), so the form the
source wrote doesn't matter.
  - [Mutare.Ecto.QueryTerminal](Mutare.Ecto.QueryTerminal.md): Swap `Ecto.Query.first/1,2` ↔ `Ecto.Query.last/1,2` — the query "terminals" that restrict a
query to a single edge of its ordering. `first` keeps the first row by the order (primary key
ascending when none is given); `last` reverses it. Swapping them is a clean, same-arity rename
(so it always compiles), behaviour-changing whenever the query can return more than one row — a
survivor means no test pins *which* end the query is taking.
  - [Mutare.Ecto.RepoAggregate](Mutare.Ecto.RepoAggregate.md): Swap the aggregate of a `Repo.aggregate/3` call along an SQL-meaningful ladder —
`:sum`↔`:avg`, `:min`↔`:max`. A surviving mutant means no test distinguishes, say, the
sum of a column from its average: the aggregate is computed but its *kind* is unchecked.
  - [Mutare.Ecto.RepoWrite](Mutare.Ecto.RepoWrite.md): Mutations on the **persisting Repo writes** — `insert`/`update`/`delete`/`insert_or_update`
and their `!` twins. Two families, both matched by resolving the call's module to one of the
configured `repo:` modules (so direct, aliased, and `use Ecto.Repo`-defined forms all match)

- Query-DSL mutators
  - [Mutare.Ecto.BindingReorder](Mutare.Ecto.BindingReorder.md): Positional **binding-reorder** mutants for every standalone/pipe query macro that takes a binding
pattern list — the `where`/`having` condition macros, `select`, `select_merge`, `order_by`,
`group_by`, `distinct`, `join`, `preload`, `windows`, …, and the free-standing `dynamic/2`
(the condition/clause/join/dynamic descriptors in `Mutare.Ecto.Surface`).
  - [Mutare.Ecto.Clause](Mutare.Ecto.Clause.md): Standalone/pipe clause-macro mutations — the composable cousins of the whole-`from` family
in `Mutare.Ecto.Query`. Where `Query` mutates `from`'s keyword clauses, this mutates the
same kinds of thing written as standalone calls or pipe stages
  - [Mutare.Ecto.ClauseDrop](Mutare.Ecto.ClauseDrop.md): Drop a standalone/pipe **query clause** — the composable cousin of `Mutare.Ecto.Query`'s
whole-`from` clause drop, and the query-side twin of `Mutare.Ecto.Changeset`'s validator drop.
Where `Query` removes a `where:`/`limit:` clause from a `from(…)` keyword list, this removes the
same kinds of clause written as a standalone call or pipe stage
  - [Mutare.Ecto.Query](Mutare.Ecto.Query.md): Whole-`from` query mutations — the ones expressible **without** Mutare's foreign-semantics
DSL host. Each returns a whole mutated `from(...)` node, which
Mutare's ordinary in-place selector wraps; the localized in-fragment mutations (operator
swaps inside a `where`, via `^`/`dynamic`) arrive with the host extensions.

- Hosted in-fragment mutations
  - [Mutare.Ecto.Fragment](Mutare.Ecto.Fragment.md): The plugin's **own** SQL-semantics mutation catalog for a query fragment — the boolean
condition of a `where`/`having` clause or of a free-standing `dynamic/1,2`. Given a condition's
AST, `mutants/1` returns every *single-point* variant: the same condition with **exactly one**
operator/predicate swapped, one variant per mutatable position. Each variant is a full,
compile-safe alternative the SQL engine will actually run; the host (`Mutare.Ecto.Host`) weaves
them behind a `^`/`dynamic` selector so one of them bakes into the query per run, while
`Mutare.Ecto.Dynamic` rebuilds a free-standing `dynamic` call whole (an ordinary expression
position, needing no weave).
  - [Mutare.Ecto.Host](Mutare.Ecto.Host.md): Builds selector-host targets for localized Ecto query conditions.
  - [Mutare.Ecto.Host.Routing](Mutare.Ecto.Host.Routing.md): The **routing classifier** half of the selector host (`Mutare.Ecto.Host`): the
`c:Mutare.CallRouting.route_arguments/2` callback that decides, per visible argument of a
`:routing`-registered query macro, how core should treat that position — `:hosted` (the plugin's
host weaves it), `:expression` (mutate it normally), `:raw` (leave it raw), `:interpolated`
(core mutates a scalar value, delivered through `^` interpolation), or `{:keyword, …}` (per-pair
shorthand routing). `Mutare.Ecto.Host` then consumes the `:hosted` decision to build and weave
the `^`/`dynamic` target.

