@Override public void connect(Consumer<? super Disposable> connection) { cf.connect(connection); }
@Override public void run() { cf.connect(); } };
@Override public void run() { cf.connect(); } };
@Override public void subscribeActual(Subscriber<? super T> child) { source.subscribe(child); if (clients.incrementAndGet() == numberOfSubscribers) { source.connect(connection); } } }
/** * Instructs the {@code ConnectableFlowable} to begin emitting the items from its underlying * {@link Flowable} to its {@link Subscriber}s. * <p> * To disconnect from a synchronous source, use the {@link #connect(io.reactivex.functions.Consumer)} method. * * @return the subscription representing the connection * @see <a href="http://reactivex.io/documentation/operators/connect.html">ReactiveX documentation: Connect</a> */ public final Disposable connect() { ConnectConsumer cc = new ConnectConsumer(); connect(cc); return cc.disposable; }
@Test public void testNoDisconnectSomeoneElse() { ConnectableFlowable<Object> source = Flowable.never().publish(); Disposable connection1 = source.connect(); Disposable connection2 = source.connect(); connection1.dispose(); Disposable connection3 = source.connect(); connection2.dispose(); assertTrue(checkPublishDisposed(connection1)); assertTrue(checkPublishDisposed(connection2)); assertFalse(checkPublishDisposed(connection3)); }
@Test(expected = TestException.class) public void createBufferFactoryCrash() { FlowableReplay.create(Flowable.just(1), new Callable<ReplayBuffer<Integer>>() { @Override public ReplayBuffer<Integer> call() throws Exception { throw new TestException(); } }) .connect(); }
@Test public void empty() { ConnectableFlowable<Integer> cf = Flowable.<Integer>empty().publish(); cf.connect(); }
@Test public void connectThrows() { ConnectableFlowable<Integer> cf = Flowable.<Integer>empty().publish(); try { cf.connect(new Consumer<Disposable>() { @Override public void accept(Disposable d) throws Exception { throw new TestException(); } }); } catch (TestException ex) { // expected } }
@Test public void delayedUpstreamOnSubscribe() { final Subscriber<?>[] sub = { null }; new Flowable<Integer>() { @Override protected void subscribeActual(Subscriber<? super Integer> s) { sub[0] = s; } } .replay() .connect() .dispose(); BooleanSubscription bs = new BooleanSubscription(); sub[0].onSubscribe(bs); assertTrue(bs.isCancelled()); }
@Test public void delayedUpstreamOnSubscribe() { final Subscriber<?>[] sub = { null }; new Flowable<Integer>() { @Override protected void subscribeActual(Subscriber<? super Integer> s) { sub[0] = s; } } .publish() .connect() .dispose(); BooleanSubscription bs = new BooleanSubscription(); sub[0].onSubscribe(bs); assertTrue(bs.isCancelled()); }
@Test public void removeNotPresent() { final AtomicReference<PublishSubscriber<Integer>> ref = new AtomicReference<PublishSubscriber<Integer>>(); final ConnectableFlowable<Integer> cf = new Flowable<Integer>() { @Override @SuppressWarnings("unchecked") protected void subscribeActual(Subscriber<? super Integer> s) { s.onSubscribe(new BooleanSubscription()); ref.set((PublishSubscriber<Integer>)s); } }.publish(); cf.connect(); ref.get().add(new InnerSubscriber<Integer>(new TestSubscriber<Integer>())); ref.get().remove(null); }
@Test public void preNextConnect() { for (int i = 0; i < TestHelper.RACE_DEFAULT_LOOPS; i++) { final ConnectableFlowable<Integer> cf = Flowable.<Integer>empty().publish(); cf.connect(); Runnable r1 = new Runnable() { @Override public void run() { cf.test(); } }; TestHelper.race(r1, r1); } }
@Test public void take() { ConnectableFlowable<Integer> cf = Flowable.range(1, 2).publish(); TestSubscriber<Integer> ts = cf.take(1).test(); cf.connect(); ts.assertResult(1); }
@Test public void replayIsUnsubscribed() { ConnectableFlowable<Integer> cf = Flowable.just(1) .replay(); if (cf instanceof Disposable) { assertTrue(((Disposable)cf).isDisposed()); Disposable connection = cf.connect(); assertFalse(((Disposable)cf).isDisposed()); connection.dispose(); assertTrue(((Disposable)cf).isDisposed()); } }
@Test public void testTakeUntilWithPublishedStream() { Flowable<Integer> xs = Flowable.range(0, Flowable.bufferSize() * 2); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); ConnectableFlowable<Integer> xsp = xs.publish(); xsp.takeUntil(xsp.skipWhile(new Predicate<Integer>() { @Override public boolean test(Integer i) { return i <= 3; } })).subscribe(ts); xsp.connect(); System.out.println(ts.values()); }
@Test public void noErrorLoss() { List<Throwable> errors = TestHelper.trackPluginErrors(); try { ConnectableFlowable<Object> cf = Flowable.error(new TestException()).publish(); cf.connect(); TestHelper.assertUndeliverable(errors, 0, TestException.class); } finally { RxJavaPlugins.reset(); } }
@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 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(); }