• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.testing.IteratorFeature.UNMODIFIABLE;
20 import static com.google.common.truth.Truth.assertThat;
21 import static java.util.Arrays.asList;
22 
23 import com.google.common.annotations.GwtCompatible;
24 import com.google.common.annotations.GwtIncompatible;
25 import com.google.common.collect.testing.Helpers;
26 import com.google.common.collect.testing.IteratorTester;
27 import com.google.common.collect.testing.MinimalCollection;
28 import com.google.common.collect.testing.MinimalIterable;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.EnumSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Set;
35 import junit.framework.TestCase;
36 
37 /**
38  * Base class for {@link ImmutableSet} and {@link ImmutableSortedSet} tests.
39  *
40  * @author Kevin Bourrillion
41  * @author Jared Levy
42  */
43 @GwtCompatible(emulated = true)
44 public abstract class AbstractImmutableSetTest extends TestCase {
45 
of()46   protected abstract <E extends Comparable<? super E>> Set<E> of();
47 
of(E e)48   protected abstract <E extends Comparable<? super E>> Set<E> of(E e);
49 
of(E e1, E e2)50   protected abstract <E extends Comparable<? super E>> Set<E> of(E e1, E e2);
51 
of(E e1, E e2, E e3)52   protected abstract <E extends Comparable<? super E>> Set<E> of(E e1, E e2, E e3);
53 
of(E e1, E e2, E e3, E e4)54   protected abstract <E extends Comparable<? super E>> Set<E> of(E e1, E e2, E e3, E e4);
55 
of(E e1, E e2, E e3, E e4, E e5)56   protected abstract <E extends Comparable<? super E>> Set<E> of(E e1, E e2, E e3, E e4, E e5);
57 
58   @SuppressWarnings("unchecked")
of( E e1, E e2, E e3, E e4, E e5, E e6, E... rest)59   protected abstract <E extends Comparable<? super E>> Set<E> of(
60       E e1, E e2, E e3, E e4, E e5, E e6, E... rest);
61 
copyOf(E[] elements)62   protected abstract <E extends Comparable<? super E>> Set<E> copyOf(E[] elements);
63 
copyOf( Collection<? extends E> elements)64   protected abstract <E extends Comparable<? super E>> Set<E> copyOf(
65       Collection<? extends E> elements);
66 
copyOf( Iterable<? extends E> elements)67   protected abstract <E extends Comparable<? super E>> Set<E> copyOf(
68       Iterable<? extends E> elements);
69 
copyOf( Iterator<? extends E> elements)70   protected abstract <E extends Comparable<? super E>> Set<E> copyOf(
71       Iterator<? extends E> elements);
72 
testCreation_noArgs()73   public void testCreation_noArgs() {
74     Set<String> set = of();
75     assertEquals(Collections.<String>emptySet(), set);
76     assertSame(of(), set);
77   }
78 
testCreation_oneElement()79   public void testCreation_oneElement() {
80     Set<String> set = of("a");
81     assertEquals(Collections.singleton("a"), set);
82   }
83 
testCreation_twoElements()84   public void testCreation_twoElements() {
85     Set<String> set = of("a", "b");
86     assertEquals(Sets.newHashSet("a", "b"), set);
87   }
88 
testCreation_threeElements()89   public void testCreation_threeElements() {
90     Set<String> set = of("a", "b", "c");
91     assertEquals(Sets.newHashSet("a", "b", "c"), set);
92   }
93 
testCreation_fourElements()94   public void testCreation_fourElements() {
95     Set<String> set = of("a", "b", "c", "d");
96     assertEquals(Sets.newHashSet("a", "b", "c", "d"), set);
97   }
98 
testCreation_fiveElements()99   public void testCreation_fiveElements() {
100     Set<String> set = of("a", "b", "c", "d", "e");
101     assertEquals(Sets.newHashSet("a", "b", "c", "d", "e"), set);
102   }
103 
testCreation_sixElements()104   public void testCreation_sixElements() {
105     Set<String> set = of("a", "b", "c", "d", "e", "f");
106     assertEquals(Sets.newHashSet("a", "b", "c", "d", "e", "f"), set);
107   }
108 
testCreation_sevenElements()109   public void testCreation_sevenElements() {
110     Set<String> set = of("a", "b", "c", "d", "e", "f", "g");
111     assertEquals(Sets.newHashSet("a", "b", "c", "d", "e", "f", "g"), set);
112   }
113 
testCreation_eightElements()114   public void testCreation_eightElements() {
115     Set<String> set = of("a", "b", "c", "d", "e", "f", "g", "h");
116     assertEquals(Sets.newHashSet("a", "b", "c", "d", "e", "f", "g", "h"), set);
117   }
118 
testCopyOf_emptyArray()119   public void testCopyOf_emptyArray() {
120     String[] array = new String[0];
121     Set<String> set = copyOf(array);
122     assertEquals(Collections.<String>emptySet(), set);
123     assertSame(of(), set);
124   }
125 
testCopyOf_arrayOfOneElement()126   public void testCopyOf_arrayOfOneElement() {
127     String[] array = new String[] {"a"};
128     Set<String> set = copyOf(array);
129     assertEquals(Collections.singleton("a"), set);
130   }
131 
testCopyOf_nullArray()132   public void testCopyOf_nullArray() {
133     try {
134       copyOf((String[]) null);
135       fail();
136     } catch (NullPointerException expected) {
137     }
138   }
139 
testCopyOf_arrayContainingOnlyNull()140   public void testCopyOf_arrayContainingOnlyNull() {
141     String[] array = new String[] {null};
142     try {
143       copyOf(array);
144       fail();
145     } catch (NullPointerException expected) {
146     }
147   }
148 
testCopyOf_collection_empty()149   public void testCopyOf_collection_empty() {
150     // "<String>" is required to work around a javac 1.5 bug.
151     Collection<String> c = MinimalCollection.<String>of();
152     Set<String> set = copyOf(c);
153     assertEquals(Collections.<String>emptySet(), set);
154     assertSame(of(), set);
155   }
156 
testCopyOf_collection_oneElement()157   public void testCopyOf_collection_oneElement() {
158     Collection<String> c = MinimalCollection.of("a");
159     Set<String> set = copyOf(c);
160     assertEquals(Collections.singleton("a"), set);
161   }
162 
testCopyOf_collection_oneElementRepeated()163   public void testCopyOf_collection_oneElementRepeated() {
164     Collection<String> c = MinimalCollection.of("a", "a", "a");
165     Set<String> set = copyOf(c);
166     assertEquals(Collections.singleton("a"), set);
167   }
168 
testCopyOf_collection_general()169   public void testCopyOf_collection_general() {
170     Collection<String> c = MinimalCollection.of("a", "b", "a");
171     Set<String> set = copyOf(c);
172     assertEquals(2, set.size());
173     assertTrue(set.contains("a"));
174     assertTrue(set.contains("b"));
175   }
176 
testCopyOf_collectionContainingNull()177   public void testCopyOf_collectionContainingNull() {
178     Collection<String> c = MinimalCollection.of("a", null, "b");
179     try {
180       copyOf(c);
181       fail();
182     } catch (NullPointerException expected) {
183     }
184   }
185 
186   enum TestEnum {
187     A,
188     B,
189     C,
190     D
191   }
192 
testCopyOf_collection_enumSet()193   public void testCopyOf_collection_enumSet() {
194     Collection<TestEnum> c = EnumSet.of(TestEnum.A, TestEnum.B, TestEnum.D);
195     Set<TestEnum> set = copyOf(c);
196     assertEquals(3, set.size());
197     assertEquals(c, set);
198   }
199 
testCopyOf_iterator_empty()200   public void testCopyOf_iterator_empty() {
201     Iterator<String> iterator = Iterators.emptyIterator();
202     Set<String> set = copyOf(iterator);
203     assertEquals(Collections.<String>emptySet(), set);
204     assertSame(of(), set);
205   }
206 
testCopyOf_iterator_oneElement()207   public void testCopyOf_iterator_oneElement() {
208     Iterator<String> iterator = Iterators.singletonIterator("a");
209     Set<String> set = copyOf(iterator);
210     assertEquals(Collections.singleton("a"), set);
211   }
212 
testCopyOf_iterator_oneElementRepeated()213   public void testCopyOf_iterator_oneElementRepeated() {
214     Iterator<String> iterator = Iterators.forArray("a", "a", "a");
215     Set<String> set = copyOf(iterator);
216     assertEquals(Collections.singleton("a"), set);
217   }
218 
testCopyOf_iterator_general()219   public void testCopyOf_iterator_general() {
220     Iterator<String> iterator = Iterators.forArray("a", "b", "a");
221     Set<String> set = copyOf(iterator);
222     assertEquals(2, set.size());
223     assertTrue(set.contains("a"));
224     assertTrue(set.contains("b"));
225   }
226 
testCopyOf_iteratorContainingNull()227   public void testCopyOf_iteratorContainingNull() {
228     Iterator<String> c = Iterators.forArray("a", null, "b");
229     try {
230       copyOf(c);
231       fail();
232     } catch (NullPointerException expected) {
233     }
234   }
235 
236   private static class CountingIterable implements Iterable<String> {
237     int count = 0;
238 
239     @Override
iterator()240     public Iterator<String> iterator() {
241       count++;
242       return Iterators.forArray("a", "b", "a");
243     }
244   }
245 
testCopyOf_plainIterable()246   public void testCopyOf_plainIterable() {
247     CountingIterable iterable = new CountingIterable();
248     Set<String> set = copyOf(iterable);
249     assertEquals(2, set.size());
250     assertTrue(set.contains("a"));
251     assertTrue(set.contains("b"));
252   }
253 
testCopyOf_plainIterable_iteratesOnce()254   public void testCopyOf_plainIterable_iteratesOnce() {
255     CountingIterable iterable = new CountingIterable();
256     Set<String> unused = copyOf(iterable);
257     assertEquals(1, iterable.count);
258   }
259 
testCopyOf_shortcut_empty()260   public void testCopyOf_shortcut_empty() {
261     Collection<String> c = of();
262     assertEquals(Collections.<String>emptySet(), copyOf(c));
263     assertSame(c, copyOf(c));
264   }
265 
testCopyOf_shortcut_singleton()266   public void testCopyOf_shortcut_singleton() {
267     Collection<String> c = of("a");
268     assertEquals(Collections.singleton("a"), copyOf(c));
269     assertSame(c, copyOf(c));
270   }
271 
testCopyOf_shortcut_sameType()272   public void testCopyOf_shortcut_sameType() {
273     Collection<String> c = of("a", "b", "c");
274     assertSame(c, copyOf(c));
275   }
276 
testToString()277   public void testToString() {
278     Set<String> set = of("a", "b", "c", "d", "e", "f", "g");
279     assertEquals("[a, b, c, d, e, f, g]", set.toString());
280   }
281 
282   @GwtIncompatible // slow (~40s)
testIterator_oneElement()283   public void testIterator_oneElement() {
284     new IteratorTester<String>(
285         5, UNMODIFIABLE, Collections.singleton("a"), IteratorTester.KnownOrder.KNOWN_ORDER) {
286       @Override
287       protected Iterator<String> newTargetIterator() {
288         return of("a").iterator();
289       }
290     }.test();
291   }
292 
293   @GwtIncompatible // slow (~30s)
testIterator_general()294   public void testIterator_general() {
295     new IteratorTester<String>(
296         5, UNMODIFIABLE, asList("a", "b", "c"), IteratorTester.KnownOrder.KNOWN_ORDER) {
297       @Override
298       protected Iterator<String> newTargetIterator() {
299         return of("a", "b", "c").iterator();
300       }
301     }.test();
302   }
303 
testContainsAll_sameType()304   public void testContainsAll_sameType() {
305     Collection<String> c = of("a", "b", "c");
306     assertFalse(c.containsAll(of("a", "b", "c", "d")));
307     assertFalse(c.containsAll(of("a", "d")));
308     assertTrue(c.containsAll(of("a", "c")));
309     assertTrue(c.containsAll(of("a", "b", "c")));
310   }
311 
testEquals_sameType()312   public void testEquals_sameType() {
313     Collection<String> c = of("a", "b", "c");
314     assertTrue(c.equals(of("a", "b", "c")));
315     assertFalse(c.equals(of("a", "b", "d")));
316   }
317 
builder()318   abstract <E extends Comparable<E>> ImmutableSet.Builder<E> builder();
319 
testBuilderWithNonDuplicateElements()320   public void testBuilderWithNonDuplicateElements() {
321     ImmutableSet<String> set =
322         this.<String>builder()
323             .add("a")
324             .add("b", "c")
325             .add("d", "e", "f")
326             .add("g", "h", "i", "j")
327             .build();
328     assertThat(set).containsExactly("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").inOrder();
329   }
330 
testReuseBuilderWithNonDuplicateElements()331   public void testReuseBuilderWithNonDuplicateElements() {
332     ImmutableSet.Builder<String> builder = this.<String>builder().add("a").add("b");
333     assertThat(builder.build()).containsExactly("a", "b").inOrder();
334     builder.add("c", "d");
335     assertThat(builder.build()).containsExactly("a", "b", "c", "d").inOrder();
336   }
337 
testBuilderWithDuplicateElements()338   public void testBuilderWithDuplicateElements() {
339     ImmutableSet<String> set =
340         this.<String>builder()
341             .add("a")
342             .add("a", "a")
343             .add("a", "a", "a")
344             .add("a", "a", "a", "a")
345             .build();
346     assertTrue(set.contains("a"));
347     assertFalse(set.contains("b"));
348     assertEquals(1, set.size());
349   }
350 
testReuseBuilderWithDuplicateElements()351   public void testReuseBuilderWithDuplicateElements() {
352     ImmutableSet.Builder<String> builder = this.<String>builder().add("a").add("a", "a").add("b");
353     assertThat(builder.build()).containsExactly("a", "b").inOrder();
354     builder.add("a", "b", "c", "c");
355     assertThat(builder.build()).containsExactly("a", "b", "c").inOrder();
356   }
357 
testBuilderAddAll()358   public void testBuilderAddAll() {
359     List<String> a = asList("a", "b", "c");
360     List<String> b = asList("c", "d", "e");
361     ImmutableSet<String> set = this.<String>builder().addAll(a).addAll(b).build();
362     assertThat(set).containsExactly("a", "b", "c", "d", "e").inOrder();
363   }
364 
365   static final int LAST_COLOR_ADDED = 0x00BFFF;
366 
testComplexBuilder()367   public void testComplexBuilder() {
368     List<Integer> colorElem = asList(0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF);
369     // javac won't compile this without "this.<Integer>"
370     ImmutableSet.Builder<Integer> webSafeColorsBuilder = this.<Integer>builder();
371     for (Integer red : colorElem) {
372       for (Integer green : colorElem) {
373         for (Integer blue : colorElem) {
374           webSafeColorsBuilder.add((red << 16) + (green << 8) + blue);
375         }
376       }
377     }
378     ImmutableSet<Integer> webSafeColors = webSafeColorsBuilder.build();
379     assertEquals(216, webSafeColors.size());
380     Integer[] webSafeColorArray = webSafeColors.toArray(new Integer[webSafeColors.size()]);
381     assertEquals(0x000000, (int) webSafeColorArray[0]);
382     assertEquals(0x000033, (int) webSafeColorArray[1]);
383     assertEquals(0x000066, (int) webSafeColorArray[2]);
384     assertEquals(0x003300, (int) webSafeColorArray[6]);
385     assertEquals(0x330000, (int) webSafeColorArray[36]);
386     ImmutableSet<Integer> addedColor = webSafeColorsBuilder.add(LAST_COLOR_ADDED).build();
387     assertEquals(
388         "Modifying the builder should not have changed any already built sets",
389         216,
390         webSafeColors.size());
391     assertEquals("the new array should be one bigger than webSafeColors", 217, addedColor.size());
392     Integer[] appendColorArray = addedColor.toArray(new Integer[addedColor.size()]);
393     assertEquals(getComplexBuilderSetLastElement(), (int) appendColorArray[216]);
394   }
395 
getComplexBuilderSetLastElement()396   abstract int getComplexBuilderSetLastElement();
397 
testBuilderAddHandlesNullsCorrectly()398   public void testBuilderAddHandlesNullsCorrectly() {
399     ImmutableSet.Builder<String> builder = this.<String>builder();
400     try {
401       builder.add((String) null);
402       fail("expected NullPointerException"); // COV_NF_LINE
403     } catch (NullPointerException expected) {
404     }
405 
406     builder = this.<String>builder();
407     try {
408       builder.add((String[]) null);
409       fail("expected NullPointerException"); // COV_NF_LINE
410     } catch (NullPointerException expected) {
411     }
412 
413     builder = this.<String>builder();
414     try {
415       builder.add("a", (String) null);
416       fail("expected NullPointerException"); // COV_NF_LINE
417     } catch (NullPointerException expected) {
418     }
419 
420     builder = this.<String>builder();
421     try {
422       builder.add("a", "b", (String) null);
423       fail("expected NullPointerException"); // COV_NF_LINE
424     } catch (NullPointerException expected) {
425     }
426 
427     builder = this.<String>builder();
428     try {
429       builder.add("a", "b", "c", null);
430       fail("expected NullPointerException"); // COV_NF_LINE
431     } catch (NullPointerException expected) {
432     }
433 
434     builder = this.<String>builder();
435     try {
436       builder.add("a", "b", null, "c");
437       fail("expected NullPointerException"); // COV_NF_LINE
438     } catch (NullPointerException expected) {
439     }
440   }
441 
testBuilderAddAllHandlesNullsCorrectly()442   public void testBuilderAddAllHandlesNullsCorrectly() {
443     ImmutableSet.Builder<String> builder = this.<String>builder();
444     try {
445       builder.addAll((Iterable<String>) null);
446       fail("expected NullPointerException"); // COV_NF_LINE
447     } catch (NullPointerException expected) {
448     }
449 
450     try {
451       builder.addAll((Iterator<String>) null);
452       fail("expected NullPointerException"); // COV_NF_LINE
453     } catch (NullPointerException expected) {
454     }
455 
456     builder = this.<String>builder();
457     List<String> listWithNulls = asList("a", null, "b");
458     try {
459       builder.addAll(listWithNulls);
460       fail("expected NullPointerException"); // COV_NF_LINE
461     } catch (NullPointerException expected) {
462     }
463 
464     Iterable<String> iterableWithNulls = MinimalIterable.of("a", null, "b");
465     try {
466       builder.addAll(iterableWithNulls);
467       fail("expected NullPointerException"); // COV_NF_LINE
468     } catch (NullPointerException expected) {
469     }
470   }
471 
472   /**
473    * Verify thread safety by using a collection whose size() may be inconsistent with the actual
474    * number of elements. Tests using this method might fail in GWT because the GWT emulations might
475    * count on size() during copy. It is safe to do so in GWT because javascript is single-threaded.
476    */
477   // TODO(benyu): turn this into a test once all copyOf(Collection) are
478   // thread-safe
479   @GwtIncompatible // GWT is single threaded
verifyThreadSafe()480   void verifyThreadSafe() {
481     List<String> sample = Lists.newArrayList("a", "b", "c");
482     for (int delta : new int[] {-1, 0, 1}) {
483       for (int i = 0; i < sample.size(); i++) {
484         Collection<String> misleading = Helpers.misleadingSizeCollection(delta);
485         List<String> expected = sample.subList(0, i);
486         misleading.addAll(expected);
487         assertEquals(
488             "delta: " + delta + " sample size: " + i,
489             Sets.newHashSet(expected),
490             copyOf(misleading));
491       }
492     }
493   }
494 }
495