19
19
20
20
import java .util .*;
21
21
import java .util .concurrent .Callable ;
22
+ import java .util .concurrent .CopyOnWriteArrayList ;
22
23
import java .util .concurrent .atomic .AtomicInteger ;
23
24
24
25
import org .junit .Test ;
25
26
26
27
import io .reactivex .*;
27
28
import io .reactivex .Observable ;
28
29
import io .reactivex .Observer ;
30
+ import io .reactivex .disposables .Disposable ;
31
+ import io .reactivex .disposables .Disposables ;
29
32
import io .reactivex .exceptions .TestException ;
30
33
import io .reactivex .functions .*;
31
34
import io .reactivex .observers .*;
35
+ import io .reactivex .plugins .RxJavaPlugins ;
32
36
import io .reactivex .subjects .PublishSubject ;
33
37
34
38
public class ObservableScanTest {
@@ -300,4 +304,85 @@ public Object apply(Object a, Object b) throws Exception {
300
304
}
301
305
}, false , 1 , 1 , 0 , 0 );
302
306
}
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
+ }
303
388
}
0 commit comments