aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/ProtocolBuffers.Test/MessageTest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'csharp/src/ProtocolBuffers.Test/MessageTest.cs')
-rw-r--r--csharp/src/ProtocolBuffers.Test/MessageTest.cs387
1 files changed, 387 insertions, 0 deletions
diff --git a/csharp/src/ProtocolBuffers.Test/MessageTest.cs b/csharp/src/ProtocolBuffers.Test/MessageTest.cs
new file mode 100644
index 00000000..8bb0fac7
--- /dev/null
+++ b/csharp/src/ProtocolBuffers.Test/MessageTest.cs
@@ -0,0 +1,387 @@
+#region Copyright notice and license
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.IO;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Google.ProtocolBuffers
+{
+ /// <summary>
+ /// Miscellaneous tests for message operations that apply to both
+ /// generated and dynamic messages.
+ /// </summary>
+ [TestClass]
+ public class MessageTest
+ {
+ // =================================================================
+ // Message-merging tests.
+
+ private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder
+ {
+ OptionalInt32 = 1,
+ OptionalString = "foo",
+ OptionalForeignMessage =
+ ForeignMessage.DefaultInstance,
+ }.AddRepeatedString("bar").Build();
+
+ private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder
+ {
+ OptionalInt64 = 2,
+ OptionalString = "baz",
+ OptionalForeignMessage =
+ new ForeignMessage.Builder {C = 3}.Build(),
+ }.AddRepeatedString("qux").Build();
+
+ private const string MergeResultText =
+ "optional_int32: 1\n" +
+ "optional_int64: 2\n" +
+ "optional_string: \"foo\"\n" +
+ "optional_foreign_message {\n" +
+ " c: 3\n" +
+ "}\n" +
+ "repeated_string: \"qux\"\n" +
+ "repeated_string: \"bar\"\n";
+
+ [TestMethod]
+ public void MergeFrom()
+ {
+ TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();
+
+ Assert.AreEqual(MergeResultText, result.ToString());
+ }
+
+ /// <summary>
+ /// Test merging a DynamicMessage into a GeneratedMessage.
+ /// As long as they have the same descriptor, this should work, but it is an
+ /// entirely different code path.
+ /// </summary>
+ [TestMethod]
+ public void MergeFromDynamic()
+ {
+ TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
+ .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
+ .Build();
+
+ Assert.AreEqual(MergeResultText, result.ToString());
+ }
+
+ /// <summary>
+ /// Test merging two DynamicMessages.
+ /// </summary>
+ [TestMethod]
+ public void DynamicMergeFrom()
+ {
+ DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
+ .MergeFrom(
+ (DynamicMessage)
+ DynamicMessage.CreateBuilder(MergeSource).Build())
+ .Build();
+
+ Assert.AreEqual(MergeResultText, result.ToString());
+ }
+
+ // =================================================================
+ // Required-field-related tests.
+
+ private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
+
+ private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder
+ {
+ A = 1,
+ B = 2,
+ C = 3
+ }.Build();
+
+ [TestMethod]
+ public void Initialization()
+ {
+ TestRequired.Builder builder = TestRequired.CreateBuilder();
+
+ Assert.IsFalse(builder.IsInitialized);
+ builder.A = 1;
+ Assert.IsFalse(builder.IsInitialized);
+ builder.B = 1;
+ Assert.IsFalse(builder.IsInitialized);
+ builder.C = 1;
+ Assert.IsTrue(builder.IsInitialized);
+ }
+
+ [TestMethod]
+ public void UninitializedBuilderToString()
+ {
+ TestRequired.Builder builder = TestRequired.CreateBuilder().SetA(1);
+ Assert.AreEqual("a: 1\n", builder.ToString());
+ }
+
+ [TestMethod]
+ public void RequiredForeign()
+ {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
+
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder.SetOptionalMessage(TestRequiredUninitialized);
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder.SetOptionalMessage(TestRequiredInitialized);
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder.AddRepeatedMessage(TestRequiredUninitialized);
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder.SetRepeatedMessage(0, TestRequiredInitialized);
+ Assert.IsTrue(builder.IsInitialized);
+ }
+
+ [TestMethod]
+ public void RequiredExtension()
+ {
+ TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder.SetExtension(TestRequired.Single, TestRequiredUninitialized);
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder.SetExtension(TestRequired.Single, TestRequiredInitialized);
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder.AddExtension(TestRequired.Multi, TestRequiredUninitialized);
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder.SetExtension(TestRequired.Multi, 0, TestRequiredInitialized);
+ Assert.IsTrue(builder.IsInitialized);
+ }
+
+ [TestMethod]
+ public void RequiredDynamic()
+ {
+ MessageDescriptor descriptor = TestRequired.Descriptor;
+ DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
+
+ Assert.IsFalse(builder.IsInitialized);
+ builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
+ Assert.IsFalse(builder.IsInitialized);
+ builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
+ Assert.IsFalse(builder.IsInitialized);
+ builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
+ Assert.IsTrue(builder.IsInitialized);
+ }
+
+ [TestMethod]
+ public void RequiredDynamicForeign()
+ {
+ MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
+ DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
+
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
+ Assert.IsTrue(builder.IsInitialized);
+
+ builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"),
+ TestRequiredUninitialized);
+ Assert.IsFalse(builder.IsInitialized);
+
+ builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0,
+ TestRequiredInitialized);
+ Assert.IsTrue(builder.IsInitialized);
+ }
+
+ [TestMethod]
+ public void UninitializedException()
+ {
+ try
+ {
+ TestRequired.CreateBuilder().Build();
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (UninitializedMessageException e)
+ {
+ Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void BuildPartial()
+ {
+ // We're mostly testing that no exception is thrown.
+ TestRequired message = TestRequired.CreateBuilder().BuildPartial();
+ Assert.IsFalse(message.IsInitialized);
+ }
+
+ [TestMethod]
+ public void NestedUninitializedException()
+ {
+ try
+ {
+ TestRequiredForeign.CreateBuilder()
+ .SetOptionalMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .Build();
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (UninitializedMessageException e)
+ {
+ Assert.AreEqual(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void BuildNestedPartial()
+ {
+ // We're mostly testing that no exception is thrown.
+ TestRequiredForeign message =
+ TestRequiredForeign.CreateBuilder()
+ .SetOptionalMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .BuildPartial();
+ Assert.IsFalse(message.IsInitialized);
+ }
+
+ [TestMethod]
+ public void ParseUnititialized()
+ {
+ try
+ {
+ TestRequired.ParseFrom(ByteString.Empty);
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (InvalidProtocolBufferException e)
+ {
+ Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void ParseNestedUnititialized()
+ {
+ ByteString data =
+ TestRequiredForeign.CreateBuilder()
+ .SetOptionalMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .AddRepeatedMessage(TestRequiredUninitialized)
+ .BuildPartial().ToByteString();
+
+ try
+ {
+ TestRequiredForeign.ParseFrom(data);
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (InvalidProtocolBufferException e)
+ {
+ Assert.AreEqual(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void DynamicUninitializedException()
+ {
+ try
+ {
+ DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build();
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (UninitializedMessageException e)
+ {
+ Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void DynamicBuildPartial()
+ {
+ // We're mostly testing that no exception is thrown.
+ DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
+ Assert.IsFalse(message.Initialized);
+ }
+
+ [TestMethod]
+ public void DynamicParseUnititialized()
+ {
+ try
+ {
+ MessageDescriptor descriptor = TestRequired.Descriptor;
+ DynamicMessage.ParseFrom(descriptor, ByteString.Empty);
+ Assert.Fail("Should have thrown an exception.");
+ }
+ catch (InvalidProtocolBufferException e)
+ {
+ Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+ }
+ }
+
+ [TestMethod]
+ public void PackedTypesWrittenDirectlyToStream()
+ {
+ TestPackedTypes message = new TestPackedTypes.Builder {PackedInt32List = {0, 1, 2}}.Build();
+ MemoryStream stream = new MemoryStream();
+ message.WriteTo(stream);
+ stream.Position = 0;
+ TestPackedTypes readMessage = TestPackedTypes.ParseFrom(stream);
+ Assert.AreEqual(message, readMessage);
+ }
+ }
+} \ No newline at end of file