001/*
002 * Copyright (C) 2010 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.testers;
018
019import static com.google.common.collect.testing.Helpers.assertEqualInOrder;
020import static com.google.common.collect.testing.features.CollectionSize.ONE;
021import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
022import static com.google.common.collect.testing.features.CollectionSize.ZERO;
023
024import com.google.common.annotations.GwtCompatible;
025import com.google.common.collect.testing.AbstractMapTester;
026import com.google.common.collect.testing.Helpers;
027import com.google.common.collect.testing.features.CollectionSize;
028import java.util.Collections;
029import java.util.Comparator;
030import java.util.Iterator;
031import java.util.List;
032import java.util.Map.Entry;
033import java.util.NoSuchElementException;
034import java.util.SortedMap;
035import org.junit.Ignore;
036
037/**
038 * A generic JUnit test which tests operations on a SortedMap. Can't be invoked directly; please see
039 * {@code SortedMapTestSuiteBuilder}.
040 *
041 * @author Jesse Wilson
042 * @author Louis Wasserman
043 */
044@GwtCompatible
045@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
046public class SortedMapNavigationTester<K, V> extends AbstractMapTester<K, V> {
047
048  private SortedMap<K, V> navigableMap;
049  private Entry<K, V> a;
050  private Entry<K, V> c;
051
052  @Override
053  public void setUp() throws Exception {
054    super.setUp();
055    navigableMap = (SortedMap<K, V>) getMap();
056    List<Entry<K, V>> entries =
057        Helpers.copyToList(
058            getSubjectGenerator()
059                .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
060    Collections.sort(entries, Helpers.<K, V>entryComparator(navigableMap.comparator()));
061
062    // some tests assume SEVERAL == 3
063    if (entries.size() >= 1) {
064      a = entries.get(0);
065      if (entries.size() >= 3) {
066        c = entries.get(2);
067      }
068    }
069  }
070
071  @CollectionSize.Require(ZERO)
072  public void testEmptyMapFirst() {
073    try {
074      navigableMap.firstKey();
075      fail();
076    } catch (NoSuchElementException e) {
077    }
078  }
079
080  @CollectionSize.Require(ZERO)
081  public void testEmptyMapLast() {
082    try {
083      assertNull(navigableMap.lastKey());
084      fail();
085    } catch (NoSuchElementException e) {
086    }
087  }
088
089  @CollectionSize.Require(ONE)
090  public void testSingletonMapFirst() {
091    assertEquals(a.getKey(), navigableMap.firstKey());
092  }
093
094  @CollectionSize.Require(ONE)
095  public void testSingletonMapLast() {
096    assertEquals(a.getKey(), navigableMap.lastKey());
097  }
098
099  @CollectionSize.Require(SEVERAL)
100  public void testFirst() {
101    assertEquals(a.getKey(), navigableMap.firstKey());
102  }
103
104  @CollectionSize.Require(SEVERAL)
105  public void testLast() {
106    assertEquals(c.getKey(), navigableMap.lastKey());
107  }
108
109  @CollectionSize.Require(absent = ZERO)
110  public void testHeadMapExclusive() {
111    assertFalse(navigableMap.headMap(a.getKey()).containsKey(a.getKey()));
112  }
113
114  @CollectionSize.Require(absent = ZERO)
115  public void testTailMapInclusive() {
116    assertTrue(navigableMap.tailMap(a.getKey()).containsKey(a.getKey()));
117  }
118
119  public void testHeadMap() {
120    List<Entry<K, V>> entries =
121        Helpers.copyToList(
122            getSubjectGenerator()
123                .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
124    Collections.sort(entries, Helpers.<K, V>entryComparator(navigableMap.comparator()));
125    for (int i = 0; i < entries.size(); i++) {
126      assertEqualInOrder(
127          entries.subList(0, i), navigableMap.headMap(entries.get(i).getKey()).entrySet());
128    }
129  }
130
131  public void testTailMap() {
132    List<Entry<K, V>> entries =
133        Helpers.copyToList(
134            getSubjectGenerator()
135                .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
136    Collections.sort(entries, Helpers.<K, V>entryComparator(navigableMap.comparator()));
137    for (int i = 0; i < entries.size(); i++) {
138      assertEqualInOrder(
139          entries.subList(i, entries.size()),
140          navigableMap.tailMap(entries.get(i).getKey()).entrySet());
141    }
142  }
143
144  public void testSubMap() {
145    List<Entry<K, V>> entries =
146        Helpers.copyToList(
147            getSubjectGenerator()
148                .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
149    Collections.sort(entries, Helpers.<K, V>entryComparator(navigableMap.comparator()));
150    for (int i = 0; i < entries.size(); i++) {
151      for (int j = i + 1; j < entries.size(); j++) {
152        assertEqualInOrder(
153            entries.subList(i, j),
154            navigableMap.subMap(entries.get(i).getKey(), entries.get(j).getKey()).entrySet());
155      }
156    }
157  }
158
159  @CollectionSize.Require(SEVERAL)
160  public void testSubMapIllegal() {
161    try {
162      navigableMap.subMap(c.getKey(), a.getKey());
163      fail("Expected IllegalArgumentException");
164    } catch (IllegalArgumentException expected) {
165    }
166  }
167
168  @CollectionSize.Require(absent = ZERO)
169  public void testOrderedByComparator() {
170    @SuppressWarnings("unchecked")
171    Comparator<? super K> comparator = navigableMap.comparator();
172    if (comparator == null) {
173      comparator =
174          new Comparator<K>() {
175            @SuppressWarnings("unchecked")
176            @Override
177            public int compare(K o1, K o2) {
178              return ((Comparable) o1).compareTo(o2);
179            }
180          };
181    }
182    Iterator<Entry<K, V>> entryItr = navigableMap.entrySet().iterator();
183    Entry<K, V> prevEntry = entryItr.next();
184    while (entryItr.hasNext()) {
185      Entry<K, V> nextEntry = entryItr.next();
186      assertTrue(comparator.compare(prevEntry.getKey(), nextEntry.getKey()) < 0);
187      prevEntry = nextEntry;
188    }
189  }
190}