@Test public void exampleEquivalence() { TestScheduler scheduler = Schedulers.test(); TestSubscriber<Object> testerJoin = new TestSubscriber<>(); TestSubscriber<Object> testerGroupJoin = new TestSubscriber<>(); Observable<Long> left = Observable.interval(100, TimeUnit.MILLISECONDS, scheduler); Observable<Long> right = Observable.interval(100, TimeUnit.MILLISECONDS, scheduler); left.join( right, i -> Observable.timer(150, TimeUnit.MILLISECONDS, scheduler), i -> Observable.timer(0, TimeUnit.MILLISECONDS, scheduler), (l, r) -> Tuple.create(l, r)) .take(10) .subscribe(testerJoin); left.groupJoin( right, i -> Observable.timer(150, TimeUnit.MILLISECONDS, scheduler), i -> Observable.timer(0, TimeUnit.MILLISECONDS, scheduler), (l, rs) -> rs.map(r -> Tuple.create(l, r))) .flatMap(i -> i) .take(10) .subscribe(testerGroupJoin); scheduler.advanceTimeTo(600, TimeUnit.MILLISECONDS); testerJoin.assertReceivedOnNext(testerGroupJoin.getOnNextEvents()); }
@Test public void test() { TestSubscriber<Object> tester = new TestSubscriber<>(); TestScheduler scheduler = Schedulers.test(); Observable<Long> left = Observable.interval(100, TimeUnit.MILLISECONDS, scheduler).take(6); Observable<Long> right = Observable.interval(200, TimeUnit.MILLISECONDS, scheduler).take(3); left.groupJoin( right, i -> Observable.never(), i -> Observable.timer(0, TimeUnit.MILLISECONDS, scheduler), (l, rs) -> rs.toList().map(rl -> Tuple.create(l, rl))) .flatMap(i -> i) .subscribe(tester); scheduler.advanceTimeTo(600, TimeUnit.MILLISECONDS); tester.assertReceivedOnNext( Arrays.asList( Tuple.create(0L, Arrays.asList(0L, 1L, 2L)), Tuple.create(1L, Arrays.asList(0L, 1L, 2L)), Tuple.create(2L, Arrays.asList(1L, 2L)), Tuple.create(3L, Arrays.asList(1L, 2L)), Tuple.create(4L, Arrays.asList(2L)), Tuple.create(5L, Arrays.asList(2L)))); }
@Test public void testSwitchWhenInnerCompleteBeforeOuter() { Observable<Observable<String>> source = Observable.create( new Observable.OnSubscribeFunc<Observable<String>>() { @Override public Subscription onSubscribe(Observer<? super Observable<String>> observer) { publishNext( observer, 10, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 0, "one"); publishNext(observer, 10, "two"); publishCompleted(observer, 20); return Subscriptions.empty(); } })); publishNext( observer, 100, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 0, "three"); publishNext(observer, 10, "four"); publishCompleted(observer, 20); return Subscriptions.empty(); } })); publishCompleted(observer, 200); return Subscriptions.empty(); } }); Observable<String> sampled = Observable.create(OperationSwitch.switchDo(source)); sampled.subscribe(observer); InOrder inOrder = inOrder(observer); scheduler.advanceTimeTo(150, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onCompleted(); inOrder.verify(observer, times(1)).onNext("one"); inOrder.verify(observer, times(1)).onNext("two"); inOrder.verify(observer, times(1)).onNext("three"); inOrder.verify(observer, times(1)).onNext("four"); scheduler.advanceTimeTo(250, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onNext(anyString()); inOrder.verify(observer, times(1)).onCompleted(); }
@Test public void testAfterUnsubscribeCalledThenObserverOnNextNeverCalled() { final TestScheduler testScheduler = new TestScheduler(); @SuppressWarnings("unchecked") final Observer<Integer> observer = mock(Observer.class); final Subscription subscription = Observable.just(1, 2, 3).observeOn(testScheduler).subscribe(observer); subscription.unsubscribe(); testScheduler.advanceTimeBy(1, TimeUnit.SECONDS); final InOrder inOrder = inOrder(observer); inOrder.verify(observer, never()).onNext(anyInt()); inOrder.verify(observer, never()).onError(any(Exception.class)); inOrder.verify(observer, never()).onCompleted(); }
@Test public void test() { TestSubscriber<Long> tester = new TestSubscriber<>(); TestScheduler scheduler = Schedulers.test(); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS, scheduler) .map(i -> Observable.interval(30, TimeUnit.MILLISECONDS, scheduler).map(i2 -> i))) .distinctUntilChanged() .subscribe(tester); scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); tester.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 3L)); tester.assertNoErrors(); assertEquals(tester.getOnCompletedEvents().size(), 0); }
@Test public void testReplayWithBufferSize() { TestScheduler scheduler = Schedulers.test(); TestSubscriber<Long> tester = new TestSubscriber<>(); ConnectableObservable<Long> source = Observable.interval(1000, TimeUnit.MILLISECONDS, scheduler).take(5).replay(2, scheduler); source.connect(); scheduler.advanceTimeBy(4500, TimeUnit.MILLISECONDS); source.subscribe(tester); scheduler.triggerActions(); tester.assertReceivedOnNext(Arrays.asList(2L, 3L)); scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); tester.assertReceivedOnNext(Arrays.asList(2L, 3L, 4L)); }
@Test public void testTimestamp() { TestSubscriber<Timestamped<Long>> tester = new TestSubscriber<>(); TestScheduler scheduler = Schedulers.test(); Observable<Long> values = Observable.interval(100, TimeUnit.MILLISECONDS, scheduler); values.take(3).timestamp(scheduler).subscribe(tester); scheduler.advanceTimeBy(1, TimeUnit.SECONDS); assertEquals(tester.getOnNextEvents().get(0).getTimestampMillis(), 100); assertEquals(tester.getOnNextEvents().get(1).getTimestampMillis(), 200); assertEquals(tester.getOnNextEvents().get(2).getTimestampMillis(), 300); tester.assertTerminalEvent(); tester.assertNoErrors(); }
@Test public void testSwitchIssue737() { // https://github.com/Netflix/RxJava/issues/737 Observable<Observable<String>> source = Observable.create( new Observable.OnSubscribeFunc<Observable<String>>() { @Override public Subscription onSubscribe(Observer<? super Observable<String>> observer) { publishNext( observer, 0, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 10, "1-one"); publishNext(observer, 20, "1-two"); // The following events will be ignored publishNext(observer, 30, "1-three"); publishCompleted(observer, 40); return Subscriptions.empty(); } })); publishNext( observer, 25, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 10, "2-one"); publishNext(observer, 20, "2-two"); publishNext(observer, 30, "2-three"); publishCompleted(observer, 40); return Subscriptions.empty(); } })); publishCompleted(observer, 30); return Subscriptions.empty(); } }); Observable<String> sampled = Observable.create(OperationSwitch.switchDo(source)); sampled.subscribe(observer); scheduler.advanceTimeTo(1000, TimeUnit.MILLISECONDS); InOrder inOrder = inOrder(observer); inOrder.verify(observer, times(1)).onNext("1-one"); inOrder.verify(observer, times(1)).onNext("1-two"); inOrder.verify(observer, times(1)).onNext("2-one"); inOrder.verify(observer, times(1)).onNext("2-two"); inOrder.verify(observer, times(1)).onNext("2-three"); inOrder.verify(observer, times(1)).onCompleted(); inOrder.verifyNoMoreInteractions(); }
@Test public void testMultipleObservers() { Observer<Object> o1 = mock(Observer.class); Observer<Object> o2 = mock(Observer.class); TestScheduler s = new TestScheduler(); Observable<Long> timer = Observable.interval(500, TimeUnit.MILLISECONDS, s).take(2); Observable<Long> o = Observable.concat(timer, timer); o.subscribe(o1); o.subscribe(o2); InOrder inOrder1 = inOrder(o1); InOrder inOrder2 = inOrder(o2); s.advanceTimeBy(500, TimeUnit.MILLISECONDS); inOrder1.verify(o1, times(1)).onNext(0L); inOrder2.verify(o2, times(1)).onNext(0L); s.advanceTimeBy(500, TimeUnit.MILLISECONDS); inOrder1.verify(o1, times(1)).onNext(1L); inOrder2.verify(o2, times(1)).onNext(1L); s.advanceTimeBy(500, TimeUnit.MILLISECONDS); inOrder1.verify(o1, times(1)).onNext(0L); inOrder2.verify(o2, times(1)).onNext(0L); s.advanceTimeBy(500, TimeUnit.MILLISECONDS); inOrder1.verify(o1, times(1)).onNext(1L); inOrder2.verify(o2, times(1)).onNext(1L); inOrder1.verify(o1, times(1)).onCompleted(); inOrder2.verify(o2, times(1)).onCompleted(); verify(o1, never()).onError(any(Throwable.class)); verify(o2, never()).onError(any(Throwable.class)); }
private <T> void publishCompleted(final Observer<T> observer, long delay) { scheduler.schedule( new Action1<Inner>() { @Override public void call(Inner inner) { observer.onCompleted(); } }, delay, TimeUnit.MILLISECONDS); }
private <T> void publishError(final Observer<T> observer, long delay, final Throwable error) { scheduler.schedule( new Action1<Inner>() { @Override public void call(Inner inner) { observer.onError(error); } }, delay, TimeUnit.MILLISECONDS); }
private <T> void publishNext(final Observer<T> observer, long delay, final T value) { scheduler.schedule( new Action1<Inner>() { @Override public void call(Inner inner) { observer.onNext(value); } }, delay, TimeUnit.MILLISECONDS); }
@Test public void testReplayWithTime() throws InterruptedException { TestScheduler scheduler = Schedulers.test(); TestSubscriber<Long> tester = new TestSubscriber<>(); ConnectableObservable<Long> source = Observable.interval(1000, TimeUnit.MILLISECONDS, scheduler) .take(5) .replay(2000, TimeUnit.MILLISECONDS, scheduler); source.connect(); scheduler.advanceTimeBy(4500, TimeUnit.MILLISECONDS); source.subscribe(tester); tester.assertReceivedOnNext(Arrays.asList(2L, 3L)); scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); tester.assertReceivedOnNext(Arrays.asList(2L, 3L, 4L)); // 2 // 3 // 4 }
@Test public void testDelayedErrorDeliveryWhenSafeSubscriberUnsubscribes() { TestScheduler testScheduler = new TestScheduler(); Observable<Integer> source = Observable.concat(Observable.<Integer>error(new TestException()), Observable.just(1)); @SuppressWarnings("unchecked") Observer<Integer> o = mock(Observer.class); InOrder inOrder = inOrder(o); source.observeOn(testScheduler).subscribe(o); inOrder.verify(o, never()).onError(any(TestException.class)); testScheduler.advanceTimeBy(1, TimeUnit.SECONDS); inOrder.verify(o).onError(any(TestException.class)); inOrder.verify(o, never()).onNext(anyInt()); inOrder.verify(o, never()).onCompleted(); }
@Test public void observeSameOnMultipleSchedulers() { TestScheduler scheduler1 = new TestScheduler(); TestScheduler scheduler2 = new TestScheduler(); Observable<Integer> o = Observable.just(1, 2, 3); Observable<Integer> o1 = o.observeOn(scheduler1); Observable<Integer> o2 = o.observeOn(scheduler2); @SuppressWarnings("unchecked") Observer<Object> observer1 = mock(Observer.class); @SuppressWarnings("unchecked") Observer<Object> observer2 = mock(Observer.class); InOrder inOrder1 = inOrder(observer1); InOrder inOrder2 = inOrder(observer2); o1.subscribe(observer1); o2.subscribe(observer2); scheduler1.advanceTimeBy(1, TimeUnit.SECONDS); scheduler2.advanceTimeBy(1, TimeUnit.SECONDS); inOrder1.verify(observer1, times(1)).onNext(1); inOrder1.verify(observer1, times(1)).onNext(2); inOrder1.verify(observer1, times(1)).onNext(3); inOrder1.verify(observer1, times(1)).onCompleted(); verify(observer1, never()).onError(any(Throwable.class)); inOrder1.verifyNoMoreInteractions(); inOrder2.verify(observer2, times(1)).onNext(1); inOrder2.verify(observer2, times(1)).onNext(2); inOrder2.verify(observer2, times(1)).onNext(3); inOrder2.verify(observer2, times(1)).onCompleted(); verify(observer2, never()).onError(any(Throwable.class)); inOrder2.verifyNoMoreInteractions(); }
@Test public void testReplay() throws InterruptedException { TestScheduler scheduler = Schedulers.test(); TestSubscriber<Long> tester1 = new TestSubscriber<>(); TestSubscriber<Long> tester2 = new TestSubscriber<>(); ConnectableObservable<Long> cold = Observable.interval(200, TimeUnit.MILLISECONDS, scheduler).replay(); Subscription connection = cold.connect(); cold.subscribe(tester1); scheduler.advanceTimeBy(700, TimeUnit.MILLISECONDS); tester1.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L)); tester2.assertReceivedOnNext(Arrays.asList()); cold.subscribe(tester2); tester1.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L)); tester2.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L)); scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); tester1.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L)); tester2.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L)); connection.unsubscribe(); }
@Test public void testSample() { Observable<Long> source = Observable.create( new Observable.OnSubscribeFunc<Long>() { @Override public Subscription onSubscribe(final Observer<? super Long> observer1) { scheduler.schedule( new Action0() { @Override public void call() { observer1.onNext(1L); } }, 1, TimeUnit.SECONDS); scheduler.schedule( new Action0() { @Override public void call() { observer1.onNext(2L); } }, 2, TimeUnit.SECONDS); scheduler.schedule( new Action0() { @Override public void call() { observer1.onCompleted(); } }, 3, TimeUnit.SECONDS); return Subscriptions.empty(); } }); Observable<Long> sampled = Observable.create(OperationSample.sample(source, 400L, TimeUnit.MILLISECONDS, scheduler)); sampled.subscribe(observer); InOrder inOrder = inOrder(observer); scheduler.advanceTimeTo(800L, TimeUnit.MILLISECONDS); verify(observer, never()).onNext(any(Long.class)); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(1200L, TimeUnit.MILLISECONDS); inOrder.verify(observer, times(1)).onNext(1L); verify(observer, never()).onNext(2L); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(1600L, TimeUnit.MILLISECONDS); inOrder.verify(observer, times(1)).onNext(1L); verify(observer, never()).onNext(2L); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(2000L, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onNext(1L); inOrder.verify(observer, times(1)).onNext(2L); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(3000L, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onNext(1L); inOrder.verify(observer, times(2)).onNext(2L); verify(observer, times(1)).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); }
@Test public void testRefCount() { TestScheduler s = new TestScheduler(); Observable<Long> interval = Observable.interval(100, TimeUnit.MILLISECONDS, s).publish().refCount(); // subscribe list1 final List<Long> list1 = new ArrayList<Long>(); Subscription s1 = interval.subscribe( new Action1<Long>() { @Override public void call(Long t1) { list1.add(t1); } }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); assertEquals(2, list1.size()); assertEquals(0L, list1.get(0).longValue()); assertEquals(1L, list1.get(1).longValue()); // subscribe list2 final List<Long> list2 = new ArrayList<Long>(); Subscription s2 = interval.subscribe( new Action1<Long>() { @Override public void call(Long t1) { list2.add(t1); } }); s.advanceTimeBy(300, TimeUnit.MILLISECONDS); // list 1 should have 5 items assertEquals(5, list1.size()); assertEquals(2L, list1.get(2).longValue()); assertEquals(3L, list1.get(3).longValue()); assertEquals(4L, list1.get(4).longValue()); // list 2 should only have 3 items assertEquals(3, list2.size()); assertEquals(2L, list2.get(0).longValue()); assertEquals(3L, list2.get(1).longValue()); assertEquals(4L, list2.get(2).longValue()); // unsubscribe list1 s1.unsubscribe(); // advance further s.advanceTimeBy(300, TimeUnit.MILLISECONDS); // list 1 should still have 5 items assertEquals(5, list1.size()); // list 2 should have 6 items assertEquals(6, list2.size()); assertEquals(5L, list2.get(3).longValue()); assertEquals(6L, list2.get(4).longValue()); assertEquals(7L, list2.get(5).longValue()); // unsubscribe list2 s2.unsubscribe(); // advance further s.advanceTimeBy(1000, TimeUnit.MILLISECONDS); // subscribing a new one should start over because the source should have been unsubscribed // subscribe list3 final List<Long> list3 = new ArrayList<Long>(); Subscription s3 = interval.subscribe( new Action1<Long>() { @Override public void call(Long t1) { list3.add(t1); } }); s.advanceTimeBy(200, TimeUnit.MILLISECONDS); assertEquals(2, list3.size()); assertEquals(0L, list3.get(0).longValue()); assertEquals(1L, list3.get(1).longValue()); }
@Test public void testSwitchWithSubsequenceError() { Observable<Observable<String>> source = Observable.create( new Observable.OnSubscribeFunc<Observable<String>>() { @Override public Subscription onSubscribe(Observer<? super Observable<String>> observer) { publishNext( observer, 50, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 50, "one"); publishNext(observer, 100, "two"); return Subscriptions.empty(); } })); publishNext( observer, 130, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishError(observer, 0, new TestException()); return Subscriptions.empty(); } })); publishNext( observer, 150, Observable.create( new Observable.OnSubscribeFunc<String>() { @Override public Subscription onSubscribe(Observer<? super String> observer) { publishNext(observer, 50, "three"); return Subscriptions.empty(); } })); return Subscriptions.empty(); } }); Observable<String> sampled = Observable.create(OperationSwitch.switchDo(source)); sampled.subscribe(observer); InOrder inOrder = inOrder(observer); scheduler.advanceTimeTo(90, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onNext(anyString()); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(125, TimeUnit.MILLISECONDS); inOrder.verify(observer, times(1)).onNext("one"); verify(observer, never()).onCompleted(); verify(observer, never()).onError(any(Throwable.class)); scheduler.advanceTimeTo(250, TimeUnit.MILLISECONDS); inOrder.verify(observer, never()).onNext("three"); verify(observer, never()).onCompleted(); verify(observer, times(1)).onError(any(TestException.class)); }