Robolectric.java revision 07a3254138fdfe62b70c194b458879c51bea72b4
1package com.xtremelabs.robolectric;
2
3import android.app.Activity;
4import android.app.AlarmManager;
5import android.app.AlertDialog;
6import android.app.Application;
7import android.app.Dialog;
8import android.app.ListActivity;
9import android.app.Notification;
10import android.app.NotificationManager;
11import android.appwidget.AppWidgetManager;
12import android.bluetooth.BluetoothAdapter;
13import android.bluetooth.BluetoothDevice;
14import android.content.ContentValues;
15import android.content.Context;
16import android.content.ContextWrapper;
17import android.content.Intent;
18import android.content.res.AssetManager;
19import android.content.res.Configuration;
20import android.content.res.Resources;
21import android.database.sqlite.SQLiteCursor;
22import android.database.sqlite.SQLiteDatabase;
23import android.database.sqlite.SQLiteOpenHelper;
24import android.database.sqlite.SQLiteQueryBuilder;
25import android.graphics.Bitmap;
26import android.graphics.Canvas;
27import android.graphics.ColorMatrix;
28import android.graphics.Matrix;
29import android.graphics.Paint;
30import android.graphics.Path;
31import android.graphics.drawable.BitmapDrawable;
32import android.graphics.drawable.Drawable;
33import android.hardware.Camera;
34import android.location.Geocoder;
35import android.location.LocationManager;
36import android.media.AudioManager;
37import android.media.MediaPlayer;
38import android.media.MediaRecorder;
39import android.net.ConnectivityManager;
40import android.net.NetworkInfo;
41import android.os.Handler;
42import android.os.Looper;
43import android.view.Display;
44import android.view.LayoutInflater;
45import android.view.MenuInflater;
46import android.view.MotionEvent;
47import android.view.View;
48import android.view.ViewGroup;
49import android.webkit.WebSettings;
50import android.webkit.WebView;
51import android.widget.AdapterView;
52import android.widget.ExpandableListView;
53import android.widget.ImageView;
54import android.widget.ListView;
55import android.widget.RemoteViews;
56import android.widget.TextView;
57import android.widget.Toast;
58import android.widget.ZoomButtonsController;
59import com.xtremelabs.robolectric.bytecode.RobolectricInternals;
60import com.xtremelabs.robolectric.bytecode.ShadowWrangler;
61import com.xtremelabs.robolectric.shadows.*;
62import com.xtremelabs.robolectric.util.HttpRequestInfo;
63import com.xtremelabs.robolectric.util.Scheduler;
64import org.apache.http.HttpRequest;
65import org.apache.http.HttpResponse;
66import org.apache.http.impl.client.DefaultRequestDirector;
67
68import java.util.Arrays;
69import java.util.List;
70
71@SuppressWarnings({"UnusedDeclaration"})
72public class Robolectric {
73    public static Application application;
74
75    public static <T> T newInstanceOf(Class<T> clazz) {
76        return RobolectricInternals.newInstanceOf(clazz);
77    }
78
79    public static Object newInstanceOf(String className) {
80        try {
81            Class<?> clazz = Class.forName(className);
82            if (clazz != null) {
83                return newInstanceOf(clazz);
84            }
85        } catch (ClassNotFoundException e) {
86        }
87        return null;
88    }
89
90    public static void bindShadowClass(Class<?> shadowClass) {
91        RobolectricInternals.bindShadowClass(shadowClass);
92    }
93
94    public static void bindDefaultShadowClasses() {
95        bindShadowClasses(getDefaultShadowClasses());
96    }
97
98    public static void bindShadowClasses(List<Class<?>> shadowClasses) {
99        for (Class<?> shadowClass : shadowClasses) {
100            bindShadowClass(shadowClass);
101        }
102    }
103
104    /**
105     * Invoke this utility method in tests to reveal which Android api classes and methods are being invoked
106     * for which there are no shadows or shadow methods. This helps expose which methods are being invoked
107     * either by a third party library or application code which need new shadow methods to be written. Generates
108     * output for the current test only.
109     */
110    public static void logMissingInvokedShadowMethods() {
111        ShadowWrangler.getInstance().logMissingInvokedShadowMethods();
112    }
113
114    public static List<Class<?>> getDefaultShadowClasses() {
115        return Arrays.asList(
116                ShadowAbsoluteLayout.class,
117                ShadowAbsSpinner.class,
118                ShadowAbstractCursor.class,
119                ShadowActivity.class,
120                ShadowAdapterView.class,
121                ShadowAddress.class,
122                ShadowAlarmManager.class,
123                ShadowAlertDialog.class,
124                ShadowAlertDialog.ShadowBuilder.class,
125                ShadowApplication.class,
126                ShadowAppWidgetManager.class,
127                ShadowArrayAdapter.class,
128                ShadowAssetManager.class,
129                ShadowAsyncTask.class,
130                ShadowAudioManager.class,
131                ShadowBaseAdapter.class,
132                ShadowBitmap.class,
133                ShadowBitmapDrawable.class,
134                ShadowBitmapFactory.class,
135                ShadowBluetoothAdapter.class,
136                ShadowBluetoothDevice.class,
137                ShadowBundle.class,
138                ShadowCamera.class,
139                ShadowCameraParameters.class,
140                ShadowCameraSize.class,
141                ShadowCanvas.class,
142                ShadowColorMatrix.class,
143                ShadowColorMatrixColorFilter.class,
144                ShadowColorStateList.class,
145                ShadowComponentName.class,
146                ShadowCompoundButton.class,
147                ShadowConfiguration.class,
148                ShadowConnectivityManager.class,
149                ShadowContentResolver.class,
150                ShadowContentValues.class,
151                ShadowContext.class,
152                ShadowContextWrapper.class,
153                ShadowContextThemeWrapper.class,
154                ShadowCookieManager.class,
155                ShadowDefaultRequestDirector.class,
156                ShadowDisplay.class,
157                ShadowDrawable.class,
158                ShadowDialog.class,
159                ShadowEditText.class,
160                ShadowExpandableListView.class,
161                ShadowFloatMath.class,
162                ShadowGeocoder.class,
163                ShadowGeoPoint.class,
164                ShadowHandler.class,
165                ShadowImageView.class,
166                ShadowIntent.class,
167                ShadowIntentFilter.class,
168                ShadowItemizedOverlay.class,
169                ShadowLayoutInflater.class,
170                ShadowLayoutParams.class,
171                ShadowListActivity.class,
172                ShadowListView.class,
173                ShadowLocation.class,
174                ShadowLocationManager.class,
175                ShadowLooper.class,
176                ShadowMapController.class,
177                ShadowMapActivity.class,
178                ShadowMapView.class,
179                ShadowMatrix.class,
180                ShadowMediaPlayer.class,
181                ShadowMediaRecorder.class,
182                ShadowMediaStore.ShadowImages.ShadowMedia.class,
183                ShadowMenuInflater.class,
184                ShadowMotionEvent.class,
185                ShadowNotification.class,
186                ShadowNotificationManager.class,
187                ShadowNetworkInfo.class,
188                ShadowOverlayItem.class,
189                ShadowPaint.class,
190                ShadowPath.class,
191                ShadowPendingIntent.class,
192                ShadowPoint.class,
193                ShadowPointF.class,
194                ShadowPowerManager.class,
195                ShadowPreferenceManager.class,
196                ShadowRect.class,
197                ShadowRemoteViews.class,
198                ShadowResources.class,
199                ShadowResources.ShadowTheme.class,
200                ShadowService.class,
201                ShadowSettings.class,
202                ShadowSettings.ShadowSecure.class,
203                ShadowSettings.ShadowSystem.class,
204                ShadowSpannableStringBuilder.class,
205                ShadowSQLiteDatabase.class,
206                ShadowSQLiteCursor.class,
207                ShadowSQLiteOpenHelper.class,
208                ShadowSQLiteQueryBuilder.class,
209                ShadowSurfaceView.class,
210                ShadowTextUtils.class,
211                ShadowTextView.class,
212                ShadowToast.class,
213                ShadowTypedArray.class,
214                ShadowTypedValue.class,
215                ShadowURLSpan.class,
216                ShadowView.class,
217                ShadowViewGroup.class,
218                ShadowViewStub.class,
219                ShadowWebSettings.class,
220                ShadowWebView.class,
221                ShadowWifiManager.class,
222                ShadowWindow.class,
223                ShadowZoomButtonsController.class
224        );
225    }
226
227    public static void resetStaticState() {
228        ShadowWrangler.getInstance().silence();
229        Robolectric.application = new Application();
230        ShadowBitmapFactory.reset();
231    }
232
233    public static <T> T directlyOn(T shadowedObject) {
234        return RobolectricInternals.directlyOn(shadowedObject);
235    }
236
237    public static ShadowDrawable shadowOf(Drawable instance) {
238        return (ShadowDrawable) shadowOf_(instance);
239    }
240
241    public static ShadowToast shadowOf(Toast instance) {
242        return (ShadowToast) shadowOf_(instance);
243    }
244
245    public static ShadowNetworkInfo shadowOf(NetworkInfo instance) {
246        return (ShadowNetworkInfo) shadowOf_(instance);
247    }
248
249    public static ShadowConnectivityManager shadowOf(ConnectivityManager instance) {
250        return (ShadowConnectivityManager) shadowOf_(instance);
251    }
252
253    public static ShadowBitmapDrawable shadowOf(BitmapDrawable instance) {
254        return (ShadowBitmapDrawable) shadowOf_(instance);
255    }
256
257    public static ShadowZoomButtonsController shadowOf(ZoomButtonsController instance) {
258        return (ShadowZoomButtonsController) shadowOf_(instance);
259    }
260
261    public static ShadowListView shadowOf(ListView instance) {
262        return (ShadowListView) shadowOf_(instance);
263    }
264
265    public static ExpandableListView shadowOf(ExpandableListView instance) {
266        return (ExpandableListView) shadowOf_(instance);
267    }
268
269    public static ShadowActivity shadowOf(Activity instance) {
270        return (ShadowActivity) shadowOf_(instance);
271    }
272
273    public static ShadowContextWrapper shadowOf(ContextWrapper instance) {
274        return (ShadowContextWrapper) shadowOf_(instance);
275    }
276
277    public static ShadowApplication shadowOf(Application instance) {
278        return (ShadowApplication) shadowOf_(instance);
279    }
280
281    public static ShadowContext shadowOf(Context instance) {
282        return (ShadowContext) shadowOf_(instance);
283    }
284
285    public static ShadowPaint shadowOf(Paint instance) {
286        return (ShadowPaint) shadowOf_(instance);
287    }
288
289    public static ShadowPath shadowOf(Path instance) {
290        return (ShadowPath) shadowOf_(instance);
291    }
292
293    public static ShadowListActivity shadowOf(ListActivity instance) {
294        return (ShadowListActivity) shadowOf_(instance);
295    }
296
297    public static ShadowHandler shadowOf(Handler instance) {
298        return (ShadowHandler) shadowOf_(instance);
299    }
300
301    public static ShadowColorMatrix shadowOf(ColorMatrix instance) {
302        return (ShadowColorMatrix) shadowOf_(instance);
303    }
304
305    public static ShadowIntent shadowOf(Intent instance) {
306        return (ShadowIntent) shadowOf_(instance);
307    }
308
309    public static ShadowView shadowOf(View instance) {
310        return (ShadowView) shadowOf_(instance);
311    }
312
313    public static ShadowViewGroup shadowOf(ViewGroup instance) {
314        return (ShadowViewGroup) shadowOf_(instance);
315    }
316
317    public static ShadowWebSettings shadowOf(WebSettings instance) {
318        return (ShadowWebSettings) shadowOf_(instance);
319    }
320
321    public static ShadowWebView shadowOf(WebView instance) {
322        return (ShadowWebView) shadowOf_(instance);
323    }
324
325    public static ShadowAdapterView shadowOf(AdapterView instance) {
326        return (ShadowAdapterView) shadowOf_(instance);
327    }
328
329    public static ShadowTextView shadowOf(TextView instance) {
330        return (ShadowTextView) shadowOf_(instance);
331    }
332
333    public static ShadowImageView shadowOf(ImageView instance) {
334        return (ShadowImageView) shadowOf_(instance);
335    }
336
337    public static ShadowRemoteViews shadowOf(RemoteViews instance) {
338        return (ShadowRemoteViews) shadowOf_(instance);
339    }
340
341    public static ShadowDialog shadowOf(Dialog instance) {
342        return (ShadowDialog) shadowOf_(instance);
343    }
344
345    public static ShadowDefaultRequestDirector shadowOf(DefaultRequestDirector instance) {
346        return (ShadowDefaultRequestDirector) shadowOf_(instance);
347    }
348
349    public static ShadowAlertDialog shadowOf(AlertDialog instance) {
350        return (ShadowAlertDialog) shadowOf_(instance);
351    }
352
353    public static ShadowLooper shadowOf(Looper instance) {
354        return (ShadowLooper) shadowOf_(instance);
355    }
356
357    public static ShadowCanvas shadowOf(Canvas instance) {
358        return (ShadowCanvas) shadowOf_(instance);
359    }
360
361    public static ShadowLocationManager shadowOf(LocationManager instance) {
362        return (ShadowLocationManager) shadowOf_(instance);
363    }
364
365    public static ShadowAppWidgetManager shadowOf(AppWidgetManager instance) {
366        return (ShadowAppWidgetManager) shadowOf_(instance);
367    }
368
369    public static ShadowResources shadowOf(Resources instance) {
370        return (ShadowResources) shadowOf_(instance);
371    }
372
373    public static ShadowLayoutInflater shadowOf(LayoutInflater instance) {
374        return (ShadowLayoutInflater) shadowOf_(instance);
375    }
376
377    public static ShadowMenuInflater shadowOf(MenuInflater instance) {
378        return (ShadowMenuInflater) shadowOf_(instance);
379    }
380
381    public static ShadowDisplay shadowOf(Display instance) {
382        return (ShadowDisplay) shadowOf_(instance);
383    }
384
385    public static ShadowAudioManager shadowOf(AudioManager instance) {
386        return (ShadowAudioManager) shadowOf_(instance);
387    }
388
389    public static ShadowGeocoder shadowOf(Geocoder instance) {
390        return (ShadowGeocoder) shadowOf_(instance);
391    }
392
393    public static ShadowSQLiteDatabase shadowOf(SQLiteDatabase other) {
394        return (ShadowSQLiteDatabase) Robolectric.shadowOf_(other);
395    }
396
397    public static ShadowSQLiteCursor shadowOf(SQLiteCursor other) {
398        return (ShadowSQLiteCursor) Robolectric.shadowOf_(other);
399    }
400
401    public static ShadowSQLiteOpenHelper shadowOf(SQLiteOpenHelper other) {
402        return (ShadowSQLiteOpenHelper) Robolectric.shadowOf_(other);
403    }
404
405    public static ShadowSQLiteQueryBuilder shadowOf(SQLiteQueryBuilder other) {
406        return (ShadowSQLiteQueryBuilder) Robolectric.shadowOf_(other);
407    }
408
409    public static ShadowContentValues shadowOf(ContentValues other) {
410        return (ShadowContentValues) Robolectric.shadowOf_(other);
411    }
412
413    public static ShadowCamera shadowOf(Camera instance) {
414        return (ShadowCamera) shadowOf_(instance);
415    }
416
417    public static ShadowCameraParameters shadowOf(Camera.Parameters instance) {
418        return (ShadowCameraParameters) shadowOf_(instance);
419    }
420
421    public static ShadowCameraSize shadowOf(Camera.Size instance) {
422        return (ShadowCameraSize) shadowOf_(instance);
423    }
424
425    public static ShadowMediaPlayer shadowOf(MediaPlayer instance) {
426        return (ShadowMediaPlayer) shadowOf_(instance);
427    }
428
429    public static ShadowMediaRecorder shadowOf(MediaRecorder instance) {
430        return (ShadowMediaRecorder) shadowOf_(instance);
431    }
432
433    public static ShadowAssetManager shadowOf(AssetManager instance) {
434        return (ShadowAssetManager) Robolectric.shadowOf_(instance);
435    }
436
437    public static ShadowAlarmManager shadowOf(AlarmManager instance) {
438        return (ShadowAlarmManager) Robolectric.shadowOf_(instance);
439    }
440
441    public static ShadowConfiguration shadowOf(Configuration instance) {
442        return (ShadowConfiguration) Robolectric.shadowOf_(instance);
443    }
444
445    public static ShadowBitmap shadowOf(Bitmap other) {
446        return (ShadowBitmap) Robolectric.shadowOf_(other);
447    }
448
449    public static ShadowBluetoothAdapter shadowOf(BluetoothAdapter other) {
450        return (ShadowBluetoothAdapter) Robolectric.shadowOf_(other);
451    }
452
453    public static ShadowBluetoothDevice shadowOf(BluetoothDevice other) {
454        return (ShadowBluetoothDevice) Robolectric.shadowOf_(other);
455    }
456
457    public static ShadowMatrix shadowOf(Matrix other) {
458        return (ShadowMatrix) Robolectric.shadowOf_(other);
459    }
460
461    public static ShadowMotionEvent shadowOf(MotionEvent other) {
462        return (ShadowMotionEvent) Robolectric.shadowOf_(other);
463    }
464
465    public static ShadowNotificationManager shadowOf(NotificationManager other) {
466        return (ShadowNotificationManager) Robolectric.shadowOf_(other);
467    }
468
469    public static ShadowNotification shadowOf(Notification other) {
470        return (ShadowNotification) Robolectric.shadowOf_(other);
471    }
472
473    @SuppressWarnings({"unchecked"})
474    public static <P, R> P shadowOf_(R instance) {
475        return (P) ShadowWrangler.getInstance().shadowOf(instance);
476    }
477
478    /**
479     * Runs any background tasks previously queued by {@link android.os.AsyncTask#execute(Object[])}.
480     * <p/>
481     * <p/>
482     * Note: calling this method does not pause or un-pause the scheduler.
483     */
484    public static void runBackgroundTasks() {
485        getBackgroundScheduler().advanceBy(0);
486    }
487
488    /**
489     * Runs any immediately runnable tasks previously queued on the UI thread,
490     * e.g. by {@link Activity#runOnUiThread(Runnable)} or {@link android.os.AsyncTask#onPostExecute(Object)}.
491     * <p/>
492     * <p/>
493     * Note: calling this method does not pause or un-pause the scheduler.
494     */
495    public static void runUiThreadTasks() {
496        getUiThreadScheduler().advanceBy(0);
497    }
498
499    /**
500     * Sets up an HTTP response to be returned by calls to Apache's {@code HttpClient} implementers.
501     *
502     * @param statusCode   the status code of the response
503     * @param responseBody the body of the response
504     */
505    public static void addPendingHttpResponse(int statusCode, String responseBody) {
506        getFakeHttpLayer().addPendingHttpResponse(statusCode, responseBody);
507    }
508
509    /**
510     * Sets up an HTTP response to be returned by calls to Apache's {@code HttpClient} implementers.
511     *
512     * @param httpResponse the response
513     */
514    public static void addPendingHttpResponse(HttpResponse httpResponse) {
515        getFakeHttpLayer().addPendingHttpResponse(httpResponse);
516    }
517
518    /**
519     * Accessor to obtain HTTP requests made during the current test in the order in which they were made.
520     *
521     * @param index index of the request to retrieve.
522     * @return the requested request.
523     */
524    public static HttpRequest getSentHttpRequest(int index) {
525        return ShadowDefaultRequestDirector.getSentHttpRequest(index);
526    }
527
528    /**
529     * Accessor to obtain metadata for an HTTP request made during the current test in the order in which they were made.
530     *
531     * @param index index of the request to retrieve.
532     * @return the requested request metadata.
533     */
534    public static HttpRequestInfo getSentHttpRequestInfo(int index) {
535        return ShadowDefaultRequestDirector.getSentHttpRequestInfo(index);
536    }
537
538    /**
539     * Adds an HTTP response rule. The response will be returned when the rule is matched.
540     *
541     * @param method   method to match.
542     * @param uri      uri to match.
543     * @param response response to return when a match is found.
544     */
545    public static void addHttpResponseRule(String method, String uri, HttpResponse response) {
546        getFakeHttpLayer().addHttpResponseRule(method, uri, response);
547    }
548
549    /**
550     * Adds an HTTP response rule with a default method of GET. The response will be returned when the rule is matched.
551     *
552     * @param uri      uri to match.
553     * @param response response to return when a match is found.
554     */
555    public static void addHttpResponseRule(String uri, HttpResponse response) {
556        getFakeHttpLayer().addHttpResponseRule(uri, response);
557    }
558
559    /**
560     * Adds an HTTP response rule. The response will be returned when the rule is matched.
561     *
562     * @param uri      uri to match.
563     * @param response response to return when a match is found.
564     */
565    public static void addHttpResponseRule(String uri, String response) {
566        getFakeHttpLayer().addHttpResponseRule(uri, response);
567    }
568
569    /**
570     * Adds an HTTP response rule. The response will be returned when the rule is matched.
571     *
572     * @param requestMatcher custom {@code RequestMatcher}.
573     * @param response       response to return when a match is found.
574     */
575    public static void addHttpResponseRule(FakeHttpLayer.RequestMatcher requestMatcher, HttpResponse response) {
576        getFakeHttpLayer().addHttpResponseRule(requestMatcher, response);
577    }
578
579    public static FakeHttpLayer getFakeHttpLayer() {
580        return getShadowApplication().getFakeHttpLayer();
581    }
582
583    public static void setDefaultHttpResponse(int statusCode, String responseBody) {
584        getFakeHttpLayer().setDefaultHttpResponse(statusCode, responseBody);
585    }
586
587    public static void setDefaultHttpResponse(HttpResponse defaultHttpResponse) {
588        getFakeHttpLayer().setDefaultHttpResponse(defaultHttpResponse);
589    }
590
591    public static void pauseLooper(Looper looper) {
592        ShadowLooper.pauseLooper(looper);
593    }
594
595    public static void unPauseLooper(Looper looper) {
596        ShadowLooper.unPauseLooper(looper);
597    }
598
599    public static void pauseMainLooper() {
600        ShadowLooper.pauseMainLooper();
601    }
602
603    public static void unPauseMainLooper() {
604        ShadowLooper.unPauseMainLooper();
605    }
606
607    public static Scheduler getUiThreadScheduler() {
608        return shadowOf(Looper.getMainLooper()).getScheduler();
609    }
610
611    public static Scheduler getBackgroundScheduler() {
612        return getShadowApplication().getBackgroundScheduler();
613    }
614
615    public static ShadowApplication getShadowApplication() {
616        return shadowOf(Robolectric.application);
617    }
618
619    /**
620     * Calls {@code performClick()} on a {@code View} after ensuring that it and its ancestors are visible and that it
621     * is enabled.
622     *
623     * @param view the view to click on
624     * @return true if {@code View.OnClickListener}s were found and fired, false otherwise.
625     * @throws RuntimeException if the preconditions are not met.
626     */
627    public static boolean clickOn(View view) {
628        return shadowOf(view).checkedPerformClick();
629    }
630
631    public static String visualize(View view) {
632        Canvas canvas = new Canvas();
633        view.draw(canvas);
634        return shadowOf(canvas).getDescription();
635    }
636
637    public static String visualize(Canvas canvas) {
638        return shadowOf(canvas).getDescription();
639    }
640
641    public static String visualize(Bitmap bitmap) {
642        return shadowOf(bitmap).getDescription();
643    }
644}
645