- 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>
50 lines
2 KiB
C#
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"));
|
|
}
|
|
}
|