# `Mutare.TestSelection`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.4.3/lib/mutare/test_selection.ex#L1)

Which tests to run for one mutant, before command-line serialization.

`:suite` runs everything; `{:files, paths}` runs whole files;
`{:tests, paths, names}` narrows those files to the named tests; and
`{:app, dirs}` runs an umbrella app and its dependents' test directories.
`:no_coverage` launches no run. File, directory, and name lists are nonempty:
an empty attribution must be resolved explicitly to a broader selection, never
passed along as an accidental whole-suite command.

The constructors enforce nonemptiness and sort for deterministic execution.
Coverage summaries and result labels read `shape/1`; only
`Mutare.Sandbox.Command` serializes a runnable selection to Mix arguments.

# `app`

```elixir
@type app() :: {:app, [Path.t(), ...]}
```

# `covered`

```elixir
@type covered() :: :suite | files() | tests()
```

# `files`

```elixir
@type files() :: {:files, [Path.t(), ...]}
```

# `runnable`

```elixir
@type runnable() :: covered() | app()
```

# `shape`

```elixir
@type shape() :: :suite | :files | :tests | :app
```

# `t`

```elixir
@type t() :: runnable() | :no_coverage
```

# `tests`

```elixir
@type tests() :: {:tests, [Path.t(), ...], [String.t(), ...]}
```

# `app`

```elixir
@spec app([Path.t(), ...]) :: app()
```

# `files`

```elixir
@spec files([Path.t(), ...]) :: files()
```

# `narrow_to_app`

```elixir
@spec narrow_to_app(t(), Path.t(), %{required(atom()) =&gt; [Path.t()]}) :: t()
```

Narrow a whole-suite run to the source file's owning app and its dependents.

`scopes` comes from `Mutare.Project.app_test_scopes/3`. Unknown apps and empty
scopes retain the whole suite; every other selection passes through unchanged.

# `shape`

```elixir
@spec shape(t()) :: shape() | :no_coverage
```

# `tests`

```elixir
@spec tests([Path.t(), ...], [String.t(), ...]) :: tests()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
