• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 package com.google.common.collect.testing.testers;
18 
19 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
20 import static com.google.common.collect.testing.features.CollectionSize.ONE;
21 import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
22 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
23 import static org.junit.Assert.assertThrows;
24 
25 import com.google.common.annotations.GwtIncompatible;
26 import com.google.common.collect.testing.Helpers;
27 import com.google.common.collect.testing.features.CollectionFeature;
28 import com.google.common.collect.testing.features.CollectionSize;
29 import java.lang.reflect.Method;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.NavigableSet;
35 import java.util.TreeSet;
36 import org.junit.Ignore;
37 
38 /**
39  * A generic JUnit test which tests operations on a NavigableSet. Can't be invoked directly; please
40  * see {@code NavigableSetTestSuiteBuilder}.
41  *
42  * @author Jesse Wilson
43  * @author Louis Wasserman
44  */
45 @GwtIncompatible
46 @Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
47 @SuppressWarnings("JUnit4ClassUsedInJUnit3")
48 public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
49 
50   private NavigableSet<E> navigableSet;
51   private List<E> values;
52   private E a;
53   private E b;
54   private E c;
55 
56   @Override
setUp()57   public void setUp() throws Exception {
58     super.setUp();
59     navigableSet = (NavigableSet<E>) getSet();
60     values =
61         Helpers.copyToList(
62             getSubjectGenerator()
63                 .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
64     Collections.sort(values, navigableSet.comparator());
65 
66     // some tests assume SEVERAL == 3
67     if (values.size() >= 1) {
68       a = values.get(0);
69       if (values.size() >= 3) {
70         b = values.get(1);
71         c = values.get(2);
72       }
73     }
74   }
75 
76   /** Resets the contents of navigableSet to have elements a, c, for the navigation tests. */
resetWithHole()77   protected void resetWithHole() {
78     super.resetContainer(getSubjectGenerator().create(a, c));
79     navigableSet = (NavigableSet<E>) getSet();
80   }
81 
82   @CollectionFeature.Require(SUPPORTS_REMOVE)
83   @CollectionSize.Require(ZERO)
testEmptySetPollFirst()84   public void testEmptySetPollFirst() {
85     assertNull(navigableSet.pollFirst());
86   }
87 
88   @CollectionSize.Require(ZERO)
testEmptySetNearby()89   public void testEmptySetNearby() {
90     assertNull(navigableSet.lower(e0()));
91     assertNull(navigableSet.floor(e0()));
92     assertNull(navigableSet.ceiling(e0()));
93     assertNull(navigableSet.higher(e0()));
94   }
95 
96   @CollectionFeature.Require(SUPPORTS_REMOVE)
97   @CollectionSize.Require(ZERO)
testEmptySetPollLast()98   public void testEmptySetPollLast() {
99     assertNull(navigableSet.pollLast());
100   }
101 
102   @CollectionFeature.Require(SUPPORTS_REMOVE)
103   @CollectionSize.Require(ONE)
testSingletonSetPollFirst()104   public void testSingletonSetPollFirst() {
105     assertEquals(a, navigableSet.pollFirst());
106     assertTrue(navigableSet.isEmpty());
107   }
108 
109   @CollectionSize.Require(ONE)
testSingletonSetNearby()110   public void testSingletonSetNearby() {
111     assertNull(navigableSet.lower(e0()));
112     assertEquals(a, navigableSet.floor(e0()));
113     assertEquals(a, navigableSet.ceiling(e0()));
114     assertNull(navigableSet.higher(e0()));
115   }
116 
117   @CollectionFeature.Require(SUPPORTS_REMOVE)
118   @CollectionSize.Require(ONE)
testSingletonSetPollLast()119   public void testSingletonSetPollLast() {
120     assertEquals(a, navigableSet.pollLast());
121     assertTrue(navigableSet.isEmpty());
122   }
123 
124   @CollectionFeature.Require(SUPPORTS_REMOVE)
125   @CollectionSize.Require(SEVERAL)
testPollFirst()126   public void testPollFirst() {
127     assertEquals(a, navigableSet.pollFirst());
128     assertEquals(values.subList(1, values.size()), Helpers.copyToList(navigableSet));
129   }
130 
131   @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
testPollFirstUnsupported()132   public void testPollFirstUnsupported() {
133     assertThrows(UnsupportedOperationException.class, () -> navigableSet.pollFirst());
134   }
135 
136   @CollectionSize.Require(SEVERAL)
testLowerHole()137   public void testLowerHole() {
138     resetWithHole();
139     assertEquals(null, navigableSet.lower(a));
140     assertEquals(a, navigableSet.lower(b));
141     assertEquals(a, navigableSet.lower(c));
142   }
143 
144   @CollectionSize.Require(SEVERAL)
testFloorHole()145   public void testFloorHole() {
146     resetWithHole();
147     assertEquals(a, navigableSet.floor(a));
148     assertEquals(a, navigableSet.floor(b));
149     assertEquals(c, navigableSet.floor(c));
150   }
151 
152   @CollectionSize.Require(SEVERAL)
testCeilingHole()153   public void testCeilingHole() {
154     resetWithHole();
155     assertEquals(a, navigableSet.ceiling(a));
156     assertEquals(c, navigableSet.ceiling(b));
157     assertEquals(c, navigableSet.ceiling(c));
158   }
159 
160   @CollectionSize.Require(SEVERAL)
testHigherHole()161   public void testHigherHole() {
162     resetWithHole();
163     assertEquals(c, navigableSet.higher(a));
164     assertEquals(c, navigableSet.higher(b));
165     assertEquals(null, navigableSet.higher(c));
166   }
167 
168   /*
169    * TODO(cpovirk): make "too small" and "too large" elements available for better navigation
170    * testing. At that point, we may be able to eliminate the "hole" tests, which would mean that
171    * ContiguousSet's tests would no longer need to suppress them.
172    */
173   @CollectionSize.Require(SEVERAL)
testLower()174   public void testLower() {
175     assertEquals(null, navigableSet.lower(a));
176     assertEquals(a, navigableSet.lower(b));
177     assertEquals(b, navigableSet.lower(c));
178   }
179 
180   @CollectionSize.Require(SEVERAL)
testFloor()181   public void testFloor() {
182     assertEquals(a, navigableSet.floor(a));
183     assertEquals(b, navigableSet.floor(b));
184     assertEquals(c, navigableSet.floor(c));
185   }
186 
187   @CollectionSize.Require(SEVERAL)
testCeiling()188   public void testCeiling() {
189     assertEquals(a, navigableSet.ceiling(a));
190     assertEquals(b, navigableSet.ceiling(b));
191     assertEquals(c, navigableSet.ceiling(c));
192   }
193 
194   @CollectionSize.Require(SEVERAL)
testHigher()195   public void testHigher() {
196     assertEquals(b, navigableSet.higher(a));
197     assertEquals(c, navigableSet.higher(b));
198     assertEquals(null, navigableSet.higher(c));
199   }
200 
201   @CollectionFeature.Require(SUPPORTS_REMOVE)
202   @CollectionSize.Require(SEVERAL)
testPollLast()203   public void testPollLast() {
204     assertEquals(c, navigableSet.pollLast());
205     assertEquals(values.subList(0, values.size() - 1), Helpers.copyToList(navigableSet));
206   }
207 
208   @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
testPollLastUnsupported()209   public void testPollLastUnsupported() {
210     assertThrows(UnsupportedOperationException.class, () -> navigableSet.pollLast());
211   }
212 
213   @CollectionSize.Require(SEVERAL)
testDescendingNavigation()214   public void testDescendingNavigation() {
215     List<E> descending = new ArrayList<>();
216     for (Iterator<E> i = navigableSet.descendingIterator(); i.hasNext(); ) {
217       descending.add(i.next());
218     }
219     Collections.reverse(descending);
220     assertEquals(values, descending);
221   }
222 
testEmptySubSet()223   public void testEmptySubSet() {
224     NavigableSet<E> empty = navigableSet.subSet(e0(), false, e0(), false);
225     assertEquals(new TreeSet<E>(), empty);
226   }
227 
228   /*
229    * TODO(cpovirk): more testing of subSet/headSet/tailSet/descendingSet? and/or generate derived
230    * suites?
231    */
232 
233   /**
234    * Returns the {@link Method} instances for the test methods in this class that create a set with
235    * a "hole" in it so that set tests of {@code ContiguousSet} can suppress them with {@code
236    * FeatureSpecificTestSuiteBuilder.suppressing()}.
237    */
238   /*
239    * TODO(cpovirk): or we could make HOLES_FORBIDDEN a feature. Or we could declare that
240    * implementations are permitted to throw IAE if a hole is requested, and we could update
241    * test*Hole to permit IAE. (But might this ignore genuine bugs?) But see the TODO above
242    * testLower, which could make this all unnecessary
243    */
getHoleMethods()244   public static Method[] getHoleMethods() {
245     return new Method[] {
246       Helpers.getMethod(NavigableSetNavigationTester.class, "testLowerHole"),
247       Helpers.getMethod(NavigableSetNavigationTester.class, "testFloorHole"),
248       Helpers.getMethod(NavigableSetNavigationTester.class, "testCeilingHole"),
249       Helpers.getMethod(NavigableSetNavigationTester.class, "testHigherHole"),
250     };
251   }
252 }
253