1919
2020import java .util .*;
2121import java .util .concurrent .Callable ;
22+ import java .util .concurrent .CopyOnWriteArrayList ;
2223import java .util .concurrent .atomic .AtomicInteger ;
2324
2425import org .junit .Test ;
2526
2627import io .reactivex .*;
2728import io .reactivex .Observable ;
2829import io .reactivex .Observer ;
30+ import io .reactivex .disposables .Disposable ;
31+ import io .reactivex .disposables .Disposables ;
2932import io .reactivex .exceptions .TestException ;
3033import io .reactivex .functions .*;
3134import io .reactivex .observers .*;
35+ import io .reactivex .plugins .RxJavaPlugins ;
3236import io .reactivex .subjects .PublishSubject ;
3337
3438public class ObservableScanTest {
@@ -300,4 +304,85 @@ public Object apply(Object a, Object b) throws Exception {
300304 }
301305 }, false , 1 , 1 , 0 , 0 );
302306 }
307+
308+ @ Test
309+ public void testScanFunctionThrowsAndUpstreamErrorsDoesNotResultInTwoTerminalEvents () {
310+ final RuntimeException err = new RuntimeException ();
311+ final RuntimeException err2 = new RuntimeException ();
312+ final List <Throwable > list = new CopyOnWriteArrayList <Throwable >();
313+ final Consumer <Throwable > errorConsumer = new Consumer <Throwable >() {
314+ @ Override
315+ public void accept (Throwable t ) throws Exception {
316+ list .add (t );
317+ }};
318+ try {
319+ RxJavaPlugins .setErrorHandler (errorConsumer );
320+ Observable .unsafeCreate (new ObservableSource <Integer >() {
321+ @ Override
322+ public void subscribe (Observer <? super Integer > o ) {
323+ Disposable d = Disposables .empty ();
324+ o .onSubscribe (d );
325+ o .onNext (1 );
326+ o .onNext (2 );
327+ o .onError (err2 );
328+ }})
329+ .scan (new BiFunction <Integer ,Integer ,Integer >() {
330+ @ Override
331+ public Integer apply (Integer t1 , Integer t2 ) throws Exception {
332+ throw err ;
333+ }})
334+ .test ()
335+ .assertError (err )
336+ .assertValue (1 );
337+ } finally {
338+ RxJavaPlugins .reset ();
339+ }
340+ }
341+
342+ @ Test
343+ public void testScanFunctionThrowsAndUpstreamCompletesDoesNotResultInTwoTerminalEvents () {
344+ final RuntimeException err = new RuntimeException ();
345+ Observable .unsafeCreate (new ObservableSource <Integer >() {
346+ @ Override
347+ public void subscribe (Observer <? super Integer > o ) {
348+ Disposable d = Disposables .empty ();
349+ o .onSubscribe (d );
350+ o .onNext (1 );
351+ o .onNext (2 );
352+ o .onComplete ();
353+ }})
354+ .scan (new BiFunction <Integer ,Integer ,Integer >() {
355+ @ Override
356+ public Integer apply (Integer t1 , Integer t2 ) throws Exception {
357+ throw err ;
358+ }})
359+ .test ()
360+ .assertError (err )
361+ .assertValue (1 );
362+ }
363+
364+ @ Test
365+ public void testScanFunctionThrowsAndUpstreamEmitsOnNextResultsInScanFunctionBeingCalledOnlyOnce () {
366+ final RuntimeException err = new RuntimeException ();
367+ final AtomicInteger count = new AtomicInteger ();
368+ Observable .unsafeCreate (new ObservableSource <Integer >() {
369+ @ Override
370+ public void subscribe (Observer <? super Integer > o ) {
371+ Disposable d = Disposables .empty ();
372+ o .onSubscribe (d );
373+ o .onNext (1 );
374+ o .onNext (2 );
375+ o .onNext (3 );
376+ }})
377+ .scan (new BiFunction <Integer ,Integer ,Integer >() {
378+ @ Override
379+ public Integer apply (Integer t1 , Integer t2 ) throws Exception {
380+ count .incrementAndGet ();
381+ throw err ;
382+ }})
383+ .test ()
384+ .assertError (err )
385+ .assertValue (1 );
386+ assertEquals (1 , count .get ());
387+ }
303388}
0 commit comments