using AcDream.Content; using DatReaderWriter; using DatReaderWriter.Options; using DatReaderWriter.Types; using Microsoft.Extensions.Logging.Abstractions; using Xunit; namespace AcDream.Content.Tests; /// /// MeshExtractor.GetOrCreateSolidColorTexture (2026-07-24 audit review, Finding /// D): solid-color surfaces bake a 32x32 RGBA fill and previously allocated a /// fresh array on every call. These tests exercise the cache directly (internal /// visibility via InternalsVisibleTo) rather than through the full GfxObj/ /// CellStruct extraction pipeline, so they don't need fixture ids — only a /// working instance, which still needs real dats to /// construct (its ctor builds a RetailPhysicsScriptLoader from dats.Portal). /// Skips cleanly when dats are absent, matching ContentConformanceDats convention. /// public sealed class SolidColorTextureCacheTests { [Fact] public void GetOrCreateSolidColorTexture_SameColor_ReturnsSameSharedArray() { var datDir = ContentConformanceDats.ResolveDatDir(); if (datDir is null) return; // dats absent (CI) — skip, matching suite convention using var dats = new DatCollection(datDir, DatAccessType.Read); using var adapter = new DatCollectionAdapter(dats); var extractor = new MeshExtractor(adapter, NullLogger.Instance, sideStagedSink: null); var color = new ColorARGB { Alpha = 255, Red = 10, Green = 20, Blue = 30 }; var first = extractor.GetOrCreateSolidColorTexture(color, 32, 32); var second = extractor.GetOrCreateSolidColorTexture(color, 32, 32); // Same ARGB value must hit the cache and return the SAME array instance, // not merely an equal one — that's the allocation this cache exists to avoid. Assert.Same(first, second); Assert.Equal(32 * 32 * 4, first.Length); Assert.Equal(10, first[0]); Assert.Equal(20, first[1]); Assert.Equal(30, first[2]); Assert.Equal(255, first[3]); } [Fact] public void GetOrCreateSolidColorTexture_DifferentColors_ReturnDistinctArrays() { var datDir = ContentConformanceDats.ResolveDatDir(); if (datDir is null) return; // dats absent (CI) — skip, matching suite convention using var dats = new DatCollection(datDir, DatAccessType.Read); using var adapter = new DatCollectionAdapter(dats); var extractor = new MeshExtractor(adapter, NullLogger.Instance, sideStagedSink: null); var red = new ColorARGB { Alpha = 255, Red = 255, Green = 0, Blue = 0 }; var blue = new ColorARGB { Alpha = 255, Red = 0, Green = 0, Blue = 255 }; var redTexture = extractor.GetOrCreateSolidColorTexture(red, 32, 32); var blueTexture = extractor.GetOrCreateSolidColorTexture(blue, 32, 32); Assert.NotSame(redTexture, blueTexture); Assert.Equal(255, redTexture[0]); Assert.Equal(0, redTexture[2]); Assert.Equal(0, blueTexture[0]); Assert.Equal(255, blueTexture[2]); } }