예제 #1
0
 @Test
 public void onlyFirstShouldSubscribeAndLastUnsubscribe() {
   final AtomicInteger subscriptionCount = new AtomicInteger();
   final AtomicInteger unsubscriptionCount = new AtomicInteger();
   Observable<Integer> observable =
       Observable.create(
           new Observable.OnSubscribeFunc<Integer>() {
             @Override
             public Subscription onSubscribe(Observer<? super Integer> observer) {
               subscriptionCount.incrementAndGet();
               return Subscriptions.create(
                   new Action0() {
                     @Override
                     public void call() {
                       unsubscriptionCount.incrementAndGet();
                     }
                   });
             }
           });
   Observable<Integer> refCounted = observable.publish().refCount();
   @SuppressWarnings("unchecked")
   Observer<Integer> observer = mock(Observer.class);
   Subscription first = refCounted.subscribe(observer);
   assertEquals(1, subscriptionCount.get());
   Subscription second = refCounted.subscribe(observer);
   assertEquals(1, subscriptionCount.get());
   first.unsubscribe();
   assertEquals(0, unsubscriptionCount.get());
   second.unsubscribe();
   assertEquals(1, unsubscriptionCount.get());
 }
예제 #2
0
 /**
  * https://github.com/ReactiveX/RxJava/issues/198
  *
  * <p>Rx Design Guidelines 5.2
  *
  * <p>"when calling the Subscribe method that only has an onNext argument, the OnError behavior
  * will be to rethrow the exception on the thread that the message comes out from the Observable.
  * The OnCompleted behavior in this case is to do nothing."
  *
  * @throws InterruptedException
  */
 @Test
 @Ignore("Subscribers can't throw")
 public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedException {
   final CountDownLatch latch = new CountDownLatch(1);
   final AtomicReference<Throwable> exception = new AtomicReference<>();
   Observable.create(
           observer -> {
             new Thread(
                     () -> {
                       try {
                         observer.onError(new Error("failure"));
                       } catch (Throwable e) {
                         // without an onError handler it has to just throw on whatever thread
                         // invokes it
                         exception.set(e);
                       }
                       latch.countDown();
                     })
                 .start();
           })
       .subscribe();
   // wait for exception
   latch.await(3000, TimeUnit.MILLISECONDS);
   assertNotNull(exception.get());
   assertEquals("failure", exception.get().getMessage());
 }
예제 #3
0
  @Test
  public void testPublishLast() throws InterruptedException {
    final AtomicInteger count = new AtomicInteger();
    ConnectableObservable<String> connectable =
        Observable.<String>create(
                observer -> {
                  observer.onSubscribe(EmptySubscription.INSTANCE);
                  count.incrementAndGet();
                  new Thread(
                          () -> {
                            observer.onNext("first");
                            observer.onNext("last");
                            observer.onComplete();
                          })
                      .start();
                })
            .takeLast(1)
            .publish();

    // subscribe once
    final CountDownLatch latch = new CountDownLatch(1);
    connectable.subscribe(
        value -> {
          assertEquals("last", value);
          latch.countDown();
        });

    // subscribe twice
    connectable.subscribe();

    Disposable subscription = connectable.connect();
    assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
    assertEquals(1, count.get());
    subscription.dispose();
  }
예제 #4
0
  @Test
  public void testReplay() throws InterruptedException {
    final AtomicInteger counter = new AtomicInteger();
    ConnectableObservable<String> o =
        Observable.<String>create(
                observer -> {
                  observer.onSubscribe(EmptySubscription.INSTANCE);
                  new Thread(
                          new Runnable() {

                            @Override
                            public void run() {
                              counter.incrementAndGet();
                              observer.onNext("one");
                              observer.onComplete();
                            }
                          })
                      .start();
                })
            .replay();

    // we connect immediately and it will emit the value
    Disposable s = o.connect();
    try {

      // we then expect the following 2 subscriptions to get that same value
      final CountDownLatch latch = new CountDownLatch(2);

      // subscribe once
      o.subscribe(
          v -> {
            assertEquals("one", v);
            latch.countDown();
          });

      // subscribe again
      o.subscribe(
          v -> {
            assertEquals("one", v);
            latch.countDown();
          });

      if (!latch.await(1000, TimeUnit.MILLISECONDS)) {
        fail("subscriptions did not receive values");
      }
      assertEquals(1, counter.get());
    } finally {
      s.dispose();
    }
  }
예제 #5
0
  @Ignore // FIXME throwing is not allowed from the create?!
  @Test
  public void testOnSubscribeFails() {
    Subscriber<String> observer = TestHelper.mockSubscriber();

    final RuntimeException re = new RuntimeException("bad impl");
    Observable<String> o =
        Observable.create(
            s -> {
              throw re;
            });

    o.subscribe(observer);
    verify(observer, times(0)).onNext(anyString());
    verify(observer, times(0)).onComplete();
    verify(observer, times(1)).onError(re);
  }
예제 #6
0
  @Test
  public void testCacheWithCapacity() throws InterruptedException {
    final AtomicInteger counter = new AtomicInteger();
    Observable<String> o =
        Observable.<String>create(
                observer -> {
                  observer.onSubscribe(EmptySubscription.INSTANCE);
                  new Thread(
                          () -> {
                            counter.incrementAndGet();
                            observer.onNext("one");
                            observer.onComplete();
                          })
                      .start();
                })
            .cache(1);

    // we then expect the following 2 subscriptions to get that same value
    final CountDownLatch latch = new CountDownLatch(2);

    // subscribe once
    o.subscribe(
        v -> {
          assertEquals("one", v);
          latch.countDown();
        });

    // subscribe again
    o.subscribe(
        v -> {
          assertEquals("one", v);
          latch.countDown();
        });

    if (!latch.await(1000, TimeUnit.MILLISECONDS)) {
      fail("subscriptions did not receive values");
    }
    assertEquals(1, counter.get());
  }