1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.collect.testing.Helpers.mapEntry; 20 import static com.google.common.truth.Truth.assertThat; 21 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.base.Equivalence; 25 import com.google.common.base.Joiner; 26 import com.google.common.collect.ImmutableBiMap.Builder; 27 import com.google.common.collect.testing.MapInterfaceTest; 28 import com.google.common.collect.testing.features.CollectionFeature; 29 import com.google.common.collect.testing.features.CollectionSize; 30 import com.google.common.collect.testing.features.MapFeature; 31 import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapCopyOfEntriesGenerator; 32 import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapCopyOfGenerator; 33 import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapGenerator; 34 import com.google.common.collect.testing.google.BiMapInverseTester; 35 import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; 36 import com.google.common.collect.testing.google.TestStringBiMapGenerator; 37 import com.google.common.testing.CollectorTester; 38 import com.google.common.testing.SerializableTester; 39 import com.google.errorprone.annotations.CanIgnoreReturnValue; 40 import java.util.AbstractMap; 41 import java.util.Arrays; 42 import java.util.Collections; 43 import java.util.EnumSet; 44 import java.util.LinkedHashMap; 45 import java.util.List; 46 import java.util.Map; 47 import java.util.Map.Entry; 48 import java.util.Set; 49 import java.util.stream.Collector; 50 import java.util.stream.Stream; 51 import junit.framework.Test; 52 import junit.framework.TestCase; 53 import junit.framework.TestSuite; 54 55 /** 56 * Tests for {@link ImmutableBiMap}. 57 * 58 * @author Jared Levy 59 */ 60 @GwtCompatible(emulated = true) 61 public class ImmutableBiMapTest extends TestCase { 62 63 // TODO: Reduce duplication of ImmutableMapTest code 64 65 @GwtIncompatible // suite suite()66 public static Test suite() { 67 TestSuite suite = new TestSuite(); 68 69 suite.addTestSuite(MapTests.class); 70 suite.addTestSuite(InverseMapTests.class); 71 suite.addTestSuite(CreationTests.class); 72 suite.addTestSuite(BiMapSpecificTests.class); 73 suite.addTestSuite(FloodingTest.class); 74 75 suite.addTest( 76 BiMapTestSuiteBuilder.using(new ImmutableBiMapGenerator()) 77 .named("ImmutableBiMap") 78 .withFeatures( 79 CollectionSize.ANY, 80 CollectionFeature.SERIALIZABLE, 81 CollectionFeature.KNOWN_ORDER, 82 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 83 MapFeature.ALLOWS_ANY_NULL_QUERIES) 84 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) 85 .createTestSuite()); 86 suite.addTest( 87 BiMapTestSuiteBuilder.using( 88 new TestStringBiMapGenerator() { 89 @Override 90 protected BiMap<String, String> create(Entry<String, String>[] entries) { 91 return ImmutableBiMap.<String, String>builder() 92 .putAll(Arrays.asList(entries)) 93 .buildJdkBacked(); 94 } 95 }) 96 .named("ImmutableBiMap [JDK backed]") 97 .withFeatures( 98 CollectionSize.ANY, 99 CollectionFeature.SERIALIZABLE, 100 CollectionFeature.KNOWN_ORDER, 101 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 102 MapFeature.ALLOWS_ANY_NULL_QUERIES) 103 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) 104 .createTestSuite()); 105 suite.addTest( 106 BiMapTestSuiteBuilder.using(new ImmutableBiMapCopyOfGenerator()) 107 .named("ImmutableBiMap.copyOf[Map]") 108 .withFeatures( 109 CollectionSize.ANY, 110 CollectionFeature.SERIALIZABLE, 111 CollectionFeature.KNOWN_ORDER, 112 MapFeature.ALLOWS_ANY_NULL_QUERIES) 113 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) 114 .createTestSuite()); 115 suite.addTest( 116 BiMapTestSuiteBuilder.using(new ImmutableBiMapCopyOfEntriesGenerator()) 117 .named("ImmutableBiMap.copyOf[Iterable<Entry>]") 118 .withFeatures( 119 CollectionSize.ANY, 120 CollectionFeature.SERIALIZABLE, 121 CollectionFeature.KNOWN_ORDER, 122 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 123 MapFeature.ALLOWS_ANY_NULL_QUERIES) 124 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) 125 .createTestSuite()); 126 suite.addTestSuite(ImmutableBiMapTest.class); 127 128 return suite; 129 } 130 131 public abstract static class AbstractMapTests<K, V> extends MapInterfaceTest<K, V> { AbstractMapTests()132 public AbstractMapTests() { 133 super(false, false, false, false, false); 134 } 135 136 @Override makeEmptyMap()137 protected Map<K, V> makeEmptyMap() { 138 throw new UnsupportedOperationException(); 139 } 140 141 private static final Joiner joiner = Joiner.on(", "); 142 143 @Override assertMoreInvariants(Map<K, V> map)144 protected void assertMoreInvariants(Map<K, V> map) { 145 146 BiMap<K, V> bimap = (BiMap<K, V>) map; 147 148 for (Entry<K, V> entry : map.entrySet()) { 149 assertEquals(entry.getKey() + "=" + entry.getValue(), entry.toString()); 150 assertEquals(entry.getKey(), bimap.inverse().get(entry.getValue())); 151 } 152 153 assertEquals("{" + joiner.join(map.entrySet()) + "}", map.toString()); 154 assertEquals("[" + joiner.join(map.entrySet()) + "]", map.entrySet().toString()); 155 assertEquals("[" + joiner.join(map.keySet()) + "]", map.keySet().toString()); 156 assertEquals("[" + joiner.join(map.values()) + "]", map.values().toString()); 157 158 assertEquals(Sets.newHashSet(map.entrySet()), map.entrySet()); 159 assertEquals(Sets.newHashSet(map.keySet()), map.keySet()); 160 } 161 } 162 163 public static class MapTests extends AbstractMapTests<String, Integer> { 164 @Override makeEmptyMap()165 protected Map<String, Integer> makeEmptyMap() { 166 return ImmutableBiMap.of(); 167 } 168 169 @Override makePopulatedMap()170 protected Map<String, Integer> makePopulatedMap() { 171 return ImmutableBiMap.of("one", 1, "two", 2, "three", 3); 172 } 173 174 @Override getKeyNotInPopulatedMap()175 protected String getKeyNotInPopulatedMap() { 176 return "minus one"; 177 } 178 179 @Override getValueNotInPopulatedMap()180 protected Integer getValueNotInPopulatedMap() { 181 return -1; 182 } 183 } 184 185 public static class InverseMapTests extends AbstractMapTests<String, Integer> { 186 @Override makeEmptyMap()187 protected Map<String, Integer> makeEmptyMap() { 188 return ImmutableBiMap.of(); 189 } 190 191 @Override makePopulatedMap()192 protected Map<String, Integer> makePopulatedMap() { 193 return ImmutableBiMap.of(1, "one", 2, "two", 3, "three").inverse(); 194 } 195 196 @Override getKeyNotInPopulatedMap()197 protected String getKeyNotInPopulatedMap() { 198 return "minus one"; 199 } 200 201 @Override getValueNotInPopulatedMap()202 protected Integer getValueNotInPopulatedMap() { 203 return -1; 204 } 205 } 206 207 public static class CreationTests extends TestCase { testEmptyBuilder()208 public void testEmptyBuilder() { 209 ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().build(); 210 assertEquals(Collections.<String, Integer>emptyMap(), map); 211 assertEquals(Collections.<Integer, String>emptyMap(), map.inverse()); 212 assertSame(ImmutableBiMap.of(), map); 213 } 214 testSingletonBuilder()215 public void testSingletonBuilder() { 216 ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().put("one", 1).build(); 217 assertMapEquals(map, "one", 1); 218 assertMapEquals(map.inverse(), 1, "one"); 219 } 220 testBuilder_withImmutableEntry()221 public void testBuilder_withImmutableEntry() { 222 ImmutableBiMap<String, Integer> map = 223 new Builder<String, Integer>().put(Maps.immutableEntry("one", 1)).build(); 224 assertMapEquals(map, "one", 1); 225 } 226 testBuilder()227 public void testBuilder() { 228 ImmutableBiMap<String, Integer> map = 229 ImmutableBiMap.<String, Integer>builder() 230 .put("one", 1) 231 .put("two", 2) 232 .put("three", 3) 233 .put("four", 4) 234 .put("five", 5) 235 .build(); 236 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 237 assertMapEquals(map.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); 238 } 239 240 @GwtIncompatible testBuilderExactlySizedReusesArray()241 public void testBuilderExactlySizedReusesArray() { 242 ImmutableBiMap.Builder<Integer, Integer> builder = ImmutableBiMap.builderWithExpectedSize(10); 243 Entry<Integer, Integer>[] builderArray = builder.entries; 244 for (int i = 0; i < 10; i++) { 245 builder.put(i, i); 246 } 247 Entry<Integer, Integer>[] builderArrayAfterPuts = builder.entries; 248 RegularImmutableBiMap<Integer, Integer> map = 249 (RegularImmutableBiMap<Integer, Integer>) builder.build(); 250 Entry<Integer, Integer>[] mapInternalArray = map.entries; 251 assertSame(builderArray, builderArrayAfterPuts); 252 assertSame(builderArray, mapInternalArray); 253 } 254 testBuilder_orderEntriesByValue()255 public void testBuilder_orderEntriesByValue() { 256 ImmutableBiMap<String, Integer> map = 257 ImmutableBiMap.<String, Integer>builder() 258 .orderEntriesByValue(Ordering.natural()) 259 .put("three", 3) 260 .put("one", 1) 261 .put("five", 5) 262 .put("four", 4) 263 .put("two", 2) 264 .build(); 265 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 266 assertMapEquals(map.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); 267 } 268 testBuilder_orderEntriesByValueAfterExactSizeBuild()269 public void testBuilder_orderEntriesByValueAfterExactSizeBuild() { 270 ImmutableBiMap.Builder<String, Integer> builder = 271 new ImmutableBiMap.Builder<String, Integer>(2).put("four", 4).put("one", 1); 272 ImmutableMap<String, Integer> keyOrdered = builder.build(); 273 ImmutableMap<String, Integer> valueOrdered = 274 builder.orderEntriesByValue(Ordering.natural()).build(); 275 assertMapEquals(keyOrdered, "four", 4, "one", 1); 276 assertMapEquals(valueOrdered, "one", 1, "four", 4); 277 } 278 testBuilder_orderEntriesByValue_usedTwiceFails()279 public void testBuilder_orderEntriesByValue_usedTwiceFails() { 280 ImmutableBiMap.Builder<String, Integer> builder = 281 new Builder<String, Integer>().orderEntriesByValue(Ordering.natural()); 282 try { 283 builder.orderEntriesByValue(Ordering.natural()); 284 fail("Expected IllegalStateException"); 285 } catch (IllegalStateException expected) { 286 } 287 } 288 testBuilderPutAllWithEmptyMap()289 public void testBuilderPutAllWithEmptyMap() { 290 ImmutableBiMap<String, Integer> map = 291 new Builder<String, Integer>().putAll(Collections.<String, Integer>emptyMap()).build(); 292 assertEquals(Collections.<String, Integer>emptyMap(), map); 293 } 294 testBuilderPutAll()295 public void testBuilderPutAll() { 296 Map<String, Integer> toPut = new LinkedHashMap<>(); 297 toPut.put("one", 1); 298 toPut.put("two", 2); 299 toPut.put("three", 3); 300 Map<String, Integer> moreToPut = new LinkedHashMap<>(); 301 moreToPut.put("four", 4); 302 moreToPut.put("five", 5); 303 304 ImmutableBiMap<String, Integer> map = 305 new Builder<String, Integer>().putAll(toPut).putAll(moreToPut).build(); 306 assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 307 assertMapEquals(map.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); 308 } 309 testBuilderReuse()310 public void testBuilderReuse() { 311 Builder<String, Integer> builder = new Builder<>(); 312 ImmutableBiMap<String, Integer> mapOne = builder.put("one", 1).put("two", 2).build(); 313 ImmutableBiMap<String, Integer> mapTwo = builder.put("three", 3).put("four", 4).build(); 314 315 assertMapEquals(mapOne, "one", 1, "two", 2); 316 assertMapEquals(mapOne.inverse(), 1, "one", 2, "two"); 317 assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4); 318 assertMapEquals(mapTwo.inverse(), 1, "one", 2, "two", 3, "three", 4, "four"); 319 } 320 testBuilderPutNullKey()321 public void testBuilderPutNullKey() { 322 Builder<String, Integer> builder = new Builder<>(); 323 try { 324 builder.put(null, 1); 325 fail(); 326 } catch (NullPointerException expected) { 327 } 328 } 329 testBuilderPutNullValue()330 public void testBuilderPutNullValue() { 331 Builder<String, Integer> builder = new Builder<>(); 332 try { 333 builder.put("one", null); 334 fail(); 335 } catch (NullPointerException expected) { 336 } 337 } 338 testBuilderPutNullKeyViaPutAll()339 public void testBuilderPutNullKeyViaPutAll() { 340 Builder<String, Integer> builder = new Builder<>(); 341 try { 342 builder.putAll(Collections.<String, Integer>singletonMap(null, 1)); 343 fail(); 344 } catch (NullPointerException expected) { 345 } 346 } 347 testBuilderPutNullValueViaPutAll()348 public void testBuilderPutNullValueViaPutAll() { 349 Builder<String, Integer> builder = new Builder<>(); 350 try { 351 builder.putAll(Collections.<String, Integer>singletonMap("one", null)); 352 fail(); 353 } catch (NullPointerException expected) { 354 } 355 } 356 testPuttingTheSameKeyTwiceThrowsOnBuild()357 public void testPuttingTheSameKeyTwiceThrowsOnBuild() { 358 Builder<String, Integer> builder = 359 new Builder<String, Integer>() 360 .put("one", 1) 361 .put("one", 1); // throwing on this line would be even better 362 363 try { 364 builder.build(); 365 fail(); 366 } catch (IllegalArgumentException expected) { 367 assertThat(expected.getMessage()).contains("one"); 368 } 369 } 370 testOf()371 public void testOf() { 372 assertMapEquals(ImmutableBiMap.of("one", 1), "one", 1); 373 assertMapEquals(ImmutableBiMap.of("one", 1).inverse(), 1, "one"); 374 assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2), "one", 1, "two", 2); 375 assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2).inverse(), 1, "one", 2, "two"); 376 assertMapEquals( 377 ImmutableBiMap.of("one", 1, "two", 2, "three", 3), "one", 1, "two", 2, "three", 3); 378 assertMapEquals( 379 ImmutableBiMap.of("one", 1, "two", 2, "three", 3).inverse(), 380 1, 381 "one", 382 2, 383 "two", 384 3, 385 "three"); 386 assertMapEquals( 387 ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4), 388 "one", 389 1, 390 "two", 391 2, 392 "three", 393 3, 394 "four", 395 4); 396 assertMapEquals( 397 ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4).inverse(), 398 1, 399 "one", 400 2, 401 "two", 402 3, 403 "three", 404 4, 405 "four"); 406 assertMapEquals( 407 ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5), 408 "one", 409 1, 410 "two", 411 2, 412 "three", 413 3, 414 "four", 415 4, 416 "five", 417 5); 418 assertMapEquals( 419 ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5).inverse(), 420 1, 421 "one", 422 2, 423 "two", 424 3, 425 "three", 426 4, 427 "four", 428 5, 429 "five"); 430 assertMapEquals( 431 ImmutableBiMap.of( 432 "one", 1, 433 "two", 2, 434 "three", 3, 435 "four", 4, 436 "five", 5, 437 "six", 6), 438 "one", 439 1, 440 "two", 441 2, 442 "three", 443 3, 444 "four", 445 4, 446 "five", 447 5, 448 "six", 449 6); 450 assertMapEquals( 451 ImmutableBiMap.of( 452 "one", 1, 453 "two", 2, 454 "three", 3, 455 "four", 4, 456 "five", 5, 457 "six", 6, 458 "seven", 7), 459 "one", 460 1, 461 "two", 462 2, 463 "three", 464 3, 465 "four", 466 4, 467 "five", 468 5, 469 "six", 470 6, 471 "seven", 472 7); 473 assertMapEquals( 474 ImmutableBiMap.of( 475 "one", 1, 476 "two", 2, 477 "three", 3, 478 "four", 4, 479 "five", 5, 480 "six", 6, 481 "seven", 7, 482 "eight", 8), 483 "one", 484 1, 485 "two", 486 2, 487 "three", 488 3, 489 "four", 490 4, 491 "five", 492 5, 493 "six", 494 6, 495 "seven", 496 7, 497 "eight", 498 8); 499 assertMapEquals( 500 ImmutableBiMap.of( 501 "one", 1, 502 "two", 2, 503 "three", 3, 504 "four", 4, 505 "five", 5, 506 "six", 6, 507 "seven", 7, 508 "eight", 8, 509 "nine", 9), 510 "one", 511 1, 512 "two", 513 2, 514 "three", 515 3, 516 "four", 517 4, 518 "five", 519 5, 520 "six", 521 6, 522 "seven", 523 7, 524 "eight", 525 8, 526 "nine", 527 9); 528 assertMapEquals( 529 ImmutableBiMap.of( 530 "one", 1, 531 "two", 2, 532 "three", 3, 533 "four", 4, 534 "five", 5, 535 "six", 6, 536 "seven", 7, 537 "eight", 8, 538 "nine", 9, 539 "ten", 10), 540 "one", 541 1, 542 "two", 543 2, 544 "three", 545 3, 546 "four", 547 4, 548 "five", 549 5, 550 "six", 551 6, 552 "seven", 553 7, 554 "eight", 555 8, 556 "nine", 557 9, 558 "ten", 559 10); 560 } 561 testOfNullKey()562 public void testOfNullKey() { 563 try { 564 ImmutableBiMap.of(null, 1); 565 fail(); 566 } catch (NullPointerException expected) { 567 } 568 569 try { 570 ImmutableBiMap.of("one", 1, null, 2); 571 fail(); 572 } catch (NullPointerException expected) { 573 } 574 } 575 testOfNullValue()576 public void testOfNullValue() { 577 try { 578 ImmutableBiMap.of("one", null); 579 fail(); 580 } catch (NullPointerException expected) { 581 } 582 583 try { 584 ImmutableBiMap.of("one", 1, "two", null); 585 fail(); 586 } catch (NullPointerException expected) { 587 } 588 } 589 testOfWithDuplicateKey()590 public void testOfWithDuplicateKey() { 591 try { 592 ImmutableBiMap.of("one", 1, "one", 1); 593 fail(); 594 } catch (IllegalArgumentException expected) { 595 assertThat(expected.getMessage()).contains("one"); 596 } 597 } 598 testOfEntries()599 public void testOfEntries() { 600 assertMapEquals( 601 ImmutableBiMap.ofEntries(entry("one", 1), entry("two", 2)), "one", 1, "two", 2); 602 } 603 testOfEntriesNull()604 public void testOfEntriesNull() { 605 Entry<Integer, Integer> nullKey = entry(null, 23); 606 try { 607 ImmutableBiMap.ofEntries(nullKey); 608 fail(); 609 } catch (NullPointerException expected) { 610 } 611 Entry<Integer, Integer> nullValue = entry(23, null); 612 try { 613 ImmutableBiMap.ofEntries(nullValue); 614 fail(); 615 } catch (NullPointerException expected) { 616 } 617 } 618 entry(T key, T value)619 private static <T> Entry<T, T> entry(T key, T value) { 620 return new AbstractMap.SimpleImmutableEntry<>(key, value); 621 } 622 testCopyOfEmptyMap()623 public void testCopyOfEmptyMap() { 624 ImmutableBiMap<String, Integer> copy = 625 ImmutableBiMap.copyOf(Collections.<String, Integer>emptyMap()); 626 assertEquals(Collections.<String, Integer>emptyMap(), copy); 627 assertSame(copy, ImmutableBiMap.copyOf(copy)); 628 assertSame(ImmutableBiMap.of(), copy); 629 } 630 testCopyOfSingletonMap()631 public void testCopyOfSingletonMap() { 632 ImmutableBiMap<String, Integer> copy = 633 ImmutableBiMap.copyOf(Collections.singletonMap("one", 1)); 634 assertMapEquals(copy, "one", 1); 635 assertSame(copy, ImmutableBiMap.copyOf(copy)); 636 } 637 testCopyOf()638 public void testCopyOf() { 639 Map<String, Integer> original = new LinkedHashMap<>(); 640 original.put("one", 1); 641 original.put("two", 2); 642 original.put("three", 3); 643 644 ImmutableBiMap<String, Integer> copy = ImmutableBiMap.copyOf(original); 645 assertMapEquals(copy, "one", 1, "two", 2, "three", 3); 646 assertSame(copy, ImmutableBiMap.copyOf(copy)); 647 } 648 testEmpty()649 public void testEmpty() { 650 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.of(); 651 assertEquals(Collections.<String, Integer>emptyMap(), bimap); 652 assertEquals(Collections.<String, Integer>emptyMap(), bimap.inverse()); 653 } 654 testFromHashMap()655 public void testFromHashMap() { 656 Map<String, Integer> hashMap = Maps.newLinkedHashMap(); 657 hashMap.put("one", 1); 658 hashMap.put("two", 2); 659 ImmutableBiMap<String, Integer> bimap = 660 ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2)); 661 assertMapEquals(bimap, "one", 1, "two", 2); 662 assertMapEquals(bimap.inverse(), 1, "one", 2, "two"); 663 } 664 testFromImmutableMap()665 public void testFromImmutableMap() { 666 ImmutableBiMap<String, Integer> bimap = 667 ImmutableBiMap.copyOf( 668 new ImmutableMap.Builder<String, Integer>() 669 .put("one", 1) 670 .put("two", 2) 671 .put("three", 3) 672 .put("four", 4) 673 .put("five", 5) 674 .build()); 675 assertMapEquals(bimap, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 676 assertMapEquals(bimap.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); 677 } 678 testDuplicateValues()679 public void testDuplicateValues() { 680 ImmutableMap<String, Integer> map = 681 new ImmutableMap.Builder<String, Integer>() 682 .put("one", 1) 683 .put("two", 2) 684 .put("uno", 1) 685 .put("dos", 2) 686 .build(); 687 688 try { 689 ImmutableBiMap.copyOf(map); 690 fail(); 691 } catch (IllegalArgumentException expected) { 692 assertThat(expected.getMessage()).contains("1"); 693 } 694 } 695 testToImmutableBiMap()696 public void testToImmutableBiMap() { 697 Collector<Entry<String, Integer>, ?, ImmutableBiMap<String, Integer>> collector = 698 ImmutableBiMap.toImmutableBiMap(Entry::getKey, Entry::getValue); 699 Equivalence<ImmutableBiMap<String, Integer>> equivalence = 700 Equivalence.equals() 701 .<Entry<String, Integer>>pairwise() 702 .onResultOf(ImmutableBiMap::entrySet); 703 CollectorTester.of(collector, equivalence) 704 .expectCollects( 705 ImmutableBiMap.of("one", 1, "two", 2, "three", 3), 706 mapEntry("one", 1), 707 mapEntry("two", 2), 708 mapEntry("three", 3)); 709 } 710 testToImmutableBiMap_exceptionOnDuplicateKey()711 public void testToImmutableBiMap_exceptionOnDuplicateKey() { 712 Collector<Entry<String, Integer>, ?, ImmutableBiMap<String, Integer>> collector = 713 ImmutableBiMap.toImmutableBiMap(Entry::getKey, Entry::getValue); 714 try { 715 Stream.of(mapEntry("one", 1), mapEntry("one", 11)).collect(collector); 716 fail("Expected IllegalArgumentException"); 717 } catch (IllegalArgumentException expected) { 718 } 719 } 720 } 721 722 public static class BiMapSpecificTests extends TestCase { 723 testForcePut()724 public void testForcePut() { 725 BiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2)); 726 try { 727 bimap.forcePut("three", 3); 728 fail(); 729 } catch (UnsupportedOperationException expected) { 730 } 731 } 732 testKeySet()733 public void testKeySet() { 734 ImmutableBiMap<String, Integer> bimap = 735 ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4)); 736 Set<String> keys = bimap.keySet(); 737 assertEquals(Sets.newHashSet("one", "two", "three", "four"), keys); 738 assertThat(keys).containsExactly("one", "two", "three", "four").inOrder(); 739 } 740 testValues()741 public void testValues() { 742 ImmutableBiMap<String, Integer> bimap = 743 ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4)); 744 Set<Integer> values = bimap.values(); 745 assertEquals(Sets.newHashSet(1, 2, 3, 4), values); 746 assertThat(values).containsExactly(1, 2, 3, 4).inOrder(); 747 } 748 testDoubleInverse()749 public void testDoubleInverse() { 750 ImmutableBiMap<String, Integer> bimap = 751 ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2)); 752 assertSame(bimap, bimap.inverse().inverse()); 753 } 754 755 @GwtIncompatible // SerializableTester testEmptySerialization()756 public void testEmptySerialization() { 757 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.of(); 758 assertSame(bimap, SerializableTester.reserializeAndAssert(bimap)); 759 } 760 761 @GwtIncompatible // SerializableTester testSerialization()762 public void testSerialization() { 763 ImmutableBiMap<String, Integer> bimap = 764 ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2)); 765 ImmutableBiMap<String, Integer> copy = SerializableTester.reserializeAndAssert(bimap); 766 assertEquals(Integer.valueOf(1), copy.get("one")); 767 assertEquals("one", copy.inverse().get(1)); 768 assertSame(copy, copy.inverse().inverse()); 769 } 770 771 @GwtIncompatible // SerializableTester testInverseSerialization()772 public void testInverseSerialization() { 773 ImmutableBiMap<String, Integer> bimap = 774 ImmutableBiMap.copyOf(ImmutableMap.of(1, "one", 2, "two")).inverse(); 775 ImmutableBiMap<String, Integer> copy = SerializableTester.reserializeAndAssert(bimap); 776 assertEquals(Integer.valueOf(1), copy.get("one")); 777 assertEquals("one", copy.inverse().get(1)); 778 assertSame(copy, copy.inverse().inverse()); 779 } 780 } 781 assertMapEquals(Map<K, V> map, Object... alternatingKeysAndValues)782 private static <K, V> void assertMapEquals(Map<K, V> map, Object... alternatingKeysAndValues) { 783 int i = 0; 784 for (Entry<K, V> entry : map.entrySet()) { 785 assertEquals(alternatingKeysAndValues[i++], entry.getKey()); 786 assertEquals(alternatingKeysAndValues[i++], entry.getValue()); 787 } 788 } 789 790 public static class FloodingTest extends AbstractHashFloodingTest<BiMap<Object, Object>> { FloodingTest()791 public FloodingTest() { 792 super( 793 EnumSet.allOf(ConstructionPathway.class).stream() 794 .flatMap( 795 path -> 796 Stream.<Construction<BiMap<Object, Object>>>of( 797 keys -> 798 path.create( 799 Lists.transform( 800 keys, key -> Maps.immutableEntry(key, new Object()))), 801 keys -> 802 path.create( 803 Lists.transform( 804 keys, key -> Maps.immutableEntry(new Object(), key))), 805 keys -> 806 path.create( 807 Lists.transform(keys, key -> Maps.immutableEntry(key, key))))) 808 .collect(ImmutableList.toImmutableList()), 809 n -> n * Math.log(n), 810 ImmutableList.of( 811 QueryOp.create("BiMap.get", BiMap::get, Math::log), 812 QueryOp.create("BiMap.inverse.get", (bm, o) -> bm.inverse().get(o), Math::log))); 813 } 814 815 /** All the ways to create an ImmutableBiMap. */ 816 enum ConstructionPathway { 817 COPY_OF_MAP { 818 @Override create(List<Map.Entry<?, ?>> entries)819 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 820 Map<Object, Object> sourceMap = new LinkedHashMap<>(); 821 for (Map.Entry<?, ?> entry : entries) { 822 if (sourceMap.put(entry.getKey(), entry.getValue()) != null) { 823 throw new UnsupportedOperationException("duplicate key"); 824 } 825 } 826 return ImmutableBiMap.copyOf(sourceMap); 827 } 828 }, 829 COPY_OF_ENTRIES { 830 @Override create(List<Map.Entry<?, ?>> entries)831 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 832 return ImmutableBiMap.copyOf(entries); 833 } 834 }, 835 BUILDER_PUT_ONE_BY_ONE { 836 @Override create(List<Map.Entry<?, ?>> entries)837 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 838 ImmutableBiMap.Builder<Object, Object> builder = ImmutableBiMap.builder(); 839 for (Map.Entry<?, ?> entry : entries) { 840 builder.put(entry.getKey(), entry.getValue()); 841 } 842 return builder.build(); 843 } 844 }, 845 BUILDER_PUT_ALL_MAP { 846 @Override create(List<Map.Entry<?, ?>> entries)847 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 848 Map<Object, Object> sourceMap = new LinkedHashMap<>(); 849 for (Map.Entry<?, ?> entry : entries) { 850 if (sourceMap.put(entry.getKey(), entry.getValue()) != null) { 851 throw new UnsupportedOperationException("duplicate key"); 852 } 853 } 854 ImmutableBiMap.Builder<Object, Object> builder = ImmutableBiMap.builder(); 855 builder.putAll(sourceMap); 856 return builder.build(); 857 } 858 }, 859 BUILDER_PUT_ALL_ENTRIES { 860 @Override create(List<Map.Entry<?, ?>> entries)861 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 862 return ImmutableBiMap.builder().putAll(entries).build(); 863 } 864 }, 865 FORCE_JDK { 866 @Override create(List<Map.Entry<?, ?>> entries)867 public ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries) { 868 return ImmutableBiMap.builder().putAll(entries).buildJdkBacked(); 869 } 870 }; 871 872 @CanIgnoreReturnValue create(List<Map.Entry<?, ?>> entries)873 public abstract ImmutableBiMap<Object, Object> create(List<Map.Entry<?, ?>> entries); 874 } 875 } 876 877 /** No-op test so that the class has at least one method, making Maven's test runner happy. */ testNoop()878 public void testNoop() {} 879 } 880