@Test
  public void shouldNotEmitUntilAfterSubscription() {
    TestSubscriber<Integer> ts = new TestSubscriber<>();
    Observable.range(1, 100)
        .scan(
            0,
            new BiFunction<Integer, Integer, Integer>() {

              @Override
              public Integer apply(Integer t1, Integer t2) {
                return t1 + t2;
              }
            })
        .filter(
            new Predicate<Integer>() {

              @Override
              public boolean test(Integer t1) {
                // this will cause request(1) when 0 is emitted
                return t1 > 0;
              }
            })
        .subscribe(ts);

    assertEquals(100, ts.values().size());
  }
  @Test
  public void testDelayErrorMaxConcurrent() {
    final List<Long> requests = new ArrayList<>();
    Observable<Integer> source =
        Observable.mergeDelayError(
            Observable.just(
                    Observable.just(1).asObservable(),
                    Observable.<Integer>error(new TestException()))
                .doOnRequest(
                    new LongConsumer() {
                      @Override
                      public void accept(long t1) {
                        requests.add(t1);
                      }
                    }),
            1);

    TestSubscriber<Integer> ts = new TestSubscriber<>();

    source.subscribe(ts);

    ts.assertValue(1);
    ts.assertTerminated();
    ts.assertError(TestException.class);
    assertEquals(Arrays.asList(1L, 1L, 1L), requests);
  }
  @Test
  public void testErrorInParentObservableDelayed() throws Exception {
    for (int i = 0; i < 50; i++) {
      final TestASynchronous1sDelayedObservable o1 = new TestASynchronous1sDelayedObservable();
      final TestASynchronous1sDelayedObservable o2 = new TestASynchronous1sDelayedObservable();
      Observable<Observable<String>> parentObservable =
          Observable.create(
              new Publisher<Observable<String>>() {
                @Override
                public void subscribe(Subscriber<? super Observable<String>> op) {
                  op.onSubscribe(EmptySubscription.INSTANCE);
                  op.onNext(Observable.create(o1));
                  op.onNext(Observable.create(o2));
                  op.onError(new NullPointerException("throwing exception in parent"));
                }
              });

      Subscriber<String> stringObserver = TestHelper.mockSubscriber();

      TestSubscriber<String> ts = new TestSubscriber<>(stringObserver);
      Observable<String> m = Observable.mergeDelayError(parentObservable);
      m.subscribe(ts);
      System.out.println("testErrorInParentObservableDelayed | " + i);
      ts.awaitTerminalEvent(2000, TimeUnit.MILLISECONDS);
      ts.assertTerminated();

      verify(stringObserver, times(2)).onNext("hello");
      verify(stringObserver, times(1)).onError(any(NullPointerException.class));
      verify(stringObserver, never()).onComplete();
    }
  }
 @Test
 public void testErrorInParentObservable() {
   TestSubscriber<Integer> ts = new TestSubscriber<>();
   Observable.mergeDelayError(
           Observable.just(Observable.just(1), Observable.just(2))
               .startWith(Observable.<Integer>error(new RuntimeException())))
       .subscribe(ts);
   ts.awaitTerminalEvent();
   ts.assertTerminated();
   ts.assertValues(1, 2);
   assertEquals(1, ts.errorCount());
 }
  /** Should request -1 for infinite */
  @Test
  public void testRequestFromFinalSubscribeWithoutRequestValue() {
    TestSubscriber<String> s = new TestSubscriber<>();
    final AtomicLong r = new AtomicLong();
    s.onSubscribe(
        new Subscription() {

          @Override
          public void request(long n) {
            r.set(n);
          }

          @Override
          public void cancel() {}
        });
    assertEquals(Long.MAX_VALUE, r.get());
  }
  @Test
  public void testScanWithRequestOne() {
    Observable<Integer> o =
        Observable.just(1, 2)
            .scan(
                0,
                new BiFunction<Integer, Integer, Integer>() {

                  @Override
                  public Integer apply(Integer t1, Integer t2) {
                    return t1 + t2;
                  }
                })
            .take(1);
    TestSubscriber<Integer> subscriber = new TestSubscriber<>();
    o.subscribe(subscriber);
    subscriber.assertValue(0);
    subscriber.assertTerminated();
    subscriber.assertNoErrors();
  }
  @Test
  public void testRequestFromChainedOperator() {
    TestSubscriber<String> s = new TestSubscriber<>();
    Operator<String, String> o =
        s1 ->
            new Subscriber<String>() {

              @Override
              public void onSubscribe(Subscription a) {
                s1.onSubscribe(a);
              }

              @Override
              public void onComplete() {}

              @Override
              public void onError(Throwable e) {}

              @Override
              public void onNext(String t) {}
            };
    s.request(10);
    Subscriber<? super String> ns = o.apply(s);

    final AtomicLong r = new AtomicLong();
    // set set the producer at the top of the chain (ns) and it should flow through the operator to
    // the (s) subscriber
    // and then it should request up with the value set on the final Subscriber (s)
    ns.onSubscribe(
        new Subscription() {

          @Override
          public void request(long n) {
            r.set(n);
          }

          @Override
          public void cancel() {}
        });
    assertEquals(10, r.get());
  }
  @Test
  public void testInitialValueEmittedWithProducer() {
    Observable<Integer> source = Observable.never();

    TestSubscriber<Integer> ts = new TestSubscriber<>();

    source
        .scan(
            0,
            new BiFunction<Integer, Integer, Integer>() {
              @Override
              public Integer apply(Integer t1, Integer t2) {
                return t1 + t2;
              }
            })
        .subscribe(ts);

    ts.assertNoErrors();
    ts.assertNotComplete();
    ts.assertValue(0);
  }
  @Test
  public void testRequestToObservable() {
    TestSubscriber<Integer> ts = new TestSubscriber<>();
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .subscribe(ts);
    assertEquals(3, requested.get());
  }
  @Test
  public void testRequestThroughTakeWhereRequestIsSmallerThanTake() {
    TestSubscriber<Integer> ts = new TestSubscriber<>((Long) null);
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .take(10)
        .subscribe(ts);
    assertEquals(3, requested.get());
  }
  @Test
  public void testRequestThroughTakeThatReducesRequest() {
    TestSubscriber<Integer> ts = new TestSubscriber<>((Long) null);
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .take(2)
        .subscribe(ts);

    // FIXME the take now requests Long.MAX_PATH if downstream requests at least the limit
    assertEquals(Long.MAX_VALUE, requested.get());
  }
  @Test
  public void testRequestFromDecoupledOperatorThatRequestsN() {
    TestSubscriber<String> s = new TestSubscriber<>();
    final AtomicLong innerR = new AtomicLong();
    Operator<String, String> o =
        child -> {
          // we want to decouple the chain so set our own Producer on the child instead of it coming
          // from the parent
          child.onSubscribe(
              new Subscription() {

                @Override
                public void request(long n) {
                  innerR.set(n);
                }

                @Override
                public void cancel() {}
              });

          AsyncObserver<String> as =
              new AsyncObserver<String>() {

                @Override
                protected void onStart() {
                  // we request 99 up to the parent
                  request(99);
                }

                @Override
                public void onComplete() {}

                @Override
                public void onError(Throwable e) {}

                @Override
                public void onNext(String t) {}
              };
          return as;
        };
    s.request(10);
    Subscriber<? super String> ns = o.apply(s);

    final AtomicLong r = new AtomicLong();
    // set set the producer at the top of the chain (ns) and it should flow through the operator to
    // the (s) subscriber
    // and then it should request up with the value set on the final Subscriber (s)
    ns.onSubscribe(
        new Subscription() {

          @Override
          public void request(long n) {
            r.set(n);
          }

          @Override
          public void cancel() {}
        });
    assertEquals(99, r.get());
    assertEquals(10, innerR.get());
  }