module FunDomain.Tests.ProtobufNetSerialization open ProtoBuf open ProtoBuf.Meta open Swensen.Unquote open Xunit open System.IO open Microsoft.FSharp.Reflection [] type MessageA = { [] X: string; [] Y: int option; } [] [] type MessageB = { [] A: string; [] B: string; } [] type Message = | MessageA of MessageA | MessageB of MessageB let serialize msg = use ms = new MemoryStream() Serializer.SerializeWithLengthPrefix(ms, msg, PrefixStyle.Fixed32) ms.ToArray() let deserialize<'TMessage> bytes = use ms = new MemoryStream(buffer=bytes) Serializer.DeserializeWithLengthPrefix<'TMessage>(ms, PrefixStyle.Fixed32) let registerSerializableDuInModel<'TMessage> (model:RuntimeTypeModel) = let baseType = model.[typeof<'TMessage>] for case in typeof<'TMessage> |> FSharpType.GetUnionCases do let caseType = case.Name |> case.DeclaringType.GetNestedType baseType.AddSubType(1000 + case.Tag, caseType) |> ignore let caseTypeModel = model.[caseType] caseTypeModel.Add("item").UseConstructor <- false baseType.CompileInPlace() let registerSerializableDu<'TMessage> () = registerSerializableDuInModel<'TMessage> RuntimeTypeModel.Default registerSerializableDu () let [] ``MessageA roundtrips with null`` () = let msg = {X=null; Y=None} let result = serialize msg test <@ msg = deserialize result @> let [] ``MessageA roundtrips with Empty`` () = let msg = {X=""; Y=None} let result = serialize msg test <@ msg = deserialize result @> let [] ``MessageA roundtrips with Some`` () = let msg = {X="foo"; Y=Some 32} let result = serialize msg test <@ msg = deserialize result @> let [] ``MessageA roundtrips with None`` () = let msg = {X="foo"; Y=None} let result = serialize msg test <@ msg = deserialize result @> let [] ``MessageB roundtrips`` () = let msg = {A="bar"; B="baz"} let result = serialize msg test <@ msg = deserialize result @> let [] ``roundtrip pair``() = let msg1 = MessageA {X="foo"; Y=Some 32} let msg1' = msg1 |> serialize |> deserialize test <@ msg1' = msg1 @> let msg2 = MessageB {A="bar"; B="baz"} let msg2' = msg2 |> serialize |> deserialize test <@ msg2' = msg2 @> let [] many() = for _ in 1..1000 do ``roundtrip pair``()