• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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 /**
42  * Misc. unit tests for message operations that apply to both generated
43  * and dynamic messages.
44  *
45  * @author kenton@google.com Kenton Varda
46  */
47 public class MessageTest extends TestCase {
48   // =================================================================
49   // Message-merging tests.
50 
51   static final TestAllTypes MERGE_SOURCE =
52     TestAllTypes.newBuilder()
53       .setOptionalInt32(1)
54       .setOptionalString("foo")
55       .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
56       .addRepeatedString("bar")
57       .build();
58 
59   static final TestAllTypes MERGE_DEST =
60     TestAllTypes.newBuilder()
61       .setOptionalInt64(2)
62       .setOptionalString("baz")
63       .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
64       .addRepeatedString("qux")
65       .build();
66 
67   static final String MERGE_RESULT_TEXT =
68       "optional_int32: 1\n" +
69       "optional_int64: 2\n" +
70       "optional_string: \"foo\"\n" +
71       "optional_foreign_message {\n" +
72       "  c: 3\n" +
73       "}\n" +
74       "repeated_string: \"qux\"\n" +
75       "repeated_string: \"bar\"\n";
76 
testMergeFrom()77   public void testMergeFrom() throws Exception {
78     TestAllTypes result =
79       TestAllTypes.newBuilder(MERGE_DEST)
80         .mergeFrom(MERGE_SOURCE).build();
81 
82     assertEquals(MERGE_RESULT_TEXT, result.toString());
83   }
84 
85   /**
86    * Test merging a DynamicMessage into a GeneratedMessage.  As long as they
87    * have the same descriptor, this should work, but it is an entirely different
88    * code path.
89    */
testMergeFromDynamic()90   public void testMergeFromDynamic() throws Exception {
91     TestAllTypes result =
92       TestAllTypes.newBuilder(MERGE_DEST)
93         .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
94         .build();
95 
96     assertEquals(MERGE_RESULT_TEXT, result.toString());
97   }
98 
99   /** Test merging two DynamicMessages. */
testDynamicMergeFrom()100   public void testDynamicMergeFrom() throws Exception {
101     DynamicMessage result =
102       DynamicMessage.newBuilder(MERGE_DEST)
103         .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
104         .build();
105 
106     assertEquals(MERGE_RESULT_TEXT, result.toString());
107   }
108 
109   // =================================================================
110   // Required-field-related tests.
111 
112   private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
113     TestRequired.getDefaultInstance();
114   private static final TestRequired TEST_REQUIRED_INITIALIZED =
115     TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
116 
testRequired()117   public void testRequired() throws Exception {
118     TestRequired.Builder builder = TestRequired.newBuilder();
119 
120     assertFalse(builder.isInitialized());
121     builder.setA(1);
122     assertFalse(builder.isInitialized());
123     builder.setB(1);
124     assertFalse(builder.isInitialized());
125     builder.setC(1);
126     assertTrue(builder.isInitialized());
127   }
128 
testRequiredForeign()129   public void testRequiredForeign() throws Exception {
130     TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
131 
132     assertTrue(builder.isInitialized());
133 
134     builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
135     assertFalse(builder.isInitialized());
136 
137     builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
138     assertTrue(builder.isInitialized());
139 
140     builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
141     assertFalse(builder.isInitialized());
142 
143     builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
144     assertTrue(builder.isInitialized());
145   }
146 
testRequiredExtension()147   public void testRequiredExtension() throws Exception {
148     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
149 
150     assertTrue(builder.isInitialized());
151 
152     builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
153     assertFalse(builder.isInitialized());
154 
155     builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
156     assertTrue(builder.isInitialized());
157 
158     builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
159     assertFalse(builder.isInitialized());
160 
161     builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
162     assertTrue(builder.isInitialized());
163   }
164 
testRequiredDynamic()165   public void testRequiredDynamic() throws Exception {
166     Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
167     DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
168 
169     assertFalse(builder.isInitialized());
170     builder.setField(descriptor.findFieldByName("a"), 1);
171     assertFalse(builder.isInitialized());
172     builder.setField(descriptor.findFieldByName("b"), 1);
173     assertFalse(builder.isInitialized());
174     builder.setField(descriptor.findFieldByName("c"), 1);
175     assertTrue(builder.isInitialized());
176   }
177 
testRequiredDynamicForeign()178   public void testRequiredDynamicForeign() throws Exception {
179     Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
180     DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
181 
182     assertTrue(builder.isInitialized());
183 
184     builder.setField(descriptor.findFieldByName("optional_message"),
185                      TEST_REQUIRED_UNINITIALIZED);
186     assertFalse(builder.isInitialized());
187 
188     builder.setField(descriptor.findFieldByName("optional_message"),
189                      TEST_REQUIRED_INITIALIZED);
190     assertTrue(builder.isInitialized());
191 
192     builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
193                              TEST_REQUIRED_UNINITIALIZED);
194     assertFalse(builder.isInitialized());
195 
196     builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
197                              TEST_REQUIRED_INITIALIZED);
198     assertTrue(builder.isInitialized());
199   }
200 
testUninitializedException()201   public void testUninitializedException() throws Exception {
202     try {
203       TestRequired.newBuilder().build();
204       fail("Should have thrown an exception.");
205     } catch (UninitializedMessageException e) {
206       assertEquals("Message missing required fields: a, b, c", e.getMessage());
207     }
208   }
209 
testBuildPartial()210   public void testBuildPartial() throws Exception {
211     // We're mostly testing that no exception is thrown.
212     TestRequired message = TestRequired.newBuilder().buildPartial();
213     assertFalse(message.isInitialized());
214   }
215 
testNestedUninitializedException()216   public void testNestedUninitializedException() throws Exception {
217     try {
218       TestRequiredForeign.newBuilder()
219         .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
220         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
221         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
222         .build();
223       fail("Should have thrown an exception.");
224     } catch (UninitializedMessageException e) {
225       assertEquals(
226         "Message missing required fields: " +
227         "optional_message.a, " +
228         "optional_message.b, " +
229         "optional_message.c, " +
230         "repeated_message[0].a, " +
231         "repeated_message[0].b, " +
232         "repeated_message[0].c, " +
233         "repeated_message[1].a, " +
234         "repeated_message[1].b, " +
235         "repeated_message[1].c",
236         e.getMessage());
237     }
238   }
239 
testBuildNestedPartial()240   public void testBuildNestedPartial() throws Exception {
241     // We're mostly testing that no exception is thrown.
242     TestRequiredForeign message =
243       TestRequiredForeign.newBuilder()
244         .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
245         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
246         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
247         .buildPartial();
248     assertFalse(message.isInitialized());
249   }
250 
testParseUnititialized()251   public void testParseUnititialized() throws Exception {
252     try {
253       TestRequired.parseFrom(ByteString.EMPTY);
254       fail("Should have thrown an exception.");
255     } catch (InvalidProtocolBufferException e) {
256       assertEquals("Message missing required fields: a, b, c", e.getMessage());
257     }
258   }
259 
testParseNestedUnititialized()260   public void testParseNestedUnititialized() throws Exception {
261     ByteString data =
262       TestRequiredForeign.newBuilder()
263         .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
264         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
265         .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
266         .buildPartial().toByteString();
267 
268     try {
269       TestRequiredForeign.parseFrom(data);
270       fail("Should have thrown an exception.");
271     } catch (InvalidProtocolBufferException e) {
272       assertEquals(
273         "Message missing required fields: " +
274         "optional_message.a, " +
275         "optional_message.b, " +
276         "optional_message.c, " +
277         "repeated_message[0].a, " +
278         "repeated_message[0].b, " +
279         "repeated_message[0].c, " +
280         "repeated_message[1].a, " +
281         "repeated_message[1].b, " +
282         "repeated_message[1].c",
283         e.getMessage());
284     }
285   }
286 
testDynamicUninitializedException()287   public void testDynamicUninitializedException() throws Exception {
288     try {
289       DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
290       fail("Should have thrown an exception.");
291     } catch (UninitializedMessageException e) {
292       assertEquals("Message missing required fields: a, b, c", e.getMessage());
293     }
294   }
295 
testDynamicBuildPartial()296   public void testDynamicBuildPartial() throws Exception {
297     // We're mostly testing that no exception is thrown.
298     DynamicMessage message =
299       DynamicMessage.newBuilder(TestRequired.getDescriptor())
300         .buildPartial();
301     assertFalse(message.isInitialized());
302   }
303 
testDynamicParseUnititialized()304   public void testDynamicParseUnititialized() throws Exception {
305     try {
306       Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
307       DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
308       fail("Should have thrown an exception.");
309     } catch (InvalidProtocolBufferException e) {
310       assertEquals("Message missing required fields: a, b, c", e.getMessage());
311     }
312   }
313 }
314