11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 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.testing;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ArrayList;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests representing the contract of {@link SortedMap}. Concrete subclasses of
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this base class test conformance of concrete {@link SortedMap} subclasses to
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that contract.
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class is GWT compatible.
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// TODO: Use this class to test classes besides ImmutableSortedMap.
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class SortedMapInterfaceTest<K, V>
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    extends MapInterfaceTest<K, V> {
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** A key type that is not assignable to any classes but Object. */
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final class IncompatibleComparableKeyType
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements Comparable<IncompatibleComparableKeyType> {
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return "IncompatibleComparableKeyType";
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public int compareTo(IncompatibleComparableKeyType o) {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new ClassCastException();
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected SortedMapInterfaceTest(boolean allowsNullKeys,
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean allowsNullValues, boolean supportsPut, boolean supportsRemove,
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean supportsClear) {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove,
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        supportsClear);
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected abstract SortedMap<K, V> makeEmptyMap()
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException;
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected abstract SortedMap<K, V> makePopulatedMap()
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException;
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected SortedMap<K, V> makeEitherMap() {
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return makePopulatedMap();
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return makeEmptyMap();
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked") // Needed for null comparator
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testOrdering() {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<K> iterator = map.keySet().iterator();
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K prior = iterator.next();
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Comparator<? super K> comparator = map.comparator();
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (iterator.hasNext()) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      K current = iterator.next();
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (comparator == null) {
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Comparable comparable = (Comparable) prior;
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(comparable.compareTo(current) < 0);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(map.comparator().compare(prior, current) < 0);
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      current = prior;
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEntrySetContainsEntryIncompatibleComparableKey() {
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Map<K, V> map;
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Set<Entry<K, V>> entrySet;
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEitherMap();
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertInvariants(map);
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entrySet = map.entrySet();
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final V unmappedValue;
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmappedValue = getValueNotInPopulatedMap();
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<IncompatibleComparableKeyType, V> entry
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = mapEntry(new IncompatibleComparableKeyType(), unmappedValue);
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(entrySet.contains(entry));
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFirstKeyEmpty() {
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEmptyMap();
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.firstKey();
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected NoSuchElementException");
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NoSuchElementException expected) {}
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertInvariants(map);
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFirstKeyNonEmpty() {
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K expected = map.keySet().iterator().next();
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected, map.firstKey());
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertInvariants(map);
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLastKeyEmpty() {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEmptyMap();
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.lastKey();
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected NoSuchElementException");
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NoSuchElementException expected) {}
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertInvariants(map);
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLastKeyNonEmpty() {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K expected = null;
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (K key : map.keySet()) {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      expected = key;
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected, map.lastKey());
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertInvariants(map);
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> List<E> toList(Collection<E> collection) {
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ArrayList<E>(collection);
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> List<E> subListSnapshot(
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      List<E> list, int fromIndex, int toIndex) {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<E> subList = new ArrayList<E>();
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = fromIndex; i < toIndex; i++) {
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      subList.add(list.get(i));
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Collections.unmodifiableList(subList);
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHeadMap() {
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEitherMap();
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<Entry<K, V>> list = toList(map.entrySet());
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < list.size(); i++) {
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      List<Entry<K, V>> expected = subListSnapshot(list, 0, i);
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedMap<K, V> headMap = map.headMap(list.get(i).getKey());
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expected, toList(headMap.entrySet()));
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMap() {
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEitherMap();
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<Entry<K, V>> list = toList(map.entrySet());
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < list.size(); i++) {
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      List<Entry<K, V>> expected = subListSnapshot(list, i, list.size());
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedMap<K, V> tailMap = map.tailMap(list.get(i).getKey());
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expected, toList(tailMap.entrySet()));
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSubMap() {
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makeEitherMap();
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<Entry<K, V>> list = toList(map.entrySet());
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < list.size(); i++) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int j = i; j < list.size(); j++) {
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        List<Entry<K, V>> expected = subListSnapshot(list, i, j);
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        SortedMap<K, V> subMap
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            = map.subMap(list.get(i).getKey(), list.get(j).getKey());
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(expected, toList(subMap.entrySet()));
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSubMapIllegal() {
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2) {
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<K> iterator = map.keySet().iterator();
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K first = iterator.next();
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K second = iterator.next();
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.subMap(second, first);
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected IllegalArgumentException");
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {}
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapEntrySet() {
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 3) {
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> thirdEntry = iterator.next();
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> tail = map.tailMap(secondEntry.getKey());
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Entry<K, V>> tailEntrySet = tail.entrySet();
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(tailEntrySet.contains(thirdEntry));
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(tailEntrySet.contains(secondEntry));
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(tailEntrySet.contains(firstEntry));
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(tail.firstKey(), secondEntry.getKey());
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHeadMapEntrySet() {
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 3) {
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> thirdEntry = iterator.next();
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> head = map.headMap(secondEntry.getKey());
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Entry<K, V>> headEntrySet = head.entrySet();
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(headEntrySet.contains(thirdEntry));
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(headEntrySet.contains(secondEntry));
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(headEntrySet.contains(firstEntry));
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(head.firstKey(), firstEntry.getKey());
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(head.lastKey(), firstEntry.getKey());
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapWriteThrough() {
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsPut) {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    V value = getValueNotInPopulatedMap();
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.put(key, value);
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(secondEntry.getValue(), value);
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.get(key), value);
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      subMap.put(firstEntry.getKey(), value);
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected IllegalArgumentException");
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapRemoveThrough() {
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int oldSize = map.size();
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsRemove) {
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.remove(key);
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(subMap.remove(firstEntry.getKey()));
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.size(), oldSize - 1);
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(map.containsKey(key));
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(subMap.size(), oldSize - 2);
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapClearThrough() {
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int oldSize = map.size();
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsClear) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int subMapSize = subMap.size();
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.clear();
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.size(), oldSize - subMapSize);
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(subMap.isEmpty());
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
373