using AyCode.Core.Extensions; using AyCode.Core.Serializers.Binaries; using AyCode.Core.Tests.TestModels; using static AyCode.Core.Tests.TestModels.AcSerializerModels; namespace AyCode.Core.Tests.Serialization; /// /// Tests for Binary Chain API (CreateDeserializeChain and CreatePopulateChain). /// [TestClass] public class AcBinarySerializerChainTests { [TestMethod] public void DeserializeChain_SingleDeserialization_WorksCorrectly() { // Arrange var original = new TestSimpleClass { Id = 42, Name = "John", Value = 3.14, IsActive = true }; var binary = original.ToBinary(); // Act using var chain = binary.BinaryToChain(); var result = chain.Value; // Assert Assert.IsNotNull(result); Assert.AreEqual(42, result.Id); Assert.AreEqual("John", result.Name); Assert.AreEqual(3.14, result.Value); Assert.AreEqual(true, result.IsActive); } [TestMethod] public void DeserializeChain_MultipleDeserializations_ParsesOnlyOnce() { // Arrange var original = new TestSimpleClass { Id = 100, Name = "Test", Value = 99.9, IsActive = false }; var binary = original.ToBinary(); // Act using var chain = binary.BinaryToChain(); var result1 = chain.Value; var result2 = chain.ThenDeserialize(); var result3 = chain.ThenDeserialize(); // Assert - All three deserializations should work Assert.IsNotNull(result1); Assert.AreEqual(100, result1.Id); Assert.IsNotNull(result2); Assert.AreEqual(100, result2.Id); Assert.AreEqual("Test", result2.Name); Assert.IsNotNull(result3); Assert.AreEqual(99.9, result3.Value); Assert.AreEqual(false, result3.IsActive); } [TestMethod] public void DeserializeChain_NestedObjects_WorksCorrectly() { // Arrange var original = new TestNestedClass { Id = 1, Name = "Parent", Child = new TestSimpleClass { Id = 2, Name = "Child", Value = 10.5 } }; var binary = original.ToBinary(); // Act using var chain = binary.BinaryToChain(); var result1 = chain.Value; var result2 = chain.ThenDeserialize(); // Assert Assert.IsNotNull(result1); Assert.AreEqual("Parent", result1.Name); Assert.IsNotNull(result1.Child); Assert.AreEqual("Child", result1.Child.Name); Assert.IsNotNull(result2); Assert.AreEqual(1, result2.Id); Assert.IsNotNull(result2.Child); Assert.AreEqual(10.5, result2.Child.Value); } [TestMethod] public void DeserializeChain_WithList_WorksCorrectly() { // Arrange var original = new TestClassWithList { Id = 5, Items = new List { "Apple", "Banana", "Cherry" } }; var binary = original.ToBinary(); // Act using var chain = binary.BinaryToChain(); var result = chain.Value; // Assert Assert.IsNotNull(result); Assert.AreEqual(5, result.Id); Assert.AreEqual(3, result.Items.Count); Assert.AreEqual("Apple", result.Items[0]); Assert.AreEqual("Banana", result.Items[1]); Assert.AreEqual("Cherry", result.Items[2]); } [TestMethod] public void PopulateChain_SinglePopulate_UpdatesObject() { // Arrange var original = new TestSimpleClass { Id = 99, Name = "Updated", Value = 123.45, IsActive = true }; var binary = original.ToBinary(); var target = new TestSimpleClass { Id = 1, Name = "Old", Value = 0, IsActive = false }; // Act using var chain = binary.BinaryToChain(target); // Assert Assert.AreEqual(99, target.Id); Assert.AreEqual("Updated", target.Name); Assert.AreEqual(123.45, target.Value); Assert.AreEqual(true, target.IsActive); } [TestMethod] public void PopulateChain_MultiplePopulates_UpdatesAllObjects() { // Arrange var original = new TestSimpleClass { Id = 100, Name = "Shared", Value = 50.0 }; var binary = original.ToBinary(); var target1 = new TestSimpleClass { Id = 1, Name = "Old1" }; var target2 = new TestSimpleClass { Id = 2, Name = "Old2" }; var target3 = new TestSimpleClass { Id = 3, Name = "Old3" }; // Act using var chain = binary.BinaryToChain(target1); chain.ThenPopulate(target2); chain.ThenPopulate(target3); // Assert Assert.AreEqual(100, target1.Id); Assert.AreEqual("Shared", target1.Name); Assert.AreEqual(50.0, target1.Value); Assert.AreEqual(100, target2.Id); Assert.AreEqual("Shared", target2.Name); Assert.AreEqual(50.0, target2.Value); Assert.AreEqual(100, target3.Id); Assert.AreEqual("Shared", target3.Name); Assert.AreEqual(50.0, target3.Value); } [TestMethod] public void PopulateChain_NestedObjects_MergesCorrectly() { // Arrange var original = new TestNestedClass { Id = 10, Name = "UpdatedParent", Child = new TestSimpleClass { Id = 20, Name = "UpdatedChild", Value = 99.9 } }; var binary = original.ToBinary(); var target = new TestNestedClass { Id = 1, Name = "OldParent", Child = new TestSimpleClass { Id = 2, Name = "OldChild", Value = 1.0 } }; // Act using var chain = binary.BinaryToChain(target); // Assert Assert.AreEqual(10, target.Id); Assert.AreEqual("UpdatedParent", target.Name); Assert.IsNotNull(target.Child); Assert.AreEqual(20, target.Child.Id); Assert.AreEqual("UpdatedChild", target.Child.Name); Assert.AreEqual(99.9, target.Child.Value); } [TestMethod] public void PopulateChain_WithList_UpdatesCollection() { // Arrange var original = new TestClassWithList { Id = 7, Items = new List { "New1", "New2", "New3" } }; var binary = original.ToBinary(); var target = new TestClassWithList { Id = 1, Items = new List { "Old1" } }; // Act using var chain = binary.BinaryToChain(target); // Assert Assert.AreEqual(7, target.Id); Assert.AreEqual(3, target.Items.Count); Assert.AreEqual("New1", target.Items[0]); Assert.AreEqual("New2", target.Items[1]); Assert.AreEqual("New3", target.Items[2]); } [TestMethod] public void DeserializeChain_EmptyBinary_ReturnsEmpty() { // Arrange var binary = Array.Empty(); // Act using var chain = binary.BinaryToChain(); // Assert Assert.IsNull(chain.Value); } [TestMethod] public void PopulateChain_EmptyBinary_DoesNothing() { // Arrange var binary = Array.Empty(); var target = new TestSimpleClass { Id = 42, Name = "Original" }; // Act using var chain = binary.BinaryToChain(target); // Assert - Should remain unchanged Assert.AreEqual(42, target.Id); Assert.AreEqual("Original", target.Name); } [TestMethod] public void DeserializeChain_Dispose_CannotReuseAfterDispose() { // Arrange var original = new TestSimpleClass { Id = 1, Name = "Test" }; var binary = original.ToBinary(); var chain = binary.BinaryToChain(); var value = chain.Value; // Act chain.Dispose(); // Assert Assert.IsNotNull(value); // Value from before dispose should still exist _ = Assert.ThrowsExactly(() => chain.ThenDeserialize()); } [TestMethod] public void PopulateChain_Dispose_CannotReuseAfterDispose() { // Arrange var original = new TestSimpleClass { Id = 1, Name = "Test" }; var binary = original.ToBinary(); var target1 = new TestSimpleClass(); var chain = binary.BinaryToChain(target1); // Act chain.Dispose(); // Assert var target2 = new TestSimpleClass(); _ = Assert.ThrowsExactly(() => chain.ThenPopulate(target2)); } [TestMethod] public void DeserializeChain_WithOptions_UsesCorrectOptions() { // Arrange var original = new TestSimpleClass { Id = 1, Name = "Test", Value = 10.5 }; var binary = original.ToBinary(); var options = new AcBinarySerializerOptions(); // Act using var chain = binary.BinaryToChain(options); var result = chain.Value; // Assert Assert.IsNotNull(result); Assert.AreEqual(1, result.Id); Assert.AreEqual("Test", result.Name); } [TestMethod] public void PopulateChain_WithOptions_UsesCorrectOptions() { // Arrange var original = new TestSimpleClass { Id = 99, Name = "Updated" }; var binary = original.ToBinary(); var target = new TestSimpleClass { Id = 1, Name = "Old" }; var options = new AcBinarySerializerOptions(); // Act using var chain = binary.BinaryToChain(target, options); // Assert Assert.AreEqual(99, target.Id); Assert.AreEqual("Updated", target.Name); } [TestMethod] public void DeserializeChain_ReadOnlyMemory_WorksCorrectly() { // Arrange var original = new TestSimpleClass { Id = 42, Name = "Memory Test" }; var binary = original.ToBinary(); ReadOnlyMemory memory = binary; // Act using var chain = memory.BinaryToChain(); var result = chain.Value; // Assert Assert.IsNotNull(result); Assert.AreEqual(42, result.Id); Assert.AreEqual("Memory Test", result.Name); } [TestMethod] public void PopulateChain_ReadOnlyMemory_WorksCorrectly() { // Arrange var original = new TestSimpleClass { Id = 99, Name = "Memory Update" }; var binary = original.ToBinary(); ReadOnlyMemory memory = binary; var target = new TestSimpleClass { Id = 1, Name = "Old" }; // Act using var chain = memory.BinaryToChain(target); // Assert Assert.AreEqual(99, target.Id); Assert.AreEqual("Memory Update", target.Name); } }