diff --git a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj
index 30d40e2..fd9eafd 100644
--- a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj
+++ b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj
@@ -24,6 +24,7 @@
+
diff --git a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj
index 2f47c80..1fdeec0 100644
--- a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj
+++ b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj
@@ -10,6 +10,8 @@
Library
Debug;Release
+
+ Capnp.Net.Runtime.Tests
diff --git a/Capnp.Net.Runtime.Tests/SerializationTests.cs b/Capnp.Net.Runtime.Tests/SerializationTests.cs
new file mode 100644
index 0000000..9ce7fdd
--- /dev/null
+++ b/Capnp.Net.Runtime.Tests/SerializationTests.cs
@@ -0,0 +1,63 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Capnp.Net.Runtime.Tests
+{
+ [TestClass]
+ [TestCategory("Coverage")]
+ public class SerializationTests
+ {
+ [TestMethod]
+ public void ListOfBits()
+ {
+ void CheckList(IEnumerable items)
+ {
+ int i = 0;
+ foreach (bool bit in items)
+ {
+ if (i == 63 || i == 66 || i == 129)
+ Assert.IsTrue(bit);
+ else
+ Assert.IsFalse(bit);
+
+ ++i;
+ }
+ Assert.AreEqual(130, i);
+ }
+
+ var b = MessageBuilder.Create();
+ var list = b.CreateObject();
+ Assert.ThrowsException(() => list.Init(-1));
+ list.Init(130);
+ list[63] = true;
+ list[65] = true;
+ list[66] = true;
+ list[65] = false;
+ list[129] = true;
+ Assert.IsFalse(list[0]);
+ Assert.IsTrue(list[63]);
+ Assert.IsFalse(list[64]);
+ Assert.IsFalse(list[65]);
+ Assert.IsTrue(list[66]);
+ Assert.IsTrue(list[129]);
+ var list2 = b.CreateObject();
+ list2.Init(null);
+ list2.Init(list);
+ Assert.IsFalse(list2[0]);
+ Assert.IsTrue(list2[63]);
+ Assert.IsFalse(list2[64]);
+ Assert.IsFalse(list2[65]);
+ Assert.IsTrue(list2[66]);
+ Assert.IsTrue(list2[129]);
+ CheckList(list2);
+ Assert.ThrowsException(() => list.Init(4));
+ DeserializerState d = list2;
+ var list3 = d.RequireList().CastBool();
+ CheckList(list3);
+ }
+ }
+}
diff --git a/Capnp.Net.Runtime/ListOfBitsSerializer.cs b/Capnp.Net.Runtime/ListOfBitsSerializer.cs
index 6c00c7a..af0eed8 100644
--- a/Capnp.Net.Runtime/ListOfBitsSerializer.cs
+++ b/Capnp.Net.Runtime/ListOfBitsSerializer.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.InteropServices;
namespace Capnp
{
@@ -10,6 +11,34 @@ namespace Capnp
///
public class ListOfBitsSerializer: SerializerState, IReadOnlyList
{
+ class Enumerator : IEnumerator
+ {
+ readonly ListOfBitsSerializer _self;
+ int _pos = -1;
+
+ public Enumerator(ListOfBitsSerializer self)
+ {
+ _self = self;
+ }
+
+ public bool Current => _pos >= 0 && _pos < _self.Count ? _self[_pos] : false;
+
+ object IEnumerator.Current => Current;
+
+ public void Dispose()
+ {
+ }
+
+ public bool MoveNext()
+ {
+ return ++_pos < _self.Count;
+ }
+
+ public void Reset()
+ {
+ _pos = -1;
+ }
+ }
///
/// Gets or sets the element at given index.
@@ -91,8 +120,8 @@ namespace Capnp
///
/// Implements
///
- public IEnumerator GetEnumerator() => (IEnumerator)this.ToArray().GetEnumerator();
+ public IEnumerator GetEnumerator() => new Enumerator(this);
- IEnumerator IEnumerable.GetEnumerator() => this.ToArray().GetEnumerator();
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
\ No newline at end of file
diff --git a/Capnp.Net.Runtime/MessageBuilder.cs b/Capnp.Net.Runtime/MessageBuilder.cs
index 9a5d826..6afb40e 100644
--- a/Capnp.Net.Runtime/MessageBuilder.cs
+++ b/Capnp.Net.Runtime/MessageBuilder.cs
@@ -64,7 +64,7 @@ namespace Capnp
///
/// Creates an object and sets it as root object.
///
- /// Serializer state specialization
+ /// Serializer state specialization (must be a struct)
/// Serializer state instance representing the new object
public TS BuildRoot() where TS: SerializerState, new()
{
@@ -72,6 +72,9 @@ namespace Capnp
throw new InvalidOperationException("Root already set");
var root = CreateObject();
+ if (root.Kind != ObjectKind.Struct)
+ throw new InvalidOperationException("Root object must be a struct");
+
Root = root;
return root;
}
diff --git a/appveyor.yml b/appveyor.yml
index a41b38e..67656b3 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -91,8 +91,7 @@ test_script:
vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests.Core21\bin\Release\netcoreapp2.1\Capnp.Net.Runtime.Tests.Core21.dll
- ps: |
.\scripts\measure-coverage.ps1
- $coveralls = ".\tools\csmacnz.coveralls.exe"
- & $coveralls --reportgenerator -i coverage/report --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_JOB_ID
+ csmacnz.Coveralls --reportgenerator -i coverage/report --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_JOB_ID
on_finish :
# any cleanup in here
deploy: