diff --git a/src/main/java/io/reactivex/CompletableTransformer.java b/src/main/java/io/reactivex/CompletableTransformer.java index 432c699771..3fc35eb3e5 100644 --- a/src/main/java/io/reactivex/CompletableTransformer.java +++ b/src/main/java/io/reactivex/CompletableTransformer.java @@ -18,5 +18,12 @@ * Completable fluently. */ public interface CompletableTransformer { - CompletableSource apply(Completable completable) throws Exception; + /** + * Applies a function to the upstream Completable and returns a CompletableSource. + * @param upstream the upstream Completable instance + * @return the transformed CompletableSource instance + * @throws Exception in case the transformation throws, checked exceptions will be wrapped + * into a RuntimeException + */ + CompletableSource apply(Completable upstream) throws Exception; } diff --git a/src/main/java/io/reactivex/FlowableTransformer.java b/src/main/java/io/reactivex/FlowableTransformer.java index 0f2017a02b..9b89e4f408 100644 --- a/src/main/java/io/reactivex/FlowableTransformer.java +++ b/src/main/java/io/reactivex/FlowableTransformer.java @@ -22,5 +22,13 @@ * @param the downstream value type */ public interface FlowableTransformer { - Publisher apply(Flowable flowable) throws Exception; + /** + * Applies a function to the upstream Flowable and returns a Publisher with + * optionally different element type. + * @param upstream the upstream Flowable instance + * @return the transformed Publisher instance + * @throws Exception in case the transformation throws, checked exceptions will be wrapped + * into a RuntimeException + */ + Publisher apply(Flowable upstream) throws Exception; } diff --git a/src/main/java/io/reactivex/MaybeTransformer.java b/src/main/java/io/reactivex/MaybeTransformer.java index c169e2023f..d98d659051 100644 --- a/src/main/java/io/reactivex/MaybeTransformer.java +++ b/src/main/java/io/reactivex/MaybeTransformer.java @@ -20,5 +20,13 @@ * @param the downstream value type */ public interface MaybeTransformer { - MaybeSource apply(Maybe maybe) throws Exception; + /** + * Applies a function to the upstream Maybe and returns a MaybeSource with + * optionally different element type. + * @param upstream the upstream Maybe instance + * @return the transformed MaybeSource instance + * @throws Exception in case the transformation throws, checked exceptions will be wrapped + * into a RuntimeException + */ + MaybeSource apply(Maybe upstream) throws Exception; } diff --git a/src/main/java/io/reactivex/ObservableTransformer.java b/src/main/java/io/reactivex/ObservableTransformer.java index 1dec08d247..7610489e37 100644 --- a/src/main/java/io/reactivex/ObservableTransformer.java +++ b/src/main/java/io/reactivex/ObservableTransformer.java @@ -20,5 +20,13 @@ * @param the downstream value type */ public interface ObservableTransformer { + /** + * Applies a function to the upstream Observable and returns an ObservableSource with + * optionally different element type. + * @param upstream the upstream Observable instance + * @return the transformed ObservableSource instance + * @throws Exception in case the transformation throws, checked exceptions will be wrapped + * into a RuntimeException + */ ObservableSource apply(Observable upstream) throws Exception; } diff --git a/src/main/java/io/reactivex/SingleTransformer.java b/src/main/java/io/reactivex/SingleTransformer.java index 4ce319aec4..fe5f5f1447 100644 --- a/src/main/java/io/reactivex/SingleTransformer.java +++ b/src/main/java/io/reactivex/SingleTransformer.java @@ -20,5 +20,13 @@ * @param the downstream value type */ public interface SingleTransformer { + /** + * Applies a function to the upstream Single and returns a SingleSource with + * optionally different element type. + * @param upstream the upstream Single instance + * @return the transformed SingleSource instance + * @throws Exception in case the transformation throws, checked exceptions will be wrapped + * into a RuntimeException + */ SingleSource apply(Single upstream) throws Exception; } diff --git a/src/test/java/io/reactivex/TransformerTest.java b/src/test/java/io/reactivex/TransformerTest.java new file mode 100644 index 0000000000..56ccfe69f0 --- /dev/null +++ b/src/test/java/io/reactivex/TransformerTest.java @@ -0,0 +1,181 @@ +/** + * Copyright 2016 Netflix, Inc. + * + * 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; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import org.junit.Test; +import org.reactivestreams.Publisher; + +import io.reactivex.exceptions.TestException; + +public class TransformerTest { + + @Test + public void flowableTransformerThrows() { + try { + Flowable.just(1).compose(new FlowableTransformer() { + @Override + public Publisher apply(Flowable v) throws Exception { + throw new TestException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (TestException ex) { + assertEquals("Forced failure", ex.getMessage()); + } + } + + @Test + public void flowableTransformerThrowsChecked() { + try { + Flowable.just(1).compose(new FlowableTransformer() { + @Override + public Publisher apply(Flowable v) throws Exception { + throw new IOException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (RuntimeException ex) { + assertTrue(ex.toString(), ex.getCause() instanceof IOException); + assertEquals("Forced failure", ex.getCause().getMessage()); + } + } + + @Test + public void observableTransformerThrows() { + try { + Observable.just(1).compose(new ObservableTransformer() { + @Override + public Observable apply(Observable v) throws Exception { + throw new TestException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (TestException ex) { + assertEquals("Forced failure", ex.getMessage()); + } + } + + @Test + public void observableTransformerThrowsChecked() { + try { + Observable.just(1).compose(new ObservableTransformer() { + @Override + public Observable apply(Observable v) throws Exception { + throw new IOException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (RuntimeException ex) { + assertTrue(ex.toString(), ex.getCause() instanceof IOException); + assertEquals("Forced failure", ex.getCause().getMessage()); + } + } + + @Test + public void singleTransformerThrows() { + try { + Single.just(1).compose(new SingleTransformer() { + @Override + public Single apply(Single v) throws Exception { + throw new TestException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (TestException ex) { + assertEquals("Forced failure", ex.getMessage()); + } + } + + @Test + public void singleTransformerThrowsChecked() { + try { + Single.just(1).compose(new SingleTransformer() { + @Override + public Single apply(Single v) throws Exception { + throw new IOException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (RuntimeException ex) { + assertTrue(ex.toString(), ex.getCause() instanceof IOException); + assertEquals("Forced failure", ex.getCause().getMessage()); + } + } + + @Test + public void maybeTransformerThrows() { + try { + Maybe.just(1).compose(new MaybeTransformer() { + @Override + public Maybe apply(Maybe v) throws Exception { + throw new TestException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (TestException ex) { + assertEquals("Forced failure", ex.getMessage()); + } + } + + @Test + public void maybeTransformerThrowsChecked() { + try { + Maybe.just(1).compose(new MaybeTransformer() { + @Override + public Maybe apply(Maybe v) throws Exception { + throw new IOException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (RuntimeException ex) { + assertTrue(ex.toString(), ex.getCause() instanceof IOException); + assertEquals("Forced failure", ex.getCause().getMessage()); + } + } + + @Test + public void completabeTransformerThrows() { + try { + Completable.complete().compose(new CompletableTransformer() { + @Override + public Completable apply(Completable v) throws Exception { + throw new TestException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (TestException ex) { + assertEquals("Forced failure", ex.getMessage()); + } + } + + @Test + public void completabeTransformerThrowsChecked() { + try { + Completable.complete().compose(new CompletableTransformer() { + @Override + public Completable apply(Completable v) throws Exception { + throw new IOException("Forced failure"); + } + }); + fail("Should have thrown!"); + } catch (RuntimeException ex) { + assertTrue(ex.toString(), ex.getCause() instanceof IOException); + assertEquals("Forced failure", ex.getCause().getMessage()); + } + } +} diff --git a/src/test/java/io/reactivex/flowable/FlowableCovarianceTest.java b/src/test/java/io/reactivex/flowable/FlowableCovarianceTest.java index 28bb1d6422..ff5d5c2e76 100644 --- a/src/test/java/io/reactivex/flowable/FlowableCovarianceTest.java +++ b/src/test/java/io/reactivex/flowable/FlowableCovarianceTest.java @@ -92,9 +92,9 @@ public void accept(Movie v) { System.out.println(v); } }) - .compose(new FlowableTransformer() { + .compose(new FlowableTransformer() { @Override - public Publisher apply(Flowable m) { + public Publisher apply(Flowable m) { return m.concatWith(Flowable.just(new ActionMovie())); } } @@ -120,7 +120,7 @@ public void testCovarianceOfCompose() { Flowable movie = Flowable.just(new HorrorMovie()); Flowable movie2 = movie.compose(new FlowableTransformer() { @Override - public Publisher apply(Flowable t) { + public Publisher apply(Flowable t) { return Flowable.just(new Movie()); } }); @@ -132,7 +132,7 @@ public void testCovarianceOfCompose2() { Flowable movie = Flowable. just(new HorrorMovie()); Flowable movie2 = movie.compose(new FlowableTransformer() { @Override - public Publisher apply(Flowable t) { + public Publisher apply(Flowable t) { return Flowable.just(new HorrorMovie()); } }); @@ -144,7 +144,7 @@ public void testCovarianceOfCompose3() { Flowable movie = Flowable.just(new HorrorMovie()); Flowable movie2 = movie.compose(new FlowableTransformer() { @Override - public Publisher apply(Flowable t) { + public Publisher apply(Flowable t) { return Flowable.just(new HorrorMovie()).map(new Function() { @Override public HorrorMovie apply(HorrorMovie v) { @@ -162,7 +162,7 @@ public void testCovarianceOfCompose4() { Flowable movie = Flowable.just(new HorrorMovie()); Flowable movie2 = movie.compose(new FlowableTransformer() { @Override - public Publisher apply(Flowable t1) { + public Publisher apply(Flowable t1) { return t1.map(new Function() { @Override public HorrorMovie apply(HorrorMovie v) { @@ -211,7 +211,7 @@ public Flowable apply(List> listOfLists) { static FlowableTransformer, Movie> deltaTransformer = new FlowableTransformer, Movie>() { @Override - public Publisher apply(Flowable> movieList) { + public Publisher apply(Flowable> movieList) { return movieList .startWith(new ArrayList()) .buffer(2, 1)