aboutsummaryrefslogblamecommitdiff
path: root/csharp/ProtocolBuffers.Test/MessageTest.cs
blob: d206e78f93faf001781a68bb90324728792a0bd5 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                                                           
























































                                                                                                 




                                         




















































                                                                                                  
                                                                           

                                            
                                                                         

                                           
                                                                          

                                            
                                                                           





























                                                                                                          
                                                                                                                          














































































































                                                                                                                           
                                                                                                    















                                                                               
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework;

namespace Google.ProtocolBuffers {
  /// <summary>
  /// Miscellaneous tests for message operations that apply to both
  /// generated and dynamic messages.
  /// </summary>
  [TestFixture]
  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";

    [Test]
    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>
    [Test]
    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>
    [Test]
    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();

    [Test]
    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);
    }

    [Test]
    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);
    }

    [Test]
    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);
    }

    [Test]
    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);
    }

    [Test]
    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);
    }

    [Test]
    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);
      }
    }

    [Test]
    public void BuildPartial() {
      // We're mostly testing that no exception is thrown.
      TestRequired message = TestRequired.CreateBuilder().BuildPartial();
      Assert.IsFalse(message.IsInitialized);
    }

    [Test]
    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);
      }
    }

    [Test]
    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);
    }

    [Test]
    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);
      }
    }

    [Test]
    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);
      }
    }

    [Test]
    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);
      }
    }

    [Test]
    public void DynamicBuildPartial() {
      // We're mostly testing that no exception is thrown.
      DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
      Assert.IsFalse(message.Initialized);
    }

    [Test]
    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);
      }
    }
  }

}