test(webview): pin image-field's G3 arm against an opener-fence flip - #391
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
image-field.ts's G3 arm fires wheneverleadingFrontmatterEndmoves, 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
G3_OPENER_ABSENT/G3_OPENER_PRESENTtotest/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.bounded ≡ fullrows — opener appears (image becomes enclosed,oracleSlots: 0) and opener disappears (image becomes exposed,oracleSlots: 1).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 beingParagraphandimage-field.ts's parent gate excludes it in both states, independently offmEnd— measured 0 → 0, pinning nothing. The blank lines keep line 1's fence status the sole variable moving the image acrossfmEnd. Two earlier proposals failed on exactly this and on hand-computed slot counts, so every number below was read off a built, settledEditorState.Related
Test Plan
EditorState, not hand-computed: opener present →fmEnd=52, image at 14, 0 widgets; opener absent →fmEnd=0, 1 widget at 13–46;parent=Paragraphon both sides (so the parent gate is confirmed not to be what moves the count).todiffers) reds both new rows —expected [{from:14,to:47}] to deeply equal [](stale widget) andexpected [] 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) greenpnpm buildgreenpnpm lintexit 0pnpm test:unit— 270 files / 5149 tests passed