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
197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible;
207dd252788645e940eada959bdde927426e2531c9Paul Duffin
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests representing the contract of {@link SortedMap}. Concrete subclasses of
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this base class test conformance of concrete {@link SortedMap} subclasses to
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that contract.
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// TODO: Use this class to test classes besides ImmutableSortedMap.
337dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class SortedMapInterfaceTest<K, V>
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    extends MapInterfaceTest<K, V> {
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected SortedMapInterfaceTest(boolean allowsNullKeys,
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean allowsNullValues, boolean supportsPut, boolean supportsRemove,
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean supportsClear) {
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove,
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        supportsClear);
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected abstract SortedMap<K, V> makeEmptyMap()
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected abstract SortedMap<K, V> makePopulatedMap()
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected SortedMap<K, V> makeEitherMap() {
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return makePopulatedMap();
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return makeEmptyMap();
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapWriteThrough() {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsPut) {
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    V value = getValueNotInPopulatedMap();
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.put(key, value);
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(secondEntry.getValue(), value);
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.get(key), value);
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      subMap.put(firstEntry.getKey(), value);
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected IllegalArgumentException");
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapRemoveThrough() {
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int oldSize = map.size();
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsRemove) {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> firstEntry = iterator.next();
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.remove(key);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(subMap.remove(firstEntry.getKey()));
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.size(), oldSize - 1);
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(map.containsKey(key));
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(subMap.size(), oldSize - 2);
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTailMapClearThrough() {
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedMap<K, V> map;
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map = makePopulatedMap();
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException e) {
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int oldSize = map.size();
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (map.size() < 2 || !supportsClear) {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return;
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    iterator.next(); // advance
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<K, V> secondEntry = iterator.next();
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    K key = secondEntry.getKey();
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<K, V> subMap = map.tailMap(key);
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int subMapSize = subMap.size();
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    subMap.clear();
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(map.size(), oldSize - subMapSize);
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(subMap.isEmpty());
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
129