Skip to content

Commit f28bc5b

Browse files
Merge pull request ReactiveX#545 from akarnokd/ZipInfiniteFix
Fixed Zip issue with infinite streams.
2 parents 881db5c + e5912ed commit f28bc5b

File tree

2 files changed

+121
-5
lines changed

2 files changed

+121
-5
lines changed

rxjava-core/src/main/java/rx/operators/OperationZip.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,9 @@ public void onNext(T value) {
445445
if (io.done) {
446446
observer.onCompleted();
447447
cancel.unsubscribe();
448+
return;
448449
}
449-
return;
450+
continue;
450451
}
451452
Object v = io.queue.peek();
452453
if (v == NULL_SENTINEL) {
@@ -459,6 +460,8 @@ public void onNext(T value) {
459460
io.queue.poll();
460461
}
461462
observer.onNext(values);
463+
} else {
464+
break;
462465
}
463466
}
464467
} finally {

rxjava-core/src/test/java/rx/operators/OperationZipTest.java

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@
1515
*/
1616
package rx.operators;
1717

18-
import static org.mockito.Matchers.*;
19-
import static org.mockito.Mockito.*;
20-
import static rx.operators.OperationZip.*;
18+
import static org.mockito.Matchers.any;
19+
import static org.mockito.Matchers.anyString;
20+
import static org.mockito.Mockito.inOrder;
21+
import static org.mockito.Mockito.mock;
22+
import static org.mockito.Mockito.never;
23+
import static org.mockito.Mockito.times;
24+
import static org.mockito.Mockito.verify;
25+
import static rx.operators.OperationZip.zip;
2126

2227
import java.util.Arrays;
2328
import java.util.Collection;
2429

30+
import org.junit.Before;
2531
import org.junit.Test;
2632
import org.mockito.InOrder;
2733

@@ -38,7 +44,32 @@
3844
import rx.util.functions.Functions;
3945

4046
public class OperationZipTest {
41-
47+
Func2<String, String, String> concat2Strings;
48+
PublishSubject<String> s1;
49+
PublishSubject<String> s2;
50+
Observable<String> zipped;
51+
52+
Observer<String> observer;
53+
InOrder inOrder;
54+
@Before
55+
@SuppressWarnings("unchecked")
56+
public void setUp() {
57+
concat2Strings = new Func2<String, String, String>() {
58+
@Override
59+
public String call(String t1, String t2) {
60+
return t1 + "-" + t2;
61+
}
62+
};
63+
64+
s1 = PublishSubject.create();
65+
s2 = PublishSubject.create();
66+
zipped = Observable.zip(s1, s2, concat2Strings);
67+
68+
observer = mock(Observer.class);
69+
inOrder = inOrder(observer);
70+
71+
zipped.subscribe(observer);
72+
}
4273
@SuppressWarnings("unchecked")
4374
@Test
4475
public void testCollectionSizeDifferentThanFunction() {
@@ -702,4 +733,86 @@ public Subscription onSubscribe(Observer<? super String> Observer) {
702733
}
703734

704735
}
736+
737+
@Test
738+
public void testFirstCompletesThenSecondInfinite() {
739+
s1.onNext("a");
740+
s1.onNext("b");
741+
s1.onCompleted();
742+
s2.onNext("1");
743+
inOrder.verify(observer, times(1)).onNext("a-1");
744+
s2.onNext("2");
745+
inOrder.verify(observer, times(1)).onNext("b-2");
746+
inOrder.verify(observer, times(1)).onCompleted();
747+
inOrder.verifyNoMoreInteractions();
748+
}
749+
750+
@Test
751+
public void testSecondInfiniteThenFirstCompletes() {
752+
s2.onNext("1");
753+
s2.onNext("2");
754+
s1.onNext("a");
755+
inOrder.verify(observer, times(1)).onNext("a-1");
756+
s1.onNext("b");
757+
inOrder.verify(observer, times(1)).onNext("b-2");
758+
s1.onCompleted();
759+
inOrder.verify(observer, times(1)).onCompleted();
760+
inOrder.verifyNoMoreInteractions();
761+
}
762+
763+
@Test
764+
public void testSecondCompletesThenFirstInfinite() {
765+
s2.onNext("1");
766+
s2.onNext("2");
767+
s2.onCompleted();
768+
s1.onNext("a");
769+
inOrder.verify(observer, times(1)).onNext("a-1");
770+
s1.onNext("b");
771+
inOrder.verify(observer, times(1)).onNext("b-2");
772+
inOrder.verify(observer, times(1)).onCompleted();
773+
inOrder.verifyNoMoreInteractions();
774+
}
775+
776+
@Test
777+
public void testFirstInfiniteThenSecondCompletes() {
778+
s1.onNext("a");
779+
s1.onNext("b");
780+
s2.onNext("1");
781+
inOrder.verify(observer, times(1)).onNext("a-1");
782+
s2.onNext("2");
783+
inOrder.verify(observer, times(1)).onNext("b-2");
784+
s2.onCompleted();
785+
inOrder.verify(observer, times(1)).onCompleted();
786+
inOrder.verifyNoMoreInteractions();
787+
}
788+
@Test
789+
public void testFirstFails() {
790+
s2.onNext("a");
791+
s1.onError(new RuntimeException("Forced failure"));
792+
793+
inOrder.verify(observer, times(1)).onError(any(RuntimeException.class));
794+
795+
s2.onNext("b");
796+
s1.onNext("1");
797+
s1.onNext("2");
798+
799+
inOrder.verify(observer, never()).onCompleted();
800+
inOrder.verify(observer, never()).onNext(any(String.class));
801+
inOrder.verifyNoMoreInteractions();
802+
}
803+
@Test
804+
public void testSecondFails() {
805+
s1.onNext("a");
806+
s1.onNext("b");
807+
s2.onError(new RuntimeException("Forced failure"));
808+
809+
inOrder.verify(observer, times(1)).onError(any(RuntimeException.class));
810+
811+
s2.onNext("1");
812+
s2.onNext("2");
813+
814+
inOrder.verify(observer, never()).onCompleted();
815+
inOrder.verify(observer, never()).onNext(any(String.class));
816+
inOrder.verifyNoMoreInteractions();
817+
}
705818
}

0 commit comments

Comments
 (0)