# `ExUnit.Filters`
[🔗](https://github.com/elixir-lang/elixir/blob/b63734982b8bec7d3386278d56be54b29a33a1aa/lib/ex_unit/lib/ex_unit/filters.ex#L5)

Conveniences for parsing and evaluating filters.

# `ex_unit_opts`

```elixir
@type ex_unit_opts() :: [exclude: [:test], include: [location(), ...]] | []
```

# `location`

```elixir
@type location() ::
  {:location, String.t() | {String.t(), pos_integer() | [pos_integer(), ...]}}
```

# `t`

```elixir
@type t() :: [{atom(), Regex.t() | String.Chars.t()} | atom()]
```

# `eval`

```elixir
@spec eval(t(), t(), map(), [ExUnit.Test.t()]) ::
  :ok | {:excluded, String.t()} | {:skipped, String.t()}
```

Evaluates the `include` and `exclude` filters against the given `tags` to
determine if tests should be skipped or excluded.

Some filters, like `:line`, may require the whole test `collection` to
find the closest line, that's why it must also be passed as an argument.

Filters can either be a regular expression or any data structure
that implements the `String.Chars` protocol, which is invoked before comparing
the filter with the `:tag` value.

## Precedence

Tests are first excluded, then included, and then skipped (if any left).

If a `:skip` tag is found in `tags`, `{:skipped, message}` is returned if the test
remains after the `exclude` and `include` filters. However, if skipped tests are
specifically included, then they will always run.

## Examples

    iex> ExUnit.Filters.eval([foo: "bar"], [:foo], %{foo: "bar"}, [])
    :ok

    iex> ExUnit.Filters.eval([foo: "bar"], [:foo], %{foo: "baz"}, [])
    {:excluded, "due to foo filter"}

# `fail_all!`

```elixir
@spec fail_all!(Path.t()) :: :ok
```

Marks the whole suite as failed in the manifest.

This is useful when the test suite cannot be loaded
and there is a desire to make all tests fail.

# `failure_info`

```elixir
@spec failure_info(Path.t()) ::
  {MapSet.t(Path.t()), MapSet.t(ExUnit.test_id())} | :all
```

Returns failure information from the manifest file.

It returns either `:all`, meaning all tests should be considered as stale,
or a tuple containing:

  * A set of files that contain tests that failed the last time they ran.
    The paths are absolute paths.

  * A set of test IDs that failed the last time they ran

# `normalize`

```elixir
@spec normalize(t() | nil, t() | nil) :: {t(), t()}
```

Normalizes `include` and `exclude` filters to remove duplicates
and keep precedence.

## Examples

    iex> ExUnit.Filters.normalize(nil, nil)
    {[], []}

    iex> ExUnit.Filters.normalize([:foo, :bar, :bar], [:foo, :baz])
    {[:foo, :bar], [:baz]}

    iex> ExUnit.Filters.normalize([foo: "true"], [:foo])
    {[foo: "true"], [:foo]}

    iex> ExUnit.Filters.normalize([:foo], [foo: "true"])
    {[:foo], []}

    iex> ExUnit.Filters.normalize([foo: "true"], [foo: true])
    {[foo: "true"], []}

    iex> ExUnit.Filters.normalize([foo: true], [foo: "true"])
    {[foo: true], []}

    iex> ExUnit.Filters.normalize([foo: 1, foo: 1, foo: 2], [])
    {[foo: 1, foo: 2], []}

    iex> ExUnit.Filters.normalize([], [foo: 1, foo: 1, foo: 2])
    {[], [foo: 1, foo: 2]}

# `parse`

```elixir
@spec parse([String.t()]) :: t()
```

Parses the given filters, as one would receive from the command line.

## Examples

    iex> ExUnit.Filters.parse(["foo:bar", "baz", "line:9", "bool:true"])
    [{:foo, "bar"}, :baz, {:line, 9}, {:bool, "true"}]

# `parse_paths`

```elixir
@spec parse_paths([String.t()]) :: {[String.t()], ex_unit_opts()}
```

Parses filters out of a path.

Determines whether a given file path (supplied to ExUnit/Mix as arguments
on the command line) includes a line number filter, and if so returns the
appropriate ExUnit configuration options.

---

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