示例#1
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());
 }
示例#2
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();
  }
示例#3
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();
    }
  }
示例#4
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);
  }
  @Test
  public void testRequestToObservable() {
    TestSubscriber<Integer> ts = new TestSubscriber<>();
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .subscribe(ts);
    assertEquals(3, requested.get());
  }
示例#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());
  }
  @Test
  public void testRequestThroughTakeWhereRequestIsSmallerThanTake() {
    TestSubscriber<Integer> ts = new TestSubscriber<>((Long) null);
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .take(10)
        .subscribe(ts);
    assertEquals(3, requested.get());
  }
  @Test
  public void testRequestThroughTakeThatReducesRequest() {
    TestSubscriber<Integer> ts = new TestSubscriber<>((Long) null);
    ts.request(3);
    final AtomicLong requested = new AtomicLong();
    Observable.<Integer>create(
            s ->
                s.onSubscribe(
                    new Subscription() {

                      @Override
                      public void request(long n) {
                        requested.set(n);
                      }

                      @Override
                      public void cancel() {}
                    }))
        .take(2)
        .subscribe(ts);

    // FIXME the take now requests Long.MAX_PATH if downstream requests at least the limit
    assertEquals(Long.MAX_VALUE, requested.get());
  }