package org.robolectric.android.controller; import static org.assertj.core.api.Assertions.assertThat; import static org.robolectric.Shadows.shadowOf; import static org.robolectric.util.TestUtil.assertStringsInclude; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.TestRunners; import android.app.IntentService; import android.content.ComponentName; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import org.robolectric.android.controller.IntentServiceController; import org.robolectric.shadows.CoreShadowsAdapter; import org.robolectric.shadows.ShadowLooper; import org.robolectric.util.TestUtil; import java.util.ArrayList; import java.util.List; @RunWith(TestRunners.SelfTest.class) public class IntentServiceControllerTest { private static final List<String> transcript = new ArrayList<>(); private final ComponentName componentName = new ComponentName("org.robolectric", MyService.class.getName()); private final IntentServiceController<MyService> controller = Robolectric.buildIntentService(MyService.class, new Intent()); @Before public void setUp() throws Exception { transcript.clear(); } @Test public void onBindShouldSetIntent() throws Exception { MyService myService = controller.create().bind().get(); assertThat(myService.boundIntent).isNotNull(); assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName); } @Test public void onStartCommandShouldSetIntent() throws Exception { MyService myService = controller.create().startCommand(3, 4).get(); assertThat(myService.startIntent).isNotNull(); assertThat(myService.startIntent.getComponent()).isEqualTo(componentName); } @Test public void onBindShouldSetIntentComponentWithCustomIntentWithoutComponentSet() throws Exception { MyService myService = Robolectric.buildIntentService(MyService.class, new Intent(Intent.ACTION_VIEW)).bind().get(); assertThat(myService.boundIntent.getAction()).isEqualTo(Intent.ACTION_VIEW); assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName); } @Test public void shouldSetIntentForGivenServiceInstance() throws Exception { IntentServiceController<MyService> intentServiceController = IntentServiceController.of(new CoreShadowsAdapter(), new MyService(""), null).bind(); assertThat(intentServiceController.get().boundIntent).isNotNull(); } @Test public void whenLooperIsNotPaused_shouldCreateWithMainLooperPaused() throws Exception { ShadowLooper.unPauseMainLooper(); controller.create(); assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isFalse(); assertStringsInclude(transcript, "finishedOnCreate", "onCreate"); } @Test public void whenLooperIsAlreadyPaused_shouldCreateWithMainLooperPaused() throws Exception { ShadowLooper.pauseMainLooper(); controller.create(); assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isTrue(); assertStringsInclude(transcript, "finishedOnCreate"); ShadowLooper.unPauseMainLooper(); assertStringsInclude(transcript, "onCreate"); } @Test public void unbind_callsUnbindWhilePaused() { controller.create().bind().unbind(); assertStringsInclude(transcript, "finishedOnUnbind", "onUnbind"); } @Test public void rebind_callsRebindWhilePaused() { controller.create().bind().unbind().bind().rebind(); assertStringsInclude(transcript, "finishedOnRebind", "onRebind"); } @Test public void destroy_callsOnDestroyWhilePaused() { controller.create().destroy(); assertStringsInclude(transcript, "finishedOnDestroy", "onDestroy"); } @Test public void bind_callsOnBindWhilePaused() { controller.create().bind(); assertStringsInclude(transcript, "finishedOnBind", "onBind"); } @Test public void startCommand_callsOnHandleIntentWhilePaused() { controller.create().startCommand(1, 2); assertStringsInclude(transcript, "finishedOnHandleIntent", "onHandleIntent"); } public static class MyService extends IntentService { private Handler handler = new Handler(Looper.getMainLooper()); public Intent boundIntent; public Intent reboundIntent; public Intent startIntent; public Intent unboundIntent; public MyService(String name) { super(name); } @Override public IBinder onBind(Intent intent) { boundIntent = intent; transcribeWhilePaused("onBind"); transcript.add("finishedOnBind"); return null; } @Override protected void onHandleIntent(Intent intent) { startIntent = intent; transcribeWhilePaused("onHandleIntent"); transcript.add("finishedOnHandleIntent"); } @Override public void onCreate() { super.onCreate(); transcribeWhilePaused("onCreate"); transcript.add("finishedOnCreate"); } @Override public void onDestroy() { super.onDestroy(); transcribeWhilePaused("onDestroy"); transcript.add("finishedOnDestroy"); } @Override public void onRebind(Intent intent) { reboundIntent = intent; transcribeWhilePaused("onRebind"); transcript.add("finishedOnRebind"); } @Override public boolean onUnbind(Intent intent) { unboundIntent = intent; transcribeWhilePaused("onUnbind"); transcript.add("finishedOnUnbind"); return false; } private void transcribeWhilePaused(final String event) { runOnUiThread(new Runnable() { @Override public void run() { transcript.add(event); } }); } private void runOnUiThread(Runnable action) { // This is meant to emulate the behavior of Activity.runOnUiThread(); shadowOf(handler.getLooper()).getScheduler().post(action); } } }