@Test
  public void testMergeSync() {
    int NUM = (int) (RxRingBuffer.SIZE * 4.1);
    AtomicInteger c1 = new AtomicInteger();
    AtomicInteger c2 = new AtomicInteger();
    TestSubscriber<Integer> ts = new TestSubscriber<Integer>();
    Observable<Integer> merged =
        Observable.merge(incrementingIntegers(c1), incrementingIntegers(c2));

    merged.take(NUM).subscribe(ts);
    ts.awaitTerminalEvent();
    ts.assertNoErrors();
    System.out.println("Expected: " + NUM + " got: " + ts.getOnNextEvents().size());
    System.out.println(
        "testMergeSync => Received: "
            + ts.getOnNextEvents().size()
            + "  Emitted: "
            + c1.get()
            + " / "
            + c2.get());
    assertEquals(NUM, ts.getOnNextEvents().size());
    // either one can starve the other, but neither should be capable of doing more than 5 batches
    // (taking 4.1)
    // TODO is it possible to make this deterministic rather than one possibly starving the other?
    // benjchristensen => In general I'd say it's not worth trying to make it so, as "fair"
    // algoritms generally take a performance hit
    assertTrue(c1.get() < RxRingBuffer.SIZE * 5);
    assertTrue(c2.get() < RxRingBuffer.SIZE * 5);
  }
  @Test
  public void testZipAsync() {
    int NUM = (int) (RxRingBuffer.SIZE * 2.1);
    AtomicInteger c1 = new AtomicInteger();
    AtomicInteger c2 = new AtomicInteger();
    TestSubscriber<Integer> ts = new TestSubscriber<Integer>();
    Observable<Integer> zipped =
        Observable.zip(
            incrementingIntegers(c1).subscribeOn(Schedulers.computation()),
            incrementingIntegers(c2).subscribeOn(Schedulers.computation()),
            new Func2<Integer, Integer, Integer>() {

              @Override
              public Integer call(Integer t1, Integer t2) {
                return t1 + t2;
              }
            });

    zipped.take(NUM).subscribe(ts);
    ts.awaitTerminalEvent();
    ts.assertNoErrors();
    System.out.println(
        "testZipAsync => Received: "
            + ts.getOnNextEvents().size()
            + "  Emitted: "
            + c1.get()
            + " / "
            + c2.get());
    assertEquals(NUM, ts.getOnNextEvents().size());
    assertTrue(c1.get() < RxRingBuffer.SIZE * 3);
    assertTrue(c2.get() < RxRingBuffer.SIZE * 3);
  }
  @Test
  public void testZipAsync() {
    int NUM = (int) (Observable.bufferSize() * 2.1);
    AtomicInteger c1 = new AtomicInteger();
    AtomicInteger c2 = new AtomicInteger();
    TestSubscriber<Integer> ts = new TestSubscriber<>();
    Observable<Integer> zipped =
        Observable.zip(
            incrementingIntegers(c1).subscribeOn(Schedulers.computation()),
            incrementingIntegers(c2).subscribeOn(Schedulers.computation()),
            (t1, t2) -> t1 + t2);

    zipped.take(NUM).subscribe(ts);
    ts.awaitTerminalEvent();
    ts.assertNoErrors();
    System.out.println(
        "testZipAsync => Received: "
            + ts.valueCount()
            + "  Emitted: "
            + c1.get()
            + " / "
            + c2.get());
    assertEquals(NUM, ts.valueCount());
    int max = Observable.bufferSize() * 5;
    assertTrue("" + c1.get() + " >= " + max, c1.get() < max);
    assertTrue("" + c2.get() + " >= " + max, c2.get() < max);
  }
  @Test
  public void testMergeAsync() {
    int NUM = (int) (Observable.bufferSize() * 4.1);
    AtomicInteger c1 = new AtomicInteger();
    AtomicInteger c2 = new AtomicInteger();
    TestSubscriber<Integer> ts = new TestSubscriber<>();
    Observable<Integer> merged =
        Observable.merge(
            incrementingIntegers(c1).subscribeOn(Schedulers.computation()),
            incrementingIntegers(c2).subscribeOn(Schedulers.computation()));

    merged.take(NUM).subscribe(ts);
    ts.awaitTerminalEvent();
    ts.assertNoErrors();
    System.out.println(
        "testMergeAsync => Received: "
            + ts.valueCount()
            + "  Emitted: "
            + c1.get()
            + " / "
            + c2.get());
    assertEquals(NUM, ts.valueCount());
    // either one can starve the other, but neither should be capable of doing more than 5 batches
    // (taking 4.1)
    // TODO is it possible to make this deterministic rather than one possibly starving the other?
    // benjchristensen => In general I'd say it's not worth trying to make it so, as "fair"
    // algoritms generally take a performance hit
    int max = Observable.bufferSize() * 7;
    assertTrue("" + c1.get() + " >= " + max, c1.get() < max);
    assertTrue("" + c2.get() + " >= " + max, c2.get() < max);
  }
 @Test
 public void testTakeFirstOfNone() {
   Observable<Integer> observable = Observable.empty();
   observable.take(1).subscribe(w);
   verify(w, never()).onNext(anyInt());
   verify(w, times(1)).onComplete();
   verify(w, never()).onError(any(Throwable.class));
 }