|
20 | 20 | import static org.mockito.Mockito.*;
|
21 | 21 |
|
22 | 22 | import java.util.ArrayList;
|
| 23 | +import java.util.Arrays; |
| 24 | +import java.util.Collections; |
23 | 25 | import java.util.List;
|
24 | 26 | import java.util.concurrent.CountDownLatch;
|
25 | 27 | import java.util.concurrent.TimeUnit;
|
|
32 | 34 | import org.mockito.MockitoAnnotations;
|
33 | 35 |
|
34 | 36 | import rx.Observable;
|
| 37 | +import rx.Observable.OnSubscribe; |
35 | 38 | import rx.Observer;
|
| 39 | +import rx.Scheduler; |
36 | 40 | import rx.Subscriber;
|
37 | 41 | import rx.Subscription;
|
38 | 42 | import rx.functions.Action0;
|
39 | 43 | import rx.functions.Action1;
|
| 44 | +import rx.observers.TestSubscriber; |
| 45 | +import rx.schedulers.Schedulers; |
| 46 | +import rx.schedulers.TestScheduler; |
40 | 47 | import rx.subscriptions.Subscriptions;
|
41 | 48 |
|
42 | 49 | public class OperatorMergeTest {
|
@@ -372,4 +379,97 @@ public Subscription onSubscribe(Observer<? super String> observer) {
|
372 | 379 | }
|
373 | 380 | }
|
374 | 381 |
|
| 382 | + @Test |
| 383 | + public void testUnsubscribeAsObservablesComplete() { |
| 384 | + TestScheduler scheduler1 = Schedulers.test(); |
| 385 | + AtomicBoolean os1 = new AtomicBoolean(false); |
| 386 | + Observable<Long> o1 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler1, os1); |
| 387 | + |
| 388 | + TestScheduler scheduler2 = Schedulers.test(); |
| 389 | + AtomicBoolean os2 = new AtomicBoolean(false); |
| 390 | + Observable<Long> o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); |
| 391 | + |
| 392 | + TestSubscriber<Long> ts = new TestSubscriber<Long>(); |
| 393 | + Observable.merge(o1, o2).subscribe(ts); |
| 394 | + |
| 395 | + // we haven't incremented time so nothing should be received yet |
| 396 | + ts.assertReceivedOnNext(Collections.<Long> emptyList()); |
| 397 | + |
| 398 | + scheduler1.advanceTimeBy(3, TimeUnit.SECONDS); |
| 399 | + scheduler2.advanceTimeBy(2, TimeUnit.SECONDS); |
| 400 | + |
| 401 | + ts.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 0L, 1L)); |
| 402 | + // not unsubscribed yet |
| 403 | + assertFalse(os1.get()); |
| 404 | + assertFalse(os2.get()); |
| 405 | + |
| 406 | + // advance to the end at which point it should complete |
| 407 | + scheduler1.advanceTimeBy(3, TimeUnit.SECONDS); |
| 408 | + |
| 409 | + ts.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 0L, 1L, 3L, 4L)); |
| 410 | + assertTrue(os1.get()); |
| 411 | + assertFalse(os2.get()); |
| 412 | + |
| 413 | + // both should be completed now |
| 414 | + scheduler2.advanceTimeBy(3, TimeUnit.SECONDS); |
| 415 | + |
| 416 | + ts.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 0L, 1L, 3L, 4L, 2L, 3L, 4L)); |
| 417 | + assertTrue(os1.get()); |
| 418 | + assertTrue(os2.get()); |
| 419 | + |
| 420 | + ts.assertTerminalEvent(); |
| 421 | + } |
| 422 | + |
| 423 | + @Test |
| 424 | + public void testEarlyUnsubscribe() { |
| 425 | + TestScheduler scheduler1 = Schedulers.test(); |
| 426 | + AtomicBoolean os1 = new AtomicBoolean(false); |
| 427 | + Observable<Long> o1 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler1, os1); |
| 428 | + |
| 429 | + TestScheduler scheduler2 = Schedulers.test(); |
| 430 | + AtomicBoolean os2 = new AtomicBoolean(false); |
| 431 | + Observable<Long> o2 = createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(scheduler2, os2); |
| 432 | + |
| 433 | + TestSubscriber<Long> ts = new TestSubscriber<Long>(); |
| 434 | + Subscription s = Observable.merge(o1, o2).subscribe(ts); |
| 435 | + |
| 436 | + // we haven't incremented time so nothing should be received yet |
| 437 | + ts.assertReceivedOnNext(Collections.<Long> emptyList()); |
| 438 | + |
| 439 | + scheduler1.advanceTimeBy(3, TimeUnit.SECONDS); |
| 440 | + scheduler2.advanceTimeBy(2, TimeUnit.SECONDS); |
| 441 | + |
| 442 | + ts.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 0L, 1L)); |
| 443 | + // not unsubscribed yet |
| 444 | + assertFalse(os1.get()); |
| 445 | + assertFalse(os2.get()); |
| 446 | + |
| 447 | + // early unsubscribe |
| 448 | + s.unsubscribe(); |
| 449 | + |
| 450 | + assertTrue(os1.get()); |
| 451 | + assertTrue(os2.get()); |
| 452 | + |
| 453 | + ts.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 0L, 1L)); |
| 454 | + ts.assertUnsubscribed(); |
| 455 | + } |
| 456 | + |
| 457 | + private Observable<Long> createObservableOf5IntervalsOf1SecondIncrementsWithSubscriptionHook(final Scheduler scheduler, final AtomicBoolean unsubscribed) { |
| 458 | + return Observable.create(new OnSubscribe<Long>() { |
| 459 | + |
| 460 | + @Override |
| 461 | + public void call(Subscriber<? super Long> s) { |
| 462 | + s.add(Subscriptions.create(new Action0() { |
| 463 | + |
| 464 | + @Override |
| 465 | + public void call() { |
| 466 | + unsubscribed.set(true); |
| 467 | + } |
| 468 | + |
| 469 | + })); |
| 470 | + Observable.interval(1, TimeUnit.SECONDS, scheduler).take(5).subscribe(s); |
| 471 | + } |
| 472 | + }); |
| 473 | + } |
| 474 | + |
375 | 475 | }
|
0 commit comments