OLD | NEW |
| (Empty) |
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.test; | |
32 import com.google.protobuf.*; | |
33 | |
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; | |
43 | |
44 import junit.framework.TestCase; | |
45 | |
46 import java.io.ByteArrayInputStream; | |
47 import java.io.ByteArrayOutputStream; | |
48 import java.io.IOException; | |
49 import java.io.InputStream; | |
50 | |
51 /** | |
52 * Unit test for {@link Parser}. | |
53 * | |
54 * @author liujisi@google.com (Pherl Liu) | |
55 */ | |
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()); | |
61 } | |
62 } | |
63 | |
64 private void assertRoundTripEquals(MessageLite message, | |
65 ExtensionRegistryLite registry) | |
66 throws Exception { | |
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)); | |
82 } | |
83 | |
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), | |
93 offset, length)); | |
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))); | |
99 } | |
100 | |
101 private void assertMessageEquals(MessageLite expected, MessageLite actual) | |
102 throws Exception { | |
103 if (expected instanceof Message) { | |
104 assertEquals(expected, actual); | |
105 } else { | |
106 assertEquals(expected.toByteString(), actual.toByteString()); | |
107 } | |
108 } | |
109 | |
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); | |
113 return result; | |
114 } | |
115 | |
116 public void testNormalMessage() throws Exception { | |
117 assertRoundTripEquals(TestUtil.getAllSet()); | |
118 } | |
119 | |
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."; | |
124 | |
125 // TestRequired.b and TestRequired.c are not set. | |
126 TestRequired partialMessage = TestRequired.newBuilder() | |
127 .setA(1).buildPartial(); | |
128 | |
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))); | |
138 | |
139 // parseFrom(ByteArray) | |
140 try { | |
141 parser.parseFrom(partialMessage.toByteArray()); | |
142 fail(errorString); | |
143 } catch (InvalidProtocolBufferException e) { | |
144 // pass. | |
145 } | |
146 | |
147 // parseFrom(ByteString) | |
148 try { | |
149 parser.parseFrom(partialMessage.toByteString()); | |
150 fail(errorString); | |
151 } catch (InvalidProtocolBufferException e) { | |
152 // pass. | |
153 } | |
154 | |
155 // parseFrom(InputStream) | |
156 try { | |
157 parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray())); | |
158 fail(errorString); | |
159 } catch (IOException e) { | |
160 // pass. | |
161 } | |
162 | |
163 // parseFrom(CodedInputStream) | |
164 try { | |
165 parser.parseFrom(CodedInputStream.newInstance( | |
166 partialMessage.toByteArray())); | |
167 fail(errorString); | |
168 } catch (IOException e) { | |
169 // pass. | |
170 } | |
171 } | |
172 | |
173 public void testParseDelimitedTo() throws Exception { | |
174 // Write normal Message. | |
175 TestAllTypes normalMessage = TestUtil.getAllSet(); | |
176 ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
177 normalMessage.writeDelimitedTo(output); | |
178 | |
179 InputStream input = new ByteArrayInputStream(output.toByteArray()); | |
180 assertMessageEquals( | |
181 normalMessage, | |
182 normalMessage.getParserForType().parseDelimitedFrom(input)); | |
183 } | |
184 | |
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()); | |
189 assertEquals( | |
190 TestUtil.getAllSet().toByteString(), | |
191 emptyMessage.toByteString()); | |
192 } | |
193 | |
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()); | |
200 | |
201 TestOptimizedForSize message = builder.build(); | |
202 ExtensionRegistry registry = ExtensionRegistry.newInstance(); | |
203 UnittestOptimizeFor.registerAllExtensions(registry); | |
204 | |
205 assertRoundTripEquals(message, registry); | |
206 } | |
207 | |
208 /** Helper method for {@link #testParsingMerge()}.*/ | |
209 private void assertMessageMerged(TestAllTypes allTypes) | |
210 throws Exception { | |
211 assertEquals(3, allTypes.getOptionalInt32()); | |
212 assertEquals(2, allTypes.getOptionalInt64()); | |
213 assertEquals("hello", allTypes.getOptionalString()); | |
214 } | |
215 | |
216 public void testParsingMerge() throws Exception { | |
217 // Build messages. | |
218 TestAllTypes.Builder builder = TestAllTypes.newBuilder(); | |
219 TestAllTypes msg1 = builder.setOptionalInt32(1).build(); | |
220 builder.clear(); | |
221 TestAllTypes msg2 = builder.setOptionalInt64(2).build(); | |
222 builder.clear(); | |
223 TestAllTypes msg3 = builder.setOptionalInt32(3) | |
224 .setOptionalString("hello").build(); | |
225 | |
226 // Build groups. | |
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(); | |
245 | |
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(); | |
256 | |
257 // Parse TestParsingMerge. | |
258 ExtensionRegistry registry = ExtensionRegistry.newInstance(); | |
259 UnittestProto.registerAllExtensions(registry); | |
260 TestParsingMerge parsingMerge = | |
261 TestParsingMerge.PARSER.parseFrom(data, registry); | |
262 | |
263 // Required and optional fields should be merged. | |
264 assertMessageMerged(parsingMerge.getRequiredAllTypes()); | |
265 assertMessageMerged(parsingMerge.getOptionalAllTypes()); | |
266 assertMessageMerged( | |
267 parsingMerge.getOptionalGroup().getOptionalGroupAllTypes()); | |
268 assertMessageMerged(parsingMerge.getExtension( | |
269 TestParsingMerge.optionalExt)); | |
270 | |
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)); | |
276 } | |
277 | |
278 } | |
OLD | NEW |