API Reference mutare_ecto v#0.1.1

Copy Markdown View Source

Modules

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.

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).

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.

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

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

In-fragment SQL mutations for a free-standing dynamic/1,2 call — the condition a user builds ahead of time and splices later

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).

Builds selector-host targets for localized Ecto query conditions.

The routing classifier half of the selector host (Mutare.Ecto.Host): the 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.

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.

Swap Ecto.Query.first/1,2Ecto.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.

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.

Mutations on the persisting Repo writesinsert/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)