1 /* 2 * Copyright (C) 2009 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 org.junit.contrib.truth.Truth.ASSERT; 20 21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.base.Joiner; 24 import com.google.common.collect.ImmutableSortedMap.Builder; 25 import com.google.common.collect.testing.CollectionTestSuiteBuilder; 26 import com.google.common.collect.testing.ReserializingTestCollectionGenerator; 27 import com.google.common.collect.testing.ReserializingTestSetGenerator; 28 import com.google.common.collect.testing.SetTestSuiteBuilder; 29 import com.google.common.collect.testing.SortedMapInterfaceTest; 30 import com.google.common.collect.testing.features.CollectionFeature; 31 import com.google.common.collect.testing.features.CollectionSize; 32 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapEntrySetGenerator; 33 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapHeadMapKeySetGenerator; 34 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapKeySetGenerator; 35 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapSubMapEntryGenerator; 36 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapTailMapValuesGenerator; 37 import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapValuesGenerator; 38 import com.google.common.testing.NullPointerTester; 39 import com.google.common.testing.SerializableTester; 40 41 import junit.framework.Test; 42 import junit.framework.TestCase; 43 import junit.framework.TestSuite; 44 45 import java.io.Serializable; 46 import java.util.Collections; 47 import java.util.Comparator; 48 import java.util.LinkedHashMap; 49 import java.util.Map; 50 import java.util.Map.Entry; 51 import java.util.SortedMap; 52 53 /** 54 * Tests for {@link ImmutableSortedMap}. 55 * 56 * @author Kevin Bourrillion 57 * @author Jesse Wilson 58 * @author Jared Levy 59 */ 60 @GwtCompatible(emulated = true) 61 public class ImmutableSortedMapTest extends TestCase { 62 // TODO: Avoid duplicating code in ImmutableMapTest 63 64 @GwtIncompatible("suite") 65 public static Test suite() { 66 TestSuite suite = new TestSuite(); 67 suite.addTestSuite(ImmutableSortedMapTest.class); 68 69 suite.addTest(SetTestSuiteBuilder.using( 70 new ImmutableSortedMapKeySetGenerator()) 71 .withFeatures( 72 CollectionSize.ANY, 73 CollectionFeature.KNOWN_ORDER, 74 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 75 CollectionFeature.ALLOWS_NULL_QUERIES) 76 .named("ImmutableSortedMap.keySet") 77 .createTestSuite()); 78 79 suite.addTest(SetTestSuiteBuilder.using( 80 new ImmutableSortedMapEntrySetGenerator()) 81 .withFeatures( 82 CollectionSize.ANY, 83 CollectionFeature.KNOWN_ORDER, 84 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 85 CollectionFeature.ALLOWS_NULL_QUERIES) 86 .named("ImmutableSortedMap.entrySet") 87 .createTestSuite()); 88 89 suite.addTest(CollectionTestSuiteBuilder.using( 90 new ImmutableSortedMapValuesGenerator()) 91 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, 92 CollectionFeature.ALLOWS_NULL_QUERIES) 93 .named("ImmutableSortedMap.values") 94 .createTestSuite()); 95 96 suite.addTest(SetTestSuiteBuilder.using( 97 ReserializingTestSetGenerator.newInstance( 98 new ImmutableSortedMapKeySetGenerator())) 99 .withFeatures( 100 CollectionSize.ANY, 101 CollectionFeature.KNOWN_ORDER, 102 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 103 CollectionFeature.ALLOWS_NULL_QUERIES) 104 .named("ImmutableSortedMap.keySet, reserialized") 105 .createTestSuite()); 106 107 suite.addTest(SetTestSuiteBuilder.using( 108 ReserializingTestSetGenerator.newInstance( 109 new ImmutableSortedMapEntrySetGenerator())) 110 .withFeatures( 111 CollectionSize.ANY, 112 CollectionFeature.KNOWN_ORDER, 113 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 114 CollectionFeature.ALLOWS_NULL_QUERIES) 115 .named("ImmutableSortedMap.entrySet, reserialized") 116 .createTestSuite()); 117 118 suite.addTest(CollectionTestSuiteBuilder.using( 119 ReserializingTestCollectionGenerator.newInstance( 120 new ImmutableSortedMapValuesGenerator())) 121 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, 122 CollectionFeature.ALLOWS_NULL_QUERIES) 123 .named("ImmutableSortedMap.values, reserialized") 124 .createTestSuite()); 125 126 suite.addTest(SetTestSuiteBuilder.using( 127 new ImmutableSortedMapHeadMapKeySetGenerator()) 128 .withFeatures( 129 CollectionSize.ANY, 130 CollectionFeature.KNOWN_ORDER, 131 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 132 CollectionFeature.ALLOWS_NULL_QUERIES) 133 .named("ImmutableSortedMap.headMap.keySet") 134 .createTestSuite()); 135 136 suite.addTest(SetTestSuiteBuilder.using( 137 new ImmutableSortedMapSubMapEntryGenerator()) 138 .withFeatures( 139 CollectionSize.ANY, 140 CollectionFeature.KNOWN_ORDER, 141 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 142 CollectionFeature.ALLOWS_NULL_QUERIES) 143 .named("ImmutableSortedMap.subMap.entrySet") 144 .createTestSuite()); 145 146 suite.addTest(CollectionTestSuiteBuilder.using( 147 new ImmutableSortedMapTailMapValuesGenerator()) 148 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, 149 CollectionFeature.ALLOWS_NULL_QUERIES) 150 .named("ImmutableSortedMap.tailMap.values") 151 .createTestSuite()); 152 153 return suite; 154 } 155 156 public abstract static class AbstractMapTests<K, V> 157 extends SortedMapInterfaceTest<K, V> { 158 public AbstractMapTests() { 159 super(false, false, false, false, false); 160 } 161 162 @Override protected SortedMap<K, V> makeEmptyMap() { 163 throw new UnsupportedOperationException(); 164 } 165 166 private static final Joiner joiner = Joiner.on(", "); 167 168 @Override protected void assertMoreInvariants(Map<K, V> map) { 169 // TODO: can these be moved to MapInterfaceTest? 170 for (Entry<K, V> entry : map.entrySet()) { 171 assertEquals(entry.getKey() + "=" + entry.getValue(), 172 entry.toString()); 173 } 174 175 assertEquals("{" + joiner.join(map.entrySet()) + "}", 176 map.toString()); 177 assertEquals("[" + joiner.join(map.entrySet()) + "]", 178 map.entrySet().toString()); 179 assertEquals("[" + joiner.join(map.keySet()) + "]", 180 map.keySet().toString()); 181 assertEquals("[" + joiner.join(map.values()) + "]", 182 map.values().toString()); 183 184 assertEquals(Sets.newHashSet(map.entrySet()), map.entrySet()); 185 assertEquals(Sets.newHashSet(map.keySet()), map.keySet()); 186 } 187 } 188 189 public static class MapTests extends AbstractMapTests<String, Integer> { 190 @Override protected SortedMap<String, Integer> makeEmptyMap() { 191 return ImmutableSortedMap.of(); 192 } 193 194 @Override protected SortedMap<String, Integer> makePopulatedMap() { 195 return ImmutableSortedMap.of("one", 1, "two", 2, "three", 3); 196 } 197 198 @Override protected String getKeyNotInPopulatedMap() { 199 return "minus one"; 200 } 201 202 @Override protected Integer getValueNotInPopulatedMap() { 203 return -1; 204 } 205 } 206 207 public static class SingletonMapTests 208 extends AbstractMapTests<String, Integer> { 209 @Override protected SortedMap<String, Integer> makePopulatedMap() { 210 return ImmutableSortedMap.of("one", 1); 211 } 212 213 @Override protected String getKeyNotInPopulatedMap() { 214 return "minus one"; 215 } 216 217 @Override protected Integer getValueNotInPopulatedMap() { 218 return -1; 219 } 220 } 221 222 @GwtIncompatible("SerializableTester") 223 public static class ReserializedMapTests 224 extends AbstractMapTests<String, Integer> { 225 @Override protected SortedMap<String, Integer> makePopulatedMap() { 226 return SerializableTester.reserialize( 227 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3)); 228 } 229 230 @Override protected String getKeyNotInPopulatedMap() { 231 return "minus one"; 232 } 233 234 @Override protected Integer getValueNotInPopulatedMap() { 235 return -1; 236 } 237 } 238 239 public static class HeadMapTests extends AbstractMapTests<String, Integer> { 240 @Override protected SortedMap<String, Integer> makePopulatedMap() { 241 return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5) 242 .headMap("d"); 243 } 244 245 @Override protected String getKeyNotInPopulatedMap() { 246 return "d"; 247 } 248 249 @Override protected Integer getValueNotInPopulatedMap() { 250 return 4; 251 } 252 } 253 254 public static class HeadMapInclusiveTests extends AbstractMapTests<String, Integer> { 255 @Override protected SortedMap<String, Integer> makePopulatedMap() { 256 return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5) 257 .headMap("c", true); 258 } 259 260 @Override protected String getKeyNotInPopulatedMap() { 261 return "d"; 262 } 263 264 @Override protected Integer getValueNotInPopulatedMap() { 265 return 4; 266 } 267 } 268 269 public static class TailMapTests extends AbstractMapTests<String, Integer> { 270 @Override protected SortedMap<String, Integer> makePopulatedMap() { 271 return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5) 272 .tailMap("b"); 273 } 274 275 @Override protected String getKeyNotInPopulatedMap() { 276 return "a"; 277 } 278 279 @Override protected Integer getValueNotInPopulatedMap() { 280 return 1; 281 } 282 } 283 284 public static class TailExclusiveMapTests extends AbstractMapTests<String, Integer> { 285 @Override protected SortedMap<String, Integer> makePopulatedMap() { 286 return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5) 287 .tailMap("a", false); 288 } 289 290 @Override protected String getKeyNotInPopulatedMap() { 291 return "a"; 292 } 293 294 @Override protected Integer getValueNotInPopulatedMap() { 295 return 1; 296 } 297 } 298 299 public static class SubMapTests extends AbstractMapTests<String, Integer> { 300 @Override protected SortedMap<String, Integer> makePopulatedMap() { 301 return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5) 302 .subMap("b", "d"); 303 } 304 305 @Override protected String getKeyNotInPopulatedMap() { 306 return "a"; 307 } 308 309 @Override protected Integer getValueNotInPopulatedMap() { 310 return 4; 311 } 312 } 313 314 public static class CreationTests extends TestCase { 315 public void testEmptyBuilder() { 316 ImmutableSortedMap<String, Integer> map 317 = ImmutableSortedMap.<String, Integer>naturalOrder().build(); 318 assertEquals(Collections.<String, Integer>emptyMap(), map); 319 } 320 321 public void testSingletonBuilder() { 322 ImmutableSortedMap<String, Integer> map 323 = ImmutableSortedMap.<String, Integer>naturalOrder() 324 .put("one", 1) 325 .build(); 326 assertMapEquals(map, "one", 1); 327 } 328 329 public void testBuilder() { 330 ImmutableSortedMap<String, Integer> map 331 = ImmutableSortedMap.<String, Integer>naturalOrder() 332 .put("one", 1) 333 .put("two", 2) 334 .put("three", 3) 335 .put("four", 4) 336 .put("five", 5) 337 .build(); 338 assertMapEquals(map, 339 "five", 5, "four", 4, "one", 1, "three", 3, "two", 2); 340 } 341 342 public void testBuilder_withImmutableEntry() { 343 ImmutableSortedMap<String, Integer> map = 344 ImmutableSortedMap.<String, Integer>naturalOrder() 345 .put(Maps.immutableEntry("one", 1)) 346 .build(); 347 assertMapEquals(map, "one", 1); 348 } 349 350 public void testBuilder_withImmutableEntryAndNullContents() { 351 Builder<String, Integer> builder = 352 ImmutableSortedMap.naturalOrder(); 353 try { 354 builder.put(Maps.immutableEntry("one", (Integer) null)); 355 fail(); 356 } catch (NullPointerException expected) { 357 } 358 try { 359 builder.put(Maps.immutableEntry((String) null, 1)); 360 fail(); 361 } catch (NullPointerException expected) { 362 } 363 } 364 365 private static class StringHolder { 366 String string; 367 } 368 369 public void testBuilder_withMutableEntry() { 370 ImmutableSortedMap.Builder<String, Integer> builder = 371 ImmutableSortedMap.naturalOrder(); 372 final StringHolder holder = new StringHolder(); 373 holder.string = "one"; 374 Entry<String, Integer> entry = new AbstractMapEntry<String, Integer>() { 375 @Override public String getKey() { 376 return holder.string; 377 } 378 @Override public Integer getValue() { 379 return 1; 380 } 381 }; 382 383 builder.put(entry); 384 holder.string = "two"; 385 assertMapEquals(builder.build(), "one", 1); 386 } 387 388 public void testBuilderPutAllWithEmptyMap() { 389 ImmutableSortedMap<String, Integer> map 390 = ImmutableSortedMap.<String, Integer>naturalOrder() 391 .putAll(Collections.<String, Integer>emptyMap()) 392 .build(); 393 assertEquals(Collections.<String, Integer>emptyMap(), map); 394 } 395 396 public void testBuilderPutAll() { 397 Map<String, Integer> toPut = new LinkedHashMap<String, Integer>(); 398 toPut.put("one", 1); 399 toPut.put("two", 2); 400 toPut.put("three", 3); 401 Map<String, Integer> moreToPut = new LinkedHashMap<String, Integer>(); 402 moreToPut.put("four", 4); 403 moreToPut.put("five", 5); 404 405 ImmutableSortedMap<String, Integer> map 406 = ImmutableSortedMap.<String, Integer>naturalOrder() 407 .putAll(toPut) 408 .putAll(moreToPut) 409 .build(); 410 assertMapEquals(map, 411 "five", 5, "four", 4, "one", 1, "three", 3, "two", 2); 412 } 413 414 public void testBuilderReuse() { 415 Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder(); 416 ImmutableSortedMap<String, Integer> mapOne = builder 417 .put("one", 1) 418 .put("two", 2) 419 .build(); 420 ImmutableSortedMap<String, Integer> mapTwo = builder 421 .put("three", 3) 422 .put("four", 4) 423 .build(); 424 425 assertMapEquals(mapOne, "one", 1, "two", 2); 426 assertMapEquals(mapTwo, "four", 4, "one", 1, "three", 3, "two", 2); 427 } 428 429 public void testBuilderPutNullKey() { 430 Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder(); 431 try { 432 builder.put(null, 1); 433 fail(); 434 } catch (NullPointerException expected) { 435 } 436 } 437 438 public void testBuilderPutNullValue() { 439 Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder(); 440 try { 441 builder.put("one", null); 442 fail(); 443 } catch (NullPointerException expected) { 444 } 445 } 446 447 public void testBuilderPutNullKeyViaPutAll() { 448 Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder(); 449 try { 450 builder.putAll(Collections.<String, Integer>singletonMap(null, 1)); 451 fail(); 452 } catch (NullPointerException expected) { 453 } 454 } 455 456 public void testBuilderPutNullValueViaPutAll() { 457 Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder(); 458 try { 459 builder.putAll(Collections.<String, Integer>singletonMap("one", null)); 460 fail(); 461 } catch (NullPointerException expected) { 462 } 463 } 464 465 public void testPuttingTheSameKeyTwiceThrowsOnBuild() { 466 Builder<String, Integer> builder 467 = ImmutableSortedMap.<String, Integer>naturalOrder() 468 .put("one", 1) 469 .put("one", 2); // throwing on this line would be even better 470 471 try { 472 builder.build(); 473 fail(); 474 } catch (IllegalArgumentException expected) { 475 assertEquals("Duplicate keys in mappings one=1 and one=2", 476 expected.getMessage()); 477 } 478 } 479 480 public void testOf() { 481 assertMapEquals( 482 ImmutableSortedMap.of("one", 1), 483 "one", 1); 484 assertMapEquals( 485 ImmutableSortedMap.of("one", 1, "two", 2), 486 "one", 1, "two", 2); 487 assertMapEquals( 488 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3), 489 "one", 1, "three", 3, "two", 2); 490 assertMapEquals( 491 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3, "four", 4), 492 "four", 4, "one", 1, "three", 3, "two", 2); 493 assertMapEquals( 494 ImmutableSortedMap.of( 495 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5), 496 "five", 5, "four", 4, "one", 1, "three", 3, "two", 2); 497 } 498 499 public void testOfNullKey() { 500 Integer n = null; 501 try { 502 ImmutableSortedMap.of(n, 1); 503 fail(); 504 } catch (NullPointerException expected) { 505 } 506 507 try { 508 ImmutableSortedMap.of("one", 1, null, 2); 509 fail(); 510 } catch (NullPointerException expected) { 511 } 512 } 513 514 public void testOfNullValue() { 515 try { 516 ImmutableSortedMap.of("one", null); 517 fail(); 518 } catch (NullPointerException expected) { 519 } 520 521 try { 522 ImmutableSortedMap.of("one", 1, "two", null); 523 fail(); 524 } catch (NullPointerException expected) { 525 } 526 } 527 528 public void testOfWithDuplicateKey() { 529 try { 530 ImmutableSortedMap.of("one", 1, "one", 1); 531 fail(); 532 } catch (IllegalArgumentException expected) { 533 assertEquals("Duplicate keys in mappings one=1 and one=1", 534 expected.getMessage()); 535 } 536 } 537 538 public void testCopyOfEmptyMap() { 539 ImmutableSortedMap<String, Integer> copy 540 = ImmutableSortedMap.copyOf(Collections.<String, Integer>emptyMap()); 541 assertEquals(Collections.<String, Integer>emptyMap(), copy); 542 assertSame(copy, ImmutableSortedMap.copyOf(copy)); 543 assertSame(Ordering.natural(), copy.comparator()); 544 } 545 546 public void testCopyOfSingletonMap() { 547 ImmutableSortedMap<String, Integer> copy 548 = ImmutableSortedMap.copyOf(Collections.singletonMap("one", 1)); 549 assertMapEquals(copy, "one", 1); 550 assertSame(copy, ImmutableSortedMap.copyOf(copy)); 551 assertSame(Ordering.natural(), copy.comparator()); 552 } 553 554 public void testCopyOf() { 555 Map<String, Integer> original = new LinkedHashMap<String, Integer>(); 556 original.put("one", 1); 557 original.put("two", 2); 558 original.put("three", 3); 559 560 ImmutableSortedMap<String, Integer> copy 561 = ImmutableSortedMap.copyOf(original); 562 assertMapEquals(copy, "one", 1, "three", 3, "two", 2); 563 assertSame(copy, ImmutableSortedMap.copyOf(copy)); 564 assertSame(Ordering.natural(), copy.comparator()); 565 } 566 567 public void testCopyOfExplicitComparator() { 568 Comparator<String> comparator = Ordering.natural().reverse(); 569 Map<String, Integer> original = new LinkedHashMap<String, Integer>(); 570 original.put("one", 1); 571 original.put("two", 2); 572 original.put("three", 3); 573 574 ImmutableSortedMap<String, Integer> copy 575 = ImmutableSortedMap.copyOf(original, comparator); 576 assertMapEquals(copy, "two", 2, "three", 3, "one", 1); 577 assertSame(copy, ImmutableSortedMap.copyOf(copy, comparator)); 578 assertSame(comparator, copy.comparator()); 579 } 580 581 public void testCopyOfImmutableSortedSetDifferentComparator() { 582 Comparator<String> comparator = Ordering.natural().reverse(); 583 Map<String, Integer> original 584 = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3); 585 ImmutableSortedMap<String, Integer> copy 586 = ImmutableSortedMap.copyOf(original, comparator); 587 assertMapEquals(copy, "two", 2, "three", 3, "one", 1); 588 assertSame(copy, ImmutableSortedMap.copyOf(copy, comparator)); 589 assertSame(comparator, copy.comparator()); 590 } 591 592 public void testCopyOfSortedNatural() { 593 SortedMap<String, Integer> original = Maps.newTreeMap(); 594 original.put("one", 1); 595 original.put("two", 2); 596 original.put("three", 3); 597 598 ImmutableSortedMap<String, Integer> copy 599 = ImmutableSortedMap.copyOfSorted(original); 600 assertMapEquals(copy, "one", 1, "three", 3, "two", 2); 601 assertSame(copy, ImmutableSortedMap.copyOfSorted(copy)); 602 assertSame(Ordering.natural(), copy.comparator()); 603 } 604 605 public void testCopyOfSortedExplicit() { 606 Comparator<String> comparator = Ordering.natural().reverse(); 607 SortedMap<String, Integer> original = Maps.newTreeMap(comparator); 608 original.put("one", 1); 609 original.put("two", 2); 610 original.put("three", 3); 611 612 ImmutableSortedMap<String, Integer> copy 613 = ImmutableSortedMap.copyOfSorted(original); 614 assertMapEquals(copy, "two", 2, "three", 3, "one", 1); 615 assertSame(copy, ImmutableSortedMap.copyOfSorted(copy)); 616 assertSame(comparator, copy.comparator()); 617 } 618 619 private static class IntegerDiv10 implements Comparable<IntegerDiv10> { 620 final int value; 621 622 IntegerDiv10(int value) { 623 this.value = value; 624 } 625 626 @Override 627 public int compareTo(IntegerDiv10 o) { 628 return value / 10 - o.value / 10; 629 } 630 631 @Override public String toString() { 632 return Integer.toString(value); 633 } 634 } 635 636 public void testCopyOfDuplicateKey() { 637 Map<IntegerDiv10, String> original = ImmutableMap.of( 638 new IntegerDiv10(3), "three", 639 new IntegerDiv10(20), "twenty", 640 new IntegerDiv10(11), "eleven", 641 new IntegerDiv10(35), "thirty five", 642 new IntegerDiv10(12), "twelve" 643 ); 644 645 try { 646 ImmutableSortedMap.copyOf(original); 647 fail("Expected IllegalArgumentException"); 648 } catch (IllegalArgumentException expected) { 649 assertEquals("Duplicate keys in mappings 11=eleven and 12=twelve", 650 expected.getMessage()); 651 } 652 } 653 654 public void testImmutableMapCopyOfImmutableSortedMap() { 655 IntegerDiv10 three = new IntegerDiv10(3); 656 IntegerDiv10 eleven = new IntegerDiv10(11); 657 IntegerDiv10 twelve = new IntegerDiv10(12); 658 IntegerDiv10 twenty = new IntegerDiv10(20); 659 Map<IntegerDiv10, String> original = ImmutableSortedMap.of( 660 three, "three", eleven, "eleven", twenty, "twenty"); 661 Map<IntegerDiv10, String> copy = ImmutableMap.copyOf(original); 662 assertTrue(original.containsKey(twelve)); 663 assertFalse(copy.containsKey(twelve)); 664 } 665 666 public void testBuilderReverseOrder() { 667 ImmutableSortedMap<String, Integer> map 668 = ImmutableSortedMap.<String, Integer>reverseOrder() 669 .put("one", 1) 670 .put("two", 2) 671 .put("three", 3) 672 .put("four", 4) 673 .put("five", 5) 674 .build(); 675 assertMapEquals(map, 676 "two", 2, "three", 3, "one", 1, "four", 4, "five", 5); 677 assertEquals(Ordering.natural().reverse(), map.comparator()); 678 } 679 680 public void testBuilderComparator() { 681 Comparator<String> comparator = Ordering.natural().reverse(); 682 ImmutableSortedMap<String, Integer> map 683 = new ImmutableSortedMap.Builder<String, Integer>(comparator) 684 .put("one", 1) 685 .put("two", 2) 686 .put("three", 3) 687 .put("four", 4) 688 .put("five", 5) 689 .build(); 690 assertMapEquals(map, 691 "two", 2, "three", 3, "one", 1, "four", 4, "five", 5); 692 assertSame(comparator, map.comparator()); 693 } 694 } 695 696 public void testNullGet() { 697 ImmutableSortedMap<String, Integer> map = ImmutableSortedMap.of("one", 1); 698 assertNull(map.get(null)); 699 } 700 701 @GwtIncompatible("NullPointerTester") 702 public void testNullPointers() throws Exception { 703 NullPointerTester tester = new NullPointerTester(); 704 tester.testAllPublicStaticMethods(ImmutableSortedMap.class); 705 tester.testAllPublicInstanceMethods( 706 ImmutableSortedMap.<String, Integer>naturalOrder()); 707 tester.testAllPublicInstanceMethods(ImmutableSortedMap.of()); 708 tester.testAllPublicInstanceMethods(ImmutableSortedMap.of("one", 1)); 709 tester.testAllPublicInstanceMethods( 710 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3)); 711 } 712 713 private static <K, V> void assertMapEquals(Map<K, V> map, 714 Object... alternatingKeysAndValues) { 715 assertEquals(map.size(), alternatingKeysAndValues.length / 2); 716 int i = 0; 717 for (Entry<K, V> entry : map.entrySet()) { 718 assertEquals(alternatingKeysAndValues[i++], entry.getKey()); 719 assertEquals(alternatingKeysAndValues[i++], entry.getValue()); 720 } 721 } 722 723 private static class IntHolder implements Serializable { 724 public int value; 725 726 public IntHolder(int value) { 727 this.value = value; 728 } 729 730 @Override public boolean equals(Object o) { 731 return (o instanceof IntHolder) && ((IntHolder) o).value == value; 732 } 733 734 @Override public int hashCode() { 735 return value; 736 } 737 738 private static final long serialVersionUID = 5; 739 } 740 741 public void testMutableValues() { 742 IntHolder holderA = new IntHolder(1); 743 IntHolder holderB = new IntHolder(2); 744 Map<String, IntHolder> map 745 = ImmutableSortedMap.of("a", holderA, "b", holderB); 746 holderA.value = 3; 747 assertTrue(map.entrySet().contains( 748 Maps.immutableEntry("a", new IntHolder(3)))); 749 Map<String, Integer> intMap 750 = ImmutableSortedMap.of("a", 3, "b", 2); 751 assertEquals(intMap.hashCode(), map.entrySet().hashCode()); 752 assertEquals(intMap.hashCode(), map.hashCode()); 753 } 754 755 @GwtIncompatible("SerializableTester") 756 public void testViewSerialization() { 757 Map<String, Integer> map 758 = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3); 759 SerializableTester.reserializeAndAssert(map.entrySet()); 760 SerializableTester.reserializeAndAssert(map.keySet()); 761 assertEquals(Lists.newArrayList(map.values()), 762 Lists.newArrayList(SerializableTester.reserialize(map.values()))); 763 } 764 765 @SuppressWarnings("unchecked") // varargs 766 public void testHeadMapInclusive() { 767 Map<String, Integer> map = 768 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", true); 769 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1), 770 Maps.immutableEntry("three", 3)); 771 } 772 773 @SuppressWarnings("unchecked") // varargs 774 public void testHeadMapExclusive() { 775 Map<String, Integer> map = 776 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", false); 777 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1)); 778 } 779 780 @SuppressWarnings("unchecked") // varargs 781 public void testTailMapInclusive() { 782 Map<String, Integer> map = 783 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", true); 784 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3), 785 Maps.immutableEntry("two", 2)); 786 } 787 788 @SuppressWarnings("unchecked") // varargs 789 public void testTailMapExclusive() { 790 Map<String, Integer> map = 791 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", false); 792 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("two", 2)); 793 } 794 795 @SuppressWarnings("unchecked") // varargs 796 public void testSubMapExclusiveExclusive() { 797 Map<String, Integer> map = 798 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", false); 799 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3)); 800 } 801 802 @SuppressWarnings("unchecked") // varargs 803 public void testSubMapInclusiveExclusive() { 804 Map<String, Integer> map = 805 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", false); 806 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1), 807 Maps.immutableEntry("three", 3)); 808 } 809 810 @SuppressWarnings("unchecked") // varargs 811 public void testSubMapExclusiveInclusive() { 812 Map<String, Integer> map = 813 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", true); 814 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3), 815 Maps.immutableEntry("two", 2)); 816 } 817 818 @SuppressWarnings("unchecked") // varargs 819 public void testSubMapInclusiveInclusive() { 820 Map<String, Integer> map = 821 ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", true); 822 ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1), 823 Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)); 824 } 825 } 826