blob: 5299e5357474d275bb700d223c62681254909b0b [file] [log] [blame]
package org.robolectric.util;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class SchedulerTest {
private final Scheduler scheduler = new Scheduler();
private final Transcript transcript = new Transcript();
@Before
public void setUp() throws Exception {
scheduler.pause();
}
@Test
public void advanceTo_shouldAdvanceTimeEvenIfThereIsNoWork() throws Exception {
scheduler.advanceTo(1000);
assertThat(scheduler.getCurrentTime()).isEqualTo(1000);
}
@Test
public void advanceBy_returnsTrueIffSomeJobWasRun() throws Exception {
scheduler.postDelayed(new AddToTranscript("one"), 0);
scheduler.postDelayed(new AddToTranscript("two"), 0);
scheduler.postDelayed(new AddToTranscript("three"), 1000);
assertThat(scheduler.advanceBy(0)).isTrue();
transcript.assertEventsSoFar("one", "two");
assertThat(scheduler.advanceBy(0)).isFalse();
transcript.assertNoEventsSoFar();
assertThat(scheduler.advanceBy(1000)).isTrue();
transcript.assertEventsSoFar("three");
}
@Test
public void postDelayed_addsAJobToBeRunInTheFuture() throws Exception {
scheduler.postDelayed(new AddToTranscript("one"), 1000);
scheduler.postDelayed(new AddToTranscript("two"), 2000);
scheduler.postDelayed(new AddToTranscript("three"), 3000);
scheduler.advanceBy(1000);
transcript.assertEventsSoFar("one");
scheduler.advanceBy(500);
transcript.assertNoEventsSoFar();
scheduler.advanceBy(501);
transcript.assertEventsSoFar("two");
scheduler.advanceBy(999);
transcript.assertEventsSoFar("three");
}
@Test
public void postDelayed_whileIdlingConstantly_executesImmediately() {
scheduler.idleConstantly(true);
scheduler.postDelayed(new AddToTranscript("one"), 1000);
transcript.assertEventsSoFar("one");
}
@Test
public void postDelayed_whileIdlingConstantly_advancesTime() {
scheduler.idleConstantly(true);
scheduler.postDelayed(new AddToTranscript("one"), 1000);
assertThat(scheduler.getCurrentTime()).isEqualTo(1000);
}
@Test
public void postAtFrontOfQueue_addsJobAtFrontOfQueue() throws Exception {
scheduler.post(new AddToTranscript("one"));
scheduler.post(new AddToTranscript("two"));
scheduler.postAtFrontOfQueue(new AddToTranscript("three"));
scheduler.runOneTask();
transcript.assertEventsSoFar("three");
scheduler.runOneTask();
transcript.assertEventsSoFar("one");
scheduler.runOneTask();
transcript.assertEventsSoFar("two");
}
@Test
public void postAtFrontOfQueue_whenUnpaused_runsJobs() throws Exception {
scheduler.unPause();
scheduler.postAtFrontOfQueue(new AddToTranscript("three"));
transcript.assertEventsSoFar("three");
}
@Test
public void postDelayed_whenMoreItemsAreAdded_runsJobs() throws Exception {
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
transcript.add("one");
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
transcript.add("two");
scheduler.postDelayed(new AddToTranscript("three"), 1000);
}
}, 1000);
}
}, 1000);
scheduler.advanceBy(1000);
transcript.assertEventsSoFar("one");
scheduler.advanceBy(500);
transcript.assertNoEventsSoFar();
scheduler.advanceBy(501);
transcript.assertEventsSoFar("two");
scheduler.advanceBy(999);
transcript.assertEventsSoFar("three");
}
@Test
public void remove_ShouldRemoveAllInstancesOfRunnableFromQueue() throws Exception {
scheduler.post(new TestRunnable());
TestRunnable runnable = new TestRunnable();
scheduler.post(runnable);
scheduler.post(runnable);
assertThat(scheduler.size()).isEqualTo(3);
scheduler.remove(runnable);
assertThat(scheduler.size()).isEqualTo(1);
scheduler.advanceToLastPostedRunnable();
assertThat(runnable.wasRun).isFalse();
}
@Test
public void removeWithToken_ShouldRemoveAllInstancesOfRunnableFromQueue() {
Object token = new Object();
scheduler.post(new TestRunnable(), token);
scheduler.post(new TestRunnable(), token);
scheduler.post(new TestRunnable());
assertThat(scheduler.size()).isEqualTo(3);
scheduler.removeWithToken(token);
assertThat(scheduler.size()).isEqualTo(1);
}
@Test
public void reset_shouldUnPause() throws Exception {
scheduler.pause();
TestRunnable runnable = new TestRunnable();
scheduler.post(runnable);
assertThat(runnable.wasRun).isFalse();
scheduler.reset();
scheduler.post(runnable);
assertThat(runnable.wasRun).isTrue();
}
@Test
public void reset_shouldClearPendingRunnables() throws Exception {
scheduler.pause();
TestRunnable runnable1 = new TestRunnable();
scheduler.post(runnable1);
assertThat(runnable1.wasRun).isFalse();
scheduler.reset();
TestRunnable runnable2 = new TestRunnable();
scheduler.post(runnable2);
assertThat(runnable1.wasRun).isFalse();
assertThat(runnable2.wasRun).isTrue();
}
@Test
public void nestedPost_whilePaused_doesntAutomaticallyExecute() {
final List<Integer> order = new ArrayList<>();
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(1);
scheduler.post(new Runnable() {
@Override
public void run() {
order.add(3);
}
});
order.add(2);
}
}, 0);
scheduler.runOneTask();
assertThat(order).as("order:first run").containsExactly(1, 2);
assertThat(scheduler.size()).as("size:first run").isEqualTo(1);
scheduler.runOneTask();
assertThat(order).as("order:second run").containsExactly(1, 2, 3);
assertThat(scheduler.size()).as("size:second run").isEqualTo(0);
}
@Test
public void nestedPost_whileUnpaused_automaticallyExecutes3After() {
final List<Integer> order = new ArrayList<>();
scheduler.unPause();
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(1);
scheduler.post(new Runnable() {
@Override
public void run() {
order.add(3);
}
});
order.add(2);
}
}, 0);
assertThat(order).as("order").containsExactly(1, 2, 3);
assertThat(scheduler.size()).as("size").isEqualTo(0);
}
@Test
public void nestedPostAtFront_whileUnpaused_runsAfter() {
final List<Integer> order = new ArrayList<>();
scheduler.unPause();
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(1);
scheduler.postAtFrontOfQueue(new Runnable() {
@Override
public void run() {
order.add(3);
}
});
order.add(2);
}
}, 0);
assertThat(order).as("order").containsExactly(1, 2, 3);
assertThat(scheduler.size()).as("size").isEqualTo(0);
}
@Test
public void nestedPostDelayed_whileUnpaused_doesntAutomaticallyExecute3() {
final List<Integer> order = new ArrayList<>();
scheduler.unPause();
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(1);
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(3);
}
}, 1);
order.add(2);
}
}, 0);
assertThat(order).as("order:before").containsExactly(1, 2);
assertThat(scheduler.size()).as("size:before").isEqualTo(1);
scheduler.advanceToLastPostedRunnable();
assertThat(order).as("order:after").containsExactly(1, 2, 3);
assertThat(scheduler.size()).as("size:after").isEqualTo(0);
assertThat(scheduler.getCurrentTime()).as("time:after").isEqualTo(1);
}
@Test
public void nestedPostDelayed_whenIdlingConstantly_automaticallyExecutes3After() {
final List<Integer> order = new ArrayList<>();
scheduler.idleConstantly(true);
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(1);
scheduler.postDelayed(new Runnable() {
@Override
public void run() {
order.add(3);
}
}, 1);
order.add(2);
}
}, 0);
assertThat(order).as("order").containsExactly(1, 2, 3);
assertThat(scheduler.size()).as("size").isEqualTo(0);
assertThat(scheduler.getCurrentTime()).as("time").isEqualTo(1);
}
@Test
public void post_whenTheRunnableThrows_executesSubsequentRunnables() throws Exception {
final List<Integer> runnablesThatWereRun = new ArrayList<>();
scheduler.post(new Runnable() {
@Override
public void run() {
runnablesThatWereRun.add(1);
throw new RuntimeException("foo");
}
});
try {
scheduler.unPause();
} catch (RuntimeException e) { }
scheduler.post(new Runnable() {
@Override
public void run() {
runnablesThatWereRun.add(2);
}
});
assertThat(runnablesThatWereRun).containsExactly(1, 2);
}
private class AddToTranscript implements Runnable {
private String event;
public AddToTranscript(String event) {
this.event = event;
}
@Override
public void run() {
transcript.add(event);
}
}
}