AyCode.Core/AyCode.Core.Tests/Serialization/AcBinarySerializerSGenNullC...

207 lines
8.4 KiB
C#

using AyCode.Core.Serializers.Binaries;
using AyCode.Core.Tests.TestModels;
namespace AyCode.Core.Tests.Serialization;
[TestClass]
public class AcBinarySerializerSGenNullComplexPropertyTests
{
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenComplexPropertyNull_DoesNotThrow_AndRoundTripsAsNull(bool useSgen, bool fastMode)
{
var model = new SGenNullComplexParent
{
Id = 7,
Customer = null!,
Note = "regression"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullComplexParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNull(roundTrip.Customer,
"complex reference property must round-trip as null when source was null " +
"(regression for SGen WriteObjectGenerated fallback else-branch null-check)");
Assert.IsTrue(System.Array.IndexOf(bytes, (byte)BinaryTypeCode.PropertySkip) >= 0,
"writer must emit PropertySkip marker on the null Customer slot " +
"(deeper verification: confirms the fix took the PropertySkip path, " +
"not an unrelated null-safe code path)");
}
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenComplexPropertyNonNull_RoundTripsCorrectly(bool useSgen, bool fastMode)
{
var model = new SGenNullComplexParent
{
Id = 13,
Customer = new NonGeneratedComplexCustomer { Id = 42, Name = "child" },
Note = "positive"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullComplexParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNotNull(roundTrip.Customer,
"non-null complex reference property must round-trip (null-check fix must not break the non-null path)");
Assert.AreEqual(model.Customer.Id, roundTrip.Customer.Id);
Assert.AreEqual(model.Customer.Name, roundTrip.Customer.Name);
}
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenCollectionPropertyNull_DoesNotThrow_AndRoundTripsAsNull(bool useSgen, bool fastMode)
{
var model = new SGenNullCollectionParent
{
Id = 11,
Items = null!,
Note = "regression-collection"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullCollectionParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNull(roundTrip.Items,
"collection property (with non-SGen element type) must round-trip as null when source was null " +
"(regression for SGen Collection fallback WriteValueGenerated else-branch null-check)");
Assert.IsTrue(System.Array.IndexOf(bytes, (byte)BinaryTypeCode.PropertySkip) >= 0,
"writer must emit PropertySkip marker on the null Items slot " +
"(confirms the fix took the PropertySkip path, not an unrelated null-safe code path)");
}
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenCollectionPropertyNonNull_RoundTripsCorrectly(bool useSgen, bool fastMode)
{
var model = new SGenNullCollectionParent
{
Id = 17,
Items = new List<NonGeneratedComplexCustomer>
{
new() { Id = 1, Name = "first" },
new() { Id = 2, Name = "second" }
},
Note = "positive-collection"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullCollectionParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNotNull(roundTrip.Items,
"non-null collection property must round-trip (null-check fix must not break the non-null path)");
Assert.AreEqual(model.Items.Count, roundTrip.Items.Count);
Assert.AreEqual(model.Items[0].Id, roundTrip.Items[0].Id);
Assert.AreEqual(model.Items[0].Name, roundTrip.Items[0].Name);
Assert.AreEqual(model.Items[1].Id, roundTrip.Items[1].Id);
Assert.AreEqual(model.Items[1].Name, roundTrip.Items[1].Name);
}
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenDictionaryPropertyNull_DoesNotThrow_AndRoundTripsAsNull(bool useSgen, bool fastMode)
{
var model = new SGenNullDictionaryParent
{
Id = 23,
Mapping = null!,
Note = "regression-dictionary"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullDictionaryParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNull(roundTrip.Mapping,
"dictionary property must round-trip as null when source was null " +
"(pins EmitDirectDictionaryWrite line ~1037 null-check against future regression)");
Assert.IsTrue(System.Array.IndexOf(bytes, (byte)BinaryTypeCode.PropertySkip) >= 0,
"writer must emit PropertySkip marker on the null Mapping slot " +
"(confirms the PropertySkip path, not an unrelated null-safe code path)");
}
[TestMethod]
[DataRow(true, true)]
[DataRow(true, false)]
[DataRow(false, false)]
[DataRow(false, true)]
public void Serialize_SGenDictionaryPropertyNonNull_RoundTripsCorrectly(bool useSgen, bool fastMode)
{
var model = new SGenNullDictionaryParent
{
Id = 29,
Mapping = new Dictionary<string, NonGeneratedComplexCustomer>
{
["alpha"] = new() { Id = 1, Name = "first" },
["beta"] = new() { Id = 2, Name = "second" }
},
Note = "positive-dictionary"
};
var options = fastMode ? AcBinarySerializerOptions.FastMode: AcBinarySerializerOptions.Default;
options.UseGeneratedCode = useSgen;
var bytes = AcBinarySerializer.Serialize(model, options);
var roundTrip = AcBinaryDeserializer.Deserialize<SGenNullDictionaryParent>(bytes, options);
Assert.IsNotNull(roundTrip);
Assert.AreEqual(model.Id, roundTrip.Id);
Assert.AreEqual(model.Note, roundTrip.Note);
Assert.IsNotNull(roundTrip.Mapping,
"non-null dictionary property must round-trip (null-check pin must not break the non-null path)");
Assert.AreEqual(model.Mapping.Count, roundTrip.Mapping.Count);
Assert.AreEqual(model.Mapping["alpha"].Id, roundTrip.Mapping["alpha"].Id);
Assert.AreEqual(model.Mapping["alpha"].Name, roundTrip.Mapping["alpha"].Name);
Assert.AreEqual(model.Mapping["beta"].Id, roundTrip.Mapping["beta"].Id);
Assert.AreEqual(model.Mapping["beta"].Name, roundTrip.Mapping["beta"].Name);
}
}