diff options
author | Jon Skeet <skeet@pobox.com> | 2008-08-14 20:35:28 +0100 |
---|---|---|
committer | Jon Skeet <skeet@pobox.com> | 2008-08-14 20:35:28 +0100 |
commit | d6c9495797d202a19a93dee724c3c9fc0d6564c6 (patch) | |
tree | 287a54214295aee786c8be4f1295f2d52cd906d2 /csharp | |
parent | 19ed9c07821e39c5a33399b7cfc21ab1a4dc1f58 (diff) | |
download | protobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.tar.gz protobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.tar.bz2 protobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.zip |
More tests, and a bug fix.
Diffstat (limited to 'csharp')
-rw-r--r-- | csharp/ProtocolBuffers.Test/WireFormatTest.cs | 192 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/DynamicMessage.cs | 2 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/ExtendableMessage.cs | 2 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/FieldSet.cs | 7 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/IBuilder.cs | 24 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/RpcUtil.cs | 2 |
6 files changed, 211 insertions, 18 deletions
diff --git a/csharp/ProtocolBuffers.Test/WireFormatTest.cs b/csharp/ProtocolBuffers.Test/WireFormatTest.cs index 87c9dc6d..ecf87306 100644 --- a/csharp/ProtocolBuffers.Test/WireFormatTest.cs +++ b/csharp/ProtocolBuffers.Test/WireFormatTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; using Google.ProtocolBuffers.Descriptors; @@ -16,5 +17,196 @@ namespace Google.ProtocolBuffers { Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.String]); Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.Message]); } + + [Test] + public void Serialization() { + TestAllTypes message = TestUtil.GetAllSet(); + + ByteString rawBytes = message.ToByteString(); + Assert.AreEqual(rawBytes.Length, message.SerializedSize); + + TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes); + + TestUtil.AssertAllFieldsSet(message2); + } + + [Test] + public void SerializeExtensions() { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serealize a TestAllExtensions then parse it as TestAllTypes + // it should work. + + TestAllExtensions message = TestUtil.GetAllExtensionsSet(); + ByteString rawBytes = message.ToByteString(); + Assert.AreEqual(rawBytes.Length, message.SerializedSize); + + TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes); + + TestUtil.AssertAllFieldsSet(message2); + } + + [Test] + public void ParseExtensions() { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serealize a TestAllTypes then parse it as TestAllExtensions + // it should work. + + TestAllTypes message = TestUtil.GetAllSet(); + ByteString rawBytes = message.ToByteString(); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + TestUtil.RegisterAllExtensions(registry); + registry = registry.AsReadOnly(); + + TestAllExtensions message2 = + TestAllExtensions.ParseFrom(rawBytes, registry); + + TestUtil.AssertAllExtensionsSet(message2); + } + + [Test] + public void ExtensionsSerializedSize() { + Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize); + } + + private void AssertFieldsInOrder(ByteString data) { + CodedInputStream input = data.CreateCodedInput(); + uint previousTag = 0; + + while (true) { + uint tag = input.ReadTag(); + if (tag == 0) { + break; + } + + Assert.IsTrue(tag > previousTag); + previousTag = tag; + input.SkipField(tag); + } + } + + [Test] + public void InterleavedFieldsAndExtensions() { + // Tests that fields are written in order even when extension ranges + // are interleaved with field numbers. + ByteString data = + TestFieldOrderings.CreateBuilder() + .SetMyInt(1) + .SetMyString("foo") + .SetMyFloat(1.0F) + .SetExtension(UnitTestProtoFile.MyExtensionInt, 23) + .SetExtension(UnitTestProtoFile.MyExtensionString, "bar") + .Build().ToByteString(); + AssertFieldsInOrder(data); + + MessageDescriptor descriptor = TestFieldOrderings.Descriptor; + ByteString dynamic_data = + DynamicMessage.CreateBuilder(TestFieldOrderings.Descriptor) + .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_int"), 1L) + .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_string"), "foo") + .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_float"), 1.0F) + .SetField(UnitTestProtoFile.MyExtensionInt.Descriptor, 23) + .SetField(UnitTestProtoFile.MyExtensionString.Descriptor, "bar") + .WeakBuild().ToByteString(); + AssertFieldsInOrder(dynamic_data); + } + + private const int UnknownTypeId = 1550055; + private static readonly int TypeId1 = TestMessageSetExtension1.Descriptor.Extensions[0].FieldNumber; + private static readonly int TypeId2 = TestMessageSetExtension2.Descriptor.Extensions[0].FieldNumber; + + [Test] + public void SerializeMessageSet() { + // Set up a TestMessageSet with two known messages and an unknown one. + TestMessageSet messageSet = + TestMessageSet.CreateBuilder() + .SetExtension( + TestMessageSetExtension1.Types.MessageSetExtension, + TestMessageSetExtension1.CreateBuilder().SetI(123).Build()) + .SetExtension( + TestMessageSetExtension2.Types.MessageSetExtension, + TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build()) + .SetUnknownFields( + UnknownFieldSet.CreateBuilder() + .AddField(UnknownTypeId, + UnknownField.CreateBuilder() + .AddLengthDelimited(ByteString.CopyFromUtf8("bar")) + .Build()) + .Build()) + .Build(); + + ByteString data = messageSet.ToByteString(); + + // Parse back using RawMessageSet and check the contents. + RawMessageSet raw = RawMessageSet.ParseFrom(data); + + Assert.AreEqual(0, raw.UnknownFields.FieldDictionary.Count); + + Assert.AreEqual(3, raw.ItemCount); + Assert.AreEqual(TypeId1, raw.ItemList[0].TypeId); + Assert.AreEqual(TypeId2, raw.ItemList[1].TypeId); + Assert.AreEqual(UnknownTypeId, raw.ItemList[2].TypeId); + + TestMessageSetExtension1 message1 = TestMessageSetExtension1.ParseFrom(raw.GetItem(0).Message.ToByteArray()); + Assert.AreEqual(123, message1.I); + + TestMessageSetExtension2 message2 = TestMessageSetExtension2.ParseFrom(raw.GetItem(1).Message.ToByteArray()); + Assert.AreEqual("foo", message2.Str); + + Assert.AreEqual("bar", raw.GetItem(2).Message.ToStringUtf8()); + } + + [Test] + public void ParseMessageSet() { + ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance(); + extensionRegistry.Add(TestMessageSetExtension1.Types.MessageSetExtension); + extensionRegistry.Add(TestMessageSetExtension2.Types.MessageSetExtension); + + // Set up a RawMessageSet with two known messages and an unknown one. + RawMessageSet raw = + RawMessageSet.CreateBuilder() + .AddItem( + RawMessageSet.Types.Item.CreateBuilder() + .SetTypeId(TypeId1) + .SetMessage( + TestMessageSetExtension1.CreateBuilder() + .SetI(123) + .Build().ToByteString()) + .Build()) + .AddItem( + RawMessageSet.Types.Item.CreateBuilder() + .SetTypeId(TypeId2) + .SetMessage( + TestMessageSetExtension2.CreateBuilder() + .SetStr("foo") + .Build().ToByteString()) + .Build()) + .AddItem( + RawMessageSet.Types.Item.CreateBuilder() + .SetTypeId(UnknownTypeId) + .SetMessage(ByteString.CopyFromUtf8("bar")) + .Build()) + .Build(); + + ByteString data = raw.ToByteString(); + + // Parse as a TestMessageSet and check the contents. + TestMessageSet messageSet = + TestMessageSet.ParseFrom(data, extensionRegistry); + + Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.Types.MessageSetExtension).I); + Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.Types.MessageSetExtension).Str); + + // Check for unknown field with type LENGTH_DELIMITED, + // number UNKNOWN_TYPE_ID, and contents "bar". + UnknownFieldSet unknownFields = messageSet.UnknownFields; + Assert.AreEqual(1, unknownFields.FieldDictionary.Count); + Assert.IsTrue(unknownFields.HasField(UnknownTypeId)); + + UnknownField field = unknownFields[UnknownTypeId]; + Assert.AreEqual(1, field.LengthDelimitedList.Count); + Assert.AreEqual("bar", field.LengthDelimitedList[0].ToStringUtf8()); + } + } } diff --git a/csharp/ProtocolBuffers/DynamicMessage.cs b/csharp/ProtocolBuffers/DynamicMessage.cs index f0f4cde1..224b8dee 100644 --- a/csharp/ProtocolBuffers/DynamicMessage.cs +++ b/csharp/ProtocolBuffers/DynamicMessage.cs @@ -233,7 +233,7 @@ namespace Google.ProtocolBuffers { internal Builder(MessageDescriptor type) { this.type = type; - this.fields = FieldSet.CreateFieldSet(); + this.fields = FieldSet.CreateInstance(); this.unknownFields = UnknownFieldSet.DefaultInstance; } diff --git a/csharp/ProtocolBuffers/ExtendableMessage.cs b/csharp/ProtocolBuffers/ExtendableMessage.cs index 60d0d583..84a69b53 100644 --- a/csharp/ProtocolBuffers/ExtendableMessage.cs +++ b/csharp/ProtocolBuffers/ExtendableMessage.cs @@ -10,7 +10,7 @@ namespace Google.ProtocolBuffers { where TBuilder : GeneratedBuilder<TMessage, TBuilder> { protected ExtendableMessage() {} - private readonly FieldSet extensions = FieldSet.CreateFieldSet(); + private readonly FieldSet extensions = FieldSet.CreateInstance(); /// <summary> /// Access for the builder. diff --git a/csharp/ProtocolBuffers/FieldSet.cs b/csharp/ProtocolBuffers/FieldSet.cs index 79394ca4..6e563e7b 100644 --- a/csharp/ProtocolBuffers/FieldSet.cs +++ b/csharp/ProtocolBuffers/FieldSet.cs @@ -30,8 +30,9 @@ namespace Google.ProtocolBuffers { this.fields = fields; } - public static FieldSet CreateFieldSet() { - return new FieldSet(new Dictionary<FieldDescriptor, object>()); + public static FieldSet CreateInstance() { + // Use SortedList to keep fields in the canonical order + return new FieldSet(new SortedList<FieldDescriptor, object>()); } /// <summary> @@ -507,7 +508,7 @@ namespace Google.ProtocolBuffers { } /// <summary> - /// See <see cref="IBuilder.MergeFrom(IMessage)" /> + /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessage)" /> /// </summary> public void MergeFrom(IMessage other) { MergeFields(other.AllFields); diff --git a/csharp/ProtocolBuffers/IBuilder.cs b/csharp/ProtocolBuffers/IBuilder.cs index 52263feb..44990792 100644 --- a/csharp/ProtocolBuffers/IBuilder.cs +++ b/csharp/ProtocolBuffers/IBuilder.cs @@ -36,6 +36,18 @@ namespace Google.ProtocolBuffers { bool IsInitialized { get; } /// <summary> + /// Only present in the nongeneric interface - useful for tests, but + /// not as much in real life. + /// </summary> + IBuilder SetField(FieldDescriptor field, object value); + + /// <summary> + /// Only present in the nongeneric interface - useful for tests, but + /// not as much in real life. + /// </summary> + IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); + + /// <summary> /// Behaves like the equivalent property in IMessage<T>. /// The returned map may or may not reflect future changes to the builder. /// Either way, the returned map is unmodifiable. @@ -57,18 +69,6 @@ namespace Google.ProtocolBuffers { MessageDescriptor DescriptorForType { get; } /// <summary> - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// </summary> - IBuilder SetField(FieldDescriptor field, object value); - - /// <summary> - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// </summary> - IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); - - /// <summary> /// <see cref="IMessage{TMessage, TBuilder}.GetRepeatedFieldCount"/> /// </summary> /// <param name="field"></param> diff --git a/csharp/ProtocolBuffers/RpcUtil.cs b/csharp/ProtocolBuffers/RpcUtil.cs index ebd3f47f..92675c02 100644 --- a/csharp/ProtocolBuffers/RpcUtil.cs +++ b/csharp/ProtocolBuffers/RpcUtil.cs @@ -26,7 +26,7 @@ namespace Google.ProtocolBuffers { where TBuilder : IBuilder<TMessage, TBuilder> { return message => { TMessage castMessage = message as TMessage; - if (castMessage == null) { + if (castMessage == null) { castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); } action(castMessage); |