# `Mix.Statifier.Corpus.Authored`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.10.0/lib/mix/statifier/corpus/authored.ex#L1)

Reads the conformance cases this repository authors itself, the
`statifier` suite (ADR-0070 decision 5), from `conformance/cases/`.

Each case is two files in one directory per spec group:

    conformance/cases/<spec>/<name>.scxml   the SCXML document
    conformance/cases/<spec>/<name>.json    what the case expects

The JSON file holds exactly the case fields a person writes -
`description`, `initial_configuration`, `steps` and, optionally, `host` -
in the shapes `conformance/schema/case.json` gives them. Everything else a
corpus case carries is derived, so it cannot drift: `id` is
`statifier/<spec>/<name>`, `suite` is `statifier`, `spec` is the directory,
`conformance` is `null`, `source` is the `.scxml` file's text, and
`required_features` is what the feature detector finds in it.

A case that diffs two charts carries a third file beside the two, the
chart the pair diffs to:

    conformance/cases/<spec>/<name>.to.scxml   the second chart of the pair

Its text is the case's `host.to_source`, derived as `source` is, so the
JSON file never writes it; a case with a `.to.scxml` file and no `host`
object gets one holding only `to_source`. A case name therefore never ends
in `.to`.

The emitter runs every case it reads before it writes
`conformance/corpus/statifier.json`, and `--check` re-derives that file
from these files. No `conformance/cases/` directory means no authored
case.

# `case_path`

```elixir
@spec case_path(corpus_case :: map()) :: Path.t() | nil
```

The path, relative to the project root, of the JSON file an authored
case is written in - the path the regression ratchet
(`test/passing_tests.json`) names the case by, since an authored case has
no generated test module. Any other case has none.

## Examples

    iex> Mix.Statifier.Corpus.Authored.case_path(%{"suite" => "statifier", "id" => "statifier/send/unregistered_type"})
    "conformance/cases/send/unregistered_type.json"

    iex> Mix.Statifier.Corpus.Authored.case_path(%{"suite" => "scion", "id" => "scion/basic/basic0"})
    nil

# `read`

```elixir
@spec read(root :: Path.t()) :: {:ok, [map()]} | {:error, String.t()}
```

Reads every authored case under `root`'s `conformance/cases/`, sorted by
id. Refuses, naming the file, a case whose JSON is invalid or carries a
field outside the written ones, a `.json` or `.scxml` file without its
partner, a `.to.scxml` file without its case's `.json` and `.scxml`, a
JSON file that writes `host.to_source` itself, a file outside a spec
directory, and a name the case id pattern does not allow.

---

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