test(quadraui): TUI MSV paint↔click round-trip harness - #298
Merged
Conversation
Adds 4 round-trip tests to quadraui::tui::multi_section_view::tests that paint a MultiSectionView into a ratatui Buffer, find painted glyph cells in that buffer, hit_test those exact coordinates against the layout the rasteriser used, and assert the hit identifies the painted-into section. The bug class this catches: paint and hit_test using different coordinate systems. Pre-cell_quantum (Session 343-346 #296), fractional EqualShare distributions made paint snap to integer rows via bounds.y.round() while hit_test consumed raw fractional bounds, so clicks at the row paint drew Watch's header on landed in Variables' body. Either of these tests would have caught that pre-merge. Tests: - header_clicks_land_in_painted_section_under_fractional_distribution - body_clicks_land_in_painted_section_under_fractional_distribution - scrollbar_column_hits_scrollbar_not_body_when_section_overflows - body_and_scrollbar_bounds_never_overlap The fractional-distribution tests use 4 EqualShare sections in 21 cells (5.25 each) — the exact worst case that broke #296. To prove the harness catches the bug, I temporarily flipped cell_quantum back to 0.0 in the rasteriser: the two fractional-distribution tests fail; the structural-bounds tests still pass. With cell_quantum: 1.0, all four pass. The harness catches what cell_quantum fixes. Refactor: extracts pub fn tui_msv_layout(view, area) -> Layout from draw_multi_section_view's body. Hosts and tests now call this helper to drive hit-testing without re-deriving metrics that could drift from paint. draw_multi_section_view itself uses tui_msv_layout internally — paint and hit_test consume one set of metrics, by construction. This is the source-of-truth contract MultiSectionView exists to enforce. Step 3 of the Session 346 course correction (PLAN.md). Next steps: - 4 (TreeView round-trip harness, same pattern) - 5 (extract quadraui to its own repo) - 6 (re-do #296 with the harness gating) Quality gate: cargo build / clippy / fmt / 1950 vimcode lib + integration green; quadraui 298 tests pass under --features tui (was 215 before this session, +83 from new harness + tui-feature- activated inline tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 1, 2026
Closed
JDonaghy
added a commit
that referenced
this pull request
May 1, 2026
PROJECT_STATE.md gains a Session 346 entry capturing: - 5 PRs that landed (cell_quantum #297, TUI MSV harness #298, TUI TreeView harness #299, quadraui extraction #300, plus 3 doc commits direct to develop) - Quadraui now lives at its own repo; vimcode consumes via path-dep sibling - Cross-repo blocked-label tracking now in place (vimcode #296, #282, #301, #302 all blocked on quadraui issues #1-#7 as appropriate) - Migration prerequisites rule means no further consumer migrations land in vimcode until quadraui's rasterisers + harnesses ship PLAN.md "Course correction" section: 7 steps now show ✅ status with PR/SHA references for steps 1-5 (shipped) and ⏳ with cross-repo issue links for steps 6-7 (in quadraui repo). New "Cross-repo prereq tracking" subsection explains how the blocked label flows through plan-next. Doc-only; landing direct to develop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
First instance of the new paint↔click round-trip harness pattern for quadraui primitives. Adds 4 tests in
quadraui::tui::multi_section_view::teststhat paint aMultiSectionViewinto aratatui::buffer::Buffer, find painted glyph cells in that buffer, hit_test those exact coordinates against the layout the rasteriser used, and assert the hit identifies the painted-into section.Also extracts
pub fn tui_msv_layout(view, area) -> MultiSectionViewLayoutfromdraw_multi_section_view's body so paint and tests consume one source of truth.Why this PR exists
Step 3 of the Session 346 course correction. The pattern this PR establishes is the gate for re-attempting #296 (step 6) and migrating SC #282 (step 7), and is the template for future quadraui primitive harnesses (TreeView next, then GTK equivalents).
The bug class the harness catches
Pre-
cell_quantum(#297, just merged), fractionalEqualSharedistributions made paint snap to integer rows viabounds.y.round() as u16whileMultiSectionViewLayout::hit_testconsumed raw fractional bounds — clicks at the row paint drew Watch's header on landed in Variables' body. The #296 smoke wave chased that drift across 8 commits. Either of the fractional-distribution tests below would have caught it pre-merge.Tests added
header_clicks_land_in_painted_section_under_fractional_distribution— 4 EqualShare sections in 21 cells (5.25 each, the exact worst case). Find each section's title row in the buffer, hit_test there, assert correctHeader{section}.body_clicks_land_in_painted_section_under_fractional_distribution— same setup, find item rows in each section's body, hit_test there, assertBody{section}.scrollbar_column_hits_scrollbar_not_body_when_section_overflows— overflowing section reserves a 1-cell scrollbar gutter; clicks on it must hitScrollbar, notBody.body_and_scrollbar_bounds_never_overlap— geometric exclusion check across multiple sections.Empirical verification that the harness catches what
cell_quantumfixesTemporarily flipped
cell_quantum: 1.0→0.0intui_msv_layout:Restored
cell_quantum: 1.0: all 4 pass. Harness catches exactly the bug class the structural fix in #297 closed.Refactor:
tui_msv_layoutdraw_multi_section_viewpreviously inlinedLayoutMetrics+bounds+measure+view.layout(...). Extracted to apub fn tui_msv_layout(view, area) -> MultiSectionViewLayoutthat the rasteriser calls internally and tests/hosts call independently. This means:tui_msv_layoutfor click handling instead of building their ownLayoutMetrics(eliminates the inlinecell_quantum: 1.0duplication that fix(quadraui): MSV snaps section bounds to integer cells (TUI cell_quantum) #297 had to add tomouse.rsandpanels.rs).Test plan
cargo build --no-default-featurescleancargo clippy --no-default-features -- -D warningscleancargo fmt --checkcleancargo test --no-default-features(1950 vimcode tests) greencd quadraui && cargo test --features tui(298 tests, +4 new harness) greencell_quantum=0.0, passes whencell_quantum=1.0Files changed
quadraui/src/tui/multi_section_view.rs—+337/-37. Extracttui_msv_layout; add 4 round-trip tests + helpers (tree_section,row_text,find_row_with,paint_then_layout).Next steps (per PLAN.md "🧭 Course correction")
🤖 Generated with Claude Code