Skip to content

fix(spec)!: examples are delimited (heading / --- / prose); remove the Gherkin compat layer#65

Merged
aslakhellesoy merged 1 commit into
mainfrom
fix/example-delimiters
Jul 23, 2026
Merged

fix(spec)!: examples are delimited (heading / --- / prose); remove the Gherkin compat layer#65
aslakhellesoy merged 1 commit into
mainfrom
fix/example-delimiters

Conversation

@aslakhellesoy

Copy link
Copy Markdown
Contributor

Fixes #61.

1. Examples are delimited (ADR 0012)

The only documented way to write a multi-table example was the "hug" — a step
paragraph directly beneath a table with no blank line. That is not valid GFM: the
step parses as another table row, so the layout does not render on GitHub and does
not survive prettier/markdownlint (the formatter silently rewrites the spec,
sometimes into a passing example that asserts nothing).

New rule: an example runs from one delimiter to the next. There are three
delimiters:

  • a heading (#######),
  • a thematic break (---), and
  • a paragraph that matches no step (prose).

Consecutive matching paragraphs (with their attached tables/doc strings) merge
into one shared-state example, so a multi-table flow is ordinary, formatter-stable
GFM:

Given the following users have been imported:

| email | name |
| ----- | ---- |
| a@b.c | Ada  |

And the following assets have been imported:

| name  |
| ----- |
| Moose |

Ported to all seven ports (TypeScript, Python, Ruby, Rust, .NET, Go, Java/Kotlin).
Drift now uses span overlap, which also closes a blind spot: deleting a step
def from the middle of a merged example turns that paragraph into prose, splitting
the example so the now-dead paragraph is reported as drift. New conformance bundle
18-multi-table-example locks the merge, the prose delimiter, and state isolation
across every port.

2. The Gherkin compatibility layer is removed

The delimiter model made multi-scenario .feature files merge (scenarios are
separated only by a blank line). Rather than grow the compat layer to compensate,
we removed it entirely as feature creep:

  • the gherkinTables / gherkinDocStrings / gherkinKeywords scanner plugins,
  • the @varar/cucumber package,
  • the generic scannerPlugins config field + JSON-schema property + the
    ScannerPlugin / scan(plugins) extension mechanism (gherkin was its only
    user), across all seven ports and every wiring point (vitest plugin/runtime,
    CLI, runner, LSP, language index, website worker).

Migration: Varar no longer runs .feature files. Hand your .feature files to
a coding agent and ask it to translate them into Markdown specs and Varar step
definitions — the rewritten Varar for Cucumber users
page maps every Gherkin-ism, including Scenario Outline → header-bound table.

Breaking changes

  • Two step-only examples separated by only a blank line now run as one
    shared-state example — separate them with a --- or a heading. Prose between the
    steps of one example ends it.
  • Varar no longer runs Gherkin .feature files; the scannerPlugins config key is
    removed and is now an unknown-key error.

Docs

  • Rewrote the examples reference ("Where an example begins and ends", naming, the
    attachment/hug section).
  • Deleted the "Run your existing .feature files" how-to; rewrote "Varar for
    Cucumber users" into a Gherkin→Varar mapping; cleaned up configuration.md and
    markup-is-yours.md.

Verification

make check green across all seven ports + commit-lint. Full TS gate (typecheck,
lint, tests, knip, jscpd) and the website build pass. Branch coverage held at the
gate by adding a failure-anchor unit test rather than lowering the threshold.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SqKahEdcXvVEYXt2zuYQwJ

…aragraph

Fixes #61. A multi-table example no longer relies on the "hug" — a step
paragraph glued directly beneath a table with no blank line — which is not valid
GFM and does not survive a Markdown formatter (prettier re-emits the step as a
table row, silently changing what the spec means). Instead an example spans
everything between two delimiters: a heading, a thematic break (---), or a
paragraph that matches no step (prose). Consecutive matching paragraphs merge
into one shared-state example, so a Given -> table -> When -> table -> Then flow
is written as ordinary, formatter-stable Markdown with blank lines between the
tables. Ported across all seven language ports with a new conformance bundle;
drift detection now reports a step paragraph that a mid-example edit turned back
into prose.

Also removes the Gherkin/.feature compatibility layer and the generic
scannerPlugins scanner-extension mechanism it was the only user of (feature
creep): the gherkin table, doc-string, and keyword plugins, the @varar/cucumber
package, the scannerPlugins config field and schema property, and all wiring
across every port. To migrate a Cucumber suite, hand your .feature files to a
coding agent and ask it to translate them into Markdown specs and Varar step
definitions; the website's "Varar for Cucumber users" page maps each
Gherkin-ism, including Scenario Outline -> header-bound table.

BREAKING CHANGE: Two step-only examples separated by only a blank line now run
as a single shared-state example — separate them with a `---` or a heading, and
keep prose out of the middle of an example (a non-matching paragraph between
steps ends the example). Additionally, Varar no longer runs Gherkin `.feature`
files and the `scannerPlugins` config key has been removed (it is now an
unknown-key error). Migrate `.feature` suites by translating them to Markdown
specs and porting the step definitions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SqKahEdcXvVEYXt2zuYQwJ
@aslakhellesoy
aslakhellesoy merged commit 7eeee98 into main Jul 23, 2026
@aslakhellesoy
aslakhellesoy deleted the fix/example-delimiters branch July 23, 2026 08:25
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.

The "hug" is not valid GFM, so a multi-table example cannot survive a markdown formatter

1 participant