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

Coverage collection for ExUnitJSON.

Note: Unit tests for this module directly manipulate `:cover` state.
They work fine with coverage OFF (default) but conflict with `--cover`.
Run with: `mix test.json test/ex_unit_json/coverage_test.exs`

Provides functions to start, collect, and stop code coverage analysis
using Erlang's `:cover` module. Outputs machine-readable coverage data
that can be merged into JSON test output.

## Usage

Coverage is typically managed by the `mix test.json` task:

    # Coverage off by default (faster)
    mix test.json

    # Enable coverage
    mix test.json --cover

## Direct Usage

    ExUnitJSON.Coverage.start()
    # ... run tests ...
    coverage = ExUnitJSON.Coverage.collect()
    ExUnitJSON.Coverage.stop()

# `collect`

```elixir
@spec collect(ignore_modules :: [module()]) :: map()
```

Collects coverage data from instrumented modules.

Returns a map with coverage statistics suitable for JSON output.
Accepts an optional list of module names to ignore.

## Options

  * `ignore_modules` - List of modules to exclude from coverage report

## Return Value

    %{
      "total_percentage" => 96.96,
      "total_lines" => 330,
      "covered_lines" => 320,
      "modules" => [
        %{
          "module" => "ExUnitJSON.Formatter",
          "file" => "lib/ex_unit_json/formatter.ex",
          "percentage" => 92.68,
          "uncovered_lines" => [45, 67, 89]
        }
      ]
    }

# `start`

```elixir
@spec start() :: :ok | {:error, term()}
```

Starts cover instrumentation for local modules.

Compiles all modules in the project for coverage analysis.
Uses `:cover.local_only/0` to avoid distributed coverage.

Returns `:ok` on success, `{:error, reason}` on failure.

# `stop`

```elixir
@spec stop() :: :ok
```

Stops cover and clears all coverage data.

Call this after collecting coverage to clean up resources.
Safe to call even if cover is not running.

Note: :cover.stop() can kill linked processes, so we run it in a
separate unlinked process to avoid killing the caller.

---

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