test: separate diagnostic apparatus from release gates

This commit is contained in:
Erik 2026-08-18 11:06:08 +02:00
parent 8f490240d4
commit c1a905004a
33 changed files with 527 additions and 24 deletions

View file

@ -541,6 +541,7 @@ public class CornerFloodReplayTests
/// <summary>Scratch: the homogeneous reciprocal primitive in isolation, on the
/// synthetic fixture geometry that Build_AppliesReciprocalOtherPortalClip uses.</summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Scratch_ReciprocalPrimitive_SyntheticPair()
{
var view = Matrix4x4.CreateLookAt(Vector3.Zero, new Vector3(0, 0, -1), Vector3.UnitY);

View file

@ -14,6 +14,7 @@ namespace AcDream.App.Tests.Rendering;
/// candidate setup's parts + bounds from the dat. The portal's setup is the
/// translucent swirl; lamp posts / creatures / signs identify by part shape.
/// </summary>
[Trait("Purpose", "Diagnostic")]
public class Issue131SetupProbeTests
{
private readonly ITestOutputHelper _out;

View file

@ -98,7 +98,8 @@ public class Issue176177FacilityHubFloodReplayTests
}
[Fact]
public void ScenarioB_StairDescent_RampCellRetention()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_ScenarioB_StairDescent_RampCellRetention()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -140,7 +141,8 @@ public class Issue176177FacilityHubFloodReplayTests
}
[Fact]
public void ScenarioC_CorridorSeamGazeSweep_Bistability()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_ScenarioC_CorridorSeamGazeSweep_Bistability()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -212,9 +214,10 @@ public class Issue176177FacilityHubFloodReplayTests
/// #177(a)/(c) at the stair transit.
/// </summary>
[Theory]
[Trait("Purpose", "Diagnostic")]
[InlineData(0x016Eu, 0x017Au, 85.00f, -4.3f)] // corridor seam, plane x=85
[InlineData(0x0182u, 0x0183u, 98.333f, -7.3f)] // stair-bottom transit, plane x=98.33
public void ScenarioE_RootLagWindow_ForwardChainRetention(
public void Diagnostic_ScenarioE_RootLagWindow_ForwardChainRetention(
uint rootLow, uint forwardLow, float planeX, float eyeZ)
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
@ -239,7 +242,8 @@ public class Issue176177FacilityHubFloodReplayTests
}
[Fact]
public void ScenarioD_CorridorWalk_PerStepChurn()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_ScenarioD_CorridorWalk_PerStepChurn()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }

View file

@ -105,7 +105,8 @@ public class Issue177StairDescentCameraFloodTests
=> string.Join(" ", ids.Select(id => $"{id & 0xFFFFu:X4}"));
[Fact]
public void StairCellComposition_ShellVsStatics()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_StairCellComposition_ShellVsStatics()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -166,7 +167,8 @@ public class Issue177StairDescentCameraFloodTests
/// locate the knife-edge and which cell flips.
/// </summary>
[Fact]
public void RealStaircase_FineYawZoomSweep_FindKnifeEdge()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_RealStaircase_FineYawZoomSweep_FindKnifeEdge()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -228,7 +230,8 @@ public class Issue177StairDescentCameraFloodTests
/// caps well below retail's 26, our flood truncates the spiral (the vanish).
/// </summary>
[Fact]
public void FloodDepthFrom015E_VsRetail26()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_FloodDepthFrom015E_VsRetail26()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -349,7 +352,8 @@ public class Issue177StairDescentCameraFloodTests
/// contact leaving the eye on the surface vs free-space boom geometry.
/// </summary>
[Fact]
public void StaircaseSweep_EyeClearanceFromCeilingPortal()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_StaircaseSweep_EyeClearanceFromCeilingPortal()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -392,10 +396,11 @@ public class Issue177StairDescentCameraFloodTests
}
[Theory]
[Trait("Purpose", "Diagnostic")]
// spot label, player x, player cell, description
[InlineData(90.0f, 0x0178u, "TOP corridor 0178 (approach view)")]
[InlineData(100.0f, 0x0183u, "BOTTOM room 0183 (look-back view)")]
public void ParkedYawZoomSweep_StairAdmission(float px, uint pcell, string label)
public void Diagnostic_ParkedYawZoomSweep_StairAdmission(float px, uint pcell, string label)
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -451,7 +456,8 @@ public class Issue177StairDescentCameraFloodTests
}
[Fact]
public void Descent_RealCameraSweep_StairCellRetention()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_Descent_RealCameraSweep_StairCellRetention()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }

View file

@ -56,6 +56,7 @@ public class Issue181VisFlapReplayTests
=> string.Join(" ", ids.Select(id => $"{id & 0xFFFFu:X4}"));
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_FlappingCellViewRegion_SliverOrLarge()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();

View file

@ -32,6 +32,7 @@ namespace AcDream.App.Tests.Rendering;
/// numbers into hard pins.
/// </summary>
[Collection(CameraDiagnosticsCollection.Name)]
[Trait("Purpose", "Diagnostic")]
public class Issue181WallPressEquilibriumTests
{
private const uint FacilityHubLandblock = 0x8A020000u;

View file

@ -14,6 +14,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// identify the two FA slots definitively: 0x1000026F (fellowship name field)
/// and 0x10000263 (swear-allegiance button). Env-gated like the other probes.
/// </summary>
[Trait("Purpose", "Diagnostic")]
public sealed class FaPanelSlotProbeTests
{
[Fact]

View file

@ -25,6 +25,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// throwaway.
/// </para>
/// </summary>
[Trait("Purpose", "Diagnostic")]
public sealed class MapHousePanelSlotProbeTests
{
private const uint HostLayoutId = 0x2100006Eu;

View file

@ -19,6 +19,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class OptionsPanelLiveMountProbeTests
{
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbeLiveMountShapes()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
@ -314,6 +315,7 @@ public sealed class OptionsPanelLiveMountProbeTests
/// FIXED 6-row + scrollbar popup in retail, user-gated during the vendor
/// campaign) as the contrast control.</summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbeMenuPopupSizingAndTextStyle()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
@ -479,6 +481,7 @@ public sealed class OptionsPanelLiveMountProbeTests
/// to resolve in table 0x23000003 — sweep the plausible tables and key
/// spellings against the live DAT to find their real home.</summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbeFilterLabelHome()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")

View file

@ -18,6 +18,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class PowerbarLayoutProbeTests
{
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbePowerbarAuthoredStrings()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
@ -75,6 +76,7 @@ public sealed class PowerbarLayoutProbeTests
/// gmSecureTradeUI's element tree (lane A gave element ids 0x10000085-8B
/// but not the layout id) and dump it.</summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbeSecureTradeLayout()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
@ -107,6 +109,7 @@ public sealed class PowerbarLayoutProbeTests
/// ID_SecureTrade_TotalItemsLabel's fragments + variable hashes so the
/// count text can use ResolveTemplate if token-free (AD-95).</summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void ProbeTotalItemsTemplate()
{
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")

View file

@ -75,6 +75,7 @@ namespace AcDream.App.Tests.UI;
/// <c>States</c> dictionary was not walked) remain open.
/// </para>
/// </summary>
[Trait("Purpose", "Diagnostic")]
public sealed class SpewBoxLayoutDumpDiagnostic
{
private readonly ITestOutputHelper _out;

View file

@ -127,7 +127,8 @@ public sealed class EnvCellSoundEmitterInventoryTests
}
[Fact]
public void PortalDat_SetupsWithAmbientSlotSoundTables()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_PortalDat_SetupsWithAmbientSlotSoundTables()
{
string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null)
@ -184,7 +185,8 @@ public sealed class EnvCellSoundEmitterInventoryTests
}
[Fact]
public void SoundTables_WithAmbientSlots_ExistForWireBinding()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_SoundTables_WithAmbientSlots_ExistForWireBinding()
{
string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null)

View file

@ -21,6 +21,7 @@ public class CottageDoorwayCharacterizationTests
public CottageDoorwayCharacterizationTests(ITestOutputHelper output) => _out = output;
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Characterize_CottageNeighborhood_PrintStructure()
{
var datDir = ConformanceDats.ResolveDatDir();
@ -65,6 +66,7 @@ public class CottageDoorwayCharacterizationTests
public const uint OutdoorLandcell0031 = 0xA9B40031u;
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Characterize_Doorway_FindInteriorPoints()
{
var datDir = ConformanceDats.ResolveDatDir();

View file

@ -16,6 +16,7 @@ namespace AcDream.Core.Tests.Conformance;
/// landblock have a LandBlock (0xXXYYFFFF) terrain record at all, or only
/// LandBlockInfo + EnvCells? Output-only — no assertions.
/// </summary>
[Trait("Purpose", "Diagnostic")]
public sealed class DungeonLandblockDatProbeTests
{
private readonly ITestOutputHelper _out;

View file

@ -20,6 +20,7 @@ namespace AcDream.Core.Tests.Conformance;
/// these falloffs ARE what retail reads (modulo any load-time transform, settled
/// separately in the decomp). Output-only — no assertions; read the log.
/// </summary>
[Trait("Purpose", "Diagnostic")]
public sealed class HoltburgTorchFalloffProbeTests
{
private readonly ITestOutputHelper _out;

View file

@ -70,6 +70,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
/// vertical door-sized quads.
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void DumpHoltburgBuildings_OrphanGeometry()
{
var datDir = ConformanceDats.ResolveDatDir();
@ -191,7 +192,8 @@ public sealed class Issue113DoorVanishDiagnosticTests
/// must move.
/// </summary>
[Fact]
public void ReplicateProductionEmission_OnPortalFills()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_ReplicateProductionEmission_OnPortalFills()
{
var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; }
@ -237,6 +239,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
/// which is exactly why retail shows doors but not the ramp.
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void DumpPortalFillSurfaceTypes()
{
var datDir = ConformanceDats.ResolveDatDir();
@ -282,6 +285,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
/// the phantom geometry, for type-model comparison against the door.
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void DumpControls_HallAndCottage()
{
var datDir = ConformanceDats.ResolveDatDir();

View file

@ -287,6 +287,7 @@ public sealed class Issue113PhantomStairsDumpTests
/// sphere STRADDLES this plane (|dist| &lt; radius + 0.0002, pc:310090-310120).
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Dump_Cell104_ExteriorPortalPlane_Vs_GapPoint()
{
var datDir = ConformanceDats.ResolveDatDir();
@ -559,6 +560,7 @@ public sealed class Issue113PhantomStairsDumpTests
/// printed top→bottom DESCENDING (north up).
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void DumpAAB3_Watchtower_TopDownMap()
{
var datDir = ConformanceDats.ResolveDatDir();
@ -679,6 +681,7 @@ public sealed class Issue113PhantomStairsDumpTests
/// retail skips and our building-mesh extraction mishandles?
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void DumpHallModel_PolyFlagHistogram()
{
var datDir = ConformanceDats.ResolveDatDir();

View file

@ -13,6 +13,7 @@ namespace AcDream.Core.Tests.Conformance;
/// FindCellList result — so the P0→P1 divergence is precisely characterized
/// (real pick-criterion divergence vs a test/sphere artifact).
/// </summary>
[Trait("Purpose", "Diagnostic")]
public class ThresholdDivergenceDiagnosticTests
{
private readonly ITestOutputHelper _out;

View file

@ -129,6 +129,7 @@ public class CameraCornerSealReplayTests
/// shadow-query path is the half that failed).
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_DispatchTrace_LeakPath_vs_Controls()
{
var datDir = ConformanceDats.ResolveDatDir();

View file

@ -237,6 +237,7 @@ public class DoorSetupGfxObjInspectionTests
// computes a different outdoor cell than 0xA9B40029
// Findings drive the fix direction.
[Fact]
[Trait("Purpose", "Diagnostic")]
public void HoltburgCottage_CellPortals_DatInspection()
{
var datDir = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")
@ -271,6 +272,7 @@ public class DoorSetupGfxObjInspectionTests
/// building wall sub-piece) lives at that XY.
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void HoltburgLandblockStatics_DatInspection()
{
var datDir = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")

View file

@ -280,6 +280,7 @@ public class Issue137CorridorSeamInspectionTests
/// hit point + normal.
/// </summary>
[Fact]
[Trait("Purpose", "Diagnostic")]
public void CorridorSeam_FindPolygonMatchingLiveHit()
{
var datDir = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")

View file

@ -33,6 +33,7 @@ public class Issue186ConnectorCellGeometryInspectionTests
}
[Fact]
[Trait("Purpose", "Diagnostic")]
public void Dump_ConnectorCells_ShellAndCollision()
{
var datDir = DatDir();

View file

@ -25,6 +25,7 @@ namespace AcDream.Core.Tests.Physics;
/// wired). Kept as a reusable decoder for any future "why doesn't this
/// animate" question — swap the MotionTableId.
/// </summary>
[Trait("Purpose", "Diagnostic")]
public class Issue188FadingDoorMotionTableInspectionTests
{
private readonly ITestOutputHelper _out;

View file

@ -244,7 +244,8 @@ public class Issue176177DungeonSeamInspectionTests
/// light exposed it.
/// </summary>
[Fact]
public void CorridorNeighborhood_CoplanarOverlappingDrawnPolyPairs()
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_CorridorNeighborhood_CoplanarOverlappingDrawnPolyPairs()
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -470,7 +471,8 @@ public class Issue176177DungeonSeamInspectionTests
[InlineData(0x8A02016Eu)] // corridor cells — the striped-floor screenshot area
[InlineData(0x8A02017Au)]
[InlineData(0x8A020165u)]
public void UnderHall_DrawnPolys_SurfaceColors(uint cellId)
[Trait("Purpose", "Diagnostic")]
public void Diagnostic_UnderHall_DrawnPolys_SurfaceColors(uint cellId)
{
var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
@ -635,6 +637,7 @@ public class Issue176177DungeonSeamInspectionTests
[Theory]
[InlineData(0x8A02015Eu)] // #176 repro corridor
[InlineData(0x8A02016Eu)] // corridor with floor-portals
[Trait("Purpose", "Diagnostic")]
public void CellVertexNormals_SmoothOrFaceted_Dump(uint cellId)
{
var datDir = ResolveDatDir();

View file

@ -50,6 +50,7 @@ public class Issue93TownNetworkFountainRoomLightInspectionTests
[InlineData(0x00070146u)]
[InlineData(0x00070155u)]
[InlineData(0x00070157u)]
[Trait("Purpose", "Diagnostic")]
public void StaticObjects_SetupLightsCount_Dump(uint cellId)
{
var datDir = ResolveDatDir();