acdream/tests/AcDream.Core.Tests/Rendering/RenderingDiagnosticsTests.cs
Erik 687040ba52 feat(render-diag): add ACDREAM_PROBE_PORTAL_CHURN flag for the bounded-propagation pin
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:49:17 +02:00

142 lines
5.8 KiB
C#

using AcDream.Core.Rendering;
using Xunit;
namespace AcDream.Core.Tests.Rendering;
public sealed class RenderingDiagnosticsTests
{
// Each flag-mutating test snapshots the IndoorAll state on entry and
// restores it via try/finally. RenderingDiagnostics is a process-wide
// static (env-var-initialized); without restoration a mutated state
// leaks into other tests + into parallel test runs. Mirrors the
// PhysicsDiagnosticsTests pattern at line 30-49.
[Fact]
public void IndoorAll_True_TurnsAllFlagsOn()
{
bool initial = RenderingDiagnostics.IndoorAll;
try
{
// Reset all flags off first to make the test deterministic
// regardless of env-var state on the test runner.
RenderingDiagnostics.ProbeIndoorWalkEnabled = false;
RenderingDiagnostics.ProbeIndoorLookupEnabled = false;
RenderingDiagnostics.ProbeIndoorUploadEnabled = false;
RenderingDiagnostics.ProbeIndoorXformEnabled = false;
RenderingDiagnostics.ProbeIndoorCullEnabled = false;
RenderingDiagnostics.IndoorAll = true;
Assert.True(RenderingDiagnostics.ProbeIndoorWalkEnabled);
Assert.True(RenderingDiagnostics.ProbeIndoorLookupEnabled);
Assert.True(RenderingDiagnostics.ProbeIndoorUploadEnabled);
Assert.True(RenderingDiagnostics.ProbeIndoorXformEnabled);
Assert.True(RenderingDiagnostics.ProbeIndoorCullEnabled);
Assert.True(RenderingDiagnostics.IndoorAll);
}
finally
{
RenderingDiagnostics.IndoorAll = initial;
}
}
[Fact]
public void IndoorAll_False_TurnsAllFlagsOff()
{
bool initial = RenderingDiagnostics.IndoorAll;
try
{
RenderingDiagnostics.IndoorAll = true; // start from all-on
RenderingDiagnostics.IndoorAll = false;
Assert.False(RenderingDiagnostics.ProbeIndoorWalkEnabled);
Assert.False(RenderingDiagnostics.ProbeIndoorLookupEnabled);
Assert.False(RenderingDiagnostics.ProbeIndoorUploadEnabled);
Assert.False(RenderingDiagnostics.ProbeIndoorXformEnabled);
Assert.False(RenderingDiagnostics.ProbeIndoorCullEnabled);
Assert.False(RenderingDiagnostics.IndoorAll);
}
finally
{
RenderingDiagnostics.IndoorAll = initial;
}
}
[Fact]
public void IndoorAll_OneOff_ReadsAsFalse()
{
bool initial = RenderingDiagnostics.IndoorAll;
try
{
RenderingDiagnostics.IndoorAll = true;
RenderingDiagnostics.ProbeIndoorCullEnabled = false; // flip one off
Assert.False(RenderingDiagnostics.IndoorAll);
}
finally
{
RenderingDiagnostics.IndoorAll = initial;
}
}
[Theory]
[InlineData(0x00000029ul, false)] // outdoor cell 0x29 in 8x8 grid
[InlineData(0xA9B40029ul, false)] // outdoor cell with landblock prefix
[InlineData(0x00000100ul, true)] // indoor cell minimum
[InlineData(0x00000105ul, true)] // typical Holtburg Inn interior
[InlineData(0xA9B40105ul, true)] // indoor with landblock prefix
[InlineData(0xA9B401FFul, true)] // indoor near top of range
public void IsEnvCellId_DistinguishesOutdoorVsIndoorByLow16Bits(ulong id, bool expected)
{
Assert.Equal(expected, RenderingDiagnostics.IsEnvCellId(id));
}
// ── Render inside/outside branch (retail RenderNormalMode is_player_outside) ──
// The top-level render branch decides DrawInside vs DrawOutside. Retail
// (SmartBox::RenderNormalMode 0x453aa0:92665) keys it on is_player_outside (the
// PLAYER's cell, 0x451e80), NOT the camera cell. acdream previously branched on the
// camera cell, so a chase camera lagging in a doorway while the player was already
// outside took the DrawInside path and degenerated to a grey world + entities showing
// through walls. These pin the player-keyed branch and loaded player-root requirement.
[Fact]
public void ShouldRenderIndoor_PlayerOutside_CameraInside_ReturnsFalse()
{
// THE doorway-grey regression: the player stepped onto a landcell (0x...0031) but the
// chase camera still resolves an interior EnvCell. Branch on the PLAYER → outdoor.
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40031u, renderRootResolved: true));
}
[Fact]
public void ShouldRenderIndoor_PlayerInside_CameraInside_ReturnsTrue()
{
Assert.True(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40171u, renderRootResolved: true));
}
[Fact]
public void ShouldRenderIndoor_PlayerInside_RootNotLoaded_ReturnsFalse()
{
// Opposite lag (camera pulled outside while the player is inside): no viewer cell to
// root DrawInside at → outdoor. Defensive; matches prior null-CameraCell behavior.
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40171u, renderRootResolved: false));
}
[Fact]
public void ShouldRenderIndoor_PlayerOutside_CameraOutside_ReturnsFalse()
{
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40031u, renderRootResolved: false));
}
[Fact]
public void ShouldRenderIndoor_UnknownPlayerCell_TreatedAsOutside_ReturnsFalse()
{
// playerCellId == 0 (unresolved) → treat as outside (safe default: outdoor render).
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0u, renderRootResolved: true));
}
[Fact]
public void ProbePortalChurn_DefaultsFalse_WhenEnvUnset()
{
// Env var is absent in the test host, so the flag must default false (inert probe).
Assert.False(AcDream.Core.Rendering.RenderingDiagnostics.ProbePortalChurnEnabled);
}
}