Skip to content

Commit 6ea879c

Browse files
Add Single.finallyDo()
1 parent 1fd245b commit 6ea879c

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/main/java/rx/Single.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import rx.internal.operators.OnSubscribeToObservableFuture;
3636
import rx.internal.operators.OperatorDelay;
3737
import rx.internal.operators.OperatorDoOnEach;
38+
import rx.internal.operators.OperatorFinally;
3839
import rx.internal.operators.OperatorMap;
3940
import rx.internal.operators.OperatorObserveOn;
4041
import rx.internal.operators.OperatorOnErrorReturn;
@@ -1946,4 +1947,25 @@ public final Single<T> delay(long delay, TimeUnit unit, Scheduler scheduler) {
19461947
public final Single<T> delay(long delay, TimeUnit unit) {
19471948
return delay(delay, unit, Schedulers.computation());
19481949
}
1950+
1951+
/**
1952+
* Registers an {@link Action0} to be called when this {@link Single} invokes either
1953+
* {@link SingleSubscriber#onSuccess(Object)} onSuccess} or {@link SingleSubscriber#onError onError}.
1954+
* <p>
1955+
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/finallyDo.png" alt="">
1956+
* <dl>
1957+
* <dt><b>Scheduler:</b></dt>
1958+
* <dd>{@code finallyDo} does not operate by default on a particular {@link Scheduler}.</dd>
1959+
* </dl>
1960+
*
1961+
* @param action
1962+
* an {@link Action0} to be invoked when the source {@link Single} finishes.
1963+
* @return a {@link Single} that emits the same item or error as the source {@link Single}, then invokes the
1964+
* {@link Action0}
1965+
* @see <a href="http://reactivex.io/documentation/operators/do.html">ReactiveX operators documentation: Do</a>
1966+
*/
1967+
@Experimental
1968+
public final Single<T> finallyDo(Action0 action) {
1969+
return lift(new OperatorFinally<T>(action));
1970+
}
19491971
}

src/test/java/rx/SingleTest.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import rx.schedulers.Schedulers;
4545
import rx.subscriptions.Subscriptions;
4646

47-
4847
public class SingleTest {
4948

5049
@Test
@@ -689,4 +688,55 @@ public void call(SingleSubscriber<? super Integer> singleSubscriber) {
689688
subscriber.assertNoValues();
690689
subscriber.assertError(expected);
691690
}
691+
692+
@Test
693+
public void finallyDoActionShouldBeInvokedAfterOnSuccess() {
694+
Action0 finallyAction = mock(Action0.class);
695+
696+
TestSubscriber<String> testSubscriber = new TestSubscriber<String>();
697+
698+
Single
699+
.just("value")
700+
.finallyDo(finallyAction)
701+
.subscribe(testSubscriber);
702+
703+
testSubscriber.assertValue("value");
704+
testSubscriber.assertNoErrors();
705+
706+
verify(finallyAction).call();
707+
}
708+
709+
@Test
710+
public void finallyDoActionShouldBeInvokedAfterOnError() {
711+
Action0 finallyAction = mock(Action0.class);
712+
713+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
714+
715+
Throwable error = new IllegalStateException();
716+
717+
Single
718+
.error(error)
719+
.finallyDo(finallyAction)
720+
.subscribe(testSubscriber);
721+
722+
testSubscriber.assertNoValues();
723+
testSubscriber.assertError(error);
724+
725+
verify(finallyAction).call();
726+
}
727+
728+
@Test
729+
public void finallyDoActionShouldNotBeInvokedUntilSubscriberSubscribes() {
730+
Action0 finallyAction = mock(Action0.class);
731+
732+
Single
733+
.just("value")
734+
.finallyDo(finallyAction);
735+
736+
Single
737+
.error(new IllegalStateException())
738+
.finallyDo(finallyAction);
739+
740+
verifyZeroInteractions(finallyAction);
741+
}
692742
}

0 commit comments

Comments
 (0)