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