Skip to content

test: replace fixture prose with field placeholders - #5

Merged
jonhoo merged 1 commit into
mainfrom
placeholders-over-prose
Aug 14, 2026
Merged

test: replace fixture prose with field placeholders#5
jonhoo merged 1 commit into
mainfrom
placeholders-over-prose

Conversation

@jonhoo

@jonhoo jonhoo commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Every test fixture used to carry its own invented Y-Statement — "Store timestamps as UTC", "Retry with exponential backoff", and so on. The parser doesn't care what the words say, so writing that prose was effort that bought nothing, and it actively made snapshot review harder: when in_context and facing_concern each hold a sentence fragment, you have to go back to the fixture to check the parser put each fragment in the slot it belongs in.

Three vocabularies were in play as a result: the README long form (<use case/user story u>) in most of the insta tests, a one-letter form (<u>, <c>, ...) in two unit tests, and hand-written prose in the on-disk fixtures and the YAdr::parse doctest. Fixtures now standardise on a single three-letter form, one per capture slot:

In the context of <ctx>, we faced <con>.

We decided for <opt>, and neglected <alt>.

We did this to achieve <qua>, accepting <dwn>.

We think this is the right trade-off because <why>.

plus <title>, <tail>, and <chg1>/<chg2>/... for change entries. The change descriptions are numbered so that a snapshot would show it if a description were ever paired with the wrong date.

Note that no placeholder may contain a comma or a period: those are what terminate the non-greedy capture groups in YADR_PARAGRAPH_REGEXES. The one fixture that needs bulk, indented_malformed_paragraph, therefore puts its filler inside the angle brackets rather than around them, so that each parameter position stays exactly one placeholder.

Three things deliberately keep their prose:

  • Both realistic tests, which parse a Y-Statement taken verbatim from dson. They exist to catch the format only working for prose we wrote ourselves, and they cover what placeholders can't: commas inside chosen_option, a period mid-because, parenthesised asides.
  • The format documentation (README, the module docs, the Args doc comment, the YAdr struct docs), which keeps the descriptive long form. Documentation explains what belongs in a slot; a fixture only needs to label it.
  • The malformed paragraph in tests/fixtures/broken/malformed.rs, since that sentence is the thing under test.

Some consequences worth knowing about:

  • Titles are all <title> now, so tests/cli.rs identifies statements by date rather than by title throughout.
  • The YAdr::parse doctest demonstrated that the parser leaves comment wrapping in a field; three-letter placeholders never wrap, so it keeps one deliberately long placeholder that spans the line break.
  • Most fixtures still wrap the third paragraph before <dwn> even though it would now fit on one line. That keeps coverage of a capture group whose match spans a line break. The first paragraph of retry.py is wrapped for the same kind of reason — the yadr show reflow assertion needs something to catch — and says so, since unwrapping it would make that assertion pass vacuously.

The 26 affected snapshots were regenerated and reviewed rather than blind-accepted: the diagnostic ones carry width-sensitive caret spans, and each was checked to still underline the paragraph it is meant to. cargo test --all-targets, cargo test --doc, clippy, and the dogfood yadr check over this repo all pass.

Every test fixture used to carry its own invented Y-Statement — "Store
timestamps as UTC", "Retry with exponential backoff", and so on. The
parser doesn't care what the words say, so writing that prose was effort
that bought nothing, and it actively made snapshot review harder: when
`in_context` and `facing_concern` each hold a sentence fragment, you
have to go back to the fixture to check the parser put each fragment in
the slot it belongs in.

Three vocabularies were in play as a result: the README long form
(`<use case/user story u>`) in most of the insta tests, a one-letter
form (`<u>`, `<c>`, ...) in two unit tests, and hand-written prose in
the on-disk fixtures and the `YAdr::parse` doctest. Fixtures now
standardise on a single three-letter form, one per capture slot:

    In the context of <ctx>, we faced <con>.

    We decided for <opt>, and neglected <alt>.

    We did this to achieve <qua>, accepting <dwn>.

    We think this is the right trade-off because <why>.

plus `<title>`, `<tail>`, and `<chg1>`/`<chg2>`/... for change entries.
The change descriptions are numbered so that a snapshot would show it if
a description were ever paired with the wrong date.

Note that no placeholder may contain a comma or a period: those are what
terminate the non-greedy capture groups in `YADR_PARAGRAPH_REGEXES`. The
one fixture that needs bulk, `indented_malformed_paragraph`, therefore
puts its filler *inside* the angle brackets rather than around them, so
that each parameter position stays exactly one placeholder.

Three things deliberately keep their prose:

- Both `realistic` tests, which parse a Y-Statement taken verbatim from
  `dson`. They exist to catch the format only working for prose we wrote
  ourselves, and they cover what placeholders can't: commas inside
  `chosen_option`, a period mid-`because`, parenthesised asides.
- The format documentation (README, the module docs, the `Args` doc
  comment, the `YAdr` struct docs), which keeps the descriptive long
  form. Documentation explains what belongs in a slot; a fixture only
  needs to label it.
- The malformed paragraph in `tests/fixtures/broken/malformed.rs`, since
  that sentence is the thing under test.

Some consequences worth knowing about:

- Titles are all `<title>` now, so `tests/cli.rs` identifies statements
  by date rather than by title throughout.
- The `YAdr::parse` doctest demonstrated that the parser leaves comment
  wrapping in a field; three-letter placeholders never wrap, so it keeps
  one deliberately long placeholder that spans the line break.
- Most fixtures still wrap the third paragraph before `<dwn>` even
  though it would now fit on one line. That keeps coverage of a capture
  group whose match spans a line break. The first paragraph of
  `retry.py` is wrapped for the same kind of reason — the `yadr show`
  reflow assertion needs something to catch — and says so, since
  unwrapping it would make that assertion pass vacuously.

The 26 affected snapshots were regenerated and reviewed rather than
blind-accepted: the diagnostic ones carry width-sensitive caret spans,
and each was checked to still underline the paragraph it is meant to.
`cargo test --all-targets`, `cargo test --doc`, clippy, and the dogfood
`yadr check` over this repo all pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jonhoo
jonhoo merged commit d6ea18c into main Aug 14, 2026
15 checks passed
@jonhoo
jonhoo deleted the placeholders-over-prose branch August 14, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant