mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 06:41:50 +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\TestCallContext.cs" Link="TestCallContext.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" />
|
||||
</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.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -32,12 +34,17 @@ namespace Capnp.Net.Runtime.Tests
|
||||
var b = MessageBuilder.Create();
|
||||
var list = b.CreateObject<ListOfBitsSerializer>();
|
||||
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[63] = true;
|
||||
list[65] = true;
|
||||
list[66] = true;
|
||||
list[65] = false;
|
||||
list[129] = true;
|
||||
Assert.ThrowsException<IndexOutOfRangeException>(() => { var _ = list[130]; });
|
||||
Assert.ThrowsException<IndexOutOfRangeException>(() => { list[130] = false; });
|
||||
Assert.IsFalse(list[0]);
|
||||
Assert.IsTrue(list[63]);
|
||||
Assert.IsFalse(list[64]);
|
||||
@ -59,5 +66,63 @@ namespace Capnp.Net.Runtime.Tests
|
||||
var list3 = d.RequireList().CastBool();
|
||||
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>
|
||||
/// <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>
|
||||
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");
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ namespace Capnp
|
||||
{
|
||||
get
|
||||
{
|
||||
ListSerializerHelper.EnsureAllocated(this);
|
||||
|
||||
if (index < 0 || index >= Count)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
@ -61,6 +63,8 @@ namespace Capnp
|
||||
}
|
||||
set
|
||||
{
|
||||
ListSerializerHelper.EnsureAllocated(this);
|
||||
|
||||
if (index < 0 || index >= Count)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
|
@ -35,16 +35,29 @@ namespace Capnp
|
||||
[AllowNull]
|
||||
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
|
||||
{
|
||||
if (!IsAllocated)
|
||||
throw new InvalidOperationException("Call Init() first");
|
||||
ListSerializerHelper.EnsureAllocated(this);
|
||||
|
||||
if (index < 0 || index >= RawData.Length)
|
||||
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>
|
||||
/// <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>
|
||||
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