A shipped routing-only extension for testing composition with foreign macro routing.
Libraries define how their macro arguments should be treated through Mutare.CallRouting. Use this fixture to test that your mutator respects routes registered by an independent module. It defines two inert pass-through macros and registers their argument routing:
| Macro | Route | Pins |
|---|---|---|
opaque/1 | :raw | every argument is left as written — nothing inside the call is mutated |
tagged/2 | [:expression, :raw] | per-argument routing — the expression mutates, the label never does |
Both expand to their (first) argument, so fixtures using them still compile and run (Mutare.Test.assert_metamutant_compiles/3, Mutare.Test.compile_metamutant/3). Enable the routes by threading the module through the Mutare.Test helpers' opts — routing applies only when the extension is enabled, so the same source doubles as the unrouted contrast:
import Mutare.Test
alias Mutare.Test.RoutingExtension
source = """
defmodule M do
import Mutare.Test.RoutingExtension
def f(x), do: opaque(x + 1)
end
"""
# Unrouted, the argument mutates; routed, the foreign :raw suppresses it.
assert {:arithmetic, "x + 1", "x - 1"} in diffs(source, [:arithmetic])
assert diffs(source, [:arithmetic], extensions: [RoutingExtension]) == []This is an extension — no name/0, no mutations — so it goes under :extensions (or a declarative :call_routes entry naming its macros, to test the config channel). It deliberately covers only the end-user treatments: the adapter-grade ones (:interpolated, {:keyword, …}, :hosted) assert facts about a real DSL's semantics that no generic fixture can stand in for — model those on the Mutare.CallRouting and Mutare.Mutator.MacroHost contracts against the library you're describing.
Summary
Functions
Passes expr through unchanged. Routed fully :raw — its argument is opaque.
Passes expr through, discarding label. Routed [:expression, :raw].