/**
* Copyright (c) 2016-present, RxJava Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
* the License for the specific language governing permissions and limitations under the License.
*/
package io.reactivex;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import org.junit.*;
import org.reactivestreams.Publisher;
import io.reactivex.exceptions.TestException;
import io.reactivex.functions.Function;
import io.reactivex.observers.TestObserver;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subscribers.TestSubscriber;
public class XFlatMapTest {
@Rule
public Retry retry = new Retry(3, 1000, true);
static final int SLEEP_AFTER_CANCEL = 500;
final CyclicBarrier cb = new CyclicBarrier(2);
void sleep() throws Exception {
cb.await();
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
// ignored here
}
}
@Test
public void flowableFlowable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestSubscriber<Integer> ts = Flowable.just(1)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Integer, Publisher<Integer>>() {
@Override
public Publisher<Integer> apply(Integer v) throws Exception {
sleep();
return Flowable.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void flowableSingle() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestSubscriber<Integer> ts = Flowable.just(1)
.subscribeOn(Schedulers.io())
.flatMapSingle(new Function<Integer, Single<Integer>>() {
@Override
public Single<Integer> apply(Integer v) throws Exception {
sleep();
return Single.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void flowableMaybe() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestSubscriber<Integer> ts = Flowable.just(1)
.subscribeOn(Schedulers.io())
.flatMapMaybe(new Function<Integer, Maybe<Integer>>() {
@Override
public Maybe<Integer> apply(Integer v) throws Exception {
sleep();
return Maybe.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void flowableCompletable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Flowable.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void flowableCompletable2() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestSubscriber<Void> ts = Flowable.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.<Void>toFlowable()
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void observableFlowable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> apply(Integer v) throws Exception {
sleep();
return Observable.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void observerSingle() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMapSingle(new Function<Integer, Single<Integer>>() {
@Override
public Single<Integer> apply(Integer v) throws Exception {
sleep();
return Single.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void observerMaybe() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMapMaybe(new Function<Integer, Maybe<Integer>>() {
@Override
public Maybe<Integer> apply(Integer v) throws Exception {
sleep();
return Maybe.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void observerCompletable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void observerCompletable2() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.<Void>toObservable()
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void singleSingle() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Single.just(1)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Integer, Single<Integer>>() {
@Override
public Single<Integer> apply(Integer v) throws Exception {
sleep();
return Single.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void singleMaybe() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Single.just(1)
.subscribeOn(Schedulers.io())
.flatMapMaybe(new Function<Integer, Maybe<Integer>>() {
@Override
public Maybe<Integer> apply(Integer v) throws Exception {
sleep();
return Maybe.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void singleCompletable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Single.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void singleCompletable2() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Single.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.toSingleDefault(0)
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void maybeSingle() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Maybe.just(1)
.subscribeOn(Schedulers.io())
.flatMapSingle(new Function<Integer, Single<Integer>>() {
@Override
public Single<Integer> apply(Integer v) throws Exception {
sleep();
return Single.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void maybeMaybe() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Integer> ts = Maybe.just(1)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Integer, Maybe<Integer>>() {
@Override
public Maybe<Integer> apply(Integer v) throws Exception {
sleep();
return Maybe.<Integer>error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void maybeCompletable() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Maybe.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
@Test
public void maybeCompletable2() throws Exception {
List<Throwable> errors = TestHelper.trackPluginErrors();
try {
TestObserver<Void> ts = Maybe.just(1)
.subscribeOn(Schedulers.io())
.flatMapCompletable(new Function<Integer, Completable>() {
@Override
public Completable apply(Integer v) throws Exception {
sleep();
return Completable.error(new TestException());
}
})
.<Void>toMaybe()
.test();
cb.await();
Thread.sleep(50);
ts.cancel();
Thread.sleep(SLEEP_AFTER_CANCEL);
ts.assertEmpty();
assertTrue(errors.toString(), errors.isEmpty());
} finally {
RxJavaPlugins.reset();
}
}
}