diff --git a/src/main/java/io/reactivex/internal/operators/single/SingleMap.java b/src/main/java/io/reactivex/internal/operators/single/SingleMap.java index cb3735c3ed..25ddcdf3e4 100644 --- a/src/main/java/io/reactivex/internal/operators/single/SingleMap.java +++ b/src/main/java/io/reactivex/internal/operators/single/SingleMap.java @@ -17,6 +17,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.Exceptions; import io.reactivex.functions.Function; +import io.reactivex.internal.functions.ObjectHelper; public final class SingleMap extends Single { final SingleSource source; @@ -53,7 +54,7 @@ public void onSubscribe(Disposable d) { public void onSuccess(T value) { R v; try { - v = mapper.apply(value); + v = ObjectHelper.requireNonNull(mapper.apply(value), "The mapper function returned a null value."); } catch (Throwable e) { Exceptions.throwIfFatal(e); onError(e); diff --git a/src/test/java/io/reactivex/internal/operators/single/SingleMapTest.java b/src/test/java/io/reactivex/internal/operators/single/SingleMapTest.java new file mode 100644 index 0000000000..2abc315e95 --- /dev/null +++ b/src/test/java/io/reactivex/internal/operators/single/SingleMapTest.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2016-present, RxJava Contributors. + * + * 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 io.reactivex.internal.operators.single; + +import org.junit.Test; + +import io.reactivex.Single; +import io.reactivex.SingleSource; +import io.reactivex.functions.Function; + +public class SingleMapTest { + + @Test(expected = NullPointerException.class) + public void mapNull() { + Single.just(1).map(null); + } + + @Test + public void mapValue() { + Single.just(1).map(new Function() { + @Override + public Integer apply(final Integer integer) throws Exception { + if (integer == 1) { + return 2; + } + + return 1; + } + }) + .test() + .assertResult(2); + } + + @Test + public void mapValueNull() { + Single.just(1).map(new Function>() { + @Override + public SingleSource apply(final Integer integer) throws Exception { + return null; + } + }) + .test() + .assertNoValues() + .assertError(NullPointerException.class) + .assertErrorMessage("The mapper function returned a null value."); + } + + @Test + public void mapValueErrorThrown() { + Single.just(1).map(new Function>() { + @Override + public SingleSource apply(final Integer integer) throws Exception { + throw new RuntimeException("something went terribly wrong!"); + } + }) + .test() + .assertNoValues() + .assertError(RuntimeException.class) + .assertErrorMessage("something went terribly wrong!"); + } + + @Test + public void mapError() { + RuntimeException exception = new RuntimeException("test"); + + Single.error(exception).map(new Function() { + @Override + public Object apply(final Object integer) throws Exception { + return new Object(); + } + }) + .test() + .assertError(exception); + } +}