Collections2Test.java revision 3c77433663281544363151bf284b0240dfd22a42
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 17package com.google.common.collect; 18 19import static com.google.common.collect.Iterables.concat; 20import static com.google.common.collect.Lists.newArrayList; 21import static com.google.common.collect.Lists.newLinkedList; 22import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; 23import static java.util.Arrays.asList; 24import static java.util.Collections.nCopies; 25import static org.truth0.Truth.ASSERT; 26 27import com.google.common.annotations.GwtCompatible; 28import com.google.common.annotations.GwtIncompatible; 29import com.google.common.base.Function; 30import com.google.common.base.Predicate; 31import com.google.common.collect.testing.CollectionTestSuiteBuilder; 32import com.google.common.collect.testing.TestStringCollectionGenerator; 33import com.google.common.collect.testing.features.CollectionFeature; 34import com.google.common.collect.testing.features.CollectionSize; 35import com.google.common.testing.NullPointerTester; 36 37import junit.framework.Test; 38import junit.framework.TestCase; 39import junit.framework.TestSuite; 40 41import java.util.Collection; 42import java.util.Collections; 43import java.util.Iterator; 44import java.util.List; 45import java.util.NoSuchElementException; 46 47/** 48 * Tests for {@link Collections2}. 49 * 50 * @author Chris Povirk 51 * @author Jared Levy 52 */ 53@GwtCompatible(emulated = true) 54public class Collections2Test extends TestCase { 55 @GwtIncompatible("suite") 56 public static Test suite() { 57 TestSuite suite = new TestSuite(Collections2Test.class.getSimpleName()); 58 suite.addTest(testsForFilter()); 59 suite.addTest(testsForFilterAll()); 60 suite.addTest(testsForFilterLinkedList()); 61 suite.addTest(testsForFilterNoNulls()); 62 suite.addTest(testsForFilterFiltered()); 63 suite.addTest(testsForTransform()); 64 suite.addTestSuite(Collections2Test.class); 65 return suite; 66 } 67 68 static final Predicate<String> NOT_YYY_ZZZ = new Predicate<String>() { 69 @Override 70 public boolean apply(String input) { 71 return !"yyy".equals(input) && !"zzz".equals(input); 72 } 73 }; 74 75 static final Predicate<String> LENGTH_1 = new Predicate<String>() { 76 @Override 77 public boolean apply(String input) { 78 return input.length() == 1; 79 } 80 }; 81 82 static final Predicate<String> STARTS_WITH_VOWEL = new Predicate<String>() { 83 @Override 84 public boolean apply(String input) { 85 return asList('a', 'e', 'i', 'o', 'u').contains(input.charAt(0)); 86 } 87 }; 88 89 @GwtIncompatible("suite") 90 private static Test testsForFilter() { 91 return CollectionTestSuiteBuilder.using( 92 new TestStringCollectionGenerator() { 93 @Override public Collection<String> create(String[] elements) { 94 List<String> unfiltered = newArrayList(); 95 unfiltered.add("yyy"); 96 unfiltered.addAll(asList(elements)); 97 unfiltered.add("zzz"); 98 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 99 } 100 }) 101 .named("Collections2.filter") 102 .withFeatures( 103 CollectionFeature.GENERAL_PURPOSE, 104 CollectionFeature.ALLOWS_NULL_VALUES, 105 CollectionFeature.KNOWN_ORDER, 106 CollectionSize.ANY) 107 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 108 .createTestSuite(); 109 } 110 111 @GwtIncompatible("suite") 112 private static Test testsForFilterAll() { 113 return CollectionTestSuiteBuilder.using( 114 new TestStringCollectionGenerator() { 115 @Override public Collection<String> create(String[] elements) { 116 List<String> unfiltered = newArrayList(); 117 unfiltered.addAll(asList(elements)); 118 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 119 } 120 }) 121 .named("Collections2.filter") 122 .withFeatures( 123 CollectionFeature.GENERAL_PURPOSE, 124 CollectionFeature.ALLOWS_NULL_VALUES, 125 CollectionFeature.KNOWN_ORDER, 126 CollectionSize.ANY) 127 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 128 .createTestSuite(); 129 } 130 131 @GwtIncompatible("suite") 132 private static Test testsForFilterLinkedList() { 133 return CollectionTestSuiteBuilder.using( 134 new TestStringCollectionGenerator() { 135 @Override public Collection<String> create(String[] elements) { 136 List<String> unfiltered = newLinkedList(); 137 unfiltered.add("yyy"); 138 unfiltered.addAll(asList(elements)); 139 unfiltered.add("zzz"); 140 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 141 } 142 }) 143 .named("Collections2.filter") 144 .withFeatures( 145 CollectionFeature.GENERAL_PURPOSE, 146 CollectionFeature.ALLOWS_NULL_VALUES, 147 CollectionFeature.KNOWN_ORDER, 148 CollectionSize.ANY) 149 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 150 .createTestSuite(); 151 } 152 153 @GwtIncompatible("suite") 154 private static Test testsForFilterNoNulls() { 155 return CollectionTestSuiteBuilder.using( 156 new TestStringCollectionGenerator() { 157 @Override public Collection<String> create(String[] elements) { 158 List<String> unfiltered = newArrayList(); 159 unfiltered.add("yyy"); 160 unfiltered.addAll(ImmutableList.copyOf(elements)); 161 unfiltered.add("zzz"); 162 return Collections2.filter(unfiltered, LENGTH_1); 163 } 164 }) 165 .named("Collections2.filter, no nulls") 166 .withFeatures( 167 CollectionFeature.GENERAL_PURPOSE, 168 CollectionFeature.ALLOWS_NULL_QUERIES, 169 CollectionFeature.KNOWN_ORDER, 170 CollectionSize.ANY) 171 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 172 .createTestSuite(); 173 } 174 175 @GwtIncompatible("suite") 176 private static Test testsForFilterFiltered() { 177 return CollectionTestSuiteBuilder.using( 178 new TestStringCollectionGenerator() { 179 @Override public Collection<String> create(String[] elements) { 180 List<String> unfiltered = newArrayList(); 181 unfiltered.add("yyy"); 182 unfiltered.addAll(ImmutableList.copyOf(elements)); 183 unfiltered.add("zzz"); 184 unfiltered.add("abc"); 185 return Collections2.filter( 186 Collections2.filter(unfiltered, LENGTH_1), NOT_YYY_ZZZ); 187 } 188 }) 189 .named("Collections2.filter, filtered input") 190 .withFeatures( 191 CollectionFeature.GENERAL_PURPOSE, 192 CollectionFeature.KNOWN_ORDER, 193 CollectionFeature.ALLOWS_NULL_QUERIES, 194 CollectionSize.ANY) 195 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 196 .createTestSuite(); 197 } 198 199 private static final Function<String, String> REMOVE_FIRST_CHAR 200 = new Function<String, String>() { 201 @Override 202 public String apply(String from) { 203 return ((from == null) || "".equals(from)) 204 ? null : from.substring(1); 205 } 206 }; 207 208 @GwtIncompatible("suite") 209 private static Test testsForTransform() { 210 return CollectionTestSuiteBuilder.using( 211 new TestStringCollectionGenerator() { 212 @Override public Collection<String> create(String[] elements) { 213 List<String> list = newArrayList(); 214 for (String element : elements) { 215 list.add((element == null) ? null : "q" + element); 216 } 217 return Collections2.transform(list, REMOVE_FIRST_CHAR); 218 } 219 }) 220 .named("Collections2.transform") 221 .withFeatures( 222 CollectionFeature.SUPPORTS_REMOVE, 223 CollectionFeature.ALLOWS_NULL_VALUES, 224 CollectionFeature.KNOWN_ORDER, 225 CollectionSize.ANY) 226 .createTestSuite(); 227 } 228 229 @GwtIncompatible("NullPointerTester") 230 public void testNullPointerExceptions() { 231 NullPointerTester tester = new NullPointerTester(); 232 tester.testAllPublicStaticMethods(Collections2.class); 233 } 234 235 public void testOrderedPermutationSetEmpty() { 236 List<Integer> list = newArrayList(); 237 Collection<List<Integer>> permutationSet = 238 Collections2.orderedPermutations(list); 239 240 assertEquals(1, permutationSet.size()); 241 ASSERT.that(permutationSet).has().item(list); 242 243 Iterator<List<Integer>> permutations = permutationSet.iterator(); 244 245 assertNextPermutation(Lists.<Integer>newArrayList(), permutations); 246 assertNoMorePermutations(permutations); 247 } 248 249 public void testOrderedPermutationSetOneElement() { 250 List<Integer> list = newArrayList(1); 251 Iterator<List<Integer>> permutations = 252 Collections2.orderedPermutations(list).iterator(); 253 254 assertNextPermutation(newArrayList(1), permutations); 255 assertNoMorePermutations(permutations); 256 } 257 258 public void testOrderedPermutationSetThreeElements() { 259 List<String> list = newArrayList("b", "a", "c"); 260 Iterator<List<String>> permutations = 261 Collections2.orderedPermutations(list).iterator(); 262 263 assertNextPermutation(newArrayList("a", "b", "c"), permutations); 264 assertNextPermutation(newArrayList("a", "c", "b"), permutations); 265 assertNextPermutation(newArrayList("b", "a", "c"), permutations); 266 assertNextPermutation(newArrayList("b", "c", "a"), permutations); 267 assertNextPermutation(newArrayList("c", "a", "b"), permutations); 268 assertNextPermutation(newArrayList("c", "b", "a"), permutations); 269 assertNoMorePermutations(permutations); 270 } 271 272 public void testOrderedPermutationSetRepeatedElements() { 273 List<Integer> list = newArrayList(1, 1, 2, 2); 274 Iterator<List<Integer>> permutations = 275 Collections2.orderedPermutations(list, Ordering.natural()).iterator(); 276 277 assertNextPermutation(newArrayList(1, 1, 2, 2), permutations); 278 assertNextPermutation(newArrayList(1, 2, 1, 2), permutations); 279 assertNextPermutation(newArrayList(1, 2, 2, 1), permutations); 280 assertNextPermutation(newArrayList(2, 1, 1, 2), permutations); 281 assertNextPermutation(newArrayList(2, 1, 2, 1), permutations); 282 assertNextPermutation(newArrayList(2, 2, 1, 1), permutations); 283 assertNoMorePermutations(permutations); 284 } 285 286 public void testOrderedPermutationSetRepeatedElementsSize() { 287 List<Integer> list = newArrayList(1, 1, 1, 1, 2, 2, 3); 288 Collection<List<Integer>> permutations = 289 Collections2.orderedPermutations(list, Ordering.natural()); 290 291 assertPermutationsCount(105, permutations); 292 } 293 294 public void testOrderedPermutationSetSizeOverflow() { 295 // 12 elements won't overflow 296 assertEquals(479001600 /*12!*/, Collections2.orderedPermutations( 297 newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)).size()); 298 // 13 elements overflow an int 299 assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations( 300 newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size()); 301 // 21 elements overflow a long 302 assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations( 303 newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 304 16, 17, 18, 19, 20, 21)).size()); 305 306 // Almost force an overflow in the binomial coefficient calculation 307 assertEquals(1391975640 /*C(34,14)*/, Collections2.orderedPermutations( 308 concat(nCopies(20, 1), nCopies(14, 2))).size()); 309 // Do force an overflow in the binomial coefficient calculation 310 assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations( 311 concat(nCopies(21, 1), nCopies(14, 2))).size()); 312 } 313 314 public void testOrderedPermutationSetContains() { 315 List<Integer> list = newArrayList(3, 2, 1); 316 Collection<List<Integer>> permutationSet = 317 Collections2.orderedPermutations(list); 318 319 assertTrue(permutationSet.contains(newArrayList(1, 2, 3))); 320 assertTrue(permutationSet.contains(newArrayList(2, 3, 1))); 321 assertFalse(permutationSet.contains(newArrayList(1, 2))); 322 assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3))); 323 assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4))); 324 assertFalse(permutationSet.contains(null)); 325 } 326 327 public void testPermutationSetEmpty() { 328 Collection<List<Integer>> permutationSet = 329 Collections2.permutations(Collections.<Integer>emptyList()); 330 331 assertEquals(1, permutationSet.size()); 332 assertTrue(permutationSet.contains(Collections.<Integer> emptyList())); 333 334 Iterator<List<Integer>> permutations = permutationSet.iterator(); 335 assertNextPermutation(Collections.<Integer> emptyList(), permutations); 336 assertNoMorePermutations(permutations); 337 } 338 339 public void testPermutationSetOneElement() { 340 Iterator<List<Integer>> permutations = 341 Collections2.permutations(Collections.<Integer> singletonList(1)) 342 .iterator(); 343 assertNextPermutation(newArrayList(1), permutations); 344 assertNoMorePermutations(permutations); 345 } 346 347 public void testPermutationSetTwoElements() { 348 Iterator<List<Integer>> permutations = Collections2.permutations( 349 newArrayList(1, 2)).iterator(); 350 assertNextPermutation(newArrayList(1, 2), permutations); 351 assertNextPermutation(newArrayList(2, 1), permutations); 352 assertNoMorePermutations(permutations); 353 } 354 355 public void testPermutationSetThreeElements() { 356 Iterator<List<Integer>> permutations = Collections2.permutations( 357 newArrayList(1, 2, 3)).iterator(); 358 assertNextPermutation(newArrayList(1, 2, 3), permutations); 359 assertNextPermutation(newArrayList(1, 3, 2), permutations); 360 assertNextPermutation(newArrayList(3, 1, 2), permutations); 361 362 assertNextPermutation(newArrayList(3, 2, 1), permutations); 363 assertNextPermutation(newArrayList(2, 3, 1), permutations); 364 assertNextPermutation(newArrayList(2, 1, 3), permutations); 365 assertNoMorePermutations(permutations); 366 } 367 368 public void testPermutationSetThreeElementsOutOfOrder() { 369 Iterator<List<Integer>> permutations = Collections2.permutations( 370 newArrayList(3, 2, 1)).iterator(); 371 assertNextPermutation(newArrayList(3, 2, 1), permutations); 372 assertNextPermutation(newArrayList(3, 1, 2), permutations); 373 assertNextPermutation(newArrayList(1, 3, 2), permutations); 374 375 assertNextPermutation(newArrayList(1, 2, 3), permutations); 376 assertNextPermutation(newArrayList(2, 1, 3), permutations); 377 assertNextPermutation(newArrayList(2, 3, 1), permutations); 378 assertNoMorePermutations(permutations); 379 } 380 381 public void testPermutationSetThreeRepeatedElements() { 382 Iterator<List<Integer>> permutations = Collections2.permutations( 383 newArrayList(1, 1, 2)).iterator(); 384 assertNextPermutation(newArrayList(1, 1, 2), permutations); 385 assertNextPermutation(newArrayList(1, 2, 1), permutations); 386 assertNextPermutation(newArrayList(2, 1, 1), permutations); 387 assertNextPermutation(newArrayList(2, 1, 1), permutations); 388 assertNextPermutation(newArrayList(1, 2, 1), permutations); 389 assertNextPermutation(newArrayList(1, 1, 2), permutations); 390 assertNoMorePermutations(permutations); 391 } 392 393 public void testPermutationSetFourElements() { 394 Iterator<List<Integer>> permutations = Collections2.permutations( 395 newArrayList(1, 2, 3, 4)).iterator(); 396 assertNextPermutation(newArrayList(1, 2, 3, 4), permutations); 397 assertNextPermutation(newArrayList(1, 2, 4, 3), permutations); 398 assertNextPermutation(newArrayList(1, 4, 2, 3), permutations); 399 assertNextPermutation(newArrayList(4, 1, 2, 3), permutations); 400 401 assertNextPermutation(newArrayList(4, 1, 3, 2), permutations); 402 assertNextPermutation(newArrayList(1, 4, 3, 2), permutations); 403 assertNextPermutation(newArrayList(1, 3, 4, 2), permutations); 404 assertNextPermutation(newArrayList(1, 3, 2, 4), permutations); 405 406 assertNextPermutation(newArrayList(3, 1, 2, 4), permutations); 407 assertNextPermutation(newArrayList(3, 1, 4, 2), permutations); 408 assertNextPermutation(newArrayList(3, 4, 1, 2), permutations); 409 assertNextPermutation(newArrayList(4, 3, 1, 2), permutations); 410 411 assertNextPermutation(newArrayList(4, 3, 2, 1), permutations); 412 assertNextPermutation(newArrayList(3, 4, 2, 1), permutations); 413 assertNextPermutation(newArrayList(3, 2, 4, 1), permutations); 414 assertNextPermutation(newArrayList(3, 2, 1, 4), permutations); 415 416 assertNextPermutation(newArrayList(2, 3, 1, 4), permutations); 417 assertNextPermutation(newArrayList(2, 3, 4, 1), permutations); 418 assertNextPermutation(newArrayList(2, 4, 3, 1), permutations); 419 assertNextPermutation(newArrayList(4, 2, 3, 1), permutations); 420 421 assertNextPermutation(newArrayList(4, 2, 1, 3), permutations); 422 assertNextPermutation(newArrayList(2, 4, 1, 3), permutations); 423 assertNextPermutation(newArrayList(2, 1, 4, 3), permutations); 424 assertNextPermutation(newArrayList(2, 1, 3, 4), permutations); 425 assertNoMorePermutations(permutations); 426 } 427 428 public void testPermutationSetSize() { 429 assertPermutationsCount(1, 430 Collections2.permutations(Collections.<Integer>emptyList())); 431 assertPermutationsCount(1, Collections2.permutations(newArrayList(1))); 432 assertPermutationsCount(2, Collections2.permutations(newArrayList(1, 2))); 433 assertPermutationsCount(6, 434 Collections2.permutations(newArrayList(1, 2, 3))); 435 assertPermutationsCount(5040, 436 Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7))); 437 assertPermutationsCount(40320, 438 Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8))); 439 } 440 441 public void testPermutationSetSizeOverflow() { 442 // 13 elements overflow an int 443 assertEquals(Integer.MAX_VALUE, Collections2.permutations(newArrayList( 444 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size()); 445 // 21 elements overflow a long 446 assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations( 447 newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 448 16, 17, 18, 19, 20)).size()); 449 assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations( 450 newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 451 16, 17, 18, 19, 20, 21)).size()); 452 } 453 454 public void testPermutationSetContains() { 455 List<Integer> list = newArrayList(3, 2, 1); 456 Collection<List<Integer>> permutationSet = 457 Collections2.permutations(list); 458 459 assertTrue(permutationSet.contains(newArrayList(1, 2, 3))); 460 assertTrue(permutationSet.contains(newArrayList(2, 3, 1))); 461 assertFalse(permutationSet.contains(newArrayList(1, 2))); 462 assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3))); 463 assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4))); 464 assertFalse(permutationSet.contains(null)); 465 } 466 467 private <T> void assertNextPermutation(List<T> expectedPermutation, 468 Iterator<List<T>> permutations) { 469 assertTrue("Expected another permutation, but there was none.", 470 permutations.hasNext()); 471 assertEquals(expectedPermutation, permutations.next()); 472 } 473 474 private <T> void assertNoMorePermutations( 475 Iterator<List<T>> permutations) { 476 assertFalse("Expected no more permutations, but there was one.", 477 permutations.hasNext()); 478 try { 479 permutations.next(); 480 fail("Expected NoSuchElementException."); 481 } catch (NoSuchElementException expected) {} 482 } 483 484 private <T> void assertPermutationsCount(int expected, 485 Collection<List<T>> permutationSet) { 486 assertEquals(expected, permutationSet.size()); 487 Iterator<List<T>> permutations = permutationSet.iterator(); 488 for (int i = 0; i < expected; i++) { 489 assertTrue(permutations.hasNext()); 490 permutations.next(); 491 } 492 assertNoMorePermutations(permutations); 493 } 494 495 public void testToStringImplWithNullEntries() throws Exception { 496 List<String> list = Lists.newArrayList(); 497 list.add("foo"); 498 list.add(null); 499 500 assertEquals(list.toString(), Collections2.toStringImpl(list)); 501 } 502 503} 504