acdream/tests
Erik ce05c4fb03 fix(plugin-ui): Slice B residuals - shelf icon sink without magenta, validated icon bindings, negative ids, memoized DID resolves
Bounded residual round on the Slice B review fix commit (466272ec5),
docs/plans/2026-09-06-plugin-shelf-and-dat-icons.md.

N1 (BLOCKING): PluginSidePanel's shelf entries resolved icons through
_bindings.Assets.ResolveSprite (= ResolveChrome =
TextureCache.GetOrUploadRenderSurface), which returns a non-zero 1x1
magenta placeholder for a missing id - so PluginShelfButton's initials
fallback could never fire in production. RetailUiRuntime.MountPlugins
now passes the same iconResolver.ResolveDid every markup icon sink
already uses, which returns (0,0,0) for an unresolvable id. Re-pointed
the existing initials-fallback unit test at a resolver matching
ResolveDid's real contract, and added an InstalledDat-lane test
(ShelfButton_BogusDescriptorId_OnTheRealResolver_FallsBackToInitials)
proving a bogus descriptor id on the REAL resolver yields initials.

N2: MarkupDocument's <button icon>/<list icons> handling only built the
uint reader (BindUintLiteralOrBinding/BindUintList) when an
IMarkupIconResolver was wired, so a malformed icon="{Typo}" or
icons="notabinding" silently loaded instead of throwing at Build on a
resolver-less host. Both readers now build unconditionally (same rule
ValidateIconKind already followed); only the IconSource/IconIdsSource
assignment stays gated on icons is not null.

N3: a negative bound icon id threw OverflowException out of
Convert.ToUInt32 every frame from inside UiSimpleButton.OnDraw (scalar
path), while the list's IEnumerable<int> path silently wrapped -1 to
0xFFFFFFFF (unchecked reinterpret). Both paths now map any
out-of-range value (negative, or above uint.MaxValue) to 0u instead -
Decal's own "no icon" convention - via a shared ToUintOrZero helper
that catches exactly the OverflowException Convert.ToUInt32 already
throws for both cases.

N4 (perf): RetailMarkupIconResolver.ResolveDid probed Portal/HighRes
(two cache misses + two B-tree lookups under the database lock) on
EVERY call for an unresolvable id, and re-entered the DAT lock on
every resolve of a hit too. Memoizes the resolved (tex,w,h) tuple per
DID, including the (0,0,0) miss, in a plain Dictionary.

N5 (nit): documented in TextureCache.GetOrUploadRenderSurface that the
(id, nearest) cache key uploads the same RenderSurface twice when both
samplers are wanted (chrome via ResolveChrome, plugin icons via
ResolveDid's nearest:true) - GetOrCreateLinearUiTwin exists but only
shares in the nearest-registered-first direction, so wiring it through
here is left as a documented nit rather than a behavior change.

N6 (nit): corrected stale SampleData.cs:64 citations to :69 (Melee
Defense's real line after the file grew) across SmokeIconPanel.cs,
PluginSidePanelTests.cs, RetailMarkupIconResolverInstalledDatTests.cs,
and docs/plugin-ui-markup.md (including the 64-82 range, now 69-83).

N7 (nit): <icon iconkind="..."> was silently ignored (icon derives its
kind from which of did/spell/item is set, unlike button/list). Now
throws FormatException at Build with a message naming the correct
surfaces; documented in plugin-ui-markup.md.

N8 (nit): the truth-table's `list colors` row now says IEnumerable<uint>
or IEnumerable<int> (shared BindUintList), matching `list icons`.

N9 (ship check): added a "Before shipment" line to the plan's Review
ledger. Confirmed the Smoke plugin (including its auto-open Icon Smoke
panel) IS included in the launcher's client-<rid>.zip release payload:
tools/publish-bin.ps1's New-PayloadZip zips App's entire publish
directory unfiltered, and AcDream.App.csproj's
CopySmokePluginToPublishOutput target runs unconditionally
AfterTargets="Publish". No behavior changed per instruction - flagged
for follow-up after the owner's connected gate.

Verification: dotnet build AcDream.slnx -c Release green; filtered
test command 108/108 passed (0 skipped) including the InstalledDat
lane; full AcDream.App.Tests suite 7362 passed / 97 skipped / 36
failed (all 36 pre-existing, same names, none touching
Markup/PluginSidePanel/RetailMarkupIconResolver/TextureCache/PluginIcons);
AcDream.Plugins.MossTank.Tests 337/337 passed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 16:28:13 +02:00
..
AcDream.App.Tests fix(plugin-ui): Slice B residuals - shelf icon sink without magenta, validated icon bindings, negative ids, memoized DID resolves 2026-09-06 16:28:13 +02:00
AcDream.Bake.Tests Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Cli.Tests build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Content.Tests fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Core.Net.Tests fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
AcDream.Core.Tests fix(physics): port ordered part-array building transit 2026-09-05 20:28:52 +02:00
AcDream.Core.Tests.Fixtures.HelloPlugin feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Headless.Tests fix(overhaul): integrate reviewed debt-free retirement #475 2026-09-05 11:05:07 +02:00
AcDream.Launcher.Core.Tests fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Launcher.Core.Tests.Fixtures.ConsolelessSupervisorParent build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Launcher.Core.Tests.Fixtures.ConsoleSignalChild build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Launcher.Core.Tests.Fixtures.InstallLeaseHolder feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Launcher.Tests Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Platform.Tests feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.HostPlugin feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.InvalidRenderPackInternal feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.InvalidRenderPackMultiple feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugins.MossTank.Tests feat(mosstank): add VTank-style automation PoC 2026-08-27 18:57:21 +02:00
AcDream.RenderPackValidator.Tests feat(render): shader ABI v2 - AtmosphericFrame gains clock/wind blocks; caster pass binds it (Campaign VM VM6a) 2026-08-23 00:30:02 +02:00
AcDream.Runtime.Tests fix(overhaul): integrate reviewed debt-free retirement #475 2026-09-05 11:05:07 +02:00
AcDream.UI.Abstractions.Tests fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
Fixtures/campaign-la feat(plugins): enforce apiVersion; launcher plugins default ON with "none" opt-out 2026-08-20 21:28:04 +02:00
Directory.Build.props fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00
TestCultureInitializer.cs fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00