content: package com.annimon.stream.streamtests;
  
  import com.annimon.stream.Functions;
  import com.annimon.stream.Stream;
  import com.annimon.stream.function.Function;
  import com.annimon.stream.test.hamcrest.StreamMatcher;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.List;
  import org.junit.Test;
  import static com.annimon.stream.test.hamcrest.StreamMatcher.assertElements;
  import static org.hamcrest.Matchers.contains;
  
  @SuppressWarnings("unchecked")
  public final class ConcatTest {
  
      @Test
      public void testConcat0Streams() {
          Stream.concat(Collections.<Stream<String>>emptyList())
                  .custom(StreamMatcher.<String>assertIsEmpty());
      }
  
      @Test
      public void testConcat1Stream() {
          Stream<String> stream1 = Stream.of("a", "b", "c", "d");
          Stream.concat(Collections.singletonList(stream1))
                  .custom(assertElements(contains(
                          "a", "b", "c", "d"
                  )));
      }
  
      @Test
      public void testConcat2Streams() {
          Stream<String> stream1 = Stream.of("a", "b", "c", "d");
          Stream<String> stream2 = Stream.of("e", "f", "g", "h");
          Stream.concat(stream1, stream2)
                  .custom(assertElements(contains(
                          "a", "b", "c", "d",
                          "e", "f", "g", "h"
                  )));
      }
  
      @Test
      public void testConcat3Streams() {
          Stream<String> stream1 = Stream.of("a", "b", "c", "d");
          Stream<String> stream2 = Stream.of("e", "f", "g", "h");
          Stream<String> stream3 = Stream.of("i", "j", "k", "l");
          Stream.concat(Arrays.asList(stream1, stream2, stream3))
                  .custom(assertElements(contains(
                          "a", "b", "c", "d",
                          "e", "f", "g", "h",
                          "i", "j", "k", "l"
                  )));
      }
  
      @SuppressWarnings("ConstantConditions")
      @Test(expected = NullPointerException.class)
      public void testConcatNull1() {
          Stream.concat(null, Stream.empty());
      }
  
      @SuppressWarnings("ConstantConditions")
      @Test(expected = NullPointerException.class)
      public void testConcatNull2() {
          Stream.concat(Stream.empty(), null);
      }
  
      @Test
      public void testConcatOfFilter() {
          Stream<Integer> stream1 = Stream.range(0, 5).filter(Functions.remainder(1));
          Stream<Integer> stream2 = Stream.range(5, 10).filter(Functions.remainder(1));
          Stream.concat(stream1, stream2)
                  .custom(assertElements(contains(
                          0, 1, 2, 3, 4, 5, 6, 7, 8, 9
                  )));
      }
  
      @Test
      public void testConcatOfFilterOn4Streams() {
          Stream<Integer> stream1 = Stream.range(0, 5).filter(Functions.remainder(1));
          Stream<Integer> stream2 = Stream.range(5, 10).filter(Functions.remainder(1));
          Stream<Integer> stream3 = Stream.range(10, 15).filter(Functions.remainder(1));
          Stream<Integer> stream4 = Stream.range(15, 20).filter(Functions.remainder(1));
          Stream.concat(Arrays.asList(stream1, stream2, stream3, stream4))
                  .custom(assertElements(contains(
                          0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                          10, 11, 12, 13, 14, 15, 16, 17, 18, 19
                  )));
      }
  
      @Test
      public void testConcatOfFlatMap() {
          final Function<Integer, Stream<Integer>> flatmapFunc = new Function<Integer, Stream<Integer>>() {
              @Override
              public Stream<Integer> apply(Integer value) {
                  return Stream.of(value, value);
              }
          };
          Stream<Integer> stream1 = Stream.range(1, 3).flatMap(flatmapFunc); // 1122
          Stream<Integer> stream2 = Stream.range(3, 5).flatMap(flatmapFunc); // 3344
          Stream.concat(stream1, stream2)
                  .custom(assertElements(contains(
                          1, 1, 2, 2, 3, 3, 4, 4
                  )));
      }
  
      @Test
      public void testConcat2Iterators() {
          List<Integer> shorter = Arrays.asList(1, 2, 3, 4, 5);
          List<Integer> longer = Stream.rangeClosed(2, 8).toList();
          Stream.concat(shorter.iterator(), longer.iterator())
                  .custom(assertElements(contains(
                          1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 7, 8
                  )));
          Stream.concat(longer.iterator(), shorter.iterator())
                  .custom(assertElements(contains(
                          2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5
                  )));
      }
  
      @Test
      public void testConcat3Iterators() {
          List<Integer> a = Arrays.asList(1, 2);
          List<Integer> b = Stream.rangeClosed(2, 7).toList();
          List<Integer> c = Arrays.asList(1, 2, 3, 4);
  
          Stream.concat(a.iterator(), b.iterator(), c.iterator())
                  .custom(assertElements(contains(
                          1, 2,
                          2, 3, 4, 5, 6, 7,
                          1, 2, 3, 4
                  )));
          Stream.concat(b.iterator(), a.iterator(), c.iterator())
                  .custom(assertElements(contains(
                          2, 3, 4, 5, 6, 7,
                          1, 2,
                          1, 2, 3, 4
                  )));
          Stream.concat(c.iterator(), b.iterator(), a.iterator())
                  .custom(assertElements(contains(
                          1, 2, 3, 4,
                          2, 3, 4, 5, 6, 7,
                          1, 2
                  )));
      }
  }
  