blob: 5d0a9291a3eead0d27418ded6294a40fcb2c9d3f [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 /* Reinstate this test in the commit where it's fixed...
317 [Test]
318 public void ExtensionMergeFrom() {
319 TestAllExtensions original = TestAllExtensions.CreateBuilder()
320 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
321 TestAllExtensions merged =
322 TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
323 Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
324 Assert.AreEqual(1, (int)merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
325 }
326 */
327
Jon Skeet68036862008-10-22 13:30:34 +0100328 /* Removed multiple files option for the moment
329 [Test]
330 public void MultipleFilesOption() {
331 // We mostly just want to check that things compile.
332 MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
333 .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
334 .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
335 .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
336 .SetForeignEnum(EnumWithNoOuter.BAR)
337 .Build();
338 Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
339
340 Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
341
342 FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
343 Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
344 .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
345
346 Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
347
348 Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
349 }*/
350
351 [Test]
352 public void OptionalFieldWithRequiredSubfieldsOptimizedForSize() {
353 TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
354 Assert.IsTrue(message.IsInitialized);
355
356 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
357 TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
358 ).BuildPartial();
359 Assert.IsFalse(message.IsInitialized);
360
361 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
362 TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
363 ).BuildPartial();
364 Assert.IsTrue(message.IsInitialized);
365 }
Jon Skeet20bfd9b2008-10-23 21:05:58 +0100366
367 [Test]
368 public void TestOptimizedForSizeMergeUsesAllFieldsFromTarget() {
369 TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder { I = 10 }.Build();
370 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
371 builder.MergeFrom(withFieldSet);
372 TestOptimizedForSize built = builder.Build();
373 Assert.AreEqual(10, built.I);
374 }
375
376 [Test]
377 public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized() {
378 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
379 builder.SetExtension(TestOptimizedForSize.TestExtension2,
380 new TestRequiredOptimizedForSize.Builder().BuildPartial());
381 Assert.IsFalse(builder.IsInitialized);
382 Assert.IsFalse(builder.BuildPartial().IsInitialized);
383
384 builder = new TestOptimizedForSize.Builder();
385 builder.SetExtension(TestOptimizedForSize.TestExtension2,
386 new TestRequiredOptimizedForSize.Builder { X = 10 }.BuildPartial());
387 Assert.IsTrue(builder.IsInitialized);
388 Assert.IsTrue(builder.BuildPartial().IsInitialized);
389 }
Jon Skeet68036862008-10-22 13:30:34 +0100390 }
391}