Temper.History.Codec (temper v0.2.0)

Copy Markdown View Source

Encodes Temper.Records as history lines and decodes them back.

Each line is one self-contained JSON object (schema v1): the run context is denormalized into every line so a history file can be read without joins, and run_id groups lines from the same run.

decode/1 never raises — corrupt or foreign input (truncated CI cache tails, future schema versions, non-test lines) comes back as a tagged {:error, reason} so readers can count and skip it.

This module is part of Temper's functional core: strings in, records out, no side effects.

Summary

Types

Reasons decode/1 can reject a line.

Functions

Decodes one history line back into a Temper.Record.

Encodes a record as a single JSON line, without a trailing newline.

Encodes the end-of-run suite summary as a single JSON line.

Types

decode_error()

@type decode_error() ::
  :invalid_json
  | {:unsupported_schema, term()}
  | {:unsupported_kind, term()}
  | {:missing_key, String.t()}
  | {:invalid_status, term()}
  | {:invalid_type, String.t()}

Reasons decode/1 can reject a line.

Functions

decode(line)

@spec decode(String.t()) :: {:ok, Temper.Record.t()} | {:error, decode_error()}

Decodes one history line back into a Temper.Record.

Returns {:error, reason} for malformed JSON, unknown schema versions, non-test kinds (e.g. future "suite" summary lines), missing required keys or unknown statuses. Never raises.

encode(record)

@spec encode(Temper.Record.t()) :: String.t()

Encodes a record as a single JSON line, without a trailing newline.

encode_suite(context, summary)

@spec encode_suite(Temper.RunContext.t(), %{
  tests: non_neg_integer(),
  times_us: map() | nil
}) ::
  String.t()

Encodes the end-of-run suite summary as a single JSON line.

Suite lines share the schema stamp but use kind "suite"; decode/1 rejects them with {:error, {:unsupported_kind, "suite"}} so readers that only want test outcomes skip them without treating them as corruption.