|
15 | 15 | */
|
16 | 16 | package rx.operators;
|
17 | 17 |
|
| 18 | +import static org.junit.Assert.assertEquals; |
18 | 19 | import static org.mockito.Mockito.any;
|
19 | 20 | import static org.mockito.Mockito.mock;
|
20 | 21 | import static org.mockito.Mockito.never;
|
21 | 22 | import static org.mockito.Mockito.times;
|
22 | 23 | import static org.mockito.Mockito.verify;
|
23 | 24 | import static org.mockito.Mockito.when;
|
24 | 25 |
|
| 26 | +import java.util.concurrent.CancellationException; |
| 27 | +import java.util.concurrent.ExecutionException; |
25 | 28 | import java.util.concurrent.Future;
|
| 29 | +import java.util.concurrent.TimeUnit; |
| 30 | +import java.util.concurrent.TimeoutException; |
| 31 | +import java.util.concurrent.atomic.AtomicBoolean; |
26 | 32 |
|
27 | 33 | import org.junit.Test;
|
28 | 34 |
|
29 | 35 | import rx.Observable;
|
30 | 36 | import rx.Observer;
|
| 37 | +import rx.Subscriber; |
31 | 38 | import rx.Subscription;
|
32 | 39 | import rx.observers.TestObserver;
|
| 40 | +import rx.observers.TestSubscriber; |
| 41 | +import rx.schedulers.Schedulers; |
33 | 42 |
|
34 | 43 | public class OnSubscribeToObservableFutureTest {
|
35 | 44 |
|
@@ -68,4 +77,64 @@ public void testFailure() throws Exception {
|
68 | 77 | verify(o, times(1)).onError(e);
|
69 | 78 | verify(future, times(1)).cancel(true);
|
70 | 79 | }
|
| 80 | + |
| 81 | + @Test |
| 82 | + public void testCancelledBeforeSubscribe() throws Exception { |
| 83 | + Future<Object> future = mock(Future.class); |
| 84 | + CancellationException e = new CancellationException("unit test synthetic cancellation"); |
| 85 | + when(future.get()).thenThrow(e); |
| 86 | + Observer<Object> o = mock(Observer.class); |
| 87 | + |
| 88 | + TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>(o); |
| 89 | + testSubscriber.unsubscribe(); |
| 90 | + Subscription sub = Observable.from(future).subscribe(testSubscriber); |
| 91 | + assertEquals(0, testSubscriber.getOnErrorEvents().size()); |
| 92 | + assertEquals(0, testSubscriber.getOnCompletedEvents().size()); |
| 93 | + } |
| 94 | + |
| 95 | + @Test |
| 96 | + public void testCancellationDuringFutureGet() throws Exception { |
| 97 | + Future<Object> future = new Future<Object>() { |
| 98 | + private AtomicBoolean isCancelled = new AtomicBoolean(false); |
| 99 | + private AtomicBoolean isDone = new AtomicBoolean(false); |
| 100 | + |
| 101 | + @Override |
| 102 | + public boolean cancel(boolean mayInterruptIfRunning) { |
| 103 | + isCancelled.compareAndSet(false, true); |
| 104 | + return true; |
| 105 | + } |
| 106 | + |
| 107 | + @Override |
| 108 | + public boolean isCancelled() { |
| 109 | + return isCancelled.get(); |
| 110 | + } |
| 111 | + |
| 112 | + @Override |
| 113 | + public boolean isDone() { |
| 114 | + return isCancelled() || isDone.get(); |
| 115 | + } |
| 116 | + |
| 117 | + @Override |
| 118 | + public Object get() throws InterruptedException, ExecutionException { |
| 119 | + Thread.sleep(500); |
| 120 | + isDone.compareAndSet(false, true); |
| 121 | + return "foo"; |
| 122 | + } |
| 123 | + |
| 124 | + @Override |
| 125 | + public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { |
| 126 | + return get(); |
| 127 | + } |
| 128 | + }; |
| 129 | + |
| 130 | + Observer<Object> o = mock(Observer.class); |
| 131 | + |
| 132 | + TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>(o); |
| 133 | + Observable<Object> futureObservable = Observable.from(future); |
| 134 | + Subscription sub = futureObservable.subscribeOn(Schedulers.computation()).subscribe(testSubscriber); |
| 135 | + sub.unsubscribe(); |
| 136 | + assertEquals(0, testSubscriber.getOnErrorEvents().size()); |
| 137 | + assertEquals(0, testSubscriber.getOnCompletedEvents().size()); |
| 138 | + assertEquals(0, testSubscriber.getOnNextEvents().size()); |
| 139 | + } |
71 | 140 | }
|
0 commit comments