Mutare.Plug.Status (mutare_plug v0.1.0)

Copy Markdown View Source

:http_status — swaps the atom status of Plug.Conn.put_status/2, send_resp/3, resp/3, send_chunked/2, and send_file/3,4,5 for a plausible sibling in the same status family. A surviving mutant means no test pins the exact status code.

put_status(conn, :ok)            # → :created / :no_content
put_status(conn, :unauthorized)  # → :forbidden
send_resp(conn, :not_found, "")  # → :gone / :forbidden

Integer statuses (put_status(conn, 200), send_resp(conn, 200, body)) are left to the built-in literal family. Matches each call written directly, aliased, or bare-imported (from use Plug.Builder / use Plug.Router, or Phoenix's use MyAppWeb, :controller).

Configurable

The swap table is tunable per instance. Give the family {module, opts} with a :swaps map: a status you list replaces its built-in siblings, an empty list disables it, and any status you omit keeps its built-in siblings. Configured siblings must be valid Plug.Conn.Status reason atoms — trusted, not checked: the built-in table guarantees this for its own entries, but a sibling you add that isn't a real status produces a crashing, uninformative mutant rather than the valid-but-wrong swap the table is built to give.

Configuring a family means listing it yourself, so expand Mutare.Plug.all/0 into its members and replace the Status entry:

# .mutare.exs — narrow :ok to one sibling, stop mutating :no_content, add a teapot
[
  mutators: [
    :builtins,
    Mutare.Plug.Halt,
    {Mutare.Plug.Status,
     swaps: %{ok: [:created], no_content: [], im_a_teapot: [:bad_request]}},
    Mutare.Plug.Session,
    Mutare.Plug.Header,
    Mutare.Plug.Cookie,
    Mutare.Plug.Body
  ]
]

An unconfigured instance — Mutare.Plug.Status, or the one in Mutare.Plug.all/0 — uses the built-in table unchanged.