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

Encodes ExUnit test structures to JSON-serializable maps.

This module handles the conversion of ExUnit structs (tests, failures,
stacktraces) into plain maps that can be serialized to JSON using
Elixir's built-in `:json` module.

# `encoded_test`

```elixir
@type encoded_test() :: %{
  name: String.t(),
  module: String.t(),
  file: String.t() | nil,
  line: non_neg_integer() | nil,
  state: String.t(),
  duration_us: non_neg_integer(),
  tags: map(),
  failures: [map()]
}
```

JSON-serializable test result map

# `test`

```elixir
@type test() :: %ExUnit.Test{
  case: term(),
  description: term(),
  logs: term(),
  module: term(),
  name: term(),
  parameters: term(),
  state: term(),
  tags: term(),
  time: term()
}
```

An ExUnit test struct

# `test_state`

```elixir
@type test_state() ::
  nil
  | {:failed, list()}
  | {:skipped, binary()}
  | {:excluded, binary()}
  | {:invalid, module()}
```

Test state as returned by ExUnit.

- `nil` - test passed
- `{:failed, failures}` - test failed with list of failure tuples
- `{:skipped, message}` - test was skipped
- `{:excluded, message}` - test was excluded by filters
- `{:invalid, module}` - test module is invalid

# `encode_failure`

```elixir
@spec encode_failure(test_state()) :: [map()]
```

Encodes failure details from a failed test.

Handles assertion errors specially to extract left/right values.

# `encode_stacktrace`

```elixir
@spec encode_stacktrace(list()) :: [map()]
```

Encodes a stacktrace to a list of frame maps.

Each frame contains file, line, and optionally module, function, arity, and app.

# `encode_state`

```elixir
@spec encode_state(test_state()) :: String.t()
```

Encodes a test state to a string representation.

## State mappings

- `nil` -> `"passed"`
- `{:failed, _}` -> `"failed"`
- `{:skipped, _}` -> `"skipped"`
- `{:excluded, _}` -> `"excluded"`
- `{:invalid, _}` -> `"invalid"`

# `encode_tags`

```elixir
@spec encode_tags(map()) :: map()
```

Encodes test tags, filtering out internal ExUnit keys.

Removes internal ExUnit keys and converts remaining tags to JSON-safe values.
Keys starting with `:ex_` are also filtered as they are ExUnit internal.

# `encode_test`

```elixir
@spec encode_test(test()) :: encoded_test()
```

Encodes an `ExUnit.Test` struct to a JSON-serializable map.

## Examples

    test = %ExUnit.Test{name: :"test example", state: nil, time: 1000}
    encode_test(test)
    %{name: "test example", state: "passed", duration_us: 1000, ...}

# `encode_test`

```elixir
@spec encode_test(test(), map() | nil) :: map()
```

Encodes a test struct and attaches captured message-trace data (if any).

`trace_data` is the map produced by `ExUnitJSON.Trace.Recorder` (or `nil`). When
present, a `"trace"` key is added alongside `failures`. Used by the formatter for
failing tests that opted into `@tag trace_messages`.

---

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