editor: add HandleEnd window-base regression test

Cover the base-offset conversion in HandleEnd (the path that slices the full
file content by the end-of-line offset), mirroring the tap-to-position
regression test.
This commit is contained in:
Greg Pomerantz 2026-08-16 21:03:03 -04:00
parent 16c39f4221
commit c22c21c872

View File

@ -154,6 +154,39 @@ func TestTapToPosition_WindowBaseOffset(t *testing.T) {
}
}
// TestHandleEnd_WindowBaseOffset is a regression test for the window-relative
// GlyphLayout bug in HandleEnd. The layout covers only the visible window
// (base = IMEWindowStartByte), so its ByteOffsets are window-relative.
// HandleEnd converts the end-of-line position to an absolute file offset
// (base + window offset) before using it to index the full file content.
// Before the fix it used the window-relative offset, landing on the previous
// line's newline.
func TestHandleEnd_WindowBaseOffset(t *testing.T) {
lh := float64(EditorLineHeight())
// File: line0 "AAAAAAAA\n" (bytes 0-8), line1 "BBBBBBBB\n" (bytes 9-17).
// Window starts at byte 9 (line 1). Window-relative offsets: B=0..7, \n=8.
gl := ui.GlyphLayout{LineHeight: EditorLineHeight()}
for i := 0; i < 9; i++ {
gl.ByteOffsets = append(gl.ByteOffsets, i)
gl.X = append(gl.X, ui.Dp(10+10*i))
gl.Y = append(gl.Y, ui.Dp(lh)) // single visual line
gl.Advance = append(gl.Advance, 10)
}
TheState = NewState()
TheState.Editor.Buffer = "AAAAAAAA\nBBBBBBBB\n"
TheState.Editor.GlyphLayout = gl
TheState.Editor.IMEWindowStartByte = 9
TheState.Editor.CursorPosition = 12 // line 1, 4th B (absolute)
HandleEnd()
// The end of line 1 is its newline at absolute byte 17. Before the fix the
// window-relative offset (8) indexed the previous line's newline (byte 8).
if TheState.Editor.CursorPosition != 17 {
t.Errorf("HandleEnd cursor = %d, want 17 (newline ending line 1); window-relative offset bug?", TheState.Editor.CursorPosition)
}
}
// TestTapToPosition_LargeFileScrolled is the end-to-end regression: with a
// window-relative GlyphLayout and a deep scroll, a tap a few lines below the top
// of the window must land on that window line, NOT be clamped to the last window