@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()); }