Skip to content

Commit bebdec6

Browse files
authored
1.x: update AssertableSubscriber API and add Javadoc (#4824)
1 parent eb58e5c commit bebdec6

File tree

5 files changed

+438
-38
lines changed

5 files changed

+438
-38
lines changed

src/main/java/rx/Completable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2365,7 +2365,7 @@ public void call() {
23652365
}
23662366
});
23672367
}
2368-
2368+
23692369
// -------------------------------------------------------------------------
23702370
// Fluent test support, super handy and reduces test preparation boilerplate
23712371
// -------------------------------------------------------------------------

src/main/java/rx/Observable.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12642,7 +12642,7 @@ public final <T2, R> Observable<R> zipWith(Iterable<? extends T2> other, Func2<?
1264212642
public final <T2, R> Observable<R> zipWith(Observable<? extends T2> other, Func2<? super T, ? super T2, ? extends R> zipFunction) {
1264312643
return (Observable<R>)zip(this, other, zipFunction);
1264412644
}
12645-
12645+
1264612646
// -------------------------------------------------------------------------
1264712647
// Fluent test support, super handy and reduces test preparation boilerplate
1264812648
// -------------------------------------------------------------------------
@@ -12664,7 +12664,7 @@ public final AssertableSubscriber<T> test() {
1266412664
subscribe(ts);
1266512665
return ts;
1266612666
}
12667-
12667+
1266812668
/**
1266912669
* Creates an AssertableSubscriber with the initial request amount and subscribes
1267012670
* it to this Observable.
@@ -12675,6 +12675,7 @@ public final AssertableSubscriber<T> test() {
1267512675
* <dd>{@code test} does not operate by default on a particular {@link Scheduler}.</dd>
1267612676
* </dl>
1267712677
* @return the new AssertableSubscriber instance
12678+
* @param initialRequestAmount the amount to request from upstream upfront, non-negative (not verified)
1267812679
* @since 1.2.3
1267912680
*/
1268012681
@Experimental

src/main/java/rx/internal/observers/AssertableSubscriberObservable.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,11 @@ public AssertableSubscriber<T> assertReceivedOnNext(List<T> items) {
135135
* @see rx.observers.AssertableSubscriber#awaitValueCount(int, long, java.util.concurrent.TimeUnit)
136136
*/
137137
@Override
138-
public final boolean awaitValueCount(int expected, long timeout, TimeUnit unit) {
139-
return ts.awaitValueCount(expected, timeout, unit);
138+
public final AssertableSubscriber<T> awaitValueCount(int expected, long timeout, TimeUnit unit) {
139+
if (!ts.awaitValueCount(expected, timeout, unit)) {
140+
throw new AssertionError("Did not receive enough values in time. Expected: " + expected + ", Actual: " + ts.getValueCount());
141+
}
142+
return this;
140143
}
141144

142145
/* (non-Javadoc)
@@ -282,7 +285,7 @@ public AssertableSubscriber<T> assertValue(T value) {
282285
ts.assertValue(value);
283286
return this;
284287
}
285-
288+
286289
/* (non-Javadoc)
287290
* @see rx.observers.AssertableSubscriber#assertValuesAndClear(T, T)
288291
*/
@@ -307,4 +310,34 @@ public String toString() {
307310
return ts.toString();
308311
}
309312

313+
@Override
314+
public final AssertableSubscriber<T> assertResult(T... values) {
315+
ts.assertValues(values);
316+
ts.assertNoErrors();
317+
ts.assertCompleted();
318+
return this;
319+
}
320+
321+
@Override
322+
public final AssertableSubscriber<T> assertFailure(Class<? extends Throwable> errorClass, T... values) {
323+
ts.assertValues(values);
324+
ts.assertError(errorClass);
325+
ts.assertNotCompleted();
326+
return this;
327+
}
328+
329+
@Override
330+
public final AssertableSubscriber<T> assertFailureAndMessage(Class<? extends Throwable> errorClass, String message,
331+
T... values) {
332+
ts.assertValues(values);
333+
ts.assertError(errorClass);
334+
ts.assertNotCompleted();
335+
336+
String actualMessage = ts.getOnErrorEvents().get(0).getMessage();
337+
if (!(actualMessage == message || (message != null && message.equals(actualMessage)))) {
338+
throw new AssertionError("Error message differs. Expected: \'" + message + "\', Received: \'" + actualMessage + "\'");
339+
}
340+
341+
return this;
342+
}
310343
}

src/main/java/rx/observers/AssertableSubscriber.java

Lines changed: 196 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,70 +18,260 @@
1818
import java.util.List;
1919
import java.util.concurrent.TimeUnit;
2020

21-
import rx.Observer;
22-
import rx.Producer;
21+
import rx.*;
22+
import rx.annotations.Experimental;
2323
import rx.functions.Action0;
2424

25-
public interface AssertableSubscriber<T> extends Observer<T> {
25+
/**
26+
* Interface for asserting the state of a sequence under testing with a {@code test()}
27+
* method of a reactive base class.
28+
* <p>
29+
* This interface is not intended to be implemented outside of RxJava.
30+
* <p>
31+
* This interface extends {@link Observer} and allows injecting onXXX signals into
32+
* the testing process.
33+
* @param <T> the value type consumed by this Observer
34+
* @since 1.2.3
35+
*/
36+
@Experimental
37+
public interface AssertableSubscriber<T> extends Observer<T>, Subscription {
2638

39+
/**
40+
* Allows manually calling the {@code onStart} method of the underlying Subscriber.
41+
*/
2742
void onStart();
2843

44+
/**
45+
* Allows manually calling the {@code setProducer} method of the underlying Subscriber.
46+
* @param p the producer to use, not null
47+
*/
2948
void setProducer(Producer p);
3049

50+
/**
51+
* Returns the number of {@code onCompleted} signals received by this Observer.
52+
* @return the number of {@code onCompleted} signals received
53+
*/
3154
int getCompletions();
3255

56+
/**
57+
* Returns a list of received {@code onError} signals.
58+
* @return this
59+
*/
3360
List<Throwable> getOnErrorEvents();
3461

62+
/**
63+
* Returns the number of {@code onNext} signals received by this Observer in
64+
* a thread-safe manner; one can read up to this number of elements from
65+
* the {@code List} returned by {@link #getOnNextEvents()}.
66+
* @return the number of {@code onNext} signals received.
67+
*/
3568
int getValueCount();
3669

70+
/**
71+
* Requests the specified amount of items from upstream.
72+
* @param n the amount requested, non-negative
73+
* @return this
74+
*/
3775
AssertableSubscriber<T> requestMore(long n);
3876

77+
/**
78+
* Returns the list of received {@code onNext} events.
79+
* <p>If the sequence hasn't completed yet and is asynchronous, use the
80+
* {@link #getValueCount()} method to determine how many elements are safe
81+
* to be read from the list returned by this method.
82+
* @return the List of received {@code onNext} events.
83+
*/
3984
List<T> getOnNextEvents();
4085

86+
/**
87+
* Assert that this Observer received the given list of items as {@code onNext} signals
88+
* in the same order and with the default null-safe object equals comparison.
89+
* @param items the List of items expected
90+
* @return this
91+
*/
4192
AssertableSubscriber<T> assertReceivedOnNext(List<T> items);
4293

43-
boolean awaitValueCount(int expected, long timeout, TimeUnit unit);
94+
/**
95+
* Assert that this Observer receives at least the given number of {@code onNext}
96+
* signals within the specified timeout period.
97+
* <p>
98+
* Note that it is possible the AssertionError thrown by this method will
99+
* contain an actual value &gt;= to the expected one in case there is an emission
100+
* race or unexpected delay on the emitter side. In this case, increase the timeout
101+
* amount to avoid false positives.
102+
*
103+
* @param expected the expected (at least) number of {@code onNext} signals
104+
* @param timeout the timeout to wait to receive the given number of {@code onNext} events
105+
* @param unit the time unit
106+
* @return this
107+
*/
108+
AssertableSubscriber<T> awaitValueCount(int expected, long timeout, TimeUnit unit);
44109

110+
/**
111+
* Assert that this Observer received either an {@code onError} or {@code onCompleted} signal.
112+
* @return this
113+
*/
45114
AssertableSubscriber<T> assertTerminalEvent();
46115

116+
/**
117+
* Assert that this Observer has been unsubscribed via {@code unsubscribe()} or by a wrapping
118+
* {@code SafeSubscriber}.
119+
* @return this
120+
*/
47121
AssertableSubscriber<T> assertUnsubscribed();
48122

123+
/**
124+
* Assert that this Observer has not received any {@code onError} signal.
125+
* @return this
126+
*/
49127
AssertableSubscriber<T> assertNoErrors();
50128

129+
/**
130+
* Waits for an {@code onError} or {code onCompleted} terminal event indefinitely.
131+
* @return this
132+
*/
51133
AssertableSubscriber<T> awaitTerminalEvent();
52134

135+
136+
/**
137+
* Waits for an {@code onError} or {code onCompleted} terminal event for the given
138+
* amount of timeout.
139+
* @param timeout the time to wait for the terminal event
140+
* @param unit the time unit of the wait time
141+
* @return this
142+
*/
53143
AssertableSubscriber<T> awaitTerminalEvent(long timeout, TimeUnit unit);
54144

145+
/**
146+
* Waits for an {@code onError} or {code onCompleted} terminal event for the given
147+
* amount of timeout and unsubscribes the sequence if the timeout passed or the
148+
* wait itself is interrupted.
149+
* @param timeout the time to wait for the terminal event
150+
* @param unit the time unit of the wait time
151+
* @return this
152+
*/
55153
AssertableSubscriber<T> awaitTerminalEventAndUnsubscribeOnTimeout(long timeout,
56154
TimeUnit unit);
57155

156+
/**
157+
* Returns the Thread that has called the last {@code onNext}, {@code onError} or
158+
* {@code onCompleted} methods of this Observer.
159+
* @return this
160+
*/
58161
Thread getLastSeenThread();
59162

163+
/**
164+
* Assert that this Observer received exaclty one {@code onCompleted} signal.
165+
* @return this
166+
*/
60167
AssertableSubscriber<T> assertCompleted();
61168

169+
/**
170+
* Assert that this Observer received no {@code onCompleted} signal.
171+
* @return this
172+
*/
62173
AssertableSubscriber<T> assertNotCompleted();
63174

175+
/**
176+
* Assert that this Observer received one {@code onError} signal with
177+
* the given subclass of a Throwable as type.
178+
* @param clazz the expected type of the {@code onError} signal received
179+
* @return this
180+
*/
64181
AssertableSubscriber<T> assertError(Class<? extends Throwable> clazz);
65182

183+
/**
184+
* Assert that this Observer received one {@code onError} signal with the
185+
* object-equals of the given Throwable instance
186+
* @param throwable the Throwable instance expected
187+
* @return this
188+
*/
66189
AssertableSubscriber<T> assertError(Throwable throwable);
67190

191+
/**
192+
* Assert that no {@code onError} or {@code onCompleted} signals were received so far.
193+
* @return this
194+
*/
68195
AssertableSubscriber<T> assertNoTerminalEvent();
69196

197+
/**
198+
* Assert that no {@code onNext} signals were received so far.
199+
* @return this
200+
*/
70201
AssertableSubscriber<T> assertNoValues();
71202

203+
/**
204+
* Assert that this Observer received exactly the given count of
205+
* {@code onNext} signals.
206+
* @param count the expected number of {@code onNext} signals
207+
* @return this
208+
*/
72209
AssertableSubscriber<T> assertValueCount(int count);
73210

211+
/**
212+
* Assert that this Observer received exactly the given expected values
213+
* (compared via null-safe object equals) in the given order.
214+
* @param values the expected values
215+
* @return this
216+
*/
74217
AssertableSubscriber<T> assertValues(T... values);
75218

219+
/**
220+
* Assert that this Observer received exactly the given single expected value
221+
* (compared via null-safe object equals).
222+
* @param value the single value expected
223+
* @return this
224+
*/
76225
AssertableSubscriber<T> assertValue(T value);
77226

227+
/**
228+
* Assert that this Observer received exactly the given values (compared via
229+
* null-safe object equals) and if so, clears the internal buffer of the
230+
* underlying Subscriber of these values.
231+
* @param expectedFirstValue the first value expected
232+
* @param expectedRestValues the rest of the values expected
233+
* @return this
234+
*/
78235
AssertableSubscriber<T> assertValuesAndClear(T expectedFirstValue,
79236
T... expectedRestValues);
80237

238+
/**
239+
* Performs an action given by the Action0 callback in a fluent manner.
240+
* @param action the action to perform, not null
241+
* @return this
242+
*/
81243
AssertableSubscriber<T> perform(Action0 action);
82-
244+
245+
@Override
83246
void unsubscribe();
84-
247+
248+
@Override
85249
boolean isUnsubscribed();
86250

251+
/**
252+
* Assert that this Observer received the specified items in the given order followed
253+
* by a completion signal and no errors.
254+
* @param values the values expected
255+
* @return this
256+
*/
257+
AssertableSubscriber<T> assertResult(T... values);
258+
259+
/**
260+
* Assert that this Observer received the specified items in the given order followed
261+
* by an error signal of the given type (but no completion signal).
262+
* @param errorClass the expected Throwable subclass type
263+
* @param values the expected values
264+
* @return this
265+
*/
266+
AssertableSubscriber<T> assertFailure(Class<? extends Throwable> errorClass, T... values);
267+
268+
/**
269+
* Assert that this Observer received the specified items in the given order followed
270+
* by an error signal of the given type and with the exact error message (but no completion signal).
271+
* @param errorClass the expected Throwable subclass type
272+
* @param message the expected error message returned by {@link Throwable#getMessage()}
273+
* @param values the expected values
274+
* @return this
275+
*/
276+
AssertableSubscriber<T> assertFailureAndMessage(Class<? extends Throwable> errorClass, String message, T... values);
87277
}

0 commit comments

Comments
 (0)