1/*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import com.google.common.collect.testing.Helpers.NullsBeforeTwo;
20import com.google.common.collect.testing.SafeTreeMap;
21import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
22import com.google.common.collect.testing.TestStringSortedMapGenerator;
23import com.google.common.collect.testing.features.CollectionFeature;
24import com.google.common.collect.testing.features.CollectionSize;
25import com.google.common.collect.testing.features.MapFeature;
26
27import junit.framework.Test;
28import junit.framework.TestSuite;
29
30import java.util.Collection;
31import java.util.Comparator;
32import java.util.Iterator;
33import java.util.Map;
34import java.util.Map.Entry;
35import java.util.Set;
36import java.util.SortedMap;
37
38/**
39 * Tests for {@code ForwardingSortedMap}.
40 *
41 * @author Robert Konigsberg
42 */
43public class ForwardingSortedMapTest extends ForwardingMapTest {
44  static class StandardImplForwardingSortedMap<K, V>
45      extends ForwardingSortedMap<K, V> {
46    private final SortedMap<K, V> backingMap;
47
48    StandardImplForwardingSortedMap(SortedMap<K, V> backingMap) {
49      this.backingMap = backingMap;
50    }
51
52    @Override protected SortedMap<K, V> delegate() {
53      return backingMap;
54    }
55
56    @Override public boolean containsKey(Object key) {
57      return standardContainsKey(key);
58    }
59
60    @Override public boolean containsValue(Object value) {
61      return standardContainsValue(value);
62    }
63
64    @Override public void putAll(Map<? extends K, ? extends V> map) {
65      standardPutAll(map);
66    }
67
68    @Override public V remove(Object object) {
69      return standardRemove(object);
70    }
71
72    @Override public boolean equals(Object object) {
73      return standardEquals(object);
74    }
75
76    @Override public int hashCode() {
77      return standardHashCode();
78    }
79
80    @Override public Set<K> keySet() {
81      return new StandardKeySet();
82    }
83
84    @Override public Collection<V> values() {
85      return new StandardValues();
86    }
87
88    @Override public String toString() {
89      return standardToString();
90    }
91
92    @Override public Set<Entry<K, V>> entrySet() {
93      return new StandardEntrySet() {
94        @Override
95        public Iterator<Entry<K, V>> iterator() {
96          return backingMap.entrySet().iterator();
97        }
98      };
99    }
100
101    @Override public void clear() {
102      standardClear();
103    }
104
105    @Override public boolean isEmpty() {
106      return standardIsEmpty();
107    }
108
109    @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
110      return standardSubMap(fromKey, toKey);
111    }
112  }
113
114  public static Test suite() {
115    TestSuite suite = new TestSuite();
116
117    suite.addTestSuite(ForwardingSortedMapTest.class);
118    suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
119      @Override protected SortedMap<String, String> create(
120          Entry<String, String>[] entries) {
121        SortedMap<String, String> map = new SafeTreeMap<String, String>();
122        for (Entry<String, String> entry : entries) {
123          map.put(entry.getKey(), entry.getValue());
124        }
125        return new StandardImplForwardingSortedMap<String, String>(map);
126      }
127    }).named("ForwardingSortedMap[SafeTreeMap] with no comparator and standard "
128        + "implementations").withFeatures(CollectionSize.ANY,
129        CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
130        MapFeature.GENERAL_PURPOSE, CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
131        .createTestSuite());
132    suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
133      private final Comparator<String> comparator = NullsBeforeTwo.INSTANCE;
134
135      @Override protected SortedMap<String, String> create(
136          Entry<String, String>[] entries) {
137        SortedMap<String, String> map =
138            new SafeTreeMap<String, String>(comparator);
139        for (Entry<String, String> entry : entries) {
140          map.put(entry.getKey(), entry.getValue());
141        }
142        return new StandardImplForwardingSortedMap<String, String>(map);
143      }
144    }).named("ForwardingSortedMap[SafeTreeMap] with natural comparator and "
145        + "standard implementations").withFeatures(CollectionSize.ANY,
146        CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
147        MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_ANY_NULL_QUERIES,
148        MapFeature.GENERAL_PURPOSE,
149        CollectionFeature.SUPPORTS_ITERATOR_REMOVE).createTestSuite());
150    suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
151      @Override protected SortedMap<String, String> create(
152          Entry<String, String>[] entries) {
153        ImmutableSortedMap.Builder<String, String> builder =
154            ImmutableSortedMap.naturalOrder();
155        for (Entry<String, String> entry : entries) {
156          builder.put(entry.getKey(), entry.getValue());
157        }
158        return new StandardImplForwardingSortedMap<String, String>(
159            builder.build());
160      }
161    }).named("ForwardingSortedMap[ImmutableSortedMap] with standard "
162        + "implementations").withFeatures(
163        CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
164        MapFeature.ALLOWS_ANY_NULL_QUERIES)
165        .createTestSuite());
166
167    return suite;
168  }
169
170  @Override public void setUp() throws Exception {
171    super.setUp();
172    /*
173     * Class parameters must be raw, so we can't create a proxy with generic
174     * type arguments. The created proxy only records calls and returns null, so
175     * the type is irrelevant at runtime.
176     */
177    @SuppressWarnings("unchecked")
178    final SortedMap<String, Boolean> sortedMap =
179        createProxyInstance(SortedMap.class);
180    forward = new ForwardingSortedMap<String, Boolean>() {
181      @Override protected SortedMap<String, Boolean> delegate() {
182        return sortedMap;
183      }
184    };
185  }
186
187  public void testComparator() {
188    forward().comparator();
189    assertEquals("[comparator]", getCalls());
190  }
191
192  public void testFirstKey() {
193    forward().firstKey();
194    assertEquals("[firstKey]", getCalls());
195  }
196
197  public void testHeadMap_K() {
198    forward().headMap("asdf");
199    assertEquals("[headMap(Object)]", getCalls());
200  }
201
202  public void testLastKey() {
203    forward().lastKey();
204    assertEquals("[lastKey]", getCalls());
205  }
206
207  public void testSubMap_K_K() {
208    forward().subMap("first", "last");
209    assertEquals("[subMap(Object,Object)]", getCalls());
210  }
211
212  public void testTailMap_K() {
213    forward().tailMap("last");
214    assertEquals("[tailMap(Object)]", getCalls());
215  }
216
217  @Override SortedMap<String, Boolean> forward() {
218    return (SortedMap<String, Boolean>) super.forward();
219  }
220}
221