test(render): Phase A8.F — RetailChaseCamera test hygiene (try/finally reset; fade-on-pull-in)

Code-review follow-ups for Task 3: wrap the flag-off test's CollideCamera reset
in try/finally so an assert failure can't poison downstream tests; add
Update_ProbePullsEyeInClose_FullyFadesPlayer covering retail stage-3 (collided
eye 0.1 m from pivot → PlayerTranslucency 1); tighten probe.Calls assertion to ==1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-29 19:26:51 +02:00
parent 319277a27b
commit 45a4218fab

View file

@ -472,7 +472,7 @@ public class RetailChaseCameraTests
isOnGround: true, contactPlaneNormal: Vector3.UnitZ, dt: 1f / 60f,
cellId: 0x100, selfEntityId: 0x5);
Assert.True(probe.Calls >= 1);
Assert.Equal(1, probe.Calls);
Assert.Equal(collided, cam.Position);
}
@ -480,18 +480,23 @@ public class RetailChaseCameraTests
public void Update_FlagOff_DoesNotConsultProbe()
{
CameraDiagnostics.CollideCamera = false;
var probe = new FakeProbe { ReturnEye = new Vector3(99f, 99f, 99f) };
var cam = new RetailChaseCamera { CollisionProbe = probe };
try
{
var probe = new FakeProbe { ReturnEye = new Vector3(99f, 99f, 99f) };
var cam = new RetailChaseCamera { CollisionProbe = probe };
cam.Update(
playerPosition: Vector3.Zero, playerYaw: 0f, playerVelocity: Vector3.Zero,
isOnGround: true, contactPlaneNormal: Vector3.UnitZ, dt: 1f / 60f,
cellId: 0x100, selfEntityId: 0x5);
cam.Update(
playerPosition: Vector3.Zero, playerYaw: 0f, playerVelocity: Vector3.Zero,
isOnGround: true, contactPlaneNormal: Vector3.UnitZ, dt: 1f / 60f,
cellId: 0x100, selfEntityId: 0x5);
Assert.Equal(0, probe.Calls);
Assert.NotEqual(new Vector3(99f, 99f, 99f), cam.Position);
CameraDiagnostics.CollideCamera = true; // reset
Assert.Equal(0, probe.Calls);
Assert.NotEqual(new Vector3(99f, 99f, 99f), cam.Position);
}
finally
{
CameraDiagnostics.CollideCamera = true; // reset even if an assert throws
}
}
[Fact]
@ -507,4 +512,23 @@ public class RetailChaseCameraTests
Assert.NotEqual(default, cam.View);
}
[Fact]
public void Update_ProbePullsEyeInClose_FullyFadesPlayer()
{
// Spec §9 / retail stage 3: when the collided eye ends up very close to
// the head-pivot, the player mesh fades. Pivot = (0,0,1.5); a collided
// eye 0.1 m above it (≤ the 0.20 m full-fade threshold) → translucency 1.
CameraDiagnostics.CollideCamera = true;
var pulledIn = new Vector3(0f, 0f, 1.6f);
var cam = new RetailChaseCamera { CollisionProbe = new FakeProbe { ReturnEye = pulledIn } };
cam.Update(
playerPosition: Vector3.Zero, playerYaw: 0f, playerVelocity: Vector3.Zero,
isOnGround: true, contactPlaneNormal: Vector3.UnitZ, dt: 1f / 60f,
cellId: 0x100, selfEntityId: 0x5);
Assert.Equal(pulledIn, cam.Position);
Assert.Equal(1f, cam.PlayerTranslucency, 3);
}
}