CultLib/tests/GameCult.Caching.Tests/AssemblyInfo.cs

44 lines
1.4 KiB
C#
Raw Normal View History

Generate derived documents' members and require [Key] on every one The generator walked only members declared on the document class and emitted a codec only when those were dense, so a derived document's generated descriptor hashed a different schema id and catalog than the reflective one. It now discovers members along the base-type chain the way CultDocumentRegistry reflects them (public instance fields and get/set properties, inherited included, [IgnoreMember] excluded), and density is over that full set: RoutingWeapon : RoutingGear gets a codec and the same SchemaId and catalog (Name@0, Damage@1) from both builds. Unkeyed members made the two orderings disagree (generator by name, registry by metadata token). Both implicit-slot paths are deleted: an unkeyed persisted member of a [CultDocument] type is generator error GCC001, and the registry throws the same message. The consumer audit found no unkeyed document with a persisted store. Tests: GeneratedAndReflectiveDescriptorsAgreeForDerivedDocuments failed on ea5a07b ("no generated codec for the derived document") and passes through UpsertWeaponThroughGearHandleReloadsAsWeapon; UnkeyedDocumentMemberIsRejected drives the generator through Roslyn and compares its diagnostic with the registry's exception. The registry's reflective BuildDescriptor is internal and visible to the tests for that comparison. The registry-collision fixture's emitted field gains its [Key]; schema-compatibility fixture ids are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 21:19:08 +02:00
#nullable enable
using GameCult.Caching.MessagePack;
using GameCult.Caching.Tests;
using MessagePack;
using MessagePack.Formatters;
[assembly: CultCacheFormatterResolver(typeof(PairResolver))]
namespace GameCult.Caching.Tests
{
public struct Pair
{
public float A;
public float B;
}
public sealed class PairResolver : IFormatterResolver
{
public static readonly IFormatterResolver Instance = new PairResolver();
public IMessagePackFormatter<T>? GetFormatter<T>()
{
return typeof(T) == typeof(Pair) ? (IMessagePackFormatter<T>)(object)PairFormatter.Instance : null;
}
private sealed class PairFormatter : IMessagePackFormatter<Pair>
{
public static readonly PairFormatter Instance = new();
public void Serialize(ref MessagePackWriter writer, Pair value, MessagePackSerializerOptions options)
{
writer.WriteArrayHeader(2);
writer.Write(value.A);
writer.Write(value.B);
}
public Pair Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
if (reader.ReadArrayHeader() != 2) throw new MessagePackSerializationException("Pair is a two-element array.");
return new Pair { A = reader.ReadSingle(), B = reader.ReadSingle() };
}
}
}
}