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