using System; using System.Configuration; using System.IO; using Google.Protobuf.TestProtos; using NUnit.Framework; namespace Google.Protobuf { /// /// Tests around the generated TestAllTypes message. /// public class GeneratedMessageTest { [Test] public void EmptyMessageFieldDistinctFromMissingMessageField() { // This demonstrates what we're really interested in... var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() }; var message2 = new TestAllTypes(); // SingleForeignMessage is null EqualityTester.AssertInequality(message1, message2); } [Test] public void DefaultValues() { // Single fields var message = new TestAllTypes(); Assert.AreEqual(false, message.SingleBool); Assert.AreEqual(ByteString.Empty, message.SingleBytes); Assert.AreEqual(0.0, message.SingleDouble); Assert.AreEqual(0, message.SingleFixed32); Assert.AreEqual(0L, message.SingleFixed64); Assert.AreEqual(0.0f, message.SingleFloat); Assert.AreEqual(ForeignEnum.FOREIGN_UNSPECIFIED, message.SingleForeignEnum); Assert.IsNull(message.SingleForeignMessage); Assert.AreEqual(ImportEnum.IMPORT_ENUM_UNSPECIFIED, message.SingleImportEnum); Assert.IsNull(message.SingleImportMessage); Assert.AreEqual(0, message.SingleInt32); Assert.AreEqual(0L, message.SingleInt64); Assert.AreEqual(TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED, message.SingleNestedEnum); Assert.IsNull(message.SingleNestedMessage); Assert.IsNull(message.SinglePublicImportMessage); Assert.AreEqual(0, message.SingleSfixed32); Assert.AreEqual(0L, message.SingleSfixed64); Assert.AreEqual(0, message.SingleSint32); Assert.AreEqual(0L, message.SingleSint64); Assert.AreEqual("", message.SingleString); Assert.AreEqual(0U, message.SingleUint32); Assert.AreEqual(0UL, message.SingleUint64); // 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.RepeatedPublicImportMessage.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(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); Assert.AreEqual(0, message.OneofUint32); Assert.AreEqual("", message.OneofString); Assert.AreEqual(ByteString.Empty, message.OneofBytes); Assert.IsNull(message.OneofNestedMessage); } [Test] public void RoundTrip_Empty() { var message = new TestAllTypes(); // Without setting any values, there's nothing to write. byte[] bytes = message.ToByteArray(); Assert.AreEqual(0, bytes.Length); TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(message, parsed); } [Test] public void RoundTrip_SingleValues() { var message = new TestAllTypes { SingleBool = true, SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), SingleDouble = 23.5, SingleFixed32 = 23, SingleFixed64 = 1234567890123, SingleFloat = 12.25f, SingleForeignEnum = ForeignEnum.FOREIGN_BAR, SingleForeignMessage = new ForeignMessage { C = 10 }, SingleImportEnum = ImportEnum.IMPORT_BAZ, SingleImportMessage = new ImportMessage { D = 20 }, SingleInt32 = 100, SingleInt64 = 3210987654321, SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 }, SinglePublicImportMessage = new PublicImportMessage { E = 54 }, SingleSfixed32 = -123, SingleSfixed64 = -12345678901234, SingleSint32 = -456, SingleSint64 = -12345678901235, SingleString = "test", SingleUint32 = uint.MaxValue, SingleUint64 = ulong.MaxValue }; byte[] bytes = message.ToByteArray(); TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(message, parsed); } [Test] public void RoundTrip_RepeatedValues() { var message = new TestAllTypes { RepeatedBool = { true, false }, RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) }, RepeatedDouble = { -12.25, 23.5 }, RepeatedFixed32 = { uint.MaxValue, 23 }, RepeatedFixed64 = { ulong.MaxValue, 1234567890123 }, RepeatedFloat = { 100f, 12.25f }, RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR }, RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } }, RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED }, RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } }, RepeatedInt32 = { 100, 200 }, RepeatedInt64 = { 3210987654321, long.MaxValue }, RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG }, RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } }, RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } }, RepeatedSfixed32 = { -123, 123 }, RepeatedSfixed64 = { -12345678901234, 12345678901234 }, RepeatedSint32 = { -456, 100 }, RepeatedSint64 = { -12345678901235, 123 }, RepeatedString = { "foo", "bar" }, RepeatedUint32 = { uint.MaxValue, uint.MinValue }, RepeatedUint64 = { ulong.MaxValue, uint.MinValue } }; byte[] bytes = message.ToByteArray(); TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(message, parsed); } [Test] public void RoundTrip_Maps() { var message = new TestAllTypes { MapBoolToEnum = { { false, TestAllTypes.Types.NestedEnum.BAR}, { true, TestAllTypes.Types.NestedEnum.BAZ} }, MapInt32ToBytes = { { 5, ByteString.CopyFrom(6, 7, 8) }, { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) }, { 10, ByteString.Empty } }, MapStringToNestedMessage = { { "", new TestAllTypes.Types.NestedMessage { Bb = 10 } }, { "null value", null }, } }; byte[] bytes = message.ToByteArray(); TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(message, parsed); } [Test] public void MapWithEmptyEntry() { var message = new TestAllTypes { MapInt32ToBytes = { { 0, ByteString.Empty } } }; byte[] bytes = message.ToByteArray(); Assert.AreEqual(3, bytes.Length); // Tag for field entry (2 bytes), length of entry (0; 1 byte) var parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(1, parsed.MapInt32ToBytes.Count); Assert.AreEqual(ByteString.Empty, parsed.MapInt32ToBytes[0]); } [Test] public void MapWithOnlyValue() { // Hand-craft the stream to contain a single entry with just a value. var memoryStream = new MemoryStream(); var output = CodedOutputStream.CreateInstance(memoryStream); output.WriteTag(TestAllTypes.MapStringToNestedMessageFieldNumber, WireFormat.WireType.LengthDelimited); var nestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }; // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage) output.WriteRawVarint32((uint)(nestedMessage.CalculateSize() + 3)); output.WriteTag(2, WireFormat.WireType.LengthDelimited); output.WriteMessage(nestedMessage); output.Flush(); var parsed = TestAllTypes.Parser.ParseFrom(memoryStream.ToArray()); Assert.AreEqual(nestedMessage, parsed.MapStringToNestedMessage[""]); } [Test] public void CloneSingleNonMessageValues() { var original = new TestAllTypes { SingleBool = true, SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), SingleDouble = 23.5, SingleFixed32 = 23, SingleFixed64 = 1234567890123, SingleFloat = 12.25f, SingleInt32 = 100, SingleInt64 = 3210987654321, SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO, SingleSfixed32 = -123, SingleSfixed64 = -12345678901234, SingleSint32 = -456, SingleSint64 = -12345678901235, SingleString = "test", SingleUint32 = uint.MaxValue, SingleUint64 = ulong.MaxValue }; var clone = original.Clone(); Assert.AreNotSame(original, clone); Assert.AreEqual(original, clone); // Just as a single example clone.SingleInt32 = 150; Assert.AreNotEqual(original, clone); } [Test] public void CloneRepeatedNonMessageValues() { var original = new TestAllTypes { RepeatedBool = { true, false }, RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) }, RepeatedDouble = { -12.25, 23.5 }, RepeatedFixed32 = { uint.MaxValue, 23 }, RepeatedFixed64 = { ulong.MaxValue, 1234567890123 }, RepeatedFloat = { 100f, 12.25f }, RepeatedInt32 = { 100, 200 }, RepeatedInt64 = { 3210987654321, long.MaxValue }, RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG }, RepeatedSfixed32 = { -123, 123 }, RepeatedSfixed64 = { -12345678901234, 12345678901234 }, RepeatedSint32 = { -456, 100 }, RepeatedSint64 = { -12345678901235, 123 }, RepeatedString = { "foo", "bar" }, RepeatedUint32 = { uint.MaxValue, uint.MinValue }, RepeatedUint64 = { ulong.MaxValue, uint.MinValue } }; var clone = original.Clone(); Assert.AreNotSame(original, clone); Assert.AreEqual(original, clone); // Just as a single example clone.RepeatedDouble.Add(25.5); Assert.AreNotEqual(original, clone); } [Test] public void CloneSingleMessageField() { var original = new TestAllTypes { SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } }; var clone = original.Clone(); Assert.AreNotSame(original, clone); Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage); Assert.AreEqual(original, clone); clone.SingleNestedMessage.Bb = 30; Assert.AreNotEqual(original, clone); } [Test] public void CloneRepeatedMessageField() { var original = new TestAllTypes { RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } } }; var clone = original.Clone(); Assert.AreNotSame(original, clone); Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage); Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]); Assert.AreEqual(original, clone); clone.RepeatedNestedMessage[0].Bb = 30; Assert.AreNotEqual(original, clone); } [Test] public void CloneOneofField() { var original = new TestAllTypes { OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } }; var clone = original.Clone(); Assert.AreNotSame(original, clone); Assert.AreEqual(original, clone); // We should have cloned the message original.OneofNestedMessage.Bb = 30; Assert.AreNotEqual(original, clone); } [Test] public void Freeze() { var frozen = new TestAllTypes(); frozen.Freeze(); Assert.IsTrue(frozen.IsFrozen); Assert.Throws(() => frozen.ClearOneofField()); Assert.Throws(() => frozen.SingleInt32 = 0); Assert.Throws(() => frozen.SingleNestedMessage = null); Assert.Throws(() => frozen.SingleNestedEnum = 0); Assert.Throws(() => frozen.OneofString = null); Assert.Throws(() => frozen.OneofUint32 = 0U); Assert.Throws(() => frozen.RepeatedDouble.Add(0.0)); Assert.Throws(() => frozen.RepeatedNestedMessage.Add(new TestAllTypes.Types.NestedMessage())); } } }