1 /* 2 * Copyright (C) 2011 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; 18 19 import static com.google.common.collect.BoundType.CLOSED; 20 import static com.google.common.collect.BoundType.OPEN; 21 import static com.google.common.collect.DiscreteDomain.integers; 22 import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES; 23 import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER; 24 import static com.google.common.collect.testing.features.CollectionFeature.NON_STANDARD_TOSTRING; 25 import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS; 26 import static com.google.common.collect.testing.testers.NavigableSetNavigationTester.getHoleMethods; 27 import static com.google.common.testing.SerializableTester.reserialize; 28 import static com.google.common.testing.SerializableTester.reserializeAndAssert; 29 import static com.google.common.truth.Truth.assertThat; 30 31 import com.google.common.annotations.GwtCompatible; 32 import com.google.common.annotations.GwtIncompatible; 33 import com.google.common.collect.testing.NavigableSetTestSuiteBuilder; 34 import com.google.common.collect.testing.features.CollectionSize; 35 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetDescendingGenerator; 36 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetGenerator; 37 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetHeadsetGenerator; 38 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetSubsetGenerator; 39 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetTailsetGenerator; 40 import com.google.common.testing.EqualsTester; 41 import java.util.Collection; 42 import java.util.Set; 43 import junit.framework.Test; 44 import junit.framework.TestCase; 45 import junit.framework.TestSuite; 46 47 /** 48 * @author Gregory Kick 49 */ 50 @GwtCompatible(emulated = true) 51 public class ContiguousSetTest extends TestCase { 52 private static final DiscreteDomain<Integer> NOT_EQUAL_TO_INTEGERS = 53 new DiscreteDomain<Integer>() { 54 @Override 55 public Integer next(Integer value) { 56 return integers().next(value); 57 } 58 59 @Override 60 public Integer previous(Integer value) { 61 return integers().previous(value); 62 } 63 64 @Override 65 public long distance(Integer start, Integer end) { 66 return integers().distance(start, end); 67 } 68 69 @Override 70 public Integer minValue() { 71 return integers().minValue(); 72 } 73 74 @Override 75 public Integer maxValue() { 76 return integers().maxValue(); 77 } 78 }; 79 testInvalidIntRange()80 public void testInvalidIntRange() { 81 try { 82 ContiguousSet.closed(2, 1); 83 fail(); 84 } catch (IllegalArgumentException expected) { 85 } 86 try { 87 ContiguousSet.closedOpen(2, 1); 88 fail(); 89 } catch (IllegalArgumentException expected) { 90 } 91 } 92 testInvalidLongRange()93 public void testInvalidLongRange() { 94 try { 95 ContiguousSet.closed(2L, 1L); 96 fail(); 97 } catch (IllegalArgumentException expected) { 98 } 99 try { 100 ContiguousSet.closedOpen(2L, 1L); 101 fail(); 102 } catch (IllegalArgumentException expected) { 103 } 104 } 105 testEquals()106 public void testEquals() { 107 new EqualsTester() 108 .addEqualityGroup( 109 ContiguousSet.create(Range.closed(1, 3), integers()), 110 ContiguousSet.closed(1, 3), 111 ContiguousSet.create(Range.closedOpen(1, 4), integers()), 112 ContiguousSet.closedOpen(1, 4), 113 ContiguousSet.create(Range.openClosed(0, 3), integers()), 114 ContiguousSet.create(Range.open(0, 4), integers()), 115 ContiguousSet.create(Range.closed(1, 3), NOT_EQUAL_TO_INTEGERS), 116 ContiguousSet.create(Range.closedOpen(1, 4), NOT_EQUAL_TO_INTEGERS), 117 ContiguousSet.create(Range.openClosed(0, 3), NOT_EQUAL_TO_INTEGERS), 118 ContiguousSet.create(Range.open(0, 4), NOT_EQUAL_TO_INTEGERS), 119 ImmutableSortedSet.of(1, 2, 3)) 120 .addEqualityGroup( 121 ContiguousSet.create(Range.closedOpen(1, 1), integers()), 122 ContiguousSet.closedOpen(1, 1), 123 ContiguousSet.closedOpen(Integer.MIN_VALUE, Integer.MIN_VALUE), 124 ImmutableSortedSet.of(), 125 ImmutableSet.of()) 126 .testEquals(); 127 // not testing hashCode for these because it takes forever to compute 128 assertEquals( 129 ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), 130 ContiguousSet.create(Range.<Integer>all(), integers())); 131 assertEquals( 132 ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), 133 ContiguousSet.create(Range.atLeast(Integer.MIN_VALUE), integers())); 134 assertEquals( 135 ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), 136 ContiguousSet.create(Range.atMost(Integer.MAX_VALUE), integers())); 137 } 138 139 @GwtIncompatible // SerializableTester testSerialization()140 public void testSerialization() { 141 ContiguousSet<Integer> empty = ContiguousSet.create(Range.closedOpen(1, 1), integers()); 142 assertTrue(empty instanceof EmptyContiguousSet); 143 reserializeAndAssert(empty); 144 145 ContiguousSet<Integer> regular = ContiguousSet.create(Range.closed(1, 3), integers()); 146 assertTrue(regular instanceof RegularContiguousSet); 147 reserializeAndAssert(regular); 148 149 /* 150 * Make sure that we're using RegularContiguousSet.SerializedForm and not 151 * ImmutableSet.SerializedForm, which would be enormous. 152 */ 153 ContiguousSet<Integer> enormous = ContiguousSet.create(Range.<Integer>all(), integers()); 154 assertTrue(enormous instanceof RegularContiguousSet); 155 // We can't use reserializeAndAssert because it calls hashCode, which is enormously slow. 156 ContiguousSet<Integer> enormousReserialized = reserialize(enormous); 157 assertEquals(enormous, enormousReserialized); 158 } 159 160 private static final DiscreteDomain<Integer> UNBOUNDED_THROWING_DOMAIN = 161 new DiscreteDomain<Integer>() { 162 @Override 163 public Integer next(Integer value) { 164 throw new AssertionError(); 165 } 166 167 @Override 168 public Integer previous(Integer value) { 169 throw new AssertionError(); 170 } 171 172 @Override 173 public long distance(Integer start, Integer end) { 174 throw new AssertionError(); 175 } 176 }; 177 testCreate_noMin()178 public void testCreate_noMin() { 179 Range<Integer> range = Range.lessThan(0); 180 try { 181 ContiguousSet.create(range, UNBOUNDED_THROWING_DOMAIN); 182 fail(); 183 } catch (IllegalArgumentException expected) { 184 } 185 } 186 testCreate_noMax()187 public void testCreate_noMax() { 188 Range<Integer> range = Range.greaterThan(0); 189 try { 190 ContiguousSet.create(range, UNBOUNDED_THROWING_DOMAIN); 191 fail(); 192 } catch (IllegalArgumentException expected) { 193 } 194 } 195 testCreate_empty()196 public void testCreate_empty() { 197 assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.closedOpen(1, 1), integers())); 198 assertEquals(ImmutableSet.of(), ContiguousSet.closedOpen(1, 1)); 199 assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.openClosed(5, 5), integers())); 200 assertEquals( 201 ImmutableSet.of(), ContiguousSet.create(Range.lessThan(Integer.MIN_VALUE), integers())); 202 assertEquals( 203 ImmutableSet.of(), ContiguousSet.create(Range.greaterThan(Integer.MAX_VALUE), integers())); 204 } 205 testHeadSet()206 public void testHeadSet() { 207 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 208 assertThat(set.headSet(1)).isEmpty(); 209 assertThat(set.headSet(2)).containsExactly(1).inOrder(); 210 assertThat(set.headSet(3)).containsExactly(1, 2).inOrder(); 211 assertThat(set.headSet(4)).containsExactly(1, 2, 3).inOrder(); 212 assertThat(set.headSet(Integer.MAX_VALUE)).containsExactly(1, 2, 3).inOrder(); 213 assertThat(set.headSet(1, true)).containsExactly(1).inOrder(); 214 assertThat(set.headSet(2, true)).containsExactly(1, 2).inOrder(); 215 assertThat(set.headSet(3, true)).containsExactly(1, 2, 3).inOrder(); 216 assertThat(set.headSet(4, true)).containsExactly(1, 2, 3).inOrder(); 217 assertThat(set.headSet(Integer.MAX_VALUE, true)).containsExactly(1, 2, 3).inOrder(); 218 } 219 testHeadSet_tooSmall()220 public void testHeadSet_tooSmall() { 221 assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).headSet(0)).isEmpty(); 222 } 223 testTailSet()224 public void testTailSet() { 225 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 226 assertThat(set.tailSet(Integer.MIN_VALUE)).containsExactly(1, 2, 3).inOrder(); 227 assertThat(set.tailSet(1)).containsExactly(1, 2, 3).inOrder(); 228 assertThat(set.tailSet(2)).containsExactly(2, 3).inOrder(); 229 assertThat(set.tailSet(3)).containsExactly(3).inOrder(); 230 assertThat(set.tailSet(Integer.MIN_VALUE, false)).containsExactly(1, 2, 3).inOrder(); 231 assertThat(set.tailSet(1, false)).containsExactly(2, 3).inOrder(); 232 assertThat(set.tailSet(2, false)).containsExactly(3).inOrder(); 233 assertThat(set.tailSet(3, false)).isEmpty(); 234 } 235 testTailSet_tooLarge()236 public void testTailSet_tooLarge() { 237 assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).tailSet(4)).isEmpty(); 238 } 239 testSubSet()240 public void testSubSet() { 241 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 242 assertThat(set.subSet(1, 4)).containsExactly(1, 2, 3).inOrder(); 243 assertThat(set.subSet(2, 4)).containsExactly(2, 3).inOrder(); 244 assertThat(set.subSet(3, 4)).containsExactly(3).inOrder(); 245 assertThat(set.subSet(3, 3)).isEmpty(); 246 assertThat(set.subSet(2, 3)).containsExactly(2).inOrder(); 247 assertThat(set.subSet(1, 3)).containsExactly(1, 2).inOrder(); 248 assertThat(set.subSet(1, 2)).containsExactly(1).inOrder(); 249 assertThat(set.subSet(2, 2)).isEmpty(); 250 assertThat(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).containsExactly(1, 2, 3).inOrder(); 251 assertThat(set.subSet(1, true, 3, true)).containsExactly(1, 2, 3).inOrder(); 252 assertThat(set.subSet(1, false, 3, true)).containsExactly(2, 3).inOrder(); 253 assertThat(set.subSet(1, true, 3, false)).containsExactly(1, 2).inOrder(); 254 assertThat(set.subSet(1, false, 3, false)).containsExactly(2).inOrder(); 255 } 256 testSubSet_outOfOrder()257 public void testSubSet_outOfOrder() { 258 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 259 try { 260 set.subSet(3, 2); 261 fail(); 262 } catch (IllegalArgumentException expected) { 263 } 264 } 265 testSubSet_tooLarge()266 public void testSubSet_tooLarge() { 267 assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(4, 6)).isEmpty(); 268 } 269 testSubSet_tooSmall()270 public void testSubSet_tooSmall() { 271 assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(-1, 0)).isEmpty(); 272 } 273 testFirst()274 public void testFirst() { 275 assertEquals(1, ContiguousSet.create(Range.closed(1, 3), integers()).first().intValue()); 276 assertEquals(1, ContiguousSet.create(Range.open(0, 4), integers()).first().intValue()); 277 assertEquals( 278 Integer.MIN_VALUE, 279 ContiguousSet.create(Range.<Integer>all(), integers()).first().intValue()); 280 } 281 testLast()282 public void testLast() { 283 assertEquals(3, ContiguousSet.create(Range.closed(1, 3), integers()).last().intValue()); 284 assertEquals(3, ContiguousSet.create(Range.open(0, 4), integers()).last().intValue()); 285 assertEquals( 286 Integer.MAX_VALUE, 287 ContiguousSet.create(Range.<Integer>all(), integers()).last().intValue()); 288 } 289 testContains()290 public void testContains() { 291 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 292 assertFalse(set.contains(0)); 293 assertTrue(set.contains(1)); 294 assertTrue(set.contains(2)); 295 assertTrue(set.contains(3)); 296 assertFalse(set.contains(4)); 297 set = ContiguousSet.create(Range.open(0, 4), integers()); 298 assertFalse(set.contains(0)); 299 assertTrue(set.contains(1)); 300 assertTrue(set.contains(2)); 301 assertTrue(set.contains(3)); 302 assertFalse(set.contains(4)); 303 assertFalse(set.contains((Object) "blah")); 304 } 305 testContainsAll()306 public void testContainsAll() { 307 ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 308 for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) { 309 assertTrue(set.containsAll(subset)); 310 } 311 for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) { 312 assertFalse(set.containsAll(Sets.union(subset, ImmutableSet.of(9)))); 313 } 314 assertFalse(set.containsAll((Collection<?>) ImmutableSet.of("blah"))); 315 } 316 testRange()317 public void testRange() { 318 assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.closed(1, 3), integers()).range()); 319 assertEquals(Range.closed(1, 3), ContiguousSet.closed(1, 3).range()); 320 assertEquals( 321 Range.closed(1, 3), ContiguousSet.create(Range.closedOpen(1, 4), integers()).range()); 322 assertEquals(Range.closed(1, 3), ContiguousSet.closedOpen(1, 4).range()); 323 assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.open(0, 4), integers()).range()); 324 assertEquals( 325 Range.closed(1, 3), ContiguousSet.create(Range.openClosed(0, 3), integers()).range()); 326 327 assertEquals( 328 Range.openClosed(0, 3), 329 ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, CLOSED)); 330 assertEquals( 331 Range.openClosed(0, 3), 332 ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, CLOSED)); 333 assertEquals( 334 Range.openClosed(0, 3), 335 ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, CLOSED)); 336 assertEquals( 337 Range.openClosed(0, 3), 338 ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, CLOSED)); 339 340 assertEquals( 341 Range.open(0, 4), ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, OPEN)); 342 assertEquals( 343 Range.open(0, 4), 344 ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, OPEN)); 345 assertEquals( 346 Range.open(0, 4), ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, OPEN)); 347 assertEquals( 348 Range.open(0, 4), 349 ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, OPEN)); 350 351 assertEquals( 352 Range.closedOpen(1, 4), 353 ContiguousSet.create(Range.closed(1, 3), integers()).range(CLOSED, OPEN)); 354 assertEquals( 355 Range.closedOpen(1, 4), 356 ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(CLOSED, OPEN)); 357 assertEquals( 358 Range.closedOpen(1, 4), 359 ContiguousSet.create(Range.open(0, 4), integers()).range(CLOSED, OPEN)); 360 assertEquals( 361 Range.closedOpen(1, 4), 362 ContiguousSet.create(Range.openClosed(0, 3), integers()).range(CLOSED, OPEN)); 363 } 364 testRange_unboundedRange()365 public void testRange_unboundedRange() { 366 assertEquals( 367 Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), 368 ContiguousSet.create(Range.<Integer>all(), integers()).range()); 369 assertEquals( 370 Range.atLeast(Integer.MIN_VALUE), 371 ContiguousSet.create(Range.<Integer>all(), integers()).range(CLOSED, OPEN)); 372 assertEquals( 373 Range.all(), ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, OPEN)); 374 assertEquals( 375 Range.atMost(Integer.MAX_VALUE), 376 ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, CLOSED)); 377 } 378 testIntersection_empty()379 public void testIntersection_empty() { 380 ContiguousSet<Integer> set = ContiguousSet.closed(1, 3); 381 ContiguousSet<Integer> emptySet = ContiguousSet.closedOpen(2, 2); 382 assertEquals(ImmutableSet.of(), set.intersection(emptySet)); 383 assertEquals(ImmutableSet.of(), emptySet.intersection(set)); 384 assertEquals( 385 ImmutableSet.of(), 386 ContiguousSet.create(Range.closed(-5, -1), integers()) 387 .intersection(ContiguousSet.create(Range.open(3, 64), integers()))); 388 } 389 testIntersection()390 public void testIntersection() { 391 ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); 392 assertEquals( 393 ImmutableSet.of(1, 2, 3), 394 ContiguousSet.create(Range.open(-1, 4), integers()).intersection(set)); 395 assertEquals( 396 ImmutableSet.of(1, 2, 3), 397 set.intersection(ContiguousSet.create(Range.open(-1, 4), integers()))); 398 assertEquals( 399 ImmutableSet.of(3), set.intersection(ContiguousSet.create(Range.closed(3, 5), integers()))); 400 } 401 testAsList()402 public void testAsList() { 403 ImmutableList<Integer> list = ContiguousSet.create(Range.closed(1, 3), integers()).asList(); 404 for (int i = 0; i < 3; i++) { 405 assertEquals(i + 1, list.get(i).intValue()); 406 } 407 assertEquals(ImmutableList.of(1, 2, 3), ImmutableList.copyOf(list.iterator())); 408 assertEquals(ImmutableList.of(1, 2, 3), ImmutableList.copyOf(list.toArray(new Integer[0]))); 409 } 410 411 @GwtIncompatible // suite 412 public static class BuiltTests extends TestCase { suite()413 public static Test suite() { 414 TestSuite suite = new TestSuite(); 415 416 suite.addTest( 417 NavigableSetTestSuiteBuilder.using(new ContiguousSetGenerator()) 418 .named("Range.asSet") 419 .withFeatures( 420 CollectionSize.ANY, 421 KNOWN_ORDER, 422 ALLOWS_NULL_QUERIES, 423 NON_STANDARD_TOSTRING, 424 RESTRICTS_ELEMENTS) 425 .suppressing(getHoleMethods()) 426 .createTestSuite()); 427 428 suite.addTest( 429 NavigableSetTestSuiteBuilder.using(new ContiguousSetHeadsetGenerator()) 430 .named("Range.asSet, headset") 431 .withFeatures( 432 CollectionSize.ANY, 433 KNOWN_ORDER, 434 ALLOWS_NULL_QUERIES, 435 NON_STANDARD_TOSTRING, 436 RESTRICTS_ELEMENTS) 437 .suppressing(getHoleMethods()) 438 .createTestSuite()); 439 440 suite.addTest( 441 NavigableSetTestSuiteBuilder.using(new ContiguousSetTailsetGenerator()) 442 .named("Range.asSet, tailset") 443 .withFeatures( 444 CollectionSize.ANY, 445 KNOWN_ORDER, 446 ALLOWS_NULL_QUERIES, 447 NON_STANDARD_TOSTRING, 448 RESTRICTS_ELEMENTS) 449 .suppressing(getHoleMethods()) 450 .createTestSuite()); 451 452 suite.addTest( 453 NavigableSetTestSuiteBuilder.using(new ContiguousSetSubsetGenerator()) 454 .named("Range.asSet, subset") 455 .withFeatures( 456 CollectionSize.ANY, 457 KNOWN_ORDER, 458 ALLOWS_NULL_QUERIES, 459 NON_STANDARD_TOSTRING, 460 RESTRICTS_ELEMENTS) 461 .suppressing(getHoleMethods()) 462 .createTestSuite()); 463 464 suite.addTest( 465 NavigableSetTestSuiteBuilder.using(new ContiguousSetDescendingGenerator()) 466 .named("Range.asSet.descendingSet") 467 .withFeatures( 468 CollectionSize.ANY, 469 KNOWN_ORDER, 470 ALLOWS_NULL_QUERIES, 471 NON_STANDARD_TOSTRING, 472 RESTRICTS_ELEMENTS) 473 .suppressing(getHoleMethods()) 474 .createTestSuite()); 475 476 return suite; 477 } 478 } 479 } 480