blob: d206e78f93faf001781a68bb90324728792a0bd5 [file] [log] [blame]
Jon Skeet68036862008-10-22 13:30:34 +01001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.
3// http://code.google.com/p/protobuf/
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16using Google.ProtocolBuffers.Descriptors;
17using Google.ProtocolBuffers.TestProtos;
18using NUnit.Framework;
19
20namespace Google.ProtocolBuffers {
21 /// <summary>
22 /// Miscellaneous tests for message operations that apply to both
23 /// generated and dynamic messages.
24 /// </summary>
25 [TestFixture]
26 public class MessageTest {
27 // =================================================================
28 // Message-merging tests.
29
30 private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder {
31 OptionalInt32 = 1,
32 OptionalString = "foo",
33 OptionalForeignMessage = ForeignMessage.DefaultInstance,
34 }.AddRepeatedString("bar").Build();
35
36 private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder {
37 OptionalInt64 = 2,
38 OptionalString = "baz",
39 OptionalForeignMessage = new ForeignMessage.Builder { C=3 }.Build(),
40 }.AddRepeatedString("qux").Build();
41
42 private const string MergeResultText =
43 "optional_int32: 1\n" +
44 "optional_int64: 2\n" +
45 "optional_string: \"foo\"\n" +
46 "optional_foreign_message {\n" +
47 " c: 3\n" +
48 "}\n" +
49 "repeated_string: \"qux\"\n" +
50 "repeated_string: \"bar\"\n";
51
52 [Test]
53 public void MergeFrom() {
54 TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();
55
56 Assert.AreEqual(MergeResultText, result.ToString());
57 }
58
59 /// <summary>
60 /// Test merging a DynamicMessage into a GeneratedMessage.
61 /// As long as they have the same descriptor, this should work, but it is an
62 /// entirely different code path.
63 /// </summary>
64 [Test]
65 public void MergeFromDynamic() {
66 TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
67 .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
68 .Build();
69
70 Assert.AreEqual(MergeResultText, result.ToString());
71 }
72
73 /// <summary>
74 /// Test merging two DynamicMessages.
75 /// </summary>
76 [Test]
77 public void DynamicMergeFrom() {
78 DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
79 .MergeFrom((DynamicMessage) DynamicMessage.CreateBuilder(MergeSource).Build())
80 .Build();
81
82 Assert.AreEqual(MergeResultText, result.ToString());
83 }
84
85 // =================================================================
86 // Required-field-related tests.
87
88 private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
89 private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder {
90 A = 1, B = 2, C = 3
91 }.Build();
92
93 [Test]
94 public void Initialization() {
95 TestRequired.Builder builder = TestRequired.CreateBuilder();
96
97 Assert.IsFalse(builder.IsInitialized);
98 builder.A = 1;
99 Assert.IsFalse(builder.IsInitialized);
100 builder.B = 1;
101 Assert.IsFalse(builder.IsInitialized);
102 builder.C = 1;
103 Assert.IsTrue(builder.IsInitialized);
104 }
105
106 [Test]
107 public void RequiredForeign() {
108 TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
109
110 Assert.IsTrue(builder.IsInitialized);
111
112 builder.SetOptionalMessage(TestRequiredUninitialized);
113 Assert.IsFalse(builder.IsInitialized);
114
115 builder.SetOptionalMessage(TestRequiredInitialized);
116 Assert.IsTrue(builder.IsInitialized);
117
118 builder.AddRepeatedMessage(TestRequiredUninitialized);
119 Assert.IsFalse(builder.IsInitialized);
120
121 builder.SetRepeatedMessage(0, TestRequiredInitialized);
122 Assert.IsTrue(builder.IsInitialized);
123 }
124
125 [Test]
126 public void RequiredExtension() {
127 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
128
129 Assert.IsTrue(builder.IsInitialized);
130
131 builder.SetExtension(TestRequired.Single, TestRequiredUninitialized);
132 Assert.IsFalse(builder.IsInitialized);
133
134 builder.SetExtension(TestRequired.Single, TestRequiredInitialized);
135 Assert.IsTrue(builder.IsInitialized);
136
137 builder.AddExtension(TestRequired.Multi, TestRequiredUninitialized);
138 Assert.IsFalse(builder.IsInitialized);
139
140 builder.SetExtension(TestRequired.Multi, 0, TestRequiredInitialized);
141 Assert.IsTrue(builder.IsInitialized);
142 }
143
144 [Test]
145 public void RequiredDynamic() {
146 MessageDescriptor descriptor = TestRequired.Descriptor;
147 DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
148
149 Assert.IsFalse(builder.IsInitialized);
150 builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
151 Assert.IsFalse(builder.IsInitialized);
152 builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
153 Assert.IsFalse(builder.IsInitialized);
154 builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
155 Assert.IsTrue(builder.IsInitialized);
156 }
157
158 [Test]
159 public void RequiredDynamicForeign() {
160 MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
161 DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
162
163 Assert.IsTrue(builder.IsInitialized);
164
165 builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
166 Assert.IsFalse(builder.IsInitialized);
167
168 builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
169 Assert.IsTrue(builder.IsInitialized);
170
171 builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), TestRequiredUninitialized);
172 Assert.IsFalse(builder.IsInitialized);
173
174 builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0, TestRequiredInitialized);
175 Assert.IsTrue(builder.IsInitialized);
176 }
177
178 [Test]
179 public void UninitializedException() {
180 try {
181 TestRequired.CreateBuilder().Build();
182 Assert.Fail("Should have thrown an exception.");
183 } catch (UninitializedMessageException e) {
184 Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
185 }
186 }
187
188 [Test]
189 public void BuildPartial() {
190 // We're mostly testing that no exception is thrown.
191 TestRequired message = TestRequired.CreateBuilder().BuildPartial();
192 Assert.IsFalse(message.IsInitialized);
193 }
194
195 [Test]
196 public void NestedUninitializedException() {
197 try {
198 TestRequiredForeign.CreateBuilder()
199 .SetOptionalMessage(TestRequiredUninitialized)
200 .AddRepeatedMessage(TestRequiredUninitialized)
201 .AddRepeatedMessage(TestRequiredUninitialized)
202 .Build();
203 Assert.Fail("Should have thrown an exception.");
204 } catch (UninitializedMessageException e) {
205 Assert.AreEqual(
206 "Message missing required fields: " +
207 "optional_message.a, " +
208 "optional_message.b, " +
209 "optional_message.c, " +
210 "repeated_message[0].a, " +
211 "repeated_message[0].b, " +
212 "repeated_message[0].c, " +
213 "repeated_message[1].a, " +
214 "repeated_message[1].b, " +
215 "repeated_message[1].c",
216 e.Message);
217 }
218 }
219
220 [Test]
221 public void BuildNestedPartial() {
222 // We're mostly testing that no exception is thrown.
223 TestRequiredForeign message =
224 TestRequiredForeign.CreateBuilder()
225 .SetOptionalMessage(TestRequiredUninitialized)
226 .AddRepeatedMessage(TestRequiredUninitialized)
227 .AddRepeatedMessage(TestRequiredUninitialized)
228 .BuildPartial();
229 Assert.IsFalse(message.IsInitialized);
230 }
231
232 [Test]
233 public void ParseUnititialized() {
234 try {
235 TestRequired.ParseFrom(ByteString.Empty);
236 Assert.Fail("Should have thrown an exception.");
237 } catch (InvalidProtocolBufferException e) {
238 Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
239 }
240 }
241
242 [Test]
243 public void ParseNestedUnititialized() {
244 ByteString data =
245 TestRequiredForeign.CreateBuilder()
246 .SetOptionalMessage(TestRequiredUninitialized)
247 .AddRepeatedMessage(TestRequiredUninitialized)
248 .AddRepeatedMessage(TestRequiredUninitialized)
249 .BuildPartial().ToByteString();
250
251 try {
252 TestRequiredForeign.ParseFrom(data);
253 Assert.Fail("Should have thrown an exception.");
254 } catch (InvalidProtocolBufferException e) {
255 Assert.AreEqual(
256 "Message missing required fields: " +
257 "optional_message.a, " +
258 "optional_message.b, " +
259 "optional_message.c, " +
260 "repeated_message[0].a, " +
261 "repeated_message[0].b, " +
262 "repeated_message[0].c, " +
263 "repeated_message[1].a, " +
264 "repeated_message[1].b, " +
265 "repeated_message[1].c",
266 e.Message);
267 }
268 }
269
270 [Test]
271 public void DynamicUninitializedException() {
272 try {
273 DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build();
274 Assert.Fail("Should have thrown an exception.");
275 } catch (UninitializedMessageException e) {
276 Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
277 }
278 }
279
280 [Test]
281 public void DynamicBuildPartial() {
282 // We're mostly testing that no exception is thrown.
283 DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
284 Assert.IsFalse(message.Initialized);
285 }
286
287 [Test]
288 public void DynamicParseUnititialized() {
289 try {
290 MessageDescriptor descriptor = TestRequired.Descriptor;
291 DynamicMessage.ParseFrom(descriptor, ByteString.Empty);
292 Assert.Fail("Should have thrown an exception.");
293 } catch (InvalidProtocolBufferException e) {
294 Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
295 }
296 }
297 }
298
299}