1 #region Copyright notice and license 2 // Protocol Buffers - Google's data interchange format 3 // Copyright 2015 Google Inc. All rights reserved. 4 // 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file or at 7 // https://developers.google.com/open-source/licenses/bsd 8 #endregion 9 10 using Google.Protobuf.TestProtos.Proto2; 11 using Proto2 = Google.Protobuf.TestProtos.Proto2; 12 using NUnit.Framework; 13 14 using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions; 15 16 namespace Google.Protobuf 17 { 18 /// <summary> 19 /// Tests around the generated TestAllTypes message in unittest.proto 20 /// </summary> 21 public partial class GeneratedMessageTest 22 { 23 [Test] DefaultProto2Values()24 public void DefaultProto2Values() 25 { 26 var message = new TestAllTypes(); 27 Assert.AreEqual(false, message.OptionalBool); 28 Assert.AreEqual(ByteString.Empty, message.OptionalBytes); 29 Assert.AreEqual(0.0, message.OptionalDouble); 30 Assert.AreEqual(0, message.OptionalFixed32); 31 Assert.AreEqual(0L, message.OptionalFixed64); 32 Assert.AreEqual(0.0f, message.OptionalFloat); 33 Assert.AreEqual(ForeignEnum.ForeignFoo, message.OptionalForeignEnum); 34 Assert.IsNull(message.OptionalForeignMessage); 35 Assert.AreEqual(ImportEnum.ImportFoo, message.OptionalImportEnum); 36 Assert.IsNull(message.OptionalImportMessage); 37 Assert.AreEqual(0, message.OptionalInt32); 38 Assert.AreEqual(0L, message.OptionalInt64); 39 Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.OptionalNestedEnum); 40 Assert.IsNull(message.OptionalNestedMessage); 41 Assert.IsNull(message.OptionalPublicImportMessage); 42 Assert.AreEqual(0, message.OptionalSfixed32); 43 Assert.AreEqual(0L, message.OptionalSfixed64); 44 Assert.AreEqual(0, message.OptionalSint32); 45 Assert.AreEqual(0L, message.OptionalSint64); 46 Assert.AreEqual("", message.OptionalString); 47 Assert.AreEqual(0U, message.OptionalUint32); 48 Assert.AreEqual(0UL, message.OptionalUint64); 49 50 // Repeated fields 51 Assert.AreEqual(0, message.RepeatedBool.Count); 52 Assert.AreEqual(0, message.RepeatedBytes.Count); 53 Assert.AreEqual(0, message.RepeatedDouble.Count); 54 Assert.AreEqual(0, message.RepeatedFixed32.Count); 55 Assert.AreEqual(0, message.RepeatedFixed64.Count); 56 Assert.AreEqual(0, message.RepeatedFloat.Count); 57 Assert.AreEqual(0, message.RepeatedForeignEnum.Count); 58 Assert.AreEqual(0, message.RepeatedForeignMessage.Count); 59 Assert.AreEqual(0, message.RepeatedImportEnum.Count); 60 Assert.AreEqual(0, message.RepeatedImportMessage.Count); 61 Assert.AreEqual(0, message.RepeatedNestedEnum.Count); 62 Assert.AreEqual(0, message.RepeatedNestedMessage.Count); 63 Assert.AreEqual(0, message.RepeatedSfixed32.Count); 64 Assert.AreEqual(0, message.RepeatedSfixed64.Count); 65 Assert.AreEqual(0, message.RepeatedSint32.Count); 66 Assert.AreEqual(0, message.RepeatedSint64.Count); 67 Assert.AreEqual(0, message.RepeatedString.Count); 68 Assert.AreEqual(0, message.RepeatedUint32.Count); 69 Assert.AreEqual(0, message.RepeatedUint64.Count); 70 71 // Oneof fields 72 Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); 73 Assert.AreEqual(0, message.OneofUint32); 74 Assert.AreEqual("", message.OneofString); 75 Assert.AreEqual(ByteString.Empty, message.OneofBytes); 76 Assert.IsNull(message.OneofNestedMessage); 77 78 Assert.AreEqual(true, message.DefaultBool); 79 Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.DefaultBytes); 80 Assert.AreEqual("123", message.DefaultCord); 81 Assert.AreEqual(52e3, message.DefaultDouble); 82 Assert.AreEqual(47, message.DefaultFixed32); 83 Assert.AreEqual(48, message.DefaultFixed64); 84 Assert.AreEqual(51.5, message.DefaultFloat); 85 Assert.AreEqual(ForeignEnum.ForeignBar, message.DefaultForeignEnum); 86 Assert.AreEqual(ImportEnum.ImportBar, message.DefaultImportEnum); 87 Assert.AreEqual(41, message.DefaultInt32); 88 Assert.AreEqual(42, message.DefaultInt64); 89 Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.DefaultNestedEnum); 90 Assert.AreEqual(49, message.DefaultSfixed32); 91 Assert.AreEqual(-50, message.DefaultSfixed64); 92 Assert.AreEqual(-45, message.DefaultSint32); 93 Assert.AreEqual(46, message.DefaultSint64); 94 Assert.AreEqual("hello", message.DefaultString); 95 Assert.AreEqual("abc", message.DefaultStringPiece); 96 Assert.AreEqual(43, message.DefaultUint32); 97 Assert.AreEqual(44, message.DefaultUint64); 98 99 Assert.False(message.HasDefaultBool); 100 Assert.False(message.HasDefaultBytes); 101 Assert.False(message.HasDefaultCord); 102 Assert.False(message.HasDefaultDouble); 103 Assert.False(message.HasDefaultFixed32); 104 Assert.False(message.HasDefaultFixed64); 105 Assert.False(message.HasDefaultFloat); 106 Assert.False(message.HasDefaultForeignEnum); 107 Assert.False(message.HasDefaultImportEnum); 108 Assert.False(message.HasDefaultInt32); 109 Assert.False(message.HasDefaultInt64); 110 Assert.False(message.HasDefaultNestedEnum); 111 Assert.False(message.HasDefaultSfixed32); 112 Assert.False(message.HasDefaultSfixed64); 113 Assert.False(message.HasDefaultSint32); 114 Assert.False(message.HasDefaultSint64); 115 Assert.False(message.HasDefaultString); 116 Assert.False(message.HasDefaultStringPiece); 117 Assert.False(message.HasDefaultUint32); 118 Assert.False(message.HasDefaultUint64); 119 } 120 121 [Test] DefaultExtensionValues()122 public void DefaultExtensionValues() 123 { 124 var message = new TestAllExtensions(); 125 Assert.AreEqual(false, message.GetExtension(OptionalBoolExtension)); 126 Assert.AreEqual(ByteString.Empty, message.GetExtension(OptionalBytesExtension)); 127 Assert.AreEqual(0.0, message.GetExtension(OptionalDoubleExtension)); 128 Assert.AreEqual(0, message.GetExtension(OptionalFixed32Extension)); 129 Assert.AreEqual(0L, message.GetExtension(OptionalFixed64Extension)); 130 Assert.AreEqual(0.0f, message.GetExtension(OptionalFloatExtension)); 131 Assert.AreEqual(ForeignEnum.ForeignFoo, message.GetExtension(OptionalForeignEnumExtension)); 132 Assert.IsNull(message.GetExtension(OptionalForeignMessageExtension)); 133 Assert.AreEqual(ImportEnum.ImportFoo, message.GetExtension(OptionalImportEnumExtension)); 134 Assert.IsNull(message.GetExtension(OptionalImportMessageExtension)); 135 Assert.AreEqual(0, message.GetExtension(OptionalInt32Extension)); 136 Assert.AreEqual(0L, message.GetExtension(OptionalInt64Extension)); 137 Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.GetExtension(OptionalNestedEnumExtension)); 138 Assert.IsNull(message.GetExtension(OptionalNestedMessageExtension)); 139 Assert.IsNull(message.GetExtension(OptionalPublicImportMessageExtension)); 140 Assert.AreEqual(0, message.GetExtension(OptionalSfixed32Extension)); 141 Assert.AreEqual(0L, message.GetExtension(OptionalSfixed64Extension)); 142 Assert.AreEqual(0, message.GetExtension(OptionalSint32Extension)); 143 Assert.AreEqual(0L, message.GetExtension(OptionalSint64Extension)); 144 Assert.AreEqual("", message.GetExtension(OptionalStringExtension)); 145 Assert.AreEqual(0U, message.GetExtension(OptionalUint32Extension)); 146 Assert.AreEqual(0UL, message.GetExtension(OptionalUint64Extension)); 147 148 // Repeated fields 149 Assert.IsNull(message.GetExtension(RepeatedBoolExtension)); 150 Assert.IsNull(message.GetExtension(RepeatedBytesExtension)); 151 Assert.IsNull(message.GetExtension(RepeatedDoubleExtension)); 152 Assert.IsNull(message.GetExtension(RepeatedFixed32Extension)); 153 Assert.IsNull(message.GetExtension(RepeatedFixed64Extension)); 154 Assert.IsNull(message.GetExtension(RepeatedFloatExtension)); 155 Assert.IsNull(message.GetExtension(RepeatedForeignEnumExtension)); 156 Assert.IsNull(message.GetExtension(RepeatedForeignMessageExtension)); 157 Assert.IsNull(message.GetExtension(RepeatedImportEnumExtension)); 158 Assert.IsNull(message.GetExtension(RepeatedImportMessageExtension)); 159 Assert.IsNull(message.GetExtension(RepeatedNestedEnumExtension)); 160 Assert.IsNull(message.GetExtension(RepeatedNestedMessageExtension)); 161 Assert.IsNull(message.GetExtension(RepeatedSfixed32Extension)); 162 Assert.IsNull(message.GetExtension(RepeatedSfixed64Extension)); 163 Assert.IsNull(message.GetExtension(RepeatedSint32Extension)); 164 Assert.IsNull(message.GetExtension(RepeatedSint64Extension)); 165 Assert.IsNull(message.GetExtension(RepeatedStringExtension)); 166 Assert.IsNull(message.GetExtension(RepeatedUint32Extension)); 167 Assert.IsNull(message.GetExtension(RepeatedUint64Extension)); 168 169 // Oneof fields 170 Assert.AreEqual(0, message.GetExtension(OneofUint32Extension)); 171 Assert.AreEqual("", message.GetExtension(OneofStringExtension)); 172 Assert.AreEqual(ByteString.Empty, message.GetExtension(OneofBytesExtension)); 173 Assert.IsNull(message.GetExtension(OneofNestedMessageExtension)); 174 175 Assert.AreEqual(true, message.GetExtension(DefaultBoolExtension)); 176 Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.GetExtension(DefaultBytesExtension)); 177 Assert.AreEqual("123", message.GetExtension(DefaultCordExtension)); 178 Assert.AreEqual(52e3, message.GetExtension(DefaultDoubleExtension)); 179 Assert.AreEqual(47, message.GetExtension(DefaultFixed32Extension)); 180 Assert.AreEqual(48, message.GetExtension(DefaultFixed64Extension)); 181 Assert.AreEqual(51.5, message.GetExtension(DefaultFloatExtension)); 182 Assert.AreEqual(ForeignEnum.ForeignBar, message.GetExtension(DefaultForeignEnumExtension)); 183 Assert.AreEqual(ImportEnum.ImportBar, message.GetExtension(DefaultImportEnumExtension)); 184 Assert.AreEqual(41, message.GetExtension(DefaultInt32Extension)); 185 Assert.AreEqual(42, message.GetExtension(DefaultInt64Extension)); 186 Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.GetExtension(DefaultNestedEnumExtension)); 187 Assert.AreEqual(49, message.GetExtension(DefaultSfixed32Extension)); 188 Assert.AreEqual(-50, message.GetExtension(DefaultSfixed64Extension)); 189 Assert.AreEqual(-45, message.GetExtension(DefaultSint32Extension)); 190 Assert.AreEqual(46, message.GetExtension(DefaultSint64Extension)); 191 Assert.AreEqual("hello", message.GetExtension(DefaultStringExtension)); 192 Assert.AreEqual("abc", message.GetExtension(DefaultStringPieceExtension)); 193 Assert.AreEqual(43, message.GetExtension(DefaultUint32Extension)); 194 Assert.AreEqual(44, message.GetExtension(DefaultUint64Extension)); 195 196 Assert.False(message.HasExtension(DefaultBoolExtension)); 197 Assert.False(message.HasExtension(DefaultBytesExtension)); 198 Assert.False(message.HasExtension(DefaultCordExtension)); 199 Assert.False(message.HasExtension(DefaultDoubleExtension)); 200 Assert.False(message.HasExtension(DefaultFixed32Extension)); 201 Assert.False(message.HasExtension(DefaultFixed64Extension)); 202 Assert.False(message.HasExtension(DefaultFloatExtension)); 203 Assert.False(message.HasExtension(DefaultForeignEnumExtension)); 204 Assert.False(message.HasExtension(DefaultImportEnumExtension)); 205 Assert.False(message.HasExtension(DefaultInt32Extension)); 206 Assert.False(message.HasExtension(DefaultInt64Extension)); 207 Assert.False(message.HasExtension(DefaultNestedEnumExtension)); 208 Assert.False(message.HasExtension(DefaultSfixed32Extension)); 209 Assert.False(message.HasExtension(DefaultSfixed64Extension)); 210 Assert.False(message.HasExtension(DefaultSint32Extension)); 211 Assert.False(message.HasExtension(DefaultSint64Extension)); 212 Assert.False(message.HasExtension(DefaultStringExtension)); 213 Assert.False(message.HasExtension(DefaultStringPieceExtension)); 214 Assert.False(message.HasExtension(DefaultUint32Extension)); 215 Assert.False(message.HasExtension(DefaultUint64Extension)); 216 } 217 218 [Test] FieldPresence()219 public void FieldPresence() 220 { 221 var message = new TestAllTypes(); 222 223 Assert.False(message.HasOptionalBool); 224 Assert.False(message.OptionalBool); 225 226 message.OptionalBool = true; 227 228 Assert.True(message.HasOptionalBool); 229 Assert.True(message.OptionalBool); 230 231 message.OptionalBool = false; 232 233 Assert.True(message.HasOptionalBool); 234 Assert.False(message.OptionalBool); 235 236 message.ClearOptionalBool(); 237 238 Assert.False(message.HasOptionalBool); 239 Assert.False(message.OptionalBool); 240 241 Assert.False(message.HasDefaultBool); 242 Assert.True(message.DefaultBool); 243 244 message.DefaultBool = false; 245 246 Assert.True(message.HasDefaultBool); 247 Assert.False(message.DefaultBool); 248 249 message.DefaultBool = true; 250 251 Assert.True(message.HasDefaultBool); 252 Assert.True(message.DefaultBool); 253 254 message.ClearDefaultBool(); 255 256 Assert.False(message.HasDefaultBool); 257 Assert.True(message.DefaultBool); 258 } 259 260 [Test] RequiredFields()261 public void RequiredFields() 262 { 263 var message = new TestRequired(); 264 Assert.False(message.IsInitialized()); 265 266 message.A = 1; 267 message.B = 2; 268 message.C = 3; 269 270 Assert.True(message.IsInitialized()); 271 } 272 273 /// <summary> 274 /// Code was accidentally left in message parser that threw exceptions when missing required fields after parsing. 275 /// We've decided to not throw exceptions on missing fields, instead leaving it up to the consumer how they 276 /// want to check and handle missing fields. 277 /// </summary> 278 [Test] RequiredFieldsNoThrow()279 public void RequiredFieldsNoThrow() 280 { 281 Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { })); 282 Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { })); 283 } 284 285 [Test] RequiredFieldsInExtensions()286 public void RequiredFieldsInExtensions() 287 { 288 var message = new TestAllExtensions(); 289 Assert.True(message.IsInitialized()); 290 291 message.SetExtension(TestRequired.Extensions.Single, new TestRequired()); 292 293 Assert.False(message.IsInitialized()); 294 295 var extensionMessage = message.GetExtension(TestRequired.Extensions.Single); 296 extensionMessage.A = 1; 297 extensionMessage.B = 2; 298 extensionMessage.C = 3; 299 300 Assert.True(message.IsInitialized()); 301 302 message.GetOrInitializeExtension(TestRequired.Extensions.Multi); 303 304 Assert.True(message.IsInitialized()); 305 306 message.GetExtension(TestRequired.Extensions.Multi).Add(new TestRequired()); 307 308 Assert.False(message.IsInitialized()); 309 310 extensionMessage = message.GetExtension(TestRequired.Extensions.Multi)[0]; 311 extensionMessage.A = 1; 312 extensionMessage.B = 2; 313 extensionMessage.C = 3; 314 315 Assert.True(message.IsInitialized()); 316 317 message.SetExtension(UnittestExtensions.OptionalBoolExtension, true); 318 319 Assert.True(message.IsInitialized()); 320 321 message.GetOrInitializeExtension(UnittestExtensions.RepeatedBoolExtension).Add(true); 322 323 Assert.True(message.IsInitialized()); 324 } 325 326 [Test] RequiredFieldInNestedMessageMapValue()327 public void RequiredFieldInNestedMessageMapValue() 328 { 329 var message = new TestRequiredMap(); 330 message.Foo.Add(0, new TestRequiredMap.Types.NestedMessage()); 331 332 Assert.False(message.IsInitialized()); 333 334 message.Foo[0].RequiredInt32 = 12; 335 336 Assert.True(message.IsInitialized()); 337 } 338 339 [Test] RoundTrip_Groups()340 public void RoundTrip_Groups() 341 { 342 var message = new TestAllTypes 343 { 344 OptionalGroup = new TestAllTypes.Types.OptionalGroup 345 { 346 A = 10 347 }, 348 RepeatedGroup = 349 { 350 new TestAllTypes.Types.RepeatedGroup { A = 10 }, 351 new TestAllTypes.Types.RepeatedGroup { A = 20 }, 352 new TestAllTypes.Types.RepeatedGroup { A = 30 } 353 } 354 }; 355 356 MessageParsingHelpers.AssertWritingMessage(message); 357 358 MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message); 359 } 360 361 [Test] RoundTrip_ExtensionGroups()362 public void RoundTrip_ExtensionGroups() 363 { 364 var message = new TestAllExtensions(); 365 message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension { A = 10 }); 366 message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[] 367 { 368 new RepeatedGroup_extension { A = 10 }, 369 new RepeatedGroup_extension { A = 20 }, 370 new RepeatedGroup_extension { A = 30 } 371 }); 372 373 MessageParsingHelpers.AssertWritingMessage(message); 374 375 MessageParsingHelpers.AssertRoundtrip( 376 TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }), 377 message); 378 } 379 380 [Test] RoundTrip_NestedExtensionGroup()381 public void RoundTrip_NestedExtensionGroup() 382 { 383 var message = new TestGroupExtension(); 384 message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 }); 385 386 MessageParsingHelpers.AssertWritingMessage(message); 387 388 MessageParsingHelpers.AssertRoundtrip( 389 TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }), 390 message); 391 } 392 393 [Test] RoundTrip_ParseUsingCodedInput()394 public void RoundTrip_ParseUsingCodedInput() 395 { 396 var message = new TestAllExtensions(); 397 message.SetExtension(UnittestExtensions.OptionalBoolExtension, true); 398 byte[] bytes = message.ToByteArray(); 399 using CodedInputStream input = new CodedInputStream(bytes); 400 var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input); 401 Assert.AreEqual(message, parsed); 402 } 403 } 404 } 405