acdream/tests/AcDream.App.Tests
Erik 03e073b748 feat(ui): Campaign CT slice CT3 — Titles page live via standard GUI classes
Titles tab (AP-109's known-inert gap) now switches to a real page and
CharacterTitlesController binds it entirely through UiTemplateListBox/
UiScrollbar/UiButton — zero bespoke widgets, matching every other
social/options row-list page in this codebase.

Retail anchors: gmCharacterTitleUI::PostInit @0x0049A610; AddTitleToList
@0x0049A840 + FindSortedInsertPosition @0x0049A760 (rows sorted by
resolved display text — this port rebuilds the full sorted set on every
change rather than a positional splice, since UiTemplateListBox has no
insert-at-index primitive and no other consumer needs one either);
InfoRegion::SetState(selected?6:1) (row Highlight/DirectState swap, the
same mechanism CT1's SEALED VERDICT confirmed for the stat rows);
UpdateButtons @0x0049A500 CORRECTED direction (Ghosted unless a row is
selected whose id differs from the current display title — no selection
IS the Ghosted case); Refresh @0x0049abc0 (display-title text, including
the hardcoded "Unknown" fallback, refreshed on both TableReplaced and
DisplayTitleChanged per CT2's review anchor 1); Event_SetDisplayCharacterTitle
@0x006a5720 (wire-only TitleSet 0x002C send, no local mutation).

CharacterStatController.Bind now three-way switches Attributes/Skills/
Titles — Titles is a genuinely separate, non-duplicated page container
(CT1 ground truth §3), unlike Attributes/Skills which share one mounted
page and only rebind content.

The two page captions (0x1000052E/0x10000531) are left untouched:
LayoutImporter.BuildText already resolves every element's authored
StringInfo caption at import time, so no controller-side string lookup
was added.

New IGameRuntimeCommands.SetTitle seam on DeferredGameRuntimeStateCommands
(InteractionUiRuntimeSources.cs) mirrors the existing Advance() shape.
CharacterRuntimeBindings gains Titles/TitleResolver/SendSetTitle;
CharacterTitleResolver (CT2) is constructed once at composition time and
its .Resolve method group is passed to the controller as a delegate
(not the concrete DAT-backed type) so the controller stays hermetically
testable without a live IDatReaderWriter.

Tests (tests/AcDream.App.Tests/UI/Layout/CharacterTitlesControllerTests.cs):
binding-seam coverage against the REAL committed character_2100002E.json
fixture (verified this session to already carry the Titles page subtree,
including the ListBox's own authored TemplateList=[(0x2100005E,
0x10000536)] entry — RowTemplateResolver_ReceivesTheFixturesOwnAuthoredTemplateIds
proves the controller reads that authored pair, not a hardcoded one); a
hand-authored ElementInfo standing in only for the row template itself
(a separate LayoutDesc with no committed fixture yet — CT1 was a live-DAT
probe only); sorted-row order, Unknown fallback, row selection/highlight,
the ghost truth table (no selection / selected==display / selected!=
display), click-sends-exactly-one-SetTitle-and-mutates-nothing,
click-while-ghosted-sends-nothing, TableReplaced rebuild (including
selection survival when the id is still earned), TitleAdded single-row
growth, DisplayTitleChanged text+ghost refresh, and Dispose
unsubscription. CharacterStatControllerTests updated for the Titles tab
no longer being ClickThrough, plus a new tab-switch visibility test.

Register: amends AP-109 (docs/architecture/retail-divergence-register.md)
to record the Titles-page half as LIVE; the header identity block and
luminance fields remain open for CT4.

Suites: full solution 15,405 tests / 0 skips (App 6,130) green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 22:59:40 +02:00
..
Architecture test: replace gameplay owner source freezes 2026-08-18 16:49:38 +02:00
Audio feat(audio): Campaign A slice A2 — retail's 2D pan+gain mixer replaces AL 3D 2026-08-08 21:58:50 +02:00
Combat fix #436: combat no-target refusal reaches the SpewBox with retail's exact text 2026-08-24 12:53:11 +02:00
Composition feat(CT): CT2 — Runtime character-title ownership + wire 2026-08-24 22:03:22 +02:00
Configuration fix(app): Campaign LA gate round 2 — session-config launches force the retail UI on 2026-08-15 08:42:33 +02:00
Credentials test: make prerequisite lanes fail honestly 2026-08-18 12:09:41 +02:00
Diagnostics test: tie the soak's move-truth grep to a live emitter — both ends now break together 2026-08-24 13:01:33 +02:00
Input fix(input): free-fly is unreachable, and Escape no longer answers to it 2026-08-21 09:55:16 +02:00
Interaction fix: social panel completion batch (user gate 2026-08-13, "fix all") 2026-08-13 19:30:51 +02:00
Net feat(CT): CT2 — Runtime character-title ownership + wire 2026-08-24 22:03:22 +02:00
Physics test: replace input and physics source freezes 2026-08-18 15:31:57 +02:00
Platform feat(platform): Campaign LA LA0 — extract ApplicationPathSet to AcDream.Platform 2026-08-14 15:19:02 +02:00
Plugins feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
Rendering fix #435 (part 1): delete 17 probes that outlived their closed investigations 2026-08-24 11:41:20 +02:00
Runtime test: replace gameplay owner source freezes 2026-08-18 16:49:38 +02:00
Settings feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
Spells feat(headless): share immutable gameplay content 2026-07-27 09:00:48 +02:00
Streaming feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
UI feat(ui): Campaign CT slice CT3 — Titles page live via standard GUI classes 2026-08-24 22:59:40 +02:00
World test: replace create authority source pin 2026-08-18 16:52:22 +02:00
AcDream.App.Tests.csproj feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
BoundedTestDatCollection.cs perf(content): remove exception-driven setup probes 2026-07-24 15:12:21 +02:00
FramePhaseTestDoubles.cs refactor(runtime): move session lifetime and ordered transport 2026-07-25 19:39:24 +02:00
FrameProfilerReportTests.cs perf(diag): complete trustworthy Slice A capture tooling 2026-07-24 12:46:51 +02:00
FrameStatsBufferTests.cs fix(pipeline): MP0 - profiler toggle-path hygiene + Max() seed (review follow-up) 2026-07-05 19:26:28 +02:00
GameRuntimeTestFactory.cs refactor(runtime): cut graphical host over to canonical root 2026-07-26 19:06:09 +02:00
GlobalUsings.cs feat(runtime): share chat commands and run login sequence 2026-08-14 20:27:45 +02:00
LiveEntityRuntimeFixture.cs test(runtime): restore the world-frame precondition across first-entry fixtures 2026-08-03 13:32:28 +02:00
LiveEntitySpawnFixture.cs feat(runtime): C3c - production placement cutover: both hosts on the residence conductors (routes 1+8) 2026-08-02 18:10:33 +02:00
packages.neutral.lock.json build: make release restore reproducible 2026-08-18 10:29:00 +02:00
RuntimeDatAccessArchitectureTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeDatCollectionFactoryTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeOptionsRetailUiTests.cs test(runtime): add deterministic world gate artifacts 2026-07-20 22:37:16 +02:00
RuntimeOptionsTests.cs fix #435 (part 2, closes it): attribute the unowned probes — delete 7, reclassify 8, restore 1 2026-08-24 12:32:42 +02:00
RuntimeWorldTransitTestDriver.cs refactor(runtime): own teleport destination correlation 2026-07-26 17:52:34 +02:00
ZeroAllocationProbe.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00
ZeroAllocationProbeTests.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00