added tests for DynamicSerializerState

This commit is contained in:
Christian Köllner 2020-03-01 17:18:25 +01:00
parent 768999b666
commit 6a87cb7dac
5 changed files with 244 additions and 78 deletions

View File

@ -469,6 +469,21 @@ namespace Capnp.Net.Runtime.Tests
Assert.AreEqual(expected, str);
}
[TestMethod]
public void CapnpSerializableAnyPointer()
{
var b = MessageBuilder.Create();
var obj = b.CreateObject<SomeStruct.WRITER>();
obj.SomeText = "hello";
obj.MoreText = "world";
DeserializerState d = obj;
var any = CapnpSerializable.Create<AnyPointer>(d);
var obj2 = new SomeStruct.READER(any.State);
Assert.AreEqual("hello", obj2.SomeText);
Assert.AreEqual("world", obj2.MoreText);
}
class Unconstructible1 : ICapnpSerializable
{
public Unconstructible1(int annoyingParameter)
@ -511,8 +526,203 @@ namespace Capnp.Net.Runtime.Tests
var d = default(DeserializerState);
Assert.ThrowsException<ArgumentException>(() => CapnpSerializable.Create<SerializationTests>(d));
Assert.ThrowsException<ArgumentException>(() => CapnpSerializable.Create<IReadOnlyList<SerializationTests>>(d));
Assert.ThrowsException<ArgumentException>(() => CapnpSerializable.Create<IReadOnlyList<DeserializerState>>(d));
Assert.ThrowsException<ArgumentException>(() => CapnpSerializable.Create<Unconstructible1>(d));
Assert.ThrowsException<ArgumentException>(() => CapnpSerializable.Create<Unconstructible2>(d));
}
[TestMethod]
public void DynamicSerializerStateBytes()
{
var expected = new byte[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastByte().ToArray());
}
[TestMethod]
public void DynamicSerializerStateSBytes()
{
var expected = new sbyte[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastSByte().ToArray());
}
[TestMethod]
public void DynamicSerializerStateShorts()
{
var expected = new short[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastShort().ToArray());
}
[TestMethod]
public void DynamicSerializerStateUShorts()
{
var expected = new ushort[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastUShort().ToArray());
}
[TestMethod]
public void DynamicSerializerStateInts()
{
var expected = new int[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastInt().ToArray());
}
[TestMethod]
public void DynamicSerializerStateUInts()
{
var expected = new uint[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastUInt().ToArray());
}
[TestMethod]
public void DynamicSerializerStateLongs()
{
var expected = new long[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastLong().ToArray());
}
[TestMethod]
public void DynamicSerializerStateULongs()
{
var expected = new ulong[] { 1, 2, 3 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastULong().ToArray());
}
[TestMethod]
public void DynamicSerializerStateFloats()
{
var expected = new float[] { 1.0f, 2.0f, 3.0f };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastFloat().ToArray());
}
[TestMethod]
public void DynamicSerializerStateDoubles()
{
var expected = new double[] { 1.0, 2.0, 3.0 };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastDouble().ToArray());
}
[TestMethod]
public void DynamicSerializerStateBools()
{
var expected = new bool[] { true, true, false };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastBool().ToArray());
}
[TestMethod]
public void DynamicSerializerStateStrings()
{
var expected = new string[] { "foo", "bar", "baz" };
var b = MessageBuilder.Create();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
CollectionAssert.AreEqual(expected, d.RequireList().CastText2().ToArray());
}
[TestMethod]
public void DynamicSerializerStateObjects()
{
var c = new Counters();
var cap = new TestInterfaceImpl(c);
var expected = new object[] { null, "foo", cap };
var b = MessageBuilder.Create();
b.InitCapTable();
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(expected);
DeserializerState d = dss;
var list = d.RequireList().Cast(_ => _);
Assert.AreEqual(3, list.Count);
Assert.IsTrue(list[0].Kind == ObjectKind.Nil);
Assert.AreEqual("foo", list[1].RequireList().CastText());
var proxy = list[2].RequireCap<ITestInterface>();
proxy.Foo(123u, true);
Assert.AreEqual(1, c.CallCount);
}
[TestMethod]
public void DynamicSerializerStateFromDeserializerState()
{
var expected = new string[] { "foo", "bar", "baz" };
var b = MessageBuilder.Create();
var lots = b.CreateObject<ListOfTextSerializer>();
lots.Init(expected);
DeserializerState d = lots;
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(d);
DeserializerState d2 = dss;
CollectionAssert.AreEqual(expected, d2.RequireList().CastText2().ToArray());
}
[TestMethod]
public void DynamicSerializerStateFromSerializerState()
{
var expected = new string[] { "foo", "bar", "baz" };
var b = MessageBuilder.Create();
var lots = b.CreateObject<ListOfTextSerializer>();
lots.Init(expected);
var dss = b.CreateObject<DynamicSerializerState>();
dss.SetObject(lots);
DeserializerState d2 = dss;
CollectionAssert.AreEqual(expected, d2.RequireList().CastText2().ToArray());
}
}
}

View File

@ -367,6 +367,7 @@ namespace Capnp.Net.Runtime.Tests
}
[TestMethod]
[TestCategory("Coverage")]
public void TestTailCallClient()
{
LaunchCompatTestProcess("server:TailCaller", stdout =>

View File

@ -135,6 +135,13 @@ namespace Capnp
/// </param>
public void SetObject(object? obj)
{
void RewrapAndInheritBack<T>(Action<T> init) where T : SerializerState, new()
{
var r = Rewrap<T>();
init(r);
InheritFrom(r);
}
switch (obj)
{
case ICapnpSerializable serializable:
@ -146,55 +153,55 @@ namespace Capnp
break;
case IReadOnlyList<byte> bytes:
Rewrap<ListOfPrimitivesSerializer<byte>>().Init(bytes);
RewrapAndInheritBack<ListOfPrimitivesSerializer<byte>>(_ => _.Init(bytes));
break;
case IReadOnlyList<sbyte> sbytes:
Rewrap<ListOfPrimitivesSerializer<sbyte>>().Init(sbytes);
RewrapAndInheritBack<ListOfPrimitivesSerializer<sbyte>>(_ => _.Init(sbytes));
break;
case IReadOnlyList<ushort> ushorts:
Rewrap<ListOfPrimitivesSerializer<ushort>>().Init(ushorts);
RewrapAndInheritBack<ListOfPrimitivesSerializer<ushort>>(_ => _.Init(ushorts));
break;
case IReadOnlyList<short> shorts:
Rewrap<ListOfPrimitivesSerializer<short>>().Init(shorts);
RewrapAndInheritBack<ListOfPrimitivesSerializer<short>>(_ => _.Init(shorts));
break;
case IReadOnlyList<uint> uints:
Rewrap<ListOfPrimitivesSerializer<uint>>().Init(uints);
RewrapAndInheritBack<ListOfPrimitivesSerializer<uint>>(_ => _.Init(uints));
break;
case IReadOnlyList<int> ints:
Rewrap<ListOfPrimitivesSerializer<int>>().Init(ints);
RewrapAndInheritBack<ListOfPrimitivesSerializer<int>>(_ => _.Init(ints));
break;
case IReadOnlyList<ulong> ulongs:
Rewrap<ListOfPrimitivesSerializer<ulong>>().Init(ulongs);
RewrapAndInheritBack<ListOfPrimitivesSerializer<ulong>>(_ => _.Init(ulongs));
break;
case IReadOnlyList<long> longs:
Rewrap<ListOfPrimitivesSerializer<long>>().Init(longs);
RewrapAndInheritBack<ListOfPrimitivesSerializer<long>>(_ => _.Init(longs));
break;
case IReadOnlyList<float> floats:
Rewrap<ListOfPrimitivesSerializer<float>>().Init(floats);
RewrapAndInheritBack<ListOfPrimitivesSerializer<float>>(_ => _.Init(floats));
break;
case IReadOnlyList<double> doubles:
Rewrap<ListOfPrimitivesSerializer<double>>().Init(doubles);
RewrapAndInheritBack<ListOfPrimitivesSerializer<double>>(_ => _.Init(doubles));
break;
case IReadOnlyList<bool> bools:
Rewrap<ListOfBitsSerializer>().Init(bools);
RewrapAndInheritBack<ListOfBitsSerializer>(_ => _.Init(bools));
break;
case IReadOnlyList<string> strings:
Rewrap<ListOfTextSerializer>().Init(strings);
RewrapAndInheritBack<ListOfTextSerializer>(_ => _.Init(strings));
break;
case IReadOnlyList<object> objects:
Rewrap<ListOfPointersSerializer<DynamicSerializerState>>().Init(objects, (s, o) => s.SetObject(o));
RewrapAndInheritBack<ListOfPointersSerializer<DynamicSerializerState>>(_ => _.Init(objects, (s, o) => s.SetObject(o)));
break;
case DeserializerState ds:

View File

@ -1,45 +0,0 @@
using System;
namespace Capnp
{
class PrimitiveCoder
{
class Coder<T>
{
public static Func<T, T, T>? Fn { get; set; }
}
static PrimitiveCoder()
{
Coder<bool>.Fn = (x, y) => x != y;
Coder<sbyte>.Fn = (x, y) => (sbyte)(x ^ y);
Coder<byte>.Fn = (x, y) => (byte)(x ^ y);
Coder<short>.Fn = (x, y) => (short)(x ^ y);
Coder<ushort>.Fn = (x, y) => (ushort)(x ^ y);
Coder<int>.Fn = (x, y) => x ^ y;
Coder<uint>.Fn = (x, y) => x ^ y;
Coder<long>.Fn = (x, y) => x ^ y;
Coder<ulong>.Fn = (x, y) => x ^ y;
Coder<float>.Fn = (x, y) =>
{
int xi = x.ReplacementSingleToInt32Bits();
int yi = y.ReplacementSingleToInt32Bits();
int zi = xi ^ yi;
return BitConverter.ToSingle(BitConverter.GetBytes(zi), 0);
};
Coder<double>.Fn = (x, y) =>
{
long xi = BitConverter.DoubleToInt64Bits(x);
long yi = BitConverter.DoubleToInt64Bits(y);
long zi = xi ^ yi;
return BitConverter.Int64BitsToDouble(zi);
};
}
public static Func<T, T, T> Get<T>()
{
return Coder<T>.Fn ??
throw new NotSupportedException("Generic type argument is not a supported primitive type, no coder defined");
}
}
}

View File

@ -75,6 +75,18 @@ namespace Capnp
MsgBuilder = owner.MsgBuilder;
}
internal void InheritFrom(SerializerState other)
{
SegmentIndex = other.SegmentIndex;
Offset = other.Offset;
ListElementCount = other.ListElementCount;
StructDataCount = other.StructDataCount;
StructPtrCount = other.StructPtrCount;
Kind = other.Kind;
CapabilityIndex = other.CapabilityIndex;
_linkedStates = other._linkedStates;
}
/// <summary>
/// Represents this state by a different serializer state specialization. This is similar to a type-cast: The underlying object remains the same,
/// but the specialization adds a particular "view" on that data.
@ -114,14 +126,7 @@ namespace Capnp
break;
}
ts.SegmentIndex = SegmentIndex;
ts.Offset = Offset;
ts.ListElementCount = ListElementCount;
ts.StructDataCount = StructDataCount;
ts.StructPtrCount = StructPtrCount;
ts.Kind = Kind;
ts.CapabilityIndex = CapabilityIndex;
ts._linkedStates = _linkedStates;
ts.InheritFrom(this);
}
if (Owner != null)
@ -132,18 +137,6 @@ namespace Capnp
return ts;
}
internal void InheritFrom(SerializerState other)
{
SegmentIndex = other.SegmentIndex;
Offset = other.Offset;
ListElementCount = other.ListElementCount;
StructDataCount = other.StructDataCount;
StructPtrCount = other.StructPtrCount;
Kind = other.Kind;
CapabilityIndex = other.CapabilityIndex;
_linkedStates = other._linkedStates;
}
/// <summary>
/// Whether storage space for the underlying object was already allocated. Note that allocation happens
/// lazily, i.e. constructing a SerializerState and binding it to a MessageBuilder does NOT yet result in allocation.