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