Tests: the Mesh test's unmarked file holds ids of a type defined in the Mesh assembly (a persisted layout is matched by CLR type name); the appended python record brings its catalog entry beside the cache's
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a1c887cde7
commit
bd3477450e
2 changed files with 40 additions and 44 deletions
|
|
@ -154,7 +154,7 @@ namespace GameCult.Caching.Tests
|
|||
var py = pySnapshot.Records.Single(record => record.Key == "py");
|
||||
change?.Invoke(py);
|
||||
snapshot.Records = snapshot.Records.Concat(new[] { py }).ToArray();
|
||||
snapshot.SchemaCatalog = pySnapshot.SchemaCatalog;
|
||||
snapshot.SchemaCatalog = snapshot.SchemaCatalog.Concat(pySnapshot.SchemaCatalog).GroupBy(entry => entry.SchemaId).Select(group => group.First()).ToArray();
|
||||
File.WriteAllBytes(path, CultDocumentMessagePackSerialization.SerializeSnapshot(snapshot));
|
||||
Assert.That(HeaderOf(path), Is.EqualTo(CultPersistedStoreSnapshot.FormatV1), "the foreign writer keeps the v1 it found");
|
||||
return opened;
|
||||
|
|
|
|||
|
|
@ -173,45 +173,41 @@ public sealed class CultMeshSingleFileElementIdTests
|
|||
cache.Get<CultMeshBodyPublicationDocument>(Key)!.Representations.Select(entry => entry.Id).Should().Equal(first);
|
||||
}
|
||||
|
||||
// cultcache-py's record (tests/vectors/numeric-leaves/py-store/leaf-record.cc): v1 header, 12-hex element ids on its list.
|
||||
// This assembly declares the same document, member for member, so its registry claims and reads the python record.
|
||||
[CultDocument("cultcache.leaf-record", "cultcache.leaf_record.v1")]
|
||||
// A list document defined in this assembly: the record another writer leaves holding ids under an unmarked header.
|
||||
[CultDocument("mesh.test.id_list", "mesh.test.id_list.v1")]
|
||||
[MessagePackObject]
|
||||
public sealed class MeshLeaf
|
||||
public sealed class MeshIdList
|
||||
{
|
||||
[Key(0)] [CultName] public string Id = string.Empty;
|
||||
[Key(1)] public bool Flag;
|
||||
[Key(2)] public byte[] Blob = Array.Empty<byte>();
|
||||
[Key(3)] public int I;
|
||||
[Key(4)] public long L;
|
||||
[Key(5)] public float F;
|
||||
[Key(6)] public double D;
|
||||
[Key(7)] public int? MaybeI;
|
||||
[Key(8)] public List<string> Tags = new();
|
||||
[Key(9)] public string[] Names = Array.Empty<string>();
|
||||
[Key(10)] public object? Any;
|
||||
[Key(11)] public MeshLeafInner? Nested;
|
||||
[Key(12)] public List<MeshLeafInner> Items = new();
|
||||
[Key(13)] public IMeshLeafShape? Shape;
|
||||
[Key(14)] public float[] Floats = Array.Empty<float>();
|
||||
[Key(15)] public float? MaybeF;
|
||||
[Key(0)] [CultName] public string Name { get; set; } = "";
|
||||
[Key(1)] public List<MeshIdItem> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public sealed class MeshLeafInner
|
||||
public sealed class MeshIdItem
|
||||
{
|
||||
[Key(0)] public string N = string.Empty;
|
||||
[Key(1)] public float W;
|
||||
[Key(2)] [CultElementId] public string Id = string.Empty;
|
||||
[Key(0)] public string N { get; set; } = "";
|
||||
[Key(1)] [CultElementId] public string Id { get; set; } = "";
|
||||
}
|
||||
|
||||
[Union(0, typeof(MeshLeafCircle))]
|
||||
public interface IMeshLeafShape { }
|
||||
private static readonly CultRecordKey IdsKey = new("ids");
|
||||
private const string HexB = "bbbbbbbbbbbb";
|
||||
|
||||
[MessagePackObject]
|
||||
public sealed class MeshLeafCircle : IMeshLeafShape { [Key(0)] public float R; }
|
||||
|
||||
private static readonly string[] PythonIds = { "000000000021", "000000000022" };
|
||||
// A v1 file whose record holds 12-hex element ids: the document is written with the type (v3), then the header is put back
|
||||
// to the v1 a writer that does not decide would have left.
|
||||
private string UnmarkedStoreHoldingIds()
|
||||
{
|
||||
var path = Path_("unmarked.cc");
|
||||
CultMesh.WriteSingleFileDocument(
|
||||
path,
|
||||
IdsKey,
|
||||
new MeshIdList { Name = "ids", Items = { new MeshIdItem { Id = HexA }, new MeshIdItem { Id = HexB } } },
|
||||
registry: Registry(typeof(MeshIdList)));
|
||||
var snapshot = CultDocumentMessagePackSerialization.DeserializeSnapshot(File.ReadAllBytes(path));
|
||||
snapshot.FormatVersion = CultPersistedStoreSnapshot.FormatV1;
|
||||
File.WriteAllBytes(path, CultDocumentMessagePackSerialization.SerializeSnapshot(snapshot));
|
||||
HeaderOf(path).Should().Be("cultcache.store.v1");
|
||||
return path;
|
||||
}
|
||||
|
||||
private string PythonStore()
|
||||
{
|
||||
|
|
@ -234,14 +230,25 @@ public sealed class CultMeshSingleFileElementIdTests
|
|||
// A CultMesh write is a writer with a type: it decides for the copied record from the bytes the file holds, whatever any
|
||||
// earlier read saw (a fresh store per call has read nothing).
|
||||
[Test]
|
||||
public void ACultMeshWriteThatCopiesAPythonRecordHoldingIdsMarksTheStore()
|
||||
public void ACultMeshWriteThatCopiesARecordHoldingIdsMarksTheStore()
|
||||
{
|
||||
var path = PythonStore();
|
||||
var path = UnmarkedStoreHoldingIds();
|
||||
|
||||
CultMesh.WriteSingleFileDocument(path, Key, Publication(), registry: Registry(typeof(MeshLeaf), typeof(CultMeshBodyPublicationDocument)));
|
||||
CultMesh.WriteSingleFileDocument(path, Key, Publication(), registry: Registry(typeof(MeshIdList), typeof(CultMeshBodyPublicationDocument)));
|
||||
|
||||
HeaderOf(path).Should().Be("cultcache.store.v3");
|
||||
CultMesh.ReadSingleFileDocument<MeshLeaf>(path, new CultRecordKey("py")).Items.Select(item => item.Id).Should().Equal(PythonIds);
|
||||
CultMesh.ReadSingleFileDocument<MeshIdList>(path, IdsKey, Registry(typeof(MeshIdList))).Items.Select(item => item.Id).Should().Equal(HexA, HexB);
|
||||
}
|
||||
|
||||
// A raw payload is opaque by design: it attaches no registry and decides nothing, even beside a record it could have read.
|
||||
[Test]
|
||||
public void ARawCultMeshWriteBesideARecordHoldingIdsLeavesTheHeaderAlone()
|
||||
{
|
||||
var path = UnmarkedStoreHoldingIds();
|
||||
|
||||
CultMesh.WriteSingleFileDocumentPayload(path, RawKey, new CultMeshSingleFileDocumentSchema("raw:schema", "RawSchema", "1"), null, new byte[] { 0x90 });
|
||||
|
||||
HeaderOf(path).Should().Be("cultcache.store.v1");
|
||||
}
|
||||
|
||||
// Soul s1 P8, committed: the writer's registry has only the type it writes, so the python record is foreign to it and it
|
||||
|
|
@ -256,18 +263,7 @@ public sealed class CultMeshSingleFileElementIdTests
|
|||
HeaderOf(path).Should().Be("cultcache.store.v1");
|
||||
}
|
||||
|
||||
// A raw payload is opaque by design: it attaches no registry and decides nothing, even beside a record it could have read.
|
||||
[Test]
|
||||
public void ARawCultMeshWriteBesideAPythonRecordHoldingIdsLeavesTheHeaderAlone()
|
||||
{
|
||||
var path = PythonStore();
|
||||
|
||||
CultMesh.WriteSingleFileDocumentPayload(path, RawKey, new CultMeshSingleFileDocumentSchema("raw:schema", "RawSchema", "1"), null, new byte[] { 0x90 });
|
||||
|
||||
HeaderOf(path).Should().Be("cultcache.store.v1");
|
||||
}
|
||||
|
||||
// The check only marks: a typed write over a store already marked does not look at, and cannot drop, the mark.
|
||||
// Typed writes beside records that hold no id leave the store unmarked: the check marks only on an id it found.
|
||||
[Test]
|
||||
public void ATypedWriteBesideARecordThatHoldsNoIdKeepsTheStoreUnmarked()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue