@Override public void run() { cf.subscribe(ts1); } };
@Override public void run() { cf.subscribe(ts2); } };
@Override public void run() { cf.subscribe(ts2); } };
@Override public void run() { cf.subscribe(ts1); } };
@Override public void run() { cf.subscribe(ts); } };
@Override public void run() { cf.subscribe(ts1); } };
@Override public void run() { cf.subscribe(ts2); } };
@Override public void subscribeActual(Subscriber<? super T> child) { source.subscribe(child); if (clients.incrementAndGet() == numberOfSubscribers) { source.connect(connection); } } }
@Override public void onNext(Integer t) { super.onNext(t); cancel(); onComplete(); cf.subscribe(ts2); } };
@Test public void testSubscribeAfterDisconnectThenConnect() { ConnectableFlowable<Integer> source = Flowable.just(1).publish(); TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>(); source.subscribe(ts1); Disposable connection = source.connect(); ts1.assertValue(1); ts1.assertNoErrors(); ts1.assertTerminated(); TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(); source.subscribe(ts2); Disposable connection2 = source.connect(); ts2.assertValue(1); ts2.assertNoErrors(); ts2.assertTerminated(); System.out.println(connection); System.out.println(connection2); }
@Test public void testBackpressure() { final AtomicLong requested = new AtomicLong(); Flowable<Integer> source = Flowable.range(1, 1000) .doOnRequest(new LongConsumer() { @Override public void accept(long t) { requested.addAndGet(t); } }); ConnectableFlowable<Integer> cf = source.replay(); TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>(10L); TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(90L); cf.subscribe(ts1); cf.subscribe(ts2); ts2.request(10); cf.connect(); ts1.assertValueCount(10); ts1.assertNotTerminated(); ts2.assertValueCount(100); ts2.assertNotTerminated(); Assert.assertEquals(100, requested.get()); }
@Test public void testBackpressureBounded() { final AtomicLong requested = new AtomicLong(); Flowable<Integer> source = Flowable.range(1, 1000) .doOnRequest(new LongConsumer() { @Override public void accept(long t) { requested.addAndGet(t); } }); ConnectableFlowable<Integer> cf = source.replay(50); TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>(10L); TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(90L); cf.subscribe(ts1); cf.subscribe(ts2); ts2.request(10); cf.connect(); ts1.assertValueCount(10); ts1.assertNotTerminated(); ts2.assertValueCount(100); ts2.assertNotTerminated(); Assert.assertEquals(100, requested.get()); }
@Test @Ignore("publish() keeps consuming the upstream if there are no subscribers, 3.x should change this") public void subscriberSwap() { final ConnectableFlowable<Integer> cf = Flowable.range(1, 5).publish(); cf.connect(); TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>() { @Override public void onNext(Integer t) { super.onNext(t); cancel(); onComplete(); } }; cf.subscribe(ts1); ts1.assertResult(1); TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(0); cf.subscribe(ts2); ts2 .assertEmpty() .requestMore(4) .assertResult(2, 3, 4, 5); }
@Test public void asyncFusedObserveOn() { ConnectableFlowable<Integer> cf = Flowable.range(0, 1000).observeOn(ImmediateThinScheduler.INSTANCE).publish(); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { List<TestSubscriber<Integer>> tss = new ArrayList<TestSubscriber<Integer>>(); for (int k = 1; k < j; k++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); tss.add(ts); cf.subscribe(ts); } Disposable connection = cf.connect(); for (TestSubscriber<Integer> ts : tss) { ts.awaitDone(5, TimeUnit.SECONDS) .assertSubscribed() .assertValueCount(1000) .assertNoErrors() .assertComplete(); } connection.dispose(); } } }
@Test public void unsubscribeOnNextRace() { for (int i = 0; i < TestHelper.RACE_DEFAULT_LOOPS; i++) { final PublishProcessor<Integer> pp = PublishProcessor.create(); final ConnectableFlowable<Integer> cf = pp.replay(); final TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>(); cf.subscribe(ts1); Runnable r1 = new Runnable() { @Override public void run() { ts1.dispose(); } }; Runnable r2 = new Runnable() { @Override public void run() { for (int j = 0; j < 1000; j++) { pp.onNext(j); } } }; TestHelper.race(r1, r2); } }
@Test public void just() { final PublishProcessor<Integer> pp = PublishProcessor.create(); ConnectableFlowable<Integer> cf = pp.publish(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>() { @Override public void onNext(Integer t) { super.onNext(t); pp.onComplete(); } }; cf.subscribe(ts); cf.connect(); pp.onNext(1); ts.assertResult(1); }
@Test public void addRemoveRace() { for (int i = 0; i < TestHelper.RACE_DEFAULT_LOOPS; i++) { final ConnectableFlowable<Integer> cf = Flowable.range(1, 3).replay(); final TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>(); final TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(); cf.subscribe(ts1); Runnable r1 = new Runnable() { @Override public void run() { ts1.cancel(); } }; Runnable r2 = new Runnable() { @Override public void run() { cf.subscribe(ts2); } }; TestHelper.race(r1, r2); } }
@Test public void subscriberLiveSwap() { final ConnectableFlowable<Integer> cf = Flowable.range(1, 5).publish(); final TestSubscriber<Integer> ts2 = new TestSubscriber<Integer>(0); TestSubscriber<Integer> ts1 = new TestSubscriber<Integer>() { @Override public void onNext(Integer t) { super.onNext(t); cancel(); onComplete(); cf.subscribe(ts2); } }; cf.subscribe(ts1); cf.connect(); ts1.assertResult(1); ts2 .assertEmpty() .requestMore(4) .assertResult(2, 3, 4, 5); }
@Test public void testConnectWithNoSubscriber() { TestScheduler scheduler = new TestScheduler(); ConnectableFlowable<Long> cf = Flowable.interval(10, 10, TimeUnit.MILLISECONDS, scheduler).take(3).publish(); cf.connect(); // Emit 0 scheduler.advanceTimeBy(15, TimeUnit.MILLISECONDS); TestSubscriber<Long> subscriber = new TestSubscriber<Long>(); cf.subscribe(subscriber); // Emit 1 and 2 scheduler.advanceTimeBy(50, TimeUnit.MILLISECONDS); subscriber.assertValues(1L, 2L); subscriber.assertNoErrors(); subscriber.assertTerminated(); }
@Test public void testZeroRequested() { ConnectableFlowable<Integer> source = Flowable.just(1).publish(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(0L); source.subscribe(ts); ts.assertNoValues(); ts.assertNoErrors(); ts.assertNotComplete(); source.connect(); ts.assertNoValues(); ts.assertNoErrors(); ts.assertNotComplete(); ts.request(5); ts.assertValue(1); ts.assertNoErrors(); ts.assertTerminated(); }