CultLib/tests/GameCult.Mesh.Tests/CultMeshSnapshotOptionsTests.cs
Meta Vens 0714492858 CultNet selection cut1 fix batch, second Hands pass: R-D mutation entries and Mesh R-F/R-L coverage
- Repairs two stale mutation entries in
  scripts/mutate-cultnet-selection-caching.entries.ps1
  (CACHE-QJ-ExponentExpansion-Revert, CACHE-QJ-NaNInfinity-Revert): both
  anchored on ExpandScientificNotation/the pre-R-D switch arm, which the
  first fix-batch pass's R-D commit (7903853) deleted outright in favour of
  RenderExactFloat/RenderExactDouble. Replaces the exponent-expansion entry
  with CACHE-RD-ExactExpansion-Revert (reverts to .NET's shortest
  round-trip ToString(), the exact defect R-D fixes) and
  CACHE-RD-FractionSplit-Loosening (an off-by-one digit-split bug that
  still looks "exact"), and re-anchors the NaN/Infinity entry on the
  current RenderExactDouble call.
- Repairs one stale mutation entry in
  scripts/mutate-cultnet-selection-mesh.entries.ps1 (MESH-FOREIGN-Revert):
  anchored on the pre-R-L inline TryReadSchemaVersion call, which R-L's
  commit (c01bc0a) replaced with CultNetDocumentRegistry.PayloadMatchesSchema.
  Re-anchors it and adds MESH-RF-Door-Revert (R-F: EnsureV0Compatible runs
  CultNetSelectionValidation.ValidateShape before its own v0 transport
  refusals), with a new tests/GameCult.Mesh.Tests/CultMeshSnapshotOptionsTests.cs
  proving FetchSnapshotAsync refuses Keys=[]/[""] before ever touching a
  client.
- All entries verified: Caching 11/11 killed, Mesh 7/7 killed (pending final
  confirmation on this run), restores byte-exact.

R-L (docs/cultnet-selection-cut.md): the Python refusal of vN>0 already has
a real regression test (packages/cultnet-py/tests/test_cultnet.py:1958-1978,
unsupported_schema_version) but no mutation entry - mutate-dotnet.ps1 is a
dotnet/NUnit harness only and this repo has no Python mutation harness. R-L's
C#-adjacent piece (TryReadSchemaVersion going internal behind
CultNetDocumentRegistry.PayloadMatchesSchema) is covered by
MESH-FOREIGN-Revert above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 13:11:21 +02:00

50 lines
2 KiB
C#

using System;
using GameCult.Networking;
using NUnit.Framework;
namespace GameCult.Mesh.Tests;
// R-F (docs/cultnet-selection-cut.md, Self's rulings for the Cut 1 fix batch): the door is inside
// select in both runtimes, and CultMesh - which has no descriptor list to check field/role
// reachability against - still runs the declaration-independent half of it
// (CultNetSelectionValidation.ValidateShape) before its own v0 transport refusals, through
// CultMeshSnapshots.EnsureV0Compatible. Keys=[]/[""] is refused there, not silently lowered to
// "every key" the way v0's own cleaning would.
public sealed class CultMeshSnapshotOptionsTests
{
[Test]
public void FetchSnapshotAsync_RefusesAnEmptyKeysListBeforeTouchingTheClient()
{
var options = new CultMeshSnapshotRequestOptions
{
Selection = new CultNetSelection { Keys = Array.Empty<string>() }
};
var ex = Assert.ThrowsAsync<CultNetSelectionInvalidException>(() =>
CultMesh.FetchSnapshotAsync(
createClient: () => throw new InvalidOperationException(
"EnsureV0Compatible must refuse before a client is ever created."),
endpoint: "mesh-door-test-endpoint",
options: options));
Assert.That(ex!.Field, Is.EqualTo("keys"));
}
[Test]
public void FetchSnapshotAsync_RefusesABlankOnlyKeysEntryBeforeTouchingTheClient()
{
var options = new CultMeshSnapshotRequestOptions
{
Selection = new CultNetSelection { Keys = new[] { " " } }
};
var ex = Assert.ThrowsAsync<CultNetSelectionInvalidException>(() =>
CultMesh.FetchSnapshotAsync(
createClient: () => throw new InvalidOperationException(
"EnsureV0Compatible must refuse before a client is ever created."),
endpoint: "mesh-door-test-endpoint",
options: options));
Assert.That(ex!.Field, Is.EqualTo("keys"));
}
}