diff --git a/src/main/java/io/reactivex/Flowable.java b/src/main/java/io/reactivex/Flowable.java index 907a044ea2..c774412846 100644 --- a/src/main/java/io/reactivex/Flowable.java +++ b/src/main/java/io/reactivex/Flowable.java @@ -4000,7 +4000,7 @@ public static Flowable zip(Iterable> public static Flowable zip(Publisher> sources, final Function zipper) { ObjectHelper.requireNonNull(zipper, "zipper is null"); - return fromPublisher(sources).toList().flatMap(FlowableInternalHelper.zipIterable(zipper)); + return fromPublisher(sources).toList().flatMapPublisher(FlowableInternalHelper.zipIterable(zipper)); } /** @@ -4848,7 +4848,7 @@ public static Flowable zipIterable(Iterable * @@ -4901,7 +4901,7 @@ public final Flowable ambWith(Publisher other) { } /** - * Returns a Flowable that emits {@code true} if any item emitted by the source Publisher satisfies a + * Returns a Single that emits {@code true} if any item emitted by the source Publisher satisfies a * specified condition, otherwise {@code false}. Note: this always emits {@code false} if the * source Publisher is empty. *

@@ -6192,8 +6192,8 @@ public final Flowable cast(final Class clazz) { } /** - * Collects items emitted by the source Publisher into a single mutable data structure and returns an - * Publisher that emits this structure. + * Collects items emitted by the source Publisher into a single mutable data structure and returns + * a Single that emits this structure. *

* *

@@ -6212,21 +6212,21 @@ public final Flowable cast(final Class clazz) { * @param collector * a function that accepts the {@code state} and an emitted item, and modifies {@code state} * accordingly - * @return a Flowable that emits the result of collecting the values emitted by the source Publisher + * @return a Single that emits the result of collecting the values emitted by the source Publisher * into a single mutable data structure * @see ReactiveX operators documentation: Reduce */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable collect(Callable initialItemSupplier, BiConsumer collector) { + public final Single collect(Callable initialItemSupplier, BiConsumer collector) { ObjectHelper.requireNonNull(initialItemSupplier, "initialItemSupplier is null"); ObjectHelper.requireNonNull(collector, "collector is null"); - return RxJavaPlugins.onAssembly(new FlowableCollect(this, initialItemSupplier, collector)); + return RxJavaPlugins.onAssembly(new FlowableCollectSingle(this, initialItemSupplier, collector)); } /** - * Collects items emitted by the source Publisher into a single mutable data structure and returns an - * Publisher that emits this structure. + * Collects items emitted by the source Publisher into a single mutable data structure and returns + * a Single that emits this structure. *

* *

@@ -6245,13 +6245,13 @@ public final Flowable collect(Callable initialItemSupplier, * @param collector * a function that accepts the {@code state} and an emitted item, and modifies {@code state} * accordingly - * @return a Flowable that emits the result of collecting the values emitted by the source Publisher + * @return a Single that emits the result of collecting the values emitted by the source Publisher * into a single mutable data structure * @see ReactiveX operators documentation: Reduce */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable collectInto(final U initialItem, BiConsumer collector) { + public final Single collectInto(final U initialItem, BiConsumer collector) { ObjectHelper.requireNonNull(initialItem, "initialItem is null"); return collect(Functions.justCallable(initialItem), collector); } @@ -6640,7 +6640,7 @@ public final Flowable concatWith(Publisher other) { } /** - * Returns a Flowable that emits a Boolean that indicates whether the source Publisher emitted a + * Returns a Single that emits a Boolean that indicates whether the source Publisher emitted a * specified item. *

* @@ -8795,7 +8795,7 @@ public final Flowable ignoreElements() { } /** - * Returns a Flowable that emits {@code true} if the source Publisher is empty, otherwise {@code false}. + * Returns a Single that emits {@code true} if the source Publisher is empty, otherwise {@code false}. *

* In Rx.Net this is negated as the {@code any} Subscriber but we renamed this in RxJava to better match Java * naming idioms. @@ -8865,7 +8865,7 @@ public final Flowable join( /** - * Returns a Flowable that emits the last item emitted by the source Publisher or notifies Subscribers of + * Returns a Single that emits the last item emitted by the source Publisher or notifies Subscribers of * a {@code NoSuchElementException} if the source Publisher is empty. *

* @@ -8888,7 +8888,7 @@ public final Single last() { } /** - * Returns a Flowable that emits only the last item emitted by the source Publisher, or a default item + * Returns a Single that emits only the last item emitted by the source Publisher, or a default item * if the source Publisher completes without emitting any items. *

* @@ -9855,7 +9855,7 @@ public final Flowable rebatchRequests(int n) { } /** - * Returns a Flowable that applies a specified accumulator function to the first item emitted by a source + * Returns a Single that applies a specified accumulator function to the first item emitted by a source * Publisher, then feeds the result of that function along with the second item emitted by the source * Publisher into the same function, and so on until all items have been emitted by the source Publisher, * and emits the final result from the final call to your function as its sole item. @@ -9887,7 +9887,6 @@ public final Flowable rebatchRequests(int n) { @SchedulerSupport(SchedulerSupport.NONE) public final Single reduce(BiFunction reducer) { ObjectHelper.requireNonNull(reducer, "reducer is null"); -// return RxJavaPlugins.onAssembly(new FlowableReduce(this, reducer)); return RxJavaPlugins.onAssembly(new SingleReduceFlowable(this, reducer)); } @@ -11593,7 +11592,7 @@ public final Flowable skipWhile(Predicate predicate) { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerSupport.NONE) public final Flowable sorted() { - return toSortedList().flatMapIterable(Functions.>identity()); + return toList().toFlowable().map(Functions.listSorter(Functions.naturalComparator())).flatMapIterable(Functions.>identity()); } /** @@ -11619,7 +11618,7 @@ public final Flowable sorted() { @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerSupport.NONE) public final Flowable sorted(Comparator sortFunction) { - return toSortedList(sortFunction).flatMapIterable(Functions.>identity()); + return toList().toFlowable().map(Functions.listSorter(sortFunction)).flatMapIterable(Functions.>identity()); } /** @@ -13453,7 +13452,7 @@ public final Completable toCompletable() { } /** - * Returns a Flowable that emits a single item, a list composed of all the items emitted by the source + * Returns a Single that emits a single item, a list composed of all the items emitted by the source * Publisher. *

* @@ -13474,18 +13473,18 @@ public final Completable toCompletable() { *

{@code toList} does not operate by default on a particular {@link Scheduler}.
* * - * @return a Flowable that emits a single item: a List containing all of the items emitted by the source + * @return a Single that emits a single item: a List containing all of the items emitted by the source * Publisher * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toList() { - return RxJavaPlugins.onAssembly(new FlowableToList>(this)); + public final Single> toList() { + return RxJavaPlugins.onAssembly(new FlowableToListSingle>(this)); } /** - * Returns a Flowable that emits a single item, a list composed of all the items emitted by the source + * Returns a Single that emits a single item, a list composed of all the items emitted by the source * Publisher. *

* @@ -13514,9 +13513,9 @@ public final Flowable> toList() { */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toList(final int capacityHint) { + public final Single> toList(final int capacityHint) { ObjectHelper.verifyPositive(capacityHint, "capacityHint"); - return RxJavaPlugins.onAssembly(new FlowableToList>(this, Functions.createArrayList(capacityHint))); + return RxJavaPlugins.onAssembly(new FlowableToListSingle>(this, Functions.createArrayList(capacityHint))); } /** @@ -13556,7 +13555,7 @@ public final > Flowable toList(Callable co } /** - * Returns a Flowable that emits a single HashMap containing all items emitted by the source Publisher, + * Returns a Single that emits a single HashMap containing all items emitted by the source Publisher, * mapped by the keys returned by a specified {@code keySelector} function. *

* @@ -13573,19 +13572,19 @@ public final > Flowable toList(Callable co * @param the key type of the Map * @param keySelector * the function that extracts the key from a source item to be used in the HashMap - * @return a Flowable that emits a single item: a HashMap containing the mapped items from the source + * @return a Single that emits a single item: a HashMap containing the mapped items from the source * Publisher * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toMap(final Function keySelector) { + public final Single> toMap(final Function keySelector) { ObjectHelper.requireNonNull(keySelector, "keySelector is null"); return collect(HashMapSupplier.asCallable(), Functions.toMapKeySelector(keySelector)); } /** - * Returns a Flowable that emits a single HashMap containing values corresponding to items emitted by the + * Returns a Single that emits a single HashMap containing values corresponding to items emitted by the * source Publisher, mapped by the keys returned by a specified {@code keySelector} function. *

* @@ -13606,20 +13605,20 @@ public final Flowable> toMap(final FunctionReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toMap(final Function keySelector, final Function valueSelector) { + public final Single> toMap(final Function keySelector, final Function valueSelector) { ObjectHelper.requireNonNull(keySelector, "keySelector is null"); ObjectHelper.requireNonNull(valueSelector, "valueSelector is null"); return collect(HashMapSupplier.asCallable(), Functions.toMapKeyValueSelector(keySelector, valueSelector)); } /** - * Returns a Flowable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains keys and values extracted from the items emitted by the source Publisher. *

* @@ -13645,7 +13644,7 @@ public final Flowable> toMap(final Function Flowable> toMap(final Function keySelector, + public final Single> toMap(final Function keySelector, final Function valueSelector, final Callable> mapSupplier) { ObjectHelper.requireNonNull(keySelector, "keySelector is null"); @@ -13654,7 +13653,7 @@ public final Flowable> toMap(final Function * @@ -13668,13 +13667,13 @@ public final Flowable> toMap(final Function the key type of the Map * @param keySelector * the function that extracts the key from the source items to be used as key in the HashMap - * @return a Flowable that emits a single item: a HashMap that contains an ArrayList of items mapped from + * @return a Single that emits a single item: a HashMap that contains an ArrayList of items mapped from * the source Publisher * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable>> toMultimap(Function keySelector) { + public final Single>> toMultimap(Function keySelector) { Function valueSelector = Functions.identity(); Callable>> mapSupplier = HashMapSupplier.asCallable(); Function> collectionFactory = ArrayListSupplier.asFunction(); @@ -13682,7 +13681,7 @@ public final Flowable>> toMultimap(Function @@ -13701,20 +13700,20 @@ public final Flowable>> toMultimap(FunctionReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable>> toMultimap(Function keySelector, Function valueSelector) { + public final Single>> toMultimap(Function keySelector, Function valueSelector) { Callable>> mapSupplier = HashMapSupplier.asCallable(); Function> collectionFactory = ArrayListSupplier.asFunction(); return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } /** - * Returns a Flowable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains a custom collection of values, extracted by a specified {@code valueSelector} function from * items emitted by the source Publisher, and keyed by the {@code keySelector} function. *

@@ -13737,13 +13736,13 @@ public final Flowable>> toMultimap(FunctionReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable>> toMultimap( + public final Single>> toMultimap( final Function keySelector, final Function valueSelector, final Callable>> mapSupplier, @@ -13756,7 +13755,7 @@ public final Flowable>> toMultimap( } /** - * Returns a Flowable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains an ArrayList of values, extracted by a specified {@code valueSelector} function from items * emitted by the source Publisher and keyed by the {@code keySelector} function. *

@@ -13777,13 +13776,13 @@ public final Flowable>> toMultimap( * the function that extracts a value from the source items to be used as the value in the Map * @param mapSupplier * the function that returns a Map instance to be used - * @return a Flowable that emits a single item: a Map that contains a list items mapped from the source + * @return a Single that emits a single item: a Map that contains a list items mapped from the source * Publisher * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable>> toMultimap( + public final Single>> toMultimap( Function keySelector, Function valueSelector, Callable>> mapSupplier @@ -13857,7 +13856,7 @@ public final Maybe toMaybe() { } /** - * Returns a Flowable that emits a list that contains the items emitted by the source Publisher, in a + * Returns a Single that emits a list that contains the items emitted by the source Publisher, in a * sorted order. Each item emitted by the Publisher must implement {@link Comparable} with respect to all * other items in the sequence. *

@@ -13873,18 +13872,18 @@ public final Maybe toMaybe() { * @throws ClassCastException * if any item emitted by the Publisher does not implement {@link Comparable} with respect to * all other items emitted by the Publisher - * @return a Flowable that emits a list that contains the items emitted by the source Publisher in + * @return a Single that emits a list that contains the items emitted by the source Publisher in * sorted order * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toSortedList() { + public final Single> toSortedList() { return toSortedList(Functions.naturalComparator()); } /** - * Returns a Flowable that emits a list that contains the items emitted by the source Publisher, in a + * Returns a Single that emits a list that contains the items emitted by the source Publisher, in a * sorted order based on a specified comparison function. *

* @@ -13899,19 +13898,19 @@ public final Flowable> toSortedList() { * @param comparator * a function that compares two items emitted by the source Publisher and returns an Integer * that indicates their sort order - * @return a Flowable that emits a list that contains the items emitted by the source Publisher in + * @return a Single that emits a list that contains the items emitted by the source Publisher in * sorted order * @see ReactiveX operators documentation: To */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toSortedList(final Comparator comparator) { + public final Single> toSortedList(final Comparator comparator) { ObjectHelper.requireNonNull(comparator, "comparator is null"); return toList().map(Functions.listSorter(comparator)); } /** - * Returns a Flowable that emits a list that contains the items emitted by the source Publisher, in a + * Returns a Single that emits a list that contains the items emitted by the source Publisher, in a * sorted order based on a specified comparison function. *

* @@ -13928,14 +13927,14 @@ public final Flowable> toSortedList(final Comparator comparat * that indicates their sort order * @param capacityHint * the initial capacity of the ArrayList used to accumulate items before sorting - * @return a Flowable that emits a list that contains the items emitted by the source Publisher in + * @return a Single that emits a list that contains the items emitted by the source Publisher in * sorted order * @see ReactiveX operators documentation: To * @since 2.0 */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toSortedList(final Comparator comparator, int capacityHint) { + public final Single> toSortedList(final Comparator comparator, int capacityHint) { ObjectHelper.requireNonNull(comparator, "comparator is null"); return toList(capacityHint).map(Functions.listSorter(comparator)); } @@ -13966,7 +13965,7 @@ public final Flowable> toSortedList(final Comparator comparat */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) - public final Flowable> toSortedList(int capacityHint) { + public final Single> toSortedList(int capacityHint) { return toSortedList(Functions.naturalComparator(), capacityHint); } diff --git a/src/main/java/io/reactivex/Observable.java b/src/main/java/io/reactivex/Observable.java index ae8951e626..729a9e8144 100644 --- a/src/main/java/io/reactivex/Observable.java +++ b/src/main/java/io/reactivex/Observable.java @@ -5411,8 +5411,8 @@ public final Observable cast(final Class clazz) { } /** - * Collects items emitted by the source ObservableSource into a single mutable data structure and returns an - * ObservableSource that emits this structure. + * Collects items emitted by the source ObservableSource into a single mutable data structure and returns + * a Single that emits this structure. *

* *

@@ -5428,20 +5428,20 @@ public final Observable cast(final Class clazz) { * @param collector * a function that accepts the {@code state} and an emitted item, and modifies {@code state} * accordingly - * @return an Observable that emits the result of collecting the values emitted by the source ObservableSource + * @return a Single that emits the result of collecting the values emitted by the source ObservableSource * into a single mutable data structure * @see ReactiveX operators documentation: Reduce */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable collect(Callable initialValueSupplier, BiConsumer collector) { + public final Single collect(Callable initialValueSupplier, BiConsumer collector) { ObjectHelper.requireNonNull(initialValueSupplier, "initialValueSupplier is null"); ObjectHelper.requireNonNull(collector, "collector is null"); - return RxJavaPlugins.onAssembly(new ObservableCollect(this, initialValueSupplier, collector)); + return RxJavaPlugins.onAssembly(new ObservableCollectSingle(this, initialValueSupplier, collector)); } /** - * Collects items emitted by the source ObservableSource into a single mutable data structure and returns an - * ObservableSource that emits this structure. + * Collects items emitted by the source ObservableSource into a single mutable data structure and returns + * a Single that emits this structure. *

* *

@@ -5457,12 +5457,12 @@ public final Observable collect(Callable initialValueSupplie * @param collector * a function that accepts the {@code state} and an emitted item, and modifies {@code state} * accordingly - * @return an Observable that emits the result of collecting the values emitted by the source ObservableSource + * @return a Single that emits the result of collecting the values emitted by the source ObservableSource * into a single mutable data structure * @see ReactiveX operators documentation: Reduce */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable collectInto(final U initialValue, BiConsumer collector) { + public final Single collectInto(final U initialValue, BiConsumer collector) { ObjectHelper.requireNonNull(initialValue, "initialValue is null"); return collect(Functions.justCallable(initialValue), collector); } @@ -9682,7 +9682,7 @@ public final Observable skipWhile(Predicate predicate) { */ @SchedulerSupport(SchedulerSupport.NONE) public final Observable sorted() { - return toSortedList().flatMapIterable(Functions.>identity()); + return toList().toObservable().map(Functions.listSorter(Functions.naturalComparator())).flatMapIterable(Functions.>identity()); } /** @@ -9704,7 +9704,7 @@ public final Observable sorted() { */ @SchedulerSupport(SchedulerSupport.NONE) public final Observable sorted(Comparator sortFunction) { - return toSortedList(sortFunction).flatMapIterable(Functions.>identity()); + return toList().toObservable().map(Functions.listSorter(sortFunction)).flatMapIterable(Functions.>identity()); } /** @@ -11280,7 +11280,7 @@ public final Completable toCompletable() { } /** - * Returns an Observable that emits a single item, a list composed of all the items emitted by the source + * Returns a Single that emits a single item, a list composed of all the items emitted by the source * ObservableSource. *

* @@ -11298,17 +11298,17 @@ public final Completable toCompletable() { *

{@code toList} does not operate by default on a particular {@link Scheduler}.
* * - * @return an Observable that emits a single item: a List containing all of the items emitted by the source + * @return a Single that emits a single item: a List containing all of the items emitted by the source * ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toList() { + public final Single> toList() { return toList(16); } /** - * Returns an Observable that emits a single item, a list composed of all the items emitted by the source + * Returns a Single that emits a single item, a list composed of all the items emitted by the source * ObservableSource. *

* @@ -11328,18 +11328,18 @@ public final Observable> toList() { * * @param capacityHint * the number of elements expected from the current Observable - * @return an Observable that emits a single item: a List containing all of the items emitted by the source + * @return a Single that emits a single item: a List containing all of the items emitted by the source * ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toList(final int capacityHint) { + public final Single> toList(final int capacityHint) { ObjectHelper.verifyPositive(capacityHint, "capacityHint"); - return RxJavaPlugins.onAssembly(new ObservableToList>(this, capacityHint)); + return RxJavaPlugins.onAssembly(new ObservableToListSingle>(this, capacityHint)); } /** - * Returns an Observable that emits a single item, a list composed of all the items emitted by the source + * Returns a Single that emits a single item, a list composed of all the items emitted by the source * ObservableSource. *

* @@ -11360,18 +11360,18 @@ public final Observable> toList(final int capacityHint) { * @param the subclass of a collection of Ts * @param collectionSupplier * the Callable returning the collection (for each individual Observer) to be filled in - * @return an Observable that emits a single item: a List containing all of the items emitted by the source + * @return a Single that emits a single item: a List containing all of the items emitted by the source * ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final > Observable toList(Callable collectionSupplier) { + public final > Single toList(Callable collectionSupplier) { ObjectHelper.requireNonNull(collectionSupplier, "collectionSupplier is null"); - return RxJavaPlugins.onAssembly(new ObservableToList(this, collectionSupplier)); + return RxJavaPlugins.onAssembly(new ObservableToListSingle(this, collectionSupplier)); } /** - * Returns an Observable that emits a single HashMap containing all items emitted by the source ObservableSource, + * Returns a Single that emits a single HashMap containing all items emitted by the source ObservableSource, * mapped by the keys returned by a specified {@code keySelector} function. *

* @@ -11385,17 +11385,17 @@ public final > Observable toList(Callable * @param the key type of the Map * @param keySelector * the function that extracts the key from a source item to be used in the HashMap - * @return an Observable that emits a single item: a HashMap containing the mapped items from the source + * @return a Single that emits a single item: a HashMap containing the mapped items from the source * ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toMap(final Function keySelector) { + public final Single> toMap(final Function keySelector) { return collect(HashMapSupplier.asCallable(), Functions.toMapKeySelector(keySelector)); } /** - * Returns an Observable that emits a single HashMap containing values corresponding to items emitted by the + * Returns a Single that emits a single HashMap containing values corresponding to items emitted by the * source ObservableSource, mapped by the keys returned by a specified {@code keySelector} function. *

* @@ -11413,12 +11413,12 @@ public final Observable> toMap(final FunctionReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toMap( + public final Single> toMap( final Function keySelector, final Function valueSelector) { ObjectHelper.requireNonNull(keySelector, "keySelector is null"); @@ -11427,7 +11427,7 @@ public final Observable> toMap( } /** - * Returns an Observable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains keys and values extracted from the items emitted by the source ObservableSource. *

* @@ -11444,12 +11444,12 @@ public final Observable> toMap( * the function that extracts the value from the source items to be used as value in the Map * @param mapSupplier * the function that returns a Map instance to be used - * @return an Observable that emits a single item: a Map that contains the mapped items emitted by the + * @return a Single that emits a single item: a Map that contains the mapped items emitted by the * source ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toMap( + public final Single> toMap( final Function keySelector, final Function valueSelector, Callable> mapSupplier) { @@ -11457,7 +11457,7 @@ public final Observable> toMap( } /** - * Returns an Observable that emits a single HashMap that contains an ArrayList of items emitted by the + * Returns a Single that emits a single HashMap that contains an ArrayList of items emitted by the * source ObservableSource keyed by a specified {@code keySelector} function. *

* @@ -11469,12 +11469,12 @@ public final Observable> toMap( * @param the key type of the Map * @param keySelector * the function that extracts the key from the source items to be used as key in the HashMap - * @return an Observable that emits a single item: a HashMap that contains an ArrayList of items mapped from + * @return a Single that emits a single item: a HashMap that contains an ArrayList of items mapped from * the source ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable>> toMultimap(Function keySelector) { + public final Single>> toMultimap(Function keySelector) { @SuppressWarnings({ "rawtypes", "unchecked" }) Function valueSelector = (Function)Functions.identity(); Callable>> mapSupplier = HashMapSupplier.asCallable(); @@ -11483,7 +11483,7 @@ public final Observable>> toMultimap(Function @@ -11499,19 +11499,19 @@ public final Observable>> toMultimap(FunctionReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable>> toMultimap(Function keySelector, Function valueSelector) { + public final Single>> toMultimap(Function keySelector, Function valueSelector) { Callable>> mapSupplier = HashMapSupplier.asCallable(); Function> collectionFactory = ArrayListSupplier.asFunction(); return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } /** - * Returns an Observable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains a custom collection of values, extracted by a specified {@code valueSelector} function from * items emitted by the source ObservableSource, and keyed by the {@code keySelector} function. *

@@ -11531,12 +11531,12 @@ public final Observable>> toMultimap(FunctionReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable>> toMultimap( + public final Single>> toMultimap( final Function keySelector, final Function valueSelector, final Callable>> mapSupplier, @@ -11549,7 +11549,7 @@ public final Observable>> toMultimap( } /** - * Returns an Observable that emits a single Map, returned by a specified {@code mapFactory} function, that + * Returns a Single that emits a single Map, returned by a specified {@code mapFactory} function, that * contains an ArrayList of values, extracted by a specified {@code valueSelector} function from items * emitted by the source ObservableSource and keyed by the {@code keySelector} function. *

@@ -11567,12 +11567,12 @@ public final Observable>> toMultimap( * the function that extracts a value from the source items to be used as the value in the Map * @param mapSupplier * the function that returns a Map instance to be used - * @return an Observable that emits a single item: a Map that contains a list items mapped from the source + * @return a Single that emits a single item: a Map that contains a list items mapped from the source * ObservableSource * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable>> toMultimap( + public final Single>> toMultimap( Function keySelector, Function valueSelector, Callable>> mapSupplier @@ -11664,7 +11664,7 @@ public final Single toSingle(T defaultIfEmpty) { } /** - * Returns an Observable that emits a list that contains the items emitted by the source ObservableSource, in a + * Returns a Single that emits a list that contains the items emitted by the source ObservableSource, in a * sorted order. Each item emitted by the ObservableSource must implement {@link Comparable} with respect to all * other items in the sequence. *

@@ -11677,17 +11677,17 @@ public final Single toSingle(T defaultIfEmpty) { * @throws ClassCastException * if any item emitted by the ObservableSource does not implement {@link Comparable} with respect to * all other items emitted by the ObservableSource - * @return an Observable that emits a list that contains the items emitted by the source ObservableSource in + * @return a Single that emits a list that contains the items emitted by the source ObservableSource in * sorted order * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toSortedList() { + public final Single> toSortedList() { return toSortedList(Functions.naturalOrder()); } /** - * Returns an Observable that emits a list that contains the items emitted by the source ObservableSource, in a + * Returns a Single that emits a list that contains the items emitted by the source ObservableSource, in a * sorted order based on a specified comparison function. *

* @@ -11699,18 +11699,18 @@ public final Observable> toSortedList() { * @param comparator * a function that compares two items emitted by the source ObservableSource and returns an Integer * that indicates their sort order - * @return an Observable that emits a list that contains the items emitted by the source ObservableSource in + * @return a Single that emits a list that contains the items emitted by the source ObservableSource in * sorted order * @see ReactiveX operators documentation: To */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toSortedList(final Comparator comparator) { + public final Single> toSortedList(final Comparator comparator) { ObjectHelper.requireNonNull(comparator, "comparator is null"); return toList().map(Functions.listSorter(comparator)); } /** - * Returns an Observable that emits a list that contains the items emitted by the source ObservableSource, in a + * Returns a Single that emits a list that contains the items emitted by the source ObservableSource, in a * sorted order based on a specified comparison function. *

* @@ -11724,19 +11724,19 @@ public final Observable> toSortedList(final Comparator compar * that indicates their sort order * @param capacityHint * the initial capacity of the ArrayList used to accumulate items before sorting - * @return an Observable that emits a list that contains the items emitted by the source ObservableSource in + * @return a Single that emits a list that contains the items emitted by the source ObservableSource in * sorted order * @see ReactiveX operators documentation: To * @since 2.0 */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toSortedList(final Comparator comparator, int capacityHint) { + public final Single> toSortedList(final Comparator comparator, int capacityHint) { ObjectHelper.requireNonNull(comparator, "comparator is null"); return toList(capacityHint).map(Functions.listSorter(comparator)); } /** - * Returns an Observable that emits a list that contains the items emitted by the source ObservableSource, in a + * Returns a Single that emits a list that contains the items emitted by the source ObservableSource, in a * sorted order. Each item emitted by the ObservableSource must implement {@link Comparable} with respect to all * other items in the sequence. *

@@ -11748,7 +11748,7 @@ public final Observable> toSortedList(final Comparator compar * * @param capacityHint * the initial capacity of the ArrayList used to accumulate items before sorting - * @return an Observable that emits a list that contains the items emitted by the source ObservableSource in + * @return a Single that emits a list that contains the items emitted by the source ObservableSource in * sorted order * @throws ClassCastException * if any item emitted by the ObservableSource does not implement {@link Comparable} with respect to @@ -11757,7 +11757,7 @@ public final Observable> toSortedList(final Comparator compar * @since 2.0 */ @SchedulerSupport(SchedulerSupport.NONE) - public final Observable> toSortedList(int capacityHint) { + public final Single> toSortedList(int capacityHint) { return toSortedList(Functions.naturalOrder(), capacityHint); } diff --git a/src/main/java/io/reactivex/internal/operators/flowable/FlowableAllSingle.java b/src/main/java/io/reactivex/internal/operators/flowable/FlowableAllSingle.java index 73552e516a..3d994e24c5 100644 --- a/src/main/java/io/reactivex/internal/operators/flowable/FlowableAllSingle.java +++ b/src/main/java/io/reactivex/internal/operators/flowable/FlowableAllSingle.java @@ -25,7 +25,7 @@ public final class FlowableAllSingle extends Single implements FuseToFlowable { final Publisher source; - + final Predicate predicate; public FlowableAllSingle(Publisher source, Predicate predicate) { @@ -42,11 +42,11 @@ protected void subscribeActual(SingleObserver s) { public Flowable fuseToFlowable() { return RxJavaPlugins.onAssembly(new FlowableAll(source, predicate)); } - + static final class AllSubscriber implements Subscriber, Disposable { - + final SingleObserver actual; - + final Predicate predicate; Subscription s; @@ -116,7 +116,7 @@ public void dispose() { s.cancel(); s = SubscriptionHelper.CANCELLED; } - + @Override public boolean isDisposed() { return s == SubscriptionHelper.CANCELLED; diff --git a/src/main/java/io/reactivex/internal/operators/flowable/FlowableAnySingle.java b/src/main/java/io/reactivex/internal/operators/flowable/FlowableAnySingle.java index 3497d03c86..e732fd3964 100644 --- a/src/main/java/io/reactivex/internal/operators/flowable/FlowableAnySingle.java +++ b/src/main/java/io/reactivex/internal/operators/flowable/FlowableAnySingle.java @@ -24,9 +24,9 @@ public final class FlowableAnySingle extends Single implements FuseToFlowable { final Publisher source; - + final Predicate predicate; - + public FlowableAnySingle(Publisher source, Predicate predicate) { this.source = source; this.predicate = predicate; @@ -36,7 +36,7 @@ public FlowableAnySingle(Publisher source, Predicate predicate) { protected void subscribeActual(SingleObserver s) { source.subscribe(new AnySubscriber(s, predicate)); } - + @Override public Flowable fuseToFlowable() { return RxJavaPlugins.onAssembly(new FlowableAny(source, predicate)); @@ -45,7 +45,7 @@ public Flowable fuseToFlowable() { static final class AnySubscriber implements Subscriber, Disposable { final SingleObserver actual; - + final Predicate predicate; Subscription s; @@ -111,7 +111,7 @@ public void dispose() { s.cancel(); s = SubscriptionHelper.CANCELLED; } - + @Override public boolean isDisposed() { return s == SubscriptionHelper.CANCELLED; diff --git a/src/main/java/io/reactivex/internal/operators/flowable/FlowableCollectSingle.java b/src/main/java/io/reactivex/internal/operators/flowable/FlowableCollectSingle.java new file mode 100644 index 0000000000..1265cc4018 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/flowable/FlowableCollectSingle.java @@ -0,0 +1,133 @@ +/** + * 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.internal.operators.flowable; + +import java.util.concurrent.Callable; + +import org.reactivestreams.*; + +import io.reactivex.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.Exceptions; +import io.reactivex.functions.BiConsumer; +import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.functions.ObjectHelper; +import io.reactivex.internal.fuseable.FuseToFlowable; +import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.plugins.RxJavaPlugins; + +public final class FlowableCollectSingle extends Single implements FuseToFlowable { + + final Publisher source; + + final Callable initialSupplier; + final BiConsumer collector; + + public FlowableCollectSingle(Publisher source, Callable initialSupplier, BiConsumer collector) { + this.source = source; + this.initialSupplier = initialSupplier; + this.collector = collector; + } + + @Override + protected void subscribeActual(SingleObserver s) { + U u; + try { + u = ObjectHelper.requireNonNull(initialSupplier.call(), "The initialSupplier returned a null value"); + } catch (Throwable e) { + EmptyDisposable.error(e, s); + return; + } + + source.subscribe(new CollectSubscriber(s, u, collector)); + } + + @Override + public Flowable fuseToFlowable() { + return RxJavaPlugins.onAssembly(new FlowableCollect(source, initialSupplier, collector)); + } + + static final class CollectSubscriber implements Subscriber, Disposable { + + final SingleObserver actual; + + final BiConsumer collector; + + final U u; + + Subscription s; + + boolean done; + + CollectSubscriber(SingleObserver actual, U u, BiConsumer collector) { + this.actual = actual; + this.collector = collector; + this.u = u; + } + + @Override + public void onSubscribe(Subscription s) { + if (SubscriptionHelper.validate(this.s, s)) { + this.s = s; + actual.onSubscribe(this); + s.request(Long.MAX_VALUE); + } + } + + @Override + public void onNext(T t) { + if (done) { + return; + } + try { + collector.accept(u, t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + s.cancel(); + onError(e); + } + } + + @Override + public void onError(Throwable t) { + if (done) { + RxJavaPlugins.onError(t); + return; + } + done = true; + s = SubscriptionHelper.CANCELLED; + actual.onError(t); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + s = SubscriptionHelper.CANCELLED; + actual.onSuccess(u); + } + + @Override + public void dispose() { + s.cancel(); + s = SubscriptionHelper.CANCELLED; + } + + @Override + public boolean isDisposed() { + return s == SubscriptionHelper.CANCELLED; + } + } +} \ No newline at end of file diff --git a/src/main/java/io/reactivex/internal/operators/flowable/FlowableLastSingle.java b/src/main/java/io/reactivex/internal/operators/flowable/FlowableLastSingle.java index e4b679d5b4..a60590a81d 100644 --- a/src/main/java/io/reactivex/internal/operators/flowable/FlowableLastSingle.java +++ b/src/main/java/io/reactivex/internal/operators/flowable/FlowableLastSingle.java @@ -30,31 +30,31 @@ public final class FlowableLastSingle extends Single { final Publisher source; - + final T defaultItem; - + public FlowableLastSingle(Publisher source, T defaultItem) { this.source = source; this.defaultItem = defaultItem; } // TODO fuse back to Flowable - + @Override protected void subscribeActual(SingleObserver observer) { source.subscribe(new LastSubscriber(observer, defaultItem)); } - + static final class LastSubscriber implements Subscriber, Disposable { - + final SingleObserver actual; - + final T defaultItem; Subscription s; - + T item; - + public LastSubscriber(SingleObserver actual, T defaultItem) { this.actual = actual; this.defaultItem = defaultItem; @@ -75,9 +75,9 @@ public boolean isDisposed() { public void onSubscribe(Subscription s) { if (SubscriptionHelper.validate(this.s, s)) { this.s = s; - + actual.onSubscribe(this); - + s.request(Long.MAX_VALUE); } } @@ -110,7 +110,5 @@ public void onComplete() { } } } - - } } diff --git a/src/main/java/io/reactivex/internal/operators/flowable/FlowableToListSingle.java b/src/main/java/io/reactivex/internal/operators/flowable/FlowableToListSingle.java new file mode 100644 index 0000000000..b847d33bf0 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/flowable/FlowableToListSingle.java @@ -0,0 +1,116 @@ +/** + * 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.internal.operators.flowable; + +import java.util.Collection; +import java.util.concurrent.Callable; + +import org.reactivestreams.*; + +import io.reactivex.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.Exceptions; +import io.reactivex.internal.disposables.EmptyDisposable; +import io.reactivex.internal.fuseable.FuseToFlowable; +import io.reactivex.internal.subscriptions.SubscriptionHelper; +import io.reactivex.internal.util.ArrayListSupplier; +import io.reactivex.plugins.RxJavaPlugins; + +public final class FlowableToListSingle> extends Single implements FuseToFlowable { + + final Publisher source; + + final Callable collectionSupplier; + + @SuppressWarnings("unchecked") + public FlowableToListSingle(Publisher source) { + this(source, (Callable)ArrayListSupplier.asCallable()); + } + + public FlowableToListSingle(Publisher source, Callable collectionSupplier) { + this.source = source; + this.collectionSupplier = collectionSupplier; + } + + @Override + protected void subscribeActual(SingleObserver s) { + U coll; + try { + coll = collectionSupplier.call(); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + EmptyDisposable.error(e, s); + return; + } + source.subscribe(new ToListSubscriber(s, coll)); + } + + @Override + public Flowable fuseToFlowable() { + return RxJavaPlugins.onAssembly(new FlowableToList(source, collectionSupplier)); + } + + static final class ToListSubscriber> + implements Subscriber, Disposable { + + final SingleObserver actual; + + Subscription s; + + U value; + + ToListSubscriber(SingleObserver actual, U collection) { + this.actual = actual; + this.value = collection; + } + + @Override + public void onSubscribe(Subscription s) { + if (SubscriptionHelper.validate(this.s, s)) { + this.s = s; + actual.onSubscribe(this); + s.request(Long.MAX_VALUE); + } + } + + @Override + public void onNext(T t) { + value.add(t); + } + + @Override + public void onError(Throwable t) { + value = null; + s = SubscriptionHelper.CANCELLED; + actual.onError(t); + } + + @Override + public void onComplete() { + s = SubscriptionHelper.CANCELLED; + actual.onSuccess(value); + } + + @Override + public void dispose() { + s.cancel(); + s = SubscriptionHelper.CANCELLED; + } + + @Override + public boolean isDisposed() { + return s == SubscriptionHelper.CANCELLED; + } + } +} diff --git a/src/main/java/io/reactivex/internal/operators/observable/ObservableAllSingle.java b/src/main/java/io/reactivex/internal/operators/observable/ObservableAllSingle.java index be4442d22b..20a90f764b 100644 --- a/src/main/java/io/reactivex/internal/operators/observable/ObservableAllSingle.java +++ b/src/main/java/io/reactivex/internal/operators/observable/ObservableAllSingle.java @@ -20,9 +20,9 @@ import io.reactivex.internal.fuseable.FuseToObservable; import io.reactivex.plugins.RxJavaPlugins; -public final class ObservableAllSingle extends Single implements FuseToObservable{ +public final class ObservableAllSingle extends Single implements FuseToObservable { final ObservableSource source; - + final Predicate predicate; public ObservableAllSingle(ObservableSource source, Predicate predicate) { this.source = source; @@ -33,7 +33,7 @@ public ObservableAllSingle(ObservableSource source, Predicate pred protected void subscribeActual(SingleObserver t) { source.subscribe(new AllObserver(t, predicate)); } - + @Override public Observable fuseToObservable() { return RxJavaPlugins.onAssembly(new ObservableAll(source, predicate)); diff --git a/src/main/java/io/reactivex/internal/operators/observable/ObservableAnySingle.java b/src/main/java/io/reactivex/internal/operators/observable/ObservableAnySingle.java index e128947999..337a573d76 100644 --- a/src/main/java/io/reactivex/internal/operators/observable/ObservableAnySingle.java +++ b/src/main/java/io/reactivex/internal/operators/observable/ObservableAnySingle.java @@ -22,9 +22,9 @@ public final class ObservableAnySingle extends Single implements FuseToObservable { final ObservableSource source; - + final Predicate predicate; - + public ObservableAnySingle(ObservableSource source, Predicate predicate) { this.source = source; this.predicate = predicate; @@ -34,7 +34,7 @@ public ObservableAnySingle(ObservableSource source, Predicate pred protected void subscribeActual(SingleObserver t) { source.subscribe(new AnyObserver(t, predicate)); } - + @Override public Observable fuseToObservable() { return RxJavaPlugins.onAssembly(new ObservableAny(source, predicate)); diff --git a/src/main/java/io/reactivex/internal/operators/observable/ObservableCollectSingle.java b/src/main/java/io/reactivex/internal/operators/observable/ObservableCollectSingle.java new file mode 100644 index 0000000000..8a8be236a7 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/observable/ObservableCollectSingle.java @@ -0,0 +1,124 @@ +/** + * 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.internal.operators.observable; + +import java.util.concurrent.Callable; + +import io.reactivex.*; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.BiConsumer; +import io.reactivex.internal.disposables.*; +import io.reactivex.internal.functions.ObjectHelper; +import io.reactivex.internal.fuseable.FuseToObservable; +import io.reactivex.plugins.RxJavaPlugins; + +public final class ObservableCollectSingle extends Single implements FuseToObservable { + + final ObservableSource source; + + final Callable initialSupplier; + final BiConsumer collector; + + public ObservableCollectSingle(ObservableSource source, + Callable initialSupplier, BiConsumer collector) { + this.source = source; + this.initialSupplier = initialSupplier; + this.collector = collector; + } + + @Override + protected void subscribeActual(SingleObserver t) { + U u; + try { + u = ObjectHelper.requireNonNull(initialSupplier.call(), "The initialSupplier returned a null value"); + } catch (Throwable e) { + EmptyDisposable.error(e, t); + return; + } + + source.subscribe(new CollectObserver(t, u, collector)); + } + + @Override + public Observable fuseToObservable() { + return RxJavaPlugins.onAssembly(new ObservableCollect(source, initialSupplier, collector)); + } + + static final class CollectObserver implements Observer, Disposable { + final SingleObserver actual; + final BiConsumer collector; + final U u; + + Disposable s; + + boolean done; + + CollectObserver(SingleObserver actual, U u, BiConsumer collector) { + this.actual = actual; + this.collector = collector; + this.u = u; + } + + @Override + public void onSubscribe(Disposable s) { + if (DisposableHelper.validate(this.s, s)) { + this.s = s; + actual.onSubscribe(this); + } + } + + + @Override + public void dispose() { + s.dispose(); + } + + @Override + public boolean isDisposed() { + return s.isDisposed(); + } + + + @Override + public void onNext(T t) { + if (done) { + return; + } + try { + collector.accept(u, t); + } catch (Throwable e) { + s.dispose(); + onError(e); + } + } + + @Override + public void onError(Throwable t) { + if (done) { + RxJavaPlugins.onError(t); + return; + } + done = true; + actual.onError(t); + } + + @Override + public void onComplete() { + if (done) { + return; + } + done = true; + actual.onSuccess(u); + } + } +} diff --git a/src/main/java/io/reactivex/internal/operators/observable/ObservableLastSingle.java b/src/main/java/io/reactivex/internal/operators/observable/ObservableLastSingle.java index 1f1683c72a..eee8a62c4f 100644 --- a/src/main/java/io/reactivex/internal/operators/observable/ObservableLastSingle.java +++ b/src/main/java/io/reactivex/internal/operators/observable/ObservableLastSingle.java @@ -28,31 +28,31 @@ public final class ObservableLastSingle extends Single { final ObservableSource source; - + final T defaultItem; - + public ObservableLastSingle(ObservableSource source, T defaultItem) { this.source = source; this.defaultItem = defaultItem; } // TODO fuse back to Observable - + @Override protected void subscribeActual(SingleObserver observer) { source.subscribe(new LastObserver(observer, defaultItem)); } - + static final class LastObserver implements Observer, Disposable { - + final SingleObserver actual; - + final T defaultItem; Disposable s; - + T item; - + public LastObserver(SingleObserver actual, T defaultItem) { this.actual = actual; this.defaultItem = defaultItem; @@ -73,7 +73,7 @@ public boolean isDisposed() { public void onSubscribe(Disposable s) { if (DisposableHelper.validate(this.s, s)) { this.s = s; - + actual.onSubscribe(this); } } @@ -106,7 +106,5 @@ public void onComplete() { } } } - - } } diff --git a/src/main/java/io/reactivex/internal/operators/observable/ObservableToListSingle.java b/src/main/java/io/reactivex/internal/operators/observable/ObservableToListSingle.java new file mode 100644 index 0000000000..9c4d5180a1 --- /dev/null +++ b/src/main/java/io/reactivex/internal/operators/observable/ObservableToListSingle.java @@ -0,0 +1,119 @@ +/** + * 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.internal.operators.observable; + +import java.util.*; +import java.util.concurrent.Callable; + +import io.reactivex.*; +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.Exceptions; +import io.reactivex.internal.disposables.*; +import io.reactivex.internal.fuseable.FuseToObservable; +import io.reactivex.plugins.RxJavaPlugins; + +public final class ObservableToListSingle> +extends Single implements FuseToObservable { + + final ObservableSource source; + + final Callable collectionSupplier; + + public ObservableToListSingle(ObservableSource source, final int defaultCapacityHint) { + this.source = source; + this.collectionSupplier = new Callable() { + @Override + @SuppressWarnings("unchecked") + public U call() throws Exception { + return (U)new ArrayList(defaultCapacityHint); + } + }; + } + + public ObservableToListSingle(ObservableSource source, Callable collectionSupplier) { + this.source = source; + this.collectionSupplier = collectionSupplier; + } + + @Override + public void subscribeActual(SingleObserver t) { + U coll; + try { + coll = collectionSupplier.call(); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + EmptyDisposable.error(e, t); + return; + } + source.subscribe(new ToListObserver(t, coll)); + } + + @Override + public Observable fuseToObservable() { + return RxJavaPlugins.onAssembly(new ObservableToList(source, collectionSupplier)); + } + + static final class ToListObserver> implements Observer, Disposable { + final SingleObserver actual; + + U collection; + + Disposable s; + + ToListObserver(SingleObserver actual, U collection) { + this.actual = actual; + this.collection = collection; + } + + @Override + public void onSubscribe(Disposable s) { + if (DisposableHelper.validate(this.s, s)) { + this.s = s; + actual.onSubscribe(this); + } + } + + + @Override + public void dispose() { + s.dispose(); + } + + @Override + public boolean isDisposed() { + return s.isDisposed(); + } + + + @Override + public void onNext(T t) { + collection.add(t); + } + + @Override + public void onError(Throwable t) { + collection = null; + actual.onError(t); + } + + @Override + public void onComplete() { + U c = collection; + collection = null; + actual.onSuccess(c); + } + } +} diff --git a/src/main/java/io/reactivex/observers/TestObserver.java b/src/main/java/io/reactivex/observers/TestObserver.java index b25a0ae492..0a599863bb 100644 --- a/src/main/java/io/reactivex/observers/TestObserver.java +++ b/src/main/java/io/reactivex/observers/TestObserver.java @@ -903,7 +903,7 @@ public void onSuccess(T value) { onNext(value); onComplete(); } - + /** * An observer that ignores all events and does not report errors. */ diff --git a/src/perf/java/io/reactivex/RxVsStreamPerf.java b/src/perf/java/io/reactivex/RxVsStreamPerf.java index 2ab87b018b..c9f48b0ae8 100644 --- a/src/perf/java/io/reactivex/RxVsStreamPerf.java +++ b/src/perf/java/io/reactivex/RxVsStreamPerf.java @@ -80,7 +80,7 @@ public Observable apply(Integer v) { } }); - values = range.toList().blockingFirst(); + values = range.toList().blockingGet(); } @Benchmark diff --git a/src/test/java/io/reactivex/InternalWrongNaming.java b/src/test/java/io/reactivex/InternalWrongNaming.java index af5f4a4bcc..a9c4b3bac9 100644 --- a/src/test/java/io/reactivex/InternalWrongNaming.java +++ b/src/test/java/io/reactivex/InternalWrongNaming.java @@ -158,11 +158,13 @@ public void observableNoUnsubscrib() throws Exception { @Test public void flowableNoObserver() throws Exception { - checkInternalOperatorNaming("Flowable", "Observer", + checkInternalOperatorNaming("Flowable", "Observer", "FlowableFromObservable", "FlowableLastSingle", "FlowableAnySingle", - "FlowableAllSingle" + "FlowableAllSingle", + "FlowableToListSingle", + "FlowableCollectSingle" ); } } diff --git a/src/test/java/io/reactivex/completable/CompletableTest.java b/src/test/java/io/reactivex/completable/CompletableTest.java index c7917c0919..3ed74e948d 100644 --- a/src/test/java/io/reactivex/completable/CompletableTest.java +++ b/src/test/java/io/reactivex/completable/CompletableTest.java @@ -1593,7 +1593,11 @@ public void onComplete() { Assert.assertFalse("Already done", done.get()); - Thread.sleep(200); + int timeout = 10; + + while (timeout-- > 0 && !done.get()) { + Thread.sleep(100); + } Assert.assertTrue("Not done", done.get()); diff --git a/src/test/java/io/reactivex/flowable/FlowableCollectTest.java b/src/test/java/io/reactivex/flowable/FlowableCollectTest.java index 320b15a3ca..3c6d2beaa4 100644 --- a/src/test/java/io/reactivex/flowable/FlowableCollectTest.java +++ b/src/test/java/io/reactivex/flowable/FlowableCollectTest.java @@ -22,14 +22,14 @@ import org.junit.Test; -import io.reactivex.Flowable; +import io.reactivex.*; import io.reactivex.functions.BiConsumer; import io.reactivex.plugins.RxJavaPlugins; public final class FlowableCollectTest { @Test - public void testCollectToList() { + public void testCollectToListFlowable() { Flowable> o = Flowable.just(1, 2, 3) .collect(new Callable>() { @Override @@ -41,7 +41,7 @@ public List call() { public void accept(List list, Integer v) { list.add(v); } - }); + }).toFlowable(); List list = o.blockingLast(); @@ -59,6 +59,159 @@ public void accept(List list, Integer v) { assertEquals(3, list2.get(2).intValue()); } + @Test + public void testCollectToStringFlowable() { + String value = Flowable.just(1, 2, 3) + .collect( + new Callable() { + @Override + public StringBuilder call() { + return new StringBuilder(); + } + }, + new BiConsumer() { + @Override + public void accept(StringBuilder sb, Integer v) { + if (sb.length() > 0) { + sb.append("-"); + } + sb.append(v); + } + }).toFlowable().blockingLast().toString(); + + assertEquals("1-2-3", value); + } + + + @Test + public void testFactoryFailureResultsInErrorEmissionFlowable() { + final RuntimeException e = new RuntimeException(); + Flowable.just(1).collect(new Callable>() { + + @Override + public List call() throws Exception { + throw e; + } + }, new BiConsumer, Integer>() { + + @Override + public void accept(List list, Integer t) { + list.add(t); + } + }) + .test() + .assertNoValues() + .assertError(e) + .assertNotComplete(); + } + + @Test + public void testCollectorFailureDoesNotResultInTwoErrorEmissionsFlowable() { + try { + final List list = new CopyOnWriteArrayList(); + RxJavaPlugins.setErrorHandler(addToList(list)); + final RuntimeException e1 = new RuntimeException(); + final RuntimeException e2 = new RuntimeException(); + + Burst.items(1).error(e2) // + .collect(callableListCreator(), biConsumerThrows(e1)) + .toFlowable() + .test() // + .assertError(e1) // + .assertNotComplete(); + assertEquals(Arrays.asList(e2), list); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void testCollectorFailureDoesNotResultInErrorAndCompletedEmissionsFlowable() { + final RuntimeException e = new RuntimeException(); + Burst.item(1).create() // + .collect(callableListCreator(), biConsumerThrows(e)) // + .toFlowable() + .test() // + .assertError(e) // + .assertNotComplete(); + } + + @Test + public void testCollectorFailureDoesNotResultInErrorAndOnNextEmissionsFlowable() { + final RuntimeException e = new RuntimeException(); + final AtomicBoolean added = new AtomicBoolean(); + BiConsumer throwOnFirstOnly = new BiConsumer() { + + boolean once = true; + + @Override + public void accept(Object o, Integer t) { + if (once) { + once = false; + throw e; + } else { + added.set(true); + } + } + }; + Burst.items(1, 2).create() // + .collect(callableListCreator(), throwOnFirstOnly)// + .toFlowable() + .test() // + .assertError(e) // + .assertNoValues() // + .assertNotComplete(); + assertFalse(added.get()); + } + + + @SuppressWarnings("unchecked") + @Test + public void collectIntoFlowable() { + Flowable.just(1, 1, 1, 1, 2) + .collectInto(new HashSet(), new BiConsumer, Integer>() { + @Override + public void accept(HashSet s, Integer v) throws Exception { + s.add(v); + } + }) + .toFlowable() + .test() + .assertResult(new HashSet(Arrays.asList(1, 2))); + } + + + @Test + public void testCollectToList() { + Single> o = Flowable.just(1, 2, 3) + .collect(new Callable>() { + @Override + public List call() { + return new ArrayList(); + } + }, new BiConsumer, Integer>() { + @Override + public void accept(List list, Integer v) { + list.add(v); + } + }); + + List list = o.blockingGet(); + + assertEquals(3, list.size()); + assertEquals(1, list.get(0).intValue()); + assertEquals(2, list.get(1).intValue()); + assertEquals(3, list.get(2).intValue()); + + // test multiple subscribe + List list2 = o.blockingGet(); + + assertEquals(3, list2.size()); + assertEquals(1, list2.get(0).intValue()); + assertEquals(2, list2.get(1).intValue()); + assertEquals(3, list2.get(2).intValue()); + } + @Test public void testCollectToString() { String value = Flowable.just(1, 2, 3) @@ -77,7 +230,7 @@ public void accept(StringBuilder sb, Integer v) { } sb.append(v); } - }).blockingLast().toString(); + }).blockingGet().toString(); assertEquals("1-2-3", value); } diff --git a/src/test/java/io/reactivex/flowable/FlowableConcatTests.java b/src/test/java/io/reactivex/flowable/FlowableConcatTests.java index f782236da7..381fad005b 100644 --- a/src/test/java/io/reactivex/flowable/FlowableConcatTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableConcatTests.java @@ -29,7 +29,7 @@ public void testConcatSimple() { Flowable o1 = Flowable.just("one", "two"); Flowable o2 = Flowable.just("three", "four"); - List values = Flowable.concat(o1, o2).toList().blockingSingle(); + List values = Flowable.concat(o1, o2).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -45,7 +45,7 @@ public void testConcatWithFlowableOfFlowable() { Flowable> os = Flowable.just(o1, o2, o3); - List values = Flowable.concat(os).toList().blockingSingle(); + List values = Flowable.concat(os).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -64,7 +64,7 @@ public void testConcatWithIterableOfFlowable() { @SuppressWarnings("unchecked") Iterable> is = Arrays.asList(o1, o2, o3); - List values = Flowable.concat(Flowable.fromIterable(is)).toList().blockingSingle(); + List values = Flowable.concat(Flowable.fromIterable(is)).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -86,7 +86,7 @@ public void testConcatCovariance() { Flowable> os = Flowable.just(o1, o2); - List values = Flowable.concat(os).toList().blockingSingle(); + List values = Flowable.concat(os).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -108,7 +108,7 @@ public void testConcatCovariance2() { Flowable> os = Flowable.just(o1, o2); - List values = Flowable.concat(os).toList().blockingSingle(); + List values = Flowable.concat(os).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -128,7 +128,7 @@ public void testConcatCovariance3() { Flowable o1 = Flowable.just(horrorMovie1, movie); Flowable o2 = Flowable.just(media, horrorMovie2); - List values = Flowable.concat(o1, o2).toList().blockingSingle(); + List values = Flowable.concat(o1, o2).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -156,7 +156,7 @@ public void subscribe(Subscriber o) { Flowable o2 = Flowable.just(media, horrorMovie2); - List values = Flowable.concat(o1, o2).toList().blockingSingle(); + List values = Flowable.concat(o1, o2).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); diff --git a/src/test/java/io/reactivex/flowable/FlowableMergeTests.java b/src/test/java/io/reactivex/flowable/FlowableMergeTests.java index d1a19e3406..49b0249775 100644 --- a/src/test/java/io/reactivex/flowable/FlowableMergeTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableMergeTests.java @@ -43,7 +43,7 @@ public void testMergeCovariance() { Flowable> os = Flowable.just(o1, o2); - List values = Flowable.merge(os).toList().blockingSingle(); + List values = Flowable.merge(os).toList().blockingGet(); assertEquals(4, values.size()); } @@ -55,7 +55,7 @@ public void testMergeCovariance2() { Flowable> os = Flowable.just(o1, o2); - List values = Flowable.merge(os).toList().blockingSingle(); + List values = Flowable.merge(os).toList().blockingGet(); assertEquals(5, values.size()); } @@ -65,7 +65,7 @@ public void testMergeCovariance3() { Flowable o1 = Flowable.just(new HorrorMovie(), new Movie()); Flowable o2 = Flowable.just(new Media(), new HorrorMovie()); - List values = Flowable.merge(o1, o2).toList().blockingSingle(); + List values = Flowable.merge(o1, o2).toList().blockingGet(); assertTrue(values.get(0) instanceof HorrorMovie); assertTrue(values.get(1) instanceof Movie); @@ -88,7 +88,7 @@ public Publisher call() { Flowable o2 = Flowable.just(new Media(), new HorrorMovie()); - List values = Flowable.merge(o1, o2).toList().blockingSingle(); + List values = Flowable.merge(o1, o2).toList().blockingGet(); assertTrue(values.get(0) instanceof HorrorMovie); assertTrue(values.get(1) instanceof Movie); diff --git a/src/test/java/io/reactivex/flowable/FlowableNullTests.java b/src/test/java/io/reactivex/flowable/FlowableNullTests.java index 1cef2c58cc..3ecdc5650f 100644 --- a/src/test/java/io/reactivex/flowable/FlowableNullTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableNullTests.java @@ -918,7 +918,7 @@ public Object call() { }, new BiConsumer() { @Override public void accept(Object a, Integer b) { } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2386,7 +2386,7 @@ public Object apply(Integer v) { public Object apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2421,7 +2421,7 @@ public Object apply(Integer v) { public Map call() { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2451,7 +2451,7 @@ public Object apply(Integer v) { public Object apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2486,7 +2486,7 @@ public Object apply(Integer v) { public Map> call() { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2531,7 +2531,7 @@ public Map> call() { public Collection apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) diff --git a/src/test/java/io/reactivex/flowable/FlowableStartWithTests.java b/src/test/java/io/reactivex/flowable/FlowableStartWithTests.java index 784c5d28a5..bc0f12efb4 100644 --- a/src/test/java/io/reactivex/flowable/FlowableStartWithTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableStartWithTests.java @@ -26,7 +26,7 @@ public class FlowableStartWithTests { @Test public void startWith1() { List values = Flowable.just("one", "two") - .startWithArray("zero").toList().blockingSingle(); + .startWithArray("zero").toList().blockingGet(); assertEquals("zero", values.get(0)); assertEquals("two", values.get(2)); @@ -37,7 +37,7 @@ public void startWithIterable() { List li = new ArrayList(); li.add("alpha"); li.add("beta"); - List values = Flowable.just("one", "two").startWith(li).toList().blockingSingle(); + List values = Flowable.just("one", "two").startWith(li).toList().blockingGet(); assertEquals("alpha", values.get(0)); assertEquals("beta", values.get(1)); @@ -53,7 +53,7 @@ public void startWithObservable() { List values = Flowable.just("one", "two") .startWith(Flowable.fromIterable(li)) .toList() - .blockingSingle(); + .blockingGet(); assertEquals("alpha", values.get(0)); assertEquals("beta", values.get(1)); diff --git a/src/test/java/io/reactivex/flowable/FlowableTests.java b/src/test/java/io/reactivex/flowable/FlowableTests.java index 34fa8e51df..d073b29f2f 100644 --- a/src/test/java/io/reactivex/flowable/FlowableTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableTests.java @@ -992,7 +992,7 @@ public boolean test(Boolean v) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); diff --git a/src/test/java/io/reactivex/flowable/FlowableWindowTests.java b/src/test/java/io/reactivex/flowable/FlowableWindowTests.java index 70870c9203..083a40b1dc 100644 --- a/src/test/java/io/reactivex/flowable/FlowableWindowTests.java +++ b/src/test/java/io/reactivex/flowable/FlowableWindowTests.java @@ -34,7 +34,7 @@ public void testWindow() { .map(new Function, Flowable>>() { @Override public Flowable> apply(Flowable xs) { - return xs.toList(); + return xs.toList().toFlowable(); } }) ) diff --git a/src/test/java/io/reactivex/internal/operators/flowable/BufferUntilSubscriberTest.java b/src/test/java/io/reactivex/internal/operators/flowable/BufferUntilSubscriberTest.java index a023209103..ee715d08a1 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/BufferUntilSubscriberTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/BufferUntilSubscriberTest.java @@ -62,7 +62,7 @@ public Object apply(Integer integer) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List integers) { counter.incrementAndGet(); diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableConcatTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableConcatTest.java index afdc5dbbd8..49d6089981 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableConcatTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableConcatTest.java @@ -622,9 +622,9 @@ public Flowable apply(Integer v) { } }); - Flowable> result = Flowable.concat(source).toList(); + Single> result = Flowable.concat(source).toList(); - Subscriber> o = TestHelper.mockSubscriber(); + SingleObserver> o = TestHelper.mockSingleObserver(); InOrder inOrder = inOrder(o); result.subscribe(o); @@ -633,8 +633,7 @@ public Flowable apply(Integer v) { for (int i = 0; i < n; i++) { list.add(i); } - inOrder.verify(o).onNext(list); - inOrder.verify(o).onComplete(); + inOrder.verify(o).onSuccess(list); verify(o, never()).onError(any(Throwable.class)); } @Test @@ -647,9 +646,9 @@ public Flowable apply(Integer v) { } }); - Flowable> result = Flowable.concat(source).take(n / 2).toList(); + Single> result = Flowable.concat(source).take(n / 2).toList(); - Subscriber> o = TestHelper.mockSubscriber(); + SingleObserver> o = TestHelper.mockSingleObserver(); InOrder inOrder = inOrder(o); result.subscribe(o); @@ -658,8 +657,7 @@ public Flowable apply(Integer v) { for (int i = 0; i < n / 2; i++) { list.add(i); } - inOrder.verify(o).onNext(list); - inOrder.verify(o).onComplete(); + inOrder.verify(o).onSuccess(list); verify(o, never()).onError(any(Throwable.class)); } diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableDoOnEachTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableDoOnEachTest.java index 253a2b41f3..3704e5ac2f 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableDoOnEachTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableDoOnEachTest.java @@ -126,7 +126,7 @@ public boolean test(Boolean value) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); @@ -152,7 +152,7 @@ public boolean test(Boolean value) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableRepeatTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableRepeatTest.java index 8361732d2d..1b9dd9b2f2 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableRepeatTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableRepeatTest.java @@ -54,7 +54,7 @@ public void subscribe(final Subscriber o) { @Test(timeout = 2000) public void testRepeatTake() { Flowable xs = Flowable.just(1, 2); - Object[] ys = xs.repeat().subscribeOn(Schedulers.newThread()).take(4).toList().blockingLast().toArray(); + Object[] ys = xs.repeat().subscribeOn(Schedulers.newThread()).take(4).toList().blockingGet().toArray(); assertArrayEquals(new Object[] { 1, 2, 1, 2 }, ys); } @@ -91,7 +91,7 @@ public Integer apply(Integer t1) { return t1; } - }).take(4).toList().blockingLast().toArray(); + }).take(4).toList().blockingGet().toArray(); assertEquals(2, counter.get()); assertArrayEquals(new Object[] { 1, 2, 1, 2 }, ys); diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableScanTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableScanTest.java index 67bf6b8ee6..58cf3ac3d9 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableScanTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableScanTest.java @@ -253,6 +253,32 @@ public void onNext(Integer t) { */ @Test public void testSeedFactory() { + Single> o = Flowable.range(1, 10) + .collect(new Callable>() { + + @Override + public List call() { + return new ArrayList(); + } + + }, new BiConsumer, Integer>() { + + @Override + public void accept(List list, Integer t2) { + list.add(t2); + } + + }); + + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingGet()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingGet()); + } + + /** + * This uses the public API collect which uses scan under the covers. + */ + @Test + public void testSeedFactoryFlowable() { Flowable> o = Flowable.range(1, 10) .collect(new Callable>() { @@ -268,7 +294,7 @@ public void accept(List list, Integer t2) { list.add(t2); } - }).takeLast(1); + }).toFlowable().takeLast(1); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingSingle()); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingSingle()); diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableTakeLastTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableTakeLastTest.java index 1ee6a54b27..5a6547e00f 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableTakeLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableTakeLastTest.java @@ -154,7 +154,7 @@ public boolean test(Long v) { } }) .toList() - .blockingSingle().size()); + .blockingGet().size()); } @Test diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToListTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToListTest.java index 26470bac70..63bc58bdbf 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToListTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToListTest.java @@ -24,6 +24,7 @@ import org.reactivestreams.Subscriber; import io.reactivex.*; +import io.reactivex.observers.TestObserver; import io.reactivex.processors.PublishProcessor; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -31,9 +32,9 @@ public class FlowableToListTest { @Test - public void testList() { + public void testListFlowable() { Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); - Flowable> observable = w.toList(); + Flowable> observable = w.toList().toFlowable(); Subscriber> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); @@ -43,9 +44,9 @@ public void testList() { } @Test - public void testListViaObservable() { + public void testListViaObservableFlowable() { Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); - Flowable> observable = w.toList(); + Flowable> observable = w.toList().toFlowable(); Subscriber> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); @@ -55,9 +56,9 @@ public void testListViaObservable() { } @Test - public void testListMultipleSubscribers() { + public void testListMultipleSubscribersFlowable() { Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); - Flowable> observable = w.toList(); + Flowable> observable = w.toList().toFlowable(); Subscriber> o1 = TestHelper.mockSubscriber(); observable.subscribe(o1); @@ -78,9 +79,9 @@ public void testListMultipleSubscribers() { @Test @Ignore("Null values are not allowed") - public void testListWithNullValue() { + public void testListWithNullValueFlowable() { Flowable w = Flowable.fromIterable(Arrays.asList("one", null, "three")); - Flowable> observable = w.toList(); + Flowable> observable = w.toList().toFlowable(); Subscriber> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); @@ -90,14 +91,14 @@ public void testListWithNullValue() { } @Test - public void testListWithBlockingFirst() { + public void testListWithBlockingFirstFlowable() { Flowable o = Flowable.fromIterable(Arrays.asList("one", "two", "three")); - List actual = o.toList().blockingFirst(); + List actual = o.toList().toFlowable().blockingFirst(); Assert.assertEquals(Arrays.asList("one", "two", "three"), actual); } @Test - public void testBackpressureHonored() { - Flowable> w = Flowable.just(1, 2, 3, 4, 5).toList(); + public void testBackpressureHonoredFlowable() { + Flowable> w = Flowable.just(1, 2, 3, 4, 5).toList().toFlowable(); TestSubscriber> ts = new TestSubscriber>(0L); w.subscribe(ts); @@ -120,7 +121,7 @@ public void testBackpressureHonored() { } @Test(timeout = 2000) @Ignore("PublishSubject no longer emits without requests so this test fails due to the race of onComplete and request") - public void testAsyncRequested() { + public void testAsyncRequestedFlowable() { Scheduler.Worker w = Schedulers.newThread().createWorker(); try { for (int i = 0; i < 1000; i++) { @@ -128,7 +129,7 @@ public void testAsyncRequested() { System.out.println("testAsyncRequested -> " + i); } PublishProcessor source = PublishProcessor.create(); - Flowable> sorted = source.toList(); + Flowable> sorted = source.toList().toFlowable(); final CyclicBarrier cb = new CyclicBarrier(2); final TestSubscriber> ts = new TestSubscriber>(0L); @@ -153,6 +154,136 @@ public void run() { w.dispose(); } } + + @SuppressWarnings("unchecked") + @Test + public void capacityHintFlowable() { + Flowable.range(1, 10) + .toList(4) + .toFlowable() + .test() + .assertResult(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + public void testList() { + Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", "two", "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testListViaObservable() { + Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", "two", "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testListMultipleSubscribers() { + Flowable w = Flowable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> o1 = TestHelper.mockSingleObserver(); + observable.subscribe(o1); + + SingleObserver> o2 = TestHelper.mockSingleObserver(); + observable.subscribe(o2); + + List expected = Arrays.asList("one", "two", "three"); + + verify(o1, times(1)).onSuccess(expected); + verify(o1, Mockito.never()).onError(any(Throwable.class)); + + verify(o2, times(1)).onSuccess(expected); + verify(o2, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + @Ignore("Null values are not allowed") + public void testListWithNullValue() { + Flowable w = Flowable.fromIterable(Arrays.asList("one", null, "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", null, "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testListWithBlockingFirst() { + Flowable o = Flowable.fromIterable(Arrays.asList("one", "two", "three")); + List actual = o.toList().blockingGet(); + Assert.assertEquals(Arrays.asList("one", "two", "three"), actual); + } + @Test + @Ignore("Single doesn't do backpressure") + public void testBackpressureHonored() { + Single> w = Flowable.just(1, 2, 3, 4, 5).toList(); + TestObserver> ts = new TestObserver>(); + + w.subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + +// ts.request(1); + + ts.assertValue(Arrays.asList(1, 2, 3, 4, 5)); + ts.assertNoErrors(); + ts.assertComplete(); + +// ts.request(1); + + ts.assertValue(Arrays.asList(1, 2, 3, 4, 5)); + ts.assertNoErrors(); + ts.assertComplete(); + } + @Test(timeout = 2000) + @Ignore("PublishProcessor no longer emits without requests so this test fails due to the race of onComplete and request") + public void testAsyncRequested() { + Scheduler.Worker w = Schedulers.newThread().createWorker(); + try { + for (int i = 0; i < 1000; i++) { + if (i % 50 == 0) { + System.out.println("testAsyncRequested -> " + i); + } + PublishProcessor source = PublishProcessor.create(); + Single> sorted = source.toList(); + + final CyclicBarrier cb = new CyclicBarrier(2); + final TestObserver> ts = new TestObserver>(); + sorted.subscribe(ts); + + w.schedule(new Runnable() { + @Override + public void run() { + await(cb); +// ts.request(1); + } + }); + source.onNext(1); + await(cb); + source.onComplete(); + ts.awaitTerminalEvent(1, TimeUnit.SECONDS); + ts.assertTerminated(); + ts.assertNoErrors(); + ts.assertValue(Arrays.asList(1)); + } + } finally { + w.dispose(); + } + } static void await(CyclicBarrier cb) { try { cb.await(); diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMapTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMapTest.java index 51e401db7a..1ecc61e23d 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMapTest.java @@ -27,10 +27,12 @@ public class FlowableToMapTest { Subscriber objectObserver; + SingleObserver singleObserver; @Before public void before() { objectObserver = TestHelper.mockSubscriber(); + singleObserver = TestHelper.mockSingleObserver(); } Function lengthFunc = new Function() { @@ -47,10 +49,10 @@ public String apply(String t1) { }; @Test - public void testToMap() { + public void testToMapFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); - Flowable> mapped = source.toMap(lengthFunc); + Flowable> mapped = source.toMap(lengthFunc).toFlowable(); Map expected = new HashMap(); expected.put(1, "a"); @@ -66,10 +68,10 @@ public void testToMap() { } @Test - public void testToMapWithValueSelector() { + public void testToMapWithValueSelectorFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); - Flowable> mapped = source.toMap(lengthFunc, duplicate); + Flowable> mapped = source.toMap(lengthFunc, duplicate).toFlowable(); Map expected = new HashMap(); expected.put(1, "aa"); @@ -85,7 +87,7 @@ public void testToMapWithValueSelector() { } @Test - public void testToMapWithError() { + public void testToMapWithErrorFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); Function lengthFuncErr = new Function() { @@ -97,7 +99,7 @@ public Integer apply(String t1) { return t1.length(); } }; - Flowable> mapped = source.toMap(lengthFuncErr); + Flowable> mapped = source.toMap(lengthFuncErr).toFlowable(); Map expected = new HashMap(); expected.put(1, "a"); @@ -114,7 +116,7 @@ public Integer apply(String t1) { } @Test - public void testToMapWithErrorInValueSelector() { + public void testToMapWithErrorInValueSelectorFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); Function duplicateErr = new Function() { @@ -127,7 +129,7 @@ public String apply(String t1) { } }; - Flowable> mapped = source.toMap(lengthFunc, duplicateErr); + Flowable> mapped = source.toMap(lengthFunc, duplicateErr).toFlowable(); Map expected = new HashMap(); expected.put(1, "aa"); @@ -144,7 +146,7 @@ public String apply(String t1) { } @Test - public void testToMapWithFactory() { + public void testToMapWithFactoryFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); Callable> mapFactory = new Callable>() { @@ -173,7 +175,7 @@ public Integer apply(String t1) { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toFlowable(); Map expected = new LinkedHashMap(); expected.put(2, "bb"); @@ -188,7 +190,7 @@ public String apply(String v) { } @Test - public void testToMapWithErrorThrowingFactory() { + public void testToMapWithErrorThrowingFactoryFlowable() { Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); Callable> mapFactory = new Callable>() { @@ -209,7 +211,7 @@ public Integer apply(String t1) { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toFlowable(); Map expected = new LinkedHashMap(); expected.put(2, "bb"); @@ -223,4 +225,176 @@ public String apply(String v) { verify(objectObserver, times(1)).onError(any(Throwable.class)); } + + @Test + public void testToMap() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Single> mapped = source.toMap(lengthFunc); + + Map expected = new HashMap(); + expected.put(1, "a"); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithValueSelector() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Single> mapped = source.toMap(lengthFunc, duplicate); + + Map expected = new HashMap(); + expected.put(1, "aa"); + expected.put(2, "bbbb"); + expected.put(3, "cccccc"); + expected.put(4, "dddddddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithError() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Function lengthFuncErr = new Function() { + @Override + public Integer apply(String t1) { + if ("bb".equals(t1)) { + throw new RuntimeException("Forced Failure"); + } + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFuncErr); + + Map expected = new HashMap(); + expected.put(1, "a"); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + + } + + @Test + public void testToMapWithErrorInValueSelector() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Function duplicateErr = new Function() { + @Override + public String apply(String t1) { + if ("bb".equals(t1)) { + throw new RuntimeException("Forced failure"); + } + return t1 + t1; + } + }; + + Single> mapped = source.toMap(lengthFunc, duplicateErr); + + Map expected = new HashMap(); + expected.put(1, "aa"); + expected.put(2, "bbbb"); + expected.put(3, "cccccc"); + expected.put(4, "dddddddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + + } + + @Test + public void testToMapWithFactory() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Callable> mapFactory = new Callable>() { + @Override + public Map call() { + return new LinkedHashMap() { + + private static final long serialVersionUID = -3296811238780863394L; + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > 3; + } + }; + } + }; + + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map expected = new LinkedHashMap(); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithErrorThrowingFactory() { + Flowable source = Flowable.just("a", "bb", "ccc", "dddd"); + + Callable> mapFactory = new Callable>() { + @Override + public Map call() { + throw new RuntimeException("Forced failure"); + } + }; + + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map expected = new LinkedHashMap(); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMultimapTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMultimapTest.java index 3fc1147f06..625f8df380 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMultimapTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToMultimapTest.java @@ -28,9 +28,12 @@ public class FlowableToMultimapTest { Subscriber objectObserver; + SingleObserver singleObserver; + @Before public void before() { objectObserver = TestHelper.mockSubscriber(); + singleObserver = TestHelper.mockSingleObserver(); } Function lengthFunc = new Function() { @@ -47,10 +50,10 @@ public String apply(String t1) { }; @Test - public void testToMultimap() { + public void testToMultimapFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd"); - Flowable>> mapped = source.toMultimap(lengthFunc); + Flowable>> mapped = source.toMultimap(lengthFunc).toFlowable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); @@ -64,10 +67,10 @@ public void testToMultimap() { } @Test - public void testToMultimapWithValueSelector() { + public void testToMultimapWithValueSelectorFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd"); - Flowable>> mapped = source.toMultimap(lengthFunc, duplicate); + Flowable>> mapped = source.toMultimap(lengthFunc, duplicate).toFlowable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); @@ -81,7 +84,7 @@ public void testToMultimapWithValueSelector() { } @Test - public void testToMultimapWithMapFactory() { + public void testToMultimapWithMapFactoryFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd", "eee", "fff"); Callable>> mapFactory = new Callable>>() { @@ -113,7 +116,7 @@ public String apply(String v) { public Collection apply(Integer e) { return new ArrayList(); } - }); + }).toFlowable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -127,7 +130,7 @@ public Collection apply(Integer e) { } @Test - public void testToMultimapWithCollectionFactory() { + public void testToMultimapWithCollectionFactoryFlowable() { Flowable source = Flowable.just("cc", "dd", "eee", "eee"); Function> collectionFactory = new Function>() { @@ -155,7 +158,7 @@ public Map> call() { }; Flowable>> mapped = source - .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); + .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory).toFlowable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -169,7 +172,7 @@ public Map> call() { } @Test - public void testToMultimapWithError() { + public void testToMultimapWithErrorFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd"); Function lengthFuncErr = new Function() { @@ -182,7 +185,7 @@ public Integer apply(String t1) { } }; - Flowable>> mapped = source.toMultimap(lengthFuncErr); + Flowable>> mapped = source.toMultimap(lengthFuncErr).toFlowable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); @@ -196,7 +199,7 @@ public Integer apply(String t1) { } @Test - public void testToMultimapWithErrorInValueSelector() { + public void testToMultimapWithErrorInValueSelectorFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd"); Function duplicateErr = new Function() { @@ -209,7 +212,7 @@ public String apply(String t1) { } }; - Flowable>> mapped = source.toMultimap(lengthFunc, duplicateErr); + Flowable>> mapped = source.toMultimap(lengthFunc, duplicateErr).toFlowable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); @@ -223,7 +226,7 @@ public String apply(String t1) { } @Test - public void testToMultimapWithMapThrowingFactory() { + public void testToMultimapWithMapThrowingFactoryFlowable() { Flowable source = Flowable.just("a", "b", "cc", "dd", "eee", "fff"); Callable>> mapFactory = new Callable>>() { @@ -239,7 +242,7 @@ public Map> call() { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toFlowable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -253,7 +256,7 @@ public String apply(String v) { } @Test - public void testToMultimapWithThrowingCollectionFactory() { + public void testToMultimapWithThrowingCollectionFactoryFlowable() { Flowable source = Flowable.just("cc", "cc", "eee", "eee"); Function> collectionFactory = new Function>() { @@ -281,7 +284,7 @@ public Map> call() { }; Flowable>> mapped = source.toMultimap(lengthFunc, - identity, mapSupplier, collectionFactory); + identity, mapSupplier, collectionFactory).toFlowable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -293,4 +296,246 @@ public Map> call() { verify(objectObserver, never()).onNext(expected); verify(objectObserver, never()).onComplete(); } + + + @Test + public void testToMultimap() { + Flowable source = Flowable.just("a", "b", "cc", "dd"); + + Single>> mapped = source.toMultimap(lengthFunc); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("a", "b")); + expected.put(2, Arrays.asList("cc", "dd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithValueSelector() { + Flowable source = Flowable.just("a", "b", "cc", "dd"); + + Single>> mapped = source.toMultimap(lengthFunc, duplicate); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("aa", "bb")); + expected.put(2, Arrays.asList("cccc", "dddd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithMapFactory() { + Flowable source = Flowable.just("a", "b", "cc", "dd", "eee", "fff"); + + Callable>> mapFactory = new Callable>>() { + @Override + public Map> call() { + return new LinkedHashMap>() { + + private static final long serialVersionUID = -2084477070717362859L; + + @Override + protected boolean removeEldestEntry(Map.Entry> eldest) { + return size() > 2; + } + }; + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + + Single>> mapped = source.toMultimap( + lengthFunc, identity, + mapFactory, new Function>() { + @Override + public Collection apply(Integer e) { + return new ArrayList(); + } + }); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Arrays.asList("eee", "fff")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithCollectionFactory() { + Flowable source = Flowable.just("cc", "dd", "eee", "eee"); + + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + return new ArrayList(); + } else { + return new HashSet(); + } + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Callable>> mapSupplier = new Callable>>() { + @Override + public Map> call() { + return new HashMap>(); + } + }; + + Single>> mapped = source + .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, new HashSet(Arrays.asList("eee"))); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithError() { + Flowable source = Flowable.just("a", "b", "cc", "dd"); + + Function lengthFuncErr = new Function() { + @Override + public Integer apply(String t1) { + if ("b".equals(t1)) { + throw new RuntimeException("Forced Failure"); + } + return t1.length(); + } + }; + + Single>> mapped = source.toMultimap(lengthFuncErr); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("a", "b")); + expected.put(2, Arrays.asList("cc", "dd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithErrorInValueSelector() { + Flowable source = Flowable.just("a", "b", "cc", "dd"); + + Function duplicateErr = new Function() { + @Override + public String apply(String t1) { + if ("b".equals(t1)) { + throw new RuntimeException("Forced failure"); + } + return t1 + t1; + } + }; + + Single>> mapped = source.toMultimap(lengthFunc, duplicateErr); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("aa", "bb")); + expected.put(2, Arrays.asList("cccc", "dddd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithMapThrowingFactory() { + Flowable source = Flowable.just("a", "b", "cc", "dd", "eee", "fff"); + + Callable>> mapFactory = new Callable>>() { + @Override + public Map> call() { + throw new RuntimeException("Forced failure"); + } + }; + + Single>> mapped = source + .toMultimap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Arrays.asList("eee", "fff")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithThrowingCollectionFactory() { + Flowable source = Flowable.just("cc", "cc", "eee", "eee"); + + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + throw new RuntimeException("Forced failure"); + } else { + return new HashSet(); + } + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Callable>> mapSupplier = new Callable>>() { + @Override + public Map> call() { + return new HashMap>(); + } + }; + + Single>> mapped = source.toMultimap(lengthFunc, + identity, mapSupplier, collectionFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Collections.singleton("eee")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToSortedListTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToSortedListTest.java index 0fb988a54e..2e48a5c8d1 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableToSortedListTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableToSortedListTest.java @@ -25,7 +25,7 @@ import org.reactivestreams.Subscriber; import io.reactivex.*; -import io.reactivex.Flowable; +import io.reactivex.observers.TestObserver; import io.reactivex.processors.PublishProcessor; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.TestSubscriber; @@ -33,9 +33,9 @@ public class FlowableToSortedListTest { @Test - public void testSortedList() { + public void testSortedListFlowable() { Flowable w = Flowable.just(1, 3, 2, 5, 4); - Flowable> observable = w.toSortedList(); + Flowable> observable = w.toSortedList().toFlowable(); Subscriber> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); @@ -45,7 +45,7 @@ public void testSortedList() { } @Test - public void testSortedListWithCustomFunction() { + public void testSortedListWithCustomFunctionFlowable() { Flowable w = Flowable.just(1, 3, 2, 5, 4); Flowable> observable = w.toSortedList(new Comparator() { @@ -54,7 +54,7 @@ public int compare(Integer t1, Integer t2) { return t2 - t1; } - }); + }).toFlowable(); Subscriber> observer = TestHelper.mockSubscriber(); observable.subscribe(observer); @@ -64,13 +64,13 @@ public int compare(Integer t1, Integer t2) { } @Test - public void testWithFollowingFirst() { + public void testWithFollowingFirstFlowable() { Flowable o = Flowable.just(1, 3, 2, 5, 4); - assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().blockingFirst()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().toFlowable().blockingFirst()); } @Test - public void testBackpressureHonored() { - Flowable> w = Flowable.just(1, 3, 2, 5, 4).toSortedList(); + public void testBackpressureHonoredFlowable() { + Flowable> w = Flowable.just(1, 3, 2, 5, 4).toSortedList().toFlowable(); TestSubscriber> ts = new TestSubscriber>(0L); w.subscribe(ts); @@ -91,9 +91,10 @@ public void testBackpressureHonored() { ts.assertNoErrors(); ts.assertComplete(); } + @Test(timeout = 2000) @Ignore("PublishSubject no longer emits without requests so this test fails due to the race of onComplete and request") - public void testAsyncRequested() { + public void testAsyncRequestedFlowable() { Scheduler.Worker w = Schedulers.newThread().createWorker(); try { for (int i = 0; i < 1000; i++) { @@ -101,7 +102,7 @@ public void testAsyncRequested() { System.out.println("testAsyncRequested -> " + i); } PublishProcessor source = PublishProcessor.create(); - Flowable> sorted = source.toSortedList(); + Flowable> sorted = source.toSortedList().toFlowable(); final CyclicBarrier cb = new CyclicBarrier(2); final TestSubscriber> ts = new TestSubscriber>(0L); @@ -125,15 +126,6 @@ public void run() { w.dispose(); } } - static void await(CyclicBarrier cb) { - try { - cb.await(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } catch (BrokenBarrierException ex) { - ex.printStackTrace(); - } - } @Test public void sorted() { @@ -154,6 +146,130 @@ public int compare(Integer a, Integer b) { .assertResult(5, 4, 3, 2, 1); } + @SuppressWarnings("unchecked") + @Test + public void toSortedListCapacityFlowable() { + Flowable.just(5, 1, 2, 4, 3).toSortedList(4).toFlowable() + .test() + .assertResult(Arrays.asList(1, 2, 3, 4, 5)); + } + + @SuppressWarnings("unchecked") + @Test + public void toSortedListComparatorCapacityFlowable() { + Flowable.just(5, 1, 2, 4, 3).toSortedList(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b - a; + } + }, 4).toFlowable() + .test() + .assertResult(Arrays.asList(5, 4, 3, 2, 1)); + } + + @Test + public void testSortedList() { + Flowable w = Flowable.just(1, 3, 2, 5, 4); + Single> observable = w.toSortedList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList(1, 2, 3, 4, 5)); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testSortedListWithCustomFunction() { + Flowable w = Flowable.just(1, 3, 2, 5, 4); + Single> observable = w.toSortedList(new Comparator() { + + @Override + public int compare(Integer t1, Integer t2) { + return t2 - t1; + } + + }); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList(5, 4, 3, 2, 1)); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testWithFollowingFirst() { + Flowable o = Flowable.just(1, 3, 2, 5, 4); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().blockingGet()); + } + @Test + @Ignore("Single doesn't do backpressure") + public void testBackpressureHonored() { + Single> w = Flowable.just(1, 3, 2, 5, 4).toSortedList(); + TestObserver> ts = new TestObserver>(); + + w.subscribe(ts); + + ts.assertNoValues(); + ts.assertNoErrors(); + ts.assertNotComplete(); + +// ts.request(1); + + ts.assertValue(Arrays.asList(1, 2, 3, 4, 5)); + ts.assertNoErrors(); + ts.assertComplete(); + +// ts.request(1); + + ts.assertValue(Arrays.asList(1, 2, 3, 4, 5)); + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test(timeout = 2000) + @Ignore("PublishProcessor no longer emits without requests so this test fails due to the race of onComplete and request") + public void testAsyncRequested() { + Scheduler.Worker w = Schedulers.newThread().createWorker(); + try { + for (int i = 0; i < 1000; i++) { + if (i % 50 == 0) { + System.out.println("testAsyncRequested -> " + i); + } + PublishProcessor source = PublishProcessor.create(); + Single> sorted = source.toSortedList(); + + final CyclicBarrier cb = new CyclicBarrier(2); + final TestObserver> ts = new TestObserver>(); + sorted.subscribe(ts); + w.schedule(new Runnable() { + @Override + public void run() { + await(cb); +// ts.request(1); + } + }); + source.onNext(1); + await(cb); + source.onComplete(); + ts.awaitTerminalEvent(1, TimeUnit.SECONDS); + ts.assertTerminated(); + ts.assertNoErrors(); + ts.assertValue(Arrays.asList(1)); + } + } finally { + w.dispose(); + } + } + static void await(CyclicBarrier cb) { + try { + cb.await(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } catch (BrokenBarrierException ex) { + ex.printStackTrace(); + } + } + @SuppressWarnings("unchecked") @Test public void toSortedListCapacity() { diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableWindowWithSizeTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableWindowWithSizeTest.java index 6344e338e6..01be65a11c 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableWindowWithSizeTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableWindowWithSizeTest.java @@ -38,7 +38,7 @@ private static List> toLists(Flowable> observables) { Flowable.concat(observables.map(new Function, Flowable>>() { @Override public Flowable> apply(Flowable xs) { - return xs.toList(); + return xs.toList().toFlowable(); } })) .blockingForEach(new Consumer>() { @@ -297,7 +297,7 @@ public void testBackpressureOuterInexact() { .map(new Function, Flowable>>() { @Override public Flowable> apply(Flowable t) { - return t.toList(); + return t.toList().toFlowable(); } }) .concatMap(new Function>, Publisher>>() { diff --git a/src/test/java/io/reactivex/internal/operators/flowable/FlowableZipTest.java b/src/test/java/io/reactivex/internal/operators/flowable/FlowableZipTest.java index b4c7a52a69..907558f34e 100644 --- a/src/test/java/io/reactivex/internal/operators/flowable/FlowableZipTest.java +++ b/src/test/java/io/reactivex/internal/operators/flowable/FlowableZipTest.java @@ -1220,7 +1220,7 @@ public Integer apply(Integer i1, Integer i2) { for (int i = 0; i < 1026; i++) { expected.add(i * 3); } - assertEquals(expected, zip2.toList().blockingSingle()); + assertEquals(expected, zip2.toList().blockingGet()); } @Test public void testUnboundedDownstreamOverrequesting() { diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableBufferUntilSubscriberTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableBufferUntilSubscriberTest.java index d11bf3bf87..47968811db 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableBufferUntilSubscriberTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableBufferUntilSubscriberTest.java @@ -61,7 +61,7 @@ public Object apply(Integer integer) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List integers) { counter.incrementAndGet(); diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableCollectTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableCollectTest.java index 6f9368357e..658b271488 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableCollectTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableCollectTest.java @@ -23,13 +23,14 @@ import org.junit.Test; import io.reactivex.Observable; +import io.reactivex.Single; import io.reactivex.functions.BiConsumer; import io.reactivex.plugins.RxJavaPlugins; public final class ObservableCollectTest { @Test - public void testCollectToList() { + public void testCollectToListObservable() { Observable> o = Observable.just(1, 2, 3) .collect(new Callable>() { @Override @@ -41,7 +42,7 @@ public List call() { public void accept(List list, Integer v) { list.add(v); } - }); + }).toObservable(); List list = o.blockingLast(); @@ -59,6 +60,130 @@ public void accept(List list, Integer v) { assertEquals(3, list2.get(2).intValue()); } + @Test + public void testCollectToStringObservable() { + String value = Observable.just(1, 2, 3).collect(new Callable() { + @Override + public StringBuilder call() { + return new StringBuilder(); + } + }, + new BiConsumer() { + @Override + public void accept(StringBuilder sb, Integer v) { + if (sb.length() > 0) { + sb.append("-"); + } + sb.append(v); + } + }).toObservable().blockingLast().toString(); + + assertEquals("1-2-3", value); + } + + @Test + public void testCollectorFailureDoesNotResultInTwoErrorEmissionsObservable() { + try { + final List list = new CopyOnWriteArrayList(); + RxJavaPlugins.setErrorHandler(addToList(list)); + final RuntimeException e1 = new RuntimeException(); + final RuntimeException e2 = new RuntimeException(); + + Burst.items(1).error(e2) // + .collect(callableListCreator(), biConsumerThrows(e1)) // + .toObservable() + .test() // + .assertError(e1) // + .assertNotComplete(); + assertEquals(Arrays.asList(e2), list); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void testCollectorFailureDoesNotResultInErrorAndCompletedEmissionsObservable() { + final RuntimeException e = new RuntimeException(); + Burst.item(1).create() // + .collect(callableListCreator(), biConsumerThrows(e)) // + .toObservable() + .test() // + .assertError(e) // + .assertNotComplete(); + } + + @Test + public void testCollectorFailureDoesNotResultInErrorAndOnNextEmissionsObservable() { + final RuntimeException e = new RuntimeException(); + final AtomicBoolean added = new AtomicBoolean(); + BiConsumer throwOnFirstOnly = new BiConsumer() { + + boolean once = true; + + @Override + public void accept(Object o, Integer t) { + if (once) { + once = false; + throw e; + } else { + added.set(true); + } + } + }; + Burst.items(1, 2).create() // + .collect(callableListCreator(), throwOnFirstOnly)// + .test() // + .assertError(e) // + .assertNoValues() // + .assertNotComplete(); + assertFalse(added.get()); + } + + @SuppressWarnings("unchecked") + @Test + public void collectIntoObservable() { + Observable.just(1, 1, 1, 1, 2) + .collectInto(new HashSet(), new BiConsumer, Integer>() { + @Override + public void accept(HashSet s, Integer v) throws Exception { + s.add(v); + } + }).toObservable() + .test() + .assertResult(new HashSet(Arrays.asList(1, 2))); + } + + @Test + public void testCollectToList() { + Single> o = Observable.just(1, 2, 3) + .collect(new Callable>() { + @Override + public List call() { + return new ArrayList(); + } + }, new BiConsumer, Integer>() { + @Override + public void accept(List list, Integer v) { + list.add(v); + } + }); + + List list = o.blockingGet(); + + assertEquals(3, list.size()); + assertEquals(1, list.get(0).intValue()); + assertEquals(2, list.get(1).intValue()); + assertEquals(3, list.get(2).intValue()); + + // test multiple subscribe + List list2 = o.blockingGet(); + + assertEquals(3, list2.size()); + assertEquals(1, list2.get(0).intValue()); + assertEquals(2, list2.get(1).intValue()); + assertEquals(3, list2.get(2).intValue()); + } + @Test public void testCollectToString() { String value = Observable.just(1, 2, 3).collect(new Callable() { @@ -75,7 +200,7 @@ public void accept(StringBuilder sb, Integer v) { } sb.append(v); } - }).blockingLast().toString(); + }).blockingGet().toString(); assertEquals("1-2-3", value); } diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableConcatTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableConcatTest.java index ef0649c4f1..2b704de0d6 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableConcatTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableConcatTest.java @@ -610,9 +610,9 @@ public Observable apply(Integer v) { } }); - Observable> result = Observable.concat(source).toList(); + Single> result = Observable.concat(source).toList(); - Observer> o = TestHelper.mockObserver(); + SingleObserver> o = TestHelper.mockSingleObserver(); InOrder inOrder = inOrder(o); result.subscribe(o); @@ -621,8 +621,7 @@ public Observable apply(Integer v) { for (int i = 0; i < n; i++) { list.add(i); } - inOrder.verify(o).onNext(list); - inOrder.verify(o).onComplete(); + inOrder.verify(o).onSuccess(list); verify(o, never()).onError(any(Throwable.class)); } @Test @@ -635,9 +634,9 @@ public Observable apply(Integer v) { } }); - Observable> result = Observable.concat(source).take(n / 2).toList(); + Single> result = Observable.concat(source).take(n / 2).toList(); - Observer> o = TestHelper.mockObserver(); + SingleObserver> o = TestHelper.mockSingleObserver(); InOrder inOrder = inOrder(o); result.subscribe(o); @@ -646,8 +645,7 @@ public Observable apply(Integer v) { for (int i = 0; i < n / 2; i++) { list.add(i); } - inOrder.verify(o).onNext(list); - inOrder.verify(o).onComplete(); + inOrder.verify(o).onSuccess(list); verify(o, never()).onError(any(Throwable.class)); } diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableDoOnEachTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableDoOnEachTest.java index c583b891ee..6bef8e0d4f 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableDoOnEachTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableDoOnEachTest.java @@ -123,7 +123,7 @@ public boolean test(Boolean value) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); @@ -149,7 +149,7 @@ public boolean test(Boolean value) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableRepeatTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableRepeatTest.java index d7344d3a32..0db14692d6 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableRepeatTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableRepeatTest.java @@ -54,7 +54,7 @@ public void subscribe(final Observer o) { @Test(timeout = 2000) public void testRepeatTake() { Observable xs = Observable.just(1, 2); - Object[] ys = xs.repeat().subscribeOn(Schedulers.newThread()).take(4).toList().blockingLast().toArray(); + Object[] ys = xs.repeat().subscribeOn(Schedulers.newThread()).take(4).toList().blockingGet().toArray(); assertArrayEquals(new Object[] { 1, 2, 1, 2 }, ys); } @@ -91,7 +91,7 @@ public Integer apply(Integer t1) { return t1; } - }).take(4).toList().blockingLast().toArray(); + }).take(4).toList().blockingGet().toArray(); assertEquals(2, counter.get()); assertArrayEquals(new Object[] { 1, 2, 1, 2 }, ys); diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableScanTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableScanTest.java index b7661a95e8..515a4c7a25 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableScanTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableScanTest.java @@ -187,7 +187,7 @@ public void accept(List list, Integer t2) { list.add(t2); } - }).takeLast(1); + }).toObservable().takeLast(1); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingSingle()); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.blockingSingle()); diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableTakeLastTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableTakeLastTest.java index 06135d109a..c964771625 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableTakeLastTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableTakeLastTest.java @@ -152,7 +152,7 @@ public boolean test(Long v) { } }) .toList() - .blockingSingle().size()); + .blockingGet().size()); } @Test diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableToListTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableToListTest.java index 3ec09841a2..fcc15b8546 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableToListTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableToListTest.java @@ -22,16 +22,16 @@ import org.junit.*; import org.mockito.Mockito; +import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; public class ObservableToListTest { @Test - public void testList() { + public void testListObservable() { Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); - Observable> observable = w.toList(); + Observable> observable = w.toList().toObservable(); Observer> observer = TestHelper.mockObserver(); observable.subscribe(observer); @@ -41,9 +41,9 @@ public void testList() { } @Test - public void testListViaObservable() { + public void testListViaObservableObservable() { Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); - Observable> observable = w.toList(); + Observable> observable = w.toList().toObservable(); Observer> observer = TestHelper.mockObserver(); observable.subscribe(observer); @@ -53,9 +53,9 @@ public void testListViaObservable() { } @Test - public void testListMultipleSubscribers() { + public void testListMultipleSubscribersObservable() { Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); - Observable> observable = w.toList(); + Observable> observable = w.toList().toObservable(); Observer> o1 = TestHelper.mockObserver(); observable.subscribe(o1); @@ -76,9 +76,9 @@ public void testListMultipleSubscribers() { @Test @Ignore("Null values are not allowed") - public void testListWithNullValue() { + public void testListWithNullValueObservable() { Observable w = Observable.fromIterable(Arrays.asList("one", null, "three")); - Observable> observable = w.toList(); + Observable> observable = w.toList().toObservable(); Observer> observer = TestHelper.mockObserver(); observable.subscribe(observer); @@ -87,10 +87,81 @@ public void testListWithNullValue() { verify(observer, times(1)).onComplete(); } + @Test + public void testListWithBlockingFirstObservable() { + Observable o = Observable.fromIterable(Arrays.asList("one", "two", "three")); + List actual = o.toList().toObservable().blockingFirst(); + Assert.assertEquals(Arrays.asList("one", "two", "three"), actual); + } + + @SuppressWarnings("unchecked") + @Test + public void capacityHintObservable() { + Observable.range(1, 10) + .toList(4) + .toObservable() + .test() + .assertResult(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + } + + @Test + public void testList() { + Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", "two", "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testListViaObservable() { + Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", "two", "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testListMultipleSubscribers() { + Observable w = Observable.fromIterable(Arrays.asList("one", "two", "three")); + Single> observable = w.toList(); + + SingleObserver> o1 = TestHelper.mockSingleObserver(); + observable.subscribe(o1); + + SingleObserver> o2 = TestHelper.mockSingleObserver(); + observable.subscribe(o2); + + List expected = Arrays.asList("one", "two", "three"); + + verify(o1, times(1)).onSuccess(expected); + verify(o1, Mockito.never()).onError(any(Throwable.class)); + + verify(o2, times(1)).onSuccess(expected); + verify(o2, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + @Ignore("Null values are not allowed") + public void testListWithNullValue() { + Observable w = Observable.fromIterable(Arrays.asList("one", null, "three")); + Single> observable = w.toList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList("one", null, "three")); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + @Test public void testListWithBlockingFirst() { Observable o = Observable.fromIterable(Arrays.asList("one", "two", "three")); - List actual = o.toList().blockingFirst(); + List actual = o.toList().blockingGet(); Assert.assertEquals(Arrays.asList("one", "two", "three"), actual); } diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableToMapTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableToMapTest.java index 21b9794ae1..8ef8efde65 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableToMapTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableToMapTest.java @@ -21,17 +21,19 @@ import org.junit.*; +import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; import io.reactivex.functions.Function; public class ObservableToMapTest { Observer objectObserver; + SingleObserver singleObserver; @Before public void before() { objectObserver = TestHelper.mockObserver(); + singleObserver = TestHelper.mockSingleObserver(); } Function lengthFunc = new Function() { @@ -48,10 +50,10 @@ public String apply(String t1) { }; @Test - public void testToMap() { + public void testToMapObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); - Observable> mapped = source.toMap(lengthFunc); + Observable> mapped = source.toMap(lengthFunc).toObservable(); Map expected = new HashMap(); expected.put(1, "a"); @@ -67,10 +69,10 @@ public void testToMap() { } @Test - public void testToMapWithValueSelector() { + public void testToMapWithValueSelectorObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); - Observable> mapped = source.toMap(lengthFunc, duplicate); + Observable> mapped = source.toMap(lengthFunc, duplicate).toObservable(); Map expected = new HashMap(); expected.put(1, "aa"); @@ -86,7 +88,7 @@ public void testToMapWithValueSelector() { } @Test - public void testToMapWithError() { + public void testToMapWithErrorObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); Function lengthFuncErr = new Function() { @@ -98,7 +100,7 @@ public Integer apply(String t1) { return t1.length(); } }; - Observable> mapped = source.toMap(lengthFuncErr); + Observable> mapped = source.toMap(lengthFuncErr).toObservable(); Map expected = new HashMap(); expected.put(1, "a"); @@ -115,7 +117,7 @@ public Integer apply(String t1) { } @Test - public void testToMapWithErrorInValueSelector() { + public void testToMapWithErrorInValueSelectorObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); Function duplicateErr = new Function() { @@ -128,7 +130,7 @@ public String apply(String t1) { } }; - Observable> mapped = source.toMap(lengthFunc, duplicateErr); + Observable> mapped = source.toMap(lengthFunc, duplicateErr).toObservable(); Map expected = new HashMap(); expected.put(1, "aa"); @@ -145,7 +147,7 @@ public String apply(String t1) { } @Test - public void testToMapWithFactory() { + public void testToMapWithFactoryObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); Callable> mapFactory = new Callable>() { @@ -174,7 +176,7 @@ public Integer apply(String t1) { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toObservable(); Map expected = new LinkedHashMap(); expected.put(2, "bb"); @@ -189,7 +191,7 @@ public String apply(String v) { } @Test - public void testToMapWithErrorThrowingFactory() { + public void testToMapWithErrorThrowingFactoryObservable() { Observable source = Observable.just("a", "bb", "ccc", "dddd"); Callable> mapFactory = new Callable>() { @@ -210,7 +212,7 @@ public Integer apply(String t1) { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toObservable(); Map expected = new LinkedHashMap(); expected.put(2, "bb"); @@ -224,4 +226,176 @@ public String apply(String v) { verify(objectObserver, times(1)).onError(any(Throwable.class)); } + + @Test + public void testToMap() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Single> mapped = source.toMap(lengthFunc); + + Map expected = new HashMap(); + expected.put(1, "a"); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithValueSelector() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Single> mapped = source.toMap(lengthFunc, duplicate); + + Map expected = new HashMap(); + expected.put(1, "aa"); + expected.put(2, "bbbb"); + expected.put(3, "cccccc"); + expected.put(4, "dddddddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithError() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Function lengthFuncErr = new Function() { + @Override + public Integer apply(String t1) { + if ("bb".equals(t1)) { + throw new RuntimeException("Forced Failure"); + } + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFuncErr); + + Map expected = new HashMap(); + expected.put(1, "a"); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + + } + + @Test + public void testToMapWithErrorInValueSelector() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Function duplicateErr = new Function() { + @Override + public String apply(String t1) { + if ("bb".equals(t1)) { + throw new RuntimeException("Forced failure"); + } + return t1 + t1; + } + }; + + Single> mapped = source.toMap(lengthFunc, duplicateErr); + + Map expected = new HashMap(); + expected.put(1, "aa"); + expected.put(2, "bbbb"); + expected.put(3, "cccccc"); + expected.put(4, "dddddddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + + } + + @Test + public void testToMapWithFactory() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Callable> mapFactory = new Callable>() { + @Override + public Map call() { + return new LinkedHashMap() { + + private static final long serialVersionUID = -3296811238780863394L; + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > 3; + } + }; + } + }; + + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map expected = new LinkedHashMap(); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMapWithErrorThrowingFactory() { + Observable source = Observable.just("a", "bb", "ccc", "dddd"); + + Callable> mapFactory = new Callable>() { + @Override + public Map call() { + throw new RuntimeException("Forced failure"); + } + }; + + Function lengthFunc = new Function() { + @Override + public Integer apply(String t1) { + return t1.length(); + } + }; + Single> mapped = source.toMap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map expected = new LinkedHashMap(); + expected.put(2, "bb"); + expected.put(3, "ccc"); + expected.put(4, "dddd"); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onSuccess(expected); + verify(singleObserver, times(1)).onError(any(Throwable.class)); + } + } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableToMultimapTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableToMultimapTest.java index 0ed0a61744..daa1f00239 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableToMultimapTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableToMultimapTest.java @@ -21,17 +21,19 @@ import org.junit.*; +import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; import io.reactivex.functions.Function; public class ObservableToMultimapTest { Observer objectObserver; + SingleObserver singleObserver; @Before public void before() { objectObserver = TestHelper.mockObserver(); + singleObserver = TestHelper.mockSingleObserver(); } Function lengthFunc = new Function() { @@ -48,10 +50,10 @@ public String apply(String t1) { }; @Test - public void testToMultimap() { + public void testToMultimapObservable() { Observable source = Observable.just("a", "b", "cc", "dd"); - Observable>> mapped = source.toMultimap(lengthFunc); + Observable>> mapped = source.toMultimap(lengthFunc).toObservable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); @@ -65,10 +67,10 @@ public void testToMultimap() { } @Test - public void testToMultimapWithValueSelector() { + public void testToMultimapWithValueSelectorObservable() { Observable source = Observable.just("a", "b", "cc", "dd"); - Observable>> mapped = source.toMultimap(lengthFunc, duplicate); + Observable>> mapped = source.toMultimap(lengthFunc, duplicate).toObservable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); @@ -82,7 +84,7 @@ public void testToMultimapWithValueSelector() { } @Test - public void testToMultimapWithMapFactory() { + public void testToMultimapWithMapFactoryObservable() { Observable source = Observable.just("a", "b", "cc", "dd", "eee", "fff"); Callable>> mapFactory = new Callable>>() { @@ -114,7 +116,7 @@ public String apply(String v) { public Collection apply(Integer v) { return new ArrayList(); } - }); + }).toObservable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -128,7 +130,7 @@ public Collection apply(Integer v) { } @Test - public void testToMultimapWithCollectionFactory() { + public void testToMultimapWithCollectionFactoryObservable() { Observable source = Observable.just("cc", "dd", "eee", "eee"); Function> collectionFactory = new Function>() { @@ -156,7 +158,7 @@ public Map> call() { }; Observable>> mapped = source - .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); + .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory).toObservable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -170,7 +172,7 @@ public Map> call() { } @Test - public void testToMultimapWithError() { + public void testToMultimapWithErrorObservable() { Observable source = Observable.just("a", "b", "cc", "dd"); Function lengthFuncErr = new Function() { @@ -183,7 +185,7 @@ public Integer apply(String t1) { } }; - Observable>> mapped = source.toMultimap(lengthFuncErr); + Observable>> mapped = source.toMultimap(lengthFuncErr).toObservable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("a", "b")); @@ -197,7 +199,7 @@ public Integer apply(String t1) { } @Test - public void testToMultimapWithErrorInValueSelector() { + public void testToMultimapWithErrorInValueSelectorObservable() { Observable source = Observable.just("a", "b", "cc", "dd"); Function duplicateErr = new Function() { @@ -210,7 +212,7 @@ public String apply(String t1) { } }; - Observable>> mapped = source.toMultimap(lengthFunc, duplicateErr); + Observable>> mapped = source.toMultimap(lengthFunc, duplicateErr).toObservable(); Map> expected = new HashMap>(); expected.put(1, Arrays.asList("aa", "bb")); @@ -224,7 +226,7 @@ public String apply(String t1) { } @Test - public void testToMultimapWithMapThrowingFactory() { + public void testToMultimapWithMapThrowingFactoryObservable() { Observable source = Observable.just("a", "b", "cc", "dd", "eee", "fff"); Callable>> mapFactory = new Callable>>() { @@ -240,7 +242,7 @@ public Map> call() { public String apply(String v) { return v; } - }, mapFactory); + }, mapFactory).toObservable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -254,7 +256,7 @@ public String apply(String v) { } @Test - public void testToMultimapWithThrowingCollectionFactory() { + public void testToMultimapWithThrowingCollectionFactoryObservable() { Observable source = Observable.just("cc", "cc", "eee", "eee"); Function> collectionFactory = new Function>() { @@ -282,7 +284,7 @@ public Map> call() { }; Observable>> mapped = source.toMultimap(lengthFunc, - identity, mapSupplier, collectionFactory); + identity, mapSupplier, collectionFactory).toObservable(); Map> expected = new HashMap>(); expected.put(2, Arrays.asList("cc", "dd")); @@ -294,4 +296,246 @@ public Map> call() { verify(objectObserver, never()).onNext(expected); verify(objectObserver, never()).onComplete(); } + + + + @Test + public void testToMultimap() { + Observable source = Observable.just("a", "b", "cc", "dd"); + + Single>> mapped = source.toMultimap(lengthFunc); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("a", "b")); + expected.put(2, Arrays.asList("cc", "dd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithValueSelector() { + Observable source = Observable.just("a", "b", "cc", "dd"); + + Single>> mapped = source.toMultimap(lengthFunc, duplicate); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("aa", "bb")); + expected.put(2, Arrays.asList("cccc", "dddd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithMapFactory() { + Observable source = Observable.just("a", "b", "cc", "dd", "eee", "fff"); + + Callable>> mapFactory = new Callable>>() { + @Override + public Map> call() { + return new LinkedHashMap>() { + + private static final long serialVersionUID = -2084477070717362859L; + + @Override + protected boolean removeEldestEntry(Map.Entry> eldest) { + return size() > 2; + } + }; + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + + Single>> mapped = source.toMultimap( + lengthFunc, identity, + mapFactory, new Function>() { + @Override + public Collection apply(Integer v) { + return new ArrayList(); + } + }); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Arrays.asList("eee", "fff")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithCollectionFactory() { + Observable source = Observable.just("cc", "dd", "eee", "eee"); + + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + return new ArrayList(); + } else { + return new HashSet(); + } + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Callable>> mapSupplier = new Callable>>() { + @Override + public Map> call() { + return new HashMap>(); + } + }; + + Single>> mapped = source + .toMultimap(lengthFunc, identity, mapSupplier, collectionFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, new HashSet(Arrays.asList("eee"))); + + mapped.subscribe(singleObserver); + + verify(singleObserver, never()).onError(any(Throwable.class)); + verify(singleObserver, times(1)).onSuccess(expected); + } + + @Test + public void testToMultimapWithError() { + Observable source = Observable.just("a", "b", "cc", "dd"); + + Function lengthFuncErr = new Function() { + @Override + public Integer apply(String t1) { + if ("b".equals(t1)) { + throw new RuntimeException("Forced Failure"); + } + return t1.length(); + } + }; + + Single>> mapped = source.toMultimap(lengthFuncErr); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("a", "b")); + expected.put(2, Arrays.asList("cc", "dd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithErrorInValueSelector() { + Observable source = Observable.just("a", "b", "cc", "dd"); + + Function duplicateErr = new Function() { + @Override + public String apply(String t1) { + if ("b".equals(t1)) { + throw new RuntimeException("Forced failure"); + } + return t1 + t1; + } + }; + + Single>> mapped = source.toMultimap(lengthFunc, duplicateErr); + + Map> expected = new HashMap>(); + expected.put(1, Arrays.asList("aa", "bb")); + expected.put(2, Arrays.asList("cccc", "dddd")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithMapThrowingFactory() { + Observable source = Observable.just("a", "b", "cc", "dd", "eee", "fff"); + + Callable>> mapFactory = new Callable>>() { + @Override + public Map> call() { + throw new RuntimeException("Forced failure"); + } + }; + + Single>> mapped = source + .toMultimap(lengthFunc, new Function() { + @Override + public String apply(String v) { + return v; + } + }, mapFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Arrays.asList("eee", "fff")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } + + @Test + public void testToMultimapWithThrowingCollectionFactory() { + Observable source = Observable.just("cc", "cc", "eee", "eee"); + + Function> collectionFactory = new Function>() { + @Override + public Collection apply(Integer t1) { + if (t1 == 2) { + throw new RuntimeException("Forced failure"); + } else { + return new HashSet(); + } + } + }; + + Function identity = new Function() { + @Override + public String apply(String v) { + return v; + } + }; + Callable>> mapSupplier = new Callable>>() { + @Override + public Map> call() { + return new HashMap>(); + } + }; + + Single>> mapped = source.toMultimap(lengthFunc, + identity, mapSupplier, collectionFactory); + + Map> expected = new HashMap>(); + expected.put(2, Arrays.asList("cc", "dd")); + expected.put(3, Collections.singleton("eee")); + + mapped.subscribe(singleObserver); + + verify(singleObserver, times(1)).onError(any(Throwable.class)); + verify(singleObserver, never()).onSuccess(expected); + } } \ No newline at end of file diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableToSortedListTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableToSortedListTest.java index d82ae47aeb..98da0de4e7 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableToSortedListTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableToSortedListTest.java @@ -23,16 +23,16 @@ import org.junit.Test; import org.mockito.Mockito; +import io.reactivex.*; import io.reactivex.Observable; import io.reactivex.Observer; -import io.reactivex.TestHelper; public class ObservableToSortedListTest { @Test - public void testSortedList() { + public void testSortedListObservable() { Observable w = Observable.just(1, 3, 2, 5, 4); - Observable> observable = w.toSortedList(); + Observable> observable = w.toSortedList().toObservable(); Observer> observer = TestHelper.mockObserver(); observable.subscribe(observer); @@ -42,7 +42,7 @@ public void testSortedList() { } @Test - public void testSortedListWithCustomFunction() { + public void testSortedListWithCustomFunctionFlowable() { Observable w = Observable.just(1, 3, 2, 5, 4); Observable> observable = w.toSortedList(new Comparator() { @@ -51,7 +51,7 @@ public int compare(Integer t1, Integer t2) { return t2 - t1; } - }); + }).toObservable(); Observer> observer = TestHelper.mockObserver(); observable.subscribe(observer); @@ -61,9 +61,9 @@ public int compare(Integer t1, Integer t2) { } @Test - public void testWithFollowingFirst() { + public void testWithFollowingFirstObservable() { Observable o = Observable.just(1, 3, 2, 5, 4); - assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().blockingFirst()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().toObservable().blockingFirst()); } static void await(CyclicBarrier cb) { @@ -95,6 +95,63 @@ public int compare(Integer a, Integer b) { .assertResult(5, 4, 3, 2, 1); } + @SuppressWarnings("unchecked") + @Test + public void toSortedListCapacityObservable() { + Observable.just(5, 1, 2, 4, 3).toSortedList(4).toObservable() + .test() + .assertResult(Arrays.asList(1, 2, 3, 4, 5)); + } + + @SuppressWarnings("unchecked") + @Test + public void toSortedListComparatorCapacityObservable() { + Observable.just(5, 1, 2, 4, 3).toSortedList(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b - a; + } + }, 4).toObservable() + .test() + .assertResult(Arrays.asList(5, 4, 3, 2, 1)); + } + + + @Test + public void testSortedList() { + Observable w = Observable.just(1, 3, 2, 5, 4); + Single> observable = w.toSortedList(); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList(1, 2, 3, 4, 5)); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testSortedListWithCustomFunction() { + Observable w = Observable.just(1, 3, 2, 5, 4); + Single> observable = w.toSortedList(new Comparator() { + + @Override + public int compare(Integer t1, Integer t2) { + return t2 - t1; + } + + }); + + SingleObserver> observer = TestHelper.mockSingleObserver(); + observable.subscribe(observer); + verify(observer, times(1)).onSuccess(Arrays.asList(5, 4, 3, 2, 1)); + verify(observer, Mockito.never()).onError(any(Throwable.class)); + } + + @Test + public void testWithFollowingFirst() { + Observable o = Observable.just(1, 3, 2, 5, 4); + assertEquals(Arrays.asList(1, 2, 3, 4, 5), o.toSortedList().blockingGet()); + } + @SuppressWarnings("unchecked") @Test public void toSortedListCapacity() { diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableWindowWithSizeTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableWindowWithSizeTest.java index 1593b39039..c5d205e36e 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableWindowWithSizeTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableWindowWithSizeTest.java @@ -37,7 +37,7 @@ private static List> toLists(Observable> observables) Observable.concat(observables.map(new Function, Observable>>() { @Override public Observable> apply(Observable xs) { - return xs.toList(); + return xs.toList().toObservable(); } })) .blockingForEach(new Consumer>() { diff --git a/src/test/java/io/reactivex/internal/operators/observable/ObservableZipTest.java b/src/test/java/io/reactivex/internal/operators/observable/ObservableZipTest.java index 1d7597c65e..2c7f4230bd 100644 --- a/src/test/java/io/reactivex/internal/operators/observable/ObservableZipTest.java +++ b/src/test/java/io/reactivex/internal/operators/observable/ObservableZipTest.java @@ -1122,7 +1122,7 @@ public Integer apply(Integer i1, Integer i2) { for (int i = 0; i < 1026; i++) { expected.add(i * 3); } - assertEquals(expected, zip2.toList().blockingSingle()); + assertEquals(expected, zip2.toList().blockingGet()); } @Test(timeout = 10000) diff --git a/src/test/java/io/reactivex/observable/ObservableConcatTests.java b/src/test/java/io/reactivex/observable/ObservableConcatTests.java index 0d64252288..279b043b3a 100644 --- a/src/test/java/io/reactivex/observable/ObservableConcatTests.java +++ b/src/test/java/io/reactivex/observable/ObservableConcatTests.java @@ -30,7 +30,7 @@ public void testConcatSimple() { Observable o1 = Observable.just("one", "two"); Observable o2 = Observable.just("three", "four"); - List values = Observable.concat(o1, o2).toList().blockingSingle(); + List values = Observable.concat(o1, o2).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -46,7 +46,7 @@ public void testConcatWithObservableOfObservable() { Observable> os = Observable.just(o1, o2, o3); - List values = Observable.concat(os).toList().blockingSingle(); + List values = Observable.concat(os).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -65,7 +65,7 @@ public void testConcatWithIterableOfObservable() { @SuppressWarnings("unchecked") Iterable> is = Arrays.asList(o1, o2, o3); - List values = Observable.concat(Observable.fromIterable(is)).toList().blockingSingle(); + List values = Observable.concat(Observable.fromIterable(is)).toList().blockingGet(); assertEquals("one", values.get(0)); assertEquals("two", values.get(1)); @@ -87,7 +87,7 @@ public void testConcatCovariance() { Observable> os = Observable.just(o1, o2); - List values = Observable.concat(os).toList().blockingSingle(); + List values = Observable.concat(os).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -109,7 +109,7 @@ public void testConcatCovariance2() { Observable> os = Observable.just(o1, o2); - List values = Observable.concat(os).toList().blockingSingle(); + List values = Observable.concat(os).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -129,7 +129,7 @@ public void testConcatCovariance3() { Observable o1 = Observable.just(horrorMovie1, movie); Observable o2 = Observable.just(media, horrorMovie2); - List values = Observable.concat(o1, o2).toList().blockingSingle(); + List values = Observable.concat(o1, o2).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); @@ -157,7 +157,7 @@ public void subscribe(Observer o) { Observable o2 = Observable.just(media, horrorMovie2); - List values = Observable.concat(o1, o2).toList().blockingSingle(); + List values = Observable.concat(o1, o2).toList().blockingGet(); assertEquals(horrorMovie1, values.get(0)); assertEquals(movie, values.get(1)); diff --git a/src/test/java/io/reactivex/observable/ObservableMergeTests.java b/src/test/java/io/reactivex/observable/ObservableMergeTests.java index 5d21027f4b..206c1e6584 100644 --- a/src/test/java/io/reactivex/observable/ObservableMergeTests.java +++ b/src/test/java/io/reactivex/observable/ObservableMergeTests.java @@ -42,7 +42,7 @@ public void testMergeCovariance() { Observable> os = Observable.just(o1, o2); - List values = Observable.merge(os).toList().blockingSingle(); + List values = Observable.merge(os).toList().blockingGet(); assertEquals(4, values.size()); } @@ -54,7 +54,7 @@ public void testMergeCovariance2() { Observable> os = Observable.just(o1, o2); - List values = Observable.merge(os).toList().blockingSingle(); + List values = Observable.merge(os).toList().blockingGet(); assertEquals(5, values.size()); } @@ -64,7 +64,7 @@ public void testMergeCovariance3() { Observable o1 = Observable.just(new HorrorMovie(), new Movie()); Observable o2 = Observable.just(new Media(), new HorrorMovie()); - List values = Observable.merge(o1, o2).toList().blockingSingle(); + List values = Observable.merge(o1, o2).toList().blockingGet(); assertTrue(values.get(0) instanceof HorrorMovie); assertTrue(values.get(1) instanceof Movie); @@ -87,7 +87,7 @@ public Observable call() { Observable o2 = Observable.just(new Media(), new HorrorMovie()); - List values = Observable.merge(o1, o2).toList().blockingSingle(); + List values = Observable.merge(o1, o2).toList().blockingGet(); assertTrue(values.get(0) instanceof HorrorMovie); assertTrue(values.get(1) instanceof Movie); diff --git a/src/test/java/io/reactivex/observable/ObservableNullTests.java b/src/test/java/io/reactivex/observable/ObservableNullTests.java index c822701dd2..0ba338a1b2 100644 --- a/src/test/java/io/reactivex/observable/ObservableNullTests.java +++ b/src/test/java/io/reactivex/observable/ObservableNullTests.java @@ -1008,7 +1008,7 @@ public Object call() { }, new BiConsumer() { @Override public void accept(Object a, Integer b) { } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2422,7 +2422,7 @@ public void toListSupplierReturnsNull() { public Collection call() { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2457,7 +2457,7 @@ public Object apply(Integer v) { public Object apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2492,7 +2492,7 @@ public Object apply(Integer v) { public Map call() { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2522,7 +2522,7 @@ public Object apply(Integer v) { public Object apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2557,7 +2557,7 @@ public Object apply(Integer v) { public Map> call() { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) @@ -2602,7 +2602,7 @@ public Map> call() { public Collection apply(Integer v) { return null; } - }).blockingSubscribe(); + }).blockingGet(); } @Test(expected = NullPointerException.class) diff --git a/src/test/java/io/reactivex/observable/ObservableStartWithTests.java b/src/test/java/io/reactivex/observable/ObservableStartWithTests.java index 2e5c4aa8eb..cad32b0d31 100644 --- a/src/test/java/io/reactivex/observable/ObservableStartWithTests.java +++ b/src/test/java/io/reactivex/observable/ObservableStartWithTests.java @@ -26,7 +26,7 @@ public class ObservableStartWithTests { @Test public void startWith1() { List values = Observable.just("one", "two") - .startWithArray("zero").toList().blockingSingle(); + .startWithArray("zero").toList().blockingGet(); assertEquals("zero", values.get(0)); assertEquals("two", values.get(2)); @@ -37,7 +37,7 @@ public void startWithIterable() { List li = new ArrayList(); li.add("alpha"); li.add("beta"); - List values = Observable.just("one", "two").startWith(li).toList().blockingSingle(); + List values = Observable.just("one", "two").startWith(li).toList().blockingGet(); assertEquals("alpha", values.get(0)); assertEquals("beta", values.get(1)); @@ -53,7 +53,7 @@ public void startWithObservable() { List values = Observable.just("one", "two") .startWith(Observable.fromIterable(li)) .toList() - .blockingSingle(); + .blockingGet(); assertEquals("alpha", values.get(0)); assertEquals("beta", values.get(1)); diff --git a/src/test/java/io/reactivex/observable/ObservableTest.java b/src/test/java/io/reactivex/observable/ObservableTest.java index ac9135f945..830fd3b454 100644 --- a/src/test/java/io/reactivex/observable/ObservableTest.java +++ b/src/test/java/io/reactivex/observable/ObservableTest.java @@ -989,7 +989,7 @@ public boolean test(Boolean v) { } }) .toList() - .doOnNext(new Consumer>() { + .doOnSuccess(new Consumer>() { @Override public void accept(List booleans) { count.incrementAndGet(); @@ -1102,7 +1102,7 @@ public void testFlatMap() { public Observable apply(Integer v) { return Observable.range(v, 2); } - }).toList().blockingFirst(); + }).toList().blockingGet(); Assert.assertEquals(Arrays.asList(1, 2, 2, 3, 3, 4, 4, 5, 5, 6), list); } diff --git a/src/test/java/io/reactivex/observable/ObservableWindowTests.java b/src/test/java/io/reactivex/observable/ObservableWindowTests.java index 72058dcea4..fb8501904d 100644 --- a/src/test/java/io/reactivex/observable/ObservableWindowTests.java +++ b/src/test/java/io/reactivex/observable/ObservableWindowTests.java @@ -34,7 +34,7 @@ public void testWindow() { .map(new Function, Observable>>() { @Override public Observable> apply(Observable xs) { - return xs.toList(); + return xs.toList().toObservable(); } }) ) diff --git a/src/test/java/io/reactivex/processors/ReplayProcessorBoundedConcurrencyTest.java b/src/test/java/io/reactivex/processors/ReplayProcessorBoundedConcurrencyTest.java index 428490d29c..92c6366ddd 100644 --- a/src/test/java/io/reactivex/processors/ReplayProcessorBoundedConcurrencyTest.java +++ b/src/test/java/io/reactivex/processors/ReplayProcessorBoundedConcurrencyTest.java @@ -179,7 +179,7 @@ public void subscribe(Subscriber o) { @Override public void run() { - List values = replay.toList().blockingLast(); + List values = replay.toList().blockingGet(); listOfListsOfValues.add(values); System.out.println("Finished thread: " + count); } diff --git a/src/test/java/io/reactivex/processors/ReplayProcessorConcurrencyTest.java b/src/test/java/io/reactivex/processors/ReplayProcessorConcurrencyTest.java index 96089c45f5..fa52b3ddd8 100644 --- a/src/test/java/io/reactivex/processors/ReplayProcessorConcurrencyTest.java +++ b/src/test/java/io/reactivex/processors/ReplayProcessorConcurrencyTest.java @@ -179,7 +179,7 @@ public void subscribe(Subscriber o) { @Override public void run() { - List values = replay.toList().blockingLast(); + List values = replay.toList().blockingGet(); listOfListsOfValues.add(values); System.out.println("Finished thread: " + count); } diff --git a/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java b/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java index 5854e6b5c1..887c3cb727 100644 --- a/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java +++ b/src/test/java/io/reactivex/schedulers/AbstractSchedulerTests.java @@ -121,7 +121,7 @@ public String apply(String s) { }); - List strings = m.toList().blockingLast(); + List strings = m.toList().blockingGet(); assertEquals(4, strings.size()); // because flatMap does a merge there is no guarantee of order diff --git a/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java b/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java index cdab416d93..3af6c23971 100644 --- a/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/ReplaySubjectBoundedConcurrencyTest.java @@ -183,7 +183,7 @@ public void subscribe(Observer o) { @Override public void run() { - List values = replay.toList().blockingLast(); + List values = replay.toList().blockingGet(); listOfListsOfValues.add(values); System.out.println("Finished thread: " + count); } diff --git a/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java b/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java index 070cc3e369..835a6167db 100644 --- a/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java +++ b/src/test/java/io/reactivex/subjects/ReplaySubjectConcurrencyTest.java @@ -183,7 +183,7 @@ public void subscribe(Observer o) { @Override public void run() { - List values = replay.toList().blockingLast(); + List values = replay.toList().blockingGet(); listOfListsOfValues.add(values); System.out.println("Finished thread: " + count); } diff --git a/src/test/java/io/reactivex/tck/CollectTckTest.java b/src/test/java/io/reactivex/tck/CollectTckTest.java index dc5f8670d5..c88520d9b6 100644 --- a/src/test/java/io/reactivex/tck/CollectTckTest.java +++ b/src/test/java/io/reactivex/tck/CollectTckTest.java @@ -33,7 +33,7 @@ public Publisher> createPublisher(final long elements) { public void accept(List a, Integer b) throws Exception { a.add(b); } - }) + }).toFlowable() ); } diff --git a/src/test/java/io/reactivex/tck/ToListTckTest.java b/src/test/java/io/reactivex/tck/ToListTckTest.java index fbccd4a819..fcf8fc6498 100644 --- a/src/test/java/io/reactivex/tck/ToListTckTest.java +++ b/src/test/java/io/reactivex/tck/ToListTckTest.java @@ -26,7 +26,7 @@ public class ToListTckTest extends BaseTck> { @Override public Publisher> createPublisher(final long elements) { return FlowableTck.wrap( - Flowable.range(1, 1000).toList() + Flowable.range(1, 1000).toList().toFlowable() ); } diff --git a/src/test/java/io/reactivex/tck/ToMapTckTest.java b/src/test/java/io/reactivex/tck/ToMapTckTest.java index 17bfe427f7..d66c97a541 100644 --- a/src/test/java/io/reactivex/tck/ToMapTckTest.java +++ b/src/test/java/io/reactivex/tck/ToMapTckTest.java @@ -27,7 +27,7 @@ public class ToMapTckTest extends BaseTck> { @Override public Publisher> createPublisher(final long elements) { return FlowableTck.wrap( - Flowable.range(1, 1000).toMap(Functions.identity()) + Flowable.range(1, 1000).toMap(Functions.identity()).toFlowable() ); } diff --git a/src/test/java/io/reactivex/tck/ToMultimapTckTest.java b/src/test/java/io/reactivex/tck/ToMultimapTckTest.java index bb9ebac3c3..6f5c67b488 100644 --- a/src/test/java/io/reactivex/tck/ToMultimapTckTest.java +++ b/src/test/java/io/reactivex/tck/ToMultimapTckTest.java @@ -27,7 +27,7 @@ public class ToMultimapTckTest extends BaseTck> @Override public Publisher>> createPublisher(final long elements) { return FlowableTck.wrap( - Flowable.range(1, 1000).toMultimap(Functions.identity()) + Flowable.range(1, 1000).toMultimap(Functions.identity()).toFlowable() ); } diff --git a/src/test/java/io/reactivex/tck/ToSortedListTckTest.java b/src/test/java/io/reactivex/tck/ToSortedListTckTest.java index f1569a1759..96e7a28b66 100644 --- a/src/test/java/io/reactivex/tck/ToSortedListTckTest.java +++ b/src/test/java/io/reactivex/tck/ToSortedListTckTest.java @@ -26,7 +26,7 @@ public class ToSortedListTckTest extends BaseTck> { @Override public Publisher> createPublisher(final long elements) { return FlowableTck.wrap( - Flowable.range(1, 1000).toSortedList() + Flowable.range(1, 1000).toSortedList().toFlowable() ); }