Reads a <chart>.fixtures.json sidecar (ADR-0003) and produces the same
StatifierUI.Fixtures struct the behaviour-based delivery path produces.
Uses the stdlib JSON module (Elixir 1.18) to decode, never jason -
jason reaches this repository only through the optional
phoenix_live_view dependency and must not become load-bearing for core
fixture loading.
Every top-level key beyond "version", "scenarios", and "events" is
ignored with a :unknown_key diagnostic (ADR-0006's extension-friendly
requirement), and every value under "scenarios" and "events" is
decoded through StatifierUI.Value.decode/1.
A $duration cannot appear inside "scenarios": it decodes to an
atom-keyed map, and a datamodel forbids atom keys at every level (the
engine's own invariant, tightened in StatifierUI.Fixtures). Such a
sidecar is rejected with {:duration_in_scenario, path}. Durations under
"events" are fine - an _event.data payload has no key constraint.
Summary
Functions
Converts an already JSON-decoded sidecar map into a validated
StatifierUI.Fixtures struct.
Reads, parses, and validates a sidecar file at path, returning the same
struct StatifierUI.Fixtures.from_source/1 produces.
Derives the sidecar path for chart_path and loads it.
Derives a sidecar path from a chart path, per ADR-0003's naming:
payment.scxml becomes payment.fixtures.json. A path with no
extension has .fixtures.json appended.
Functions
@spec from_json( map(), keyword() ) :: {:ok, StatifierUI.Fixtures.t()} | {:error, term()}
Converts an already JSON-decoded sidecar map into a validated
StatifierUI.Fixtures struct.
Options:
:source- the file the map was read from, recorded on each diagnostic and named in each logged warning.load/1passes it; omitting it is for a map that never was a file.
@spec load(Path.t()) :: {:ok, StatifierUI.Fixtures.t()} | {:error, term()}
Reads, parses, and validates a sidecar file at path, returning the same
struct StatifierUI.Fixtures.from_source/1 produces.
Every error names path, because a corpus run loads many sidecars and a
bare POSIX reason does not say which one failed.
@spec load_for_chart(Path.t()) :: {:ok, StatifierUI.Fixtures.t()} | {:error, term()}
Derives the sidecar path for chart_path and loads it.
A missing sidecar is {:error, {:sidecar_not_found, path}}, not an empty
bundle - whether "no fixtures" is acceptable is a caller-level decision,
and a typo'd chart path must not look like a chart without fixtures.
Derives a sidecar path from a chart path, per ADR-0003's naming:
payment.scxml becomes payment.fixtures.json. A path with no
extension has .fixtures.json appended.
Examples
iex> StatifierUI.Fixtures.Sidecar.sidecar_path("payment.scxml")
"payment.fixtures.json"
iex> StatifierUI.Fixtures.Sidecar.sidecar_path("payment")
"payment.fixtures.json"