All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
0.3.1 - 2026-10-03
Changed
- Requires Mutare 0.5 (
{:mutare, "~> 0.5.0"}) andmutare_plug0.2.1.
0.3.0 - 2026-09-26
Changed
- Breaking: requires Mutare 0.4.1 and mutare_plug 0.2 (
{:mutare, "~> 0.4.1"},{:mutare_plug, "~> 0.2"}). Mutare 0.4.0 offers a call written as a pipe stage to a mutator as the direct call it is sugar for, with the piped value as its first argument; the families here read their argument positions that way now and no longer need Mutare's removed pipe-mode API. - A mutant that leaves the piped value alone is still reported at the stage
(
conn |> json(%{id: 1})→json(%{})at thejsonstage, as before); one that replaces the whole call is reported over the whole pipe.
Added
- The removal families mutate a call written as a pipe stage.
socket |> push("ack", %{})andpubsub |> Phoenix.PubSub.subscribe(topic)now collapse to:okover the whole pipe, upstream stages included; through 0.2.0 the piped spelling was left alone because the:okcould not be spelled as a stage.
0.2.0 - 2026-09-14
Added
Mutare.Phoenix.ChannelReply(:channel_reply) — drops replies from channel return tuples in modules implementingPhoenix.Channel, exposing tests that do not check join payloads or callback replies.Mutare.Phoenix.ChannelMessage(:channel_message) — replaces channel broadcast, push, and deferred reply calls with:ok, exposing tests that do not assert outbound messages.Mutare.Phoenix.PubSub(:pubsub) — replaces subscription, unsubscription, and broadcast calls with:ok, exposing tests that do not check message delivery or subscription changes.Mutare.Phoenix.Token(:token) — swapssign↔encryptandverify↔decrypt, replaces token payloads withnil, and disables expiry by replacing explicit integermax_age:values with:infinity. Marksmax_age:as a timeout so built-in integer and atom mutators skip it.- Variant-specific ignore support for channel message, PubSub, and token
mutations, such as
# mutare:ignore[token:expiry].
Changed
Mutare.Phoenix.all/0now includes the four new families alongside the three controller families, enabling them in configurations using this preset.
0.1.0 - 2026-09-07
Initial release. Builds on mutare_plug, which provides the Plug.Conn
families (:plug_halt, :http_status, :plug_session, :resp_header,
:resp_cookie, :resp_body).
Added
Mutare.Phoenix.Redirect(:redirect_status) — swaps explicit atomstatus:options onPhoenix.Controller.redirect/2among valid redirect status siblings.Mutare.Phoenix.Body(:controller_body) — blanks the body argument ofPhoenix.Controller.json/2to%{}and oftext/2/html/2to""("does any test read the rendered body?"); on a literal text/html body its whole-call rewrite supersedes the built-in string family's sentinel leaves via Mutare's overlap pruning.Mutare.Phoenix.Download(:download_disposition) — flips the explicitdisposition:option ofPhoenix.Controller.send_download/3between:attachmentand:inline.Mutare.Phoenixas aMutare.CallRoutingextension (list it under:extensions): routes thePhoenix.RouterDSL (get/scope/…):skip, so compile-time route definitions are left unmutated, andPhoenix.Component.sigil_H/2(~H) arguments as compile-time literals, so HEEx arguments remain valid during metamutant compilation.Mutare.Phoenix.all/0for splicing the Phoenix families into a:mutatorslist, composing withMutare.Plug.all/0.