1/*
2 * Copyright (C) 2011 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 * express or implied. See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15package com.google.common.collect;
16
17import static com.google.common.collect.BoundType.CLOSED;
18import static com.google.common.collect.BoundType.OPEN;
19
20import com.google.common.collect.testing.features.CollectionFeature;
21import com.google.common.collect.testing.features.CollectionSize;
22import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
23import com.google.common.collect.testing.google.TestStringMultisetGenerator;
24
25import junit.framework.Test;
26import junit.framework.TestSuite;
27
28import java.util.Arrays;
29import java.util.Collection;
30import java.util.Iterator;
31import java.util.List;
32import java.util.NavigableSet;
33
34import javax.annotation.Nullable;
35
36/**
37 * Tests for {@link ForwardingSortedMultiset}.
38 *
39 * @author Louis Wasserman
40 */
41public class ForwardingSortedMultisetTest extends ForwardingMultisetTest {
42  static class StandardImplForwardingSortedMultiset<E> extends ForwardingSortedMultiset<E> {
43    private final SortedMultiset<E> backingMultiset;
44
45    StandardImplForwardingSortedMultiset(SortedMultiset<E> backingMultiset) {
46      this.backingMultiset = backingMultiset;
47    }
48
49    @Override
50    protected SortedMultiset<E> delegate() {
51      return backingMultiset;
52    }
53
54    @Override
55    public SortedMultiset<E> descendingMultiset() {
56      return new StandardDescendingMultiset() {
57
58        @Override
59        Iterator<Entry<E>> entryIterator() {
60          return backingMultiset
61              .descendingMultiset()
62              .entrySet()
63              .iterator();
64        }
65      };
66    }
67
68    @Override
69    public NavigableSet<E> elementSet() {
70      return new StandardElementSet();
71    }
72
73    @Override
74    public Entry<E> firstEntry() {
75      return standardFirstEntry();
76    }
77
78    @Override
79    public Entry<E> lastEntry() {
80      return standardLastEntry();
81    }
82
83    @Override
84    public Entry<E> pollFirstEntry() {
85      return standardPollFirstEntry();
86    }
87
88    @Override
89    public Entry<E> pollLastEntry() {
90      return standardPollLastEntry();
91    }
92
93    @Override
94    public SortedMultiset<E> subMultiset(
95        E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) {
96      return standardSubMultiset(lowerBound, lowerBoundType, upperBound, upperBoundType);
97    }
98
99    @Override
100    public int count(@Nullable Object element) {
101      return standardCount(element);
102    }
103
104    @Override
105    public boolean equals(@Nullable Object object) {
106      return standardEquals(object);
107    }
108
109    @Override
110    public int hashCode() {
111      return standardHashCode();
112    }
113
114    @Override
115    public boolean add(E element) {
116      return standardAdd(element);
117    }
118
119    @Override
120    public boolean addAll(Collection<? extends E> collection) {
121      return standardAddAll(collection);
122    }
123
124    @Override
125    public void clear() {
126      standardClear();
127    }
128
129    @Override
130    public boolean contains(@Nullable Object object) {
131      return standardContains(object);
132    }
133
134    @Override
135    public boolean containsAll(Collection<?> collection) {
136      return standardContainsAll(collection);
137    }
138
139    @Override
140    public boolean isEmpty() {
141      return standardIsEmpty();
142    }
143
144    @Override
145    public Iterator<E> iterator() {
146      return standardIterator();
147    }
148
149    @Override
150    public boolean remove(@Nullable Object object) {
151      return standardRemove(object);
152    }
153
154    @Override
155    public boolean removeAll(Collection<?> collection) {
156      return standardRemoveAll(collection);
157    }
158
159    @Override
160    public boolean retainAll(Collection<?> collection) {
161      return standardRetainAll(collection);
162    }
163
164    @Override
165    public int size() {
166      return standardSize();
167    }
168
169    @Override
170    public Object[] toArray() {
171      return standardToArray();
172    }
173
174    @Override
175    public <T> T[] toArray(T[] array) {
176      return standardToArray(array);
177    }
178  }
179
180  public static Test suite() {
181    TestSuite suite = new TestSuite();
182
183    suite.addTestSuite(ForwardingSortedMultisetTest.class);
184    suite.addTest(SortedMultisetTestSuiteBuilder
185        .using(new TestStringMultisetGenerator() {
186          @Override
187          protected Multiset<String> create(String[] elements) {
188            return new StandardImplForwardingSortedMultiset<String>(
189                TreeMultiset.create(Arrays.asList(elements)));
190          }
191
192          @Override
193          public List<String> order(List<String> insertionOrder) {
194            return Ordering.natural().sortedCopy(insertionOrder);
195          }
196        })
197        .named("ForwardingSortedMultiset with standard impls")
198        .withFeatures(
199            CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE,
200            CollectionFeature.ALLOWS_NULL_QUERIES)
201        .createTestSuite());
202
203    return suite;
204  }
205
206  @Override
207  public void setUp() throws Exception {
208    super.setUp();
209    /*
210     * Class parameters must be raw, so we can't create a proxy with generic type arguments. The
211     * created proxy only records calls and returns null, so the type is irrelevant at runtime.
212     */
213    @SuppressWarnings("unchecked")
214    final SortedMultiset<String> sortedMultiset = createProxyInstance(SortedMultiset.class);
215    forward = new ForwardingSortedMultiset<String>() {
216      @Override
217      protected SortedMultiset<String> delegate() {
218        return sortedMultiset;
219      }
220    };
221  }
222
223  public void testComparator() {
224    forward().comparator();
225    assertEquals("[comparator]", getCalls());
226  }
227
228  public void testFirstEntry() {
229    forward().firstEntry();
230    assertEquals("[firstEntry]", getCalls());
231  }
232
233  public void testLastEntry() {
234    forward().lastEntry();
235    assertEquals("[lastEntry]", getCalls());
236  }
237
238  public void testPollFirstEntry() {
239    forward().pollFirstEntry();
240    assertEquals("[pollFirstEntry]", getCalls());
241  }
242
243  public void testPollLastEntry() {
244    forward().pollLastEntry();
245    assertEquals("[pollLastEntry]", getCalls());
246  }
247
248  public void testDescendingMultiset() {
249    forward().descendingMultiset();
250    assertEquals("[descendingMultiset]", getCalls());
251  }
252
253  public void testHeadMultiset() {
254    forward().headMultiset("abcd", CLOSED);
255    assertEquals("[headMultiset(Object,BoundType)]", getCalls());
256  }
257
258  public void testSubMultiset() {
259    forward().subMultiset("abcd", CLOSED, "dcba", OPEN);
260    assertEquals("[subMultiset(Object,BoundType,Object,BoundType)]", getCalls());
261  }
262
263  public void testTailMultiset() {
264    forward().tailMultiset("last", OPEN);
265    assertEquals("[tailMultiset(Object,BoundType)]", getCalls());
266  }
267
268  @Override
269  protected SortedMultiset<String> forward() {
270    return (SortedMultiset<String>) super.forward();
271  }
272}
273