Home | History | Annotate | Download | only in robolectric
      1 package org.robolectric;
      2 
      3 import android.app.Activity;
      4 import android.app.Fragment;
      5 import android.app.IntentService;
      6 import android.app.Service;
      7 import android.app.backup.BackupAgent;
      8 import android.content.ContentProvider;
      9 import android.content.Intent;
     10 import android.os.Bundle;
     11 import android.util.AttributeSet;
     12 import android.view.View;
     13 import java.util.ServiceLoader;
     14 import javax.xml.parsers.DocumentBuilder;
     15 import javax.xml.parsers.DocumentBuilderFactory;
     16 import javax.xml.parsers.ParserConfigurationException;
     17 import org.robolectric.android.XmlResourceParserImpl;
     18 import org.robolectric.android.controller.ActivityController;
     19 import org.robolectric.android.controller.BackupAgentController;
     20 import org.robolectric.android.controller.ContentProviderController;
     21 import org.robolectric.android.controller.FragmentController;
     22 import org.robolectric.android.controller.IntentServiceController;
     23 import org.robolectric.android.controller.ServiceController;
     24 import org.robolectric.internal.ShadowProvider;
     25 import org.robolectric.res.ResName;
     26 import org.robolectric.res.ResourceTable;
     27 import org.robolectric.shadows.ShadowApplication;
     28 import org.robolectric.util.ReflectionHelpers;
     29 import org.robolectric.util.Scheduler;
     30 import org.w3c.dom.Document;
     31 import org.w3c.dom.Element;
     32 
     33 public class Robolectric {
     34 
     35   /**
     36    * This method is internal and shouldn't be called by developers.
     37    */
     38   @Deprecated
     39   public static void reset() {
     40     // No-op- is now handled in the test runner. Users should not be calling this method anyway.
     41   }
     42 
     43   public static <T extends Service> ServiceController<T> buildService(Class<T> serviceClass) {
     44     return buildService(serviceClass, null);
     45   }
     46 
     47   public static <T extends Service> ServiceController<T> buildService(Class<T> serviceClass, Intent intent) {
     48     return ServiceController.of(ReflectionHelpers.callConstructor(serviceClass), intent);
     49   }
     50 
     51   public static <T extends Service> T setupService(Class<T> serviceClass) {
     52     return buildService(serviceClass).create().get();
     53   }
     54 
     55   public static <T extends IntentService> IntentServiceController<T> buildIntentService(Class<T> serviceClass) {
     56     return buildIntentService(serviceClass, null);
     57   }
     58 
     59   public static <T extends IntentService> IntentServiceController<T> buildIntentService(Class<T> serviceClass, Intent intent) {
     60     return IntentServiceController.of(ReflectionHelpers.callConstructor(serviceClass, new ReflectionHelpers.ClassParameter<String>(String.class, "IntentService")), intent);
     61   }
     62 
     63   public static <T extends IntentService> T setupIntentService(Class<T> serviceClass) {
     64     return buildIntentService(serviceClass).create().get();
     65   }
     66 
     67   public static <T extends ContentProvider> ContentProviderController<T> buildContentProvider(Class<T> contentProviderClass) {
     68     return ContentProviderController.of(ReflectionHelpers.callConstructor(contentProviderClass));
     69   }
     70 
     71   public static <T extends ContentProvider> T setupContentProvider(Class<T> contentProviderClass) {
     72     return buildContentProvider(contentProviderClass).create().get();
     73   }
     74 
     75   public static <T extends ContentProvider> T setupContentProvider(Class<T> contentProviderClass, String authority) {
     76     return buildContentProvider(contentProviderClass).create(authority).get();
     77   }
     78 
     79   public static <T extends Activity> ActivityController<T> buildActivity(Class<T> activityClass) {
     80     return buildActivity(activityClass, null);
     81   }
     82 
     83   public static <T extends Activity> ActivityController<T> buildActivity(Class<T> activityClass, Intent intent) {
     84     return ActivityController.of(ReflectionHelpers.callConstructor(activityClass), intent);
     85   }
     86 
     87   public static <T extends Activity> T setupActivity(Class<T> activityClass) {
     88     return buildActivity(activityClass).setup().get();
     89   }
     90 
     91   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass) {
     92     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass));
     93   }
     94 
     95   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
     96                                                                          Bundle arguments) {
     97     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), arguments);
     98   }
     99 
    100   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
    101                                                                          Class<? extends Activity> activityClass) {
    102     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), activityClass);
    103   }
    104 
    105   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass, Intent intent) {
    106     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), intent);
    107   }
    108 
    109   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
    110                                                                          Intent intent,
    111                                                                          Bundle arguments) {
    112     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), intent, arguments);
    113   }
    114 
    115   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
    116                                                                          Class<? extends Activity> activityClass,
    117                                                                          Intent intent) {
    118     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), activityClass, intent);
    119   }
    120 
    121   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
    122                                                                          Class<? extends Activity> activityClass,
    123                                                                          Bundle arguments) {
    124     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), activityClass, arguments);
    125   }
    126 
    127   public static <T extends Fragment> FragmentController<T> buildFragment(Class<T> fragmentClass,
    128                                                                          Class<? extends Activity> activityClass,
    129                                                                          Intent intent,
    130                                                                          Bundle arguments) {
    131     return FragmentController.of(ReflectionHelpers.callConstructor(fragmentClass), activityClass, intent, arguments);
    132   }
    133 
    134   public static <T extends BackupAgent> BackupAgentController<T> buildBackupAgent(Class<T> backupAgentClass) {
    135     return BackupAgentController.of(ReflectionHelpers.callConstructor(backupAgentClass));
    136   }
    137 
    138   public static <T extends BackupAgent> T setupBackupAgent(Class<T> backupAgentClass) {
    139     return buildBackupAgent(backupAgentClass).create().get();
    140   }
    141 
    142   /**
    143    * Allows for the programatic creation of an {@link AttributeSet} useful for testing {@link View} classes without
    144    * the need for creating XML snippets.
    145    */
    146   public static AttributeSetBuilder buildAttributeSet() {
    147     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    148     factory.setNamespaceAware(true);
    149     factory.setIgnoringComments(true);
    150     factory.setIgnoringElementContentWhitespace(true);
    151     Document document;
    152     try {
    153       DocumentBuilder documentBuilder = factory.newDocumentBuilder();
    154       document = documentBuilder.newDocument();
    155       Element dummy = document.createElementNS("http://schemas.android.com/apk/res/" + RuntimeEnvironment.application.getPackageName(), "dummy");
    156       document.appendChild(dummy);
    157     } catch (ParserConfigurationException e) {
    158       throw new RuntimeException(e);
    159     }
    160     return new AttributeSetBuilder(document, RuntimeEnvironment.getCompileTimeResourceTable());
    161   }
    162 
    163   public static class AttributeSetBuilder {
    164 
    165     private Document doc;
    166     private ResourceTable appResourceTable;
    167 
    168     AttributeSetBuilder(Document doc, ResourceTable resourceTable) {
    169       this.doc = doc;
    170       this.appResourceTable = resourceTable;
    171     }
    172 
    173     public AttributeSetBuilder addAttribute(int resId, String value) {
    174       ResName resName = appResourceTable.getResName(resId);
    175       if ("style".equals(resName.name)) {
    176         ((Element)doc.getFirstChild()).setAttribute(resName.name, value);
    177       } else {
    178         ((Element)doc.getFirstChild()).setAttributeNS(resName.getNamespaceUri(), resName.packageName + ":" + resName.name, value);
    179       }
    180       return this;
    181     }
    182 
    183     public AttributeSetBuilder setStyleAttribute(String value) {
    184       ((Element)doc.getFirstChild()).setAttribute("style", value);
    185       return this;
    186     }
    187 
    188     public AttributeSet build() {
    189       XmlResourceParserImpl parser = new XmlResourceParserImpl(doc, null, RuntimeEnvironment.application.getPackageName(), RuntimeEnvironment.application.getPackageName(), appResourceTable);
    190       try {
    191         parser.next(); // Root document element
    192         parser.next(); // "dummy" element
    193       } catch (Exception e) {
    194         throw new IllegalStateException("Expected single dummy element in the document to contain the attributes.", e);
    195       }
    196 
    197       return parser;
    198     }
    199   }
    200 
    201   /**
    202    * Return the foreground scheduler (e.g. the UI thread scheduler).
    203    *
    204    * @return  Foreground scheduler.
    205    */
    206   public static Scheduler getForegroundThreadScheduler() {
    207     return ShadowApplication.getInstance().getForegroundThreadScheduler();
    208   }
    209 
    210   /**
    211    * Execute all runnables that have been enqueued on the foreground scheduler.
    212    */
    213   public static void flushForegroundThreadScheduler() {
    214     getForegroundThreadScheduler().advanceToLastPostedRunnable();
    215   }
    216 
    217   /**
    218    * Return the background scheduler.
    219    *
    220    * @return  Background scheduler.
    221    */
    222   public static Scheduler getBackgroundThreadScheduler() {
    223     return ShadowApplication.getInstance().getBackgroundThreadScheduler();
    224   }
    225 
    226   /**
    227    * Execute all runnables that have been enqueued on the background scheduler.
    228    */
    229   public static void flushBackgroundThreadScheduler() {
    230     getBackgroundThreadScheduler().advanceToLastPostedRunnable();
    231   }
    232 }
    233