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
17package com.google.common.collect;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.annotations.GwtIncompatible;
23import com.google.common.collect.ImmutableSet.Builder;
24import com.google.common.collect.testing.ListTestSuiteBuilder;
25import com.google.common.collect.testing.SetTestSuiteBuilder;
26import com.google.common.collect.testing.features.CollectionFeature;
27import com.google.common.collect.testing.features.CollectionSize;
28import com.google.common.collect.testing.google.SetGenerators.DegeneratedImmutableSetGenerator;
29import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsListGenerator;
30import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator;
31import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator;
32import com.google.common.testing.EqualsTester;
33
34import junit.framework.Test;
35import junit.framework.TestSuite;
36
37import java.util.Collection;
38import java.util.Collections;
39import java.util.Iterator;
40import java.util.Set;
41
42/**
43 * Unit test for {@link ImmutableSet}.
44 *
45 * @author Kevin Bourrillion
46 * @author Jared Levy
47 * @author Nick Kralevich
48 */
49@GwtCompatible(emulated = true)
50public class ImmutableSetTest extends AbstractImmutableSetTest {
51
52  @GwtIncompatible("suite")
53  public static Test suite() {
54    TestSuite suite = new TestSuite();
55
56    suite.addTest(SetTestSuiteBuilder.using(new ImmutableSetCopyOfGenerator())
57        .named(ImmutableSetTest.class.getName())
58        .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
59            CollectionFeature.SERIALIZABLE,
60            CollectionFeature.ALLOWS_NULL_QUERIES)
61        .createTestSuite());
62
63    suite.addTest(SetTestSuiteBuilder.using(
64        new ImmutableSetWithBadHashesGenerator())
65        .named(ImmutableSetTest.class.getName() + ", with bad hashes")
66        .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
67            CollectionFeature.ALLOWS_NULL_QUERIES)
68        .createTestSuite());
69
70    suite.addTest(SetTestSuiteBuilder.using(
71        new DegeneratedImmutableSetGenerator())
72        .named(ImmutableSetTest.class.getName() + ", degenerate")
73        .withFeatures(CollectionSize.ONE, CollectionFeature.KNOWN_ORDER,
74            CollectionFeature.ALLOWS_NULL_QUERIES)
75        .createTestSuite());
76
77    suite.addTest(ListTestSuiteBuilder.using(new ImmutableSetAsListGenerator())
78        .named("ImmutableSet.asList")
79        .withFeatures(CollectionSize.ANY,
80            CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
81            CollectionFeature.SERIALIZABLE,
82            CollectionFeature.ALLOWS_NULL_QUERIES)
83        .createTestSuite());
84
85    suite.addTestSuite(ImmutableSetTest.class);
86
87    return suite;
88  }
89
90  @Override protected Set<String> of() {
91    return ImmutableSet.of();
92  }
93
94  @Override protected Set<String> of(String e) {
95    return ImmutableSet.of(e);
96  }
97
98  @Override protected Set<String> of(String e1, String e2) {
99    return ImmutableSet.of(e1, e2);
100  }
101
102  @Override protected Set<String> of(String e1, String e2, String e3) {
103    return ImmutableSet.of(e1, e2, e3);
104  }
105
106  @Override protected Set<String> of(
107      String e1, String e2, String e3, String e4) {
108    return ImmutableSet.of(e1, e2, e3, e4);
109  }
110
111  @Override protected Set<String> of(
112      String e1, String e2, String e3, String e4, String e5) {
113    return ImmutableSet.of(e1, e2, e3, e4, e5);
114  }
115
116  @Override protected Set<String> of(String e1, String e2, String e3,
117      String e4, String e5, String e6, String... rest) {
118    return ImmutableSet.of(e1, e2, e3, e4, e5, e6, rest);
119  }
120
121  @Override protected Set<String> copyOf(String[] elements) {
122    return ImmutableSet.copyOf(elements);
123  }
124
125  @Override protected Set<String> copyOf(Collection<String> elements) {
126    return ImmutableSet.copyOf(elements);
127  }
128
129  @Override protected Set<String> copyOf(Iterable<String> elements) {
130    return ImmutableSet.copyOf(elements);
131  }
132
133  @Override protected Set<String> copyOf(Iterator<String> elements) {
134    return ImmutableSet.copyOf(elements);
135  }
136
137  public void testCreation_allDuplicates() {
138    ImmutableSet<String> set = ImmutableSet.copyOf(Lists.newArrayList("a", "a"));
139    assertTrue(set instanceof SingletonImmutableSet);
140    assertEquals(Lists.newArrayList("a"), Lists.newArrayList(set));
141  }
142
143  public void testCreation_oneDuplicate() {
144    // now we'll get the varargs overload
145    ImmutableSet<String> set = ImmutableSet.of(
146        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "a");
147    assertEquals(Lists.newArrayList(
148        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"),
149        Lists.newArrayList(set));
150  }
151
152  public void testCreation_manyDuplicates() {
153    // now we'll get the varargs overload
154    ImmutableSet<String> set = ImmutableSet.of(
155        "a", "b", "c", "c", "c", "c", "b", "b", "a", "a", "c", "c", "c", "a");
156    assertThat(set).has().exactly("a", "b", "c").inOrder();
157  }
158
159  public void testCreation_arrayOfArray() {
160    String[] array = new String[] { "a" };
161    Set<String[]> set = ImmutableSet.<String[]>of(array);
162    assertEquals(Collections.singleton(array), set);
163  }
164
165  @GwtIncompatible("ImmutableSet.chooseTableSize")
166  public void testChooseTableSize() {
167    assertEquals(8, ImmutableSet.chooseTableSize(3));
168    assertEquals(8, ImmutableSet.chooseTableSize(4));
169
170    assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 28));
171    assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 29 - 1));
172
173    // Now we hit the cap
174    assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 29));
175    assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 30 - 1));
176
177    // Now we've gone too far
178    try {
179      ImmutableSet.chooseTableSize(1 << 30);
180      fail();
181    } catch (IllegalArgumentException expected) {
182    }
183  }
184
185  @GwtIncompatible("RegularImmutableSet.table not in emulation")
186  public void testResizeTable() {
187    verifyTableSize(100, 2, 4);
188    verifyTableSize(100, 5, 8);
189    verifyTableSize(100, 33, 64);
190    verifyTableSize(17, 17, 32);
191    verifyTableSize(17, 16, 32);
192    verifyTableSize(17, 15, 32);
193  }
194
195  @GwtIncompatible("RegularImmutableSet.table not in emulation")
196  private void verifyTableSize(int inputSize, int setSize, int tableSize) {
197    Builder<Integer> builder = ImmutableSet.builder();
198    for (int i = 0; i < inputSize; i++) {
199      builder.add(i % setSize);
200    }
201    ImmutableSet<Integer> set = builder.build();
202    assertTrue(set instanceof RegularImmutableSet);
203    assertEquals("Input size " + inputSize + " and set size " + setSize,
204        tableSize, ((RegularImmutableSet<Integer>) set).table.length);
205  }
206
207  public void testCopyOf_copiesImmutableSortedSet() {
208    ImmutableSortedSet<String> sortedSet = ImmutableSortedSet.of("a");
209    ImmutableSet<String> copy = ImmutableSet.copyOf(sortedSet);
210    assertNotSame(sortedSet, copy);
211  }
212
213  @GwtIncompatible("GWT is single threaded")
214  public void testCopyOf_threadSafe() {
215    verifyThreadSafe();
216  }
217
218  @Override <E extends Comparable<E>> Builder<E> builder() {
219    return ImmutableSet.builder();
220  }
221
222  @Override int getComplexBuilderSetLastElement() {
223    return LAST_COLOR_ADDED;
224  }
225
226  public void testEquals() {
227    new EqualsTester()
228        .addEqualityGroup(ImmutableSet.of(), ImmutableSet.of())
229        .addEqualityGroup(ImmutableSet.of(1), ImmutableSet.of(1), ImmutableSet.of(1, 1))
230        .addEqualityGroup(ImmutableSet.of(1, 2, 1), ImmutableSet.of(2, 1, 1))
231        .testEquals();
232  }
233}
234