acdream/tests/AcDream.App.Tests/UI
Erik 67379d1f9a
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
fix(ui): UiField wrapped-line cache coherent with the text at mouse-hit time
Fixes the crash the user hit twice today (captured in
artifacts/coldeve-acceptance-20260729/crash-hunt.log): clicking into a
multiline UiField - the examination window's inscription field - after
the text had changed since the last draw threw an unhandled
ArgumentOutOfRangeException from String.Substring and took the whole
client down (UiField.MeasureRange <- HitChar <- OnEvent MouseDown).

Root cause: _wrappedLines is a DRAW-side cache (rebuilt only in
DrawMultiLine) consumed by the INPUT side (HitChar on MouseDown and
drag-select MouseMove). Input events are pumped before the frame's
draw, so a mutation (backspace, SetText, paste) followed by a click in
the same pumped frame handed HitChar wrap lines describing the OLD,
longer text; measuring those stale ranges ran past the end of the live
string.

Fix: text mutations now bump a version (the _text field became a
private property so every existing mutation site participates without
churn), the draw records which version its wrap lines describe, and
HitChar proves coherence via EnsureWrappedLinesCurrent() - rebuilding
with the last draw width when stale. Rebuilding rather than clamping
keeps caret placement CORRECT against the live text, not merely
non-throwing. Two inversion-sensitive regression tests reproduce the
exact crash sequence (wrap long text, shrink without a draw, click);
they throw without the HitChar coherence call.

App tests 3,962 passed / 3 skipped (3,960 + 2 new).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 19:38:52 +02:00
..
Layout test(app): put every strict-zero site on the probe (#250) 2026-07-29 03:49:13 +02:00
AutoWieldGenerationTests.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
ClientCommandControllerTests.cs feat(chat): port retail client command families 2026-07-13 14:50:15 +02:00
ControlsIniTests.cs feat(D.2b): controls.ini stylesheet loader + apply title color 2026-06-14 17:31:55 +02:00
CursorFeedbackControllerTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
DatWidgetFactoryZOrderTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
DragDropSpineTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
GameplayConfirmationControllerTests.cs refactor(net): converge live session state reset 2026-07-21 12:00:48 +02:00
IconComposerTests.cs fix(D.5.2): effect tint = per-pixel tile copy (surface ReplaceColor overload) 2026-06-18 10:21:33 +02:00
ItemInteractionControllerTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
LayoutImporterMountTests.cs feat(ui): D.2b-B — sub-window mount (inheritor attaches base subtree) 2026-06-20 22:36:20 +02:00
MarkupDocumentTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
PortalWaitNoticeControllerTests.cs perf(streaming): reserve destination reveal capacity 2026-07-24 19:39:23 +02:00
RetailCursorCatalogTests.cs fix(ui): port retail window control feedback 2026-07-17 09:40:08 +02:00
RetailCursorManagerTests.cs feat(ui): complete retail cursor state machine 2026-07-11 08:31:40 +02:00
RetailItemConfirmationControllerTests.cs refactor(runtime): own interaction transactions 2026-07-26 11:13:09 +02:00
RetailSkillTrainingConfirmationControllerTests.cs fix(ui): restore retail skill training confirmation 2026-07-13 17:57:29 +02:00
RetailUiAutomationProbeTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
RetailUiInteractionFlowTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
RetailUiRuntimeLeaseTests.cs refactor(lifetime): own render resource prefixes 2026-07-22 14:42:14 +02:00
RetailWindowLayoutPersistenceTests.cs fix(ui): restore modern spell formula presentation 2026-07-24 07:08:47 +02:00
RetailWindowManagerTests.cs fix(ui): port retail window control feedback 2026-07-17 09:40:08 +02:00
RetainedPanelControllerGroupTests.cs refactor(ui): own retained controller lifetimes 2026-07-10 23:35:26 +02:00
RetainedUiInputBindingTests.cs refactor(input): own pointer and callback lifetime 2026-07-22 11:59:33 +02:00
UiButtonStateMachineTests.cs feat(ui): port retained widget foundations 2026-07-10 17:55:41 +02:00
UiButtonTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiClipRectTests.cs fix(ui): complete retail inventory scroll polish 2026-07-11 10:56:33 +02:00
UiCollapsibleFrameTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiCompositeShutdownTests.cs test(runtime): add unattended connected R6 soak 2026-07-20 12:12:08 +02:00
UiDatFontTests.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00
UiElementChildOrderTests.cs fix(rendering): bound portal resource lifetime 2026-07-18 21:35:16 +02:00
UiFieldTests.cs fix(ui): UiField wrapped-line cache coherent with the text at mouse-hit time 2026-07-29 19:38:52 +02:00
UiItemListGridTests.cs feat(ui): D.2b item interaction + retail cursors + live character sheet 2026-07-03 09:18:43 +02:00
UiItemListScrollTests.cs fix(ui): complete retail inventory scroll polish 2026-07-11 10:56:33 +02:00
UiItemListTests.cs feat(items): port retail shared cooldown overlays 2026-07-23 10:41:16 +02:00
UiItemSlotTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiLayoutPolicyTests.cs fix(ui): preserve cropped chat and button faces 2026-07-10 18:11:14 +02:00
UiMenuTests.cs fix(D.2b): UiMenu — controller owns Selected (review fix for Task 4) 2026-06-16 17:27:30 +02:00
UiMeterTests.cs feat(D.2b): UiMeter vital bar + fill-geometry tests 2026-06-14 16:38:07 +02:00
UiMeterVerticalTests.cs feat(ui): D.2b-B — UiMeter vertical fill (burden bar, retail m_eDirection 2/4) 2026-06-21 08:58:37 +02:00
UiNineSlicePanelTests.cs feat(D.2b): UiNineSlicePanel — 8-piece retail window frame + geometry test 2026-06-14 16:36:11 +02:00
UiRadarTests.cs feat(ui): port retail radar and compass 2026-07-10 16:14:37 +02:00
UiRootInputTests.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UiScrollablePanelTests.cs feat(ui): D.2b item interaction + retail cursors + live character sheet 2026-07-03 09:18:43 +02:00
UiScrollableTests.cs feat(ui): unify retained window mounts 2026-07-10 22:22:25 +02:00
UiScrollbarTests.cs fix(ui): match retail spell bar controls 2026-07-23 07:49:09 +02:00
UiTextDatFontTests.cs feat(D.2b): UiText (Type 12) -- generic text + Type-12 flip; transcript factory-built (widget-generalization Task 5) 2026-06-16 17:39:02 +02:00
UiTextTests.cs fix(ui): render live component counts 2026-07-15 18:11:02 +02:00