# `ExUnitJSON.Filters`
[🔗](https://github.com/ZenHive/ex_unit_json/blob/main/lib/ex_unit_json/filters.ex#L1)

Test filtering logic for ExUnitJSON.

Provides functions to filter test results based on configuration options
like `--failures-only`, `--first-failure`, and `--filter-out` patterns.

# `encoded_test`

```elixir
@type encoded_test() :: map()
```

A JSON-encoded test result map

# `filter_opts`

```elixir
@type filter_opts() :: [
  summary_only: boolean(),
  failures_only: boolean(),
  first_failure: boolean(),
  filter_out: [String.t()]
]
```

Filter options keyword list

# `apply_filter_out`

```elixir
@spec apply_filter_out([encoded_test()], [String.t()]) :: [encoded_test()]
```

Marks failed tests as filtered if their failure message matches any pattern.

Returns tests unchanged if no patterns provided.

## Examples

    # No patterns - tests unchanged
    apply_filter_out(tests, [])
    #=> tests

    # Matching pattern adds :filtered key
    tests = [%{state: "failed", failures: [%{message: "credentials missing"}]}]
    apply_filter_out(tests, ["credentials"])
    #=> [%{state: "failed", failures: [...], filtered: true}]

# `count_filtered_failures`

```elixir
@spec count_filtered_failures([encoded_test()], [String.t()]) :: non_neg_integer()
```

Counts failed tests that match any filter_out pattern.

Returns 0 if no patterns provided or no matches found.

## Examples

    tests = [
      %{state: "failed", failures: [%{message: "credentials missing"}]},
      %{state: "failed", failures: [%{message: "timeout error"}]},
      %{state: "passed"}
    ]
    count_filtered_failures(tests, ["credentials"])
    #=> 1

    count_filtered_failures(tests, [])
    #=> 0

# `failure_matches_pattern?`

```elixir
@spec failure_matches_pattern?(encoded_test(), [String.t()]) :: boolean()
```

Checks if any failure message in the test matches any of the patterns.

## Examples

    test = %{failures: [%{message: "connection timeout"}]}
    failure_matches_pattern?(test, ["timeout"])
    #=> true

    failure_matches_pattern?(test, ["credentials"])
    #=> false

# `filter_tests`

```elixir
@spec filter_tests([encoded_test()], filter_opts()) :: [encoded_test()] | nil
```

Filters tests based on configuration options.

Returns nil for summary_only (omit tests array), filtered list, or all tests.

## Priority

  1. `summary_only` - Highest priority, returns nil (omits tests array)
  2. `first_failure` - Returns only the first failed test
  3. `failures_only` - Returns all failed tests (the default since v0.3.0)
  4. `failures_only: false` (the `--all` flag) - Returns all tests

## Examples

    # summary_only returns nil
    filter_tests(tests, summary_only: true)
    #=> nil

    # failures_only returns only failed tests
    filter_tests([%{state: "passed"}, %{state: "failed"}], failures_only: true)
    #=> [%{state: "failed"}]

# `reject_filtered_failures`

```elixir
@spec reject_filtered_failures([encoded_test()], [String.t()]) :: [encoded_test()]
```

Rejects (excludes) failed tests whose failure message matches any pattern.

Unlike `apply_filter_out/2` which marks tests with `filtered: true`,
this function removes matching tests entirely. Used for error_groups
where filtered failures should not appear at all.

## Examples

    # No patterns - tests unchanged
    reject_filtered_failures(tests, [])
    #=> tests

    # Matching failures are removed entirely
    tests = [
      %{state: "failed", failures: [%{message: "credentials missing"}]},
      %{state: "failed", failures: [%{message: "timeout error"}]}
    ]
    reject_filtered_failures(tests, ["credentials"])
    #=> [%{state: "failed", failures: [%{message: "timeout error"}]}]

---

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