@Test
  public void concatVeryLongObservableOfObservablesTakeHalf() {
    final int n = 10000;
    Observable<Observable<Integer>> source =
        Observable.create(
            new OnSubscribe<Observable<Integer>>() {
              @Override
              public void call(Subscriber<? super Observable<Integer>> s) {
                for (int i = 0; i < n; i++) {
                  if (s.isUnsubscribed()) {
                    return;
                  }
                  s.onNext(Observable.from(i));
                }
                s.onCompleted();
              }
            });

    Observable<List<Integer>> result = Observable.concat(source).take(n / 2).toList();

    Observer<List<Integer>> o = mock(Observer.class);
    InOrder inOrder = inOrder(o);

    result.subscribe(o);

    List<Integer> list = new ArrayList<Integer>(n);
    for (int i = 0; i < n / 2; i++) {
      list.add(i);
    }
    inOrder.verify(o).onNext(list);
    inOrder.verify(o).onCompleted();
    verify(o, never()).onError(any(Throwable.class));
  }
  /** Simple concat of 2 asynchronous observables ensuring it emits in correct order. */
  @SuppressWarnings("unchecked")
  @Test
  public void testSimpleAsyncConcat() {
    Observer<String> observer = mock(Observer.class);

    TestObservable<String> o1 = new TestObservable<String>("one", "two", "three");
    TestObservable<String> o2 = new TestObservable<String>("four", "five", "six");

    Observable.concat(Observable.create(o1), Observable.create(o2)).subscribe(observer);

    try {
      // wait for async observables to complete
      o1.t.join();
      o2.t.join();
    } catch (Throwable e) {
      throw new RuntimeException("failed waiting on threads");
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(1)).onNext("four");
    inOrder.verify(observer, times(1)).onNext("five");
    inOrder.verify(observer, times(1)).onNext("six");
  }
  @Test
  public void testConcatObservableOfObservables() {
    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);

    final String[] o = {"1", "3", "5", "7"};
    final String[] e = {"2", "4", "6"};

    final Observable<String> odds = Observable.from(o);
    final Observable<String> even = Observable.from(e);

    Observable<Observable<String>> observableOfObservables =
        Observable.create(
            new Observable.OnSubscribeFunc<Observable<String>>() {

              @Override
              public Subscription onSubscribe(Observer<? super Observable<String>> observer) {
                // simulate what would happen in an observable
                observer.onNext(odds);
                observer.onNext(even);
                observer.onCompleted();

                return Subscriptions.empty();
              }
            });
    Observable<String> concat = Observable.concat(observableOfObservables);

    concat.subscribe(observer);

    verify(observer, times(7)).onNext(anyString());
  }
  @Test
  public void testFlatMapTransformsException() {
    Observable<Integer> onNext = Observable.from(Arrays.asList(1, 2, 3));
    Observable<Integer> onCompleted = Observable.from(Arrays.asList(4));
    Observable<Integer> onError = Observable.from(Arrays.asList(5));

    Observable<Integer> source =
        Observable.concat(
            Observable.from(Arrays.asList(10, 20, 30)),
            Observable.<Integer>error(new RuntimeException("Forced failure!")));

    @SuppressWarnings("unchecked")
    Observer<Object> o = mock(Observer.class);

    source.flatMap(just(onNext), just(onError), just0(onCompleted)).subscribe(o);

    verify(o, times(3)).onNext(1);
    verify(o, times(3)).onNext(2);
    verify(o, times(3)).onNext(3);
    verify(o).onNext(5);
    verify(o).onCompleted();
    verify(o, never()).onNext(4);

    verify(o, never()).onError(any(Throwable.class));
  }
  @Test
  public void testConcatConcurrentWithInfinity() {
    final TestObservable<String> w1 = new TestObservable<String>("one", "two", "three");
    // This observable will send "hello" MAX_VALUE time.
    final TestObservable<String> w2 = new TestObservable<String>("hello", Integer.MAX_VALUE);

    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);
    @SuppressWarnings("unchecked")
    TestObservable<Observable<String>> observableOfObservables =
        new TestObservable<Observable<String>>(Observable.create(w1), Observable.create(w2));
    Observable<String> concatF = Observable.concat(Observable.create(observableOfObservables));

    concatF.take(50).subscribe(observer);

    // Wait for the thread to start up.
    try {
      w1.waitForThreadDone();
      w2.waitForThreadDone();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(47)).onNext("hello");
    verify(observer, times(1)).onCompleted();
    verify(observer, never()).onError(any(Throwable.class));
  }
 public Observable<V> get(User user, K key) {
   return Observable.concat(
           fromMemory(user, key),
           fromDiskWithCaching(user, key),
           fromNetworkWithCaching(user, key))
       .first();
 }
  @Test
  public void testConcatNonBlockingObservables() {

    final CountDownLatch okToContinueW1 = new CountDownLatch(1);
    final CountDownLatch okToContinueW2 = new CountDownLatch(1);

    final TestObservable<String> w1 =
        new TestObservable<String>(null, okToContinueW1, "one", "two", "three");
    final TestObservable<String> w2 =
        new TestObservable<String>(null, okToContinueW2, "four", "five", "six");

    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);
    Observable<Observable<String>> observableOfObservables =
        Observable.create(
            new Observable.OnSubscribeFunc<Observable<String>>() {

              @Override
              public Subscription onSubscribe(Observer<? super Observable<String>> observer) {
                // simulate what would happen in an observable
                observer.onNext(Observable.create(w1));
                observer.onNext(Observable.create(w2));
                observer.onCompleted();

                return Subscriptions.empty();
              }
            });
    Observable<String> concat = Observable.concat(observableOfObservables);
    concat.subscribe(observer);

    verify(observer, times(0)).onCompleted();

    try {
      // release both threads
      okToContinueW1.countDown();
      okToContinueW2.countDown();
      // wait for both to finish
      w1.t.join();
      w2.t.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(1)).onNext("four");
    inOrder.verify(observer, times(1)).onNext("five");
    inOrder.verify(observer, times(1)).onNext("six");
    verify(observer, times(1)).onCompleted();
  }
Example #8
0
 @Test
 public void testPropogateErrorInTheMiddleOfMultibyte() {
   Observable<byte[]> src = Observable.from(new byte[] {(byte) 0xc2});
   Observable<byte[]> err = Observable.error(new IOException());
   CharsetDecoder charsetDecoder = Charset.forName("UTF-8").newDecoder();
   try {
     StringObservable.decode(Observable.concat(src, err), charsetDecoder)
         .toList()
         .toBlockingObservable()
         .single();
     fail();
   } catch (RuntimeException e) {
     assertEquals(MalformedInputException.class, e.getCause().getClass());
   }
 }
  @Test
  public void testConcat() {
    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);

    final String[] o = {"1", "3", "5", "7"};
    final String[] e = {"2", "4", "6"};

    final Observable<String> odds = Observable.from(o);
    final Observable<String> even = Observable.from(e);

    @SuppressWarnings("unchecked")
    Observable<String> concat = Observable.concat(odds, even);
    concat.subscribe(observer);

    verify(observer, times(7)).onNext(anyString());
  }
Example #10
0
  @Test
  public void testConcatWithList() {
    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);

    final String[] o = {"1", "3", "5", "7"};
    final String[] e = {"2", "4", "6"};

    final Observable<String> odds = Observable.from(o);
    final Observable<String> even = Observable.from(e);
    final List<Observable<String>> list = new ArrayList<Observable<String>>();
    list.add(odds);
    list.add(even);
    Observable<String> concat = Observable.concat(Observable.from(list));
    concat.subscribe(observer);

    verify(observer, times(7)).onNext(anyString());
  }
Example #11
0
  /**
   * All observables will be running in different threads so subscribe() is unblocked.
   * CountDownLatch is only used in order to call unsubscribe() in a predictable manner.
   */
  @Test
  public void testConcatUnsubscribeConcurrent() {
    final CountDownLatch callOnce = new CountDownLatch(1);
    final CountDownLatch okToContinue = new CountDownLatch(1);
    final TestObservable<String> w1 = new TestObservable<String>("one", "two", "three");
    final TestObservable<String> w2 =
        new TestObservable<String>(callOnce, okToContinue, "four", "five", "six");

    @SuppressWarnings("unchecked")
    Observer<String> observer = mock(Observer.class);
    @SuppressWarnings("unchecked")
    TestObservable<Observable<String>> observableOfObservables =
        new TestObservable<Observable<String>>(Observable.create(w1), Observable.create(w2));
    Observable<String> concatF = Observable.concat(Observable.create(observableOfObservables));

    Subscription s1 = concatF.subscribe(observer);

    try {
      // Block main thread to allow observable "w1" to complete and observable "w2" to call onNext
      // exactly once.
      callOnce.await();
      // "four" from w2 has been processed by onNext()
      s1.unsubscribe();
      // "five" and "six" will NOT be processed by onNext()
      // Unblock the observable to continue.
      okToContinue.countDown();
      w1.t.join();
      w2.t.join();
    } catch (Throwable e) {
      e.printStackTrace();
      fail(e.getMessage());
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(1)).onNext("four");
    inOrder.verify(observer, never()).onNext("five");
    inOrder.verify(observer, never()).onNext("six");
    verify(observer, never()).onCompleted();
    verify(observer, never()).onError(any(Throwable.class));
  }
Example #12
0
  @Test
  public void testMultipleObservers() {
    Observer<Object> o1 = mock(Observer.class);
    Observer<Object> o2 = mock(Observer.class);

    TestScheduler s = new TestScheduler();

    Observable<Long> timer = Observable.interval(500, TimeUnit.MILLISECONDS, s).take(2);
    Observable<Long> o = Observable.concat(timer, timer);

    o.subscribe(o1);
    o.subscribe(o2);

    InOrder inOrder1 = inOrder(o1);
    InOrder inOrder2 = inOrder(o2);

    s.advanceTimeBy(500, TimeUnit.MILLISECONDS);

    inOrder1.verify(o1, times(1)).onNext(0L);
    inOrder2.verify(o2, times(1)).onNext(0L);

    s.advanceTimeBy(500, TimeUnit.MILLISECONDS);

    inOrder1.verify(o1, times(1)).onNext(1L);
    inOrder2.verify(o2, times(1)).onNext(1L);

    s.advanceTimeBy(500, TimeUnit.MILLISECONDS);

    inOrder1.verify(o1, times(1)).onNext(0L);
    inOrder2.verify(o2, times(1)).onNext(0L);

    s.advanceTimeBy(500, TimeUnit.MILLISECONDS);

    inOrder1.verify(o1, times(1)).onNext(1L);
    inOrder2.verify(o2, times(1)).onNext(1L);

    inOrder1.verify(o1, times(1)).onCompleted();
    inOrder2.verify(o2, times(1)).onCompleted();

    verify(o1, never()).onError(any(Throwable.class));
    verify(o2, never()).onError(any(Throwable.class));
  }
Example #13
0
  @SuppressWarnings("unchecked")
  @Test
  public void testBlockedObservableOfObservables() {
    Observer<String> observer = mock(Observer.class);

    final String[] o = {"1", "3", "5", "7"};
    final String[] e = {"2", "4", "6"};
    final Observable<String> odds = Observable.from(o);
    final Observable<String> even = Observable.from(e);
    final CountDownLatch callOnce = new CountDownLatch(1);
    final CountDownLatch okToContinue = new CountDownLatch(1);
    TestObservable<Observable<String>> observableOfObservables =
        new TestObservable<Observable<String>>(callOnce, okToContinue, odds, even);
    Observable<String> concatF = Observable.concat(Observable.create(observableOfObservables));
    concatF.subscribe(observer);
    try {
      // Block main thread to allow observables to serve up o1.
      callOnce.await();
    } catch (Throwable ex) {
      ex.printStackTrace();
      fail(ex.getMessage());
    }
    // The concated observable should have served up all of the odds.
    verify(observer, times(1)).onNext("1");
    verify(observer, times(1)).onNext("3");
    verify(observer, times(1)).onNext("5");
    verify(observer, times(1)).onNext("7");

    try {
      // unblock observables so it can serve up o2 and complete
      okToContinue.countDown();
      observableOfObservables.t.join();
    } catch (Throwable ex) {
      ex.printStackTrace();
      fail(ex.getMessage());
    }
    // The concatenated observable should now have served up all the evens.
    verify(observer, times(1)).onNext("2");
    verify(observer, times(1)).onNext("4");
    verify(observer, times(1)).onNext("6");
  }
  @Test
  public void testDelayedErrorDeliveryWhenSafeSubscriberUnsubscribes() {
    TestScheduler testScheduler = new TestScheduler();

    Observable<Integer> source =
        Observable.concat(Observable.<Integer>error(new TestException()), Observable.just(1));

    @SuppressWarnings("unchecked")
    Observer<Integer> o = mock(Observer.class);
    InOrder inOrder = inOrder(o);

    source.observeOn(testScheduler).subscribe(o);

    inOrder.verify(o, never()).onError(any(TestException.class));

    testScheduler.advanceTimeBy(1, TimeUnit.SECONDS);

    inOrder.verify(o).onError(any(TestException.class));
    inOrder.verify(o, never()).onNext(anyInt());
    inOrder.verify(o, never()).onCompleted();
  }
Example #15
0
  /** Test unsubscribing the concatenated Observable in a single thread. */
  @Test
  public void testConcatUnsubscribe() {
    final CountDownLatch callOnce = new CountDownLatch(1);
    final CountDownLatch okToContinue = new CountDownLatch(1);
    final TestObservable<String> w1 = new TestObservable<String>("one", "two", "three");
    final TestObservable<String> w2 =
        new TestObservable<String>(callOnce, okToContinue, "four", "five", "six");

    @SuppressWarnings("unchecked")
    final Observer<String> observer = mock(Observer.class);
    @SuppressWarnings("unchecked")
    final Observable<String> concat =
        Observable.concat(Observable.create(w1), Observable.create(w2));

    try {
      // Subscribe
      Subscription s1 = concat.subscribe(observer);
      // Block main thread to allow observable "w1" to complete and observable "w2" to call onNext
      // once.
      callOnce.await();
      // Unsubcribe
      s1.unsubscribe();
      // Unblock the observable to continue.
      okToContinue.countDown();
      w1.t.join();
      w2.t.join();
    } catch (Throwable e) {
      e.printStackTrace();
      fail(e.getMessage());
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(1)).onNext("four");
    inOrder.verify(observer, never()).onNext("five");
    inOrder.verify(observer, never()).onNext("six");
    inOrder.verify(observer, never()).onCompleted();
  }
Example #16
0
  /** Test an async Observable that emits more async Observables */
  @SuppressWarnings("unchecked")
  @Test
  public void testNestedAsyncConcat() throws Throwable {
    Observer<String> observer = mock(Observer.class);

    final TestObservable<String> o1 = new TestObservable<String>("one", "two", "three");
    final TestObservable<String> o2 = new TestObservable<String>("four", "five", "six");
    final TestObservable<String> o3 = new TestObservable<String>("seven", "eight", "nine");
    final CountDownLatch allowThird = new CountDownLatch(1);

    final AtomicReference<Thread> parent = new AtomicReference<Thread>();
    final CountDownLatch parentHasStarted = new CountDownLatch(1);
    Observable<Observable<String>> observableOfObservables =
        Observable.create(
            new Observable.OnSubscribeFunc<Observable<String>>() {

              @Override
              public Subscription onSubscribe(final Observer<? super Observable<String>> observer) {
                final BooleanSubscription s = new BooleanSubscription();
                parent.set(
                    new Thread(
                        new Runnable() {

                          @Override
                          public void run() {
                            try {
                              // emit first
                              if (!s.isUnsubscribed()) {
                                System.out.println("Emit o1");
                                observer.onNext(Observable.create(o1));
                              }
                              // emit second
                              if (!s.isUnsubscribed()) {
                                System.out.println("Emit o2");
                                observer.onNext(Observable.create(o2));
                              }

                              // wait until sometime later and emit third
                              try {
                                allowThird.await();
                              } catch (InterruptedException e) {
                                observer.onError(e);
                              }
                              if (!s.isUnsubscribed()) {
                                System.out.println("Emit o3");
                                observer.onNext(Observable.create(o3));
                              }

                            } catch (Throwable e) {
                              observer.onError(e);
                            } finally {
                              System.out.println("Done parent Observable");
                              observer.onCompleted();
                            }
                          }
                        }));
                parent.get().start();
                parentHasStarted.countDown();
                return s;
              }
            });

    Observable.concat(observableOfObservables).subscribe(observer);

    // wait for parent to start
    parentHasStarted.await();

    try {
      // wait for first 2 async observables to complete
      System.out.println("Thread1 is starting ... waiting for it to complete ...");
      o1.waitForThreadDone();
      System.out.println("Thread2 is starting ... waiting for it to complete ...");
      o2.waitForThreadDone();
    } catch (Throwable e) {
      throw new RuntimeException("failed waiting on threads", e);
    }

    InOrder inOrder = inOrder(observer);
    inOrder.verify(observer, times(1)).onNext("one");
    inOrder.verify(observer, times(1)).onNext("two");
    inOrder.verify(observer, times(1)).onNext("three");
    inOrder.verify(observer, times(1)).onNext("four");
    inOrder.verify(observer, times(1)).onNext("five");
    inOrder.verify(observer, times(1)).onNext("six");
    // we shouldn't have the following 3 yet
    inOrder.verify(observer, never()).onNext("seven");
    inOrder.verify(observer, never()).onNext("eight");
    inOrder.verify(observer, never()).onNext("nine");
    // we should not be completed yet
    verify(observer, never()).onCompleted();
    verify(observer, never()).onError(any(Throwable.class));

    // now allow the third
    allowThird.countDown();

    try {
      // wait for 3rd to complete
      o3.waitForThreadDone();
    } catch (Throwable e) {
      throw new RuntimeException("failed waiting on threads", e);
    }

    inOrder.verify(observer, times(1)).onNext("seven");
    inOrder.verify(observer, times(1)).onNext("eight");
    inOrder.verify(observer, times(1)).onNext("nine");

    inOrder.verify(observer, times(1)).onCompleted();
    verify(observer, never()).onError(any(Throwable.class));
  }
 /**
  * Perform a long operation to be used in the main thread
  *
  * @param maxResults
  * @return
  */
 @Override
 public Observable<List<Promotion>> queryLastestPromotion(int maxResults) {
   return Observable.concat(queryLocalPromotions(), queryServerPromotions())
       .observeOn(AndroidSchedulers.mainThread());
 }