@Override public void run() { PublishSubject<Integer> source = PublishSubject.create(); source.timeout(timeoutFunc, Observable.just(3)).subscribe(to); source.onNext(1); // start timeout try { if (!enteredTimeoutOne.await(30, TimeUnit.SECONDS)) { latchTimeout.set(true); } } catch (InterruptedException e) { e.printStackTrace(); } source.onNext(2); // disable timeout try { if (!timeoutEmittedOne.await(30, TimeUnit.SECONDS)) { latchTimeout.set(true); } } catch (InterruptedException e) { e.printStackTrace(); } source.onComplete(); }
@Before public void setUp() { underlyingSubject = PublishSubject.create(); testScheduler = new TestScheduler(); withTimeout = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, testScheduler); }
@Test public void testTimeoutSelectorFirstObservableThrows() { PublishSubject<Integer> source = PublishSubject.create(); final PublishSubject<Integer> timeout = PublishSubject.create(); Function<Integer, Observable<Integer>> timeoutFunc = new Function<Integer, Observable<Integer>>() { @Override public Observable<Integer> apply(Integer t1) { return timeout; } }; Observable<Integer> other = Observable.fromIterable(Arrays.asList(100)); Observer<Object> o = TestHelper.mockObserver(); source.timeout(Observable.<Integer> error(new TestException()), timeoutFunc, other).subscribe(o); verify(o).onError(any(TestException.class)); verify(o, never()).onNext(any()); verify(o, never()).onComplete(); }
@Test public void testTimeoutSelectorSubsequentObservableThrows() { PublishSubject<Integer> source = PublishSubject.create(); final PublishSubject<Integer> timeout = PublishSubject.create(); Function<Integer, Observable<Integer>> timeoutFunc = new Function<Integer, Observable<Integer>>() { @Override public Observable<Integer> apply(Integer t1) { return Observable.<Integer> error(new TestException()); } }; Observable<Integer> other = Observable.fromIterable(Arrays.asList(100)); Observer<Object> o = TestHelper.mockObserver(); InOrder inOrder = inOrder(o); source.timeout(timeout, timeoutFunc, other).subscribe(o); source.onNext(1); inOrder.verify(o).onNext(1); inOrder.verify(o).onError(any(TestException.class)); verify(o, never()).onComplete(); }
@Test public void shouldSwitchToOtherIfOnErrorNotWithinTimeout() { Observable<String> other = Observable.just("a", "b", "c"); Observable<String> source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, testScheduler, other); Observer<String> observer = TestHelper.mockObserver(); TestObserver<String> to = new TestObserver<String>(observer); source.subscribe(to); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onNext("One"); testScheduler.advanceTimeBy(4, TimeUnit.SECONDS); underlyingSubject.onError(new UnsupportedOperationException()); InOrder inOrder = inOrder(observer); inOrder.verify(observer, times(1)).onNext("One"); inOrder.verify(observer, times(1)).onNext("a"); inOrder.verify(observer, times(1)).onNext("b"); inOrder.verify(observer, times(1)).onNext("c"); inOrder.verify(observer, times(1)).onComplete(); inOrder.verifyNoMoreInteractions(); to.dispose(); }
@Test public void testTimeoutSelectorSubsequentThrows() { PublishSubject<Integer> source = PublishSubject.create(); final PublishSubject<Integer> timeout = PublishSubject.create(); Function<Integer, Observable<Integer>> timeoutFunc = new Function<Integer, Observable<Integer>>() { @Override public Observable<Integer> apply(Integer t1) { throw new TestException(); } }; Observable<Integer> other = Observable.fromIterable(Arrays.asList(100)); Observer<Object> o = TestHelper.mockObserver(); InOrder inOrder = inOrder(o); source.timeout(timeout, timeoutFunc, other).subscribe(o); source.onNext(1); inOrder.verify(o).onNext(1); inOrder.verify(o).onError(any(TestException.class)); verify(o, never()).onComplete(); }
@Test public void shouldSwitchToOtherIfOnNextNotWithinTimeout() { Observable<String> other = Observable.just("a", "b", "c"); Observable<String> source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, testScheduler, other); Observer<String> observer = TestHelper.mockObserver(); TestObserver<String> to = new TestObserver<String>(observer); source.subscribe(to); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onNext("One"); testScheduler.advanceTimeBy(4, TimeUnit.SECONDS); underlyingSubject.onNext("Two"); InOrder inOrder = inOrder(observer); inOrder.verify(observer, times(1)).onNext("One"); inOrder.verify(observer, times(1)).onNext("a"); inOrder.verify(observer, times(1)).onNext("b"); inOrder.verify(observer, times(1)).onNext("c"); inOrder.verify(observer, times(1)).onComplete(); inOrder.verifyNoMoreInteractions(); to.dispose(); }
@Test public void shouldSwitchToOtherIfOnCompletedNotWithinTimeout() { Observable<String> other = Observable.just("a", "b", "c"); Observable<String> source = underlyingSubject.timeout(TIMEOUT, TIME_UNIT, testScheduler, other); Observer<String> observer = TestHelper.mockObserver(); TestObserver<String> to = new TestObserver<String>(observer); source.subscribe(to); testScheduler.advanceTimeBy(2, TimeUnit.SECONDS); underlyingSubject.onNext("One"); testScheduler.advanceTimeBy(4, TimeUnit.SECONDS); underlyingSubject.onComplete(); InOrder inOrder = inOrder(observer); inOrder.verify(observer, times(1)).onNext("One"); inOrder.verify(observer, times(1)).onNext("a"); inOrder.verify(observer, times(1)).onNext("b"); inOrder.verify(observer, times(1)).onNext("c"); inOrder.verify(observer, times(1)).onComplete(); inOrder.verifyNoMoreInteractions(); to.dispose(); }
@Test public void testTimeoutSelectorWithFirstTimeoutFirstAndNoOtherObservable() { PublishSubject<Integer> source = PublishSubject.create(); final PublishSubject<Integer> timeout = PublishSubject.create(); Function<Integer, Observable<Integer>> timeoutFunc = new Function<Integer, Observable<Integer>>() { @Override public Observable<Integer> apply(Integer t1) { return PublishSubject.create(); } }; Observer<Object> o = TestHelper.mockObserver(); source.timeout(timeout, timeoutFunc).subscribe(o); timeout.onNext(1); InOrder inOrder = inOrder(o); inOrder.verify(o).onError(isA(TimeoutException.class)); inOrder.verifyNoMoreInteractions(); }
@Test public void disposedUpfrontFallback() { PublishSubject<Object> ps = PublishSubject.create(); final AtomicInteger counter = new AtomicInteger(); Observable<Object> timeoutAndFallback = Observable.never().doOnSubscribe(new Consumer<Disposable>() { @Override public void accept(Disposable d) throws Exception { counter.incrementAndGet(); } }); ps .timeout(timeoutAndFallback, Functions.justFunction(timeoutAndFallback), timeoutAndFallback) .test(true) .assertEmpty(); assertEquals(0, counter.get()); } }
@Test public void testTimeoutSelectorWithTimeoutFirstAndNoOtherObservable() { PublishSubject<Integer> source = PublishSubject.create(); final PublishSubject<Integer> timeout = PublishSubject.create(); Function<Integer, Observable<Integer>> timeoutFunc = new Function<Integer, Observable<Integer>>() { @Override public Observable<Integer> apply(Integer t1) { return timeout; } }; Observer<Object> o = TestHelper.mockObserver(); source.timeout(PublishSubject.create(), timeoutFunc).subscribe(o); source.onNext(1); timeout.onNext(1); InOrder inOrder = inOrder(o); inOrder.verify(o).onNext(1); inOrder.verify(o).onError(isA(TimeoutException.class)); inOrder.verifyNoMoreInteractions(); }
@Test public void disposedUpfront() { PublishSubject<Integer> ps = PublishSubject.create(); final AtomicInteger counter = new AtomicInteger(); Observable<Object> timeoutAndFallback = Observable.never().doOnSubscribe(new Consumer<Disposable>() { @Override public void accept(Disposable d) throws Exception { counter.incrementAndGet(); } }); ps .timeout(timeoutAndFallback, Functions.justFunction(timeoutAndFallback)) .test(true) .assertEmpty(); assertEquals(0, counter.get()); }
@Test public void emptyInner() { PublishSubject<Integer> ps = PublishSubject.create(); TestObserver<Integer> to = ps .timeout(Functions.justFunction(Observable.empty())) .test(); ps.onNext(1); to.assertFailure(TimeoutException.class, 1); }
@Test public void timedFallbackTake() { PublishSubject<Integer> ps = PublishSubject.create(); TestObserver<Integer> to = ps.timeout(1, TimeUnit.DAYS, Observable.just(2)) .take(1) .test(); assertTrue(ps.hasObservers()); ps.onNext(1); assertFalse(ps.hasObservers()); to.assertResult(1); }
@Test public void selectorFallbackTake() { PublishSubject<Integer> ps = PublishSubject.create(); TestObserver<Integer> to = ps .timeout(Functions.justFunction(Observable.never()), Observable.just(2)) .take(1) .test(); assertTrue(ps.hasObservers()); ps.onNext(1); assertFalse(ps.hasObservers()); to.assertResult(1); }
@Test public void shouldUnsubscribeFromUnderlyingSubscriptionOnDispose() { final PublishSubject<String> subject = PublishSubject.create(); final TestScheduler scheduler = new TestScheduler(); final TestObserver<String> observer = subject .timeout(100, TimeUnit.MILLISECONDS, scheduler) .test(); assertTrue(subject.hasObservers()); observer.dispose(); assertFalse(subject.hasObservers()); }
@Test public void timedTake() { PublishSubject<Integer> ps = PublishSubject.create(); TestObserver<Integer> to = ps.timeout(1, TimeUnit.DAYS) .take(1) .test(); assertTrue(ps.hasObservers()); ps.onNext(1); assertFalse(ps.hasObservers()); to.assertResult(1); }
@Test public void selectorTake() { PublishSubject<Integer> ps = PublishSubject.create(); TestObserver<Integer> to = ps .timeout(Functions.justFunction(Observable.never())) .take(1) .test(); assertTrue(ps.hasObservers()); ps.onNext(1); assertFalse(ps.hasObservers()); to.assertResult(1); }