MapsTest.java revision 7dd252788645e940eada959bdde927426e2531c9
11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Maps.transformEntries;
207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.Maps.transformValues;
217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.mapEntry;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Functions;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.ValueDifferenceImpl;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.SetsTest.Derived;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.EqualsTester;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase;
377dd252788645e940eada959bdde927426e2531c9Paul Duffin
387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport org.truth0.Truth;
397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport org.truth0.subjects.CollectionSubject;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
427dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.StringBufferInputStream;
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Field;
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays;
457dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.EnumMap;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Enumeration;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashMap;
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.IdentityHashMap;
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap;
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Properties;
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
607dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.SortedSet;
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap;
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap;
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@code Maps}.
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MapsTest extends TestCase {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
747dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Comparator<Integer> SOME_COMPARATOR = Collections.reverseOrder();
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMap() {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<Integer, Integer> map = Maps.newHashMap();
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapWithInitialMap() {
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<String, Integer> map = Maps.newHashMap(original);
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapGeneralizesTypes() {
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
957dd252788645e940eada959bdde927426e2531c9Paul Duffin    HashMap<Object, Object> map = Maps
967dd252788645e940eada959bdde927426e2531c9Paul Duffin        .newHashMap((Map<? extends Object, ? extends Object>) original);
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForNegativeSizeFails() {
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.capacity(-1);
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Negative expected size must result in IllegalArgumentException");
1047dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (IllegalArgumentException ex) {}
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Tests that nHMWES makes hash maps large enough that adding the expected
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * number of elements won't cause a rehash.
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This test may fail miserably on non-OpenJDK environments...
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void notestNewHashMapWithExpectedSize_wontGrow() throws Exception {
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int size = 0; size < 200; size++) {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map1 = Maps.newHashMapWithExpectedSize(size);
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int startSize = sizeOf(map1);
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int i = 0; i < size; i++) {
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        map1.put(i, null);
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("table size after adding " + size + "elements", startSize, sizeOf(map1));
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * Something slightly different happens when the entries are added all at
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * once; make sure that passes too.
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map2 = Maps.newHashMapWithExpectedSize(size);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map2.putAll(map1);
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("table size after adding " + size + "elements", startSize, sizeOf(map2));
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static int sizeOf(HashMap<?, ?> hashMap) throws Exception {
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Field tableField = HashMap.class.getDeclaredField("table");
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tableField.setAccessible(true);
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] table = (Object[]) tableField.get(hashMap);
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return table.length;
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForLargeSizes() {
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin    int[] largeExpectedSizes = new int[] { Integer.MAX_VALUE / 2 - 1, Integer.MAX_VALUE / 2,
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin        Integer.MAX_VALUE / 2 + 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE };
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int expectedSize : largeExpectedSizes) {
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int capacity = Maps.capacity(expectedSize);
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue("capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")",
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          capacity >= expectedSize);
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMap() {
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<Integer, Integer> map = Maps.newLinkedHashMap();
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("serial")
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapWithInitialMap() {
1607dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> map = new LinkedHashMap<String, String>() {
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin      {
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin        put("Hello", "World");
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin        put("first", "second");
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin        put("polygene", "lubricants");
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin        put("alpha", "betical");
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<String, String> copy = Maps.newLinkedHashMap(map);
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<String, String>> iter = copy.entrySet().iterator();
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<String, String> entry = iter.next();
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("Hello", entry.getKey());
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("World", entry.getValue());
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("first", entry.getKey());
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("second", entry.getValue());
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("polygene", entry.getKey());
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("lubricants", entry.getValue());
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("alpha", entry.getKey());
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("betical", entry.getValue());
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(iter.hasNext());
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapGeneralizesTypes() {
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new LinkedHashMap<String, Integer>();
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
1997dd252788645e940eada959bdde927426e2531c9Paul Duffin    HashMap<Object, Object> map = Maps.<Object, Object>newLinkedHashMap(original);
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIdentityHashMap() {
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    IdentityHashMap<Integer, Integer> map = Maps.newIdentityHashMap();
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConcurrentMap() {
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConcurrentMap<Integer, Integer> map = Maps.newConcurrentMap();
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMap() {
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> map = Maps.newTreeMap();
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapDerived() {
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Derived, Integer> map = Maps.newTreeMap();
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("foo"), 1);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("bar"), 2);
2247dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.keySet()).has().allOf(new Derived("bar"), new Derived("foo")).inOrder();
2257dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapNonGeneric() {
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<LegacyComparable, Integer> map = Maps.newTreeMap();
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("foo"), 1);
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("bar"), 2);
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.keySet()).has().allOf(new LegacyComparable("bar"), new LegacyComparable("foo"))
2357dd252788645e940eada959bdde927426e2531c9Paul Duffin        .inOrder();
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithComparator() {
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin    TreeMap<Integer, Integer> map = Maps.<Integer, Integer, Integer>newTreeMap(SOME_COMPARATOR);
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(SOME_COMPARATOR, map.comparator());
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithInitialMap() {
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, Integer> map = Maps.newTreeMap();
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(5, 10);
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(3, 20);
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(1, 30);
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> copy = Maps.newTreeMap(map);
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(copy, map);
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(copy.comparator(), map.comparator());
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin  public enum SomeEnum {
2577dd252788645e940eada959bdde927426e2531c9Paul Duffin    SOME_INSTANCE
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMap() {
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> map = Maps.newEnumMap(SomeEnum.class);
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(SomeEnum.SOME_INSTANCE, 0);
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.singletonMap(SomeEnum.SOME_INSTANCE, 0), map);
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapNullClass() {
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.<SomeEnum, Long>newEnumMap((Class<MapsTest.SomeEnum>) null);
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("no exception thrown");
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException expected) {}
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEnumMap() {
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyEnumMap() {
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotSame(original, copy);
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialMap() {
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<SomeEnum, Integer> original = Maps.newHashMap();
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyMap() {
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<SomeEnum, Integer> original = Maps.newHashMap();
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.newEnumMap(original);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Empty map must result in an IllegalArgumentException");
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {}
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3037dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToStringImplWithNullKeys() throws Exception {
3047dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3057dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("foo", "bar");
3067dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put(null, "baz");
3077dd252788645e940eada959bdde927426e2531c9Paul Duffin
3087dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3097dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3107dd252788645e940eada959bdde927426e2531c9Paul Duffin
3117dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToStringImplWithNullValues() throws Exception {
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("foo", "bar");
3147dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("baz", null);
3157dd252788645e940eada959bdde927426e2531c9Paul Duffin
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("NullPointerTester")
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNullPointerExceptions() {
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin    new NullPointerTester().testAllPublicStaticMethods(Maps.class);
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Map<Integer, Integer> EMPTY = Collections.emptyMap();
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Map<Integer, Integer> SINGLETON = Collections.singletonMap(1, 2);
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptyEmpty() {
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, EMPTY);
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptySingleton() {
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, SINGLETON);
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnRight());
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceSingletonEmpty() {
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(SINGLETON, EMPTY);
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnLeft());
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceTypical() {
3587dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
3597dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> right = ImmutableMap.of(1, "a", 3, "f", 5, "g", 6, "z");
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff1 = Maps.difference(left, right);
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff1.entriesOnlyOnRight());
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
3667dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(
3677dd252788645e940eada959bdde927426e2531c9Paul Duffin        ImmutableMap.of(3, ValueDifferenceImpl.create("c", "f"), 5,
3687dd252788645e940eada959bdde927426e2531c9Paul Duffin            ValueDifferenceImpl.create("e", "g")), diff1.entriesDiffering());
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=z}: "
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, f), 5=(e, g)}", diff1.toString());
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(right, left);
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff2.entriesOnlyOnLeft());
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff2.entriesInCommon());
3777dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(
3787dd252788645e940eada959bdde927426e2531c9Paul Duffin        ImmutableMap.of(3, ValueDifferenceImpl.create("f", "c"), 5,
3797dd252788645e940eada959bdde927426e2531c9Paul Duffin            ValueDifferenceImpl.create("g", "e")), diff2.entriesDiffering());
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEquals() {
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
3867dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> right = ImmutableMap.of(1, "a", 3, "f", 5, "g", 6, "z");
3877dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> right2 = ImmutableMap.of(1, "a", 3, "h", 5, "g", 6, "z");
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> original = Maps.difference(left, right);
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> same = Maps.difference(left, right);
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> reverse = Maps.difference(right, left);
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(left, right2);
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3937dd252788645e940eada959bdde927426e2531c9Paul Duffin    new EqualsTester().addEqualityGroup(original, same).addEqualityGroup(reverse)
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin        .addEqualityGroup(diff2).testEquals();
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferencePredicateTypical() {
3987dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
3997dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<Integer, String> right = ImmutableMap.of(1, "A", 3, "F", 5, "G", 6, "Z");
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // exists
4037dd252788645e940eada959bdde927426e2531c9Paul Duffin    Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<String, String>() {
4057dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override
4067dd252788645e940eada959bdde927426e2531c9Paul Duffin          public String apply(String input) {
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return input.toLowerCase();
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        });
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4117dd252788645e940eada959bdde927426e2531c9Paul Duffin    MapDifference<Integer, String> diff1 = Maps.difference(left, right, caseInsensitiveEquivalence);
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff1.entriesOnlyOnRight());
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
4167dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(
4177dd252788645e940eada959bdde927426e2531c9Paul Duffin        ImmutableMap.of(3, ValueDifferenceImpl.create("c", "F"), 5,
4187dd252788645e940eada959bdde927426e2531c9Paul Duffin            ValueDifferenceImpl.create("e", "G")), diff1.entriesDiffering());
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=Z}: "
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, F), 5=(e, G)}", diff1.toString());
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin    MapDifference<Integer, String> diff2 = Maps.difference(right, left, caseInsensitiveEquivalence);
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff2.entriesOnlyOnLeft());
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "A"), diff2.entriesInCommon());
4277dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin        ImmutableMap.of(3, ValueDifferenceImpl.create("F", "c"), 5,
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin            ValueDifferenceImpl.create("G", "e")), diff2.entriesDiffering());
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=Z}: only on right={2=b, 4=d}: "
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(F, c), 5=(G, e)}", diff2.toString());
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final SortedMap<Integer, Integer> SORTED_EMPTY = Maps.newTreeMap();
4357dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final SortedMap<Integer, Integer> SORTED_SINGLETON = ImmutableSortedMap.of(1, 2);
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceOfSortedMapIsSorted() {
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map = SORTED_SINGLETON;
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> difference = Maps.difference(map, EMPTY);
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(difference instanceof SortedMapDifference);
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptyEmpty() {
4447dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_EMPTY, SORTED_EMPTY);
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptySingleton() {
4547dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_EMPTY, SORTED_SINGLETON);
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnRight());
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceSingletonEmpty() {
4647dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_SINGLETON, SORTED_EMPTY);
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnLeft());
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceTypical() {
4747dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> left = ImmutableSortedMap.<Integer, String>reverseOrder()
4757dd252788645e940eada959bdde927426e2531c9Paul Duffin        .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e").build();
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4777dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> right = ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4797dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> diff1 = Maps.difference(left, right);
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
4817dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has()
4827dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
4837dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(Maps.immutableEntry(6, "z"));
4847dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a"));
4857dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesDiffering().entrySet())
4867dd252788645e940eada959bdde927426e2531c9Paul Duffin        .has()
4877dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
4887dd252788645e940eada959bdde927426e2531c9Paul Duffin            Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4927dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> diff2 = Maps.difference(right, left);
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
4947dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item(Maps.immutableEntry(6, "z"));
4957dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has()
4967dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
4977dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a"));
4987dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(
4997dd252788645e940eada959bdde927426e2531c9Paul Duffin        ImmutableMap.of(3, ValueDifferenceImpl.create("f", "c"), 5,
5007dd252788645e940eada959bdde927426e2531c9Paul Duffin            ValueDifferenceImpl.create("g", "e")), diff2.entriesDiffering());
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceImmutable() {
5067dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> left = Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 2, "b", 3, "c",
5077dd252788645e940eada959bdde927426e2531c9Paul Duffin        4, "d", 5, "e"));
5087dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> right = Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5,
5097dd252788645e940eada959bdde927426e2531c9Paul Duffin        "g", 6, "z"));
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5117dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> diff1 = Maps.difference(left, right);
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    left.put(6, "z");
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
5147dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has()
5157dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
5167dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(Maps.immutableEntry(6, "z"));
5177dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a"));
5187dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(diff1.entriesDiffering().entrySet())
5197dd252788645e940eada959bdde927426e2531c9Paul Duffin        .has()
5207dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
5217dd252788645e940eada959bdde927426e2531c9Paul Duffin            Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesInCommon().put(7, "x");
5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5257dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnLeft().put(7, "x");
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5297dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnRight().put(7, "x");
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5337dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEquals() {
5377dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> left = ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
5387dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> right = ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
5397dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<Integer, String> right2 = ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z");
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> original = Maps.difference(left, right);
5417dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> same = Maps.difference(left, right);
5427dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> reverse = Maps.difference(right, left);
5437dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMapDifference<Integer, String> diff2 = Maps.difference(left, right2);
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5457dd252788645e940eada959bdde927426e2531c9Paul Duffin    new EqualsTester().addEqualityGroup(original, same).addEqualityGroup(reverse)
5467dd252788645e940eada959bdde927426e2531c9Paul Duffin        .addEqualityGroup(diff2).testEquals();
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Function<String, Integer> LENGTH_FUNCTION = new Function<String, Integer>() {
5507dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5517dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Integer apply(String input) {
5527dd252788645e940eada959bdde927426e2531c9Paul Duffin      return input.length();
5537dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5547dd252788645e940eada959bdde927426e2531c9Paul Duffin  };
5557dd252788645e940eada959bdde927426e2531c9Paul Duffin
5567dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMap() {
5577dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = ImmutableSet.of("one", "two", "three");
5587dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
5597dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
5607dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
5617dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
5627dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
5637dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder();
5647dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5657dd252788645e940eada959bdde927426e2531c9Paul Duffin
5667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapReadsThrough() {
5677dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
5687dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
5697dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
5717dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("four"));
5727dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("four");
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5767dd252788645e940eada959bdde927426e2531c9Paul Duffin
5777dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapWritesThrough() {
5787dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
5797dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
5807dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
5817dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
5827dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
5837dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(strings).has().allOf("one", "three").inOrder();
5847dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5857dd252788645e940eada959bdde927426e2531c9Paul Duffin
5867dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapEmpty() {
5877dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = ImmutableSet.of();
5887dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
5897dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).isEmpty();
5907dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(map.isEmpty());
5917dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5947dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class NonNavigableSortedSet extends ForwardingSortedSet<String> {
5957dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final SortedSet<String> delegate = Sets.newTreeSet();
5967dd252788645e940eada959bdde927426e2531c9Paul Duffin
597dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    @Override
5987dd252788645e940eada959bdde927426e2531c9Paul Duffin    protected SortedSet<String> delegate() {
5997dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate;
600dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    }
601dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
602dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
6037dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapReturnsSortedMapForSortedSetInput() {
6047dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> set = new NonNavigableSortedSet();
6057dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
6067dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6077dd252788645e940eada959bdde927426e2531c9Paul Duffin
6087dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSorted() {
6097dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6107dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6117dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6127dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6137dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
6147dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
6157dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
6167dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("three", 5), mapEntry("two", 3)).inOrder();
6177dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.tailMap("onea").entrySet()).has()
6187dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("three", 5), mapEntry("two", 3)).inOrder();
6197dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.subMap("one", "two").entrySet()).has()
6207dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("three", 5)).inOrder();
6217dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
622dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
6237dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedReadsThrough() {
6247dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6257dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.comparator());
6287dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("four"));
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("four");
6317dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
6327dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
6337dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> headMap = map.headMap("two");
6347dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableSortedMap.of("four", 4, "one", 3, "three", 5), headMap);
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("five");
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.remove("one");
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableSortedMap.of("five", 4, "four", 4, "three", 5), headMap);
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("five", 4), mapEntry("four", 4), mapEntry("three", 5), mapEntry("two", 3))
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin        .inOrder();
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin
6437dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedWritesThrough() {
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6467dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6477dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6487dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(strings).has().allOf("one", "three").inOrder();
6507dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6517dd252788645e940eada959bdde927426e2531c9Paul Duffin
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(new NonNavigableSortedSet(), LENGTH_FUNCTION);
6547dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.subMap("a", "z").keySet().add("a");
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
6577dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.tailMap("a").keySet().add("a");
6607dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
6617dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
6637dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.headMap("r").keySet().add("a");
6647dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
6657dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
6667dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
6677dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.headMap("r").tailMap("m").keySet().add("a");
6687dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
6697dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (UnsupportedOperationException expected) {}
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin
6727dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedEmpty() {
6737dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6747dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).isEmpty();
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(map.isEmpty());
6777dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMap() {
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
6827dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
6837dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6847dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
6857dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder();
6867dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6877dd252788645e940eada959bdde927426e2531c9Paul Duffin
6887dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapIterator() {
6897dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
6907dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
6917dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6927dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
6937dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder();
6947dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6957dd252788645e940eada959bdde927426e2531c9Paul Duffin
6967dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithDuplicateKeys() {
6977dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
6987dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
6997dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
7007dd252788645e940eada959bdde927426e2531c9Paul Duffin    ASSERT.that(map.entrySet()).has()
7017dd252788645e940eada959bdde927426e2531c9Paul Duffin        .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder();
7027dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7037dd252788645e940eada959bdde927426e2531c9Paul Duffin
7047dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithNullKeys() {
7057dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = Arrays.asList("one", null, "three");
7067dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7077dd252788645e940eada959bdde927426e2531c9Paul Duffin      Maps.toMap(strings, Functions.constant("foo"));
7087dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7097dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException expected) {}
7107dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7117dd252788645e940eada959bdde927426e2531c9Paul Duffin
7127dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithNullValues() {
7137dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
7147dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7157dd252788645e940eada959bdde927426e2531c9Paul Duffin      Maps.toMap(strings, Functions.constant(null));
7167dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7177dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException expected) {}
7187dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7197dd252788645e940eada959bdde927426e2531c9Paul Duffin
7207dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final BiMap<Integer, String> INT_TO_STRING_MAP = new ImmutableBiMap.Builder<Integer, String>()
7217dd252788645e940eada959bdde927426e2531c9Paul Duffin      .put(1, "one").put(2, "two").put(3, "three").build();
7227dd252788645e940eada959bdde927426e2531c9Paul Duffin
7237dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testUniqueIndexCollection() {
7247dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(INT_TO_STRING_MAP.values(),
725dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin        Functions.forMap(INT_TO_STRING_MAP.inverse()));
726dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    assertEquals(INT_TO_STRING_MAP, outputMap);
727dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
728dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
7297dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testUniqueIndexIterable() {
7307dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(new Iterable<String>() {
7317dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
7327dd252788645e940eada959bdde927426e2531c9Paul Duffin      public Iterator<String> iterator() {
7337dd252788645e940eada959bdde927426e2531c9Paul Duffin        return INT_TO_STRING_MAP.values().iterator();
7347dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7357dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, Functions.forMap(INT_TO_STRING_MAP.inverse()));
7367dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(INT_TO_STRING_MAP, outputMap);
7377dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7387dd252788645e940eada959bdde927426e2531c9Paul Duffin
7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexIterator() {
7407dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(INT_TO_STRING_MAP.values()
7417dd252788645e940eada959bdde927426e2531c9Paul Duffin        .iterator(), Functions.forMap(INT_TO_STRING_MAP.inverse()));
7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(INT_TO_STRING_MAP, outputMap);
7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Can't create the map if more than one value maps to the same key. */
7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexDuplicates() {
7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(ImmutableSet.of("one", "uno"), Functions.constant(1));
7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
7507dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (IllegalArgumentException expected) {}
7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null values are not allowed. */
7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullValue() {
7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> listWithNull = Lists.newArrayList((String) null);
7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(listWithNull, Functions.constant(1));
7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
7597dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException expected) {}
7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null keys aren't allowed either. */
7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullKey() {
7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> oneStringList = Lists.newArrayList("foo");
7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(oneStringList, Functions.constant(null));
7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
7687dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException expected) {}
7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
7727dd252788645e940eada959bdde927426e2531c9Paul Duffin  @SuppressWarnings("deprecation")
7737dd252788645e940eada959bdde927426e2531c9Paul Duffin  // StringBufferInputStream
7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromProperties() throws IOException {
7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties testProp = new Properties();
7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> result = Maps.fromProperties(testProp);
7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.isEmpty());
7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("first", "true");
7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, result.size());
7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("second", "null");
7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null", result.get("second"));
7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(2, result.size());
7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Now test values loaded from a stream.
7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String props = "test\n second = 2\n Third item :   a short  phrase   ";
7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7947dd252788645e940eada959bdde927426e2531c9Paul Duffin    testProp.load(new StringBufferInputStream(props));
7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(4, result.size());
7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("2", result.get("second"));
8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("item :   a short  phrase   ", result.get("Third"));
8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(result.containsKey("not here"));
8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test loading system properties
8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(System.getProperties());
8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.containsKey("java.version"));
8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test that defaults work, too.
8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp = new Properties(System.getProperties());
8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String override = "test\njava.version : hidden";
8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8127dd252788645e940eada959bdde927426e2531c9Paul Duffin    testProp.load(new StringBufferInputStream(override));
8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.size() > 2);
8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("hidden", result.get("java.version"));
8187dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNotSame(System.getProperty("java.version"), result.get("java.version"));
8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
8227dd252788645e940eada959bdde927426e2531c9Paul Duffin  @SuppressWarnings("serial")
8237dd252788645e940eada959bdde927426e2531c9Paul Duffin  // never serialized
8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNullKey() {
8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
8267dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8277dd252788645e940eada959bdde927426e2531c9Paul Duffin      public Enumeration<?> propertyNames() {
8287dd252788645e940eada959bdde927426e2531c9Paul Duffin        return Iterators.asEnumeration(Arrays.asList(null, "first", "second").iterator());
8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("first", "true");
8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("second", "null");
8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {}
8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
8417dd252788645e940eada959bdde927426e2531c9Paul Duffin  @SuppressWarnings("serial")
8427dd252788645e940eada959bdde927426e2531c9Paul Duffin  // never serialized
8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNonStringKeys() {
8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
8457dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8467dd252788645e940eada959bdde927426e2531c9Paul Duffin      public Enumeration<?> propertyNames() {
8477dd252788645e940eada959bdde927426e2531c9Paul Duffin        return Iterators.asEnumeration(Arrays.<Object>asList(Integer.valueOf(123), "first")
8487dd252788645e940eada959bdde927426e2531c9Paul Duffin            .iterator());
8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ClassCastException expected) {}
8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Constructs a "nefarious" map entry with the specified key and value,
8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * meaning an entry that is suitable for testing that map entries cannot be
8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modified via a nefarious implementation of equals. This is used for testing
8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * unmodifiable collections of map entries; for example, it should not be
8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * possible to access the raw (modifiable) map entry via a nefarious equals
8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * method.
8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static <K, V> Map.Entry<K, V> nefariousEntry(final K key, final V value) {
8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new AbstractMapEntry<K, V>() {
8687dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8697dd252788645e940eada959bdde927426e2531c9Paul Duffin      public K getKey() {
8707dd252788645e940eada959bdde927426e2531c9Paul Duffin        return key;
8717dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8727dd252788645e940eada959bdde927426e2531c9Paul Duffin
8737dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8747dd252788645e940eada959bdde927426e2531c9Paul Duffin      public V getValue() {
8757dd252788645e940eada959bdde927426e2531c9Paul Duffin        return value;
8767dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8777dd252788645e940eada959bdde927426e2531c9Paul Duffin
8787dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8797dd252788645e940eada959bdde927426e2531c9Paul Duffin      public V setValue(V value) {
8807dd252788645e940eada959bdde927426e2531c9Paul Duffin        throw new UnsupportedOperationException();
8817dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8827dd252788645e940eada959bdde927426e2531c9Paul Duffin
8837dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked")
8847dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
8857dd252788645e940eada959bdde927426e2531c9Paul Duffin      public boolean equals(Object o) {
8867dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (o instanceof Map.Entry) {
8877dd252788645e940eada959bdde927426e2531c9Paul Duffin          Map.Entry<K, V> e = (Map.Entry<K, V>) o;
8887dd252788645e940eada959bdde927426e2531c9Paul Duffin          e.setValue(value); // muhahaha!
8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
8907dd252788645e940eada959bdde927426e2531c9Paul Duffin        return super.equals(o);
8917dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8927dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUnmodifiableBiMap() {
8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Integer, String> mod = HashBiMap.create();
8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(1, "one");
8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(2, "two");
8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(3, "three");
9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Number, String> unmod = Maps.<Number, String>unmodifiableBiMap(mod);
9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* No aliasing on inverse operations. */
9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod.inverse(), unmod.inverse());
9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod, unmod.inverse().inverse());
9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* Unmodifiable is a view. */
9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(4, "four");
9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.get(4).equals("four"));
9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.inverse().get("four").equals(4));
9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on direct modifications. */
9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.put(4, "four");
9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.forcePut(4, "four");
9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.putAll(Collections.singletonMap(4, "four"));
9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on indirect modifications. */
9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Number> inverse = unmod.inverse();
9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.put("four", 4);
9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.forcePut("four", 4);
9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.putAll(Collections.singletonMap("four", 4));
9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<String> values = unmod.values();
9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      values.remove("four");
9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Map.Entry<Number, String>> entries = unmod.entrySet();
9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<Number, String> entry = entries.iterator().next();
9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry.setValue("four");
9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
9527dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map.Entry<Integer, String> entry2 = (Map.Entry<Integer, String>) entries.toArray()[0];
9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry2.setValue("four");
9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntry() {
9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo", e.getKey());
9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, (int) e.getValue());
9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(2);
9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo=1", e.toString());
9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(101575, e.hashCode());
9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntryNull() {
9727dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map.Entry<String, Integer> e = Maps.immutableEntry((String) null, (Integer) null);
9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getKey());
9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getValue());
9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(null);
9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null=null", e.toString());
9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(0, e.hashCode());
9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** See {@link SynchronizedBiMapTest} for more tests. */
9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedBiMap() {
9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> bimap = HashBiMap.create();
9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("one", 1);
9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> sync = Maps.synchronizedBiMap(bimap);
9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("two", 2);
9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    sync.put("three", 3);
9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), bimap.inverse().keySet());
9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), sync.inverse().keySet());
9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9947dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Predicate<String> NOT_LENGTH_3 = new Predicate<String>() {
9957dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
9967dd252788645e940eada959bdde927426e2531c9Paul Duffin    public boolean apply(String input) {
9977dd252788645e940eada959bdde927426e2531c9Paul Duffin      return input == null || input.length() != 3;
9987dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9997dd252788645e940eada959bdde927426e2531c9Paul Duffin  };
10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10017dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Predicate<Integer> EVEN = new Predicate<Integer>() {
10027dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
10037dd252788645e940eada959bdde927426e2531c9Paul Duffin    public boolean apply(Integer input) {
10047dd252788645e940eada959bdde927426e2531c9Paul Duffin      return input == null || input % 2 == 0;
10057dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10067dd252788645e940eada959bdde927426e2531c9Paul Duffin  };
10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10087dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH = new Predicate<Entry<String, Integer>>() {
10097dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
10107dd252788645e940eada959bdde927426e2531c9Paul Duffin    public boolean apply(Entry<String, Integer> input) {
10117dd252788645e940eada959bdde927426e2531c9Paul Duffin      return input.getKey().length() == input.getValue();
10127dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10137dd252788645e940eada959bdde927426e2531c9Paul Duffin  };
10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10157dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
10167dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
10177dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Double apply(Integer in) {
10187dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Math.sqrt(in);
10197dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10207dd252788645e940eada959bdde927426e2531c9Paul Duffin  };
10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10227dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredMapTest extends TestCase {
10237dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> createUnfiltered() {
10247dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Maps.newHashMap();
10257dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10263c77433663281544363151bf284b0240dfd22a42Paul Duffin
10277dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysIllegalPut() {
10287dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
10297dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
10307dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 1);
10317dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 2);
10327dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
10333c77433663281544363151bf284b0240dfd22a42Paul Duffin
10347dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
10357dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("yyy", 3);
10367dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
10377dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
10387dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10393c77433663281544363151bf284b0240dfd22a42Paul Duffin
10407dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysIllegalPutAll() {
10417dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
10427dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
10437dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 1);
10447dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 2);
10457dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
10463c77433663281544363151bf284b0240dfd22a42Paul Duffin
10477dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
10487dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
10497dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
10507dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
10513c77433663281544363151bf284b0240dfd22a42Paul Duffin
10527dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
10537dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10543c77433663281544363151bf284b0240dfd22a42Paul Duffin
10557dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysFilteredReflectsBackingChanges() {
10567dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
10577dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
10587dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("two", 2);
10597dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("three", 3);
10607dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("four", 4);
10617dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
10627dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
10637dd252788645e940eada959bdde927426e2531c9Paul Duffin
10647dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.remove("three");
10657dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
10667dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("four", 4), filtered);
10677dd252788645e940eada959bdde927426e2531c9Paul Duffin
10687dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.clear();
10697dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), unfiltered);
10707dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), filtered);
10717dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10737dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalPut() {
10747dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
10757dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
10767dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
10777dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("b", 4);
10787dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("c", 5);
10797dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
10803c77433663281544363151bf284b0240dfd22a42Paul Duffin
10817dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
10827dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("yyy", 3);
10837dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
10847dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
10857dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
10867dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10887dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalPutAll() {
10897dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
10907dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
10917dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
10927dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("b", 4);
10937dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("c", 5);
10947dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
10953c77433663281544363151bf284b0240dfd22a42Paul Duffin
10967dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
10977dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
10987dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
10997dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
11007dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
11017dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11023c77433663281544363151bf284b0240dfd22a42Paul Duffin
11037dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalSetValue() {
11047dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11057dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
11067dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
11077dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 4);
11087dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
11093c77433663281544363151bf284b0240dfd22a42Paul Duffin
11107dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<String, Integer> entry = filtered.entrySet().iterator().next();
11117dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
11127dd252788645e940eada959bdde927426e2531c9Paul Duffin        entry.setValue(5);
11137dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
11147dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
11153c77433663281544363151bf284b0240dfd22a42Paul Duffin
11167dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
11177dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11183c77433663281544363151bf284b0240dfd22a42Paul Duffin
11197dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesClear() {
11207dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11217dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("one", 1);
11227dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("two", 2);
11237dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("three", 3);
11247dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("four", 4);
11257dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
11267dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4), unfiltered);
11277dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
11287dd252788645e940eada959bdde927426e2531c9Paul Duffin
11297dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.clear();
11307dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
11317dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(filtered.isEmpty());
11327dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11337dd252788645e940eada959bdde927426e2531c9Paul Duffin
11347dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesIllegalPut() {
11357dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11367dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
11377dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
11387dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
11397dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
11407dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
11417dd252788645e940eada959bdde927426e2531c9Paul Duffin
11427dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("chicken", 7);
11437dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
11443c77433663281544363151bf284b0240dfd22a42Paul Duffin
11457dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
11467dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("cow", 7);
11477dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
11487dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
11497dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
11507dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11517dd252788645e940eada959bdde927426e2531c9Paul Duffin
11527dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesIllegalPutAll() {
11537dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11547dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
11557dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
11567dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
11577dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
11587dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
11597dd252788645e940eada959bdde927426e2531c9Paul Duffin
11607dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("chicken", 7);
11617dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
11627dd252788645e940eada959bdde927426e2531c9Paul Duffin
11637dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
11647dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
11657dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
11667dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
11677dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
11687dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11697dd252788645e940eada959bdde927426e2531c9Paul Duffin
11707dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesObjectPredicate() {
11717dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11727dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
11737dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
11747dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
11757dd252788645e940eada959bdde927426e2531c9Paul Duffin      Predicate<Object> predicate = Predicates.alwaysFalse();
11767dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterEntries(unfiltered, predicate);
11777dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(filtered.isEmpty());
11787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11797dd252788645e940eada959bdde927426e2531c9Paul Duffin
11807dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesWildCardEntryPredicate() {
11817dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
11827dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
11837dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
11847dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
11857dd252788645e940eada959bdde927426e2531c9Paul Duffin      Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
11867dd252788645e940eada959bdde927426e2531c9Paul Duffin        @Override
11877dd252788645e940eada959bdde927426e2531c9Paul Duffin        public boolean apply(Entry<?, ?> input) {
11887dd252788645e940eada959bdde927426e2531c9Paul Duffin          return "cat".equals(input.getKey()) || Integer.valueOf(2) == input.getValue();
11897dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
11907dd252788645e940eada959bdde927426e2531c9Paul Duffin      };
11917dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterEntries(unfiltered, predicate);
11927dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
11937dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1194dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
11953c77433663281544363151bf284b0240dfd22a42Paul Duffin
11967dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredSortedMapTest extends FilteredMapTest {
11977dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
11987dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> createUnfiltered() {
11997dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Maps.newTreeMap();
12007dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12017dd252788645e940eada959bdde927426e2531c9Paul Duffin
12027dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterKeysIdentifiesSortedMap() {
12037dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
12047dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) instanceof SortedMap);
12057dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12067dd252788645e940eada959bdde927426e2531c9Paul Duffin
12077dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterValuesIdentifiesSortedMap() {
12087dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
12097dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) instanceof SortedMap);
12107dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12117dd252788645e940eada959bdde927426e2531c9Paul Duffin
12127dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterEntriesIdentifiesSortedMap() {
12137dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
12147dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) instanceof SortedMap);
12157dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12167dd252788645e940eada959bdde927426e2531c9Paul Duffin
12177dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFirstAndLastKeyFilteredMap() {
12187dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
12197dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("apple", 2);
12207dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("banana", 6);
12217dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
12227dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 5);
12237dd252788645e940eada959bdde927426e2531c9Paul Duffin
12247dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
12257dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("banana", filtered.firstKey());
12267dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("cat", filtered.lastKey());
12277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12287dd252788645e940eada959bdde927426e2531c9Paul Duffin
12297dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testHeadSubTailMap_FilteredMap() {
12307dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
12317dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("apple", 2);
12327dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("banana", 6);
12337dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 4);
12347dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 3);
12357dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
12367dd252788645e940eada959bdde927426e2531c9Paul Duffin
12377dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
12387dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
12397dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
12407dd252788645e940eada959bdde927426e2531c9Paul Duffin
12417dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
12427dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
12433c77433663281544363151bf284b0240dfd22a42Paul Duffin
12447dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
12457dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
12467dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12497dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredBiMapTest extends FilteredMapTest {
12507dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
12517dd252788645e940eada959bdde927426e2531c9Paul Duffin    BiMap<String, Integer> createUnfiltered() {
12527dd252788645e940eada959bdde927426e2531c9Paul Duffin      return HashBiMap.create();
12537dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12557dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterKeysIdentifiesBiMap() {
12567dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
12577dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) instanceof BiMap);
12587dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12607dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterValuesIdentifiesBiMap() {
12617dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
12627dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) instanceof BiMap);
12637dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12657dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterEntriesIdentifiesBiMap() {
12667dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
12677dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) instanceof BiMap);
12687dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
12691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValues() {
12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
12737dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValuesSecretlySorted() {
12797dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
12807dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
12813c77433663281544363151bf284b0240dfd22a42Paul Duffin
12823c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1283dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    assertTrue(transformed instanceof SortedMap);
12843c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
12853c77433663281544363151bf284b0240dfd22a42Paul Duffin
12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntries() {
12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableMap.of("a", "4", "b", "9");
12887dd252788645e940eada959bdde927426e2531c9Paul Duffin    EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() {
12897dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
12907dd252788645e940eada959bdde927426e2531c9Paul Duffin      public String transformEntry(String key, String value) {
12917dd252788645e940eada959bdde927426e2531c9Paul Duffin        return key + value;
12927dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
12937dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
12947dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesSecretlySorted() {
13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
13017dd252788645e940eada959bdde927426e2531c9Paul Duffin    EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() {
13027dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
13037dd252788645e940eada959bdde927426e2531c9Paul Duffin      public String transformEntry(String key, String value) {
13047dd252788645e940eada959bdde927426e2531c9Paul Duffin        return key + value;
13057dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
13067dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
13077dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(transformed instanceof SortedMap);
13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesGenerics() {
13141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Integer> map3 = ImmutableMap.<Object, Integer>of(1, 2);
13171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Object> map4 = ImmutableMap.<Number, Object>of(1, 2);
13181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Number> map5 = ImmutableMap.<Number, Number>of(1, 2);
13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Integer> map6 = ImmutableMap.<Number, Integer>of(1, 2);
13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Object> map7 = ImmutableMap.<Integer, Object>of(1, 2);
13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Number> map8 = ImmutableMap.<Integer, Number>of(1, 2);
13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map9 = ImmutableMap.<Integer, Integer>of(1, 2);
13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, ? extends Number> map0 = ImmutableMap.of(1, 2);
13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13257dd252788645e940eada959bdde927426e2531c9Paul Duffin    EntryTransformer<Number, Number, Double> transformer = new EntryTransformer<Number, Number, Double>() {
13267dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
13277dd252788645e940eada959bdde927426e2531c9Paul Duffin      public Double transformEntry(Number key, Number value) {
13287dd252788645e940eada959bdde927426e2531c9Paul Duffin        return key.doubleValue() + value.doubleValue();
13297dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
13307dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Double> objectKeyed;
13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Double> numberKeyed;
13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Double> integerKeyed;
13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map5, transformer);
13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map6, transformer);
13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map8, transformer);
13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map9, transformer);
13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, Double> wildcarded = transformEntries(map0, transformer);
13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the key type:
13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map5, transformer);
13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map6, transformer);
13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map8, transformer);
13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map9, transformer);
13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map8, transformer);
13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map9, transformer);
13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the value type:
13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued1 = transformEntries(map5, transformer);
13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued2 = transformEntries(map6, transformer);
13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued3 = transformEntries(map8, transformer);
13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued4 = transformEntries(map9, transformer);
13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a key:
13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map2, transformer);
13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map3, transformer);
13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a value:
13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map4, transformer);
13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map7, transformer);
13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesExample() {
13697dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Boolean> options = ImmutableMap.of("verbose", true, "sort", false);
13707dd252788645e940eada959bdde927426e2531c9Paul Duffin    EntryTransformer<String, Boolean, String> flagPrefixer = new EntryTransformer<String, Boolean, String>() {
13717dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
13727dd252788645e940eada959bdde927426e2531c9Paul Duffin      public String transformEntry(String key, Boolean value) {
13737dd252788645e940eada959bdde927426e2531c9Paul Duffin        return value ? key : "no" + key;
13747dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
13757dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
13767dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(options, flagPrefixer);
13771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13807dd252788645e940eada959bdde927426e2531c9Paul Duffin  // Logically this would accept a NavigableMap, but that won't work under GWT.
13817dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static <K, V> SortedMap<K, V> sortedNotNavigable(final SortedMap<K, V> map) {
13827dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new ForwardingSortedMap<K, V>() {
1383dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin      @Override
13847dd252788645e940eada959bdde927426e2531c9Paul Duffin      protected SortedMap<K, V> delegate() {
13857dd252788645e940eada959bdde927426e2531c9Paul Duffin        return map;
1386dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin      }
1387dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    };
13887dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
13897dd252788645e940eada959bdde927426e2531c9Paul Duffin
13907dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testSortedMapTransformValues() {
13917dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
13927dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13947dd252788645e940eada959bdde927426e2531c9Paul Duffin    /*
13957dd252788645e940eada959bdde927426e2531c9Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
13967dd252788645e940eada959bdde927426e2531c9Paul Duffin     * can't easily do so while maintaining GWT compatibility.
13977dd252788645e940eada959bdde927426e2531c9Paul Duffin     */
13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapTransformEntries() {
14027dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, String> map = sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
14037dd252788645e940eada959bdde927426e2531c9Paul Duffin    EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() {
14047dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
14057dd252788645e940eada959bdde927426e2531c9Paul Duffin      public String transformEntry(String key, String value) {
14067dd252788645e940eada959bdde927426e2531c9Paul Duffin        return key + value;
14077dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
14087dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
14097dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, String> transformed = transformEntries(map, concat);
14103c77433663281544363151bf284b0240dfd22a42Paul Duffin
14117dd252788645e940eada959bdde927426e2531c9Paul Duffin    /*
14127dd252788645e940eada959bdde927426e2531c9Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
14137dd252788645e940eada959bdde927426e2531c9Paul Duffin     * can't easily do so while maintaining GWT compatibility.
14147dd252788645e940eada959bdde927426e2531c9Paul Duffin     */
14153c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
14163c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
14173c77433663281544363151bf284b0240dfd22a42Paul Duffin
14187dd252788645e940eada959bdde927426e2531c9Paul Duffin  // Hack for JDK5 type inference.
14197dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ASSERT {
14207dd252788645e940eada959bdde927426e2531c9Paul Duffin    static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that(
14217dd252788645e940eada959bdde927426e2531c9Paul Duffin        Collection<T> collection) {
14227dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Truth.ASSERT.<T, Collection<T>>that(collection);
14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
1426