tizen 2.3.1 release
[external/protobuf.git] / java / src / test / java / com / google / protobuf / MessageTest.java
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
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
14 // distribution.
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.
18 //
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.
30
31 package com.google.protobuf;
32
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;
38
39 import junit.framework.TestCase;
40
41 import java.util.List;
42
43 /**
44  * Misc. unit tests for message operations that apply to both generated
45  * and dynamic messages.
46  *
47  * @author kenton@google.com Kenton Varda
48  */
49 public class MessageTest extends TestCase {
50   // =================================================================
51   // Message-merging tests.
52
53   static final TestAllTypes MERGE_SOURCE =
54     TestAllTypes.newBuilder()
55       .setOptionalInt32(1)
56       .setOptionalString("foo")
57       .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
58       .addRepeatedString("bar")
59       .build();
60
61   static final TestAllTypes MERGE_DEST =
62     TestAllTypes.newBuilder()
63       .setOptionalInt64(2)
64       .setOptionalString("baz")
65       .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
66       .addRepeatedString("qux")
67       .build();
68
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" +
74       "  c: 3\n" +
75       "}\n" +
76       "repeated_string: \"qux\"\n" +
77       "repeated_string: \"bar\"\n";
78
79   public void testMergeFrom() throws Exception {
80     TestAllTypes result =
81       TestAllTypes.newBuilder(MERGE_DEST)
82         .mergeFrom(MERGE_SOURCE).build();
83
84     assertEquals(MERGE_RESULT_TEXT, result.toString());
85   }
86
87   /**
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
90    * code path.
91    */
92   public void testMergeFromDynamic() throws Exception {
93     TestAllTypes result =
94       TestAllTypes.newBuilder(MERGE_DEST)
95         .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
96         .build();
97
98     assertEquals(MERGE_RESULT_TEXT, result.toString());
99   }
100
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())
106         .build();
107
108     assertEquals(MERGE_RESULT_TEXT, result.toString());
109   }
110
111   // =================================================================
112   // Required-field-related tests.
113
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();
118
119   public void testRequired() throws Exception {
120     TestRequired.Builder builder = TestRequired.newBuilder();
121
122     assertFalse(builder.isInitialized());
123     builder.setA(1);
124     assertFalse(builder.isInitialized());
125     builder.setB(1);
126     assertFalse(builder.isInitialized());
127     builder.setC(1);
128     assertTrue(builder.isInitialized());
129   }
130
131   public void testRequiredForeign() throws Exception {
132     TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
133
134     assertTrue(builder.isInitialized());
135
136     builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
137     assertFalse(builder.isInitialized());
138
139     builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
140     assertTrue(builder.isInitialized());
141
142     builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
143     assertFalse(builder.isInitialized());
144
145     builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
146     assertTrue(builder.isInitialized());
147   }
148
149   public void testRequiredExtension() throws Exception {
150     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
151
152     assertTrue(builder.isInitialized());
153
154     builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
155     assertFalse(builder.isInitialized());
156
157     builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
158     assertTrue(builder.isInitialized());
159
160     builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
161     assertFalse(builder.isInitialized());
162
163     builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
164     assertTrue(builder.isInitialized());
165   }
166
167   public void testRequiredDynamic() throws Exception {
168     Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
169     DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
170
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());
178   }
179
180   public void testRequiredDynamicForeign() throws Exception {
181     Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
182     DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
183
184     assertTrue(builder.isInitialized());
185
186     builder.setField(descriptor.findFieldByName("optional_message"),
187                      TEST_REQUIRED_UNINITIALIZED);
188     assertFalse(builder.isInitialized());
189
190     builder.setField(descriptor.findFieldByName("optional_message"),
191                      TEST_REQUIRED_INITIALIZED);
192     assertTrue(builder.isInitialized());
193
194     builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
195                              TEST_REQUIRED_UNINITIALIZED);
196     assertFalse(builder.isInitialized());
197
198     builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
199                              TEST_REQUIRED_INITIALIZED);
200     assertTrue(builder.isInitialized());
201   }
202
203   public void testUninitializedException() throws Exception {
204     try {
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());
209     }
210   }
211
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());
216   }
217
218   public void testNestedUninitializedException() throws Exception {
219     try {
220       TestRequiredForeign.newBuilder()
221         .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
222         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
223         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
224         .build();
225       fail("Should have thrown an exception.");
226     } catch (UninitializedMessageException e) {
227       assertEquals(
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",
238         e.getMessage());
239     }
240   }
241
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)
249         .buildPartial();
250     assertFalse(message.isInitialized());
251   }
252
253   public void testParseUnititialized() throws Exception {
254     try {
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());
259     }
260   }
261
262   public void testParseNestedUnititialized() throws Exception {
263     ByteString data =
264       TestRequiredForeign.newBuilder()
265         .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
266         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
267         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
268         .buildPartial().toByteString();
269
270     try {
271       TestRequiredForeign.parseFrom(data);
272       fail("Should have thrown an exception.");
273     } catch (InvalidProtocolBufferException e) {
274       assertEquals(
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",
285         e.getMessage());
286     }
287   }
288
289   public void testDynamicUninitializedException() throws Exception {
290     try {
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());
295     }
296   }
297
298   public void testDynamicBuildPartial() throws Exception {
299     // We're mostly testing that no exception is thrown.
300     DynamicMessage message =
301       DynamicMessage.newBuilder(TestRequired.getDescriptor())
302         .buildPartial();
303     assertFalse(message.isInitialized());
304   }
305
306   public void testDynamicParseUnititialized() throws Exception {
307     try {
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());
313     }
314   }
315   
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())
322         .build();
323
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);
328   }
329   
330   /** Test reading repeated message from DynamicMessage. */
331   public void testDynamicRepeatedMessageNotNull() throws Exception {
332
333     TestAllTypes REPEATED_NESTED =
334       TestAllTypes.newBuilder()
335         .setOptionalInt32(1)
336         .setOptionalString("foo")
337         .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
338         .addRepeatedString("bar")
339         .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
340         .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
341         .build();
342     Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
343     DynamicMessage result =
344       DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
345         .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build())
346         .build();
347
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);
352   }
353 }