• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 map_lite_test.MapForProto2TestProto.BizarroTestMap;
34 import map_lite_test.MapForProto2TestProto.TestMap;
35 import map_lite_test.MapForProto2TestProto.TestMap.MessageValue;
36 import map_lite_test.MapForProto2TestProto.TestMapOrBuilder;
37 import map_lite_test.MapForProto2TestProto.TestUnknownEnumValue;
38 import java.io.ByteArrayOutputStream;
39 import java.io.IOException;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.HashMap;
43 import java.util.Map;
44 import junit.framework.TestCase;
45 
46 /** Unit tests for map fields. */
47 public final class MapForProto2LiteTest extends TestCase {
48 
setMapValues(TestMap.Builder builder)49   private void setMapValues(TestMap.Builder builder) {
50     builder
51         .putInt32ToInt32Field(1, 11)
52         .putInt32ToInt32Field(2, 22)
53         .putInt32ToInt32Field(3, 33)
54         .putInt32ToStringField(1, "11")
55         .putInt32ToStringField(2, "22")
56         .putInt32ToStringField(3, "33")
57         .putInt32ToBytesField(1, TestUtil.toBytes("11"))
58         .putInt32ToBytesField(2, TestUtil.toBytes("22"))
59         .putInt32ToBytesField(3, TestUtil.toBytes("33"))
60         .putInt32ToEnumField(1, TestMap.EnumValue.FOO)
61         .putInt32ToEnumField(2, TestMap.EnumValue.BAR)
62         .putInt32ToEnumField(3, TestMap.EnumValue.BAZ)
63         .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build())
64         .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build())
65         .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build())
66         .putStringToInt32Field("1", 11)
67         .putStringToInt32Field("2", 22)
68         .putStringToInt32Field("3", 33);
69   }
70 
testSetMapValues()71   public void testSetMapValues() {
72     TestMap.Builder mapBuilder = TestMap.newBuilder();
73     setMapValues(mapBuilder);
74     TestMap map = mapBuilder.build();
75     assertMapValuesSet(map);
76   }
77 
copyMapValues(TestMap source, TestMap.Builder destination)78   private void copyMapValues(TestMap source, TestMap.Builder destination) {
79     destination
80         .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
81         .putAllInt32ToStringField(source.getInt32ToStringFieldMap())
82         .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
83         .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
84         .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
85         .putAllStringToInt32Field(source.getStringToInt32FieldMap());
86   }
87 
assertMapValuesSet(TestMap message)88   private void assertMapValuesSet(TestMap message) {
89     assertEquals(3, message.getInt32ToInt32FieldMap().size());
90     assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
91     assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
92     assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
93 
94     assertEquals(3, message.getInt32ToStringFieldMap().size());
95     assertEquals("11", message.getInt32ToStringFieldMap().get(1));
96     assertEquals("22", message.getInt32ToStringFieldMap().get(2));
97     assertEquals("33", message.getInt32ToStringFieldMap().get(3));
98 
99     assertEquals(3, message.getInt32ToBytesFieldMap().size());
100     assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
101     assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
102     assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
103 
104     assertEquals(3, message.getInt32ToEnumFieldMap().size());
105     assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
106     assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
107     assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
108 
109     assertEquals(3, message.getInt32ToMessageFieldMap().size());
110     assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
111     assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
112     assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
113 
114     assertEquals(3, message.getStringToInt32FieldMap().size());
115     assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
116     assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
117     assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
118   }
119 
updateMapValues(TestMap.Builder builder)120   private void updateMapValues(TestMap.Builder builder) {
121     builder
122         .putInt32ToInt32Field(1, 111)
123         .removeInt32ToInt32Field(2)
124         .putInt32ToInt32Field(4, 44)
125         .putInt32ToStringField(1, "111")
126         .removeInt32ToStringField(2)
127         .putInt32ToStringField(4, "44")
128         .putInt32ToBytesField(1, TestUtil.toBytes("111"))
129         .removeInt32ToBytesField(2)
130         .putInt32ToBytesField(4, TestUtil.toBytes("44"))
131         .putInt32ToEnumField(1, TestMap.EnumValue.BAR)
132         .removeInt32ToEnumField(2)
133         .putInt32ToEnumField(4, TestMap.EnumValue.QUX)
134         .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build())
135         .removeInt32ToMessageField(2)
136         .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build())
137         .putStringToInt32Field("1", 111)
138         .removeStringToInt32Field("2")
139         .putStringToInt32Field("4", 44);
140   }
141 
testUpdateMapValues()142   public void testUpdateMapValues() {
143     TestMap.Builder mapBuilder = TestMap.newBuilder();
144     setMapValues(mapBuilder);
145     TestMap map = mapBuilder.build();
146     assertMapValuesSet(map);
147 
148     mapBuilder = map.toBuilder();
149     updateMapValues(mapBuilder);
150     map = mapBuilder.build();
151     assertMapValuesUpdated(map);
152   }
153 
assertMapValuesUpdated(TestMap message)154   private void assertMapValuesUpdated(TestMap message) {
155     assertEquals(3, message.getInt32ToInt32FieldMap().size());
156     assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
157     assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
158     assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
159 
160     assertEquals(3, message.getInt32ToStringFieldMap().size());
161     assertEquals("111", message.getInt32ToStringFieldMap().get(1));
162     assertEquals("33", message.getInt32ToStringFieldMap().get(3));
163     assertEquals("44", message.getInt32ToStringFieldMap().get(4));
164 
165     assertEquals(3, message.getInt32ToBytesFieldMap().size());
166     assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
167     assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
168     assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
169 
170     assertEquals(3, message.getInt32ToEnumFieldMap().size());
171     assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
172     assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
173     assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
174 
175     assertEquals(3, message.getInt32ToMessageFieldMap().size());
176     assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
177     assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
178     assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
179 
180     assertEquals(3, message.getStringToInt32FieldMap().size());
181     assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
182     assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
183     assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
184   }
185 
assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder)186   private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
187     assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size());
188     assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount());
189     assertEquals(0, testMapOrBuilder.getInt32ToStringField().size());
190     assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount());
191     assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size());
192     assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount());
193     assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size());
194     assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount());
195     assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size());
196     assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount());
197     assertEquals(0, testMapOrBuilder.getStringToInt32Field().size());
198     assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount());
199   }
200 
testSanityCopyOnWrite()201   public void testSanityCopyOnWrite() throws InvalidProtocolBufferException {
202     // Since builders are implemented as a thin wrapper around a message
203     // instance, we attempt to verify that we can't cause the builder to modify
204     // a produced message.
205 
206     TestMap.Builder builder = TestMap.newBuilder();
207     TestMap message = builder.build();
208     builder.putInt32ToInt32Field(1, 2);
209     assertTrue(message.getInt32ToInt32FieldMap().isEmpty());
210     message = builder.build();
211     assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
212     assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
213     builder.putInt32ToInt32Field(2, 3);
214     assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
215     assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
216   }
217 
testGetMapIsImmutable()218   public void testGetMapIsImmutable() {
219     TestMap.Builder builder = TestMap.newBuilder();
220     assertMapsAreImmutable(builder);
221     assertMapsAreImmutable(builder.build());
222 
223     setMapValues(builder);
224     assertMapsAreImmutable(builder);
225     assertMapsAreImmutable(builder.build());
226   }
227 
assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder)228   private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) {
229     assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2);
230     assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2");
231     assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2"));
232     assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO);
233     assertImmutable(
234         testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance());
235     assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2);
236   }
237 
assertImmutable(Map<K, V> map, K key, V value)238   private <K, V> void assertImmutable(Map<K, V> map, K key, V value) {
239     try {
240       map.put(key, value);
241       fail();
242     } catch (UnsupportedOperationException e) {
243       // expected
244     }
245     if (!map.isEmpty()) {
246       try {
247         map.entrySet().remove(map.entrySet().iterator().next());
248         fail();
249       } catch (UnsupportedOperationException e) {
250         // expected
251       }
252     }
253   }
254 
testMutableMapLifecycle()255   public void testMutableMapLifecycle() {
256     TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
257     assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap());
258     assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
259     builder.putInt32ToInt32Field(2, 3);
260     assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
261 
262     builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
263     assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap());
264     assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap());
265     builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
266     assertEquals(
267         newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
268         builder.getInt32ToEnumFieldMap());
269 
270     builder.putInt32ToStringField(1, "1");
271     assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap());
272     assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap());
273     builder.putInt32ToStringField(2, "2");
274     assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap());
275 
276     builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
277     assertEquals(
278         newMap(1, TestMap.MessageValue.getDefaultInstance()),
279         builder.build().getInt32ToMessageFieldMap());
280     assertEquals(
281         newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap());
282     builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
283     assertEquals(
284         newMap(
285             1,
286             TestMap.MessageValue.getDefaultInstance(),
287             2,
288             TestMap.MessageValue.getDefaultInstance()),
289         builder.getInt32ToMessageFieldMap());
290   }
291 
testGettersAndSetters()292   public void testGettersAndSetters() throws Exception {
293     TestMap.Builder builder = TestMap.newBuilder();
294     TestMap message = builder.build();
295     assertMapValuesCleared(message);
296 
297     builder = message.toBuilder();
298     setMapValues(builder);
299     message = builder.build();
300     assertMapValuesSet(message);
301 
302     builder = message.toBuilder();
303     updateMapValues(builder);
304     message = builder.build();
305     assertMapValuesUpdated(message);
306 
307     builder = message.toBuilder();
308     builder.clear();
309     assertMapValuesCleared(builder);
310     message = builder.build();
311     assertMapValuesCleared(message);
312   }
313 
testPutAll()314   public void testPutAll() throws Exception {
315     TestMap.Builder sourceBuilder = TestMap.newBuilder();
316     setMapValues(sourceBuilder);
317     TestMap source = sourceBuilder.build();
318     assertMapValuesSet(source);
319 
320     TestMap.Builder destination = TestMap.newBuilder();
321     copyMapValues(source, destination);
322     assertMapValuesSet(destination.build());
323   }
324 
testPutChecksNullKeysAndValues()325   public void testPutChecksNullKeysAndValues() throws Exception {
326     TestMap.Builder builder = TestMap.newBuilder();
327 
328     try {
329       builder.putInt32ToStringField(1, null);
330       fail();
331     } catch (NullPointerException e) {
332       // expected.
333     }
334 
335     try {
336       builder.putInt32ToBytesField(1, null);
337       fail();
338     } catch (NullPointerException e) {
339       // expected.
340     }
341 
342     try {
343       builder.putInt32ToEnumField(1, null);
344       fail();
345     } catch (NullPointerException e) {
346       // expected.
347     }
348 
349     try {
350       builder.putInt32ToMessageField(1, null);
351       fail();
352     } catch (NullPointerException e) {
353       // expected.
354     }
355 
356     try {
357       builder.putStringToInt32Field(null, 1);
358       fail();
359     } catch (NullPointerException e) {
360       // expected.
361     }
362   }
363 
testSerializeAndParse()364   public void testSerializeAndParse() throws Exception {
365     TestMap.Builder builder = TestMap.newBuilder();
366     setMapValues(builder);
367     TestMap message = builder.build();
368     assertEquals(message.getSerializedSize(), message.toByteString().size());
369     message = TestMap.parser().parseFrom(message.toByteString());
370     assertMapValuesSet(message);
371 
372     builder = message.toBuilder();
373     updateMapValues(builder);
374     message = builder.build();
375     assertEquals(message.getSerializedSize(), message.toByteString().size());
376     message = TestMap.parser().parseFrom(message.toByteString());
377     assertMapValuesUpdated(message);
378 
379     builder = message.toBuilder();
380     builder.clear();
381     message = builder.build();
382     assertEquals(message.getSerializedSize(), message.toByteString().size());
383     message = TestMap.parser().parseFrom(message.toByteString());
384     assertMapValuesCleared(message);
385   }
386 
tryParseTestMap(BizarroTestMap bizarroMap)387   private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException {
388     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
389     CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
390     bizarroMap.writeTo(output);
391     output.flush();
392     return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray()));
393   }
394 
testParseError()395   public void testParseError() throws Exception {
396     ByteString bytes = TestUtil.toBytes("SOME BYTES");
397     String stringKey = "a string key";
398 
399     TestMap map =
400         tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build());
401     assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1));
402 
403     map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build());
404     assertEquals("", map.getInt32ToStringFieldOrDefault(0, null));
405 
406     map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build());
407     assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY);
408 
409     map =
410         tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build());
411     assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null));
412 
413     try {
414       tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build());
415       fail();
416     } catch (InvalidProtocolBufferException expected) {
417       assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
418       map = (TestMap) expected.getUnfinishedMessage();
419       assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
420     }
421 
422     map =
423         tryParseTestMap(
424             BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build());
425     assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1));
426   }
427 
testMergeFrom()428   public void testMergeFrom() throws Exception {
429     TestMap.Builder builder = TestMap.newBuilder();
430     setMapValues(builder);
431     TestMap message = builder.build();
432 
433     TestMap.Builder other = TestMap.newBuilder();
434     other.mergeFrom(message);
435     assertMapValuesSet(other.build());
436   }
437 
testEqualsAndHashCode()438   public void testEqualsAndHashCode() throws Exception {
439     // Test that generated equals() and hashCode() will disregard the order
440     // of map entries when comparing/hashing map fields.
441 
442     // We can't control the order of elements in a HashMap. The best we can do
443     // here is to add elements in different order.
444     TestMap m1 =
445         TestMap.newBuilder()
446             .putInt32ToInt32Field(1, 2)
447             .putInt32ToInt32Field(3, 4)
448             .putInt32ToInt32Field(5, 6)
449             .build();
450 
451     TestMap.Builder b2 =
452         TestMap.newBuilder()
453             .putInt32ToInt32Field(5, 6)
454             .putInt32ToInt32Field(1, 2)
455             .putInt32ToInt32Field(3, 4);
456     TestMap m2 = b2.build();
457 
458     assertEquals(m1, m2);
459     assertEquals(m1.hashCode(), m2.hashCode());
460 
461     // Make sure we did compare map fields.
462     b2.putInt32ToInt32Field(1, 0);
463     m2 = b2.build();
464     assertFalse(m1.equals(m2));
465     // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
466     // to be different.
467   }
468 
testUnknownEnumValues()469   public void testUnknownEnumValues() throws Exception {
470     ByteString data =
471         TestUnknownEnumValue.newBuilder()
472             .putInt32ToInt32Field(1, 1)
473             .putInt32ToInt32Field(2, 54321)
474             .build()
475             .toByteString();
476 
477     TestMap message = TestMap.parseFrom(data);
478     // Entries with unknown enum values will be stored into UnknownFieldSet so
479     // there is only one entry in the map.
480     assertEquals(1, message.getInt32ToEnumFieldMap().size());
481     assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
482     // Serializing and parsing should preserve the unknown entry.
483     data = message.toByteString();
484     TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data);
485     assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size());
486     assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue());
487     assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue());
488   }
489 
testIterationOrder()490   public void testIterationOrder() throws Exception {
491     TestMap.Builder builder = TestMap.newBuilder();
492     setMapValues(builder);
493     TestMap message = builder.build();
494 
495     assertEquals(
496         Arrays.asList("1", "2", "3"),
497         new ArrayList<String>(message.getStringToInt32FieldMap().keySet()));
498   }
499 
newMap(K key1, V value1)500   private static <K, V> Map<K, V> newMap(K key1, V value1) {
501     Map<K, V> map = new HashMap<>();
502     map.put(key1, value1);
503     return map;
504   }
505 
newMap(K key1, V value1, K key2, V value2)506   private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
507     Map<K, V> map = new HashMap<>();
508     map.put(key1, value1);
509     map.put(key2, value2);
510     return map;
511   }
512 
testGetMap()513   public void testGetMap() {
514     TestMap.Builder builder = TestMap.newBuilder();
515     setMapValues(builder);
516     TestMap message = builder.build();
517     assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
518     assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
519     assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
520     assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
521   }
522 
testContains()523   public void testContains() {
524     TestMap.Builder builder = TestMap.newBuilder();
525     setMapValues(builder);
526     assertMapContainsSetValues(builder);
527     assertMapContainsSetValues(builder.build());
528   }
529 
assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder)530   private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) {
531     assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1));
532     assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2));
533     assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3));
534     assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1));
535 
536     assertTrue(testMapOrBuilder.containsInt32ToStringField(1));
537     assertTrue(testMapOrBuilder.containsInt32ToStringField(2));
538     assertTrue(testMapOrBuilder.containsInt32ToStringField(3));
539     assertFalse(testMapOrBuilder.containsInt32ToStringField(-1));
540 
541     assertTrue(testMapOrBuilder.containsInt32ToBytesField(1));
542     assertTrue(testMapOrBuilder.containsInt32ToBytesField(2));
543     assertTrue(testMapOrBuilder.containsInt32ToBytesField(3));
544     assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1));
545 
546     assertTrue(testMapOrBuilder.containsInt32ToEnumField(1));
547     assertTrue(testMapOrBuilder.containsInt32ToEnumField(2));
548     assertTrue(testMapOrBuilder.containsInt32ToEnumField(3));
549     assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1));
550 
551     assertTrue(testMapOrBuilder.containsInt32ToMessageField(1));
552     assertTrue(testMapOrBuilder.containsInt32ToMessageField(2));
553     assertTrue(testMapOrBuilder.containsInt32ToMessageField(3));
554     assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1));
555 
556     assertTrue(testMapOrBuilder.containsStringToInt32Field("1"));
557     assertTrue(testMapOrBuilder.containsStringToInt32Field("2"));
558     assertTrue(testMapOrBuilder.containsStringToInt32Field("3"));
559     assertFalse(testMapOrBuilder.containsStringToInt32Field("-1"));
560   }
561 
testCount()562   public void testCount() {
563     TestMap.Builder builder = TestMap.newBuilder();
564     assertMapCounts(0, builder);
565 
566     setMapValues(builder);
567     assertMapCounts(3, builder);
568 
569     TestMap message = builder.build();
570     assertMapCounts(3, message);
571 
572     builder = message.toBuilder().putInt32ToInt32Field(4, 44);
573     assertEquals(4, builder.getInt32ToInt32FieldCount());
574     assertEquals(4, builder.build().getInt32ToInt32FieldCount());
575 
576     // already present - should be unchanged
577     builder.putInt32ToInt32Field(4, 44);
578     assertEquals(4, builder.getInt32ToInt32FieldCount());
579   }
580 
assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder)581   private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) {
582     assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount());
583     assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount());
584     assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount());
585     assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount());
586     assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount());
587     assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount());
588   }
589 
testGetOrDefault()590   public void testGetOrDefault() {
591     TestMap.Builder builder = TestMap.newBuilder();
592     assertMapCounts(0, builder);
593     setMapValues(builder);
594     doTestGetOrDefault(builder);
595     doTestGetOrDefault(builder.build());
596   }
597 
doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder)598   public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) {
599     assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11));
600     assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11));
601 
602     assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11"));
603     assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null));
604 
605     assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null));
606     assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null));
607 
608     assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null));
609     assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null));
610 
611     assertEquals(
612         MessageValue.newBuilder().setValue(11).build(),
613         testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null));
614     assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null));
615 
616     assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11));
617     assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11));
618 
619     try {
620       testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11);
621       fail();
622     } catch (NullPointerException e) {
623       // expected
624     }
625   }
626 
testGetOrThrow()627   public void testGetOrThrow() {
628     TestMap.Builder builder = TestMap.newBuilder();
629     assertMapCounts(0, builder);
630     setMapValues(builder);
631     doTestGetOrDefault(builder);
632     doTestGetOrDefault(builder.build());
633   }
634 
doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder)635   public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) {
636     assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1));
637     try {
638       testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1);
639       fail();
640     } catch (IllegalArgumentException e) {
641       // expected
642     }
643 
644     assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1));
645 
646     try {
647       testMapOrBuilder.getInt32ToStringFieldOrThrow(-1);
648       fail();
649     } catch (IllegalArgumentException e) {
650       // expected
651     }
652 
653     assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1));
654 
655     try {
656       testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1);
657       fail();
658     } catch (IllegalArgumentException e) {
659       // expected
660     }
661 
662     assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1));
663     try {
664       testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1);
665       fail();
666     } catch (IllegalArgumentException e) {
667       // expected
668     }
669 
670     assertEquals(
671         MessageValue.newBuilder().setValue(11).build(),
672         testMapOrBuilder.getInt32ToMessageFieldOrThrow(1));
673     try {
674       testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1);
675       fail();
676     } catch (IllegalArgumentException e) {
677       // expected
678     }
679 
680     assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1"));
681     try {
682       testMapOrBuilder.getStringToInt32FieldOrThrow("-1");
683       fail();
684     } catch (IllegalArgumentException e) {
685       // expected
686     }
687 
688     try {
689       testMapOrBuilder.getStringToInt32FieldOrThrow(null);
690       fail();
691     } catch (NullPointerException e) {
692       // expected
693     }
694   }
695 
testPut()696   public void testPut() {
697     TestMap.Builder builder = TestMap.newBuilder();
698     builder.putInt32ToInt32Field(1, 11);
699     assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
700 
701     builder.putInt32ToStringField(1, "a");
702     assertEquals("a", builder.getInt32ToStringFieldOrThrow(1));
703     try {
704       builder.putInt32ToStringField(1, null);
705       fail();
706     } catch (NullPointerException e) {
707       // expected
708     }
709 
710     builder.putInt32ToBytesField(1, TestUtil.toBytes("11"));
711     assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
712     try {
713       builder.putInt32ToBytesField(1, null);
714       fail();
715     } catch (NullPointerException e) {
716       // expected
717     }
718 
719     builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO);
720     assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
721     try {
722       builder.putInt32ToEnumField(1, null);
723       fail();
724     } catch (NullPointerException e) {
725       // expected
726     }
727 
728     builder.putStringToInt32Field("a", 1);
729     assertEquals(1, builder.getStringToInt32FieldOrThrow("a"));
730     try {
731       builder.putStringToInt32Field(null, -1);
732     } catch (NullPointerException e) {
733       // expected
734     }
735   }
736 
testRemove()737   public void testRemove() {
738     TestMap.Builder builder = TestMap.newBuilder();
739     setMapValues(builder);
740     assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
741     for (int times = 0; times < 2; times++) {
742       builder.removeInt32ToInt32Field(1);
743       assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1));
744     }
745 
746     assertEquals("11", builder.getInt32ToStringFieldOrThrow(1));
747     for (int times = 0; times < 2; times++) {
748       builder.removeInt32ToStringField(1);
749       assertNull(builder.getInt32ToStringFieldOrDefault(1, null));
750     }
751 
752     assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
753     for (int times = 0; times < 2; times++) {
754       builder.removeInt32ToBytesField(1);
755       assertNull(builder.getInt32ToBytesFieldOrDefault(1, null));
756     }
757 
758     assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
759     for (int times = 0; times < 2; times++) {
760       builder.removeInt32ToEnumField(1);
761       assertNull(builder.getInt32ToEnumFieldOrDefault(1, null));
762     }
763 
764     assertEquals(11, builder.getStringToInt32FieldOrThrow("1"));
765     for (int times = 0; times < 2; times++) {
766       builder.removeStringToInt32Field("1");
767       assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1));
768     }
769 
770     try {
771       builder.removeStringToInt32Field(null);
772       fail();
773     } catch (NullPointerException e) {
774       // expected
775     }
776   }
777 }
778