/**
* 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.internal.operators.flowable;
import static org.junit.Assert.*;
import java.util.concurrent.atomic.*;
import org.junit.Test;
import org.reactivestreams.*;
import io.reactivex.*;
import io.reactivex.exceptions.TestException;
import io.reactivex.functions.*;
import io.reactivex.internal.fuseable.QueueSubscription;
import io.reactivex.observers.*;
import io.reactivex.processors.PublishProcessor;
import io.reactivex.subscribers.*;
public class FlowableIgnoreElementsTest {
@Test
public void testWithEmptyFlowable() {
assertTrue(Flowable.empty().ignoreElements().toFlowable().isEmpty().blockingGet());
}
@Test
public void testWithNonEmptyFlowable() {
assertTrue(Flowable.just(1, 2, 3).ignoreElements().toFlowable().isEmpty().blockingGet());
}
@Test
public void testUpstreamIsProcessedButIgnoredFlowable() {
final int num = 10;
final AtomicInteger upstreamCount = new AtomicInteger();
long count = Flowable.range(1, num)
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
upstreamCount.incrementAndGet();
}
})
.ignoreElements()
.toFlowable()
.count().blockingGet();
assertEquals(num, upstreamCount.get());
assertEquals(0, count);
}
@Test
public void testCompletedOkFlowable() {
TestSubscriber<Object> ts = new TestSubscriber<Object>();
Flowable.range(1, 10).ignoreElements().toFlowable().subscribe(ts);
ts.assertNoErrors();
ts.assertNoValues();
ts.assertTerminated();
// FIXME no longer testable
// ts.assertUnsubscribed();
}
@Test
public void testErrorReceivedFlowable() {
TestSubscriber<Object> ts = new TestSubscriber<Object>();
TestException ex = new TestException("boo");
Flowable.error(ex).ignoreElements().toFlowable().subscribe(ts);
ts.assertNoValues();
ts.assertTerminated();
// FIXME no longer testable
// ts.assertUnsubscribed();
ts.assertError(TestException.class);
ts.assertErrorMessage("boo");
}
@Test
public void testUnsubscribesFromUpstreamFlowable() {
final AtomicBoolean unsub = new AtomicBoolean();
Flowable.range(1, 10).concatWith(Flowable.<Integer>never())
.doOnCancel(new Action() {
@Override
public void run() {
unsub.set(true);
}})
.ignoreElements()
.toFlowable()
.subscribe().dispose();
assertTrue(unsub.get());
}
@Test(timeout = 10000)
public void testDoesNotHangAndProcessesAllUsingBackpressureFlowable() {
final AtomicInteger upstreamCount = new AtomicInteger();
final AtomicInteger count = new AtomicInteger(0);
int num = 10;
Flowable.range(1, num)
//
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
upstreamCount.incrementAndGet();
}
})
//
.ignoreElements()
.<Integer>toFlowable()
//
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
upstreamCount.incrementAndGet();
}
})
//
.subscribe(new DefaultSubscriber<Integer>() {
@Override
public void onStart() {
request(1);
}
@Override
public void onComplete() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer t) {
count.incrementAndGet();
}
});
assertEquals(num, upstreamCount.get());
assertEquals(0, count.get());
}
@Test
public void testWithEmpty() {
assertNull(Flowable.empty().ignoreElements().blockingGet());
}
@Test
public void testWithNonEmpty() {
assertNull(Flowable.just(1, 2, 3).ignoreElements().blockingGet());
}
@Test
public void testUpstreamIsProcessedButIgnored() {
final int num = 10;
final AtomicInteger upstreamCount = new AtomicInteger();
Object count = Flowable.range(1, num)
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
upstreamCount.incrementAndGet();
}
})
.ignoreElements()
.blockingGet();
assertEquals(num, upstreamCount.get());
assertNull(count);
}
@Test
public void testCompletedOk() {
TestObserver<Object> ts = new TestObserver<Object>();
Flowable.range(1, 10).ignoreElements().subscribe(ts);
ts.assertNoErrors();
ts.assertNoValues();
ts.assertTerminated();
// FIXME no longer testable
// ts.assertUnsubscribed();
}
@Test
public void testErrorReceived() {
TestObserver<Object> ts = new TestObserver<Object>();
TestException ex = new TestException("boo");
Flowable.error(ex).ignoreElements().subscribe(ts);
ts.assertNoValues();
ts.assertTerminated();
// FIXME no longer testable
// ts.assertUnsubscribed();
ts.assertError(TestException.class);
ts.assertErrorMessage("boo");
}
@Test
public void testUnsubscribesFromUpstream() {
final AtomicBoolean unsub = new AtomicBoolean();
Flowable.range(1, 10).concatWith(Flowable.<Integer>never())
.doOnCancel(new Action() {
@Override
public void run() {
unsub.set(true);
}})
.ignoreElements()
.subscribe().dispose();
assertTrue(unsub.get());
}
@Test(timeout = 10000)
public void testDoesNotHangAndProcessesAllUsingBackpressure() {
final AtomicInteger upstreamCount = new AtomicInteger();
final AtomicInteger count = new AtomicInteger(0);
int num = 10;
Flowable.range(1, num)
//
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
upstreamCount.incrementAndGet();
}
})
//
.ignoreElements()
//
.subscribe(new DisposableCompletableObserver() {
@Override
public void onComplete() {
}
@Override
public void onError(Throwable e) {
}
});
assertEquals(num, upstreamCount.get());
assertEquals(0, count.get());
}
@Test
public void cancel() {
PublishProcessor<Integer> pp = PublishProcessor.create();
TestSubscriber<Integer> ts = pp.ignoreElements().<Integer>toFlowable().test();
assertTrue(pp.hasSubscribers());
ts.cancel();
assertFalse(pp.hasSubscribers());
}
@Test
public void fused() {
TestSubscriber<Integer> ts = SubscriberFusion.newTest(QueueSubscription.ANY);
Flowable.just(1).hide().ignoreElements().<Integer>toFlowable()
.subscribe(ts);
ts.assertOf(SubscriberFusion.<Integer>assertFuseable())
.assertOf(SubscriberFusion.<Integer>assertFusionMode(QueueSubscription.ASYNC))
.assertResult();
}
@Test
public void fusedAPICalls() {
Flowable.just(1).hide().ignoreElements().<Integer>toFlowable()
.subscribe(new FlowableSubscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
@SuppressWarnings("unchecked")
QueueSubscription<Integer> qs = (QueueSubscription<Integer>)s;
try {
assertNull(qs.poll());
} catch (Exception ex) {
throw new AssertionError(ex);
}
assertTrue(qs.isEmpty());
qs.clear();
assertTrue(qs.isEmpty());
try {
assertNull(qs.poll());
} catch (Exception ex) {
throw new AssertionError(ex);
}
try {
qs.offer(1);
fail("Should have thrown!");
} catch (UnsupportedOperationException ex) {
// expected
}
try {
qs.offer(1, 2);
fail("Should have thrown!");
} catch (UnsupportedOperationException ex) {
// expected
}
}
@Override
public void onNext(Integer t) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
@Test
public void dispose() {
TestHelper.checkDisposed(Flowable.just(1).ignoreElements());
TestHelper.checkDisposed(Flowable.just(1).ignoreElements().toFlowable());
}
}