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