blob: d97b0ed50fe4323b832706a98ba442550fc7c3a9 [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 }
106
107 [Test]
108 public void RepeatedSetters() {
109 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
110 TestUtil.SetAllFields(builder);
111 TestUtil.ModifyRepeatedFields(builder);
112 TestAllTypes message = builder.Build();
113 TestUtil.AssertRepeatedFieldsModified(message);
114 }
115
116 [Test]
117 public void RepeatedAppend() {
118 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
119
120 builder.AddRangeRepeatedInt32(new int[]{1, 2, 3, 4});
121 builder.AddRangeRepeatedForeignEnum((new ForeignEnum[] { ForeignEnum.FOREIGN_BAZ }));
122
123 ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
124 builder.AddRangeRepeatedForeignMessage(new ForeignMessage[] {foreignMessage});
125
126 TestAllTypes message = builder.Build();
127 TestUtil.AssertEqual(message.RepeatedInt32List, new int[]{1, 2, 3, 4});
128 TestUtil.AssertEqual(message.RepeatedForeignEnumList, new ForeignEnum[] {ForeignEnum.FOREIGN_BAZ});
129 Assert.AreEqual(1, message.RepeatedForeignMessageCount);
130 Assert.AreEqual(12, message.GetRepeatedForeignMessage(0).C);
131 }
132
133 [Test]
134 public void SettingForeignMessageUsingBuilder() {
135 TestAllTypes message = TestAllTypes.CreateBuilder()
136 // Pass builder for foreign message instance.
137 .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123))
138 .Build();
139 TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
140 // Create expected version passing foreign message instance explicitly.
141 .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123).Build())
142 .Build();
143 Assert.AreEqual(expectedMessage, message);
144 }
145
146 [Test]
147 public void SettingRepeatedForeignMessageUsingBuilder() {
148 TestAllTypes message = TestAllTypes.CreateBuilder()
149 // Pass builder for foreign message instance.
150 .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456))
151 .Build();
152 TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
153 // Create expected version passing foreign message instance explicitly.
154 .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456).Build())
155 .Build();
156 Assert.AreEqual(expectedMessage, message);
157 }
158
159
160 [Test]
161 public void Defaults() {
162 TestUtil.AssertClear(TestAllTypes.DefaultInstance);
163 TestUtil.AssertClear(TestAllTypes.CreateBuilder().Build());
164
165 Assert.AreEqual("\u1234", TestExtremeDefaultValues.DefaultInstance.Utf8String);
166 }
167
168 [Test]
169 public void ReflectionGetters() {
170 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
171 TestUtil.SetAllFields(builder);
172 TestAllTypes message = builder.Build();
173 reflectionTester.AssertAllFieldsSetViaReflection(message);
174 }
175
176 [Test]
177 public void ReflectionSetters() {
178 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
179 reflectionTester.SetAllFieldsViaReflection(builder);
180 TestAllTypes message = builder.Build();
181 TestUtil.AssertAllFieldsSet(message);
182 }
183
184 [Test]
185 public void ReflectionRepeatedSetters() {
186 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
187 reflectionTester.SetAllFieldsViaReflection(builder);
188 reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
189 TestAllTypes message = builder.Build();
190 TestUtil.AssertRepeatedFieldsModified(message);
191 }
192
193 [Test]
194 public void ReflectionDefaults() {
195 reflectionTester.AssertClearViaReflection(TestAllTypes.DefaultInstance);
196 reflectionTester.AssertClearViaReflection(TestAllTypes.CreateBuilder().Build());
197 }
198 // =================================================================
199 // Extensions.
200
201 [Test]
202 public void ExtensionAccessors() {
203 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
204 TestUtil.SetAllExtensions(builder);
205 TestAllExtensions message = builder.Build();
206 TestUtil.AssertAllExtensionsSet(message);
207 }
208
209 [Test]
210 public void ExtensionRepeatedSetters() {
211 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
212 TestUtil.SetAllExtensions(builder);
213 TestUtil.ModifyRepeatedExtensions(builder);
214 TestAllExtensions message = builder.Build();
215 TestUtil.AssertRepeatedExtensionsModified(message);
216 }
217
218 [Test]
219 public void ExtensionDefaults() {
220 TestUtil.AssertExtensionsClear(TestAllExtensions.DefaultInstance);
221 TestUtil.AssertExtensionsClear(TestAllExtensions.CreateBuilder().Build());
222 }
223
224 [Test]
225 public void ExtensionReflectionGetters() {
226 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
227 TestUtil.SetAllExtensions(builder);
228 TestAllExtensions message = builder.Build();
229 extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
230 }
231
232 [Test]
233 public void ExtensionReflectionSetters() {
234 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
235 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
236 TestAllExtensions message = builder.Build();
237 TestUtil.AssertAllExtensionsSet(message);
238 }
239
240 [Test]
241 public void ExtensionReflectionRepeatedSetters() {
242 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
243 extensionsReflectionTester.SetAllFieldsViaReflection(builder);
244 extensionsReflectionTester.ModifyRepeatedFieldsViaReflection(builder);
245 TestAllExtensions message = builder.Build();
246 TestUtil.AssertRepeatedExtensionsModified(message);
247 }
248
249 [Test]
250 public void ExtensionReflectionDefaults() {
251 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.DefaultInstance);
252 extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.CreateBuilder().Build());
253 }
254
255 [Test]
256 public void ClearExtension() {
257 // ClearExtension() is not actually used in TestUtil, so try it manually.
258 Assert.IsFalse(TestAllExtensions.CreateBuilder()
259 .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1)
260 .ClearExtension(UnitTestProtoFile.OptionalInt32Extension)
261 .HasExtension(UnitTestProtoFile.OptionalInt32Extension));
262 Assert.AreEqual(0, TestAllExtensions.CreateBuilder()
263 .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 1)
264 .ClearExtension(UnitTestProtoFile.RepeatedInt32Extension)
265 .GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
266 }
267
268 /* Removed multiple files option for the moment
269 [Test]
270 public void MultipleFilesOption() {
271 // We mostly just want to check that things compile.
272 MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
273 .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
274 .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
275 .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
276 .SetForeignEnum(EnumWithNoOuter.BAR)
277 .Build();
278 Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
279
280 Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
281
282 FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
283 Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
284 .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
285
286 Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
287
288 Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
289 }*/
290
291 [Test]
292 public void OptionalFieldWithRequiredSubfieldsOptimizedForSize() {
293 TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
294 Assert.IsTrue(message.IsInitialized);
295
296 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
297 TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
298 ).BuildPartial();
299 Assert.IsFalse(message.IsInitialized);
300
301 message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
302 TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
303 ).BuildPartial();
304 Assert.IsTrue(message.IsInitialized);
305 }
Jon Skeet20bfd9b2008-10-23 21:05:58 +0100306
307 [Test]
308 public void TestOptimizedForSizeMergeUsesAllFieldsFromTarget() {
309 TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder { I = 10 }.Build();
310 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
311 builder.MergeFrom(withFieldSet);
312 TestOptimizedForSize built = builder.Build();
313 Assert.AreEqual(10, built.I);
314 }
315
316 [Test]
317 public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized() {
318 TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
319 builder.SetExtension(TestOptimizedForSize.TestExtension2,
320 new TestRequiredOptimizedForSize.Builder().BuildPartial());
321 Assert.IsFalse(builder.IsInitialized);
322 Assert.IsFalse(builder.BuildPartial().IsInitialized);
323
324 builder = new TestOptimizedForSize.Builder();
325 builder.SetExtension(TestOptimizedForSize.TestExtension2,
326 new TestRequiredOptimizedForSize.Builder { X = 10 }.BuildPartial());
327 Assert.IsTrue(builder.IsInitialized);
328 Assert.IsTrue(builder.BuildPartial().IsInitialized);
329 }
Jon Skeet68036862008-10-22 13:30:34 +0100330 }
331}