Current section

Files

Jump to
Raw

README.md

# mutare_gettext
A [Mutare](https://github.com/foxbenjaminfox/mutare) **extension** that teaches mutation testing to read
[Gettext](https://hexdocs.pm/gettext). It is an *extension*, not a mutator: it produces no mutations
of its own — it only makes Mutare's **built-in** mutators land correctly on a `use Gettext` module,
without poisoning the single metamutant build.
## Install
```elixir
# mix.exs
def deps do
[
{:mutare, "~> 0.1", only: [:dev, :test], runtime: false},
{:mutare_gettext, "~> 0.1", only: [:dev, :test], runtime: false}
]
end
```
```elixir
# .mutare.exs
[extensions: [Mutare.Gettext]]
```
## What it does
Gettext (>= 0.26) is two problems for a single-compile mutation tool:
1. **`use Gettext, backend: MyApp.Gettext`** registers its backend by *mutating the caller module*,
so Mutare's in-process `use` expansion raises and never surfaces the `import Gettext.Macros` it
injects — the bare `gettext`/`ngettext` calls then never resolve.
2. A message id (`gettext("Hello")`) must be a **compile-time literal**; splicing a mutation
selector there makes the macro raise while expanding and poisons the build.
The extension fixes both via Mutare's two extension capability behaviours:
- **`Mutare.UseExpansion`** (`expand_use/3`) takes over every `use Gettext` and injects
`import Gettext.Macros`, so the bare calls resolve.
- **`Mutare.CallRouting`** (`call_routes/0`) routes each macro's arguments per position: the **compile-time literals** (message
id, plural id, domain, context, backend) are `:raw` (never mutated → no poison), while the
**runtime** arguments — the `ngettext` plural `count` and the interpolation `bindings` — are
`:expression`, so a stale plural threshold or wrong interpolation value still gets caught.
This is a whole-module `:raw` baseline plus a per-position override for every arity carrying a
`count`/`bindings`. The overrides are *derived* from the Gettext macro families (so a position
can't drift); the package's test cross-checks each one against the real `Gettext.Macros`.
Targets Gettext **>= 0.26**; on older versions it degrades to a harmless no-op.
## Development
```
mix deps.get
mix test
mix check # format --check-formatted, credo, dialyzer
```
## License
MIT — see [LICENSE](LICENSE).