From 93eca09dc19e8676c0df5fb804b5809ebc37f3cf Mon Sep 17 00:00:00 2001 From: Ogoun Date: Sat, 22 Jul 2023 18:15:27 +0300 Subject: [PATCH] Tests --- TestApp/Program.cs | 45 +- ZeroLevel.UnitTests/AsyncSerializationTest.cs | 430 ++++++++++++++++++ ZeroLevel.UnitTests/SerializationTests.cs | 9 +- .../Serialization/MemoryStreamWriter.cs | 22 +- ZeroLevel/ZeroLevel.csproj | 6 +- 5 files changed, 455 insertions(+), 57 deletions(-) create mode 100644 ZeroLevel.UnitTests/AsyncSerializationTest.cs diff --git a/TestApp/Program.cs b/TestApp/Program.cs index 2205568..89f88dc 100644 --- a/TestApp/Program.cs +++ b/TestApp/Program.cs @@ -54,53 +54,10 @@ namespace TestApp internal static class Program { - private class LogQueueWrapper - { - private string TakeMethod; - private string PushMethod; - private object Target; - public IInvokeWrapper Invoker; - - public LogMessage Take() - { - return (LogMessage)Invoker.Invoke(Target, TakeMethod); - } - - public void Push(LogLevel level, LogMessage value) - { - Invoker.Invoke(Target, PushMethod, new object[] { level, value }); - } - - public static LogQueueWrapper Create(object target) - { - var wrapper = new LogQueueWrapper { Invoker = InvokeWrapper.Create(), Target = target }; - wrapper.PushMethod = wrapper.Invoker.ConfigureGeneric(typeof(T), "Push").First(); - wrapper.TakeMethod = wrapper.Invoker.ConfigureGeneric(typeof(T), "Take").First(); - return wrapper; - } - } - - private static Func CreateArrayPredicate() - { - var typeArg = typeof(T).GetElementType(); - return mi => mi.Name.Equals("WriteArray", StringComparison.Ordinal) && - mi.GetParameters().First().ParameterType.GetElementType().IsAssignableFrom(typeArg); - } - - private static Func CreateCollectionPredicate() - { - var typeArg = typeof(T).GetGenericArguments().First(); - return mi => mi.Name.Equals("WriteCollection", StringComparison.Ordinal) && - mi.GetParameters().First().ParameterType.GetGenericArguments().First().IsAssignableFrom(typeArg); - } + private static void Main(string[] args) { - var wrapper = new Wrapper { Invoker = InvokeWrapper.Create() }; - var ReadId = wrapper.Invoker.Configure(typeof(MemoryStreamReader), "ReadDateTimeArray").First(); - var WriteId = wrapper.Invoker.Configure(typeof(MemoryStreamWriter), CreateArrayPredicate()).First(); - - Console.Write(WriteId); } } } \ No newline at end of file diff --git a/ZeroLevel.UnitTests/AsyncSerializationTest.cs b/ZeroLevel.UnitTests/AsyncSerializationTest.cs new file mode 100644 index 0000000..ec0fd1c --- /dev/null +++ b/ZeroLevel.UnitTests/AsyncSerializationTest.cs @@ -0,0 +1,430 @@ +ο»Ώusing System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Xunit; +using ZeroLevel.Network; +using ZeroLevel.Services.FileSystem; +using ZeroLevel.Services.Serialization; + +namespace ZeroLevel.Serialization +{ + public class AsyncSerializationTest + { + private static bool TestOrderingEquals(IEnumerable A, IEnumerable B, Func comparer) + { + if (A == null && B == null) return true; + if (A == null || B == null) return false; + if (A.Count() != B.Count()) return false; + var enumA = A.GetEnumerator(); + var enumB = B.GetEnumerator(); + while (enumA.MoveNext() && enumB.MoveNext()) + { + if (enumA.Current == null && enumB.Current == null) continue; + if (comparer(enumA.Current, enumB.Current) == false) return false; + } + return true; + } + private async Task MakePrimitiveAsyncTest(T value, Func serializer, Func> deserializer, Func comparator = null) + { + // Act + var writer = new MemoryStreamWriter(); + await serializer.Invoke(writer, value); + var data = writer.Complete(); + + var reader = new MemoryStreamReader(data); + var clone = await deserializer.Invoke(reader); + + // Assert + if (comparator == null) + { + Assert.Equal(value, clone); + } + else + { + Assert.True(comparator(value, clone)); + } + } + + + private async Task AsyncMakeCollectionTest(IEnumerable value, Func, Task> serializer, Func>> deserializer, Func comparator = null) + { + // In-Memory + // Act + var writer = new MemoryStreamWriter(); + await serializer.Invoke(writer, value); + var data = writer.Complete(); + + var reader = new MemoryStreamReader(data); + var clone = await deserializer.Invoke(reader); + + // Assert + if (value == null && clone != null && !clone.Any()) return; // OK + if (comparator == null) + { + Assert.True(CollectionComparsionExtensions.OrderingEquals(value, clone)); + } + else + { + Assert.True(TestOrderingEquals(value, clone, comparator)); + } + + // FS + var name = FSUtils.FileNameCorrection(typeof(T).Name) + ".bin"; + if (File.Exists(name)) + { + File.Delete(name); + } + using (var fs_writer = new MemoryStreamWriter(File.OpenWrite(name))) + { + await serializer.Invoke(fs_writer, value); + } + + using (var fs_reader = new MemoryStreamReader(File.OpenRead(name))) + { + clone = await deserializer.Invoke(fs_reader); + + // Assert + if (value == null && clone != null && !clone.Any()) return; // OK + if (comparator == null) + { + Assert.True(CollectionComparsionExtensions.OrderingEquals(value, clone)); + } + else + { + Assert.True(TestOrderingEquals(value, clone, comparator)); + } + } + } + + #region Primitive types tests + [Fact] + public async Task AsyncSerializeDateTime() + { + await MakePrimitiveAsyncTest(DateTime.Now, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + await MakePrimitiveAsyncTest(DateTime.UtcNow, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + await MakePrimitiveAsyncTest(DateTime.Today, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + await MakePrimitiveAsyncTest(DateTime.Now.AddYears(2000), async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + await MakePrimitiveAsyncTest(DateTime.MinValue, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + await MakePrimitiveAsyncTest(DateTime.MaxValue, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => (await r.ReadDateTimeAsync()).Value); + } + + [Fact] + public async Task AsyncSerializeNullableDateTime() + { + await MakePrimitiveAsyncTest(null, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + await MakePrimitiveAsyncTest(DateTime.UtcNow, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + await MakePrimitiveAsyncTest(DateTime.Today, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + await MakePrimitiveAsyncTest(DateTime.Now.AddYears(2000), async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + await MakePrimitiveAsyncTest(DateTime.MinValue, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + await MakePrimitiveAsyncTest(DateTime.MaxValue, async (w, v) => await w.WriteDateTimeAsync(v), async (r) => await r.ReadDateTimeAsync()); + } + + [Fact] + public async Task AsyncSerializeIPAddress() + { + var comparator = new Func((left, right) => NetUtils.Compare(left, right) == 0); + await MakePrimitiveAsyncTest(null, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.Any, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.Broadcast, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.IPv6Any, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.IPv6Loopback, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.IPv6None, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.Loopback, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.None, async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + await MakePrimitiveAsyncTest(IPAddress.Parse("93.111.16.58"), async (w, v) => await w.WriteIPAsync(v), async (r) => await r.ReadIPAsync(), comparator); + } + + [Fact] + public async Task AsyncSerializeIPEndPoint() + { + var comparator = new Func((left, right) => NetUtils.Compare(left, right) == 0); + await MakePrimitiveAsyncTest(null, async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.Any, 1), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.Broadcast, 600), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.IPv6Any, IPEndPoint.MaxPort), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.IPv6Loopback, 8080), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.IPv6None, 80), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.Loopback, 9000), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.None, 0), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + await MakePrimitiveAsyncTest(new IPEndPoint(IPAddress.Parse("93.111.16.58"), IPEndPoint.MinPort), async (w, v) => await w.WriteIPEndpointAsync(v), async (r) => await r.ReadIPEndpointAsync(), comparator); + } + + [Fact] + public async Task AsyncSerializeGuid() + { + await MakePrimitiveAsyncTest(Guid.Empty, async (w, v) => await w.WriteGuidAsync(v), async (r) => await r.ReadGuidAsync()); + await MakePrimitiveAsyncTest(Guid.NewGuid(), async (w, v) => await w.WriteGuidAsync(v), async (r) => await r.ReadGuidAsync()); + } + + [Fact] + public async Task AsyncSerializeTimeSpan() + { + await MakePrimitiveAsyncTest(TimeSpan.MaxValue, async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.MinValue, async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.Zero, async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.FromDays(1024), async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.FromMilliseconds(1), async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.FromTicks(1), async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + await MakePrimitiveAsyncTest(TimeSpan.FromTicks(0), async (w, v) => await w.WriteTimeSpanAsync(v), async (r) => await r.ReadTimeSpanAsync()); + } + + + [Fact] + public async Task AsyncSerializeString() + { + var comparator = new Func((left, right) => + (left == null && right == null) || + (left == null && right != null && right.Length == 0) || + (left != null && left.Length == 0 && right == null) || + string.Compare(left, right, StringComparison.InvariantCulture) == 0); + await MakePrimitiveAsyncTest("", async (w, v) => await w.WriteStringAsync(v), async (r) => await r.ReadStringAsync(), comparator); + await MakePrimitiveAsyncTest(String.Empty, async (w, v) => await w.WriteStringAsync(v), async (r) => await r.ReadStringAsync(), comparator); + await MakePrimitiveAsyncTest(null, async (w, v) => await w.WriteStringAsync(v), async (r) => await r.ReadStringAsync(), comparator); + await MakePrimitiveAsyncTest("HELLO!", async (w, v) => await w.WriteStringAsync(v), async (r) => await r.ReadStringAsync(), comparator); + await MakePrimitiveAsyncTest("𐌼𐌰𐌲 πŒ²πŒ»πŒ΄πƒ πŒΉΜˆπ„πŒ°πŒ½, 𐌽𐌹 πŒΌπŒΉπƒ π…πŒΏ 𐌽𐌳𐌰𐌽 πŒ±π‚πŒΉπŒ²πŒ²πŒΉπŒΈ", async (w, v) => await w.WriteStringAsync(v), async (r) => await r.ReadStringAsync(), comparator); + } + + + [Fact] + public async Task AsyncSerializeInt32() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + await MakePrimitiveAsyncTest(Int32.MinValue, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + await MakePrimitiveAsyncTest(Int32.MaxValue, async (w, v) => await w.WriteInt32Async(v), async (r) => await r.ReadInt32Async()); + } + + [Fact] + public async Task AsyncSerializeUInt32() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteUInt32Async(v), async (r) => await r.ReadUInt32Async()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteUInt32Async(v), async (r) => await r.ReadUInt32Async()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteUInt32Async(v), async (r) => await r.ReadUInt32Async()); + await MakePrimitiveAsyncTest(UInt32.MinValue, async (w, v) => await w.WriteUInt32Async(v), async (r) => await r.ReadUInt32Async()); + await MakePrimitiveAsyncTest(UInt32.MaxValue, async (w, v) => await w.WriteUInt32Async(v), async (r) => await r.ReadUInt32Async()); + } + + [Fact] + public async Task AsyncSerializeShort() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + await MakePrimitiveAsyncTest(short.MinValue, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + await MakePrimitiveAsyncTest(short.MaxValue, async (w, v) => await w.WriteShortAsync(v), async (r) => await r.ReadShortAsync()); + } + + [Fact] + public async Task AsyncSerializeUShort() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteUShortAsync(v), async (r) => await r.ReadUShortAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteUShortAsync(v), async (r) => await r.ReadUShortAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteUShortAsync(v), async (r) => await r.ReadUShortAsync()); + await MakePrimitiveAsyncTest(ushort.MinValue, async (w, v) => await w.WriteUShortAsync(v), async (r) => await r.ReadUShortAsync()); + await MakePrimitiveAsyncTest(ushort.MaxValue, async (w, v) => await w.WriteUShortAsync(v), async (r) => await r.ReadUShortAsync()); + } + + [Fact] + public async Task AsyncSerializeInt64() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(Int64.MinValue, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(Int64.MaxValue, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(Int64.MinValue / 2, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + await MakePrimitiveAsyncTest(Int64.MaxValue / 2, async (w, v) => await w.WriteLongAsync(v), async (r) => await r.ReadLongAsync()); + } + + [Fact] + public async Task AsyncSerializeUInt64() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(UInt64.MinValue, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(UInt64.MaxValue, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(UInt64.MinValue / 2, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + await MakePrimitiveAsyncTest(UInt64.MaxValue / 2, async (w, v) => await w.WriteULongAsync(v), async (r) => await r.ReadULongAsync()); + } + + [Fact] + public async Task AsyncSerializeDecimal() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(Decimal.MinValue, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(Decimal.MaxValue, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(Decimal.MinValue / 2, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + await MakePrimitiveAsyncTest(Decimal.MaxValue / 2, async (w, v) => await w.WriteDecimalAsync(v), async (r) => await r.ReadDecimalAsync()); + } + + [Fact] + public async Task AsyncSerializeFloat() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(float.MinValue, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(float.MaxValue, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(float.MinValue / 2, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + await MakePrimitiveAsyncTest(float.MaxValue / 2, async (w, v) => await w.WriteFloatAsync(v), async (r) => await r.ReadFloatAsync()); + } + + [Fact] + public async Task AsyncSerializeDouble() + { + await MakePrimitiveAsyncTest(-0, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(0, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(-10, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(10, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(Double.MinValue, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(Double.MaxValue, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(Double.MinValue / 2, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + await MakePrimitiveAsyncTest(Double.MaxValue / 2, async (w, v) => await w.WriteDoubleAsync(v), async (r) => await r.ReadDoubleAsync()); + } + + [Fact] + public async Task AsyncSerializeBytes() + { + var comparator = new Func((left, right) => + (left == null && (right == null || right.Length == 0)) || ArrayExtensions.UnsafeEquals(left, right)); + await MakePrimitiveAsyncTest(null, async (w, v) => await w.WriteBytesAsync(v), async (r) => await r.ReadBytesAsync(), comparator); + await MakePrimitiveAsyncTest(new byte[] { }, async (w, v) => await w.WriteBytesAsync(v), async (r) => await r.ReadBytesAsync(), comparator); + await MakePrimitiveAsyncTest(new byte[] { 1 }, async (w, v) => await w.WriteBytesAsync(v), async (r) => await r.ReadBytesAsync(), comparator); + await MakePrimitiveAsyncTest(new byte[] { 0, 1, 10, 100, 128, 255 }, async (w, v) => await w.WriteBytesAsync(v), async (r) => await r.ReadBytesAsync(), comparator); + } + #endregion + + #region Collection tests + [Fact] + public async Task AsyncSerializeCollectionDateTime() + { + await AsyncMakeCollectionTest(null, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadDateTimeCollectionAsync()); + await AsyncMakeCollectionTest(new DateTime?[] { }, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadDateTimeCollectionAsync()); + await AsyncMakeCollectionTest(new DateTime?[] { DateTime.Now, DateTime.UtcNow, DateTime.Today, DateTime.Now.AddYears(2000), null, DateTime.MinValue, DateTime.MaxValue }, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadDateTimeCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionIPAddress() + { + var comparator = new Func((left, right) => NetUtils.Compare(left, right) == 0); + await AsyncMakeCollectionTest(null, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadIPCollectionAsync()); + await AsyncMakeCollectionTest(new IPAddress[] { IPAddress.Any, IPAddress.Broadcast, IPAddress.IPv6Any, IPAddress.IPv6Loopback, IPAddress.IPv6None, IPAddress.Loopback, IPAddress.None, IPAddress.Parse("93.111.16.58") }, + async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadIPCollectionAsync(), + comparator); + } + + [Fact] + public async Task AsyncSerializeCollectionIPEndPoint() + { + var comparator = new Func((left, right) => NetUtils.Compare(left, right) == 0); + await AsyncMakeCollectionTest(null, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadIPEndPointCollectionAsync()); + await AsyncMakeCollectionTest(new IPEndPoint[] { }, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadIPEndPointCollectionAsync()); + await AsyncMakeCollectionTest(new IPEndPoint[] { new IPEndPoint(IPAddress.Any, 1), new IPEndPoint(IPAddress.Broadcast, 600), new IPEndPoint(IPAddress.IPv6Any, IPEndPoint.MaxPort), new IPEndPoint(IPAddress.IPv6Loopback, 8080), new IPEndPoint(IPAddress.IPv6None, 80), new IPEndPoint(IPAddress.Loopback, 9000), new IPEndPoint(IPAddress.None, 0), new IPEndPoint(IPAddress.Parse("93.111.16.58"), IPEndPoint.MinPort) } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadIPEndPointCollectionAsync() + , comparator); + } + + [Fact] + public async Task AsyncSerializeCollectionGuid() + { + await AsyncMakeCollectionTest(null, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadGuidCollectionAsync()); + await AsyncMakeCollectionTest(new Guid[] { }, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadGuidCollectionAsync()); + await AsyncMakeCollectionTest(new Guid[] { Guid.Empty, Guid.NewGuid() }, async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadGuidCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionTimeSpan() + { + await AsyncMakeCollectionTest(new TimeSpan[] { TimeSpan.MaxValue, TimeSpan.MinValue, TimeSpan.Zero, TimeSpan.FromDays(1024), TimeSpan.FromMilliseconds(1), TimeSpan.FromTicks(1), TimeSpan.FromTicks(0) } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadTimeSpanCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionString() + { + var comparator = new Func((left, right) => + (left == null && right == null) || + (left == null && right != null && right.Length == 0) || + (left != null && left.Length == 0 && right == null) || + string.Compare(left, right, StringComparison.InvariantCulture) == 0); + await AsyncMakeCollectionTest(new string[] { "", String.Empty, null, "HELLO!", "𐌼𐌰𐌲 πŒ²πŒ»πŒ΄πƒ πŒΉΜˆπ„πŒ°πŒ½, 𐌽𐌹 πŒΌπŒΉπƒ π…πŒΏ 𐌽𐌳𐌰𐌽 πŒ±π‚πŒΉπŒ²πŒ²πŒΉπŒΈ" } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadStringCollectionAsync() + , comparator); + } + + + [Fact] + public async Task AsyncSerializeCollectionInt32() + { + await AsyncMakeCollectionTest(new int[] { -0, 0, -10, 10, Int32.MinValue, Int32.MaxValue } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadInt32CollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionInt64() + { + await AsyncMakeCollectionTest(new long[] { -0, 0, -10, 10, Int64.MinValue, Int64.MaxValue, Int64.MinValue / 2, Int64.MaxValue / 2 } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadInt64CollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionDecimal() + { + await AsyncMakeCollectionTest(new Decimal[] { -0, 0, -10, 10, Decimal.MinValue, Decimal.MaxValue, Decimal.MinValue / 2, Decimal.MaxValue / 2 } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadDecimalCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionFloat() + { + await AsyncMakeCollectionTest(new float[] { -0, 0, -10, 10, float.MinValue, float.MaxValue, float.MinValue / 2, float.MaxValue / 2 } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadFloatCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionDouble() + { + await AsyncMakeCollectionTest(new Double[] { -0, 0, -10, 10, Double.MinValue, Double.MaxValue, Double.MinValue / 2, Double.MaxValue / 2 } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadDoubleCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionBoolean() + { + await AsyncMakeCollectionTest(new Boolean[] { true, false, true } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadBooleanCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionByte() + { + await AsyncMakeCollectionTest(new byte[] { 0, 3, -0, 1, 10, 128, 255 } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadByteCollectionAsync()); + } + + [Fact] + public async Task AsyncSerializeCollectionBytes() + { + var comparator = new Func((left, right) => + (left == null && (right == null || right.Length == 0)) || ArrayExtensions.UnsafeEquals(left, right)); + + await AsyncMakeCollectionTest(new Byte[][] { null, new byte[] { }, new byte[] { 1 }, new byte[] { 0, 1, 10, 100, 128, 255 } } + , async (w, v) => await w.WriteCollectionAsync(v), async r => await r.ReadByteArrayCollectionAsync() + , comparator); + } + + #endregion + } +} diff --git a/ZeroLevel.UnitTests/SerializationTests.cs b/ZeroLevel.UnitTests/SerializationTests.cs index 8f15365..0304db0 100644 --- a/ZeroLevel.UnitTests/SerializationTests.cs +++ b/ZeroLevel.UnitTests/SerializationTests.cs @@ -1,7 +1,9 @@ -ο»Ώusing System; +ο»Ώusing Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading.Tasks; using Xunit; using ZeroLevel.DocumentObjectModel; using ZeroLevel.Network; @@ -44,11 +46,12 @@ namespace ZeroLevel.Serialization } } + private void MakeCollectionTest(IEnumerable value, Func comparator = null) { // Act var data = MessageSerializer.SerializeCompatible>(value); - var clone = MessageSerializer.DeserializeCompatible>(data); + var clone = MessageSerializer.DeserializeCompatible>(data); // Assert if (value == null && clone != null && !clone.Any()) return; // OK @@ -406,7 +409,7 @@ namespace ZeroLevel.Serialization [Fact] public void EOSTest() { - var data = new Dictionary + var data = new Dictionary { { 0, "asd"}, { 1, "sdf"}, diff --git a/ZeroLevel/Services/Serialization/MemoryStreamWriter.cs b/ZeroLevel/Services/Serialization/MemoryStreamWriter.cs index 0c47c40..78bd4bd 100644 --- a/ZeroLevel/Services/Serialization/MemoryStreamWriter.cs +++ b/ZeroLevel/Services/Serialization/MemoryStreamWriter.cs @@ -488,6 +488,16 @@ namespace ZeroLevel.Services.Serialization await _stream.WriteAsync(val, 0, val.Length); } } + + public async Task WriteRawBytesAsyncNoLength(byte[] val) + { + if (val == null) + { + throw new ArgumentNullException(nameof(val)); + } + await _stream.WriteAsync(val, 0, val.Length); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public async Task WriteShortAsync(short number) => await _stream.WriteAsync(BitConverter.GetBytes(number), 0, 2); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -505,7 +515,7 @@ namespace ZeroLevel.Services.Serialization [MethodImpl(MethodImplOptions.AggressiveInlining)] public async Task WriteDecimalAsync(Decimal number) => await _stream.WriteAsync(BitConverterExt.GetBytes(number), 0, 16); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public async Task WriteDoubleAsync(double val)=> await _stream.WriteAsync(BitConverter.GetBytes(val), 0, 8); + public async Task WriteDoubleAsync(double val) => await _stream.WriteAsync(BitConverter.GetBytes(val), 0, 8); [MethodImpl(MethodImplOptions.AggressiveInlining)] public async Task WriteFloatAsync(float val) => await _stream.WriteAsync(BitConverter.GetBytes(val), 0, 4); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -528,8 +538,6 @@ namespace ZeroLevel.Services.Serialization } } - - /// /// Record the datetime /// @@ -695,7 +703,7 @@ namespace ZeroLevel.Services.Serialization saveAction.Invoke(writer, item); count++; } - await WriteBytesAsync(writer.Complete()); + await WriteRawBytesAsyncNoLength(writer.Complete()); writer.Stream.Position = 0; } } @@ -933,7 +941,7 @@ namespace ZeroLevel.Services.Serialization { saveAction.Invoke(writer, array[i + j]); } - await WriteBytesAsync(writer.Complete()); + await WriteRawBytesAsyncNoLength(writer.Complete()); writer.Stream.Position = 0; } } @@ -1044,7 +1052,7 @@ namespace ZeroLevel.Services.Serialization { buffer[j] = array[i + j] ? ONE : ZERO; } - await WriteBytesAsync(writer.Complete()); + await WriteRawBytesAsyncNoLength(writer.Complete()); writer.Stream.Position = 0; } } @@ -1083,7 +1091,7 @@ namespace ZeroLevel.Services.Serialization { buffer[j] = array[i + j]; } - await WriteBytesAsync(writer.Complete()); + await WriteRawBytesAsyncNoLength(writer.Complete()); writer.Stream.Position = 0; } } diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj index dc05807..2f03ac5 100644 --- a/ZeroLevel/ZeroLevel.csproj +++ b/ZeroLevel/ZeroLevel.csproj @@ -6,7 +6,7 @@ ogoun ogoun - 3.3.9.9 + 3.4.0.0 Token encryptor https://github.com/ogoun/Zero/wiki Copyright Ogoun 2023 @@ -14,8 +14,8 @@ https://github.com/ogoun/Zero git - 3.3.9.9 - 3.3.9.9 + 3.4.0.0 + 3.4.0.0 AnyCPU;x64;x86 zero.png full