blob: 9d03656b1b7d68d2e90a1d62f36ffcc627ea9687 [file] [log] [blame]
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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 Google.Protobuf.TestProtos.Proto2;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
namespace Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message in unittest.proto
/// </summary>
public partial class GeneratedMessageTest
{
[Test]
public void DefaultProto2Values()
{
var message = new TestAllTypes();
Assert.AreEqual(false, message.OptionalBool);
Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
Assert.AreEqual(0.0, message.OptionalDouble);
Assert.AreEqual(0, message.OptionalFixed32);
Assert.AreEqual(0L, message.OptionalFixed64);
Assert.AreEqual(0.0f, message.OptionalFloat);
Assert.AreEqual(ForeignEnum.ForeignFoo, message.OptionalForeignEnum);
Assert.IsNull(message.OptionalForeignMessage);
Assert.AreEqual(ImportEnum.ImportFoo, message.OptionalImportEnum);
Assert.IsNull(message.OptionalImportMessage);
Assert.AreEqual(0, message.OptionalInt32);
Assert.AreEqual(0L, message.OptionalInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.OptionalNestedEnum);
Assert.IsNull(message.OptionalNestedMessage);
Assert.IsNull(message.OptionalPublicImportMessage);
Assert.AreEqual(0, message.OptionalSfixed32);
Assert.AreEqual(0L, message.OptionalSfixed64);
Assert.AreEqual(0, message.OptionalSint32);
Assert.AreEqual(0L, message.OptionalSint64);
Assert.AreEqual("", message.OptionalString);
Assert.AreEqual(0U, message.OptionalUint32);
Assert.AreEqual(0UL, message.OptionalUint64);
// Repeated fields
Assert.AreEqual(0, message.RepeatedBool.Count);
Assert.AreEqual(0, message.RepeatedBytes.Count);
Assert.AreEqual(0, message.RepeatedDouble.Count);
Assert.AreEqual(0, message.RepeatedFixed32.Count);
Assert.AreEqual(0, message.RepeatedFixed64.Count);
Assert.AreEqual(0, message.RepeatedFloat.Count);
Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
Assert.AreEqual(0, message.RepeatedImportEnum.Count);
Assert.AreEqual(0, message.RepeatedImportMessage.Count);
Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
Assert.AreEqual(0, message.RepeatedSfixed32.Count);
Assert.AreEqual(0, message.RepeatedSfixed64.Count);
Assert.AreEqual(0, message.RepeatedSint32.Count);
Assert.AreEqual(0, message.RepeatedSint64.Count);
Assert.AreEqual(0, message.RepeatedString.Count);
Assert.AreEqual(0, message.RepeatedUint32.Count);
Assert.AreEqual(0, message.RepeatedUint64.Count);
// Oneof fields
Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(true, message.DefaultBool);
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.DefaultBytes);
Assert.AreEqual("123", message.DefaultCord);
Assert.AreEqual(52e3, message.DefaultDouble);
Assert.AreEqual(47, message.DefaultFixed32);
Assert.AreEqual(48, message.DefaultFixed64);
Assert.AreEqual(51.5, message.DefaultFloat);
Assert.AreEqual(ForeignEnum.ForeignBar, message.DefaultForeignEnum);
Assert.AreEqual(ImportEnum.ImportBar, message.DefaultImportEnum);
Assert.AreEqual(41, message.DefaultInt32);
Assert.AreEqual(42, message.DefaultInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.DefaultNestedEnum);
Assert.AreEqual(49, message.DefaultSfixed32);
Assert.AreEqual(-50, message.DefaultSfixed64);
Assert.AreEqual(-45, message.DefaultSint32);
Assert.AreEqual(46, message.DefaultSint64);
Assert.AreEqual("hello", message.DefaultString);
Assert.AreEqual("abc", message.DefaultStringPiece);
Assert.AreEqual(43, message.DefaultUint32);
Assert.AreEqual(44, message.DefaultUint64);
Assert.False(message.HasDefaultBool);
Assert.False(message.HasDefaultBytes);
Assert.False(message.HasDefaultCord);
Assert.False(message.HasDefaultDouble);
Assert.False(message.HasDefaultFixed32);
Assert.False(message.HasDefaultFixed64);
Assert.False(message.HasDefaultFloat);
Assert.False(message.HasDefaultForeignEnum);
Assert.False(message.HasDefaultImportEnum);
Assert.False(message.HasDefaultInt32);
Assert.False(message.HasDefaultInt64);
Assert.False(message.HasDefaultNestedEnum);
Assert.False(message.HasDefaultSfixed32);
Assert.False(message.HasDefaultSfixed64);
Assert.False(message.HasDefaultSint32);
Assert.False(message.HasDefaultSint64);
Assert.False(message.HasDefaultString);
Assert.False(message.HasDefaultStringPiece);
Assert.False(message.HasDefaultUint32);
Assert.False(message.HasDefaultUint64);
}
[Test]
public void DefaultExtensionValues()
{
var message = new TestAllExtensions();
Assert.AreEqual(false, message.GetExtension(OptionalBoolExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OptionalBytesExtension));
Assert.AreEqual(0.0, message.GetExtension(OptionalDoubleExtension));
Assert.AreEqual(0, message.GetExtension(OptionalFixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalFixed64Extension));
Assert.AreEqual(0.0f, message.GetExtension(OptionalFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignFoo, message.GetExtension(OptionalForeignEnumExtension));
Assert.IsNull(message.GetExtension(OptionalForeignMessageExtension));
Assert.AreEqual(ImportEnum.ImportFoo, message.GetExtension(OptionalImportEnumExtension));
Assert.IsNull(message.GetExtension(OptionalImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalInt32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.GetExtension(OptionalNestedEnumExtension));
Assert.IsNull(message.GetExtension(OptionalNestedMessageExtension));
Assert.IsNull(message.GetExtension(OptionalPublicImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalSfixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSfixed64Extension));
Assert.AreEqual(0, message.GetExtension(OptionalSint32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSint64Extension));
Assert.AreEqual("", message.GetExtension(OptionalStringExtension));
Assert.AreEqual(0U, message.GetExtension(OptionalUint32Extension));
Assert.AreEqual(0UL, message.GetExtension(OptionalUint64Extension));
// Repeated fields
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
Assert.IsNull(message.GetExtension(RepeatedBytesExtension));
Assert.IsNull(message.GetExtension(RepeatedDoubleExtension));
Assert.IsNull(message.GetExtension(RepeatedFixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedFixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedFloatExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedImportEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedImportMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedSfixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedSfixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedSint32Extension));
Assert.IsNull(message.GetExtension(RepeatedSint64Extension));
Assert.IsNull(message.GetExtension(RepeatedStringExtension));
Assert.IsNull(message.GetExtension(RepeatedUint32Extension));
Assert.IsNull(message.GetExtension(RepeatedUint64Extension));
// Oneof fields
Assert.AreEqual(0, message.GetExtension(OneofUint32Extension));
Assert.AreEqual("", message.GetExtension(OneofStringExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OneofBytesExtension));
Assert.IsNull(message.GetExtension(OneofNestedMessageExtension));
Assert.AreEqual(true, message.GetExtension(DefaultBoolExtension));
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.GetExtension(DefaultBytesExtension));
Assert.AreEqual("123", message.GetExtension(DefaultCordExtension));
Assert.AreEqual(52e3, message.GetExtension(DefaultDoubleExtension));
Assert.AreEqual(47, message.GetExtension(DefaultFixed32Extension));
Assert.AreEqual(48, message.GetExtension(DefaultFixed64Extension));
Assert.AreEqual(51.5, message.GetExtension(DefaultFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignBar, message.GetExtension(DefaultForeignEnumExtension));
Assert.AreEqual(ImportEnum.ImportBar, message.GetExtension(DefaultImportEnumExtension));
Assert.AreEqual(41, message.GetExtension(DefaultInt32Extension));
Assert.AreEqual(42, message.GetExtension(DefaultInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.GetExtension(DefaultNestedEnumExtension));
Assert.AreEqual(49, message.GetExtension(DefaultSfixed32Extension));
Assert.AreEqual(-50, message.GetExtension(DefaultSfixed64Extension));
Assert.AreEqual(-45, message.GetExtension(DefaultSint32Extension));
Assert.AreEqual(46, message.GetExtension(DefaultSint64Extension));
Assert.AreEqual("hello", message.GetExtension(DefaultStringExtension));
Assert.AreEqual("abc", message.GetExtension(DefaultStringPieceExtension));
Assert.AreEqual(43, message.GetExtension(DefaultUint32Extension));
Assert.AreEqual(44, message.GetExtension(DefaultUint64Extension));
Assert.False(message.HasExtension(DefaultBoolExtension));
Assert.False(message.HasExtension(DefaultBytesExtension));
Assert.False(message.HasExtension(DefaultCordExtension));
Assert.False(message.HasExtension(DefaultDoubleExtension));
Assert.False(message.HasExtension(DefaultFixed32Extension));
Assert.False(message.HasExtension(DefaultFixed64Extension));
Assert.False(message.HasExtension(DefaultFloatExtension));
Assert.False(message.HasExtension(DefaultForeignEnumExtension));
Assert.False(message.HasExtension(DefaultImportEnumExtension));
Assert.False(message.HasExtension(DefaultInt32Extension));
Assert.False(message.HasExtension(DefaultInt64Extension));
Assert.False(message.HasExtension(DefaultNestedEnumExtension));
Assert.False(message.HasExtension(DefaultSfixed32Extension));
Assert.False(message.HasExtension(DefaultSfixed64Extension));
Assert.False(message.HasExtension(DefaultSint32Extension));
Assert.False(message.HasExtension(DefaultSint64Extension));
Assert.False(message.HasExtension(DefaultStringExtension));
Assert.False(message.HasExtension(DefaultStringPieceExtension));
Assert.False(message.HasExtension(DefaultUint32Extension));
Assert.False(message.HasExtension(DefaultUint64Extension));
}
[Test]
public void FieldPresence()
{
var message = new TestAllTypes();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.OptionalBool = true;
Assert.True(message.HasOptionalBool);
Assert.True(message.OptionalBool);
message.OptionalBool = false;
Assert.True(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.ClearOptionalBool();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.DefaultBool = false;
Assert.True(message.HasDefaultBool);
Assert.False(message.DefaultBool);
message.DefaultBool = true;
Assert.True(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.ClearDefaultBool();
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
}
[Test]
public void RequiredFields()
{
var message = new TestRequired();
Assert.False(message.IsInitialized());
message.A = 1;
message.B = 2;
message.C = 3;
Assert.True(message.IsInitialized());
}
/// <summary>
/// Code was accidentally left in message parser that threw exceptions when missing required fields after parsing.
/// We've decided to not throw exceptions on missing fields, instead leaving it up to the consumer how they
/// want to check and handle missing fields.
/// </summary>
[Test]
public void RequiredFieldsNoThrow()
{
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { }));
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { }));
}
[Test]
public void RequiredFieldsInExtensions()
{
var message = new TestAllExtensions();
Assert.True(message.IsInitialized());
message.SetExtension(TestRequired.Extensions.Single, new TestRequired());
Assert.False(message.IsInitialized());
var extensionMessage = message.GetExtension(TestRequired.Extensions.Single);
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(TestRequired.Extensions.Multi);
Assert.True(message.IsInitialized());
message.GetExtension(TestRequired.Extensions.Multi).Add(new TestRequired());
Assert.False(message.IsInitialized());
extensionMessage = message.GetExtension(TestRequired.Extensions.Multi)[0];
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(UnittestExtensions.RepeatedBoolExtension).Add(true);
Assert.True(message.IsInitialized());
}
[Test]
public void RequiredFieldInNestedMessageMapValue()
{
var message = new TestRequiredMap();
message.Foo.Add(0, new TestRequiredMap.Types.NestedMessage());
Assert.False(message.IsInitialized());
message.Foo[0].RequiredInt32 = 12;
Assert.True(message.IsInitialized());
}
[Test]
public void RoundTrip_Groups()
{
var message = new TestAllTypes
{
OptionalGroup = new TestAllTypes.Types.OptionalGroup
{
A = 10
},
RepeatedGroup =
{
new TestAllTypes.Types.RepeatedGroup { A = 10 },
new TestAllTypes.Types.RepeatedGroup { A = 20 },
new TestAllTypes.Types.RepeatedGroup { A = 30 }
}
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);
}
[Test]
public void RoundTrip_ExtensionGroups()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension { A = 10 });
message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
{
new RepeatedGroup_extension { A = 10 },
new RepeatedGroup_extension { A = 20 },
new RepeatedGroup_extension { A = 30 }
});
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }),
message);
}
[Test]
public void RoundTrip_NestedExtensionGroup()
{
var message = new TestGroupExtension();
message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }),
message);
}
[Test]
public void RoundTrip_ParseUsingCodedInput()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
byte[] bytes = message.ToByteArray();
using CodedInputStream input = new CodedInputStream(bytes);
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
Assert.AreEqual(message, parsed);
}
}
}