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 17 package com.google.common.collect; 18 19 import static com.google.common.collect.Iterables.unmodifiableIterable; 20 import static com.google.common.collect.Sets.newEnumSet; 21 import static com.google.common.collect.Sets.newHashSet; 22 import static com.google.common.collect.Sets.newLinkedHashSet; 23 import static com.google.common.collect.Sets.powerSet; 24 import static com.google.common.collect.Sets.unmodifiableNavigableSet; 25 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; 26 import static com.google.common.truth.Truth.assertThat; 27 import static com.google.common.truth.Truth.assertWithMessage; 28 import static java.io.ObjectStreamConstants.TC_REFERENCE; 29 import static java.io.ObjectStreamConstants.baseWireHandle; 30 import static java.util.Collections.emptySet; 31 import static java.util.Collections.singleton; 32 33 import com.google.common.annotations.GwtCompatible; 34 import com.google.common.annotations.GwtIncompatible; 35 import com.google.common.base.Predicate; 36 import com.google.common.collect.testing.AnEnum; 37 import com.google.common.collect.testing.IteratorTester; 38 import com.google.common.collect.testing.MinimalIterable; 39 import com.google.common.collect.testing.NavigableSetTestSuiteBuilder; 40 import com.google.common.collect.testing.SafeTreeSet; 41 import com.google.common.collect.testing.SetTestSuiteBuilder; 42 import com.google.common.collect.testing.TestEnumSetGenerator; 43 import com.google.common.collect.testing.TestStringSetGenerator; 44 import com.google.common.collect.testing.features.CollectionFeature; 45 import com.google.common.collect.testing.features.CollectionSize; 46 import com.google.common.collect.testing.features.SetFeature; 47 import com.google.common.testing.EqualsTester; 48 import com.google.common.testing.NullPointerTester; 49 import com.google.common.testing.SerializableTester; 50 import java.io.ByteArrayInputStream; 51 import java.io.ByteArrayOutputStream; 52 import java.io.IOException; 53 import java.io.ObjectInputStream; 54 import java.io.ObjectOutputStream; 55 import java.nio.ByteBuffer; 56 import java.util.ArrayList; 57 import java.util.Arrays; 58 import java.util.Collection; 59 import java.util.Collections; 60 import java.util.Comparator; 61 import java.util.EnumSet; 62 import java.util.HashMap; 63 import java.util.HashSet; 64 import java.util.Iterator; 65 import java.util.LinkedHashMap; 66 import java.util.LinkedHashSet; 67 import java.util.List; 68 import java.util.Map; 69 import java.util.NavigableSet; 70 import java.util.NoSuchElementException; 71 import java.util.Set; 72 import java.util.SortedSet; 73 import java.util.TreeSet; 74 import java.util.concurrent.CopyOnWriteArraySet; 75 import junit.framework.Test; 76 import junit.framework.TestCase; 77 import junit.framework.TestSuite; 78 import org.checkerframework.checker.nullness.qual.Nullable; 79 80 /** 81 * Unit test for {@code Sets}. 82 * 83 * @author Kevin Bourrillion 84 * @author Jared Levy 85 */ 86 @GwtCompatible(emulated = true) 87 public class SetsTest extends TestCase { 88 89 private static final IteratorTester.KnownOrder KNOWN_ORDER = 90 IteratorTester.KnownOrder.KNOWN_ORDER; 91 92 private static final Collection<Integer> EMPTY_COLLECTION = Arrays.<Integer>asList(); 93 94 private static final Collection<Integer> SOME_COLLECTION = Arrays.asList(0, 1, 1); 95 96 private static final Iterable<Integer> SOME_ITERABLE = 97 new Iterable<Integer>() { 98 @Override 99 public Iterator<Integer> iterator() { 100 return SOME_COLLECTION.iterator(); 101 } 102 }; 103 104 private static final List<Integer> LONGER_LIST = Arrays.asList(8, 6, 7, 5, 3, 0, 9); 105 106 private static final Comparator<Integer> SOME_COMPARATOR = Collections.reverseOrder(); 107 108 @GwtIncompatible // suite suite()109 public static Test suite() { 110 TestSuite suite = new TestSuite(); 111 suite.addTestSuite(SetsTest.class); 112 113 suite.addTest( 114 SetTestSuiteBuilder.using( 115 new TestStringSetGenerator() { 116 @Override 117 protected Set<String> create(String[] elements) { 118 return Sets.newConcurrentHashSet(Arrays.asList(elements)); 119 } 120 }) 121 .named("Sets.newConcurrentHashSet") 122 .withFeatures(CollectionSize.ANY, SetFeature.GENERAL_PURPOSE) 123 .createTestSuite()); 124 125 suite.addTest( 126 SetTestSuiteBuilder.using( 127 new TestStringSetGenerator() { 128 @Override 129 protected Set<String> create(String[] elements) { 130 int size = elements.length; 131 // Remove last element, if size > 1 132 Set<String> set1 = 133 (size > 1) 134 ? Sets.newHashSet(Arrays.asList(elements).subList(0, size - 1)) 135 : Sets.newHashSet(elements); 136 // Remove first element, if size > 0 137 Set<String> set2 = 138 (size > 0) 139 ? Sets.newHashSet(Arrays.asList(elements).subList(1, size)) 140 : Sets.<String>newHashSet(); 141 return Sets.union(set1, set2); 142 } 143 }) 144 .named("Sets.union") 145 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) 146 .createTestSuite()); 147 148 suite.addTest( 149 SetTestSuiteBuilder.using( 150 new TestStringSetGenerator() { 151 @Override 152 protected Set<String> create(String[] elements) { 153 Set<String> set1 = Sets.newHashSet(elements); 154 set1.add(samples().e3()); 155 Set<String> set2 = Sets.newHashSet(elements); 156 set2.add(samples().e4()); 157 return Sets.intersection(set1, set2); 158 } 159 }) 160 .named("Sets.intersection") 161 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) 162 .createTestSuite()); 163 164 suite.addTest( 165 SetTestSuiteBuilder.using( 166 new TestStringSetGenerator() { 167 @Override 168 protected Set<String> create(String[] elements) { 169 Set<String> set1 = Sets.newHashSet(elements); 170 set1.add(samples().e3()); 171 Set<String> set2 = Sets.newHashSet(samples().e3()); 172 return Sets.difference(set1, set2); 173 } 174 }) 175 .named("Sets.difference") 176 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) 177 .createTestSuite()); 178 179 suite.addTest( 180 SetTestSuiteBuilder.using( 181 new TestEnumSetGenerator() { 182 @Override 183 protected Set<AnEnum> create(AnEnum[] elements) { 184 AnEnum[] otherElements = new AnEnum[elements.length - 1]; 185 System.arraycopy(elements, 1, otherElements, 0, otherElements.length); 186 return Sets.immutableEnumSet(elements[0], otherElements); 187 } 188 }) 189 .named("Sets.immutableEnumSet") 190 .withFeatures( 191 CollectionSize.ONE, CollectionSize.SEVERAL, CollectionFeature.ALLOWS_NULL_QUERIES) 192 .createTestSuite()); 193 194 suite.addTest( 195 NavigableSetTestSuiteBuilder.using( 196 new TestStringSetGenerator() { 197 @Override 198 protected Set<String> create(String[] elements) { 199 SafeTreeSet<String> set = new SafeTreeSet<>(Arrays.asList(elements)); 200 return Sets.unmodifiableNavigableSet(set); 201 } 202 203 @Override 204 public List<String> order(List<String> insertionOrder) { 205 return Ordering.natural().sortedCopy(insertionOrder); 206 } 207 }) 208 .named("Sets.unmodifiableNavigableSet[TreeSet]") 209 .withFeatures( 210 CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.SERIALIZABLE) 211 .createTestSuite()); 212 213 suite.addTest(testsForFilter()); 214 suite.addTest(testsForFilterNoNulls()); 215 suite.addTest(testsForFilterFiltered()); 216 217 return suite; 218 } 219 220 @GwtIncompatible // suite testsForFilter()221 private static Test testsForFilter() { 222 return SetTestSuiteBuilder.using( 223 new TestStringSetGenerator() { 224 @Override 225 public Set<String> create(String[] elements) { 226 Set<String> unfiltered = Sets.newLinkedHashSet(); 227 unfiltered.add("yyy"); 228 Collections.addAll(unfiltered, elements); 229 unfiltered.add("zzz"); 230 return Sets.filter(unfiltered, Collections2Test.NOT_YYY_ZZZ); 231 } 232 }) 233 .named("Sets.filter") 234 .withFeatures( 235 CollectionFeature.SUPPORTS_ADD, 236 CollectionFeature.SUPPORTS_REMOVE, 237 CollectionFeature.ALLOWS_NULL_VALUES, 238 CollectionFeature.KNOWN_ORDER, 239 CollectionSize.ANY) 240 .createTestSuite(); 241 } 242 243 @GwtIncompatible // suite 244 private static Test testsForFilterNoNulls() { 245 TestSuite suite = new TestSuite(); 246 suite.addTest( 247 SetTestSuiteBuilder.using( 248 new TestStringSetGenerator() { 249 @Override 250 public Set<String> create(String[] elements) { 251 Set<String> unfiltered = Sets.newLinkedHashSet(); 252 unfiltered.add("yyy"); 253 unfiltered.addAll(ImmutableList.copyOf(elements)); 254 unfiltered.add("zzz"); 255 return Sets.filter(unfiltered, Collections2Test.LENGTH_1); 256 } 257 }) 258 .named("Sets.filter, no nulls") 259 .withFeatures( 260 CollectionFeature.SUPPORTS_ADD, 261 CollectionFeature.SUPPORTS_REMOVE, 262 CollectionFeature.KNOWN_ORDER, 263 CollectionSize.ANY, 264 CollectionFeature.ALLOWS_NULL_QUERIES) 265 .createTestSuite()); 266 suite.addTest( 267 NavigableSetTestSuiteBuilder.using( 268 new TestStringSetGenerator() { 269 @Override 270 public NavigableSet<String> create(String[] elements) { 271 NavigableSet<String> unfiltered = Sets.newTreeSet(); 272 unfiltered.add("yyy"); 273 unfiltered.addAll(ImmutableList.copyOf(elements)); 274 unfiltered.add("zzz"); 275 return Sets.filter(unfiltered, Collections2Test.LENGTH_1); 276 } 277 278 @Override 279 public List<String> order(List<String> insertionOrder) { 280 return Ordering.natural().sortedCopy(insertionOrder); 281 } 282 }) 283 .named("Sets.filter[NavigableSet]") 284 .withFeatures( 285 CollectionFeature.SUPPORTS_ADD, 286 CollectionFeature.SUPPORTS_REMOVE, 287 CollectionFeature.KNOWN_ORDER, 288 CollectionSize.ANY, 289 CollectionFeature.ALLOWS_NULL_QUERIES) 290 .createTestSuite()); 291 return suite; 292 } 293 294 @GwtIncompatible // suite 295 private static Test testsForFilterFiltered() { 296 return SetTestSuiteBuilder.using( 297 new TestStringSetGenerator() { 298 @Override 299 public Set<String> create(String[] elements) { 300 Set<String> unfiltered = Sets.newLinkedHashSet(); 301 unfiltered.add("yyy"); 302 unfiltered.addAll(ImmutableList.copyOf(elements)); 303 unfiltered.add("zzz"); 304 unfiltered.add("abc"); 305 return Sets.filter( 306 Sets.filter(unfiltered, Collections2Test.LENGTH_1), 307 Collections2Test.NOT_YYY_ZZZ); 308 } 309 }) 310 .named("Sets.filter, filtered input") 311 .withFeatures( 312 CollectionFeature.SUPPORTS_ADD, 313 CollectionFeature.SUPPORTS_REMOVE, 314 CollectionFeature.KNOWN_ORDER, 315 CollectionSize.ANY, 316 CollectionFeature.ALLOWS_NULL_QUERIES) 317 .createTestSuite(); 318 } 319 320 private enum SomeEnum { 321 A, 322 B, 323 C, 324 D 325 } 326 327 @SuppressWarnings("DoNotCall") 328 public void testImmutableEnumSet() { 329 Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B); 330 331 assertThat(units).containsExactly(SomeEnum.B, SomeEnum.D).inOrder(); 332 try { 333 units.remove(SomeEnum.B); 334 fail("ImmutableEnumSet should throw an exception on remove()"); 335 } catch (UnsupportedOperationException expected) { 336 } 337 try { 338 units.add(SomeEnum.C); 339 fail("ImmutableEnumSet should throw an exception on add()"); 340 } catch (UnsupportedOperationException expected) { 341 } 342 } 343 344 @GwtIncompatible // SerializableTester 345 public void testImmutableEnumSet_serialized() { 346 Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B); 347 348 assertThat(units).containsExactly(SomeEnum.B, SomeEnum.D).inOrder(); 349 350 Set<SomeEnum> copy = SerializableTester.reserializeAndAssert(units); 351 assertTrue(copy instanceof ImmutableEnumSet); 352 } 353 354 public void testImmutableEnumSet_fromIterable() { 355 ImmutableSet<SomeEnum> none = Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of()); 356 assertThat(none).isEmpty(); 357 358 ImmutableSet<SomeEnum> one = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B)); 359 assertThat(one).contains(SomeEnum.B); 360 361 ImmutableSet<SomeEnum> two = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B)); 362 assertThat(two).containsExactly(SomeEnum.B, SomeEnum.D).inOrder(); 363 } 364 365 @GwtIncompatible // java serialization not supported in GWT. 366 public void testImmutableEnumSet_deserializationMakesDefensiveCopy() throws Exception { 367 ImmutableSet<SomeEnum> original = Sets.immutableEnumSet(SomeEnum.A, SomeEnum.B); 368 int handleOffset = 6; 369 byte[] serializedForm = serializeWithBackReference(original, handleOffset); 370 ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializedForm)); 371 372 ImmutableSet<?> deserialized = (ImmutableSet<?>) in.readObject(); 373 EnumSet<?> delegate = (EnumSet<?>) in.readObject(); 374 375 assertEquals(original, deserialized); 376 assertTrue(delegate.remove(SomeEnum.A)); 377 assertTrue(deserialized.contains(SomeEnum.A)); 378 } 379 380 @GwtIncompatible // java serialization not supported in GWT. 381 private static byte[] serializeWithBackReference(Object original, int handleOffset) 382 throws IOException { 383 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 384 ObjectOutputStream out = new ObjectOutputStream(bos); 385 386 out.writeObject(original); 387 388 byte[] handle = toByteArray(baseWireHandle + handleOffset); 389 byte[] ref = prepended(TC_REFERENCE, handle); 390 bos.write(ref); 391 392 return bos.toByteArray(); 393 } 394 395 private static byte[] prepended(byte b, byte[] array) { 396 byte[] out = new byte[array.length + 1]; 397 out[0] = b; 398 System.arraycopy(array, 0, out, 1, array.length); 399 return out; 400 } 401 402 @GwtIncompatible // java.nio.ByteBuffer 403 private static byte[] toByteArray(int h) { 404 return ByteBuffer.allocate(4).putInt(h).array(); 405 } 406 407 public void testNewEnumSet_empty() { 408 EnumSet<SomeEnum> copy = newEnumSet(Collections.<SomeEnum>emptySet(), SomeEnum.class); 409 assertEquals(EnumSet.noneOf(SomeEnum.class), copy); 410 } 411 412 public void testNewEnumSet_enumSet() { 413 EnumSet<SomeEnum> set = EnumSet.of(SomeEnum.A, SomeEnum.D); 414 assertEquals(set, newEnumSet(set, SomeEnum.class)); 415 } 416 417 public void testNewEnumSet_collection() { 418 Set<SomeEnum> set = ImmutableSet.of(SomeEnum.B, SomeEnum.C); 419 assertEquals(set, newEnumSet(set, SomeEnum.class)); 420 } 421 422 public void testNewEnumSet_iterable() { 423 Set<SomeEnum> set = ImmutableSet.of(SomeEnum.A, SomeEnum.B, SomeEnum.C); 424 assertEquals(set, newEnumSet(unmodifiableIterable(set), SomeEnum.class)); 425 } 426 427 public void testNewHashSetEmpty() { 428 HashSet<Integer> set = Sets.newHashSet(); 429 verifySetContents(set, EMPTY_COLLECTION); 430 } 431 432 public void testNewHashSetVarArgs() { 433 HashSet<Integer> set = Sets.newHashSet(0, 1, 1); 434 verifySetContents(set, Arrays.asList(0, 1)); 435 } 436 437 public void testNewHashSetFromCollection() { 438 HashSet<Integer> set = Sets.newHashSet(SOME_COLLECTION); 439 verifySetContents(set, SOME_COLLECTION); 440 } 441 442 public void testNewHashSetFromIterable() { 443 HashSet<Integer> set = Sets.newHashSet(SOME_ITERABLE); 444 verifySetContents(set, SOME_ITERABLE); 445 } 446 447 public void testNewHashSetWithExpectedSizeSmall() { 448 HashSet<Integer> set = Sets.newHashSetWithExpectedSize(0); 449 verifySetContents(set, EMPTY_COLLECTION); 450 } 451 452 public void testNewHashSetWithExpectedSizeLarge() { 453 HashSet<Integer> set = Sets.newHashSetWithExpectedSize(1000); 454 verifySetContents(set, EMPTY_COLLECTION); 455 } 456 457 public void testNewHashSetFromIterator() { 458 HashSet<Integer> set = Sets.newHashSet(SOME_COLLECTION.iterator()); 459 verifySetContents(set, SOME_COLLECTION); 460 } 461 462 public void testNewConcurrentHashSetEmpty() { 463 Set<Integer> set = Sets.newConcurrentHashSet(); 464 verifySetContents(set, EMPTY_COLLECTION); 465 } 466 467 public void testNewConcurrentHashSetFromCollection() { 468 Set<Integer> set = Sets.newConcurrentHashSet(SOME_COLLECTION); 469 verifySetContents(set, SOME_COLLECTION); 470 } 471 472 public void testNewLinkedHashSetEmpty() { 473 LinkedHashSet<Integer> set = Sets.newLinkedHashSet(); 474 verifyLinkedHashSetContents(set, EMPTY_COLLECTION); 475 } 476 477 public void testNewLinkedHashSetFromCollection() { 478 LinkedHashSet<Integer> set = Sets.newLinkedHashSet(LONGER_LIST); 479 verifyLinkedHashSetContents(set, LONGER_LIST); 480 } 481 482 public void testNewLinkedHashSetFromIterable() { 483 LinkedHashSet<Integer> set = 484 Sets.newLinkedHashSet( 485 new Iterable<Integer>() { 486 @Override 487 public Iterator<Integer> iterator() { 488 return LONGER_LIST.iterator(); 489 } 490 }); 491 verifyLinkedHashSetContents(set, LONGER_LIST); 492 } 493 494 public void testNewLinkedHashSetWithExpectedSizeSmall() { 495 LinkedHashSet<Integer> set = Sets.newLinkedHashSetWithExpectedSize(0); 496 verifySetContents(set, EMPTY_COLLECTION); 497 } 498 499 public void testNewLinkedHashSetWithExpectedSizeLarge() { 500 LinkedHashSet<Integer> set = Sets.newLinkedHashSetWithExpectedSize(1000); 501 verifySetContents(set, EMPTY_COLLECTION); 502 } 503 504 public void testNewTreeSetEmpty() { 505 TreeSet<Integer> set = Sets.newTreeSet(); 506 verifySortedSetContents(set, EMPTY_COLLECTION, null); 507 } 508 509 public void testNewTreeSetEmptyDerived() { 510 TreeSet<Derived> set = Sets.newTreeSet(); 511 assertTrue(set.isEmpty()); 512 set.add(new Derived("foo")); 513 set.add(new Derived("bar")); 514 assertThat(set).containsExactly(new Derived("bar"), new Derived("foo")).inOrder(); 515 } 516 517 public void testNewTreeSetEmptyNonGeneric() { 518 TreeSet<LegacyComparable> set = Sets.newTreeSet(); 519 assertTrue(set.isEmpty()); 520 set.add(new LegacyComparable("foo")); 521 set.add(new LegacyComparable("bar")); 522 assertThat(set) 523 .containsExactly(new LegacyComparable("bar"), new LegacyComparable("foo")) 524 .inOrder(); 525 } 526 527 public void testNewTreeSetFromCollection() { 528 TreeSet<Integer> set = Sets.newTreeSet(SOME_COLLECTION); 529 verifySortedSetContents(set, SOME_COLLECTION, null); 530 } 531 532 public void testNewTreeSetFromIterable() { 533 TreeSet<Integer> set = Sets.newTreeSet(SOME_ITERABLE); 534 verifySortedSetContents(set, SOME_ITERABLE, null); 535 } 536 537 public void testNewTreeSetFromIterableDerived() { 538 Iterable<Derived> iterable = Arrays.asList(new Derived("foo"), new Derived("bar")); 539 TreeSet<Derived> set = Sets.newTreeSet(iterable); 540 assertThat(set).containsExactly(new Derived("bar"), new Derived("foo")).inOrder(); 541 } 542 543 public void testNewTreeSetFromIterableNonGeneric() { 544 Iterable<LegacyComparable> iterable = 545 Arrays.asList(new LegacyComparable("foo"), new LegacyComparable("bar")); 546 TreeSet<LegacyComparable> set = Sets.newTreeSet(iterable); 547 assertThat(set) 548 .containsExactly(new LegacyComparable("bar"), new LegacyComparable("foo")) 549 .inOrder(); 550 } 551 552 public void testNewTreeSetEmptyWithComparator() { 553 TreeSet<Integer> set = Sets.newTreeSet(SOME_COMPARATOR); 554 verifySortedSetContents(set, EMPTY_COLLECTION, SOME_COMPARATOR); 555 } 556 557 public void testNewIdentityHashSet() { 558 Set<Integer> set = Sets.newIdentityHashSet(); 559 Integer value1 = new Integer(12357); 560 Integer value2 = new Integer(12357); 561 assertTrue(set.add(value1)); 562 assertFalse(set.contains(value2)); 563 assertTrue(set.contains(value1)); 564 assertTrue(set.add(value2)); 565 assertEquals(2, set.size()); 566 } 567 568 @GwtIncompatible // CopyOnWriteArraySet 569 public void testNewCOWASEmpty() { 570 CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet(); 571 verifySetContents(set, EMPTY_COLLECTION); 572 } 573 574 @GwtIncompatible // CopyOnWriteArraySet 575 public void testNewCOWASFromIterable() { 576 CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet(SOME_ITERABLE); 577 verifySetContents(set, SOME_COLLECTION); 578 } 579 580 @GwtIncompatible // complementOf 581 public void testComplementOfEnumSet() { 582 Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D); 583 EnumSet<SomeEnum> otherUnits = Sets.complementOf(units); 584 verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C)); 585 } 586 587 @GwtIncompatible // complementOf 588 public void testComplementOfEnumSetWithType() { 589 Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D); 590 EnumSet<SomeEnum> otherUnits = Sets.complementOf(units, SomeEnum.class); 591 verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C)); 592 } 593 594 @GwtIncompatible // complementOf 595 public void testComplementOfRegularSet() { 596 Set<SomeEnum> units = Sets.newHashSet(SomeEnum.B, SomeEnum.D); 597 EnumSet<SomeEnum> otherUnits = Sets.complementOf(units); 598 verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C)); 599 } 600 601 @GwtIncompatible // complementOf 602 public void testComplementOfRegularSetWithType() { 603 Set<SomeEnum> units = Sets.newHashSet(SomeEnum.B, SomeEnum.D); 604 EnumSet<SomeEnum> otherUnits = Sets.complementOf(units, SomeEnum.class); 605 verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C)); 606 } 607 608 @GwtIncompatible // complementOf 609 public void testComplementOfEmptySet() { 610 Set<SomeEnum> noUnits = Collections.emptySet(); 611 EnumSet<SomeEnum> allUnits = Sets.complementOf(noUnits, SomeEnum.class); 612 verifySetContents(EnumSet.allOf(SomeEnum.class), allUnits); 613 } 614 615 @GwtIncompatible // complementOf 616 public void testComplementOfFullSet() { 617 Set<SomeEnum> allUnits = Sets.newHashSet(SomeEnum.values()); 618 EnumSet<SomeEnum> noUnits = Sets.complementOf(allUnits, SomeEnum.class); 619 verifySetContents(noUnits, EnumSet.noneOf(SomeEnum.class)); 620 } 621 622 @GwtIncompatible // complementOf 623 public void testComplementOfEmptyEnumSetWithoutType() { 624 Set<SomeEnum> noUnits = EnumSet.noneOf(SomeEnum.class); 625 EnumSet<SomeEnum> allUnits = Sets.complementOf(noUnits); 626 verifySetContents(allUnits, EnumSet.allOf(SomeEnum.class)); 627 } 628 629 @GwtIncompatible // complementOf 630 public void testComplementOfEmptySetWithoutTypeDoesntWork() { 631 Set<SomeEnum> set = Collections.emptySet(); 632 try { 633 Sets.complementOf(set); 634 fail(); 635 } catch (IllegalArgumentException expected) { 636 } 637 } 638 639 @GwtIncompatible // NullPointerTester 640 @AndroidIncompatible // see ImmutableTableTest.testNullPointerInstance 641 public void testNullPointerExceptions() { 642 new NullPointerTester() 643 .setDefault(Enum.class, SomeEnum.A) 644 .setDefault(Class.class, SomeEnum.class) // for newEnumSet 645 .testAllPublicStaticMethods(Sets.class); 646 } 647 648 public void testNewSetFromMap() { 649 Set<Integer> set = Sets.newSetFromMap(new HashMap<Integer, Boolean>()); 650 set.addAll(SOME_COLLECTION); 651 verifySetContents(set, SOME_COLLECTION); 652 } 653 654 @GwtIncompatible // SerializableTester 655 public void testNewSetFromMapSerialization() { 656 Set<Integer> set = Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>()); 657 set.addAll(SOME_COLLECTION); 658 Set<Integer> copy = SerializableTester.reserializeAndAssert(set); 659 assertThat(copy).containsExactly(0, 1).inOrder(); 660 } 661 662 public void testNewSetFromMapIllegal() { 663 Map<Integer, Boolean> map = new LinkedHashMap<>(); 664 map.put(2, true); 665 try { 666 Sets.newSetFromMap(map); 667 fail(); 668 } catch (IllegalArgumentException expected) { 669 } 670 } 671 672 // TODO: the overwhelming number of suppressions below suggests that maybe 673 // it's not worth having a varargs form of this method at all... 674 675 /** The 0-ary cartesian product is a single empty list. */ 676 @SuppressWarnings("unchecked") // varargs! 677 public void testCartesianProduct_zeroary() { 678 assertThat(Sets.cartesianProduct()).containsExactly(list()); 679 } 680 681 /** A unary cartesian product is one list of size 1 for each element in the input set. */ 682 @SuppressWarnings("unchecked") // varargs! 683 public void testCartesianProduct_unary() { 684 assertThat(Sets.cartesianProduct(set(1, 2))).containsExactly(list(1), list(2)); 685 } 686 687 @SuppressWarnings("unchecked") // varargs! 688 public void testCartesianProduct_binary0x0() { 689 Set<Integer> mt = emptySet(); 690 assertEmpty(Sets.cartesianProduct(mt, mt)); 691 } 692 693 @SuppressWarnings("unchecked") // varargs! 694 public void testCartesianProduct_binary0x1() { 695 Set<Integer> mt = emptySet(); 696 assertEmpty(Sets.cartesianProduct(mt, set(1))); 697 } 698 699 @SuppressWarnings("unchecked") // varargs! 700 public void testCartesianProduct_binary1x0() { 701 Set<Integer> mt = emptySet(); 702 assertEmpty(Sets.cartesianProduct(set(1), mt)); 703 } 704 705 private static void assertEmpty(Set<? extends List<?>> set) { 706 assertTrue(set.isEmpty()); 707 assertEquals(0, set.size()); 708 assertFalse(set.iterator().hasNext()); 709 } 710 711 @SuppressWarnings("unchecked") // varargs! 712 public void testCartesianProduct_binary1x1() { 713 assertThat(Sets.cartesianProduct(set(1), set(2))).contains(list(1, 2)); 714 } 715 716 @SuppressWarnings("unchecked") // varargs! 717 public void testCartesianProduct_binary1x2() { 718 assertThat(Sets.cartesianProduct(set(1), set(2, 3))) 719 .containsExactly(list(1, 2), list(1, 3)) 720 .inOrder(); 721 } 722 723 @SuppressWarnings("unchecked") // varargs! 724 public void testCartesianProduct_binary2x2() { 725 assertThat(Sets.cartesianProduct(set(1, 2), set(3, 4))) 726 .containsExactly(list(1, 3), list(1, 4), list(2, 3), list(2, 4)) 727 .inOrder(); 728 } 729 730 @SuppressWarnings("unchecked") // varargs! 731 public void testCartesianProduct_2x2x2() { 732 assertThat(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))) 733 .containsExactly( 734 list(0, 0, 0), 735 list(0, 0, 1), 736 list(0, 1, 0), 737 list(0, 1, 1), 738 list(1, 0, 0), 739 list(1, 0, 1), 740 list(1, 1, 0), 741 list(1, 1, 1)) 742 .inOrder(); 743 } 744 745 @SuppressWarnings("unchecked") // varargs! 746 public void testCartesianProduct_contains() { 747 Set<List<Integer>> actual = Sets.cartesianProduct(set(1, 2), set(3, 4)); 748 assertTrue(actual.contains(list(1, 3))); 749 assertTrue(actual.contains(list(1, 4))); 750 assertTrue(actual.contains(list(2, 3))); 751 assertTrue(actual.contains(list(2, 4))); 752 assertFalse(actual.contains(list(3, 1))); 753 } 754 755 public void testCartesianProduct_equals() { 756 Set<List<Integer>> cartesian = Sets.cartesianProduct(set(1, 2), set(3, 4)); 757 ImmutableSet<List<Integer>> equivalent = 758 ImmutableSet.of(ImmutableList.of(1, 3), ImmutableList.of(1, 4), list(2, 3), list(2, 4)); 759 ImmutableSet<List<Integer>> different1 = 760 ImmutableSet.of(ImmutableList.of(0, 3), ImmutableList.of(1, 4), list(2, 3), list(2, 4)); 761 ImmutableSet<List<Integer>> different2 = 762 ImmutableSet.of(ImmutableList.of(1, 3), ImmutableList.of(1, 4), list(2, 3)); 763 new EqualsTester() 764 .addEqualityGroup(cartesian, equivalent) 765 .addEqualityGroup(different1) 766 .addEqualityGroup(different2) 767 .testEquals(); 768 } 769 770 @SuppressWarnings("unchecked") // varargs! 771 public void testCartesianProduct_unrelatedTypes() { 772 Set<Integer> x = set(1, 2); 773 Set<String> y = set("3", "4"); 774 775 List<Object> exp1 = list((Object) 1, "3"); 776 List<Object> exp2 = list((Object) 1, "4"); 777 List<Object> exp3 = list((Object) 2, "3"); 778 List<Object> exp4 = list((Object) 2, "4"); 779 780 assertThat(Sets.<Object>cartesianProduct(x, y)) 781 .containsExactly(exp1, exp2, exp3, exp4) 782 .inOrder(); 783 } 784 785 @SuppressWarnings("unchecked") // varargs! 786 public void testCartesianProductTooBig() { 787 Set<Integer> set = ContiguousSet.create(Range.closed(0, 10000), DiscreteDomain.integers()); 788 try { 789 Sets.cartesianProduct(set, set, set, set, set); 790 fail("Expected IAE"); 791 } catch (IllegalArgumentException expected) { 792 } 793 } 794 795 @SuppressWarnings("unchecked") // varargs! 796 public void testCartesianProduct_hashCode() { 797 // Run through the same cartesian products we tested above 798 799 Set<List<Integer>> degenerate = Sets.cartesianProduct(); 800 checkHashCode(degenerate); 801 802 checkHashCode(Sets.cartesianProduct(set(1, 2))); 803 804 int num = Integer.MAX_VALUE / 3 * 2; // tickle overflow-related problems 805 checkHashCode(Sets.cartesianProduct(set(1, 2, num))); 806 807 Set<Integer> mt = emptySet(); 808 checkHashCode(Sets.cartesianProduct(mt, mt)); 809 checkHashCode(Sets.cartesianProduct(mt, set(num))); 810 checkHashCode(Sets.cartesianProduct(set(num), mt)); 811 checkHashCode(Sets.cartesianProduct(set(num), set(1))); 812 checkHashCode(Sets.cartesianProduct(set(1), set(2, num))); 813 checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1))); 814 checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1), set(3, num + 1))); 815 816 // a bigger one 817 checkHashCode( 818 Sets.cartesianProduct(set(1, num, num + 1), set(2), set(3, num + 2), set(4, 5, 6, 7, 8))); 819 } 820 821 public void testPowerSetEmpty() { 822 ImmutableSet<Integer> elements = ImmutableSet.of(); 823 Set<Set<Integer>> powerSet = powerSet(elements); 824 assertEquals(1, powerSet.size()); 825 assertEquals(ImmutableSet.of(ImmutableSet.of()), powerSet); 826 assertEquals(0, powerSet.hashCode()); 827 } 828 829 public void testPowerSetContents() { 830 ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3); 831 Set<Set<Integer>> powerSet = powerSet(elements); 832 assertEquals(8, powerSet.size()); 833 assertEquals(4 * 1 + 4 * 2 + 4 * 3, powerSet.hashCode()); 834 835 Set<Set<Integer>> expected = newHashSet(); 836 expected.add(ImmutableSet.<Integer>of()); 837 expected.add(ImmutableSet.of(1)); 838 expected.add(ImmutableSet.of(2)); 839 expected.add(ImmutableSet.of(3)); 840 expected.add(ImmutableSet.of(1, 2)); 841 expected.add(ImmutableSet.of(1, 3)); 842 expected.add(ImmutableSet.of(2, 3)); 843 expected.add(ImmutableSet.of(1, 2, 3)); 844 845 Set<Set<Integer>> almostPowerSet = newHashSet(expected); 846 almostPowerSet.remove(ImmutableSet.of(1, 2, 3)); 847 almostPowerSet.add(ImmutableSet.of(1, 2, 4)); 848 849 new EqualsTester() 850 .addEqualityGroup(expected, powerSet) 851 .addEqualityGroup(ImmutableSet.of(1, 2, 3)) 852 .addEqualityGroup(almostPowerSet) 853 .testEquals(); 854 855 for (Set<Integer> subset : expected) { 856 assertTrue(powerSet.contains(subset)); 857 } 858 assertFalse(powerSet.contains(ImmutableSet.of(1, 2, 4))); 859 assertFalse(powerSet.contains(singleton(null))); 860 assertFalse(powerSet.contains(null)); 861 assertFalse(powerSet.contains((Object) "notASet")); 862 } 863 864 public void testPowerSetIteration_manual() { 865 ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3); 866 Set<Set<Integer>> powerSet = powerSet(elements); 867 // The API doesn't promise this iteration order, but it's convenient here. 868 Iterator<Set<Integer>> i = powerSet.iterator(); 869 assertEquals(ImmutableSet.of(), i.next()); 870 assertEquals(ImmutableSet.of(1), i.next()); 871 assertEquals(ImmutableSet.of(2), i.next()); 872 assertEquals(ImmutableSet.of(2, 1), i.next()); 873 assertEquals(ImmutableSet.of(3), i.next()); 874 assertEquals(ImmutableSet.of(3, 1), i.next()); 875 assertEquals(ImmutableSet.of(3, 2), i.next()); 876 assertEquals(ImmutableSet.of(3, 2, 1), i.next()); 877 assertFalse(i.hasNext()); 878 try { 879 i.next(); 880 fail(); 881 } catch (NoSuchElementException expected) { 882 } 883 } 884 885 @GwtIncompatible // too slow for GWT 886 public void testPowerSetIteration_iteratorTester() { 887 ImmutableSet<Integer> elements = ImmutableSet.of(1, 2); 888 889 Set<Set<Integer>> expected = newLinkedHashSet(); 890 expected.add(ImmutableSet.<Integer>of()); 891 expected.add(ImmutableSet.of(1)); 892 expected.add(ImmutableSet.of(2)); 893 expected.add(ImmutableSet.of(1, 2)); 894 895 final Set<Set<Integer>> powerSet = powerSet(elements); 896 new IteratorTester<Set<Integer>>(6, UNMODIFIABLE, expected, KNOWN_ORDER) { 897 @Override 898 protected Iterator<Set<Integer>> newTargetIterator() { 899 return powerSet.iterator(); 900 } 901 }.test(); 902 } 903 904 public void testPowerSetIteration_iteratorTester_fast() { 905 ImmutableSet<Integer> elements = ImmutableSet.of(1, 2); 906 907 Set<Set<Integer>> expected = newLinkedHashSet(); 908 expected.add(ImmutableSet.<Integer>of()); 909 expected.add(ImmutableSet.of(1)); 910 expected.add(ImmutableSet.of(2)); 911 expected.add(ImmutableSet.of(1, 2)); 912 913 final Set<Set<Integer>> powerSet = powerSet(elements); 914 new IteratorTester<Set<Integer>>(4, UNMODIFIABLE, expected, KNOWN_ORDER) { 915 @Override 916 protected Iterator<Set<Integer>> newTargetIterator() { 917 return powerSet.iterator(); 918 } 919 }.test(); 920 } 921 922 public void testPowerSetSize() { 923 assertPowerSetSize(1); 924 assertPowerSetSize(2, 'a'); 925 assertPowerSetSize(4, 'a', 'b'); 926 assertPowerSetSize(8, 'a', 'b', 'c'); 927 assertPowerSetSize(16, 'a', 'b', 'd', 'e'); 928 assertPowerSetSize( 929 1 << 30, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 930 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4'); 931 } 932 933 public void testPowerSetCreationErrors() { 934 try { 935 Set<Set<Character>> unused = 936 powerSet( 937 newHashSet( 938 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 939 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5')); 940 fail(); 941 } catch (IllegalArgumentException expected) { 942 } 943 944 try { 945 Set<Set<Integer>> unused = powerSet(ContiguousSet.closed(0, Integer.MAX_VALUE / 2)); 946 fail(); 947 } catch (IllegalArgumentException expected) { 948 } 949 950 try { 951 powerSet(singleton(null)); 952 fail(); 953 } catch (NullPointerException expected) { 954 } 955 } 956 957 public void testPowerSetEqualsAndHashCode_verifyAgainstHashSet() { 958 ImmutableList<Integer> allElements = 959 ImmutableList.of( 960 4233352, 3284593, 3794208, 3849533, 4013967, 2902658, 1886275, 2131109, 985872, 961 1843868); 962 for (int i = 0; i < allElements.size(); i++) { 963 Set<Integer> elements = newHashSet(allElements.subList(0, i)); 964 Set<Set<Integer>> powerSet1 = powerSet(elements); 965 Set<Set<Integer>> powerSet2 = powerSet(elements); 966 new EqualsTester() 967 .addEqualityGroup(powerSet1, powerSet2, toHashSets(powerSet1)) 968 .addEqualityGroup(ImmutableSet.of()) 969 .addEqualityGroup(ImmutableSet.of(9999999)) 970 .addEqualityGroup("notASet") 971 .testEquals(); 972 assertEquals(toHashSets(powerSet1).hashCode(), powerSet1.hashCode()); 973 } 974 } 975 976 public void testPowerSetEquals_independentOfOrder() { 977 ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3, 4); 978 Set<Set<Integer>> forward = powerSet(elements); 979 Set<Set<Integer>> reverse = powerSet(ImmutableSet.copyOf(elements.asList().reverse())); 980 new EqualsTester().addEqualityGroup(forward, reverse).testEquals(); 981 } 982 983 /** 984 * Test that a hash code miscomputed by "input.hashCode() * tooFarValue / 2" is correct under our 985 * {@code hashCode} implementation. 986 */ 987 public void testPowerSetHashCode_inputHashCodeTimesTooFarValueIsZero() { 988 Set<Object> sumToEighthMaxIntElements = 989 newHashSet(objectWithHashCode(1 << 29), objectWithHashCode(0)); 990 assertPowerSetHashCode(1 << 30, sumToEighthMaxIntElements); 991 992 Set<Object> sumToQuarterMaxIntElements = 993 newHashSet(objectWithHashCode(1 << 30), objectWithHashCode(0)); 994 assertPowerSetHashCode(1 << 31, sumToQuarterMaxIntElements); 995 } 996 997 public void testPowerSetShowOff() { 998 Set<Object> zero = ImmutableSet.of(); 999 Set<Set<Object>> one = powerSet(zero); 1000 Set<Set<Set<Object>>> two = powerSet(one); 1001 Set<Set<Set<Set<Object>>>> four = powerSet(two); 1002 Set<Set<Set<Set<Set<Object>>>>> sixteen = powerSet(four); 1003 Set<Set<Set<Set<Set<Set<Object>>>>>> sixtyFiveThousandish = powerSet(sixteen); 1004 assertEquals(1 << 16, sixtyFiveThousandish.size()); 1005 1006 assertTrue(powerSet(makeSetOfZeroToTwentyNine()).contains(makeSetOfZeroToTwentyNine())); 1007 assertFalse(powerSet(makeSetOfZeroToTwentyNine()).contains(ImmutableSet.of(30))); 1008 } 1009 1010 private static Set<Integer> makeSetOfZeroToTwentyNine() { 1011 // TODO: use Range once it's publicly available 1012 Set<Integer> zeroToTwentyNine = newHashSet(); 1013 for (int i = 0; i < 30; i++) { 1014 zeroToTwentyNine.add(i); 1015 } 1016 return zeroToTwentyNine; 1017 } 1018 1019 private static <E> Set<Set<E>> toHashSets(Set<Set<E>> powerSet) { 1020 Set<Set<E>> result = newHashSet(); 1021 for (Set<E> subset : powerSet) { 1022 result.add(new HashSet<E>(subset)); 1023 } 1024 return result; 1025 } 1026 1027 private static Object objectWithHashCode(final int hashCode) { 1028 return new Object() { 1029 @Override 1030 public int hashCode() { 1031 return hashCode; 1032 } 1033 }; 1034 } 1035 1036 private static void assertPowerSetHashCode(int expected, Set<?> elements) { 1037 assertEquals(expected, powerSet(elements).hashCode()); 1038 } 1039 1040 private static void assertPowerSetSize(int i, Object... elements) { 1041 assertEquals(i, powerSet(newHashSet(elements)).size()); 1042 } 1043 1044 private static void checkHashCode(Set<?> set) { 1045 assertEquals(Sets.newHashSet(set).hashCode(), set.hashCode()); 1046 } 1047 1048 public void testCombinations() { 1049 ImmutableList<Set<Integer>> sampleSets = 1050 ImmutableList.<Set<Integer>>of( 1051 ImmutableSet.<Integer>of(), 1052 ImmutableSet.of(1, 2), 1053 ImmutableSet.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); 1054 for (Set<Integer> sampleSet : sampleSets) { 1055 for (int k = 0; k <= sampleSet.size(); k++) { 1056 final int size = k; 1057 Set<Set<Integer>> expected = 1058 Sets.filter( 1059 Sets.powerSet(sampleSet), 1060 new Predicate<Set<Integer>>() { 1061 1062 @Override 1063 public boolean apply(Set<Integer> input) { 1064 return input.size() == size; 1065 } 1066 }); 1067 assertWithMessage("Sets.combinations(%s, %s)", sampleSet, k) 1068 .that(Sets.combinations(sampleSet, k)) 1069 .containsExactlyElementsIn(expected) 1070 .inOrder(); 1071 } 1072 } 1073 } 1074 1075 private static <E> Set<E> set(E... elements) { 1076 return ImmutableSet.copyOf(elements); 1077 } 1078 1079 private static <E> List<E> list(E... elements) { 1080 return ImmutableList.copyOf(elements); 1081 } 1082 1083 /** 1084 * Utility method to verify that the given LinkedHashSet is equal to and hashes identically to a 1085 * set constructed with the elements in the given collection. Also verifies that the ordering in 1086 * the set is the same as the ordering of the given contents. 1087 */ 1088 private static <E> void verifyLinkedHashSetContents( 1089 LinkedHashSet<E> set, Collection<E> contents) { 1090 assertEquals( 1091 "LinkedHashSet should have preserved order for iteration", 1092 new ArrayList<E>(set), 1093 new ArrayList<E>(contents)); 1094 verifySetContents(set, contents); 1095 } 1096 1097 /** 1098 * Utility method to verify that the given SortedSet is equal to and hashes identically to a set 1099 * constructed with the elements in the given iterable. Also verifies that the comparator is the 1100 * same as the given comparator. 1101 */ 1102 private static <E> void verifySortedSetContents( 1103 SortedSet<E> set, Iterable<E> iterable, @Nullable Comparator<E> comparator) { 1104 assertSame(comparator, set.comparator()); 1105 verifySetContents(set, iterable); 1106 } 1107 1108 /** 1109 * Utility method that verifies that the given set is equal to and hashes identically to a set 1110 * constructed with the elements in the given iterable. 1111 */ 1112 private static <E> void verifySetContents(Set<E> set, Iterable<E> contents) { 1113 Set<E> expected = null; 1114 if (contents instanceof Set) { 1115 expected = (Set<E>) contents; 1116 } else { 1117 expected = new HashSet<E>(); 1118 for (E element : contents) { 1119 expected.add(element); 1120 } 1121 } 1122 assertEquals(expected, set); 1123 } 1124 1125 @GwtIncompatible // NavigableSet 1126 public void testUnmodifiableNavigableSet() { 1127 TreeSet<Integer> mod = Sets.newTreeSet(); 1128 mod.add(1); 1129 mod.add(2); 1130 mod.add(3); 1131 1132 NavigableSet<Integer> unmod = unmodifiableNavigableSet(mod); 1133 1134 /* Unmodifiable is a view. */ 1135 mod.add(4); 1136 assertTrue(unmod.contains(4)); 1137 assertTrue(unmod.descendingSet().contains(4)); 1138 1139 ensureNotDirectlyModifiable(unmod); 1140 ensureNotDirectlyModifiable(unmod.descendingSet()); 1141 ensureNotDirectlyModifiable(unmod.headSet(2)); 1142 ensureNotDirectlyModifiable(unmod.headSet(2, true)); 1143 ensureNotDirectlyModifiable(unmod.tailSet(2)); 1144 ensureNotDirectlyModifiable(unmod.tailSet(2, true)); 1145 ensureNotDirectlyModifiable(unmod.subSet(1, 3)); 1146 ensureNotDirectlyModifiable(unmod.subSet(1, true, 3, true)); 1147 1148 /* UnsupportedOperationException on indirect modifications. */ 1149 NavigableSet<Integer> reverse = unmod.descendingSet(); 1150 try { 1151 reverse.add(4); 1152 fail("UnsupportedOperationException expected"); 1153 } catch (UnsupportedOperationException expected) { 1154 } 1155 try { 1156 reverse.addAll(Collections.singleton(4)); 1157 fail("UnsupportedOperationException expected"); 1158 } catch (UnsupportedOperationException expected) { 1159 } 1160 try { 1161 reverse.remove(4); 1162 fail("UnsupportedOperationException expected"); 1163 } catch (UnsupportedOperationException expected) { 1164 } 1165 } 1166 1167 void ensureNotDirectlyModifiable(SortedSet<Integer> unmod) { 1168 try { 1169 unmod.add(4); 1170 fail("UnsupportedOperationException expected"); 1171 } catch (UnsupportedOperationException expected) { 1172 } 1173 try { 1174 unmod.remove(4); 1175 fail("UnsupportedOperationException expected"); 1176 } catch (UnsupportedOperationException expected) { 1177 } 1178 try { 1179 unmod.addAll(Collections.singleton(4)); 1180 fail("UnsupportedOperationException expected"); 1181 } catch (UnsupportedOperationException expected) { 1182 } 1183 try { 1184 Iterator<Integer> iterator = unmod.iterator(); 1185 iterator.next(); 1186 iterator.remove(); 1187 fail("UnsupportedOperationException expected"); 1188 } catch (UnsupportedOperationException expected) { 1189 } 1190 } 1191 1192 @GwtIncompatible // NavigableSet 1193 void ensureNotDirectlyModifiable(NavigableSet<Integer> unmod) { 1194 try { 1195 unmod.add(4); 1196 fail("UnsupportedOperationException expected"); 1197 } catch (UnsupportedOperationException expected) { 1198 } 1199 try { 1200 unmod.remove(4); 1201 fail("UnsupportedOperationException expected"); 1202 } catch (UnsupportedOperationException expected) { 1203 } 1204 try { 1205 unmod.addAll(Collections.singleton(4)); 1206 fail("UnsupportedOperationException expected"); 1207 } catch (UnsupportedOperationException expected) { 1208 } 1209 try { 1210 unmod.pollFirst(); 1211 fail("UnsupportedOperationException expected"); 1212 } catch (UnsupportedOperationException expected) { 1213 } 1214 try { 1215 unmod.pollLast(); 1216 fail("UnsupportedOperationException expected"); 1217 } catch (UnsupportedOperationException expected) { 1218 } 1219 try { 1220 Iterator<Integer> iterator = unmod.iterator(); 1221 iterator.next(); 1222 iterator.remove(); 1223 fail("UnsupportedOperationException expected"); 1224 } catch (UnsupportedOperationException expected) { 1225 } 1226 try { 1227 Iterator<Integer> iterator = unmod.descendingIterator(); 1228 iterator.next(); 1229 iterator.remove(); 1230 fail("UnsupportedOperationException expected"); 1231 } catch (UnsupportedOperationException expected) { 1232 } 1233 } 1234 1235 @GwtIncompatible // NavigableSet 1236 public void testSubSet_boundedRange() { 1237 ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10); 1238 ImmutableSortedSet<Integer> empty = ImmutableSortedSet.of(); 1239 1240 assertEquals(set, Sets.subSet(set, Range.closed(0, 12))); 1241 assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.closed(0, 4))); 1242 assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.closed(2, 6))); 1243 assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.closed(3, 7))); 1244 assertEquals(empty, Sets.subSet(set, Range.closed(20, 30))); 1245 1246 assertEquals(set, Sets.subSet(set, Range.open(0, 12))); 1247 assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.open(0, 4))); 1248 assertEquals(ImmutableSortedSet.of(4), Sets.subSet(set, Range.open(2, 6))); 1249 assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.open(3, 7))); 1250 assertEquals(empty, Sets.subSet(set, Range.open(20, 30))); 1251 1252 assertEquals(set, Sets.subSet(set, Range.openClosed(0, 12))); 1253 assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.openClosed(0, 4))); 1254 assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.openClosed(2, 6))); 1255 assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.openClosed(3, 7))); 1256 assertEquals(empty, Sets.subSet(set, Range.openClosed(20, 30))); 1257 1258 assertEquals(set, Sets.subSet(set, Range.closedOpen(0, 12))); 1259 assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.closedOpen(0, 4))); 1260 assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.closedOpen(2, 6))); 1261 assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.closedOpen(3, 7))); 1262 assertEquals(empty, Sets.subSet(set, Range.closedOpen(20, 30))); 1263 } 1264 1265 @GwtIncompatible // NavigableSet 1266 public void testSubSet_halfBoundedRange() { 1267 ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10); 1268 ImmutableSortedSet<Integer> empty = ImmutableSortedSet.of(); 1269 1270 assertEquals(set, Sets.subSet(set, Range.atLeast(0))); 1271 assertEquals(ImmutableSortedSet.of(4, 6, 8, 10), Sets.subSet(set, Range.atLeast(4))); 1272 assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.atLeast(7))); 1273 assertEquals(empty, Sets.subSet(set, Range.atLeast(20))); 1274 1275 assertEquals(set, Sets.subSet(set, Range.greaterThan(0))); 1276 assertEquals(ImmutableSortedSet.of(6, 8, 10), Sets.subSet(set, Range.greaterThan(4))); 1277 assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.greaterThan(7))); 1278 assertEquals(empty, Sets.subSet(set, Range.greaterThan(20))); 1279 1280 assertEquals(empty, Sets.subSet(set, Range.lessThan(0))); 1281 assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.lessThan(4))); 1282 assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.lessThan(7))); 1283 assertEquals(set, Sets.subSet(set, Range.lessThan(20))); 1284 1285 assertEquals(empty, Sets.subSet(set, Range.atMost(0))); 1286 assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.atMost(4))); 1287 assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.atMost(7))); 1288 assertEquals(set, Sets.subSet(set, Range.atMost(20))); 1289 } 1290 1291 @GwtIncompatible // NavigableSet 1292 public void testSubSet_unboundedRange() { 1293 ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10); 1294 1295 assertEquals(set, Sets.subSet(set, Range.<Integer>all())); 1296 } 1297 1298 @GwtIncompatible // NavigableSet 1299 public void testSubSet_unnaturalOrdering() { 1300 ImmutableSortedSet<Integer> set = 1301 ImmutableSortedSet.<Integer>reverseOrder().add(2, 4, 6, 8, 10).build(); 1302 1303 try { 1304 Sets.subSet(set, Range.closed(4, 8)); 1305 fail("IllegalArgumentException expected"); 1306 } catch (IllegalArgumentException expected) { 1307 } 1308 1309 // These results are all incorrect, but there's no way (short of iterating over the result) 1310 // to verify that with an arbitrary ordering or comparator. 1311 assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.atLeast(4))); 1312 assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.atMost(8))); 1313 assertEquals(ImmutableSortedSet.of(2, 4, 6, 8, 10), Sets.subSet(set, Range.<Integer>all())); 1314 } 1315 } 1316