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

Groups failed tests by similar error messages.

Provides functionality for the `--group-by-error` option, which helps
identify patterns in test failures by grouping them by error message.

# `encoded_test`

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

A JSON-encoded test result map

# `error_group`

```elixir
@type error_group() :: %{
  pattern: String.t(),
  count: non_neg_integer(),
  example: %{
    name: String.t(),
    module: String.t(),
    file: String.t(),
    line: non_neg_integer()
  }
}
```

An error group with pattern, count, and example test

# `build_error_groups`

```elixir
@spec build_error_groups([encoded_test()]) :: [error_group()]
```

Groups failed tests by similar error message (first line of first failure).

Returns list of groups sorted by count descending.

## Examples

    failed_tests = [
      %{name: "t1", failures: [%{message: "timeout"}], ...},
      %{name: "t2", failures: [%{message: "timeout"}], ...},
      %{name: "t3", failures: [%{message: "connection refused"}], ...}
    ]
    build_error_groups(failed_tests)
    #=> [
    #=>   %{pattern: "timeout", count: 2, example: %{...}},
    #=>   %{pattern: "connection refused", count: 1, example: %{...}}
    #=> ]

# `extract_error_pattern`

```elixir
@spec extract_error_pattern(encoded_test()) :: String.t()
```

Extracts the grouping key from a failed test.

Uses the first line of the first failure message as the pattern.
Normalizes whitespace for better grouping of similar errors.

## Examples

    test = %{failures: [%{message: "timeout after 30s\ndetails here"}]}
    extract_error_pattern(test)
    #=> "timeout after 30s"

    test_no_failures = %{failures: []}
    extract_error_pattern(test_no_failures)
    #=> "(unknown error)"

# `truncate_pattern`

```elixir
@spec truncate_pattern(String.t()) :: String.t()
```

Truncates long patterns to a reasonable length for display.

Adds "..." suffix when truncated.

## Examples

    truncate_pattern("short")
    #=> "short"

    truncate_pattern(String.duplicate("x", 300))
    #=> "xxx...xxx..."  # 200 chars + "..."

---

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