mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 14:51:41 +01:00
added cap list serializer TC
bugfixes
This commit is contained in:
parent
3877e2aca3
commit
fc6af91833
@ -34,7 +34,6 @@
|
|||||||
<Compile Include="..\Capnp.Net.Runtime.Tests\TestBase.cs" Link="TestBase.cs" />
|
<Compile Include="..\Capnp.Net.Runtime.Tests\TestBase.cs" Link="TestBase.cs" />
|
||||||
<Compile Include="..\Capnp.Net.Runtime.Tests\TestCallContext.cs" Link="TestCallContext.cs" />
|
<Compile Include="..\Capnp.Net.Runtime.Tests\TestCallContext.cs" Link="TestCallContext.cs" />
|
||||||
<Compile Include="..\Capnp.Net.Runtime.Tests\TestCapImplementations.cs" Link="TestCapImplementations.cs" />
|
<Compile Include="..\Capnp.Net.Runtime.Tests\TestCapImplementations.cs" Link="TestCapImplementations.cs" />
|
||||||
<Compile Include="..\Capnp.Net.Runtime.Tests\TestInterfaces.cs" Link="TestInterfaces.cs" />
|
|
||||||
<Compile Include="..\Capnp.Net.Runtime.Tests\WirePointerTests.cs" Link="WirePointerTests.cs" />
|
<Compile Include="..\Capnp.Net.Runtime.Tests\WirePointerTests.cs" Link="WirePointerTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Capnp.Net.Runtime.Tests.GenImpls;
|
||||||
|
using Capnproto_test.Capnp.Test;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -32,12 +34,17 @@ namespace Capnp.Net.Runtime.Tests
|
|||||||
var b = MessageBuilder.Create();
|
var b = MessageBuilder.Create();
|
||||||
var list = b.CreateObject<ListOfBitsSerializer>();
|
var list = b.CreateObject<ListOfBitsSerializer>();
|
||||||
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Init(-1));
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Init(-1));
|
||||||
|
// Assert.AreEqual(0, list.Count); // Bug or feature? Uninitialized list's Count is -1
|
||||||
|
Assert.ThrowsException<InvalidOperationException>(() => { var _ = list[0]; });
|
||||||
|
Assert.ThrowsException<InvalidOperationException>(() => { list[0] = false; });
|
||||||
list.Init(130);
|
list.Init(130);
|
||||||
list[63] = true;
|
list[63] = true;
|
||||||
list[65] = true;
|
list[65] = true;
|
||||||
list[66] = true;
|
list[66] = true;
|
||||||
list[65] = false;
|
list[65] = false;
|
||||||
list[129] = true;
|
list[129] = true;
|
||||||
|
Assert.ThrowsException<IndexOutOfRangeException>(() => { var _ = list[130]; });
|
||||||
|
Assert.ThrowsException<IndexOutOfRangeException>(() => { list[130] = false; });
|
||||||
Assert.IsFalse(list[0]);
|
Assert.IsFalse(list[0]);
|
||||||
Assert.IsTrue(list[63]);
|
Assert.IsTrue(list[63]);
|
||||||
Assert.IsFalse(list[64]);
|
Assert.IsFalse(list[64]);
|
||||||
@ -59,5 +66,63 @@ namespace Capnp.Net.Runtime.Tests
|
|||||||
var list3 = d.RequireList().CastBool();
|
var list3 = d.RequireList().CastBool();
|
||||||
CheckList(list3);
|
CheckList(list3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ListOfCaps()
|
||||||
|
{
|
||||||
|
var b = MessageBuilder.Create();
|
||||||
|
b.InitCapTable();
|
||||||
|
var list = b.CreateObject<ListOfCapsSerializer<ITestInterface>>();
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Init(-1));
|
||||||
|
Assert.ThrowsException<InvalidOperationException>(() => { var _ = list[0]; });
|
||||||
|
Assert.ThrowsException<InvalidOperationException>(() => { list[0] = null; });
|
||||||
|
list.Init(5);
|
||||||
|
Assert.ThrowsException<InvalidOperationException>(() => list.Init(1));
|
||||||
|
var c1 = new Counters();
|
||||||
|
var cap1 = new TestInterfaceImpl(c1);
|
||||||
|
var c2 = new Counters();
|
||||||
|
var cap2 = new TestInterfaceImpl(c2);
|
||||||
|
list[0] = null;
|
||||||
|
list[1] = cap1;
|
||||||
|
list[2] = cap2;
|
||||||
|
list[3] = cap1;
|
||||||
|
list[4] = cap2;
|
||||||
|
list[3] = null;
|
||||||
|
Assert.IsTrue(list.All(p => p is Rpc.Proxy));
|
||||||
|
var proxies = list.Cast<Rpc.Proxy>().ToArray();
|
||||||
|
Assert.IsTrue(proxies[0].IsNull);
|
||||||
|
Assert.IsFalse(proxies[1].IsNull);
|
||||||
|
Assert.IsTrue(proxies[3].IsNull);
|
||||||
|
list[2].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(0, c1.CallCount);
|
||||||
|
Assert.AreEqual(1, c2.CallCount);
|
||||||
|
list[4].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(2, c2.CallCount);
|
||||||
|
|
||||||
|
var list2 = b.CreateObject<ListOfCapsSerializer<ITestInterface>>();
|
||||||
|
list2.Init(null);
|
||||||
|
list2.Init(list);
|
||||||
|
proxies = list2.Cast<Rpc.Proxy>().ToArray();
|
||||||
|
Assert.IsTrue(proxies[0].IsNull);
|
||||||
|
Assert.IsFalse(proxies[1].IsNull);
|
||||||
|
Assert.IsTrue(proxies[3].IsNull);
|
||||||
|
list2[2].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(0, c1.CallCount);
|
||||||
|
Assert.AreEqual(3, c2.CallCount);
|
||||||
|
list2[4].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(4, c2.CallCount);
|
||||||
|
|
||||||
|
DeserializerState d = list2;
|
||||||
|
var list3 = d.RequireList().CastCapList<ITestInterface>();
|
||||||
|
proxies = list3.Cast<Rpc.Proxy>().ToArray();
|
||||||
|
Assert.IsTrue(proxies[0].IsNull);
|
||||||
|
Assert.IsFalse(proxies[1].IsNull);
|
||||||
|
Assert.IsTrue(proxies[3].IsNull);
|
||||||
|
list3[2].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(0, c1.CallCount);
|
||||||
|
Assert.AreEqual(5, c2.CallCount);
|
||||||
|
list3[4].Foo(123u, true).Wait();
|
||||||
|
Assert.AreEqual(6, c2.CallCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
using Capnp.Rpc;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Capnp.Net.Runtime.Tests.ManualImpls
|
|
||||||
{
|
|
||||||
// [Skeleton(typeof(TestInterfaceSkeleton))]
|
|
||||||
// [Proxy(typeof(TestInterfaceProxy))]
|
|
||||||
// interface ITestInterface: IDisposable
|
|
||||||
// {
|
|
||||||
// Task<string> Foo(uint i, bool j);
|
|
||||||
// Task Bar();
|
|
||||||
// Task<int> Baz(int s);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestExtendsSkeleton))]
|
|
||||||
// [Proxy(typeof(TestExtendsProxy))]
|
|
||||||
// interface ITestExtends: ITestInterface, IDisposable
|
|
||||||
// {
|
|
||||||
// void Qux();
|
|
||||||
// Task Corge(int x);
|
|
||||||
// Task<int> Grault();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// interface ITestExtends2: ITestExtends, IDisposable
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct Box
|
|
||||||
// {
|
|
||||||
// public ITestExtends Cap { get; set; }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct AnyBox
|
|
||||||
// {
|
|
||||||
// public object Cap { get; set; }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestPipelineSkeleton))]
|
|
||||||
// [Proxy(typeof(TestPipelineProxy))]
|
|
||||||
// interface ITestPipeline: IDisposable
|
|
||||||
// {
|
|
||||||
// Task<(string, Box)> GetCap(uint n, ITestInterface inCap);
|
|
||||||
// Task TestPointers(ITestExtends cap, DeserializerState obj, IReadOnlyList<ITestExtends> list);
|
|
||||||
// Task<(string, AnyBox)> GetAnyCap(uint n, object inCap);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestCallOrderSkeleton))]
|
|
||||||
// [Proxy(typeof(TestCallOrderProxy))]
|
|
||||||
// interface ITestCallOrder : IDisposable
|
|
||||||
// {
|
|
||||||
// Task<uint> GetCallSequence(uint expected);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct TailResult
|
|
||||||
// {
|
|
||||||
// public uint I { get; set; }
|
|
||||||
// public string T { get; set; }
|
|
||||||
// public ITestCallOrder C { get; set; }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestTailCalleeSkeleton))]
|
|
||||||
// [Proxy(typeof(TestTailCalleeProxy))]
|
|
||||||
// interface ITestTailCallee: IDisposable
|
|
||||||
// {
|
|
||||||
// Task<TailResult> Foo(int i, string t);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestTailCallerSkeleton))]
|
|
||||||
// [Proxy(typeof(TestTailCallerProxy))]
|
|
||||||
// interface ITestTailCaller: IDisposable
|
|
||||||
// {
|
|
||||||
// Task<TailResult> Foo(int i, ITestTailCallee c);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestHandleSkeleton))]
|
|
||||||
// [Proxy(typeof(TestHandleProxy))]
|
|
||||||
// interface ITestHandle: IDisposable { }
|
|
||||||
|
|
||||||
|
|
||||||
// [Skeleton(typeof(TestMoreStuffSkeleton))]
|
|
||||||
// [Proxy(typeof(TestMoreStuffProxy))]
|
|
||||||
// interface ITestMoreStuff: ITestCallOrder
|
|
||||||
// {
|
|
||||||
// Task<string> CallFoo(ITestInterface cap);
|
|
||||||
// Task<string> CallFooWhenResolved(ITestInterface cap);
|
|
||||||
// Task<ITestInterface> NeverReturn(ITestInterface cap, CancellationToken ct);
|
|
||||||
// Task Hold(ITestInterface cap);
|
|
||||||
// Task<string> CallHeld();
|
|
||||||
// Task<ITestInterface> GetHeld();
|
|
||||||
// Task<ITestCallOrder> Echo(ITestCallOrder cap);
|
|
||||||
// Task ExpectCancel(ITestInterface cap, CancellationToken ct);
|
|
||||||
// Task<(string, string)> MethodWithDefaults(string a, uint b, string c);
|
|
||||||
// void MethodWithNullDefault(string a, ITestInterface b);
|
|
||||||
// Task<ITestHandle> GetHandle();
|
|
||||||
// Task<ITestMoreStuff> GetNull();
|
|
||||||
// Task<string> GetEnormousString();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
@ -89,7 +89,7 @@ namespace Capnp
|
|||||||
/// <returns>Capability list representation</returns>
|
/// <returns>Capability list representation</returns>
|
||||||
/// <exception cref="NotSupportedException">If this kind of list cannot be represented as list of capabilities (because it is a list of non-pointers)</exception>
|
/// <exception cref="NotSupportedException">If this kind of list cannot be represented as list of capabilities (because it is a list of non-pointers)</exception>
|
||||||
/// <exception cref="Rpc.InvalidCapabilityInterfaceException">If <typeparamref name="T"/> does not qualify as capability interface.</exception>
|
/// <exception cref="Rpc.InvalidCapabilityInterfaceException">If <typeparamref name="T"/> does not qualify as capability interface.</exception>
|
||||||
public virtual IReadOnlyList<ListOfCapsDeserializer<T>> CastCapList<T>() where T: class
|
public virtual IReadOnlyList<T> CastCapList<T>() where T: class
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("This kind of list does not contain nested lists");
|
throw new NotSupportedException("This kind of list does not contain nested lists");
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ namespace Capnp
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
ListSerializerHelper.EnsureAllocated(this);
|
||||||
|
|
||||||
if (index < 0 || index >= Count)
|
if (index < 0 || index >= Count)
|
||||||
throw new IndexOutOfRangeException();
|
throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
@ -61,6 +63,8 @@ namespace Capnp
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
ListSerializerHelper.EnsureAllocated(this);
|
||||||
|
|
||||||
if (index < 0 || index >= Count)
|
if (index < 0 || index >= Count)
|
||||||
throw new IndexOutOfRangeException();
|
throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
|
@ -35,16 +35,29 @@ namespace Capnp
|
|||||||
[AllowNull]
|
[AllowNull]
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
get => (Rpc.CapabilityReflection.CreateProxy<T>(DecodeCapPointer(index)) as T)!;
|
get
|
||||||
|
{
|
||||||
|
ListSerializerHelper.EnsureAllocated(this);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (Rpc.CapabilityReflection.CreateProxy<T>(DecodeCapPointer(index)) as T)!;
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!IsAllocated)
|
ListSerializerHelper.EnsureAllocated(this);
|
||||||
throw new InvalidOperationException("Call Init() first");
|
|
||||||
|
|
||||||
if (index < 0 || index >= RawData.Length)
|
if (index < 0 || index >= RawData.Length)
|
||||||
throw new IndexOutOfRangeException("index out of range");
|
throw new IndexOutOfRangeException("index out of range");
|
||||||
|
|
||||||
RawData[index] = ProvideCapability(value);
|
var p = default(WirePointer);
|
||||||
|
p.SetCapability(ProvideCapability(value));
|
||||||
|
RawData[index] = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +83,9 @@ namespace Capnp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Capability interface</typeparam>
|
/// <typeparam name="T">Capability interface</typeparam>
|
||||||
/// <returns>The desired representation. Since it is evaluated lazily, type conflicts will not happen before accessing the resulting list's elements.</returns>
|
/// <returns>The desired representation. Since it is evaluated lazily, type conflicts will not happen before accessing the resulting list's elements.</returns>
|
||||||
public override IReadOnlyList<ListOfCapsDeserializer<T>> CastCapList<T>()
|
public override IReadOnlyList<T> CastCapList<T>()
|
||||||
{
|
{
|
||||||
return this.LazyListSelect(d => d.RequireCapList<T>());
|
return State.RequireCapList<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
13
Capnp.Net.Runtime/ListSerializerHelper.cs
Normal file
13
Capnp.Net.Runtime/ListSerializerHelper.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Capnp
|
||||||
|
{
|
||||||
|
static class ListSerializerHelper
|
||||||
|
{
|
||||||
|
public static void EnsureAllocated(SerializerState serializer)
|
||||||
|
{
|
||||||
|
if (!serializer.IsAllocated)
|
||||||
|
throw new InvalidOperationException("Call Init() first");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user