1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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.test;
32 import com.google.protobuf.*;
34 import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
35 import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
36 import protobuf_unittest.UnittestOptimizeFor;
37 import protobuf_unittest.UnittestProto.ForeignMessage;
38 import protobuf_unittest.UnittestProto.TestAllTypes;
39 import protobuf_unittest.UnittestProto.TestEmptyMessage;
40 import protobuf_unittest.UnittestProto.TestRequired;
41 import protobuf_unittest.UnittestProto.TestParsingMerge;
42 import protobuf_unittest.UnittestProto;
44 import junit.framework.TestCase;
46 import java.io.ByteArrayInputStream;
47 import java.io.ByteArrayOutputStream;
48 import java.io.IOException;
49 import java.io.InputStream;
52 * Unit test for {@link Parser}.
54 * @author liujisi@google.com (Pherl Liu)
56 public class ParserTest extends TestCase {
57 public void testGeneratedMessageParserSingleton() throws Exception {
58 for (int i = 0; i < 10; i++) {
59 assertEquals(TestAllTypes.PARSER,
60 TestUtil.getAllSet().getParserForType());
64 private void assertRoundTripEquals(MessageLite message,
65 ExtensionRegistryLite registry)
67 final byte[] data = message.toByteArray();
68 final int offset = 20;
69 final int length = data.length;
70 final int padding = 30;
71 Parser<? extends MessageLite> parser = message.getParserForType();
72 assertMessageEquals(message, parser.parseFrom(data, registry));
73 assertMessageEquals(message, parser.parseFrom(
74 generatePaddingArray(data, offset, padding),
75 offset, length, registry));
76 assertMessageEquals(message, parser.parseFrom(
77 message.toByteString(), registry));
78 assertMessageEquals(message, parser.parseFrom(
79 new ByteArrayInputStream(data), registry));
80 assertMessageEquals(message, parser.parseFrom(
81 CodedInputStream.newInstance(data), registry));
84 private void assertRoundTripEquals(MessageLite message) throws Exception {
85 final byte[] data = message.toByteArray();
86 final int offset = 20;
87 final int length = data.length;
88 final int padding = 30;
89 Parser<? extends MessageLite> parser = message.getParserForType();
90 assertMessageEquals(message, parser.parseFrom(data));
91 assertMessageEquals(message, parser.parseFrom(
92 generatePaddingArray(data, offset, padding),
94 assertMessageEquals(message, parser.parseFrom(message.toByteString()));
95 assertMessageEquals(message, parser.parseFrom(
96 new ByteArrayInputStream(data)));
97 assertMessageEquals(message, parser.parseFrom(
98 CodedInputStream.newInstance(data)));
101 private void assertMessageEquals(MessageLite expected, MessageLite actual)
103 if (expected instanceof Message) {
104 assertEquals(expected, actual);
106 assertEquals(expected.toByteString(), actual.toByteString());
110 private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
111 byte[] result = new byte[offset + data.length + padding];
112 System.arraycopy(data, 0, result, offset, data.length);
116 public void testNormalMessage() throws Exception {
117 assertRoundTripEquals(TestUtil.getAllSet());
120 public void testParsePartial() throws Exception {
121 Parser<TestRequired> parser = TestRequired.PARSER;
122 final String errorString =
123 "Should throw exceptions when the parsed message isn't initialized.";
125 // TestRequired.b and TestRequired.c are not set.
126 TestRequired partialMessage = TestRequired.newBuilder()
127 .setA(1).buildPartial();
129 // parsePartialFrom should pass.
130 byte[] data = partialMessage.toByteArray();
131 assertEquals(partialMessage, parser.parsePartialFrom(data));
132 assertEquals(partialMessage, parser.parsePartialFrom(
133 partialMessage.toByteString()));
134 assertEquals(partialMessage, parser.parsePartialFrom(
135 new ByteArrayInputStream(data)));
136 assertEquals(partialMessage, parser.parsePartialFrom(
137 CodedInputStream.newInstance(data)));
139 // parseFrom(ByteArray)
141 parser.parseFrom(partialMessage.toByteArray());
143 } catch (InvalidProtocolBufferException e) {
147 // parseFrom(ByteString)
149 parser.parseFrom(partialMessage.toByteString());
151 } catch (InvalidProtocolBufferException e) {
155 // parseFrom(InputStream)
157 parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray()));
159 } catch (IOException e) {
163 // parseFrom(CodedInputStream)
165 parser.parseFrom(CodedInputStream.newInstance(
166 partialMessage.toByteArray()));
168 } catch (IOException e) {
173 public void testParseDelimitedTo() throws Exception {
174 // Write normal Message.
175 TestAllTypes normalMessage = TestUtil.getAllSet();
176 ByteArrayOutputStream output = new ByteArrayOutputStream();
177 normalMessage.writeDelimitedTo(output);
179 InputStream input = new ByteArrayInputStream(output.toByteArray());
182 normalMessage.getParserForType().parseDelimitedFrom(input));
185 public void testParseUnknownFields() throws Exception {
186 // All fields will be treated as unknown fields in emptyMessage.
187 TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom(
188 TestUtil.getAllSet().toByteString());
190 TestUtil.getAllSet().toByteString(),
191 emptyMessage.toByteString());
194 public void testOptimizeForSize() throws Exception {
195 TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
196 builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build());
197 builder.setExtension(TestOptimizedForSize.testExtension, 56);
198 builder.setExtension(TestOptimizedForSize.testExtension2,
199 TestRequiredOptimizedForSize.newBuilder().setX(78).build());
201 TestOptimizedForSize message = builder.build();
202 ExtensionRegistry registry = ExtensionRegistry.newInstance();
203 UnittestOptimizeFor.registerAllExtensions(registry);
205 assertRoundTripEquals(message, registry);
208 /** Helper method for {@link #testParsingMerge()}.*/
209 private void assertMessageMerged(TestAllTypes allTypes)
211 assertEquals(3, allTypes.getOptionalInt32());
212 assertEquals(2, allTypes.getOptionalInt64());
213 assertEquals("hello", allTypes.getOptionalString());
216 public void testParsingMerge() throws Exception {
218 TestAllTypes.Builder builder = TestAllTypes.newBuilder();
219 TestAllTypes msg1 = builder.setOptionalInt32(1).build();
221 TestAllTypes msg2 = builder.setOptionalInt64(2).build();
223 TestAllTypes msg3 = builder.setOptionalInt32(3)
224 .setOptionalString("hello").build();
227 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 =
228 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
229 .setField1(msg1).build();
230 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 =
231 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
232 .setField1(msg2).build();
233 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 =
234 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
235 .setField1(msg3).build();
236 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 =
237 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
238 .setField1(msg1).build();
239 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 =
240 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
241 .setField1(msg2).build();
242 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 =
243 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
244 .setField1(msg3).build();
246 // Assign and serialize RepeatedFieldsGenerator.
247 ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
248 .addField1(msg1).addField1(msg2).addField1(msg3)
249 .addField2(msg1).addField2(msg2).addField2(msg3)
250 .addField3(msg1).addField3(msg2).addField3(msg3)
251 .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
252 .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
253 .addExt1(msg1).addExt1(msg2).addExt1(msg3)
254 .addExt2(msg1).addExt2(msg2).addExt2(msg3)
255 .build().toByteString();
257 // Parse TestParsingMerge.
258 ExtensionRegistry registry = ExtensionRegistry.newInstance();
259 UnittestProto.registerAllExtensions(registry);
260 TestParsingMerge parsingMerge =
261 TestParsingMerge.PARSER.parseFrom(data, registry);
263 // Required and optional fields should be merged.
264 assertMessageMerged(parsingMerge.getRequiredAllTypes());
265 assertMessageMerged(parsingMerge.getOptionalAllTypes());
267 parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
268 assertMessageMerged(parsingMerge.getExtension(
269 TestParsingMerge.optionalExt));
271 // Repeated fields should not be merged.
272 assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
273 assertEquals(3, parsingMerge.getRepeatedGroupCount());
274 assertEquals(3, parsingMerge.getExtensionCount(
275 TestParsingMerge.repeatedExt));