Skip to content

test(webview): pin image-field's G3 arm against an opener-fence flip - #391

Merged
mtskf merged 3 commits into
mainfrom
chore/pin-g3-opener-flip
Sep 1, 2026
Merged

test(webview): pin image-field's G3 arm against an opener-fence flip#391
mtskf merged 3 commits into
mainfrom
chore/pin-g3-opener-flip

Conversation

@mtskf

@mtskf mtskf commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

image-field.ts's G3 arm fires whenever leadingFrontmatterEnd moves, but PR #390 only pinned one reason it can move — the closer fence crossing the image. detect.ts's other trigger, line 1 itself flipping fence/non-fence (an O(1) reject that makes frontmatter appear or vanish with no closer moving at all), had no fixture crossing an image anywhere in the suite, so narrowing the arm to a closer-only comparison left the whole suite green. This adds the opener pair. Test-only; no source changes.

Changes

  • Add G3_OPENER_ABSENT / G3_OPENER_PRESENT to test/webview/cm-block-widget-bounded.test.ts. The two docs differ by exactly one dash at offset 0, written as a prefix off the other so the "one dash on line 1, nothing else" invariant is textual rather than a promise in a comment: prepending it IS the edit, deleting [0, 1) is its inverse.
  • Add the two bounded ≡ full rows — opener appears (image becomes enclosed, oracleSlots: 0) and opener disappears (image becomes exposed, oracleSlots: 1).
  • Correct the stale row-count claim in checkEquivalence's anti-masking comment: three G3 rows → five, of which four are boundary-crossing.

Notes

The image sits in its own blank-line-delimited paragraph, and that shape is load-bearing. Packed directly under the body key with no blank line, lines 2–4 lazily merge into one paragraph that the trailing --- closes as a setext heading, so the image's Lezer parent stops being Paragraph and image-field.ts's parent gate excludes it in both states, independently of fmEnd — measured 0 → 0, pinning nothing. The blank lines keep line 1's fence status the sole variable moving the image across fmEnd. Two earlier proposals failed on exactly this and on hand-computed slot counts, so every number below was read off a built, settled EditorState.

Related

Test Plan

  • Fixture measurements read off built + settled EditorState, not hand-computed: opener present → fmEnd=52, image at 14, 0 widgets; opener absent → fmEnd=0, 1 widget at 13–46; parent=Paragraph on both sides (so the parent gate is confirmed not to be what moves the count).
  • Non-vacuity: narrowing the G3 arm to a closer-only comparison (fire only when both states have a span and their to differs) reds both new rows — expected [{from:14,to:47}] to deeply equal [] (stale widget) and expected [] to deeply equal [{from:13,to:46}] (missing widget) — while the two closer-fence rows from test(webview): pin image-field's G3 arm with a fence-crossing fixture #390 stay green. Source restored afterwards; the diff is test-only.
  • pnpm compile (5 tsconfigs) green
  • pnpm build green
  • pnpm lint exit 0
  • pnpm test:unit — 270 files / 5149 tests passed

The G3 arm fires whenever leadingFrontmatterEnd moves, but PR #390 only
pinned one reason it can move: the closer fence crossing the image. The
detector's other trigger — line 1 itself flipping fence/non-fence, which
makes frontmatter appear or vanish with no closer moving at all — had no
fixture crossing an image anywhere in the suite. Narrowing the arm to a
closer-only comparison therefore left the whole suite green.

Add the opener pair. The two docs differ by exactly one dash at offset 0,
written as a prefix off the other so the invariant is textual rather than
a promise in a comment, and the image sits in its own blank-line-delimited
paragraph: packed under the body key with no blank line, lines 2-4 lazily
merge into one paragraph that the trailing --- closes as a setext heading,
so the image's Lezer parent stops being Paragraph and the parent gate
excludes it in both states, pinning nothing.

Measured on built, settled states: opener present is fmEnd=52 with the
image at 14 (0 widgets), opener absent is fmEnd=0 (1 widget at 13-46),
parent=Paragraph on both sides. With the arm narrowed to a closer-only
comparison both rows red — stale [14,47] vs [] and missing [] vs [13,46] —
while the two closer rows stay green.
… G3-count comments

Add a third G3 row pair to cm-block-widget-bounded.test.ts pinning the
closer-EXISTENCE-flip direction of image-field.ts's G3 arm (the closer
fence appearing/disappearing entirely below the image while line 1
stays a fence in both states), which the existing closer-position and
opener-identity pairs do not exercise. Verified by mutation testing: a
narrowed arm (openerFenceFlip || both-spans-non-null-with-differing-to)
survives all 16 prior rows but reds exactly these two new ones.

Also fix two comments left stale by PR #390's opener-pair addition
(:199, :294) that read as exhaustive against the file's own
'four/five/six/seven G3 rows' vocabulary, and update the top-of-file
docstring's row/boundary-crossing counts to match the new total (7
G3 rows, 6 boundary-crossing).
… the G3 pair comments

The closer-existence pair's comment opened by calling itself "the third and
last way fmEnd can change". Measured against detect.ts's computeSpan, that is
false: a trailing space on either fence line grows doc.line(n).to while both
fences stay put, and a doc shrinking to one line hits the doc.lines < 2 early
return. The file's own "G3 frontmatter length shift" row is a counterexample
sitting a few lines above. Per the repo's comment contract, the claim is
deleted rather than restated.

Each of the three G3 pairs had also grown a comment explaining the other two,
in both the constants block and the cases array, with the cursorAtEnd
rationale repeated verbatim three times. The shared material now appears once
per block and each pair's comment covers only its own fixture shape and
measurement.

TRAILING_CLOSER is extracted so the suffix the insert row appends is the same
constant G3_TRAILING_CLOSER is built from, mirroring the FM_OPEN / FENCE
precedent — the "appending it IS the edit" invariant is now textual.

Comments and one constant only: no fixture text, oracleSlots, or edit range
changed. 18/18 green.
@mtskf
mtskf merged commit 776e241 into main Sep 1, 2026
2 checks passed
@mtskf
mtskf deleted the chore/pin-g3-opener-flip branch September 1, 2026 21:12
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