Skip to content

Commit 550005c

Browse files
committed
Fix violations of the Observer contract.
1 parent b2697cb commit 550005c

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import static org.mockito.Mockito.never;
3232
import static org.mockito.Mockito.times;
3333
import static org.mockito.Mockito.verify;
34+
import static rx.testing.TrustedObservableTester.assertTrustedObservable;
3435

3536
/**
3637
* Returns a specified number of contiguous values from the start of an observable sequence.
@@ -97,12 +98,16 @@ public ItemObserver(Observer<T> observer) {
9798

9899
@Override
99100
public void onCompleted() {
100-
observer.onCompleted();
101+
if (counter.getAndSet(num) < num) {
102+
observer.onCompleted();
103+
}
101104
}
102105

103106
@Override
104107
public void onError(Exception e) {
105-
observer.onError(e);
108+
if (counter.getAndSet(num) < num) {
109+
observer.onError(e);
110+
}
106111
}
107112

108113
@Override
@@ -129,7 +134,7 @@ public static class UnitTest {
129134
@Test
130135
public void testTake1() {
131136
Observable<String> w = Observable.toObservable("one", "two", "three");
132-
Observable<String> take = Observable.create(take(w, 2));
137+
Observable<String> take = Observable.create(assertTrustedObservable(take(w, 2)));
133138

134139
@SuppressWarnings("unchecked")
135140
Observer<String> aObserver = mock(Observer.class);
@@ -144,7 +149,7 @@ public void testTake1() {
144149
@Test
145150
public void testTake2() {
146151
Observable<String> w = Observable.toObservable("one", "two", "three");
147-
Observable<String> take = Observable.create(take(w, 1));
152+
Observable<String> take = Observable.create(assertTrustedObservable(take(w, 1)));
148153

149154
@SuppressWarnings("unchecked")
150155
Observer<String> aObserver = mock(Observer.class);
@@ -158,14 +163,23 @@ public void testTake2() {
158163

159164
@Test
160165
public void testTakeDoesntLeakErrors() {
161-
Observable<String> source = Observable.concat(Observable.from("one"), Observable.<String>error(new Exception("test failed")));
162-
Observable.create(take(source, 1)).last();
166+
Observable<String> source = Observable.create(new Func1<Observer<String>, Subscription>()
167+
{
168+
@Override
169+
public Subscription call(Observer<String> observer)
170+
{
171+
observer.onNext("one");
172+
observer.onError(new Exception("test failed"));
173+
return Subscriptions.empty();
174+
}
175+
});
176+
Observable.create(assertTrustedObservable(take(source, 1))).last();
163177
}
164178

165179
@Test
166180
public void testTakeZeroDoesntLeakError() {
167-
Observable<String> source = Observable.<String>error(new Exception("test failed"));
168-
Observable.create(take(source, 0)).lastOrDefault("ok");
181+
Observable<String> source = Observable.error(new Exception("test failed"));
182+
Observable.create(assertTrustedObservable(take(source, 0))).lastOrDefault("ok");
169183
}
170184

171185
@Test
@@ -175,7 +189,7 @@ public void testUnsubscribeAfterTake() {
175189

176190
@SuppressWarnings("unchecked")
177191
Observer<String> aObserver = mock(Observer.class);
178-
Observable<String> take = Observable.create(take(w, 1));
192+
Observable<String> take = Observable.create(assertTrustedObservable(take(w, 1)));
179193
take.subscribe(aObserver);
180194

181195
// wait for the Observable to complete

0 commit comments

Comments
 (0)