/** * Copyright (c) 2016-present, RxJava Contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See * the License for the specific language governing permissions and limitations under the License. */ package io.reactivex.schedulers; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; import org.mockito.*; import org.reactivestreams.*; import io.reactivex.*; import io.reactivex.Scheduler.Worker; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Function; import io.reactivex.internal.subscriptions.BooleanSubscription; import io.reactivex.internal.util.ExceptionHelper; import io.reactivex.schedulers.TestScheduler.*; public class TestSchedulerTest { @SuppressWarnings("unchecked") // mocking is unchecked, unfortunately @Test public final void testPeriodicScheduling() throws Exception { final Function<Long, Void> calledOp = mock(Function.class); final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { inner.schedulePeriodically(new Runnable() { @Override public void run() { System.out.println(scheduler.now(TimeUnit.MILLISECONDS)); try { calledOp.apply(scheduler.now(TimeUnit.MILLISECONDS)); } catch (Throwable ex) { ExceptionHelper.wrapOrThrow(ex); } } }, 1, 2, TimeUnit.SECONDS); verify(calledOp, never()).apply(anyLong()); InOrder inOrder = Mockito.inOrder(calledOp); scheduler.advanceTimeBy(999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).apply(anyLong()); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).apply(1000L); scheduler.advanceTimeBy(1999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).apply(3000L); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).apply(3000L); scheduler.advanceTimeBy(5L, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).apply(5000L); inOrder.verify(calledOp, times(1)).apply(7000L); inner.dispose(); scheduler.advanceTimeBy(11L, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).apply(anyLong()); } finally { inner.dispose(); } } @SuppressWarnings("unchecked") // mocking is unchecked, unfortunately @Test public final void testPeriodicSchedulingUnsubscription() throws Exception { final Function<Long, Void> calledOp = mock(Function.class); final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { final Disposable subscription = inner.schedulePeriodically(new Runnable() { @Override public void run() { System.out.println(scheduler.now(TimeUnit.MILLISECONDS)); try { calledOp.apply(scheduler.now(TimeUnit.MILLISECONDS)); } catch (Throwable ex) { ExceptionHelper.wrapOrThrow(ex); } } }, 1, 2, TimeUnit.SECONDS); verify(calledOp, never()).apply(anyLong()); InOrder inOrder = Mockito.inOrder(calledOp); scheduler.advanceTimeBy(999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).apply(anyLong()); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).apply(1000L); scheduler.advanceTimeBy(1999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).apply(3000L); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).apply(3000L); scheduler.advanceTimeBy(5L, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).apply(5000L); inOrder.verify(calledOp, times(1)).apply(7000L); subscription.dispose(); scheduler.advanceTimeBy(11L, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).apply(anyLong()); } finally { inner.dispose(); } } @Test public final void testImmediateUnsubscribes() { TestScheduler s = new TestScheduler(); final Scheduler.Worker inner = s.createWorker(); final AtomicInteger counter = new AtomicInteger(0); try { inner.schedule(new Runnable() { @Override public void run() { counter.incrementAndGet(); System.out.println("counter: " + counter.get()); inner.schedule(this); } }); inner.dispose(); assertEquals(0, counter.get()); } finally { inner.dispose(); } } @Test public final void testImmediateUnsubscribes2() { TestScheduler s = new TestScheduler(); final Scheduler.Worker inner = s.createWorker(); try { final AtomicInteger counter = new AtomicInteger(0); final Disposable subscription = inner.schedule(new Runnable() { @Override public void run() { counter.incrementAndGet(); System.out.println("counter: " + counter.get()); inner.schedule(this); } }); subscription.dispose(); assertEquals(0, counter.get()); } finally { inner.dispose(); } } @Test public final void testNestedSchedule() { final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { final Runnable calledOp = mock(Runnable.class); Flowable<Object> poller; poller = Flowable.unsafeCreate(new Publisher<Object>() { @Override public void subscribe(final Subscriber<? super Object> aSubscriber) { final BooleanSubscription bs = new BooleanSubscription(); aSubscriber.onSubscribe(bs); inner.schedule(new Runnable() { @Override public void run() { if (!bs.isCancelled()) { calledOp.run(); inner.schedule(this, 5, TimeUnit.SECONDS); } } }); } }); InOrder inOrder = Mockito.inOrder(calledOp); Disposable sub; sub = poller.subscribe(); scheduler.advanceTimeTo(6, TimeUnit.SECONDS); inOrder.verify(calledOp, times(2)).run(); sub.dispose(); scheduler.advanceTimeTo(11, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).run(); sub = poller.subscribe(); scheduler.advanceTimeTo(12, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).run(); } finally { inner.dispose(); } } @Test public void timedRunnableToString() { TimedRunnable r = new TimedRunnable((TestWorker) new TestScheduler().createWorker(), 5, new Runnable() { @Override public void run() { // TODO Auto-generated method stub } @Override public String toString() { return "Runnable"; } }, 1); assertEquals("TimedRunnable(time = 5, run = Runnable)", r.toString()); } @Test public void workerDisposed() { TestScheduler scheduler = new TestScheduler(); Worker w = scheduler.createWorker(); w.dispose(); assertTrue(w.isDisposed()); } }