/**
* Copyright 2014 Netflix, Inc.
*
* 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 rx.internal.operators;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import rx.Observable;
import rx.Observer;
import rx.functions.Func1;
import rx.functions.Func2;
import rx.subjects.PublishSubject;
public class OnSubscribeJoinTest {
@Mock
Observer<Object> observer;
Func2<Integer, Integer, Integer> add = new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer t1, Integer t2) {
return t1 + t2;
}
};
<T> Func1<Integer, Observable<T>> just(final Observable<T> observable) {
return new Func1<Integer, Observable<T>>() {
@Override
public Observable<T> call(Integer t1) {
return observable;
}
};
}
@Before
public void before() {
MockitoAnnotations.initMocks(this);
}
@Test
public void normal1() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
source1.onNext(2);
source1.onNext(4);
source2.onNext(16);
source2.onNext(32);
source2.onNext(64);
source1.onCompleted();
source2.onCompleted();
verify(observer, times(1)).onNext(17);
verify(observer, times(1)).onNext(18);
verify(observer, times(1)).onNext(20);
verify(observer, times(1)).onNext(33);
verify(observer, times(1)).onNext(34);
verify(observer, times(1)).onNext(36);
verify(observer, times(1)).onNext(65);
verify(observer, times(1)).onNext(66);
verify(observer, times(1)).onNext(68);
verify(observer, times(1)).onCompleted();
verify(observer, never()).onError(any(Throwable.class));
}
@Test
public void normal1WithDuration() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
PublishSubject<Integer> duration1 = PublishSubject.create();
Observable<Integer> m = source1.join(source2,
just(duration1),
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
source1.onNext(2);
source2.onNext(16);
duration1.onNext(1);
source1.onNext(4);
source1.onNext(8);
source1.onCompleted();
source2.onCompleted();
verify(observer, times(1)).onNext(17);
verify(observer, times(1)).onNext(18);
verify(observer, times(1)).onNext(20);
verify(observer, times(1)).onNext(24);
verify(observer, times(1)).onCompleted();
verify(observer, never()).onError(any(Throwable.class));
}
@Test
public void normal2() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
source1.onNext(2);
source1.onCompleted();
source2.onNext(16);
source2.onNext(32);
source2.onNext(64);
source2.onCompleted();
verify(observer, times(1)).onNext(17);
verify(observer, times(1)).onNext(18);
verify(observer, times(1)).onNext(33);
verify(observer, times(1)).onNext(34);
verify(observer, times(1)).onNext(65);
verify(observer, times(1)).onNext(66);
verify(observer, times(1)).onCompleted();
verify(observer, never()).onError(any(Throwable.class));
}
@Test
public void leftThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(Observable.never()), add);
m.subscribe(observer);
source2.onNext(1);
source1.onError(new RuntimeException("Forced failure"));
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void rightThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
source2.onError(new RuntimeException("Forced failure"));
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void leftDurationThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> duration1 = Observable.<Integer> error(new RuntimeException("Forced failure"));
Observable<Integer> m = source1.join(source2,
just(duration1),
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void rightDurationThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Observable<Integer> duration1 = Observable.<Integer> error(new RuntimeException("Forced failure"));
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(duration1), add);
m.subscribe(observer);
source2.onNext(1);
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void leftDurationSelectorThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Func1<Integer, Observable<Integer>> fail = new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer t1) {
throw new RuntimeException("Forced failure");
}
};
Observable<Integer> m = source1.join(source2,
fail,
just(Observable.never()), add);
m.subscribe(observer);
source1.onNext(1);
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void rightDurationSelectorThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Func1<Integer, Observable<Integer>> fail = new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer t1) {
throw new RuntimeException("Forced failure");
}
};
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
fail, add);
m.subscribe(observer);
source2.onNext(1);
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
@Test
public void resultSelectorThrows() {
PublishSubject<Integer> source1 = PublishSubject.create();
PublishSubject<Integer> source2 = PublishSubject.create();
Func2<Integer, Integer, Integer> fail = new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer t1, Integer t2) {
throw new RuntimeException("Forced failure");
}
};
Observable<Integer> m = source1.join(source2,
just(Observable.never()),
just(Observable.never()), fail);
m.subscribe(observer);
source1.onNext(1);
source2.onNext(2);
verify(observer, times(1)).onError(any(Throwable.class));
verify(observer, never()).onCompleted();
verify(observer, never()).onNext(any());
}
}