/**
* 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.assertEquals;
import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Test;
import org.reactivestreams.Subscriber;
import io.reactivex.*;
import io.reactivex.functions.LongConsumer;
import io.reactivex.subscribers.TestSubscriber;
public class FlowableSkipTest {
@Test
public void testSkipNegativeElements() {
Flowable<String> skip = Flowable.just("one", "two", "three").skip(-99);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, times(1)).onNext("one");
verify(observer, times(1)).onNext("two");
verify(observer, times(1)).onNext("three");
verify(observer, never()).onError(any(Throwable.class));
verify(observer, times(1)).onComplete();
}
@Test
public void testSkipZeroElements() {
Flowable<String> skip = Flowable.just("one", "two", "three").skip(0);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, times(1)).onNext("one");
verify(observer, times(1)).onNext("two");
verify(observer, times(1)).onNext("three");
verify(observer, never()).onError(any(Throwable.class));
verify(observer, times(1)).onComplete();
}
@Test
public void testSkipOneElement() {
Flowable<String> skip = Flowable.just("one", "two", "three").skip(1);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, never()).onNext("one");
verify(observer, times(1)).onNext("two");
verify(observer, times(1)).onNext("three");
verify(observer, never()).onError(any(Throwable.class));
verify(observer, times(1)).onComplete();
}
@Test
public void testSkipTwoElements() {
Flowable<String> skip = Flowable.just("one", "two", "three").skip(2);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, never()).onNext("one");
verify(observer, never()).onNext("two");
verify(observer, times(1)).onNext("three");
verify(observer, never()).onError(any(Throwable.class));
verify(observer, times(1)).onComplete();
}
@Test
public void testSkipEmptyStream() {
Flowable<String> w = Flowable.empty();
Flowable<String> skip = w.skip(1);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, never()).onNext(any(String.class));
verify(observer, never()).onError(any(Throwable.class));
verify(observer, times(1)).onComplete();
}
@Test
public void testSkipMultipleObservers() {
Flowable<String> skip = Flowable.just("one", "two", "three")
.skip(2);
Subscriber<String> observer1 = TestHelper.mockSubscriber();
skip.subscribe(observer1);
Subscriber<String> observer2 = TestHelper.mockSubscriber();
skip.subscribe(observer2);
verify(observer1, times(1)).onNext(any(String.class));
verify(observer1, never()).onError(any(Throwable.class));
verify(observer1, times(1)).onComplete();
verify(observer2, times(1)).onNext(any(String.class));
verify(observer2, never()).onError(any(Throwable.class));
verify(observer2, times(1)).onComplete();
}
@Test
public void testSkipError() {
Exception e = new Exception();
Flowable<String> ok = Flowable.just("one");
Flowable<String> error = Flowable.error(e);
Flowable<String> skip = Flowable.concat(ok, error).skip(100);
Subscriber<String> observer = TestHelper.mockSubscriber();
skip.subscribe(observer);
verify(observer, never()).onNext(any(String.class));
verify(observer, times(1)).onError(e);
verify(observer, never()).onComplete();
}
@Test
public void testBackpressureMultipleSmallAsyncRequests() throws InterruptedException {
final AtomicLong requests = new AtomicLong(0);
TestSubscriber<Long> ts = new TestSubscriber<Long>(0L);
Flowable.interval(100, TimeUnit.MILLISECONDS)
.doOnRequest(new LongConsumer() {
@Override
public void accept(long n) {
requests.addAndGet(n);
}
}).skip(4).subscribe(ts);
Thread.sleep(100);
ts.request(1);
ts.request(1);
Thread.sleep(100);
ts.dispose();
// FIXME not assertable anymore
// ts.assertUnsubscribed();
ts.assertNoErrors();
assertEquals(6, requests.get());
}
@Test
public void testRequestOverflowDoesNotOccur() {
TestSubscriber<Integer> ts = new TestSubscriber<Integer>(Long.MAX_VALUE - 1);
Flowable.range(1, 10).skip(5).subscribe(ts);
ts.assertTerminated();
ts.assertComplete();
ts.assertNoErrors();
assertEquals(Arrays.asList(6,7,8,9,10), ts.values());
}
@Test
public void dispose() {
TestHelper.checkDisposed(Flowable.just(1).skip(2));
}
}