1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 package com.google.protobuf;
33 import protobuf_unittest.UnittestProto.TestAllTypes;
34 import protobuf_unittest.UnittestProto.TestAllExtensions;
35 import protobuf_unittest.UnittestProto.TestRequired;
36 import protobuf_unittest.UnittestProto.TestRequiredForeign;
37 import protobuf_unittest.UnittestProto.ForeignMessage;
39 import junit.framework.TestCase;
41 import java.util.List;
44 * Misc. unit tests for message operations that apply to both generated
45 * and dynamic messages.
47 * @author kenton@google.com Kenton Varda
49 public class MessageTest extends TestCase {
50 // =================================================================
51 // Message-merging tests.
53 static final TestAllTypes MERGE_SOURCE =
54 TestAllTypes.newBuilder()
56 .setOptionalString("foo")
57 .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
58 .addRepeatedString("bar")
61 static final TestAllTypes MERGE_DEST =
62 TestAllTypes.newBuilder()
64 .setOptionalString("baz")
65 .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
66 .addRepeatedString("qux")
69 static final String MERGE_RESULT_TEXT =
70 "optional_int32: 1\n" +
71 "optional_int64: 2\n" +
72 "optional_string: \"foo\"\n" +
73 "optional_foreign_message {\n" +
76 "repeated_string: \"qux\"\n" +
77 "repeated_string: \"bar\"\n";
79 public void testMergeFrom() throws Exception {
81 TestAllTypes.newBuilder(MERGE_DEST)
82 .mergeFrom(MERGE_SOURCE).build();
84 assertEquals(MERGE_RESULT_TEXT, result.toString());
88 * Test merging a DynamicMessage into a GeneratedMessage. As long as they
89 * have the same descriptor, this should work, but it is an entirely different
92 public void testMergeFromDynamic() throws Exception {
94 TestAllTypes.newBuilder(MERGE_DEST)
95 .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
98 assertEquals(MERGE_RESULT_TEXT, result.toString());
101 /** Test merging two DynamicMessages. */
102 public void testDynamicMergeFrom() throws Exception {
103 DynamicMessage result =
104 DynamicMessage.newBuilder(MERGE_DEST)
105 .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
108 assertEquals(MERGE_RESULT_TEXT, result.toString());
111 // =================================================================
112 // Required-field-related tests.
114 private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
115 TestRequired.getDefaultInstance();
116 private static final TestRequired TEST_REQUIRED_INITIALIZED =
117 TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
119 public void testRequired() throws Exception {
120 TestRequired.Builder builder = TestRequired.newBuilder();
122 assertFalse(builder.isInitialized());
124 assertFalse(builder.isInitialized());
126 assertFalse(builder.isInitialized());
128 assertTrue(builder.isInitialized());
131 public void testRequiredForeign() throws Exception {
132 TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
134 assertTrue(builder.isInitialized());
136 builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
137 assertFalse(builder.isInitialized());
139 builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
140 assertTrue(builder.isInitialized());
142 builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
143 assertFalse(builder.isInitialized());
145 builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
146 assertTrue(builder.isInitialized());
149 public void testRequiredExtension() throws Exception {
150 TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
152 assertTrue(builder.isInitialized());
154 builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
155 assertFalse(builder.isInitialized());
157 builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
158 assertTrue(builder.isInitialized());
160 builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
161 assertFalse(builder.isInitialized());
163 builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
164 assertTrue(builder.isInitialized());
167 public void testRequiredDynamic() throws Exception {
168 Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
169 DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
171 assertFalse(builder.isInitialized());
172 builder.setField(descriptor.findFieldByName("a"), 1);
173 assertFalse(builder.isInitialized());
174 builder.setField(descriptor.findFieldByName("b"), 1);
175 assertFalse(builder.isInitialized());
176 builder.setField(descriptor.findFieldByName("c"), 1);
177 assertTrue(builder.isInitialized());
180 public void testRequiredDynamicForeign() throws Exception {
181 Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
182 DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
184 assertTrue(builder.isInitialized());
186 builder.setField(descriptor.findFieldByName("optional_message"),
187 TEST_REQUIRED_UNINITIALIZED);
188 assertFalse(builder.isInitialized());
190 builder.setField(descriptor.findFieldByName("optional_message"),
191 TEST_REQUIRED_INITIALIZED);
192 assertTrue(builder.isInitialized());
194 builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
195 TEST_REQUIRED_UNINITIALIZED);
196 assertFalse(builder.isInitialized());
198 builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
199 TEST_REQUIRED_INITIALIZED);
200 assertTrue(builder.isInitialized());
203 public void testUninitializedException() throws Exception {
205 TestRequired.newBuilder().build();
206 fail("Should have thrown an exception.");
207 } catch (UninitializedMessageException e) {
208 assertEquals("Message missing required fields: a, b, c", e.getMessage());
212 public void testBuildPartial() throws Exception {
213 // We're mostly testing that no exception is thrown.
214 TestRequired message = TestRequired.newBuilder().buildPartial();
215 assertFalse(message.isInitialized());
218 public void testNestedUninitializedException() throws Exception {
220 TestRequiredForeign.newBuilder()
221 .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
222 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
223 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
225 fail("Should have thrown an exception.");
226 } catch (UninitializedMessageException e) {
228 "Message missing required fields: " +
229 "optional_message.a, " +
230 "optional_message.b, " +
231 "optional_message.c, " +
232 "repeated_message[0].a, " +
233 "repeated_message[0].b, " +
234 "repeated_message[0].c, " +
235 "repeated_message[1].a, " +
236 "repeated_message[1].b, " +
237 "repeated_message[1].c",
242 public void testBuildNestedPartial() throws Exception {
243 // We're mostly testing that no exception is thrown.
244 TestRequiredForeign message =
245 TestRequiredForeign.newBuilder()
246 .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
247 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
248 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
250 assertFalse(message.isInitialized());
253 public void testParseUnititialized() throws Exception {
255 TestRequired.parseFrom(ByteString.EMPTY);
256 fail("Should have thrown an exception.");
257 } catch (InvalidProtocolBufferException e) {
258 assertEquals("Message missing required fields: a, b, c", e.getMessage());
262 public void testParseNestedUnititialized() throws Exception {
264 TestRequiredForeign.newBuilder()
265 .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
266 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
267 .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
268 .buildPartial().toByteString();
271 TestRequiredForeign.parseFrom(data);
272 fail("Should have thrown an exception.");
273 } catch (InvalidProtocolBufferException e) {
275 "Message missing required fields: " +
276 "optional_message.a, " +
277 "optional_message.b, " +
278 "optional_message.c, " +
279 "repeated_message[0].a, " +
280 "repeated_message[0].b, " +
281 "repeated_message[0].c, " +
282 "repeated_message[1].a, " +
283 "repeated_message[1].b, " +
284 "repeated_message[1].c",
289 public void testDynamicUninitializedException() throws Exception {
291 DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
292 fail("Should have thrown an exception.");
293 } catch (UninitializedMessageException e) {
294 assertEquals("Message missing required fields: a, b, c", e.getMessage());
298 public void testDynamicBuildPartial() throws Exception {
299 // We're mostly testing that no exception is thrown.
300 DynamicMessage message =
301 DynamicMessage.newBuilder(TestRequired.getDescriptor())
303 assertFalse(message.isInitialized());
306 public void testDynamicParseUnititialized() throws Exception {
308 Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
309 DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
310 fail("Should have thrown an exception.");
311 } catch (InvalidProtocolBufferException e) {
312 assertEquals("Message missing required fields: a, b, c", e.getMessage());
316 /** Test reading unset repeated message from DynamicMessage. */
317 public void testDynamicRepeatedMessageNull() throws Exception {
318 Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
319 DynamicMessage result =
320 DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
321 .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
324 assertTrue(result.getField(result.getDescriptorForType()
325 .findFieldByName("repeated_foreign_message")) instanceof List<?>);
326 assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
327 .findFieldByName("repeated_foreign_message")), 0);
330 /** Test reading repeated message from DynamicMessage. */
331 public void testDynamicRepeatedMessageNotNull() throws Exception {
333 TestAllTypes REPEATED_NESTED =
334 TestAllTypes.newBuilder()
336 .setOptionalString("foo")
337 .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
338 .addRepeatedString("bar")
339 .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
340 .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
342 Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
343 DynamicMessage result =
344 DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
345 .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build())
348 assertTrue(result.getField(result.getDescriptorForType()
349 .findFieldByName("repeated_foreign_message")) instanceof List<?>);
350 assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
351 .findFieldByName("repeated_foreign_message")), 2);