Skip to content

fix(comments): make reflow settle in one pass and keep URLs and sentences intact - #715

Merged
aversini merged 1 commit into
mainfrom
test/comments-properties
Oct 23, 2026
Merged

aversini merged 1 commit into
mainfrom
test/comments-properties

Conversation

@aversini

Copy link
Copy Markdown
Collaborator

Summary

Adds property-based tests (fast-check) for parseAndTransformComments and fixes the bugs they found. The most visible: a URL inside a NOTE: sentence was split, FOOTNOTE: deleted the sentence before it, and several inputs needed two or more runs to settle, which is why we re-run comments until it reports no changes.

Properties (lib.property.test.ts)

Property Input
changed is true exactly when the output differs broad generator
Code outside comments never changes broad generator
Every comment word survives whole (no split URLs or tokens) broad generator
A second pass changes nothing realistic prose (realistic-source.ts)

Each property was checked against a one-line mutant of lib.ts that it must catch, and its comment records the mutant. Idempotence is scoped to realistic prose; degenerate input such as an empty or stacked note: can still need two passes. The minimal inputs for each bug are plain cases in lib.regressions.test.ts, and each one fails on the code it fixes.

Fixes (lib.ts)

  • A NOTE sentence now ends only at ., ! or ? followed by a space or the end of the text, so URLs and regex tokens stay whole.
  • A word ending in NOTE: (for example FOOTNOTE:) no longer drops the text before it.
  • A wrapped line never starts with something the next pass reads as structure: -, +, 1., a fence, a tag, note:, or a directive in // comments. A wrapped line that looks like a heading is joined to its neighbor.
  • A NOTE sentence that wraps keeps its tail; the next sentence starts a new line, as the existing NOTE tests specify.
  • With --merge-line-comments, merging runs again after wrapping, so a long // line settles in one run.
  • Merging no longer starts in the middle of an ineligible // comment.
  • An unclosed code fence no longer grows by one blank line on every run.
  • Removed qualifiesExplanatoryAfterStatement, which never ran: ; is already in the merge eligibility pattern.

Effect on existing code

I ran the old and new versions over the 2,040 TypeScript files in clubroad, episodia, sassysaint, auth0-thin, ui-components, ui-icons and node-cli with --merge-line-comments at width 80:

  • 21 files needed more than one pass before; none do now.
  • 7 files that are stable today change once when they pick up this version: multi-sentence NOTE paragraphs in sassysaint (6) and clubroad (1) settle on one layout.

One existing test changed: it expected the first-pass output without the period that the old code added on its second pass.

Test plan

  • pnpm exec vitest run --globals in packages/comments: 64 tests pass
  • Property file green in 35 consecutive runs (new seed each run)
  • biome check, tsc --noEmit, and comments --merge-line-comments on the touched files are clean

🤖 Generated with Claude Code

…nces intact

Add fast-check property tests for parseAndTransformComments (changed flag,
code outside comments, idempotence on realistic prose, comment words kept
whole) and fix the bugs they found:

- A NOTE sentence ended at any ".", "!" or "?", so a URL inside it was split.
- A word ending in "NOTE:" (FOOTNOTE:) dropped the text before it.
- A wrap that started a line with "-", "+", "1.", a fence, a tag, "note:", or
  (in // comments) a directive changed the comment on the next pass; a wrapped
  line that looked like a heading did too.
- A NOTE sentence that wrapped got its tail joined to the next sentence on the
  second pass, and a sentence split off before a NOTE got its period late.
- With --merge-line-comments, a long // line took two runs to become JSDoc.
- Merging could start in the middle of an ineligible // comment.
- An unclosed code fence grew by one blank line on every run.

Remove the unreachable "explanatory group after a ;" heuristic: ";" is
already in the merge eligibility pattern.

Across the 2,040 TypeScript files in the seven ~/projects repos, 21 needed
more than one pass before; none do now. Seven files that are stable today
change once (multi-sentence NOTE paragraphs settle on one layout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aversini
aversini marked this pull request as ready for review October 23, 2026 13:51
@aversini
aversini merged commit ba55900 into main Oct 23, 2026
4 checks passed
@aversini
aversini deleted the test/comments-properties branch October 23, 2026 14:03
@aversini aversini mentioned this pull request Oct 23, 2026
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