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 17 package com.google.common.collect; 18 19 import static com.google.common.collect.Iterables.skip; 20 import static com.google.common.collect.Lists.newArrayList; 21 import static com.google.common.collect.Sets.newLinkedHashSet; 22 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; 23 import static com.google.common.truth.Truth.assertThat; 24 import static java.util.Arrays.asList; 25 import static java.util.Collections.emptyList; 26 27 import com.google.common.annotations.GwtCompatible; 28 import com.google.common.base.Function; 29 import com.google.common.base.Optional; 30 import com.google.common.base.Predicate; 31 import com.google.common.base.Predicates; 32 import com.google.common.collect.testing.IteratorTester; 33 34 import junit.framework.AssertionFailedError; 35 import junit.framework.TestCase; 36 37 import java.util.ArrayList; 38 import java.util.Collection; 39 import java.util.Collections; 40 import java.util.Iterator; 41 import java.util.List; 42 import java.util.NoSuchElementException; 43 import java.util.Queue; 44 import java.util.RandomAccess; 45 import java.util.Set; 46 import java.util.SortedSet; 47 import java.util.TreeSet; 48 49 /** 50 * Unit test for {@code Iterables}. 51 * 52 * @author Kevin Bourrillion 53 * @author Jared Levy 54 */ 55 @GwtCompatible(emulated = true) 56 public class IterablesTest extends TestCase { 57 58 public void testSize0() { 59 Iterable<String> iterable = Collections.emptySet(); 60 assertEquals(0, Iterables.size(iterable)); 61 } 62 63 public void testSize1Collection() { 64 Iterable<String> iterable = Collections.singleton("a"); 65 assertEquals(1, Iterables.size(iterable)); 66 } 67 68 public void testSize2NonCollection() { 69 Iterable<Integer> iterable = new Iterable<Integer>() { 70 @Override 71 public Iterator<Integer> iterator() { 72 return asList(0, 1).iterator(); 73 } 74 }; 75 assertEquals(2, Iterables.size(iterable)); 76 } 77 78 @SuppressWarnings("serial") 79 public void testSize_collection_doesntIterate() { 80 List<Integer> nums = asList(1, 2, 3, 4, 5); 81 List<Integer> collection = new ArrayList<Integer>(nums) { 82 @Override public Iterator<Integer> iterator() { 83 throw new AssertionFailedError("Don't iterate me!"); 84 } 85 }; 86 assertEquals(5, Iterables.size(collection)); 87 } 88 89 private static Iterable<String> iterable(String... elements) { 90 final List<String> list = asList(elements); 91 return new Iterable<String>() { 92 @Override 93 public Iterator<String> iterator() { 94 return list.iterator(); 95 } 96 }; 97 } 98 99 public void test_contains_null_set_yes() { 100 Iterable<String> set = Sets.newHashSet("a", null, "b"); 101 assertTrue(Iterables.contains(set, null)); 102 } 103 104 public void test_contains_null_set_no() { 105 Iterable<String> set = Sets.newHashSet("a", "b"); 106 assertFalse(Iterables.contains(set, null)); 107 } 108 109 public void test_contains_null_iterable_yes() { 110 Iterable<String> set = iterable("a", null, "b"); 111 assertTrue(Iterables.contains(set, null)); 112 } 113 114 public void test_contains_null_iterable_no() { 115 Iterable<String> set = iterable("a", "b"); 116 assertFalse(Iterables.contains(set, null)); 117 } 118 119 public void test_contains_nonnull_set_yes() { 120 Iterable<String> set = Sets.newHashSet("a", null, "b"); 121 assertTrue(Iterables.contains(set, "b")); 122 } 123 124 public void test_contains_nonnull_set_no() { 125 Iterable<String> set = Sets.newHashSet("a", "b"); 126 assertFalse(Iterables.contains(set, "c")); 127 } 128 129 public void test_contains_nonnull_iterable_yes() { 130 Iterable<String> set = iterable("a", null, "b"); 131 assertTrue(Iterables.contains(set, "b")); 132 } 133 134 public void test_contains_nonnull_iterable_no() { 135 Iterable<String> set = iterable("a", "b"); 136 assertFalse(Iterables.contains(set, "c")); 137 } 138 139 public void testGetOnlyElement_noDefault_valid() { 140 Iterable<String> iterable = Collections.singletonList("foo"); 141 assertEquals("foo", Iterables.getOnlyElement(iterable)); 142 } 143 144 public void testGetOnlyElement_noDefault_empty() { 145 Iterable<String> iterable = Collections.emptyList(); 146 try { 147 Iterables.getOnlyElement(iterable); 148 fail(); 149 } catch (NoSuchElementException expected) { 150 } 151 } 152 153 public void testGetOnlyElement_noDefault_multiple() { 154 Iterable<String> iterable = asList("foo", "bar"); 155 try { 156 Iterables.getOnlyElement(iterable); 157 fail(); 158 } catch (IllegalArgumentException expected) { 159 } 160 } 161 162 public void testGetOnlyElement_withDefault_singleton() { 163 Iterable<String> iterable = Collections.singletonList("foo"); 164 assertEquals("foo", Iterables.getOnlyElement(iterable, "bar")); 165 } 166 167 public void testGetOnlyElement_withDefault_empty() { 168 Iterable<String> iterable = Collections.emptyList(); 169 assertEquals("bar", Iterables.getOnlyElement(iterable, "bar")); 170 } 171 172 public void testGetOnlyElement_withDefault_empty_null() { 173 Iterable<String> iterable = Collections.emptyList(); 174 assertNull(Iterables.getOnlyElement(iterable, null)); 175 } 176 177 public void testGetOnlyElement_withDefault_multiple() { 178 Iterable<String> iterable = asList("foo", "bar"); 179 try { 180 Iterables.getOnlyElement(iterable, "x"); 181 fail(); 182 } catch (IllegalArgumentException expected) { 183 } 184 } 185 186 public void testAny() { 187 List<String> list = newArrayList(); 188 Predicate<String> predicate = Predicates.equalTo("pants"); 189 190 assertFalse(Iterables.any(list, predicate)); 191 list.add("cool"); 192 assertFalse(Iterables.any(list, predicate)); 193 list.add("pants"); 194 assertTrue(Iterables.any(list, predicate)); 195 } 196 197 public void testAll() { 198 List<String> list = newArrayList(); 199 Predicate<String> predicate = Predicates.equalTo("cool"); 200 201 assertTrue(Iterables.all(list, predicate)); 202 list.add("cool"); 203 assertTrue(Iterables.all(list, predicate)); 204 list.add("pants"); 205 assertFalse(Iterables.all(list, predicate)); 206 } 207 208 public void testFind() { 209 Iterable<String> list = newArrayList("cool", "pants"); 210 assertEquals("cool", Iterables.find(list, Predicates.equalTo("cool"))); 211 assertEquals("pants", Iterables.find(list, Predicates.equalTo("pants"))); 212 try { 213 Iterables.find(list, Predicates.alwaysFalse()); 214 fail(); 215 } catch (NoSuchElementException e) { 216 } 217 assertEquals("cool", Iterables.find(list, Predicates.alwaysTrue())); 218 assertCanIterateAgain(list); 219 } 220 221 public void testFind_withDefault() { 222 Iterable<String> list = Lists.newArrayList("cool", "pants"); 223 assertEquals("cool", 224 Iterables.find(list, Predicates.equalTo("cool"), "woot")); 225 assertEquals("pants", 226 Iterables.find(list, Predicates.equalTo("pants"), "woot")); 227 assertEquals("woot", Iterables.find(list, 228 Predicates.alwaysFalse(), "woot")); 229 assertNull(Iterables.find(list, Predicates.alwaysFalse(), null)); 230 assertEquals("cool", 231 Iterables.find(list, Predicates.alwaysTrue(), "woot")); 232 assertCanIterateAgain(list); 233 } 234 235 public void testTryFind() { 236 Iterable<String> list = newArrayList("cool", "pants"); 237 assertEquals(Optional.of("cool"), 238 Iterables.tryFind(list, Predicates.equalTo("cool"))); 239 assertEquals(Optional.of("pants"), 240 Iterables.tryFind(list, Predicates.equalTo("pants"))); 241 assertEquals(Optional.of("cool"), 242 Iterables.tryFind(list, Predicates.alwaysTrue())); 243 assertEquals(Optional.absent(), 244 Iterables.tryFind(list, Predicates.alwaysFalse())); 245 assertCanIterateAgain(list); 246 } 247 248 private static class TypeA {} 249 private interface TypeB {} 250 private static class HasBoth extends TypeA implements TypeB {} 251 252 public void testTransform() { 253 List<String> input = asList("1", "2", "3"); 254 Iterable<Integer> result = Iterables.transform(input, 255 new Function<String, Integer>() { 256 @Override 257 public Integer apply(String from) { 258 return Integer.valueOf(from); 259 } 260 }); 261 262 List<Integer> actual = newArrayList(result); 263 List<Integer> expected = asList(1, 2, 3); 264 assertEquals(expected, actual); 265 assertCanIterateAgain(result); 266 assertEquals("[1, 2, 3]", result.toString()); 267 } 268 269 public void testPoorlyBehavedTransform() { 270 List<String> input = asList("1", null, "3"); 271 Iterable<Integer> result = Iterables.transform(input, 272 new Function<String, Integer>() { 273 @Override 274 public Integer apply(String from) { 275 return Integer.valueOf(from); 276 } 277 }); 278 279 Iterator<Integer> resultIterator = result.iterator(); 280 resultIterator.next(); 281 282 try { 283 resultIterator.next(); 284 fail("Expected NFE"); 285 } catch (NumberFormatException nfe) { 286 // Expected to fail. 287 } 288 } 289 290 public void testNullFriendlyTransform() { 291 List<Integer> input = asList(1, 2, null, 3); 292 Iterable<String> result = Iterables.transform(input, 293 new Function<Integer, String>() { 294 @Override 295 public String apply(Integer from) { 296 return String.valueOf(from); 297 } 298 }); 299 300 List<String> actual = newArrayList(result); 301 List<String> expected = asList("1", "2", "null", "3"); 302 assertEquals(expected, actual); 303 } 304 305 // Far less exhaustive than the tests in IteratorsTest 306 public void testCycle() { 307 Iterable<String> cycle = Iterables.cycle("a", "b"); 308 309 int howManyChecked = 0; 310 for (String string : cycle) { 311 String expected = (howManyChecked % 2 == 0) ? "a" : "b"; 312 assertEquals(expected, string); 313 if (howManyChecked++ == 5) { 314 break; 315 } 316 } 317 318 // We left the last iterator pointing to "b". But a new iterator should 319 // always point to "a". 320 for (String string : cycle) { 321 assertEquals("a", string); 322 break; 323 } 324 325 assertEquals("[a, b] (cycled)", cycle.toString()); 326 } 327 328 // Again, the exhaustive tests are in IteratorsTest 329 public void testConcatIterable() { 330 List<Integer> list1 = newArrayList(1); 331 List<Integer> list2 = newArrayList(4); 332 333 @SuppressWarnings("unchecked") 334 List<List<Integer>> input = newArrayList(list1, list2); 335 336 Iterable<Integer> result = Iterables.concat(input); 337 assertEquals(asList(1, 4), newArrayList(result)); 338 339 // Now change the inputs and see result dynamically change as well 340 341 list1.add(2); 342 List<Integer> list3 = newArrayList(3); 343 input.add(1, list3); 344 345 assertEquals(asList(1, 2, 3, 4), newArrayList(result)); 346 assertEquals("[1, 2, 3, 4]", result.toString()); 347 } 348 349 public void testConcatVarargs() { 350 List<Integer> list1 = newArrayList(1); 351 List<Integer> list2 = newArrayList(4); 352 List<Integer> list3 = newArrayList(7, 8); 353 List<Integer> list4 = newArrayList(9); 354 List<Integer> list5 = newArrayList(10); 355 @SuppressWarnings("unchecked") 356 Iterable<Integer> result = 357 Iterables.concat(list1, list2, list3, list4, list5); 358 assertEquals(asList(1, 4, 7, 8, 9, 10), newArrayList(result)); 359 assertEquals("[1, 4, 7, 8, 9, 10]", result.toString()); 360 } 361 362 public void testConcatNullPointerException() { 363 List<Integer> list1 = newArrayList(1); 364 List<Integer> list2 = newArrayList(4); 365 366 try { 367 Iterables.concat(list1, null, list2); 368 fail(); 369 } catch (NullPointerException expected) {} 370 } 371 372 public void testConcatPeformingFiniteCycle() { 373 Iterable<Integer> iterable = asList(1, 2, 3); 374 int n = 4; 375 Iterable<Integer> repeated 376 = Iterables.concat(Collections.nCopies(n, iterable)); 377 assertThat(repeated).iteratesAs( 378 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3); 379 } 380 381 public void testPartition_badSize() { 382 Iterable<Integer> source = Collections.singleton(1); 383 try { 384 Iterables.partition(source, 0); 385 fail(); 386 } catch (IllegalArgumentException expected) { 387 } 388 } 389 390 public void testPartition_empty() { 391 Iterable<Integer> source = Collections.emptySet(); 392 Iterable<List<Integer>> partitions = Iterables.partition(source, 1); 393 assertTrue(Iterables.isEmpty(partitions)); 394 } 395 396 public void testPartition_singleton1() { 397 Iterable<Integer> source = Collections.singleton(1); 398 Iterable<List<Integer>> partitions = Iterables.partition(source, 1); 399 assertEquals(1, Iterables.size(partitions)); 400 assertEquals(Collections.singletonList(1), partitions.iterator().next()); 401 } 402 403 public void testPartition_view() { 404 List<Integer> list = asList(1, 2); 405 Iterable<List<Integer>> partitions = Iterables.partition(list, 2); 406 407 // Changes before the partition is retrieved are reflected 408 list.set(0, 3); 409 410 Iterator<List<Integer>> iterator = partitions.iterator(); 411 412 // Changes before the partition is retrieved are reflected 413 list.set(1, 4); 414 415 List<Integer> first = iterator.next(); 416 417 // Changes after are not 418 list.set(0, 5); 419 420 assertEquals(ImmutableList.of(3, 4), first); 421 } 422 423 public void testPaddedPartition_basic() { 424 List<Integer> list = asList(1, 2, 3, 4, 5); 425 Iterable<List<Integer>> partitions = Iterables.paddedPartition(list, 2); 426 assertEquals(3, Iterables.size(partitions)); 427 assertEquals(asList(5, null), Iterables.getLast(partitions)); 428 } 429 430 public void testPaddedPartitionRandomAccessInput() { 431 Iterable<Integer> source = asList(1, 2, 3); 432 Iterable<List<Integer>> partitions = Iterables.paddedPartition(source, 2); 433 Iterator<List<Integer>> iterator = partitions.iterator(); 434 assertTrue(iterator.next() instanceof RandomAccess); 435 assertTrue(iterator.next() instanceof RandomAccess); 436 } 437 438 public void testPaddedPartitionNonRandomAccessInput() { 439 Iterable<Integer> source = Lists.newLinkedList(asList(1, 2, 3)); 440 Iterable<List<Integer>> partitions = Iterables.paddedPartition(source, 2); 441 Iterator<List<Integer>> iterator = partitions.iterator(); 442 // Even though the input list doesn't implement RandomAccess, the output 443 // lists do. 444 assertTrue(iterator.next() instanceof RandomAccess); 445 assertTrue(iterator.next() instanceof RandomAccess); 446 } 447 448 // More tests in IteratorsTest 449 public void testAddAllToList() { 450 List<String> alreadyThere = newArrayList("already", "there"); 451 List<String> freshlyAdded = newArrayList("freshly", "added"); 452 453 boolean changed = Iterables.addAll(alreadyThere, freshlyAdded); 454 assertThat(alreadyThere).has().exactly( 455 "already", "there", "freshly", "added").inOrder(); 456 assertTrue(changed); 457 } 458 459 private static void assertCanIterateAgain(Iterable<?> iterable) { 460 for (@SuppressWarnings("unused") Object obj : iterable) { 461 } 462 } 463 464 // More exhaustive tests are in IteratorsTest. 465 public void testElementsEqual() throws Exception { 466 Iterable<?> a; 467 Iterable<?> b; 468 469 // A few elements. 470 a = asList(4, 8, 15, 16, 23, 42); 471 b = asList(4, 8, 15, 16, 23, 42); 472 assertTrue(Iterables.elementsEqual(a, b)); 473 474 // An element differs. 475 a = asList(4, 8, 15, 12, 23, 42); 476 b = asList(4, 8, 15, 16, 23, 42); 477 assertFalse(Iterables.elementsEqual(a, b)); 478 479 // null versus non-null. 480 a = asList(4, 8, 15, null, 23, 42); 481 b = asList(4, 8, 15, 16, 23, 42); 482 assertFalse(Iterables.elementsEqual(a, b)); 483 assertFalse(Iterables.elementsEqual(b, a)); 484 485 // Different lengths. 486 a = asList(4, 8, 15, 16, 23); 487 b = asList(4, 8, 15, 16, 23, 42); 488 assertFalse(Iterables.elementsEqual(a, b)); 489 assertFalse(Iterables.elementsEqual(b, a)); 490 } 491 492 public void testToString() { 493 List<String> list = Collections.emptyList(); 494 assertEquals("[]", Iterables.toString(list)); 495 496 list = newArrayList("yam", "bam", "jam", "ham"); 497 assertEquals("[yam, bam, jam, ham]", Iterables.toString(list)); 498 } 499 500 public void testLimit() { 501 Iterable<String> iterable = newArrayList("foo", "bar", "baz"); 502 Iterable<String> limited = Iterables.limit(iterable, 2); 503 504 List<String> expected = ImmutableList.of("foo", "bar"); 505 List<String> actual = newArrayList(limited); 506 assertEquals(expected, actual); 507 assertCanIterateAgain(limited); 508 assertEquals("[foo, bar]", limited.toString()); 509 } 510 511 public void testLimit_illegalArgument() { 512 List<String> list = newArrayList("a", "b", "c"); 513 try { 514 Iterables.limit(list, -1); 515 fail(); 516 } catch (IllegalArgumentException expected) {} 517 } 518 519 public void testIsEmpty() { 520 Iterable<String> emptyList = Collections.emptyList(); 521 assertTrue(Iterables.isEmpty(emptyList)); 522 523 Iterable<String> singletonList = Collections.singletonList("foo"); 524 assertFalse(Iterables.isEmpty(singletonList)); 525 } 526 527 public void testSkip_simple() { 528 Collection<String> set = ImmutableSet.of("a", "b", "c", "d", "e"); 529 assertEquals(newArrayList("c", "d", "e"), newArrayList(skip(set, 2))); 530 assertEquals("[c, d, e]", skip(set, 2).toString()); 531 } 532 533 public void testSkip_simpleList() { 534 Collection<String> list = newArrayList("a", "b", "c", "d", "e"); 535 assertEquals(newArrayList("c", "d", "e"), newArrayList(skip(list, 2))); 536 assertEquals("[c, d, e]", skip(list, 2).toString()); 537 } 538 539 public void testSkip_pastEnd() { 540 Collection<String> set = ImmutableSet.of("a", "b"); 541 assertEquals(emptyList(), newArrayList(skip(set, 20))); 542 } 543 544 public void testSkip_pastEndList() { 545 Collection<String> list = newArrayList("a", "b"); 546 assertEquals(emptyList(), newArrayList(skip(list, 20))); 547 } 548 549 public void testSkip_skipNone() { 550 Collection<String> set = ImmutableSet.of("a", "b"); 551 assertEquals(newArrayList("a", "b"), newArrayList(skip(set, 0))); 552 } 553 554 public void testSkip_skipNoneList() { 555 Collection<String> list = newArrayList("a", "b"); 556 assertEquals(newArrayList("a", "b"), newArrayList(skip(list, 0))); 557 } 558 559 public void testSkip_removal() { 560 Collection<String> set = Sets.newHashSet("a", "b"); 561 Iterator<String> iterator = skip(set, 2).iterator(); 562 try { 563 iterator.next(); 564 } catch (NoSuchElementException suppressed) { 565 // We want remove() to fail even after a failed call to next(). 566 } 567 try { 568 iterator.remove(); 569 fail("Expected IllegalStateException"); 570 } catch (IllegalStateException expected) {} 571 } 572 573 public void testSkip_allOfMutableList_modifiable() { 574 List<String> list = newArrayList("a", "b"); 575 Iterator<String> iterator = skip(list, 2).iterator(); 576 try { 577 iterator.remove(); 578 fail("Expected IllegalStateException"); 579 } catch (IllegalStateException expected) {} 580 } 581 582 public void testSkip_allOfImmutableList_modifiable() { 583 List<String> list = ImmutableList.of("a", "b"); 584 Iterator<String> iterator = skip(list, 2).iterator(); 585 try { 586 iterator.remove(); 587 fail("Expected UnsupportedOperationException"); 588 } catch (UnsupportedOperationException expected) {} 589 } 590 591 public void testSkip_nonStructurallyModifiedList() throws Exception { 592 List<String> list = newArrayList("a", "b", "c"); 593 Iterable<String> tail = skip(list, 1); 594 Iterator<String> tailIterator = tail.iterator(); 595 list.set(2, "C"); 596 assertEquals("b", tailIterator.next()); 597 assertEquals("C", tailIterator.next()); 598 assertFalse(tailIterator.hasNext()); 599 } 600 601 public void testSkip_structurallyModifiedSkipSome() throws Exception { 602 Collection<String> set = newLinkedHashSet(asList("a", "b", "c")); 603 Iterable<String> tail = skip(set, 1); 604 set.remove("b"); 605 set.addAll(newArrayList("A", "B", "C")); 606 assertThat(tail).iteratesAs("c", "A", "B", "C"); 607 } 608 609 public void testSkip_structurallyModifiedSkipSomeList() throws Exception { 610 List<String> list = newArrayList("a", "b", "c"); 611 Iterable<String> tail = skip(list, 1); 612 list.subList(1, 3).clear(); 613 list.addAll(0, newArrayList("A", "B", "C")); 614 assertThat(tail).iteratesAs("B", "C", "a"); 615 } 616 617 public void testSkip_structurallyModifiedSkipAll() throws Exception { 618 Collection<String> set = newLinkedHashSet(asList("a", "b", "c")); 619 Iterable<String> tail = skip(set, 2); 620 set.remove("a"); 621 set.remove("b"); 622 assertFalse(tail.iterator().hasNext()); 623 } 624 625 public void testSkip_structurallyModifiedSkipAllList() throws Exception { 626 List<String> list = newArrayList("a", "b", "c"); 627 Iterable<String> tail = skip(list, 2); 628 list.subList(0, 2).clear(); 629 assertTrue(Iterables.isEmpty(tail)); 630 } 631 632 public void testSkip_illegalArgument() { 633 List<String> list = newArrayList("a", "b", "c"); 634 try { 635 skip(list, -1); 636 fail(); 637 } catch (IllegalArgumentException expected) {} 638 } 639 640 private void testGetOnAbc(Iterable<String> iterable) { 641 try { 642 Iterables.get(iterable, -1); 643 fail(); 644 } catch (IndexOutOfBoundsException expected) {} 645 assertEquals("a", Iterables.get(iterable, 0)); 646 assertEquals("b", Iterables.get(iterable, 1)); 647 assertEquals("c", Iterables.get(iterable, 2)); 648 try { 649 Iterables.get(iterable, 3); 650 fail(); 651 } catch (IndexOutOfBoundsException nsee) {} 652 try { 653 Iterables.get(iterable, 4); 654 fail(); 655 } catch (IndexOutOfBoundsException nsee) {} 656 } 657 658 private void testGetOnEmpty(Iterable<String> iterable) { 659 try { 660 Iterables.get(iterable, 0); 661 fail(); 662 } catch (IndexOutOfBoundsException expected) {} 663 } 664 665 public void testGet_list() { 666 testGetOnAbc(newArrayList("a", "b", "c")); 667 } 668 669 public void testGet_emptyList() { 670 testGetOnEmpty(Collections.<String>emptyList()); 671 } 672 673 public void testGet_sortedSet() { 674 testGetOnAbc(ImmutableSortedSet.of("b", "c", "a")); 675 } 676 677 public void testGet_emptySortedSet() { 678 testGetOnEmpty(ImmutableSortedSet.<String>of()); 679 } 680 681 public void testGet_iterable() { 682 testGetOnAbc(ImmutableSet.of("a", "b", "c")); 683 } 684 685 public void testGet_emptyIterable() { 686 testGetOnEmpty(Sets.<String>newHashSet()); 687 } 688 689 public void testGet_withDefault_negativePosition() { 690 try { 691 Iterables.get(newArrayList("a", "b", "c"), -1, "d"); 692 fail(); 693 } catch (IndexOutOfBoundsException expected) { 694 // pass 695 } 696 } 697 698 public void testGet_withDefault_simple() { 699 ArrayList<String> list = newArrayList("a", "b", "c"); 700 assertEquals("b", Iterables.get(list, 1, "d")); 701 } 702 703 public void testGet_withDefault_iterable() { 704 Set<String> set = ImmutableSet.of("a", "b", "c"); 705 assertEquals("b", Iterables.get(set, 1, "d")); 706 } 707 708 public void testGet_withDefault_last() { 709 ArrayList<String> list = newArrayList("a", "b", "c"); 710 assertEquals("c", Iterables.get(list, 2, "d")); 711 } 712 713 public void testGet_withDefault_lastPlusOne() { 714 ArrayList<String> list = newArrayList("a", "b", "c"); 715 assertEquals("d", Iterables.get(list, 3, "d")); 716 } 717 718 public void testGet_withDefault_doesntIterate() { 719 List<String> list = new DiesOnIteratorArrayList(); 720 list.add("a"); 721 assertEquals("a", Iterables.get(list, 0, "b")); 722 } 723 724 public void testGetFirst_withDefault_singleton() { 725 Iterable<String> iterable = Collections.singletonList("foo"); 726 assertEquals("foo", Iterables.getFirst(iterable, "bar")); 727 } 728 729 public void testGetFirst_withDefault_empty() { 730 Iterable<String> iterable = Collections.emptyList(); 731 assertEquals("bar", Iterables.getFirst(iterable, "bar")); 732 } 733 734 public void testGetFirst_withDefault_empty_null() { 735 Iterable<String> iterable = Collections.emptyList(); 736 assertNull(Iterables.getFirst(iterable, null)); 737 } 738 739 public void testGetFirst_withDefault_multiple() { 740 Iterable<String> iterable = asList("foo", "bar"); 741 assertEquals("foo", Iterables.getFirst(iterable, "qux")); 742 } 743 744 public void testGetLast_list() { 745 List<String> list = newArrayList("a", "b", "c"); 746 assertEquals("c", Iterables.getLast(list)); 747 } 748 749 public void testGetLast_emptyList() { 750 List<String> list = Collections.emptyList(); 751 try { 752 Iterables.getLast(list); 753 fail(); 754 } catch (NoSuchElementException e) {} 755 } 756 757 public void testGetLast_sortedSet() { 758 SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a"); 759 assertEquals("c", Iterables.getLast(sortedSet)); 760 } 761 762 public void testGetLast_withDefault_singleton() { 763 Iterable<String> iterable = Collections.singletonList("foo"); 764 assertEquals("foo", Iterables.getLast(iterable, "bar")); 765 } 766 767 public void testGetLast_withDefault_empty() { 768 Iterable<String> iterable = Collections.emptyList(); 769 assertEquals("bar", Iterables.getLast(iterable, "bar")); 770 } 771 772 public void testGetLast_withDefault_empty_null() { 773 Iterable<String> iterable = Collections.emptyList(); 774 assertNull(Iterables.getLast(iterable, null)); 775 } 776 777 public void testGetLast_withDefault_multiple() { 778 Iterable<String> iterable = asList("foo", "bar"); 779 assertEquals("bar", Iterables.getLast(iterable, "qux")); 780 } 781 782 /** 783 * {@link ArrayList} extension that forbids the use of 784 * {@link Collection#iterator} for tests that need to prove that it isn't 785 * called. 786 */ 787 private static class DiesOnIteratorArrayList extends ArrayList<String> { 788 /** 789 * @throws UnsupportedOperationException all the time 790 */ 791 @Override 792 public Iterator<String> iterator() { 793 throw new UnsupportedOperationException(); 794 } 795 } 796 797 public void testGetLast_withDefault_not_empty_list() { 798 // TODO: verify that this is the best testing strategy. 799 List<String> diesOnIteratorList = new DiesOnIteratorArrayList(); 800 diesOnIteratorList.add("bar"); 801 802 assertEquals("bar", Iterables.getLast(diesOnIteratorList, "qux")); 803 } 804 805 /** 806 * {@link TreeSet} extension that forbids the use of 807 * {@link Collection#iterator} for tests that need to prove that it isn't 808 * called. 809 */ 810 private static final class DiesOnIteratorTreeSet extends TreeSet<String> { 811 /** 812 * @throws UnsupportedOperationException all the time 813 */ 814 @Override 815 public Iterator<String> iterator() { 816 throw new UnsupportedOperationException(); 817 } 818 } 819 820 public void testGetLast_emptySortedSet() { 821 SortedSet<String> sortedSet = ImmutableSortedSet.of(); 822 try { 823 Iterables.getLast(sortedSet); 824 fail(); 825 } catch (NoSuchElementException e) {} 826 } 827 828 public void testGetLast_iterable() { 829 Set<String> set = ImmutableSet.of("a", "b", "c"); 830 assertEquals("c", Iterables.getLast(set)); 831 } 832 833 public void testGetLast_emptyIterable() { 834 Set<String> set = Sets.newHashSet(); 835 try { 836 Iterables.getLast(set); 837 fail(); 838 } catch (NoSuchElementException e) {} 839 } 840 841 public void testUnmodifiableIterable() { 842 List<String> list = newArrayList("a", "b", "c"); 843 Iterable<String> iterable = Iterables.unmodifiableIterable(list); 844 Iterator<String> iterator = iterable.iterator(); 845 iterator.next(); 846 try { 847 iterator.remove(); 848 fail(); 849 } catch (UnsupportedOperationException expected) {} 850 assertEquals("[a, b, c]", iterable.toString()); 851 } 852 853 @SuppressWarnings("deprecation") // test of deprecated method 854 public void testUnmodifiableIterableShortCircuit() { 855 List<String> list = newArrayList("a", "b", "c"); 856 Iterable<String> iterable = Iterables.unmodifiableIterable(list); 857 Iterable<String> iterable2 = Iterables.unmodifiableIterable(iterable); 858 assertSame(iterable, iterable2); 859 ImmutableList<String> immutableList = ImmutableList.of("a", "b", "c"); 860 assertSame(immutableList, Iterables.unmodifiableIterable(immutableList)); 861 assertSame(immutableList, 862 Iterables.unmodifiableIterable((List<String>) immutableList)); 863 } 864 865 public void testFrequency_multiset() { 866 Multiset<String> multiset 867 = ImmutableMultiset.of("a", "b", "a", "c", "b", "a"); 868 assertEquals(3, Iterables.frequency(multiset, "a")); 869 assertEquals(2, Iterables.frequency(multiset, "b")); 870 assertEquals(1, Iterables.frequency(multiset, "c")); 871 assertEquals(0, Iterables.frequency(multiset, "d")); 872 assertEquals(0, Iterables.frequency(multiset, 4.2)); 873 assertEquals(0, Iterables.frequency(multiset, null)); 874 } 875 876 public void testFrequency_set() { 877 Set<String> set = Sets.newHashSet("a", "b", "c"); 878 assertEquals(1, Iterables.frequency(set, "a")); 879 assertEquals(1, Iterables.frequency(set, "b")); 880 assertEquals(1, Iterables.frequency(set, "c")); 881 assertEquals(0, Iterables.frequency(set, "d")); 882 assertEquals(0, Iterables.frequency(set, 4.2)); 883 assertEquals(0, Iterables.frequency(set, null)); 884 } 885 886 public void testFrequency_list() { 887 List<String> list = newArrayList("a", "b", "a", "c", "b", "a"); 888 assertEquals(3, Iterables.frequency(list, "a")); 889 assertEquals(2, Iterables.frequency(list, "b")); 890 assertEquals(1, Iterables.frequency(list, "c")); 891 assertEquals(0, Iterables.frequency(list, "d")); 892 assertEquals(0, Iterables.frequency(list, 4.2)); 893 assertEquals(0, Iterables.frequency(list, null)); 894 } 895 896 public void testRemoveAll_collection() { 897 List<String> list = newArrayList("a", "b", "c", "d", "e"); 898 assertTrue(Iterables.removeAll(list, newArrayList("b", "d", "f"))); 899 assertEquals(newArrayList("a", "c", "e"), list); 900 assertFalse(Iterables.removeAll(list, newArrayList("x", "y", "z"))); 901 assertEquals(newArrayList("a", "c", "e"), list); 902 } 903 904 public void testRemoveAll_iterable() { 905 final List<String> list = newArrayList("a", "b", "c", "d", "e"); 906 Iterable<String> iterable = new Iterable<String>() { 907 @Override 908 public Iterator<String> iterator() { 909 return list.iterator(); 910 } 911 }; 912 assertTrue(Iterables.removeAll(iterable, newArrayList("b", "d", "f"))); 913 assertEquals(newArrayList("a", "c", "e"), list); 914 assertFalse(Iterables.removeAll(iterable, newArrayList("x", "y", "z"))); 915 assertEquals(newArrayList("a", "c", "e"), list); 916 } 917 918 public void testRetainAll_collection() { 919 List<String> list = newArrayList("a", "b", "c", "d", "e"); 920 assertTrue(Iterables.retainAll(list, newArrayList("b", "d", "f"))); 921 assertEquals(newArrayList("b", "d"), list); 922 assertFalse(Iterables.retainAll(list, newArrayList("b", "e", "d"))); 923 assertEquals(newArrayList("b", "d"), list); 924 } 925 926 public void testRetainAll_iterable() { 927 final List<String> list = newArrayList("a", "b", "c", "d", "e"); 928 Iterable<String> iterable = new Iterable<String>() { 929 @Override 930 public Iterator<String> iterator() { 931 return list.iterator(); 932 } 933 }; 934 assertTrue(Iterables.retainAll(iterable, newArrayList("b", "d", "f"))); 935 assertEquals(newArrayList("b", "d"), list); 936 assertFalse(Iterables.retainAll(iterable, newArrayList("b", "e", "d"))); 937 assertEquals(newArrayList("b", "d"), list); 938 } 939 940 public void testRemoveIf_randomAccess() { 941 List<String> list = newArrayList("a", "b", "c", "d", "e"); 942 assertTrue(Iterables.removeIf(list, 943 new Predicate<String>() { 944 @Override 945 public boolean apply(String s) { 946 return s.equals("b") || s.equals("d") || s.equals("f"); 947 } 948 })); 949 assertEquals(newArrayList("a", "c", "e"), list); 950 assertFalse(Iterables.removeIf(list, 951 new Predicate<String>() { 952 @Override 953 public boolean apply(String s) { 954 return s.equals("x") || s.equals("y") || s.equals("z"); 955 } 956 })); 957 assertEquals(newArrayList("a", "c", "e"), list); 958 } 959 960 public void testRemoveIf_transformedList() { 961 List<String> list = newArrayList("1", "2", "3", "4", "5"); 962 List<Integer> transformed = Lists.transform(list, 963 new Function<String, Integer>() { 964 @Override 965 public Integer apply(String s) { 966 return Integer.valueOf(s); 967 } 968 }); 969 assertTrue(Iterables.removeIf(transformed, 970 new Predicate<Integer>() { 971 @Override 972 public boolean apply(Integer n) { 973 return (n & 1) == 0; // isEven() 974 } 975 })); 976 assertEquals(newArrayList("1", "3", "5"), list); 977 assertFalse(Iterables.removeIf(transformed, 978 new Predicate<Integer>() { 979 @Override 980 public boolean apply(Integer n) { 981 return (n & 1) == 0; // isEven() 982 } 983 })); 984 assertEquals(newArrayList("1", "3", "5"), list); 985 } 986 987 public void testRemoveIf_noRandomAccess() { 988 List<String> list = Lists.newLinkedList(asList("a", "b", "c", "d", "e")); 989 assertTrue(Iterables.removeIf(list, 990 new Predicate<String>() { 991 @Override 992 public boolean apply(String s) { 993 return s.equals("b") || s.equals("d") || s.equals("f"); 994 } 995 })); 996 assertEquals(newArrayList("a", "c", "e"), list); 997 assertFalse(Iterables.removeIf(list, 998 new Predicate<String>() { 999 @Override 1000 public boolean apply(String s) { 1001 return s.equals("x") || s.equals("y") || s.equals("z"); 1002 } 1003 })); 1004 assertEquals(newArrayList("a", "c", "e"), list); 1005 } 1006 1007 // The Maps returned by Maps.filterEntries(), Maps.filterKeys(), and 1008 // Maps.filterValues() are not tested with removeIf() since Maps are not 1009 // Iterable. Those returned by Iterators.filter() and Iterables.filter() 1010 // are not tested because they are unmodifiable. 1011 1012 public void testIterableWithToString() { 1013 assertEquals("[]", create().toString()); 1014 assertEquals("[a]", create("a").toString()); 1015 assertEquals("[a, b, c]", create("a", "b", "c").toString()); 1016 assertEquals("[c, a, a]", create("c", "a", "a").toString()); 1017 } 1018 1019 public void testIterableWithToStringNull() { 1020 assertEquals("[null]", create((String) null).toString()); 1021 assertEquals("[null, null]", create(null, null).toString()); 1022 assertEquals("[, null, a]", create("", null, "a").toString()); 1023 } 1024 1025 /** Returns a new iterable over the specified strings. */ 1026 private static Iterable<String> create(String... strings) { 1027 final List<String> list = asList(strings); 1028 return new FluentIterable<String>() { 1029 @Override 1030 public Iterator<String> iterator() { 1031 return list.iterator(); 1032 } 1033 }; 1034 } 1035 1036 public void testConsumingIterable() { 1037 // Test data 1038 List<String> list = Lists.newArrayList(asList("a", "b")); 1039 1040 // Test & Verify 1041 Iterable<String> consumingIterable = Iterables.consumingIterable(list); 1042 assertEquals("Iterables.consumingIterable(...)", consumingIterable.toString()); 1043 Iterator<String> consumingIterator = consumingIterable.iterator(); 1044 1045 assertThat(list).has().exactly("a", "b").inOrder(); 1046 1047 assertTrue(consumingIterator.hasNext()); 1048 assertThat(list).has().exactly("a", "b").inOrder(); 1049 assertEquals("a", consumingIterator.next()); 1050 assertThat(list).has().item("b"); 1051 1052 assertTrue(consumingIterator.hasNext()); 1053 assertEquals("b", consumingIterator.next()); 1054 assertThat(list).isEmpty(); 1055 1056 assertFalse(consumingIterator.hasNext()); 1057 } 1058 1059 public void testConsumingIterable_queue_iterator() { 1060 final List<Integer> items = ImmutableList.of(4, 8, 15, 16, 23, 42); 1061 new IteratorTester<Integer>( 1062 3, 1063 UNMODIFIABLE, 1064 items, 1065 IteratorTester.KnownOrder.KNOWN_ORDER) { 1066 @Override protected Iterator<Integer> newTargetIterator() { 1067 return Iterables.consumingIterable(Lists.newLinkedList(items)) 1068 .iterator(); 1069 } 1070 }.test(); 1071 } 1072 1073 public void testConsumingIterable_queue_removesFromQueue() { 1074 Queue<Integer> queue = Lists.newLinkedList(asList(5, 14)); 1075 1076 Iterator<Integer> consumingIterator = 1077 Iterables.consumingIterable(queue).iterator(); 1078 1079 assertEquals(5, queue.peek().intValue()); 1080 assertEquals(5, consumingIterator.next().intValue()); 1081 1082 assertEquals(14, queue.peek().intValue()); 1083 assertTrue(consumingIterator.hasNext()); 1084 assertTrue(queue.isEmpty()); 1085 } 1086 1087 public void testConsumingIterable_noIteratorCall() { 1088 Queue<Integer> queue = 1089 new UnIterableQueue<Integer>(Lists.newLinkedList(asList(5, 14))); 1090 1091 Iterator<Integer> consumingIterator = 1092 Iterables.consumingIterable(queue).iterator(); 1093 /* 1094 * Make sure that we can get an element off without calling 1095 * UnIterableQueue.iterator(). 1096 */ 1097 assertEquals(5, consumingIterator.next().intValue()); 1098 } 1099 1100 private static class UnIterableQueue<T> extends ForwardingQueue<T> { 1101 private Queue<T> queue; 1102 1103 UnIterableQueue(Queue<T> queue) { 1104 this.queue = queue; 1105 } 1106 1107 @Override public Iterator<T> iterator() { 1108 throw new UnsupportedOperationException(); 1109 } 1110 1111 @Override protected Queue<T> delegate() { 1112 return queue; 1113 } 1114 } 1115 1116 public void testIndexOf_empty() { 1117 List<String> list = new ArrayList<String>(); 1118 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo(""))); 1119 } 1120 1121 public void testIndexOf_oneElement() { 1122 List<String> list = Lists.newArrayList("bob"); 1123 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("bob"))); 1124 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack"))); 1125 } 1126 1127 public void testIndexOf_twoElements() { 1128 List<String> list = Lists.newArrayList("mary", "bob"); 1129 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("mary"))); 1130 assertEquals(1, Iterables.indexOf(list, Predicates.equalTo("bob"))); 1131 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack"))); 1132 } 1133 1134 public void testIndexOf_withDuplicates() { 1135 List<String> list = 1136 Lists.newArrayList("mary", "bob", "bob", "bob", "sam"); 1137 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("mary"))); 1138 assertEquals(1, Iterables.indexOf(list, Predicates.equalTo("bob"))); 1139 assertEquals(4, Iterables.indexOf(list, Predicates.equalTo("sam"))); 1140 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack"))); 1141 } 1142 1143 private static final Predicate<CharSequence> STARTSWITH_A = 1144 new Predicate<CharSequence>() { 1145 @Override public boolean apply(CharSequence input) { 1146 return (input.length() > 0) && (input.charAt(0) == 'a'); 1147 } 1148 }; 1149 1150 public void testIndexOf_genericPredicate() { 1151 List<CharSequence> sequences = Lists.newArrayList(); 1152 sequences.add("bob"); 1153 sequences.add(new StringBuilder("charlie")); 1154 sequences.add(new StringBuffer("henry")); 1155 sequences.add(new StringBuilder("apple")); 1156 sequences.add("lemon"); 1157 1158 assertEquals(3, Iterables.indexOf(sequences, STARTSWITH_A)); 1159 } 1160 1161 public void testIndexOf_genericPredicate2() { 1162 List<String> sequences = 1163 Lists.newArrayList("bob", "charlie", "henry", "apple", "lemon"); 1164 assertEquals(3, Iterables.indexOf(sequences, STARTSWITH_A)); 1165 } 1166 1167 public void testMergeSorted_empty() { 1168 // Setup 1169 Iterable<Iterable<Integer>> elements = ImmutableList.of(); 1170 1171 // Test 1172 Iterable<Integer> iterable = 1173 Iterables.mergeSorted(elements, Ordering.natural()); 1174 1175 // Verify 1176 Iterator<Integer> iterator = iterable.iterator(); 1177 assertFalse(iterator.hasNext()); 1178 try { 1179 iterator.next(); 1180 fail("next() on empty iterator should throw NoSuchElementException"); 1181 } catch (NoSuchElementException e) { 1182 // Huzzah! 1183 } 1184 } 1185 1186 public void testMergeSorted_single_empty() { 1187 // Setup 1188 Iterable<Integer> iterable0 = ImmutableList.of(); 1189 Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0); 1190 1191 // Test & Verify 1192 verifyMergeSorted(iterables, ImmutableList.<Integer>of()); 1193 } 1194 1195 public void testMergeSorted_single() { 1196 // Setup 1197 Iterable<Integer> iterable0 = ImmutableList.of(1, 2, 3); 1198 Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0); 1199 1200 // Test & Verify 1201 verifyMergeSorted(iterables, iterable0); 1202 } 1203 1204 public void testMergeSorted_pyramid() { 1205 List<Iterable<Integer>> iterables = Lists.newLinkedList(); 1206 List<Integer> allIntegers = Lists.newArrayList(); 1207 1208 // Creates iterators like: {{}, {0}, {0, 1}, {0, 1, 2}, ...} 1209 for (int i = 0; i < 10; i++) { 1210 List<Integer> list = Lists.newLinkedList(); 1211 for (int j = 0; j < i; j++) { 1212 list.add(j); 1213 allIntegers.add(j); 1214 } 1215 iterables.add(Ordering.natural().sortedCopy(list)); 1216 } 1217 1218 verifyMergeSorted(iterables, allIntegers); 1219 } 1220 1221 // Like the pyramid, but creates more unique values, along with repeated ones. 1222 public void testMergeSorted_skipping_pyramid() { 1223 List<Iterable<Integer>> iterables = Lists.newLinkedList(); 1224 List<Integer> allIntegers = Lists.newArrayList(); 1225 1226 for (int i = 0; i < 20; i++) { 1227 List<Integer> list = Lists.newLinkedList(); 1228 for (int j = 0; j < i; j++) { 1229 list.add(j * i); 1230 allIntegers.add(j * i); 1231 } 1232 iterables.add(Ordering.natural().sortedCopy(list)); 1233 } 1234 1235 verifyMergeSorted(iterables, allIntegers); 1236 } 1237 1238 private static void verifyMergeSorted(Iterable<Iterable<Integer>> iterables, 1239 Iterable<Integer> unsortedExpected) { 1240 Iterable<Integer> expected = 1241 Ordering.natural().sortedCopy(unsortedExpected); 1242 1243 Iterable<Integer> mergedIterator = 1244 Iterables.mergeSorted(iterables, Ordering.natural()); 1245 1246 assertEquals(Lists.newLinkedList(expected), 1247 Lists.newLinkedList(mergedIterator)); 1248 } 1249 } 1250