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