Skip to content

Fixes #5356. Add tab fan-out layout/draw diagnostic tests#5364

Merged
harder merged 3 commits into
gui-cs:developfrom
harder:fix-5356-tab-fanout-diagnostics
May 22, 2026
Merged

Fixes #5356. Add tab fan-out layout/draw diagnostic tests#5364
harder merged 3 commits into
gui-cs:developfrom
harder:fix-5356-tab-fanout-diagnostics

Conversation

@harder
Copy link
Copy Markdown
Collaborator

@harder harder commented May 21, 2026

Summary

  • Adds TabsFanOutDiagnosticTests (7 parallelizable tests) that count layout and draw activity per tab via SubViewsLaidOut, DrawComplete, ClearedViewport, DrawingContent, and FrameChanged events.
  • Captures the current Draw cascade and layout propagation bugs cause O(N) full redraws on overlapping siblings #4973 fan-out as observable, regression-detectable counters so future fixes can be verified and silent regressions caught.
  • Instrumentation-only: no rendering or invalidation behavior changes.

Implements the acceptance criteria from #5356:

  • Active vs. inactive tab layout work
  • Active vs. inactive tab draw work (DrawComplete, ClearedViewport, DrawingContent)
  • Comparable single-TextView baseline vs. tabbed scenario, reporting fan-out ratios
  • ViewportSettings.Transparent edge case (inactive tabs marked transparent)
  • Shadow-margin edge case (active tab with ShadowStyle = Opaque)
  • IOutput-level check via driver.GetOutput().GetLastOutput() — not relying solely on Driver.Contents
  • Layout and draw counters reported separately so regressions can be localized to one pipeline

Each test emits a per-view counter table via ITestOutputHelper so the data is visible in CI logs even when the test passes. Assertions encode the current (buggy) behavior with comments indicating which assertions need to flip once #4973 is fixed.

Split from #4973.

Test plan

  • dotnet build Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj succeeds
  • dotnet test --no-build -- --filter-method "*TabsFanOutDiagnostic*" — 7 passed
  • dotnet test --no-build -- --filter-method "*TabsTests*" "*TabsScrollingTests*" "*TabsFanOutDiagnostic*" — 102 passed (no regressions in surrounding Tab tests)

Related

Adds TabsFanOutDiagnosticTests with seven parallelizable tests that
observe SubViewsLaidOut, DrawComplete, ClearedViewport, DrawingContent,
and FrameChanged events per tab to measure layout/draw fan-out when an
active TextView inside Tabs scrolls.

Captures the current gui-cs#4973 behavior so that future fixes can be verified
and silent regressions caught:

- Active tab vs. inactive tab layout work
- Active tab vs. inactive tab draw work (DrawComplete, ClearedViewport,
  DrawingContent)
- A comparable single-TextView baseline vs. tabbed scenario fan-out ratio
- ViewportSettings.Transparent does not mask the diagnostic
- Shadow margin does not mask active-tab activity
- IOutput-level output (not Driver.Contents) is observed
- Layout and draw counters reported separately so regressions can be
  localized to one pipeline

The tests are instrumentation-only and do not change rendering or
invalidation semantics.
@harder harder requested a review from tig as a code owner May 21, 2026 14:20
TextView is being deprecated in favor of Code (read-only) and Editor
(editable). The fan-out behavior lives in the View base class layout/draw
pipeline, so any scrollable view inside Tabs reproduces it — swap to Code
so the diagnostic survives the deprecation.

Adjusts assertions to use only widget-agnostic signals (DrawComplete on
each tab, ClearedViewport on the Tabs container). Code overrides
OnClearingViewport/OnDrawingContent and returns true, which suppresses
the ClearedViewport/DrawingContent events on the Code instances. The
per-Code data is still reported but no longer asserted at that level.

Adds Tests/IntegrationTests/TabsFanOutIntegrationTests.cs that drives
the active tab via a real Key.PageDown through the input processor →
command dispatch → main-loop LayoutAndDraw path (rather than mutating
Viewport directly). Runs against all registered drivers. Confirms the
fan-out is observable end-to-end:

  Driver: <each>
  Active tab Viewport.Y after 3 PageDowns: 3
    Tabs             3             3                3
    Code1 (active)   3             3                0
    Code2-4 (inact)  3             3                0
  Sum inactive DrawComplete = 9
@harder
Copy link
Copy Markdown
Collaborator Author

harder commented May 21, 2026

Updated this PR to:

  1. Swap TextViewCode in TabsFanOutDiagnosticTests since TextView is being deprecated in favor of Code (read-only) and Editor (editable). The fan-out behavior lives in the View base class layout/draw pipeline, so any scrollable view inside Tabs reproduces it — Code is a clean in-tree substitute.

    One finding worth surfacing: Code overrides OnClearingViewport and OnDrawingContent and returns true, which suppresses those events on the Code instances themselves. The per-Code DrawComplete and SubViewsLaidOut events still fire, so the fan-out is fully visible via those. Adjusted the per-tab assertions to use only the widget-agnostic signals (DrawComplete); the ClearedViewport assertion now applies to the Tabs container (which goes through the default draw path and does fire the events).

  2. Added Tests/IntegrationTests/TabsFanOutIntegrationTests.cs — drives the active tab via a real Key.PageDown through the input processor → command dispatch → main-loop LayoutAndDraw path (instead of mutating Viewport directly). Runs against all registered drivers via [Theory] [MemberData(GetAllDriverNames)]. Confirms the fan-out is observable end-to-end and not an artifact of the synthetic Layout()/Draw() calls used by the unit tests.

End-to-end result (per driver):

Active tab Viewport.Y after 3 PageDowns: 3
Per-tab counters:
  tab             laidOut  drawComplete  clearedViewport
  Tabs                  3             3                3
  Code1 (active)        3             3                0
  Code2-4 (inactive)    3             3                0
Sum inactive DrawComplete = 9
Sum inactive SubViewsLaidOut = 9

7 unit tests + 3 integration tests, all green. 102 existing tab tests still pass.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds diagnostic (instrumentation-only) tests that quantify the current tabbed layout/draw “fan-out” behavior (issue #4973) so it’s observable and regression-detectable, including an end-to-end integration variant driven through real input/command dispatch.

Changes:

  • Adds TabsFanOutDiagnosticTests (unit tests) that attach per-view counters to layout/draw-related events and report them via ITestOutputHelper.
  • Adds TabsFanOutIntegrationTests (integration) that exercises the same fan-out via real Key.PageDown injection through the main-loop pipeline.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
Tests/UnitTestsParallelizable/Views/TabView/TabsFanOutDiagnosticTests.cs New unit-level diagnostic tests and counter/reporting helper for per-tab layout/draw fan-out.
Tests/IntegrationTests/TabsFanOutIntegrationTests.cs New integration test validating fan-out via real input → command dispatch → main-loop layout/draw path across drivers.

Comment thread Tests/UnitTestsParallelizable/Views/TabView/TabsFanOutDiagnosticTests.cs Outdated
Comment thread Tests/IntegrationTests/TabsFanOutIntegrationTests.cs
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

Add regression diagnostics for tabbed redraw/layout fan-out

3 participants