blob: ecf07b6a65442a21644c2cb42bc7b7c61edf8be1 [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() {
Jon Skeetd33bff02009-05-11 19:42:18 +0100231 TestUtil.TestInMultipleCultures(() => {
232 reflectionTester.AssertClearViaReflection(TestAllTypes.DefaultInstance);
233 reflectionTester.AssertClearViaReflection(TestAllTypes.CreateBuilder().Build());
234 });
Jon Skeet68036862008-10-22 13:30:34 +0100235 }
236 // =================================================================
237 // Extensions.
238
239 [Test]
240 public void ExtensionAccessors() {
241 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
242 TestUtil.SetAllExtensions(builder);
243 TestAllExtensions message = builder.Build();
244 TestUtil.AssertAllExtensionsSet(message);
245 }
246
247 [Test]
248 public void ExtensionRepeatedSetters() {
249 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
250 TestUtil.SetAllExtensions(builder);
251 TestUtil.ModifyRepeatedExtensions(builder);
252 TestAllExtensions message = builder.Build();
253 TestUtil.AssertRepeatedExtensionsModified(message);
254 }
255
256 [Test]
257 public void ExtensionDefaults() {
258 TestUtil.AssertExtensionsClear(TestAllExtensions.DefaultInstance);
259 TestUtil.AssertExtensionsClear(TestAllExtensions.CreateBuilder().Build());
260 }
261
262 [Test]
263 public void ExtensionReflectionGetters() {
264 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
265 TestUtil.SetAllExtensions(builder);
266 TestAllExtensions message = builder.Build();
267 extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
268 }
269
270 [Test]
271 public void ExtensionReflectionSetters() {
272 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
273 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
274 TestAllExtensions message = builder.Build();
275 TestUtil.AssertAllExtensionsSet(message);
276 }
277
278 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000279 public void ExtensionReflectionSettersRejectNull() {
280 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
281 extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
282 }
283
284 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100285 public void ExtensionReflectionRepeatedSetters() {
286 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
287 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
288 extensionsReflectionTester.ModifyRepeatedFieldsViaReflection(builder);
289 TestAllExtensions message = builder.Build();
290 TestUtil.AssertRepeatedExtensionsModified(message);
291 }
292
293 [Test]
Jon Skeet642a8142009-01-27 12:25:21 +0000294 public void ExtensionReflectionRepeatedSettersRejectNull() {
295 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
296 extensionsReflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
297 }
298
299 [Test]
Jon Skeet68036862008-10-22 13:30:34 +0100300 public void ExtensionReflectionDefaults() {
Jon Skeetd33bff02009-05-11 19:42:18 +0100301 TestUtil.TestInMultipleCultures(() => {
302 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.DefaultInstance);
303 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.CreateBuilder().Build());
304 });
Jon Skeet68036862008-10-22 13:30:34 +0100305 }
306
307 [Test]
308 public void ClearExtension() {
309 // ClearExtension() is not actually used in TestUtil, so try it manually.
310 Assert.IsFalse(TestAllExtensions.CreateBuilder()
311 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1)
312 .ClearExtension(UnitTestProtoFile.OptionalInt32Extension)
313 .HasExtension(UnitTestProtoFile.OptionalInt32Extension));
314 Assert.AreEqual(0, TestAllExtensions.CreateBuilder()
315 .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 1)
316 .ClearExtension(UnitTestProtoFile.RepeatedInt32Extension)
317 .GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
318 }
319
Jon Skeet642a8142009-01-27 12:25:21 +0000320 [Test]
321 public void ExtensionMergeFrom() {
322 TestAllExtensions original = TestAllExtensions.CreateBuilder()
323 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
324 TestAllExtensions merged =
325 TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
326 Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
327 Assert.AreEqual(1, (int)merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
Jon Skeet49fcd4f2009-01-27 14:43:10 +0000328 }
Jon Skeet642a8142009-01-27 12:25:21 +0000329
Jon Skeet68036862008-10-22 13:30:34 +0100330 /* Removed multiple files option for the moment
331 [Test]
332 public void MultipleFilesOption() {
333 // We mostly just want to check that things compile.
334 MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
335 .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
336 .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
337 .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
338 .SetForeignEnum(EnumWithNoOuter.BAR)
339 .Build();
340 Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
341
342 Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
343
344 FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
345 Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
346 .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
347
348 Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
349
350 Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
351 }*/
352
353 [Test]
354 public void OptionalFieldWithRequiredSubfieldsOptimizedForSize() {
355 TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
356 Assert.IsTrue(message.IsInitialized);
357
358 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
359 TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
360 ).BuildPartial();
361 Assert.IsFalse(message.IsInitialized);
362
363 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
364 TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
365 ).BuildPartial();
366 Assert.IsTrue(message.IsInitialized);
367 }
Jon Skeet20bfd9b2008-10-23 21:05:58 +0100368
369 [Test]
370 public void TestOptimizedForSizeMergeUsesAllFieldsFromTarget() {
371 TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder { I = 10 }.Build();
372 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
373 builder.MergeFrom(withFieldSet);
374 TestOptimizedForSize built = builder.Build();
375 Assert.AreEqual(10, built.I);
376 }
377
378 [Test]
379 public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized() {
380 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
381 builder.SetExtension(TestOptimizedForSize.TestExtension2,
382 new TestRequiredOptimizedForSize.Builder().BuildPartial());
383 Assert.IsFalse(builder.IsInitialized);
384 Assert.IsFalse(builder.BuildPartial().IsInitialized);
385
386 builder = new TestOptimizedForSize.Builder();
387 builder.SetExtension(TestOptimizedForSize.TestExtension2,
388 new TestRequiredOptimizedForSize.Builder { X = 10 }.BuildPartial());
389 Assert.IsTrue(builder.IsInitialized);
390 Assert.IsTrue(builder.BuildPartial().IsInitialized);
391 }
Jon Skeete81a9d72009-02-24 16:50:56 +0000392
393 [Test]
394 public void ToBuilder() {
395 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
396 TestUtil.SetAllFields(builder);
397 TestAllTypes message = builder.Build();
398 TestUtil.AssertAllFieldsSet(message.ToBuilder().Build());
399 }
Jon Skeet68036862008-10-22 13:30:34 +0100400 }
401}