1package com.xtremelabs.robolectric;
2
3import android.app.Activity;
4import android.content.Context;
5import android.os.Handler;
6import android.view.Display;
7import android.view.View;
8import com.xtremelabs.robolectric.internal.Implementation;
9import com.xtremelabs.robolectric.internal.Implements;
10import com.xtremelabs.robolectric.shadows.ShadowDisplay;
11import com.xtremelabs.robolectric.util.TestOnClickListener;
12import org.apache.http.HttpException;
13import org.apache.http.HttpResponse;
14import org.apache.http.client.methods.HttpGet;
15import org.apache.http.conn.ConnectionKeepAliveStrategy;
16import org.apache.http.impl.client.DefaultRequestDirector;
17import org.apache.http.protocol.HttpContext;
18import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
21import org.junit.runner.RunWith;
22
23import java.io.ByteArrayOutputStream;
24import java.io.IOException;
25import java.io.PrintStream;
26
27import static com.xtremelabs.robolectric.Robolectric.shadowOf;
28import static org.hamcrest.CoreMatchers.equalTo;
29import static org.junit.Assert.*;
30
31@RunWith(WithTestDefaultsRunner.class)
32public class RobolectricTest {
33
34    private PrintStream originalSystemOut;
35    private ByteArrayOutputStream buff;
36    private String defaultLineSeparator;
37
38    @Before
39    public void setUp() {
40        originalSystemOut = System.out;
41        defaultLineSeparator = System.getProperty("line.separator");
42
43        System.setProperty("line.separator", "\n");
44        buff = new ByteArrayOutputStream();
45        PrintStream testOut = new PrintStream(buff);
46        System.setOut(testOut);
47    }
48
49    @After
50    public void tearDown() throws Exception {
51        System.setProperty("line.separator", defaultLineSeparator);
52        System.setOut(originalSystemOut);
53    }
54
55    @Test
56    public void shouldLogMissingInvokedShadowMethodsWhenRequested() throws Exception {
57        Robolectric.bindShadowClass(TestShadowView.class);
58        Robolectric.logMissingInvokedShadowMethods();
59
60
61        View aView = new View(null);
62        // There's a shadow method for this
63        aView.getContext();
64        String output = buff.toString();
65        assertEquals("No Shadow method found for View.<init>(android.content.Context)\n", output);
66        buff.reset();
67
68        aView.findViewById(27);
69        // No shadow here... should be logged
70        output = buff.toString();
71        assertEquals("No Shadow method found for View.findViewById(int)\n", output);
72    }
73
74    @Test // This is nasty because it depends on the test above having run first in order to fail
75    public void shouldNotLogMissingInvokedShadowMethodsByDefault() throws Exception {
76        View aView = new View(null);
77        aView.findViewById(27);
78        String output = buff.toString();
79
80        assertEquals("", output);
81    }
82
83    @Test(expected = RuntimeException.class)
84    public void clickOn_shouldThrowIfViewIsDisabled() throws Exception {
85        View view = new View(null);
86        view.setEnabled(false);
87        Robolectric.clickOn(view);
88    }
89
90    @Test
91    public void shouldResetBackgroundSchedulerBeforeTests() throws Exception {
92        assertThat(Robolectric.getBackgroundScheduler().isPaused(), equalTo(false));
93        Robolectric.getBackgroundScheduler().pause();
94    }
95
96    @Test
97    public void shouldResetBackgroundSchedulerAfterTests() throws Exception {
98        assertThat(Robolectric.getBackgroundScheduler().isPaused(), equalTo(false));
99        Robolectric.getBackgroundScheduler().pause();
100    }
101
102    @Test
103    public void httpRequestWasSent_ReturnsTrueIfRequestWasSent() throws IOException, HttpException {
104        makeRequest("http://example.com");
105
106        assertTrue(Robolectric.httpRequestWasMade());
107    }
108
109    @Test
110    public void httpRequestWasMade_ReturnsFalseIfNoRequestWasMade() {
111        assertFalse(Robolectric.httpRequestWasMade());
112    }
113
114    @Test
115    public void httpRequestWasMade_returnsTrueIfRequestMatchingGivenRuleWasMade() throws IOException, HttpException {
116        makeRequest("http://example.com");
117        assertTrue(Robolectric.httpRequestWasMade("http://example.com"));
118    }
119
120    @Test
121    public void httpRequestWasMade_returnsFalseIfNoRequestMatchingGivenRuleWasMAde() throws IOException, HttpException {
122        makeRequest("http://example.com");
123        assertFalse(Robolectric.httpRequestWasMade("http://example.org"));
124    }
125
126    @Test
127    public void idleMainLooper_executesScheduledTasks() {
128        final boolean[] wasRun = new boolean[]{false};
129        new Handler().postDelayed(new Runnable() {
130            @Override
131            public void run() {
132                wasRun[0] = true;
133            }
134        }, 2000);
135
136        assertFalse(wasRun[0]);
137        Robolectric.idleMainLooper(1999);
138        assertFalse(wasRun[0]);
139        Robolectric.idleMainLooper(1);
140        assertTrue(wasRun[0]);
141    }
142
143    @Test
144    public void shouldUseSetDensityForContexts() throws Exception {
145        assertThat(new Activity().getResources().getDisplayMetrics().density, equalTo(1.0f));
146        Robolectric.setDisplayMetricsDensity(1.5f);
147        assertThat(new Activity().getResources().getDisplayMetrics().density, equalTo(1.5f));
148    }
149
150    @Test
151    public void shouldUseSetDisplayForContexts() throws Exception {
152        assertThat(new Activity().getResources().getDisplayMetrics().widthPixels, equalTo(480));
153        assertThat(new Activity().getResources().getDisplayMetrics().heightPixels, equalTo(800));
154
155        Display display = Robolectric.newInstanceOf(Display.class);
156        ShadowDisplay shadowDisplay = shadowOf(display);
157        shadowDisplay.setWidth(100);
158        shadowDisplay.setHeight(200);
159        Robolectric.setDefaultDisplay(display);
160
161        assertThat(new Activity().getResources().getDisplayMetrics().widthPixels, equalTo(100));
162        assertThat(new Activity().getResources().getDisplayMetrics().heightPixels, equalTo(200));
163    }
164
165    public void clickOn_shouldCallClickListener() throws Exception {
166        View view = new View(null);
167        TestOnClickListener testOnClickListener = new TestOnClickListener();
168        view.setOnClickListener(testOnClickListener);
169        Robolectric.clickOn(view);
170        assertTrue(testOnClickListener.clicked);
171    }
172
173    @Implements(View.class)
174    public static class TestShadowView {
175        @SuppressWarnings({"UnusedDeclaration"})
176        @Implementation
177        public Context getContext() {
178            return null;
179        }
180    }
181
182    private void makeRequest(String uri) throws HttpException, IOException {
183        Robolectric.addPendingHttpResponse(200, "a happy response body");
184
185        ConnectionKeepAliveStrategy connectionKeepAliveStrategy = new ConnectionKeepAliveStrategy() {
186            @Override
187            public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
188                return 0;
189            }
190
191        };
192        DefaultRequestDirector requestDirector = new DefaultRequestDirector(null, null, null, connectionKeepAliveStrategy, null, null, null, null, null, null, null, null);
193
194        requestDirector.execute(null, new HttpGet(uri), null);
195    }
196}
197