package org.robolectric; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.Display; import android.view.View; import android.view.ViewParent; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; import org.robolectric.internal.ShadowProvider; import org.robolectric.res.builder.RobolectricPackageManager; import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowDisplay; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowView; import org.robolectric.util.ReflectionHelpers; import org.robolectric.android.TestOnClickListener; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.robolectric.Shadows.shadowOf; @RunWith(TestRunners.SelfTest.class) public class RobolectricTest { private PrintStream originalSystemOut; private ByteArrayOutputStream buff; private String defaultLineSeparator; @Before public void setUp() { originalSystemOut = System.out; defaultLineSeparator = System.getProperty("line.separator"); System.setProperty("line.separator", "\n"); buff = new ByteArrayOutputStream(); PrintStream testOut = new PrintStream(buff); System.setOut(testOut); } @After public void tearDown() throws Exception { System.setProperty("line.separator", defaultLineSeparator); System.setOut(originalSystemOut); } @Test(expected = RuntimeException.class) public void clickOn_shouldThrowIfViewIsDisabled() throws Exception { View view = new View(RuntimeEnvironment.application); view.setEnabled(false); ShadowView.clickOn(view); } @Test public void shouldResetBackgroundSchedulerBeforeTests() throws Exception { assertThat(Robolectric.getBackgroundThreadScheduler().isPaused()).isFalse(); Robolectric.getBackgroundThreadScheduler().pause(); } @Test public void shouldResetBackgroundSchedulerAfterTests() throws Exception { assertThat(Robolectric.getBackgroundThreadScheduler().isPaused()).isFalse(); Robolectric.getBackgroundThreadScheduler().pause(); } @Test public void idleMainLooper_executesScheduledTasks() { final boolean[] wasRun = new boolean[]{false}; new Handler().postDelayed(new Runnable() { @Override public void run() { wasRun[0] = true; } }, 2000); assertFalse(wasRun[0]); ShadowLooper.idleMainLooper(1999); assertFalse(wasRun[0]); ShadowLooper.idleMainLooper(1); assertTrue(wasRun[0]); } @Test public void shouldUseSetDensityForContexts() throws Exception { assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().density).isEqualTo(1.0f); ShadowApplication.setDisplayMetricsDensity(1.5f); assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().density).isEqualTo(1.5f); } @Test public void shouldUseSetDisplayForContexts() throws Exception { assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().widthPixels).isEqualTo(480); assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().heightPixels).isEqualTo(800); Display display = Shadow.newInstanceOf(Display.class); ShadowDisplay shadowDisplay = Shadows.shadowOf(display); shadowDisplay.setWidth(100); shadowDisplay.setHeight(200); ShadowApplication.setDefaultDisplay(display); assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().widthPixels).isEqualTo(100); assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().heightPixels).isEqualTo(200); } @Test public void clickOn_shouldCallClickListener() throws Exception { View view = new View(RuntimeEnvironment.application); shadowOf(view).setMyParent(ReflectionHelpers.createNullProxy(ViewParent.class)); TestOnClickListener testOnClickListener = new TestOnClickListener(); view.setOnClickListener(testOnClickListener); ShadowView.clickOn(view); assertTrue(testOnClickListener.clicked); } @Test(expected = ActivityNotFoundException.class) public void checkActivities_shouldSetValueOnShadowApplication() throws Exception { ShadowApplication.getInstance().checkActivities(true); RuntimeEnvironment.application.startActivity(new Intent("i.dont.exist.activity")); } @Test public void setupActivity_returnsAVisibleActivity() throws Exception { LifeCycleActivity activity = Robolectric.setupActivity(LifeCycleActivity.class); assertThat(activity.isCreated()).isTrue(); assertThat(activity.isStarted()).isTrue(); assertThat(activity.isResumed()).isTrue(); assertThat(activity.isVisible()).isTrue(); } private List<String> order = new ArrayList<>(); private class MockProvider implements ShadowProvider { @Override public void reset() { order.add("shadowProvider"); assertThat(RuntimeEnvironment.application).as("app during shadow reset").isNotNull(); assertThat(RuntimeEnvironment.getActivityThread()).as("activityThread during shadow reset").isNotNull(); assertThat(RuntimeEnvironment.getRobolectricPackageManager()).as("packageManager during shadow reset").isNotNull(); } @Override public String[] getProvidedPackageNames() { return null; } @Override public Map<String, String> getShadowMap() { return null; } } @Test public void reset_shouldResetShadows_beforeClearingPackageManager() { Iterable<ShadowProvider> oldProviders = ReflectionHelpers.getStaticField(Robolectric.class, "providers");; ShadowProvider mockProvider = new MockProvider(); List<ShadowProvider> mockProviders = Collections.singletonList(mockProvider); ReflectionHelpers.setStaticField(Robolectric.class, "providers", mockProviders); RobolectricPackageManager mockManager = mock(RobolectricPackageManager.class); doAnswer(new Answer<Void>() { public Void answer(InvocationOnMock invocation) { order.add("packageManager"); return null; } }).when(mockManager).reset(); RuntimeEnvironment.setRobolectricPackageManager(mockManager); try { Robolectric.reset(); } finally { // Make sure we clean up after ourselves ReflectionHelpers.setStaticField(Robolectric.class, "providers", oldProviders); } assertThat(order).as("reset order").containsExactly("shadowProvider", "packageManager"); assertThat(RuntimeEnvironment.application).as("app after reset").isNull(); assertThat(RuntimeEnvironment.getRobolectricPackageManager()).as("packageManager after reset").isNull(); assertThat(RuntimeEnvironment.getActivityThread()).as("activityThread after reset").isNull(); } @Implements(View.class) public static class TestShadowView { @Implementation public Context getContext() { return null; } } private static class LifeCycleActivity extends Activity { private boolean created; private boolean started; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); created = true; } @Override protected void onStart() { super.onStart(); started = true; } public boolean isStarted() { return started; } public boolean isCreated() { return created; } public boolean isVisible() { return getWindow().getDecorView().getWindowToken() != null; } } }