Documentation
¶
Overview ¶
Package golden loads and asserts against the cell-exact terminal fixtures in docs/fixtures — the acceptance artifact for TUI 2.0's frame integrity and column alignment (docs/tui-2.0.md, decision 11).
The fixtures exist before the renderer does. That is the point: they turn the frame and grid work from "does this look right" into red/green, so a row that is one cell too wide fails a test instead of shearing a panel in someone's terminal.
Two assertions, deliberately reported separately, because they have different lifetimes:
- Display width. Every rendered row must be exactly the frame width. This must pass from the first commit and must never be regenerated away — a width diff is a layout bug.
- Byte equality against the fixture. This is the design contract. Expect to regenerate a fixture when copy changes; never when geometry does.
Fixture.Compare returns both kinds tagged by DiffKind so a caller can gate on the first while tolerating churn in the second.
This package deliberately does not import "testing": it returns values and errors so it can also back a regeneration command. Callers in _test.go files turn a non-empty []Diff into t.Errorf.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Dir ¶
Dir returns the absolute path of docs/fixtures, located by walking up from the working directory to the module root. Tests run with their package directory as the working directory, so a relative path would differ per package; this keeps every caller writing golden.Dir().
func SplitLines ¶
SplitLines normalises rendered output into frame rows: ANSI stripped, a single trailing newline tolerated. A View() that ends with a newline and one that does not must not disagree about how many rows it drew.
func StripANSI ¶
StripANSI removes escape sequences, leaving the plain text a fixture stores. Rendered output is styled; fixtures are not, so every comparison goes through this first.
func Width ¶
Width returns the display width of s in terminal cells.
This deliberately delegates to cell.Width rather than measuring independently: the harness must agree with the renderer it judges, and two measurement implementations would eventually disagree about some grapheme and make a real shear look like a passing test.
Types ¶
type Diff ¶
type Diff struct {
Kind DiffKind
// Row is the 1-indexed frame row, or 0 for a whole-frame problem such
// as DiffRowCount.
Row int
// Got and Want are the rendered and expected rows, ANSI already
// stripped. Both are empty for DiffRowCount.
Got, Want string
// GotWidth and WantWidth are display widths in cells.
GotWidth, WantWidth int
}
Diff is a single mismatch between rendered output and a fixture.
type DiffKind ¶
type DiffKind int
DiffKind classifies a mismatch. Callers gate on this: DiffWidth, DiffRowCount, and DiffControl are always bugs in the renderer, while DiffContent can legitimately mean the fixture needs regenerating after a copy change.
const ( // DiffRowCount means the rendered output had the wrong number of rows. DiffRowCount DiffKind = iota // DiffWidth means a row's display width was not the frame width. This // is the assertion that must pass from day one. DiffWidth // DiffContent means a row's text did not match the fixture. DiffContent // DiffControl means a row contained a control character. Tabs and // carriage returns make "display width" meaningless — a tab's width // depends on the terminal's tab stops, not on the string — so they are // rejected outright rather than measured. DiffControl )
type Fixture ¶
type Fixture struct {
// Name is the file name without its extension, e.g. "frame-80x24".
Name string
// Path is the file the fixture was read from.
Path string
// Width and Height are the frame's dimensions in cells and rows.
Width, Height int
// Lines is the frame itself, with the comment header and the two rule
// lines removed. Fixtures carry geometry, not colour, so these are
// plain text with no escape sequences.
Lines []string
}
Fixture is one parsed golden file: a frame of exactly Height lines, each exactly Width display cells wide.
func LoadAll ¶
LoadAll reads every .txt fixture in dir, sorted by name for deterministic test output.
func (*Fixture) Bytes ¶
Bytes renders the fixture back into its on-disk form, header and rules included. Load(Bytes()) round-trips.
func (*Fixture) Compare ¶
Compare checks rendered output against the fixture. rendered may carry ANSI styling and may end with a trailing newline; both are normalised away first, since fixtures store geometry rather than colour.
Every row is checked for width even when the row count is wrong, so a frame that lost one row still reports which of the remaining rows are mis-sized instead of hiding them behind a single count failure.
func (*Fixture) Update ¶
Update replaces the fixture's frame with rendered output and writes it back to disk. It backs the -update flag that regenerates goldens once a renderer exists.
It refuses to write output that is not self-consistent — wrong row count, a mis-sized row, a stray control character — because the whole value of these files is that every line is exactly the frame width. A regeneration that laundered a layout bug into the expected output would destroy that. Height is taken from the fixture, not from the rendered output, so -update cannot quietly resize a frame either.
func (*Fixture) Validate ¶
Validate checks a fixture against its own header: the right number of rows, every row exactly Width cells, and no control characters.
This guards the fixtures themselves, which are hand-maintained until the renderer can regenerate them. It is what catches a row padded with the wrong width rule — the ZWJ-emoji defect found on first review.