1package com.xtremelabs.robolectric.bytecode;
2
3import android.accounts.AccountManager;
4import android.content.Context;
5import android.graphics.Paint;
6import android.graphics.drawable.Drawable;
7import android.util.Log;
8import android.view.View;
9import android.widget.TextView;
10import com.google.android.maps.ItemizedOverlay;
11import com.google.android.maps.OverlayItem;
12import com.xtremelabs.robolectric.Robolectric;
13import com.xtremelabs.robolectric.WithTestDefaultsRunner;
14import com.xtremelabs.robolectric.internal.Implementation;
15import com.xtremelabs.robolectric.internal.Implements;
16import com.xtremelabs.robolectric.internal.Instrument;
17import com.xtremelabs.robolectric.shadows.ShadowItemizedOverlay;
18import org.junit.Test;
19import org.junit.runner.RunWith;
20
21import java.lang.reflect.Constructor;
22
23import static com.xtremelabs.robolectric.Robolectric.directlyOn;
24import static com.xtremelabs.robolectric.RobolectricForMaps.shadowOf;
25import static org.hamcrest.CoreMatchers.*;
26import static org.hamcrest.core.StringContains.containsString;
27import static org.hamcrest.core.StringStartsWith.startsWith;
28import static org.junit.Assert.*;
29import static org.mockito.Mockito.mock;
30
31@RunWith(WithTestDefaultsRunner.class)
32public class AndroidTranslatorTest {
33
34    @Test
35    public void testStaticMethodsAreDelegated() throws Exception {
36        Robolectric.bindShadowClass(ShadowAccountManagerForTests.class);
37
38        Context context = mock(Context.class);
39        AccountManager.get(context);
40        assertThat(ShadowAccountManagerForTests.wasCalled, is(true));
41        assertThat(ShadowAccountManagerForTests.context, sameInstance(context));
42    }
43
44    @Test
45    public void testProtectedMethodsAreDelegated() throws Exception {
46        Robolectric.bindShadowClass(ShadowItemizedOverlay.class);
47
48        ItemizedOverlayForTests overlay = new ItemizedOverlayForTests(null);
49        overlay.triggerProtectedCall();
50
51        assertThat(shadowOf(overlay).isPopulated(), is(true));
52    }
53
54    @Test
55    public void testNativeMethodsAreDelegated() throws Exception {
56        Robolectric.bindShadowClass(ShadowPaintForTests.class);
57
58        Paint paint = new Paint();
59        paint.setColor(1234);
60
61        assertThat(paint.getColor(), is(1234));
62    }
63
64    @Test
65    public void testPrintlnWorks() throws Exception {
66        Log.println(1, "tag", "msg");
67    }
68
69    @Test
70    public void testGeneratedDefaultConstructorIsWired() throws Exception {
71        Robolectric.bindShadowClass(ShadowClassWithNoDefaultConstructor.class);
72
73        Constructor<ClassWithNoDefaultConstructor> ctor = ClassWithNoDefaultConstructor.class.getDeclaredConstructor();
74        ctor.setAccessible(true);
75        ClassWithNoDefaultConstructor instance = ctor.newInstance();
76        assertThat(Robolectric.shadowOf_(instance), not(nullValue()));
77        assertThat(Robolectric.shadowOf_(instance), instanceOf(ShadowClassWithNoDefaultConstructor.class));
78    }
79
80    @Test
81    public void testDirectlyOn() throws Exception {
82        View view = new View(null);
83        view.bringToFront();
84
85        Exception e = null;
86        try {
87            directlyOn(view).bringToFront();
88        } catch (RuntimeException e1) {
89            e = e1;
90        }
91        assertNotNull(e);
92        assertEquals("Stub!", e.getMessage());
93
94        view.bringToFront();
95    }
96
97    @Test
98    public void testDirectlyOn_Statics() throws Exception {
99        View.resolveSize(0, 0);
100
101        Exception e = null;
102        try {
103            directlyOn(View.class);
104            View.resolveSize(0, 0);
105        } catch (RuntimeException e1) {
106            e = e1;
107        }
108        assertNotNull(e);
109        assertEquals("Stub!", e.getMessage());
110
111        View.resolveSize(0, 0);
112    }
113
114    @Test
115    public void testDirectlyOn_InstanceChecking() throws Exception {
116        View view1 = new View(null);
117        View view2 = new View(null);
118
119        Exception e = null;
120        try {
121            directlyOn(view1);
122            view2.bringToFront();
123        } catch (RuntimeException e1) {
124            e = e1;
125        }
126        assertNotNull(e);
127        assertThat(e.getMessage(), startsWith("expected to perform direct call on <android.view.View"));
128        assertThat(e.getMessage(), containsString("> but got <android.view.View"));
129    }
130
131    @Test
132    public void testDirectlyOn_Statics_InstanceChecking() throws Exception {
133        TextView.getTextColors(null, null);
134
135        Exception e = null;
136        try {
137            directlyOn(View.class);
138            TextView.getTextColors(null, null);
139        } catch (RuntimeException e1) {
140            e = e1;
141        }
142        assertNotNull(e);
143        assertThat(e.getMessage(), equalTo("expected to perform direct call on <class android.view.View> but got <class android.widget.TextView>"));
144    }
145
146    @Test
147    public void testDirectlyOn_CallTwiceChecking() throws Exception {
148        directlyOn(View.class);
149
150        Exception e = null;
151        try {
152            directlyOn(View.class);
153        } catch (RuntimeException e1) {
154            e = e1;
155        }
156        assertNotNull(e);
157        assertThat(e.getMessage(), equalTo("already expecting a direct call on <class android.view.View> but here's a new request for <class android.view.View>"));
158    }
159
160    @Test
161    public void shouldDelegateToObjectToStringIfShadowHasNone() throws Exception {
162        assertTrue(new View(null).toString().startsWith("android.view.View@"));
163    }
164
165    @Test
166    public void shouldDelegateToObjectHashCodeIfShadowHasNone() throws Exception {
167        assertFalse(new View(null).hashCode() == 0);
168    }
169
170    @Test
171    public void shouldDelegateToObjectEqualsIfShadowHasNone() throws Exception {
172        View view = new View(null);
173        assertEquals(view, view);
174    }
175
176    @Implements(ItemizedOverlay.class)
177    public static class ItemizedOverlayForTests extends ItemizedOverlay {
178        public ItemizedOverlayForTests(Drawable drawable) {
179            super(drawable);
180        }
181
182        @Override
183        protected OverlayItem createItem(int i) {
184            return null;
185        }
186
187        public void triggerProtectedCall() {
188            populate();
189        }
190
191        @Override
192        public int size() {
193            return 0;
194        }
195    }
196
197    @Implements(Paint.class)
198    public static class ShadowPaintForTests {
199        private int color;
200
201        @Implementation
202        public void setColor(int color) {
203            this.color = color;
204        }
205
206        @Implementation
207        public int getColor() {
208            return color;
209        }
210    }
211
212    @Implements(AccountManager.class)
213    public static class ShadowAccountManagerForTests {
214        public static boolean wasCalled = false;
215        public static Context context;
216
217        public static AccountManager get(Context context) {
218            wasCalled = true;
219            ShadowAccountManagerForTests.context = context;
220            return mock(AccountManager.class);
221        }
222    }
223
224    @Instrument
225    @SuppressWarnings({"UnusedDeclaration"})
226    public static class ClassWithNoDefaultConstructor {
227        ClassWithNoDefaultConstructor(String string) {
228        }
229    }
230
231    @Implements(ClassWithNoDefaultConstructor.class)
232    public static class ShadowClassWithNoDefaultConstructor {
233    }
234}
235