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