001/*
002 * Copyright (C) 2009 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect.testing;
018
019import com.google.common.annotations.GwtCompatible;
020import java.util.Iterator;
021import java.util.Map.Entry;
022import java.util.SortedMap;
023
024/**
025 * Tests representing the contract of {@link SortedMap}. Concrete subclasses of this base class test
026 * conformance of concrete {@link SortedMap} subclasses to that contract.
027 *
028 * @author Jared Levy
029 */
030// TODO: Use this class to test classes besides ImmutableSortedMap.
031@GwtCompatible
032public abstract class SortedMapInterfaceTest<K, V> extends MapInterfaceTest<K, V> {
033
034  protected SortedMapInterfaceTest(
035      boolean allowsNullKeys,
036      boolean allowsNullValues,
037      boolean supportsPut,
038      boolean supportsRemove,
039      boolean supportsClear) {
040    super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, supportsClear);
041  }
042
043  @Override
044  protected abstract SortedMap<K, V> makeEmptyMap() throws UnsupportedOperationException;
045
046  @Override
047  protected abstract SortedMap<K, V> makePopulatedMap() throws UnsupportedOperationException;
048
049  @Override
050  protected SortedMap<K, V> makeEitherMap() {
051    try {
052      return makePopulatedMap();
053    } catch (UnsupportedOperationException e) {
054      return makeEmptyMap();
055    }
056  }
057
058  public void testTailMapWriteThrough() {
059    final SortedMap<K, V> map;
060    try {
061      map = makePopulatedMap();
062    } catch (UnsupportedOperationException e) {
063      return;
064    }
065    if (map.size() < 2 || !supportsPut) {
066      return;
067    }
068    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
069    Entry<K, V> firstEntry = iterator.next();
070    Entry<K, V> secondEntry = iterator.next();
071    K key = secondEntry.getKey();
072    SortedMap<K, V> subMap = map.tailMap(key);
073    V value = getValueNotInPopulatedMap();
074    subMap.put(key, value);
075    assertEquals(secondEntry.getValue(), value);
076    assertEquals(map.get(key), value);
077    try {
078      subMap.put(firstEntry.getKey(), value);
079      fail("Expected IllegalArgumentException");
080    } catch (IllegalArgumentException expected) {
081    }
082  }
083
084  public void testTailMapRemoveThrough() {
085    final SortedMap<K, V> map;
086    try {
087      map = makePopulatedMap();
088    } catch (UnsupportedOperationException e) {
089      return;
090    }
091    int oldSize = map.size();
092    if (map.size() < 2 || !supportsRemove) {
093      return;
094    }
095    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
096    Entry<K, V> firstEntry = iterator.next();
097    Entry<K, V> secondEntry = iterator.next();
098    K key = secondEntry.getKey();
099    SortedMap<K, V> subMap = map.tailMap(key);
100    subMap.remove(key);
101    assertNull(subMap.remove(firstEntry.getKey()));
102    assertEquals(map.size(), oldSize - 1);
103    assertFalse(map.containsKey(key));
104    assertEquals(subMap.size(), oldSize - 2);
105  }
106
107  public void testTailMapClearThrough() {
108    final SortedMap<K, V> map;
109    try {
110      map = makePopulatedMap();
111    } catch (UnsupportedOperationException e) {
112      return;
113    }
114    int oldSize = map.size();
115    if (map.size() < 2 || !supportsClear) {
116      return;
117    }
118    Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
119    iterator.next(); // advance
120    Entry<K, V> secondEntry = iterator.next();
121    K key = secondEntry.getKey();
122    SortedMap<K, V> subMap = map.tailMap(key);
123    int subMapSize = subMap.size();
124    subMap.clear();
125    assertEquals(map.size(), oldSize - subMapSize);
126    assertTrue(subMap.isEmpty());
127  }
128}