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: