1 /* 2 * Copyright (C) 2016 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.collect; 16 17 import static com.google.common.collect.Streams.findLast; 18 import static com.google.common.collect.Streams.stream; 19 20 import com.google.common.annotations.GwtCompatible; 21 import com.google.common.annotations.GwtIncompatible; 22 import com.google.common.collect.testing.SpliteratorTester; 23 import com.google.common.primitives.Doubles; 24 import com.google.common.truth.IterableSubject; 25 import com.google.common.truth.Truth; 26 import com.google.common.truth.Truth8; 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.LinkedHashSet; 31 import java.util.LinkedList; 32 import java.util.List; 33 import java.util.OptionalDouble; 34 import java.util.OptionalInt; 35 import java.util.OptionalLong; 36 import java.util.concurrent.atomic.AtomicInteger; 37 import java.util.function.Function; 38 import java.util.stream.Collectors; 39 import java.util.stream.DoubleStream; 40 import java.util.stream.IntStream; 41 import java.util.stream.LongStream; 42 import java.util.stream.Stream; 43 import junit.framework.TestCase; 44 45 /** Unit test for {@link Streams}. */ 46 @GwtCompatible(emulated = true) 47 public class StreamsTest extends TestCase { 48 /* 49 * Full and proper black-box testing of a Stream-returning method is extremely involved, and is 50 * overkill when nearly all Streams are produced using well-tested JDK calls. So, we cheat and 51 * just test that the toArray() contents are as expected. 52 */ testStream_nonCollection()53 public void testStream_nonCollection() { 54 assertThat(stream(FluentIterable.of())).isEmpty(); 55 assertThat(stream(FluentIterable.of("a"))).containsExactly("a"); 56 assertThat(stream(FluentIterable.of(1, 2, 3)).filter(n -> n > 1)).containsExactly(2, 3); 57 } 58 59 @SuppressWarnings("deprecation") testStream_collection()60 public void testStream_collection() { 61 assertThat(stream(Arrays.asList())).isEmpty(); 62 assertThat(stream(Arrays.asList("a"))).containsExactly("a"); 63 assertThat(stream(Arrays.asList(1, 2, 3)).filter(n -> n > 1)).containsExactly(2, 3); 64 } 65 testStream_iterator()66 public void testStream_iterator() { 67 assertThat(stream(Arrays.asList().iterator())).isEmpty(); 68 assertThat(stream(Arrays.asList("a").iterator())).containsExactly("a"); 69 assertThat(stream(Arrays.asList(1, 2, 3).iterator()).filter(n -> n > 1)).containsExactly(2, 3); 70 } 71 testStream_googleOptional()72 public void testStream_googleOptional() { 73 assertThat(stream(com.google.common.base.Optional.absent())).isEmpty(); 74 assertThat(stream(com.google.common.base.Optional.of("a"))).containsExactly("a"); 75 } 76 testStream_javaOptional()77 public void testStream_javaOptional() { 78 assertThat(stream(java.util.Optional.empty())).isEmpty(); 79 assertThat(stream(java.util.Optional.of("a"))).containsExactly("a"); 80 } 81 testFindLast_refStream()82 public void testFindLast_refStream() { 83 Truth8.assertThat(findLast(Stream.of())).isEmpty(); 84 Truth8.assertThat(findLast(Stream.of("a", "b", "c", "d"))).hasValue("d"); 85 86 // test with a large, not-subsized Spliterator 87 List<Integer> list = 88 IntStream.rangeClosed(0, 10000).boxed().collect(Collectors.toCollection(LinkedList::new)); 89 Truth8.assertThat(findLast(list.stream())).hasValue(10000); 90 91 // no way to find out the stream is empty without walking its spliterator 92 Truth8.assertThat(findLast(list.stream().filter(i -> i < 0))).isEmpty(); 93 } 94 testFindLast_intStream()95 public void testFindLast_intStream() { 96 Truth.assertThat(findLast(IntStream.of())).isEqualTo(OptionalInt.empty()); 97 Truth.assertThat(findLast(IntStream.of(1, 2, 3, 4, 5))).isEqualTo(OptionalInt.of(5)); 98 99 // test with a large, not-subsized Spliterator 100 List<Integer> list = 101 IntStream.rangeClosed(0, 10000).boxed().collect(Collectors.toCollection(LinkedList::new)); 102 Truth.assertThat(findLast(list.stream().mapToInt(i -> i))).isEqualTo(OptionalInt.of(10000)); 103 104 // no way to find out the stream is empty without walking its spliterator 105 Truth.assertThat(findLast(list.stream().mapToInt(i -> i).filter(i -> i < 0))) 106 .isEqualTo(OptionalInt.empty()); 107 } 108 testFindLast_longStream()109 public void testFindLast_longStream() { 110 Truth.assertThat(findLast(LongStream.of())).isEqualTo(OptionalLong.empty()); 111 Truth.assertThat(findLast(LongStream.of(1, 2, 3, 4, 5))).isEqualTo(OptionalLong.of(5)); 112 113 // test with a large, not-subsized Spliterator 114 List<Long> list = 115 LongStream.rangeClosed(0, 10000).boxed().collect(Collectors.toCollection(LinkedList::new)); 116 Truth.assertThat(findLast(list.stream().mapToLong(i -> i))).isEqualTo(OptionalLong.of(10000)); 117 118 // no way to find out the stream is empty without walking its spliterator 119 Truth.assertThat(findLast(list.stream().mapToLong(i -> i).filter(i -> i < 0))) 120 .isEqualTo(OptionalLong.empty()); 121 } 122 testFindLast_doubleStream()123 public void testFindLast_doubleStream() { 124 Truth.assertThat(findLast(DoubleStream.of())).isEqualTo(OptionalDouble.empty()); 125 Truth.assertThat(findLast(DoubleStream.of(1, 2, 3, 4, 5))).isEqualTo(OptionalDouble.of(5)); 126 127 // test with a large, not-subsized Spliterator 128 List<Long> list = 129 LongStream.rangeClosed(0, 10000).boxed().collect(Collectors.toCollection(LinkedList::new)); 130 Truth.assertThat(findLast(list.stream().mapToDouble(i -> i))) 131 .isEqualTo(OptionalDouble.of(10000)); 132 133 // no way to find out the stream is empty without walking its spliterator 134 Truth.assertThat(findLast(list.stream().mapToDouble(i -> i).filter(i -> i < 0))) 135 .isEqualTo(OptionalDouble.empty()); 136 } 137 testConcat_refStream()138 public void testConcat_refStream() { 139 assertThat(Streams.concat(Stream.of("a"), Stream.of("b"), Stream.empty(), Stream.of("c", "d"))) 140 .containsExactly("a", "b", "c", "d") 141 .inOrder(); 142 SpliteratorTester.of( 143 () -> 144 Streams.concat(Stream.of("a"), Stream.of("b"), Stream.empty(), Stream.of("c", "d")) 145 .spliterator()) 146 .expect("a", "b", "c", "d"); 147 } 148 testConcat_refStream_closeIsPropagated()149 public void testConcat_refStream_closeIsPropagated() { 150 AtomicInteger closeCountB = new AtomicInteger(0); 151 Stream<String> streamB = Stream.of("b").onClose(closeCountB::incrementAndGet); 152 Stream<String> concatenated = 153 Streams.concat(Stream.of("a"), streamB, Stream.empty(), Stream.of("c", "d")); 154 assertThat(concatenated).containsExactly("a", "b", "c", "d").inOrder(); 155 concatenated.close(); 156 Truth.assertThat(closeCountB.get()).isEqualTo(1); 157 } 158 testConcat_refStream_closeIsPropagated_Stream_concat()159 public void testConcat_refStream_closeIsPropagated_Stream_concat() { 160 // Just to demonstrate behavior of Stream::concat in the standard library 161 AtomicInteger closeCountB = new AtomicInteger(0); 162 Stream<String> streamB = Stream.of("b").onClose(closeCountB::incrementAndGet); 163 Stream<String> concatenated = 164 Stream.<Stream<String>>of(Stream.of("a"), streamB, Stream.empty(), Stream.of("c", "d")) 165 .reduce(Stream.empty(), Stream::concat); 166 assertThat(concatenated).containsExactly("a", "b", "c", "d").inOrder(); 167 concatenated.close(); 168 Truth.assertThat(closeCountB.get()).isEqualTo(1); 169 } 170 testConcat_refStream_closeIsPropagated_Stream_flatMap()171 public void testConcat_refStream_closeIsPropagated_Stream_flatMap() { 172 // Just to demonstrate behavior of Stream::flatMap in the standard library 173 AtomicInteger closeCountB = new AtomicInteger(0); 174 Stream<String> streamB = Stream.of("b").onClose(closeCountB::incrementAndGet); 175 Stream<String> concatenated = 176 Stream.<Stream<String>>of(Stream.of("a"), streamB, Stream.empty(), Stream.of("c", "d")) 177 .flatMap(x -> x); 178 assertThat(concatenated).containsExactly("a", "b", "c", "d").inOrder(); 179 concatenated.close(); 180 // even without close, see doc for flatMap 181 Truth.assertThat(closeCountB.get()).isEqualTo(1); 182 } 183 testConcat_refStream_closeIsPropagated_exceptionsChained()184 public void testConcat_refStream_closeIsPropagated_exceptionsChained() { 185 RuntimeException exception1 = new IllegalArgumentException("exception from stream 1"); 186 RuntimeException exception2 = new IllegalStateException("exception from stream 2"); 187 RuntimeException exception3 = new ArithmeticException("exception from stream 3"); 188 Stream<String> stream1 = Stream.of("foo", "bar").onClose(doThrow(exception1)); 189 Stream<String> stream2 = Stream.of("baz", "buh").onClose(doThrow(exception2)); 190 Stream<String> stream3 = Stream.of("quux").onClose(doThrow(exception3)); 191 RuntimeException exception = null; 192 try (Stream<String> concatenated = Streams.concat(stream1, stream2, stream3)) { 193 } catch (RuntimeException e) { 194 exception = e; 195 } 196 Truth.assertThat(exception).isEqualTo(exception1); 197 Truth.assertThat(exception.getSuppressed()) 198 .asList() 199 .containsExactly(exception2, exception3) 200 .inOrder(); 201 } 202 doThrow(RuntimeException exception)203 private static Runnable doThrow(RuntimeException exception) { 204 return () -> { 205 throw exception; 206 }; 207 } 208 testConcat_refStream_parallel()209 public void testConcat_refStream_parallel() { 210 Truth.assertThat( 211 Streams.concat(Stream.of("a"), Stream.of("b"), Stream.empty(), Stream.of("c", "d")) 212 .parallel() 213 .toArray()) 214 .asList() 215 .containsExactly("a", "b", "c", "d") 216 .inOrder(); 217 } 218 testConcat_intStream()219 public void testConcat_intStream() { 220 assertThat( 221 Streams.concat(IntStream.of(1), IntStream.of(2), IntStream.empty(), IntStream.of(3, 4))) 222 .containsExactly(1, 2, 3, 4) 223 .inOrder(); 224 } 225 testConcat_longStream()226 public void testConcat_longStream() { 227 assertThat( 228 Streams.concat( 229 LongStream.of(1), LongStream.of(2), LongStream.empty(), LongStream.of(3, 4))) 230 .containsExactly(1L, 2L, 3L, 4L) 231 .inOrder(); 232 } 233 testConcat_doubleStream()234 public void testConcat_doubleStream() { 235 assertThat( 236 Streams.concat( 237 DoubleStream.of(1), 238 DoubleStream.of(2), 239 DoubleStream.empty(), 240 DoubleStream.of(3, 4))) 241 .containsExactly(1.0, 2.0, 3.0, 4.0) 242 .inOrder(); 243 } 244 testStream_optionalInt()245 public void testStream_optionalInt() { 246 assertThat(stream(OptionalInt.empty())).isEmpty(); 247 assertThat(stream(OptionalInt.of(5))).containsExactly(5); 248 } 249 testStream_optionalLong()250 public void testStream_optionalLong() { 251 assertThat(stream(OptionalLong.empty())).isEmpty(); 252 assertThat(stream(OptionalLong.of(5L))).containsExactly(5L); 253 } 254 testStream_optionalDouble()255 public void testStream_optionalDouble() { 256 assertThat(stream(OptionalDouble.empty())).isEmpty(); 257 assertThat(stream(OptionalDouble.of(5.0))).containsExactly(5.0); 258 } 259 testConcatInfiniteStream()260 public void testConcatInfiniteStream() { 261 assertThat(Streams.concat(Stream.of(1, 2, 3), Stream.generate(() -> 5)).limit(5)) 262 .containsExactly(1, 2, 3, 5, 5) 263 .inOrder(); 264 } 265 testConcatInfiniteStream_int()266 public void testConcatInfiniteStream_int() { 267 assertThat(Streams.concat(IntStream.of(1, 2, 3), IntStream.generate(() -> 5)).limit(5)) 268 .containsExactly(1, 2, 3, 5, 5) 269 .inOrder(); 270 } 271 testConcatInfiniteStream_long()272 public void testConcatInfiniteStream_long() { 273 assertThat(Streams.concat(LongStream.of(1, 2, 3), LongStream.generate(() -> 5)).limit(5)) 274 .containsExactly(1L, 2L, 3L, 5L, 5L) 275 .inOrder(); 276 } 277 testConcatInfiniteStream_double()278 public void testConcatInfiniteStream_double() { 279 assertThat(Streams.concat(DoubleStream.of(1, 2, 3), DoubleStream.generate(() -> 5)).limit(5)) 280 .containsExactly(1., 2., 3., 5., 5.) 281 .inOrder(); 282 } 283 testMapWithIndex(Function<Collection<String>, Stream<String>> collectionImpl)284 private void testMapWithIndex(Function<Collection<String>, Stream<String>> collectionImpl) { 285 SpliteratorTester.of( 286 () -> 287 Streams.mapWithIndex( 288 collectionImpl.apply(ImmutableList.of()), (str, i) -> str + ":" + i) 289 .spliterator()) 290 .expect(ImmutableList.of()); 291 SpliteratorTester.of( 292 () -> 293 Streams.mapWithIndex( 294 collectionImpl.apply(ImmutableList.of("a", "b", "c", "d", "e")), 295 (str, i) -> str + ":" + i) 296 .spliterator()) 297 .expect("a:0", "b:1", "c:2", "d:3", "e:4"); 298 } 299 testMapWithIndex_arrayListSource()300 public void testMapWithIndex_arrayListSource() { 301 testMapWithIndex(elems -> new ArrayList<>(elems).stream()); 302 } 303 testMapWithIndex_linkedHashSetSource()304 public void testMapWithIndex_linkedHashSetSource() { 305 testMapWithIndex(elems -> new LinkedHashSet<>(elems).stream()); 306 } 307 testMapWithIndex_unsizedSource()308 public void testMapWithIndex_unsizedSource() { 309 testMapWithIndex( 310 elems -> Stream.of((Object) null).flatMap(unused -> ImmutableList.copyOf(elems).stream())); 311 } 312 testMapWithIndex_closeIsPropagated_sizedSource()313 public void testMapWithIndex_closeIsPropagated_sizedSource() { 314 testMapWithIndex_closeIsPropagated(Stream.of("a", "b", "c")); 315 } 316 testMapWithIndex_closeIsPropagated_unsizedSource()317 public void testMapWithIndex_closeIsPropagated_unsizedSource() { 318 testMapWithIndex_closeIsPropagated( 319 Stream.of((Object) null).flatMap(unused -> Stream.of("a", "b", "c"))); 320 } 321 testMapWithIndex_closeIsPropagated(Stream<String> source)322 private void testMapWithIndex_closeIsPropagated(Stream<String> source) { 323 AtomicInteger stringsCloseCount = new AtomicInteger(); 324 Stream<String> strings = source.onClose(stringsCloseCount::incrementAndGet); 325 Stream<String> withIndex = Streams.mapWithIndex(strings, (str, i) -> str + ":" + i); 326 327 withIndex.close(); 328 329 Truth.assertThat(stringsCloseCount.get()).isEqualTo(1); 330 } 331 testMapWithIndex_intStream()332 public void testMapWithIndex_intStream() { 333 SpliteratorTester.of( 334 () -> Streams.mapWithIndex(IntStream.of(0, 1, 2), (x, i) -> x + ":" + i).spliterator()) 335 .expect("0:0", "1:1", "2:2"); 336 } 337 testMapWithIndex_intStream_closeIsPropagated_sized()338 public void testMapWithIndex_intStream_closeIsPropagated_sized() { 339 testMapWithIndex_intStream_closeIsPropagated(IntStream.of(1, 2, 3)); 340 } 341 testMapWithIndex_intStream_closeIsPropagated_unsized()342 public void testMapWithIndex_intStream_closeIsPropagated_unsized() { 343 testMapWithIndex_intStream_closeIsPropagated( 344 IntStream.of(0).flatMap(unused -> IntStream.of(1, 2, 3))); 345 } 346 testMapWithIndex_intStream_closeIsPropagated(IntStream source)347 private void testMapWithIndex_intStream_closeIsPropagated(IntStream source) { 348 AtomicInteger intStreamCloseCount = new AtomicInteger(); 349 IntStream intStream = source.onClose(intStreamCloseCount::incrementAndGet); 350 Stream<String> withIndex = Streams.mapWithIndex(intStream, (str, i) -> str + ":" + i); 351 352 withIndex.close(); 353 354 Truth.assertThat(intStreamCloseCount.get()).isEqualTo(1); 355 } 356 testMapWithIndex_longStream()357 public void testMapWithIndex_longStream() { 358 SpliteratorTester.of( 359 () -> Streams.mapWithIndex(LongStream.of(0, 1, 2), (x, i) -> x + ":" + i).spliterator()) 360 .expect("0:0", "1:1", "2:2"); 361 } 362 testMapWithIndex_longStream_closeIsPropagated_sized()363 public void testMapWithIndex_longStream_closeIsPropagated_sized() { 364 testMapWithIndex_longStream_closeIsPropagated(LongStream.of(1, 2, 3)); 365 } 366 testMapWithIndex_longStream_closeIsPropagated_unsized()367 public void testMapWithIndex_longStream_closeIsPropagated_unsized() { 368 testMapWithIndex_longStream_closeIsPropagated( 369 LongStream.of(0).flatMap(unused -> LongStream.of(1, 2, 3))); 370 } 371 testMapWithIndex_longStream_closeIsPropagated(LongStream source)372 private void testMapWithIndex_longStream_closeIsPropagated(LongStream source) { 373 AtomicInteger longStreamCloseCount = new AtomicInteger(); 374 LongStream longStream = source.onClose(longStreamCloseCount::incrementAndGet); 375 Stream<String> withIndex = Streams.mapWithIndex(longStream, (str, i) -> str + ":" + i); 376 377 withIndex.close(); 378 379 Truth.assertThat(longStreamCloseCount.get()).isEqualTo(1); 380 } 381 382 @GwtIncompatible // TODO(b/38490623): reenable after GWT double-to-string conversion is fixed testMapWithIndex_doubleStream()383 public void testMapWithIndex_doubleStream() { 384 SpliteratorTester.of( 385 () -> 386 Streams.mapWithIndex(DoubleStream.of(0, 1, 2), (x, i) -> x + ":" + i).spliterator()) 387 .expect("0.0:0", "1.0:1", "2.0:2"); 388 } 389 testMapWithIndex_doubleStream_closeIsPropagated_sized()390 public void testMapWithIndex_doubleStream_closeIsPropagated_sized() { 391 testMapWithIndex_doubleStream_closeIsPropagated(DoubleStream.of(1, 2, 3)); 392 } 393 testMapWithIndex_doubleStream_closeIsPropagated_unsized()394 public void testMapWithIndex_doubleStream_closeIsPropagated_unsized() { 395 testMapWithIndex_doubleStream_closeIsPropagated( 396 DoubleStream.of(0).flatMap(unused -> DoubleStream.of(1, 2, 3))); 397 } 398 testMapWithIndex_doubleStream_closeIsPropagated(DoubleStream source)399 private void testMapWithIndex_doubleStream_closeIsPropagated(DoubleStream source) { 400 AtomicInteger doubleStreamCloseCount = new AtomicInteger(); 401 DoubleStream doubleStream = source.onClose(doubleStreamCloseCount::incrementAndGet); 402 Stream<String> withIndex = Streams.mapWithIndex(doubleStream, (str, i) -> str + ":" + i); 403 404 withIndex.close(); 405 406 Truth.assertThat(doubleStreamCloseCount.get()).isEqualTo(1); 407 } 408 testZip()409 public void testZip() { 410 assertThat(Streams.zip(Stream.of("a", "b", "c"), Stream.of(1, 2, 3), (a, b) -> a + ":" + b)) 411 .containsExactly("a:1", "b:2", "c:3") 412 .inOrder(); 413 } 414 testZip_closeIsPropagated()415 public void testZip_closeIsPropagated() { 416 AtomicInteger lettersCloseCount = new AtomicInteger(); 417 Stream<String> letters = Stream.of("a", "b", "c").onClose(lettersCloseCount::incrementAndGet); 418 AtomicInteger numbersCloseCount = new AtomicInteger(); 419 Stream<Integer> numbers = Stream.of(1, 2, 3).onClose(numbersCloseCount::incrementAndGet); 420 421 Stream<String> zipped = Streams.zip(letters, numbers, (a, b) -> a + ":" + b); 422 423 zipped.close(); 424 425 Truth.assertThat(lettersCloseCount.get()).isEqualTo(1); 426 Truth.assertThat(numbersCloseCount.get()).isEqualTo(1); 427 } 428 testZipFiniteWithInfinite()429 public void testZipFiniteWithInfinite() { 430 assertThat( 431 Streams.zip( 432 Stream.of("a", "b", "c"), Stream.iterate(1, i -> i + 1), (a, b) -> a + ":" + b)) 433 .containsExactly("a:1", "b:2", "c:3") 434 .inOrder(); 435 } 436 testZipInfiniteWithInfinite()437 public void testZipInfiniteWithInfinite() { 438 // zip is doing an infinite zip, but we truncate the result so we can actually test it 439 // but we want the zip itself to work 440 assertThat( 441 Streams.zip( 442 Stream.iterate(1, i -> i + 1).map(String::valueOf), 443 Stream.iterate(1, i -> i + 1), 444 (String str, Integer i) -> str.equals(Integer.toString(i))) 445 .limit(100)) 446 .doesNotContain(false); 447 } 448 testZipDifferingLengths()449 public void testZipDifferingLengths() { 450 assertThat( 451 Streams.zip(Stream.of("a", "b", "c", "d"), Stream.of(1, 2, 3), (a, b) -> a + ":" + b)) 452 .containsExactly("a:1", "b:2", "c:3") 453 .inOrder(); 454 assertThat(Streams.zip(Stream.of("a", "b", "c"), Stream.of(1, 2, 3, 4), (a, b) -> a + ":" + b)) 455 .containsExactly("a:1", "b:2", "c:3") 456 .inOrder(); 457 } 458 testForEachPair()459 public void testForEachPair() { 460 List<String> list = new ArrayList<>(); 461 Streams.forEachPair( 462 Stream.of("a", "b", "c"), Stream.of(1, 2, 3), (a, b) -> list.add(a + ":" + b)); 463 Truth.assertThat(list).containsExactly("a:1", "b:2", "c:3"); 464 } 465 testForEachPair_differingLengths1()466 public void testForEachPair_differingLengths1() { 467 List<String> list = new ArrayList<>(); 468 Streams.forEachPair( 469 Stream.of("a", "b", "c", "d"), Stream.of(1, 2, 3), (a, b) -> list.add(a + ":" + b)); 470 Truth.assertThat(list).containsExactly("a:1", "b:2", "c:3"); 471 } 472 testForEachPair_differingLengths2()473 public void testForEachPair_differingLengths2() { 474 List<String> list = new ArrayList<>(); 475 Streams.forEachPair( 476 Stream.of("a", "b", "c"), Stream.of(1, 2, 3, 4), (a, b) -> list.add(a + ":" + b)); 477 Truth.assertThat(list).containsExactly("a:1", "b:2", "c:3"); 478 } 479 testForEachPair_oneEmpty()480 public void testForEachPair_oneEmpty() { 481 Streams.forEachPair(Stream.of("a"), Stream.empty(), (a, b) -> fail()); 482 } 483 testForEachPair_finiteWithInfinite()484 public void testForEachPair_finiteWithInfinite() { 485 List<String> list = new ArrayList<>(); 486 Streams.forEachPair( 487 Stream.of("a", "b", "c"), Stream.iterate(1, i -> i + 1), (a, b) -> list.add(a + ":" + b)); 488 Truth.assertThat(list).containsExactly("a:1", "b:2", "c:3"); 489 } 490 testForEachPair_parallel()491 public void testForEachPair_parallel() { 492 Stream<String> streamA = IntStream.range(0, 100000).mapToObj(String::valueOf).parallel(); 493 Stream<Integer> streamB = IntStream.range(0, 100000).mapToObj(i -> i).parallel(); 494 495 AtomicInteger count = new AtomicInteger(0); 496 Streams.forEachPair( 497 streamA, 498 streamB, 499 (a, b) -> { 500 count.incrementAndGet(); 501 Truth.assertThat(a.equals(String.valueOf(b))).isTrue(); 502 }); 503 Truth.assertThat(count.get()).isEqualTo(100000); 504 // of course, this test doesn't prove that anything actually happened in parallel... 505 } 506 507 // TODO(kevinb): switch to importing Truth's assertThat(Stream) if we get that added assertThat(Stream<?> stream)508 private static IterableSubject assertThat(Stream<?> stream) { 509 return Truth.assertThat(stream.toArray()).asList(); 510 } 511 assertThat(IntStream stream)512 private static IterableSubject assertThat(IntStream stream) { 513 return Truth.assertThat(stream.toArray()).asList(); 514 } 515 assertThat(LongStream stream)516 private static IterableSubject assertThat(LongStream stream) { 517 return Truth.assertThat(stream.toArray()).asList(); 518 } 519 assertThat(DoubleStream stream)520 private static IterableSubject assertThat(DoubleStream stream) { 521 return Truth.assertThat(Doubles.asList(stream.toArray())); 522 } 523 } 524