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.Lists.newArrayList; 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.base.Function; 26 import com.google.common.base.Functions; 27 import com.google.common.base.Joiner; 28 import com.google.common.base.Predicate; 29 import com.google.common.base.Predicates; 30 import com.google.common.collect.testing.IteratorFeature; 31 import com.google.common.collect.testing.IteratorTester; 32 import com.google.common.testing.NullPointerTester; 33 import java.util.ArrayList; 34 import java.util.Collection; 35 import java.util.Collections; 36 import java.util.Iterator; 37 import java.util.List; 38 import java.util.Set; 39 import java.util.SortedSet; 40 import java.util.concurrent.TimeUnit; 41 import junit.framework.AssertionFailedError; 42 import junit.framework.TestCase; 43 import org.checkerframework.checker.nullness.qual.Nullable; 44 45 /** 46 * Unit test for {@link FluentIterable}. 47 * 48 * @author Marcin Mikosik 49 */ 50 @GwtCompatible(emulated = true) 51 public class FluentIterableTest extends TestCase { 52 53 @GwtIncompatible // NullPointerTester testNullPointerExceptions()54 public void testNullPointerExceptions() { 55 NullPointerTester tester = new NullPointerTester(); 56 tester.testAllPublicStaticMethods(FluentIterable.class); 57 } 58 testFromArrayAndAppend()59 public void testFromArrayAndAppend() { 60 FluentIterable<TimeUnit> unused = 61 FluentIterable.from(TimeUnit.values()).append(TimeUnit.SECONDS); 62 } 63 testFromArrayAndIteratorRemove()64 public void testFromArrayAndIteratorRemove() { 65 FluentIterable<TimeUnit> units = FluentIterable.from(TimeUnit.values()); 66 try { 67 Iterables.removeIf(units, Predicates.equalTo(TimeUnit.SECONDS)); 68 fail("Expected an UnsupportedOperationException to be thrown but it wasn't."); 69 } catch (UnsupportedOperationException expected) { 70 } 71 } 72 testFrom()73 public void testFrom() { 74 assertEquals( 75 ImmutableList.of(1, 2, 3, 4), 76 Lists.newArrayList(FluentIterable.from(ImmutableList.of(1, 2, 3, 4)))); 77 } 78 79 @SuppressWarnings("deprecation") // test of deprecated method testFrom_alreadyFluentIterable()80 public void testFrom_alreadyFluentIterable() { 81 FluentIterable<Integer> iterable = FluentIterable.from(asList(1)); 82 assertSame(iterable, FluentIterable.from(iterable)); 83 } 84 testOf()85 public void testOf() { 86 assertEquals(ImmutableList.of(1, 2, 3, 4), Lists.newArrayList(FluentIterable.of(1, 2, 3, 4))); 87 } 88 testFromArray()89 public void testFromArray() { 90 assertEquals( 91 ImmutableList.of("1", "2", "3", "4"), 92 Lists.newArrayList(FluentIterable.from(new Object[] {"1", "2", "3", "4"}))); 93 } 94 testOf_empty()95 public void testOf_empty() { 96 assertEquals(ImmutableList.of(), Lists.newArrayList(FluentIterable.of())); 97 } 98 99 // Exhaustive tests are in IteratorsTest. These are copied from IterablesTest. testConcatIterable()100 public void testConcatIterable() { 101 List<Integer> list1 = newArrayList(1); 102 List<Integer> list2 = newArrayList(4); 103 104 List<List<Integer>> input = newArrayList(list1, list2); 105 106 FluentIterable<Integer> result = FluentIterable.concat(input); 107 assertEquals(asList(1, 4), newArrayList(result)); 108 109 // Now change the inputs and see result dynamically change as well 110 111 list1.add(2); 112 List<Integer> list3 = newArrayList(3); 113 input.add(1, list3); 114 115 assertEquals(asList(1, 2, 3, 4), newArrayList(result)); 116 assertEquals("[1, 2, 3, 4]", result.toString()); 117 } 118 testConcatVarargs()119 public void testConcatVarargs() { 120 List<Integer> list1 = newArrayList(1); 121 List<Integer> list2 = newArrayList(4); 122 List<Integer> list3 = newArrayList(7, 8); 123 List<Integer> list4 = newArrayList(9); 124 List<Integer> list5 = newArrayList(10); 125 FluentIterable<Integer> result = FluentIterable.concat(list1, list2, list3, list4, list5); 126 assertEquals(asList(1, 4, 7, 8, 9, 10), newArrayList(result)); 127 assertEquals("[1, 4, 7, 8, 9, 10]", result.toString()); 128 } 129 testConcatNullPointerException()130 public void testConcatNullPointerException() { 131 List<Integer> list1 = newArrayList(1); 132 List<Integer> list2 = newArrayList(4); 133 134 try { 135 FluentIterable.concat(list1, null, list2); 136 fail(); 137 } catch (NullPointerException expected) { 138 } 139 } 140 testConcatPeformingFiniteCycle()141 public void testConcatPeformingFiniteCycle() { 142 Iterable<Integer> iterable = asList(1, 2, 3); 143 int n = 4; 144 FluentIterable<Integer> repeated = FluentIterable.concat(Collections.nCopies(n, iterable)); 145 assertThat(repeated).containsExactly(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3).inOrder(); 146 } 147 148 interface X {} 149 150 interface Y {} 151 152 static class A implements X, Y {} 153 154 static class B implements X, Y {} 155 156 /** 157 * This test passes if the {@code concat(…).filter(…).filter(…)} statement at the end compiles. 158 * That statement compiles only if {@link FluentIterable#concat concat(aIterable, bIterable)} 159 * returns a {@link FluentIterable} of elements of an anonymous type whose supertypes are the <a 160 * href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.9">intersection</a> of 161 * the supertypes of {@code A} and the supertypes of {@code B}. 162 */ testConcatIntersectionType()163 public void testConcatIntersectionType() { 164 Iterable<A> aIterable = ImmutableList.of(); 165 Iterable<B> bIterable = ImmutableList.of(); 166 167 Predicate<X> xPredicate = Predicates.alwaysTrue(); 168 Predicate<Y> yPredicate = Predicates.alwaysTrue(); 169 170 FluentIterable<?> unused = 171 FluentIterable.concat(aIterable, bIterable).filter(xPredicate).filter(yPredicate); 172 173 /* The following fails to compile: 174 * 175 * The method append(Iterable<? extends FluentIterableTest.A>) in the type 176 * FluentIterable<FluentIterableTest.A> is not applicable for the arguments 177 * (Iterable<FluentIterableTest.B>) 178 */ 179 // FluentIterable.from(aIterable).append(bIterable); 180 181 /* The following fails to compile: 182 * 183 * The method filter(Predicate<? super Object>) in the type FluentIterable<Object> is not 184 * applicable for the arguments (Predicate<FluentIterableTest.X>) 185 */ 186 // FluentIterable.of().append(aIterable).append(bIterable).filter(xPredicate); 187 } 188 testSize0()189 public void testSize0() { 190 assertEquals(0, FluentIterable.<String>of().size()); 191 } 192 testSize1Collection()193 public void testSize1Collection() { 194 assertEquals(1, FluentIterable.from(asList("a")).size()); 195 } 196 testSize2NonCollection()197 public void testSize2NonCollection() { 198 Iterable<Integer> iterable = 199 new Iterable<Integer>() { 200 @Override 201 public Iterator<Integer> iterator() { 202 return asList(0, 1).iterator(); 203 } 204 }; 205 assertEquals(2, FluentIterable.from(iterable).size()); 206 } 207 testSize_collectionDoesntIterate()208 public void testSize_collectionDoesntIterate() { 209 List<Integer> nums = asList(1, 2, 3, 4, 5); 210 List<Integer> collection = 211 new ArrayList<Integer>(nums) { 212 @Override 213 public Iterator<Integer> iterator() { 214 throw new AssertionFailedError("Don't iterate me!"); 215 } 216 }; 217 assertEquals(5, FluentIterable.from(collection).size()); 218 } 219 testContains_nullSetYes()220 public void testContains_nullSetYes() { 221 Iterable<String> set = Sets.newHashSet("a", null, "b"); 222 assertTrue(FluentIterable.from(set).contains(null)); 223 } 224 testContains_nullSetNo()225 public void testContains_nullSetNo() { 226 Iterable<String> set = ImmutableSortedSet.of("a", "b"); 227 assertFalse(FluentIterable.from(set).contains(null)); 228 } 229 testContains_nullIterableYes()230 public void testContains_nullIterableYes() { 231 Iterable<String> iterable = iterable("a", null, "b"); 232 assertTrue(FluentIterable.from(iterable).contains(null)); 233 } 234 testContains_nullIterableNo()235 public void testContains_nullIterableNo() { 236 Iterable<String> iterable = iterable("a", "b"); 237 assertFalse(FluentIterable.from(iterable).contains(null)); 238 } 239 testContains_nonNullSetYes()240 public void testContains_nonNullSetYes() { 241 Iterable<String> set = Sets.newHashSet("a", null, "b"); 242 assertTrue(FluentIterable.from(set).contains("b")); 243 } 244 testContains_nonNullSetNo()245 public void testContains_nonNullSetNo() { 246 Iterable<String> set = Sets.newHashSet("a", "b"); 247 assertFalse(FluentIterable.from(set).contains("c")); 248 } 249 testContains_nonNullIterableYes()250 public void testContains_nonNullIterableYes() { 251 Iterable<String> set = iterable("a", null, "b"); 252 assertTrue(FluentIterable.from(set).contains("b")); 253 } 254 testContains_nonNullIterableNo()255 public void testContains_nonNullIterableNo() { 256 Iterable<String> iterable = iterable("a", "b"); 257 assertFalse(FluentIterable.from(iterable).contains("c")); 258 } 259 testOfToString()260 public void testOfToString() { 261 assertEquals("[yam, bam, jam, ham]", FluentIterable.of("yam", "bam", "jam", "ham").toString()); 262 } 263 testToString()264 public void testToString() { 265 assertEquals("[]", FluentIterable.from(Collections.emptyList()).toString()); 266 assertEquals("[]", FluentIterable.<String>of().toString()); 267 268 assertEquals( 269 "[yam, bam, jam, ham]", FluentIterable.from(asList("yam", "bam", "jam", "ham")).toString()); 270 } 271 testCycle()272 public void testCycle() { 273 FluentIterable<String> cycle = FluentIterable.from(asList("a", "b")).cycle(); 274 275 int howManyChecked = 0; 276 for (String string : cycle) { 277 String expected = (howManyChecked % 2 == 0) ? "a" : "b"; 278 assertEquals(expected, string); 279 if (howManyChecked++ == 5) { 280 break; 281 } 282 } 283 284 // We left the last iterator pointing to "b". But a new iterator should 285 // always point to "a". 286 assertEquals("a", cycle.iterator().next()); 287 } 288 testCycle_emptyIterable()289 public void testCycle_emptyIterable() { 290 FluentIterable<Integer> cycle = FluentIterable.<Integer>of().cycle(); 291 assertFalse(cycle.iterator().hasNext()); 292 } 293 testCycle_removingAllElementsStopsCycle()294 public void testCycle_removingAllElementsStopsCycle() { 295 FluentIterable<Integer> cycle = fluent(1, 2).cycle(); 296 Iterator<Integer> iterator = cycle.iterator(); 297 iterator.next(); 298 iterator.remove(); 299 iterator.next(); 300 iterator.remove(); 301 assertFalse(iterator.hasNext()); 302 assertFalse(cycle.iterator().hasNext()); 303 } 304 testAppend()305 public void testAppend() { 306 FluentIterable<Integer> result = 307 FluentIterable.<Integer>from(asList(1, 2, 3)).append(Lists.newArrayList(4, 5, 6)); 308 assertEquals(asList(1, 2, 3, 4, 5, 6), Lists.newArrayList(result)); 309 assertEquals("[1, 2, 3, 4, 5, 6]", result.toString()); 310 311 result = FluentIterable.<Integer>from(asList(1, 2, 3)).append(4, 5, 6); 312 assertEquals(asList(1, 2, 3, 4, 5, 6), Lists.newArrayList(result)); 313 assertEquals("[1, 2, 3, 4, 5, 6]", result.toString()); 314 } 315 testAppend_toEmpty()316 public void testAppend_toEmpty() { 317 FluentIterable<Integer> result = 318 FluentIterable.<Integer>of().append(Lists.newArrayList(1, 2, 3)); 319 assertEquals(asList(1, 2, 3), Lists.newArrayList(result)); 320 } 321 testAppend_emptyList()322 public void testAppend_emptyList() { 323 FluentIterable<Integer> result = 324 FluentIterable.<Integer>from(asList(1, 2, 3)).append(Lists.<Integer>newArrayList()); 325 assertEquals(asList(1, 2, 3), Lists.newArrayList(result)); 326 } 327 testAppend_nullPointerException()328 public void testAppend_nullPointerException() { 329 try { 330 FluentIterable<Integer> unused = 331 FluentIterable.<Integer>from(asList(1, 2)).append((List<Integer>) null); 332 fail("Appending null iterable should throw NPE."); 333 } catch (NullPointerException expected) { 334 } 335 } 336 337 /* 338 * Tests for partition(int size) method. 339 */ 340 341 /* 342 * Tests for partitionWithPadding(int size) method. 343 */ 344 testFilter()345 public void testFilter() { 346 FluentIterable<String> filtered = 347 FluentIterable.from(asList("foo", "bar")).filter(Predicates.equalTo("foo")); 348 349 List<String> expected = Collections.singletonList("foo"); 350 List<String> actual = Lists.newArrayList(filtered); 351 assertEquals(expected, actual); 352 assertCanIterateAgain(filtered); 353 assertEquals("[foo]", filtered.toString()); 354 } 355 356 private static class TypeA {} 357 358 private interface TypeB {} 359 360 private static class HasBoth extends TypeA implements TypeB {} 361 362 @GwtIncompatible // Iterables.filter(Iterable, Class) testFilterByType()363 public void testFilterByType() throws Exception { 364 HasBoth hasBoth = new HasBoth(); 365 FluentIterable<TypeA> alist = 366 FluentIterable.from(asList(new TypeA(), new TypeA(), hasBoth, new TypeA())); 367 Iterable<TypeB> blist = alist.filter(TypeB.class); 368 assertThat(blist).containsExactly(hasBoth).inOrder(); 369 } 370 testAnyMatch()371 public void testAnyMatch() { 372 ArrayList<String> list = Lists.newArrayList(); 373 FluentIterable<String> iterable = FluentIterable.<String>from(list); 374 Predicate<String> predicate = Predicates.equalTo("pants"); 375 376 assertFalse(iterable.anyMatch(predicate)); 377 list.add("cool"); 378 assertFalse(iterable.anyMatch(predicate)); 379 list.add("pants"); 380 assertTrue(iterable.anyMatch(predicate)); 381 } 382 testAllMatch()383 public void testAllMatch() { 384 List<String> list = Lists.newArrayList(); 385 FluentIterable<String> iterable = FluentIterable.<String>from(list); 386 Predicate<String> predicate = Predicates.equalTo("cool"); 387 388 assertTrue(iterable.allMatch(predicate)); 389 list.add("cool"); 390 assertTrue(iterable.allMatch(predicate)); 391 list.add("pants"); 392 assertFalse(iterable.allMatch(predicate)); 393 } 394 testFirstMatch()395 public void testFirstMatch() { 396 FluentIterable<String> iterable = FluentIterable.from(Lists.newArrayList("cool", "pants")); 397 assertThat(iterable.firstMatch(Predicates.equalTo("cool"))).hasValue("cool"); 398 assertThat(iterable.firstMatch(Predicates.equalTo("pants"))).hasValue("pants"); 399 assertThat(iterable.firstMatch(Predicates.alwaysFalse())).isAbsent(); 400 assertThat(iterable.firstMatch(Predicates.alwaysTrue())).hasValue("cool"); 401 } 402 403 private static final class IntegerValueOfFunction implements Function<String, Integer> { 404 @Override apply(String from)405 public Integer apply(String from) { 406 return Integer.valueOf(from); 407 } 408 } 409 testTransformWith()410 public void testTransformWith() { 411 List<String> input = asList("1", "2", "3"); 412 Iterable<Integer> iterable = FluentIterable.from(input).transform(new IntegerValueOfFunction()); 413 414 assertEquals(asList(1, 2, 3), Lists.newArrayList(iterable)); 415 assertCanIterateAgain(iterable); 416 assertEquals("[1, 2, 3]", iterable.toString()); 417 } 418 testTransformWith_poorlyBehavedTransform()419 public void testTransformWith_poorlyBehavedTransform() { 420 List<String> input = asList("1", null, "3"); 421 Iterable<Integer> iterable = FluentIterable.from(input).transform(new IntegerValueOfFunction()); 422 423 Iterator<Integer> resultIterator = iterable.iterator(); 424 resultIterator.next(); 425 426 try { 427 resultIterator.next(); 428 fail("Transforming null to int should throw NumberFormatException"); 429 } catch (NumberFormatException expected) { 430 } 431 } 432 433 private static final class StringValueOfFunction implements Function<Integer, String> { 434 @Override apply(Integer from)435 public String apply(Integer from) { 436 return String.valueOf(from); 437 } 438 } 439 testTransformWith_nullFriendlyTransform()440 public void testTransformWith_nullFriendlyTransform() { 441 List<Integer> input = asList(1, 2, null, 3); 442 Iterable<String> result = FluentIterable.from(input).transform(new StringValueOfFunction()); 443 444 assertEquals(asList("1", "2", "null", "3"), Lists.newArrayList(result)); 445 } 446 447 private static final class RepeatedStringValueOfFunction 448 implements Function<Integer, List<String>> { 449 @Override apply(Integer from)450 public List<String> apply(Integer from) { 451 String value = String.valueOf(from); 452 return ImmutableList.of(value, value); 453 } 454 } 455 testTransformAndConcat()456 public void testTransformAndConcat() { 457 List<Integer> input = asList(1, 2, 3); 458 Iterable<String> result = 459 FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfFunction()); 460 assertEquals(asList("1", "1", "2", "2", "3", "3"), Lists.newArrayList(result)); 461 } 462 463 private static final class RepeatedStringValueOfWildcardFunction 464 implements Function<Integer, List<? extends String>> { 465 @Override apply(Integer from)466 public List<String> apply(Integer from) { 467 String value = String.valueOf(from); 468 return ImmutableList.of(value, value); 469 } 470 } 471 testTransformAndConcat_wildcardFunctionGenerics()472 public void testTransformAndConcat_wildcardFunctionGenerics() { 473 List<Integer> input = asList(1, 2, 3); 474 FluentIterable<String> unused = 475 FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfWildcardFunction()); 476 } 477 testFirst_list()478 public void testFirst_list() { 479 List<String> list = Lists.newArrayList("a", "b", "c"); 480 assertThat(FluentIterable.from(list).first()).hasValue("a"); 481 } 482 testFirst_null()483 public void testFirst_null() { 484 List<String> list = Lists.newArrayList(null, "a", "b"); 485 try { 486 FluentIterable.from(list).first(); 487 fail(); 488 } catch (NullPointerException expected) { 489 } 490 } 491 testFirst_emptyList()492 public void testFirst_emptyList() { 493 List<String> list = Collections.emptyList(); 494 assertThat(FluentIterable.from(list).first()).isAbsent(); 495 } 496 testFirst_sortedSet()497 public void testFirst_sortedSet() { 498 SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a"); 499 assertThat(FluentIterable.from(sortedSet).first()).hasValue("a"); 500 } 501 testFirst_emptySortedSet()502 public void testFirst_emptySortedSet() { 503 SortedSet<String> sortedSet = ImmutableSortedSet.of(); 504 assertThat(FluentIterable.from(sortedSet).first()).isAbsent(); 505 } 506 testFirst_iterable()507 public void testFirst_iterable() { 508 Set<String> set = ImmutableSet.of("a", "b", "c"); 509 assertThat(FluentIterable.from(set).first()).hasValue("a"); 510 } 511 testFirst_emptyIterable()512 public void testFirst_emptyIterable() { 513 Set<String> set = Sets.newHashSet(); 514 assertThat(FluentIterable.from(set).first()).isAbsent(); 515 } 516 testLast_list()517 public void testLast_list() { 518 List<String> list = Lists.newArrayList("a", "b", "c"); 519 assertThat(FluentIterable.from(list).last()).hasValue("c"); 520 } 521 testLast_null()522 public void testLast_null() { 523 List<String> list = Lists.newArrayList("a", "b", null); 524 try { 525 FluentIterable.from(list).last(); 526 fail(); 527 } catch (NullPointerException expected) { 528 } 529 } 530 testLast_emptyList()531 public void testLast_emptyList() { 532 List<String> list = Collections.emptyList(); 533 assertThat(FluentIterable.from(list).last()).isAbsent(); 534 } 535 testLast_sortedSet()536 public void testLast_sortedSet() { 537 SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a"); 538 assertThat(FluentIterable.from(sortedSet).last()).hasValue("c"); 539 } 540 testLast_emptySortedSet()541 public void testLast_emptySortedSet() { 542 SortedSet<String> sortedSet = ImmutableSortedSet.of(); 543 assertThat(FluentIterable.from(sortedSet).last()).isAbsent(); 544 } 545 testLast_iterable()546 public void testLast_iterable() { 547 Set<String> set = ImmutableSet.of("a", "b", "c"); 548 assertThat(FluentIterable.from(set).last()).hasValue("c"); 549 } 550 testLast_emptyIterable()551 public void testLast_emptyIterable() { 552 Set<String> set = Sets.newHashSet(); 553 assertThat(FluentIterable.from(set).last()).isAbsent(); 554 } 555 testSkip_simple()556 public void testSkip_simple() { 557 Collection<String> set = ImmutableSet.of("a", "b", "c", "d", "e"); 558 assertEquals( 559 Lists.newArrayList("c", "d", "e"), Lists.newArrayList(FluentIterable.from(set).skip(2))); 560 assertEquals("[c, d, e]", FluentIterable.from(set).skip(2).toString()); 561 } 562 testSkip_simpleList()563 public void testSkip_simpleList() { 564 Collection<String> list = Lists.newArrayList("a", "b", "c", "d", "e"); 565 assertEquals( 566 Lists.newArrayList("c", "d", "e"), Lists.newArrayList(FluentIterable.from(list).skip(2))); 567 assertEquals("[c, d, e]", FluentIterable.from(list).skip(2).toString()); 568 } 569 testSkip_pastEnd()570 public void testSkip_pastEnd() { 571 Collection<String> set = ImmutableSet.of("a", "b"); 572 assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(set).skip(20))); 573 } 574 testSkip_pastEndList()575 public void testSkip_pastEndList() { 576 Collection<String> list = Lists.newArrayList("a", "b"); 577 assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(list).skip(20))); 578 } 579 testSkip_skipNone()580 public void testSkip_skipNone() { 581 Collection<String> set = ImmutableSet.of("a", "b"); 582 assertEquals( 583 Lists.newArrayList("a", "b"), Lists.newArrayList(FluentIterable.from(set).skip(0))); 584 } 585 testSkip_skipNoneList()586 public void testSkip_skipNoneList() { 587 Collection<String> list = Lists.newArrayList("a", "b"); 588 assertEquals( 589 Lists.newArrayList("a", "b"), Lists.newArrayList(FluentIterable.from(list).skip(0))); 590 } 591 testSkip_iterator()592 public void testSkip_iterator() throws Exception { 593 new IteratorTester<Integer>( 594 5, 595 IteratorFeature.MODIFIABLE, 596 Lists.newArrayList(2, 3), 597 IteratorTester.KnownOrder.KNOWN_ORDER) { 598 @Override 599 protected Iterator<Integer> newTargetIterator() { 600 Collection<Integer> collection = Sets.newLinkedHashSet(); 601 Collections.addAll(collection, 1, 2, 3); 602 return FluentIterable.from(collection).skip(1).iterator(); 603 } 604 }.test(); 605 } 606 testSkip_iteratorList()607 public void testSkip_iteratorList() throws Exception { 608 new IteratorTester<Integer>( 609 5, 610 IteratorFeature.MODIFIABLE, 611 Lists.newArrayList(2, 3), 612 IteratorTester.KnownOrder.KNOWN_ORDER) { 613 @Override 614 protected Iterator<Integer> newTargetIterator() { 615 return FluentIterable.from(Lists.newArrayList(1, 2, 3)).skip(1).iterator(); 616 } 617 }.test(); 618 } 619 testSkip_nonStructurallyModifiedList()620 public void testSkip_nonStructurallyModifiedList() throws Exception { 621 List<String> list = Lists.newArrayList("a", "b", "c"); 622 FluentIterable<String> tail = FluentIterable.from(list).skip(1); 623 Iterator<String> tailIterator = tail.iterator(); 624 list.set(2, "c2"); 625 assertEquals("b", tailIterator.next()); 626 assertEquals("c2", tailIterator.next()); 627 assertFalse(tailIterator.hasNext()); 628 } 629 testSkip_structurallyModifiedSkipSome()630 public void testSkip_structurallyModifiedSkipSome() throws Exception { 631 Collection<String> set = Sets.newLinkedHashSet(); 632 Collections.addAll(set, "a", "b", "c"); 633 FluentIterable<String> tail = FluentIterable.from(set).skip(1); 634 set.remove("b"); 635 set.addAll(Lists.newArrayList("X", "Y", "Z")); 636 assertThat(tail).containsExactly("c", "X", "Y", "Z").inOrder(); 637 } 638 testSkip_structurallyModifiedSkipSomeList()639 public void testSkip_structurallyModifiedSkipSomeList() throws Exception { 640 List<String> list = Lists.newArrayList("a", "b", "c"); 641 FluentIterable<String> tail = FluentIterable.from(list).skip(1); 642 list.subList(1, 3).clear(); 643 list.addAll(0, Lists.newArrayList("X", "Y", "Z")); 644 assertThat(tail).containsExactly("Y", "Z", "a").inOrder(); 645 } 646 testSkip_structurallyModifiedSkipAll()647 public void testSkip_structurallyModifiedSkipAll() throws Exception { 648 Collection<String> set = Sets.newLinkedHashSet(); 649 Collections.addAll(set, "a", "b", "c"); 650 FluentIterable<String> tail = FluentIterable.from(set).skip(2); 651 set.remove("a"); 652 set.remove("b"); 653 assertFalse(tail.iterator().hasNext()); 654 } 655 testSkip_structurallyModifiedSkipAllList()656 public void testSkip_structurallyModifiedSkipAllList() throws Exception { 657 List<String> list = Lists.newArrayList("a", "b", "c"); 658 FluentIterable<String> tail = FluentIterable.from(list).skip(2); 659 list.subList(0, 2).clear(); 660 assertThat(tail).isEmpty(); 661 } 662 testSkip_illegalArgument()663 public void testSkip_illegalArgument() { 664 try { 665 FluentIterable.from(asList("a", "b", "c")).skip(-1); 666 fail("Skipping negative number of elements should throw IllegalArgumentException."); 667 } catch (IllegalArgumentException expected) { 668 } 669 } 670 testLimit()671 public void testLimit() { 672 Iterable<String> iterable = Lists.newArrayList("foo", "bar", "baz"); 673 FluentIterable<String> limited = FluentIterable.from(iterable).limit(2); 674 675 assertEquals(ImmutableList.of("foo", "bar"), Lists.newArrayList(limited)); 676 assertCanIterateAgain(limited); 677 assertEquals("[foo, bar]", limited.toString()); 678 } 679 testLimit_illegalArgument()680 public void testLimit_illegalArgument() { 681 try { 682 FluentIterable<String> unused = 683 FluentIterable.from(Lists.newArrayList("a", "b", "c")).limit(-1); 684 fail("Passing negative number to limit(...) method should throw IllegalArgumentException"); 685 } catch (IllegalArgumentException expected) { 686 } 687 } 688 testIsEmpty()689 public void testIsEmpty() { 690 assertTrue(FluentIterable.<String>from(Collections.<String>emptyList()).isEmpty()); 691 assertFalse(FluentIterable.<String>from(Lists.newArrayList("foo")).isEmpty()); 692 } 693 testToList()694 public void testToList() { 695 assertEquals(Lists.newArrayList(1, 2, 3, 4), fluent(1, 2, 3, 4).toList()); 696 } 697 testToList_empty()698 public void testToList_empty() { 699 assertTrue(fluent().toList().isEmpty()); 700 } 701 testToSortedList_withComparator()702 public void testToSortedList_withComparator() { 703 assertEquals( 704 Lists.newArrayList(4, 3, 2, 1), 705 fluent(4, 1, 3, 2).toSortedList(Ordering.<Integer>natural().reverse())); 706 } 707 testToSortedList_withDuplicates()708 public void testToSortedList_withDuplicates() { 709 assertEquals( 710 Lists.newArrayList(4, 3, 1, 1), 711 fluent(1, 4, 1, 3).toSortedList(Ordering.<Integer>natural().reverse())); 712 } 713 testToSet()714 public void testToSet() { 715 assertThat(fluent(1, 2, 3, 4).toSet()).containsExactly(1, 2, 3, 4).inOrder(); 716 } 717 testToSet_removeDuplicates()718 public void testToSet_removeDuplicates() { 719 assertThat(fluent(1, 2, 1, 2).toSet()).containsExactly(1, 2).inOrder(); 720 } 721 testToSet_empty()722 public void testToSet_empty() { 723 assertTrue(fluent().toSet().isEmpty()); 724 } 725 testToSortedSet()726 public void testToSortedSet() { 727 assertThat(fluent(1, 4, 2, 3).toSortedSet(Ordering.<Integer>natural().reverse())) 728 .containsExactly(4, 3, 2, 1) 729 .inOrder(); 730 } 731 testToSortedSet_removeDuplicates()732 public void testToSortedSet_removeDuplicates() { 733 assertThat(fluent(1, 4, 1, 3).toSortedSet(Ordering.<Integer>natural().reverse())) 734 .containsExactly(4, 3, 1) 735 .inOrder(); 736 } 737 testToMultiset()738 public void testToMultiset() { 739 assertThat(fluent(1, 2, 1, 3, 2, 4).toMultiset()).containsExactly(1, 1, 2, 2, 3, 4).inOrder(); 740 } 741 testToMultiset_empty()742 public void testToMultiset_empty() { 743 assertThat(fluent().toMultiset()).isEmpty(); 744 } 745 testToMap()746 public void testToMap() { 747 assertThat(fluent(1, 2, 3).toMap(Functions.toStringFunction()).entrySet()) 748 .containsExactly( 749 Maps.immutableEntry(1, "1"), Maps.immutableEntry(2, "2"), Maps.immutableEntry(3, "3")) 750 .inOrder(); 751 } 752 testToMap_nullKey()753 public void testToMap_nullKey() { 754 try { 755 fluent(1, null, 2).toMap(Functions.constant("foo")); 756 fail(); 757 } catch (NullPointerException expected) { 758 } 759 } 760 testToMap_nullValue()761 public void testToMap_nullValue() { 762 try { 763 fluent(1, 2, 3).toMap(Functions.constant(null)); 764 fail(); 765 } catch (NullPointerException expected) { 766 } 767 } 768 testIndex()769 public void testIndex() { 770 ImmutableListMultimap<Integer, String> expected = 771 ImmutableListMultimap.<Integer, String>builder() 772 .putAll(3, "one", "two") 773 .put(5, "three") 774 .put(4, "four") 775 .build(); 776 ImmutableListMultimap<Integer, String> index = 777 FluentIterable.from(asList("one", "two", "three", "four")) 778 .index( 779 new Function<String, Integer>() { 780 @Override 781 public Integer apply(String input) { 782 return input.length(); 783 } 784 }); 785 assertEquals(expected, index); 786 } 787 testIndex_nullKey()788 public void testIndex_nullKey() { 789 try { 790 ImmutableListMultimap<Object, Integer> unused = 791 fluent(1, 2, 3).index(Functions.constant(null)); 792 fail(); 793 } catch (NullPointerException expected) { 794 } 795 } 796 testIndex_nullValue()797 public void testIndex_nullValue() { 798 try { 799 ImmutableListMultimap<String, Integer> unused = 800 fluent(1, null, 2).index(Functions.constant("foo")); 801 fail(); 802 } catch (NullPointerException expected) { 803 } 804 } 805 testUniqueIndex()806 public void testUniqueIndex() { 807 ImmutableMap<Integer, String> expected = ImmutableMap.of(3, "two", 5, "three", 4, "four"); 808 ImmutableMap<Integer, String> index = 809 FluentIterable.from(asList("two", "three", "four")) 810 .uniqueIndex( 811 new Function<String, Integer>() { 812 @Override 813 public Integer apply(String input) { 814 return input.length(); 815 } 816 }); 817 assertEquals(expected, index); 818 } 819 testUniqueIndex_duplicateKey()820 public void testUniqueIndex_duplicateKey() { 821 try { 822 ImmutableMap<Integer, String> unused = 823 FluentIterable.from(asList("one", "two", "three", "four")) 824 .uniqueIndex( 825 new Function<String, Integer>() { 826 @Override 827 public Integer apply(String input) { 828 return input.length(); 829 } 830 }); 831 fail(); 832 } catch (IllegalArgumentException expected) { 833 } 834 } 835 testUniqueIndex_nullKey()836 public void testUniqueIndex_nullKey() { 837 try { 838 fluent(1, 2, 3).uniqueIndex(Functions.constant(null)); 839 fail(); 840 } catch (NullPointerException expected) { 841 } 842 } 843 testUniqueIndex_nullValue()844 public void testUniqueIndex_nullValue() { 845 try { 846 ImmutableMap<Object, Integer> unused = 847 fluent(1, null, 2) 848 .uniqueIndex( 849 new Function<Integer, Object>() { 850 @Override 851 public Object apply(@Nullable Integer input) { 852 return String.valueOf(input); 853 } 854 }); 855 fail(); 856 } catch (NullPointerException expected) { 857 } 858 } 859 testCopyInto_List()860 public void testCopyInto_List() { 861 assertThat(fluent(1, 3, 5).copyInto(Lists.newArrayList(1, 2))) 862 .containsExactly(1, 2, 1, 3, 5) 863 .inOrder(); 864 } 865 testCopyInto_Set()866 public void testCopyInto_Set() { 867 assertThat(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2))).containsExactly(1, 2, 3, 5); 868 } 869 testCopyInto_SetAllDuplicates()870 public void testCopyInto_SetAllDuplicates() { 871 assertThat(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2, 3, 5))).containsExactly(1, 2, 3, 5); 872 } 873 testCopyInto_NonCollection()874 public void testCopyInto_NonCollection() { 875 final ArrayList<Integer> list = Lists.newArrayList(1, 2, 3); 876 877 final ArrayList<Integer> iterList = Lists.newArrayList(9, 8, 7); 878 Iterable<Integer> iterable = 879 new Iterable<Integer>() { 880 @Override 881 public Iterator<Integer> iterator() { 882 return iterList.iterator(); 883 } 884 }; 885 886 assertThat(FluentIterable.from(iterable).copyInto(list)) 887 .containsExactly(1, 2, 3, 9, 8, 7) 888 .inOrder(); 889 } 890 testJoin()891 public void testJoin() { 892 assertEquals("2,1,3,4", fluent(2, 1, 3, 4).join(Joiner.on(","))); 893 } 894 testJoin_empty()895 public void testJoin_empty() { 896 assertEquals("", fluent().join(Joiner.on(","))); 897 } 898 testGet()899 public void testGet() { 900 assertEquals("a", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(0)); 901 assertEquals("b", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(1)); 902 assertEquals("c", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(2)); 903 } 904 testGet_outOfBounds()905 public void testGet_outOfBounds() { 906 try { 907 FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(-1); 908 fail(); 909 } catch (IndexOutOfBoundsException expected) { 910 } 911 912 try { 913 FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(3); 914 fail(); 915 } catch (IndexOutOfBoundsException expected) { 916 } 917 } 918 assertCanIterateAgain(Iterable<?> iterable)919 private static void assertCanIterateAgain(Iterable<?> iterable) { 920 for (Object unused : iterable) { 921 // do nothing 922 } 923 } 924 fluent(Integer... elements)925 private static FluentIterable<Integer> fluent(Integer... elements) { 926 return FluentIterable.from(Lists.newArrayList(elements)); 927 } 928 iterable(String... elements)929 private static Iterable<String> iterable(String... elements) { 930 final List<String> list = asList(elements); 931 return new Iterable<String>() { 932 @Override 933 public Iterator<String> iterator() { 934 return list.iterator(); 935 } 936 }; 937 } 938 } 939