StatifierUI.Fixtures.Bundle.Markdown (StatifierUI v0.4.0)

Copy Markdown View Source

Renders one StatifierUI.Fixtures.Bundle as the per-fragment "test this step" panel: what the fragment's expressions evaluate to under each of its datasets, and whether each expectation it states still holds.

A pure function over the bundle, in the shape of StatifierUI.TruthTable.Markdown and StatifierUI.EventLog.Markdown: it names Kino only in this moduledoc and calls nothing under Kino.*, so the same string serves a Livebook cell, a generated docs page, or a test assertion. StatifierUI.Kino.test_panel/2 is the widget wrapper.

Two questions, both shown

The panel is deliberately both halves of the fixture contract at once:

  • the truth table (StatifierUI.TruthTable) - what every expression actually evaluates to under every dataset, whether or not an expectation was stated. This is the reading surface.
  • the expectations (StatifierUI.Fixtures.Expectations) - whether every stated expect value held. This is the checking surface.

A fragment's panel is useless with only one: the table without the expectations says what happens but not what was meant, and the expectations without the table say a stated belief held while staying silent about every expression that stated none.

The summary counts rather than passes

The expectations summary reports four counts - matched, mismatched, errored, and stated against a dataset the bundle does not carry - and never collapses them into a pass or a fail. That is not indecision: this package's two consumers of the same fact already disagree about it. StatifierUI.Fixtures.Expectations.check/2 counts a :missing_dataset as a failure, because an expectation naming no dataset was never actually checked; StatifierUI.Fixtures.Lint reports the same dangling key as a warning, per ADR-0006's severity reasoning. Both are right about their own question, the reconciliation is not this renderer's to make, and a panel that printed one verdict would silently pick a side. Four counts let the reader see exactly which of the two situations they are in.

Orientation is passed through, not chosen here

:orientation is forwarded verbatim to StatifierUI.TruthTable.Markdown.render/2, whose own default stands. This renderer states no preference between the two axes.

Summary

Types

Options. :heading is this panel's own # heading; the truth table below it is always rendered untitled, since the panel is already named. Every other option is forwarded to the layer that owns it.

Functions

Renders bundle as a Markdown string.

Renders every bundle in a StatifierUI.Fixtures.Bundle.discovery/0, one panel after another, followed by a section naming the entries that failed to load.

Types

opt()

@type opt() ::
  {:heading, String.t() | nil}
  | {:origin, boolean()}
  | {:expectations, boolean()}
  | {:diagnostics, boolean()}
  | {:orientation, StatifierUI.TruthTable.Markdown.orientation()}
  | {:legend, boolean()}
  | {:sources, boolean()}
  | {:functions, map()}
  | {:providers, keyword()}

Options. :heading is this panel's own # heading; the truth table below it is always rendered untitled, since the panel is already named. Every other option is forwarded to the layer that owns it.

Functions

render(bundle, opts \\ [])

@spec render(StatifierUI.Fixtures.Bundle.t(), [opt()]) :: String.t()

Renders bundle as a Markdown string.

Options:

  • :heading - the # heading. Defaults to the bundle's name; nil for none.
  • :origin - include a line naming the module or file the bundle came from. Defaults to true, because a panel that shows wrong examples is most often showing the wrong bundle.
  • :expectations - include the expectations section. Defaults to true.
  • :diagnostics - include the bundle's load diagnostics (an unknown sidecar key, a future version). Defaults to true.
  • :orientation, :legend, :sources - forwarded to StatifierUI.TruthTable.Markdown.render/2.
  • :functions, :providers - forwarded to Predicator.evaluate/3 through both the table and the expectation run, so the panel's two halves evaluate under identical conditions.

Never raises: an expression that fails to evaluate is a cell and a row, not an exception.

render_discovery(map, opts \\ [])

@spec render_discovery(StatifierUI.Fixtures.Bundle.discovery(), [opt()]) :: String.t()

Renders every bundle in a StatifierUI.Fixtures.Bundle.discovery/0, one panel after another, followed by a section naming the entries that failed to load.

Entries that ship no bundle are not listed. A palette where most fragments carry no examples is the normal case, and a page reciting them says nothing a reader can act on; a bundle that was meant to load and did not is the opposite, and is always named.

:legend defaults to false here rather than true: the three-values legend is worth one appearance on a page, not one per fragment.