blob: 610078f2d4157e6421ad40fcb2a3bdf59dafd8ce [file] [log] [blame]
Jon Skeet60c059b2008-10-23 21:17:56 +01001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// http://github.com/jskeet/dotnet-protobufs/
4// Original C++/Java/Python code:
Jon Skeet68036862008-10-22 13:30:34 +01005// http://code.google.com/p/protobuf/
6//
Jon Skeet60c059b2008-10-23 21:17:56 +01007// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
Jon Skeet68036862008-10-22 13:30:34 +010010//
Jon Skeet60c059b2008-10-23 21:17:56 +010011// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
Jon Skeet68036862008-10-22 13:30:34 +010020//
Jon Skeet60c059b2008-10-23 21:17:56 +010021// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jon Skeet68036862008-10-22 13:30:34 +010032using System;
33using System.Collections.Generic;
34using Google.ProtocolBuffers.Descriptors;
35using Google.ProtocolBuffers.TestProtos;
36using NUnit.Framework;
37
38namespace Google.ProtocolBuffers {
39 [TestFixture]
40 public class GeneratedMessageTest {
41 ReflectionTester reflectionTester;
42 ReflectionTester extensionsReflectionTester;
43
44 [SetUp]
45 public void SetUp() {
46 reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
47 extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
48 }
49
50 [Test]
51 public void RepeatedAddPrimitiveBeforeBuild() {
52 TestAllTypes message = new TestAllTypes.Builder { RepeatedInt32List = { 1, 2, 3 } }.Build();
53 TestUtil.AssertEqual(new int[]{1, 2, 3}, message.RepeatedInt32List);
54 }
55
56 [Test]
57 public void AddPrimitiveFailsAfterBuild() {
58 TestAllTypes.Builder builder = new TestAllTypes.Builder();
59 IList<int> list = builder.RepeatedInt32List;
60 list.Add(1); // Fine
61 builder.Build();
62
63 try {
64 list.Add(2);
65 Assert.Fail("List should be frozen");
66 } catch (NotSupportedException) {
67 // Expected
68 }
69 }
70
71 [Test]
72 public void RepeatedAddMessageBeforeBuild() {
73 TestAllTypes message = new TestAllTypes.Builder {
74 RepeatedNestedMessageList = { new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build() } }.Build();
75 Assert.AreEqual(1, message.RepeatedNestedMessageCount);
76 Assert.AreEqual(10, message.RepeatedNestedMessageList[0].Bb);
77 }
78
79 [Test]
80 public void AddMessageFailsAfterBuild() {
81 TestAllTypes.Builder builder = new TestAllTypes.Builder();
82 IList<TestAllTypes.Types.NestedMessage> list = builder.RepeatedNestedMessageList;
83 builder.Build();
84
85 try {
86 list.Add(new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build());
87 Assert.Fail("List should be frozen");
88 } catch (NotSupportedException) {
89 // Expected
90 }
91 }
92
93 [Test]
94 public void DefaultInstance() {
95 Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.DefaultInstance.DefaultInstanceForType);
96 Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.CreateBuilder().DefaultInstanceForType);
97 }
98
99 [Test]
100 public void Accessors() {
101 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
102 TestUtil.SetAllFields(builder);
103 TestAllTypes message = builder.Build();
104 TestUtil.AssertAllFieldsSet(message);
105 }
Jon Skeet642a8142009-01-27 12:25:21 +0000106
107 [Test]
108 public void SettersRejectNull() {
109 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
110 TestUtil.AssertArgumentNullException(() => builder.SetOptionalString(null));
111 TestUtil.AssertArgumentNullException(() => builder.SetOptionalBytes(null));
112 TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage)null));
113 TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
114 TestUtil.AssertArgumentNullException(() => builder.AddRepeatedString(null));
115 TestUtil.AssertArgumentNullException(() => builder.AddRepeatedBytes(null));
116 TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage)null));
117 TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
118 }
119
Jon Skeet68036862008-10-22 13:30:34 +0100120 [Test]
121 public void RepeatedSetters() {
122 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
123 TestUtil.SetAllFields(builder);
124 TestUtil.ModifyRepeatedFields(builder);
125 TestAllTypes message = builder.Build();
126 TestUtil.AssertRepeatedFieldsModified(message);
127 }
128
129 [Test]
130 public void RepeatedAppend() {
131 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
132
133 builder.AddRangeRepeatedInt32(new int[]{1, 2, 3, 4});
134 builder.AddRangeRepeatedForeignEnum((new ForeignEnum[] { ForeignEnum.FOREIGN_BAZ }));
135
136 ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
137 builder.AddRangeRepeatedForeignMessage(new ForeignMessage[] {foreignMessage});
138
139 TestAllTypes message = builder.Build();
140 TestUtil.AssertEqual(message.RepeatedInt32List, new int[]{1, 2, 3, 4});
141 TestUtil.AssertEqual(message.RepeatedForeignEnumList, new ForeignEnum[] {ForeignEnum.FOREIGN_BAZ});
142 Assert.AreEqual(1, message.RepeatedForeignMessageCount);
143 Assert.AreEqual(12, message.GetRepeatedForeignMessage(0).C);
144 }
145
146 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000147 public void RepeatedAppendRejectsNull() {
148 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
149
150 ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
151 TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(new[] { foreignMessage, null }));
152 TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(null));
153 TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignEnum(null));
154 TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedString(new[] { "one", null }));
155 TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedBytes(new[] { TestUtil.ToBytes("one"), null }));
156 }
157
158 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100159 public void SettingForeignMessageUsingBuilder() {
160 TestAllTypes message = TestAllTypes.CreateBuilder()
161 // Pass builder for foreign message instance.
162 .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123))
163 .Build();
164 TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
165 // Create expected version passing foreign message instance explicitly.
166 .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123).Build())
167 .Build();
168 Assert.AreEqual(expectedMessage, message);
169 }
170
171 [Test]
172 public void SettingRepeatedForeignMessageUsingBuilder() {
173 TestAllTypes message = TestAllTypes.CreateBuilder()
174 // Pass builder for foreign message instance.
175 .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456))
176 .Build();
177 TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
178 // Create expected version passing foreign message instance explicitly.
179 .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456).Build())
180 .Build();
181 Assert.AreEqual(expectedMessage, message);
182 }
183
184
185 [Test]
186 public void Defaults() {
187 TestUtil.AssertClear(TestAllTypes.DefaultInstance);
188 TestUtil.AssertClear(TestAllTypes.CreateBuilder().Build());
189
190 Assert.AreEqual("\u1234", TestExtremeDefaultValues.DefaultInstance.Utf8String);
191 }
192
193 [Test]
194 public void ReflectionGetters() {
195 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
196 TestUtil.SetAllFields(builder);
197 TestAllTypes message = builder.Build();
198 reflectionTester.AssertAllFieldsSetViaReflection(message);
199 }
200
201 [Test]
202 public void ReflectionSetters() {
203 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
204 reflectionTester.SetAllFieldsViaReflection(builder);
205 TestAllTypes message = builder.Build();
206 TestUtil.AssertAllFieldsSet(message);
207 }
208
209 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000210 public void ReflectionSettersRejectNull() {
211 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
212 reflectionTester.AssertReflectionSettersRejectNull(builder);
213 }
214 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100215 public void ReflectionRepeatedSetters() {
216 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
217 reflectionTester.SetAllFieldsViaReflection(builder);
218 reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
219 TestAllTypes message = builder.Build();
220 TestUtil.AssertRepeatedFieldsModified(message);
221 }
222
223 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000224 public void TestReflectionRepeatedSettersRejectNull() {
225 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
226 reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
227 }
228
229 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100230 public void ReflectionDefaults() {
231 reflectionTester.AssertClearViaReflection(TestAllTypes.DefaultInstance);
232 reflectionTester.AssertClearViaReflection(TestAllTypes.CreateBuilder().Build());
233 }
234 // =================================================================
235 // Extensions.
236
237 [Test]
238 public void ExtensionAccessors() {
239 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
240 TestUtil.SetAllExtensions(builder);
241 TestAllExtensions message = builder.Build();
242 TestUtil.AssertAllExtensionsSet(message);
243 }
244
245 [Test]
246 public void ExtensionRepeatedSetters() {
247 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
248 TestUtil.SetAllExtensions(builder);
249 TestUtil.ModifyRepeatedExtensions(builder);
250 TestAllExtensions message = builder.Build();
251 TestUtil.AssertRepeatedExtensionsModified(message);
252 }
253
254 [Test]
255 public void ExtensionDefaults() {
256 TestUtil.AssertExtensionsClear(TestAllExtensions.DefaultInstance);
257 TestUtil.AssertExtensionsClear(TestAllExtensions.CreateBuilder().Build());
258 }
259
260 [Test]
261 public void ExtensionReflectionGetters() {
262 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
263 TestUtil.SetAllExtensions(builder);
264 TestAllExtensions message = builder.Build();
265 extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
266 }
267
268 [Test]
269 public void ExtensionReflectionSetters() {
270 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
271 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
272 TestAllExtensions message = builder.Build();
273 TestUtil.AssertAllExtensionsSet(message);
274 }
275
276 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000277 public void ExtensionReflectionSettersRejectNull() {
278 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
279 extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
280 }
281
282 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100283 public void ExtensionReflectionRepeatedSetters() {
284 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
285 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
286 extensionsReflectionTester.ModifyRepeatedFieldsViaReflection(builder);
287 TestAllExtensions message = builder.Build();
288 TestUtil.AssertRepeatedExtensionsModified(message);
289 }
290
291 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000292 public void ExtensionReflectionRepeatedSettersRejectNull() {
293 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
294 extensionsReflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
295 }
296
297 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100298 public void ExtensionReflectionDefaults() {
299 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.DefaultInstance);
300 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.CreateBuilder().Build());
301 }
302
303 [Test]
304 public void ClearExtension() {
305 // ClearExtension() is not actually used in TestUtil, so try it manually.
306 Assert.IsFalse(TestAllExtensions.CreateBuilder()
307 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1)
308 .ClearExtension(UnitTestProtoFile.OptionalInt32Extension)
309 .HasExtension(UnitTestProtoFile.OptionalInt32Extension));
310 Assert.AreEqual(0, TestAllExtensions.CreateBuilder()
311 .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 1)
312 .ClearExtension(UnitTestProtoFile.RepeatedInt32Extension)
313 .GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
314 }
315
Jon Skeet642a8142009-01-27 12:25:21 +0000316 [Test]
317 public void ExtensionMergeFrom() {
318 TestAllExtensions original = TestAllExtensions.CreateBuilder()
319 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
320 TestAllExtensions merged =
321 TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
322 Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
323 Assert.AreEqual(1, (int)merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
Jon Skeet49fcd4f2009-01-27 14:43:10 +0000324 }
Jon Skeet642a8142009-01-27 12:25:21 +0000325
Jon Skeet68036862008-10-22 13:30:34 +0100326 /* Removed multiple files option for the moment
327 [Test]
328 public void MultipleFilesOption() {
329 // We mostly just want to check that things compile.
330 MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
331 .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
332 .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
333 .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
334 .SetForeignEnum(EnumWithNoOuter.BAR)
335 .Build();
336 Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
337
338 Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
339
340 FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
341 Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
342 .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
343
344 Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
345
346 Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
347 }*/
348
349 [Test]
350 public void OptionalFieldWithRequiredSubfieldsOptimizedForSize() {
351 TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
352 Assert.IsTrue(message.IsInitialized);
353
354 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
355 TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
356 ).BuildPartial();
357 Assert.IsFalse(message.IsInitialized);
358
359 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
360 TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
361 ).BuildPartial();
362 Assert.IsTrue(message.IsInitialized);
363 }
Jon Skeet20bfd9b2008-10-23 21:05:58 +0100364
365 [Test]
366 public void TestOptimizedForSizeMergeUsesAllFieldsFromTarget() {
367 TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder { I = 10 }.Build();
368 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
369 builder.MergeFrom(withFieldSet);
370 TestOptimizedForSize built = builder.Build();
371 Assert.AreEqual(10, built.I);
372 }
373
374 [Test]
375 public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized() {
376 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
377 builder.SetExtension(TestOptimizedForSize.TestExtension2,
378 new TestRequiredOptimizedForSize.Builder().BuildPartial());
379 Assert.IsFalse(builder.IsInitialized);
380 Assert.IsFalse(builder.BuildPartial().IsInitialized);
381
382 builder = new TestOptimizedForSize.Builder();
383 builder.SetExtension(TestOptimizedForSize.TestExtension2,
384 new TestRequiredOptimizedForSize.Builder { X = 10 }.BuildPartial());
385 Assert.IsTrue(builder.IsInitialized);
386 Assert.IsTrue(builder.BuildPartial().IsInitialized);
387 }
Jon Skeete81a9d72009-02-24 16:50:56 +0000388
389 [Test]
390 public void ToBuilder() {
391 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
392 TestUtil.SetAllFields(builder);
393 TestAllTypes message = builder.Build();
394 TestUtil.AssertAllFieldsSet(message.ToBuilder().Build());
395 }
Jon Skeet68036862008-10-22 13:30:34 +0100396 }
397}