Home | History | Annotate | Download | only in matchers
      1 package com.xtremelabs.robolectric.matchers;
      2 
      3 import android.app.Service;
      4 import android.content.Context;
      5 import android.content.ContextWrapper;
      6 import android.content.Intent;
      7 import com.xtremelabs.robolectric.shadows.ShadowIntent;
      8 import org.hamcrest.Description;
      9 import org.junit.internal.matchers.TypeSafeMatcher;
     10 
     11 import java.util.Set;
     12 
     13 import static com.xtremelabs.robolectric.Robolectric.getShadowApplication;
     14 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     15 
     16 public class StartedServiceMatcher extends TypeSafeMatcher<Context> {
     17     private final Intent expectedIntent;
     18 
     19     private String message;
     20 
     21     public StartedServiceMatcher(Intent expectedIntent) {
     22         this.expectedIntent = expectedIntent;
     23     }
     24 
     25     public StartedServiceMatcher(String packageName, Class<? extends Service> expectedServiceClass) {
     26         this(createIntent(packageName, expectedServiceClass));
     27     }
     28 
     29     public StartedServiceMatcher(Class<? extends Service> expectedServiceClass) {
     30         this(createIntent(expectedServiceClass));
     31     }
     32 
     33     public StartedServiceMatcher(Class<? extends Service> expectedServiceClass, String expectedAction) {
     34         this(createIntent(expectedServiceClass));
     35 
     36         expectedIntent.setAction(expectedAction);
     37     }
     38 
     39     /**
     40      * Check if the class of the intent and the keys of the intent's extras match
     41      *
     42      * @param actualContext
     43      * @return
     44      */
     45     @Override
     46     public boolean matchesSafely(Context actualContext) {
     47         if (expectedIntent == null) {
     48             message = "null intent (did you mean to expect null?)";
     49             return false;
     50         }
     51 
     52         String expected = expectedIntent.toString();
     53         message = "to start " + expected + ", but ";
     54 
     55         Intent actualStartedIntent = shadowOf((ContextWrapper) actualContext).getNextStartedService();
     56 
     57         if (actualStartedIntent == null) {
     58             message += "didn't start anything";
     59             return false;
     60         }
     61 
     62         ShadowIntent shadowIntent = shadowOf(actualStartedIntent);
     63 
     64         //boolean intentsMatch = shadowOf(expectedIntent).realIntentEquals(shadowIntent);
     65         // Test only that we are sending intent to the right service class
     66         boolean intentsMatch = shadowOf(expectedIntent).getIntentClass().equals(shadowIntent.getIntentClass());
     67         if (!intentsMatch) {
     68             message += "started " + actualStartedIntent;
     69         } else {
     70             // Test that both intent extras have the same keys
     71             Set<String> keys = shadowIntent.getExtras().keySet();
     72             Set<String> expectedKeys = shadowOf(expectedIntent).getExtras().keySet();
     73             intentsMatch = keys.equals(expectedKeys);
     74             if(!intentsMatch){
     75                 message += "did not get the same extras keys";
     76             }
     77         }
     78 
     79         return intentsMatch;
     80     }
     81 
     82     @Override
     83     public void describeTo(Description description) {
     84         description.appendText(message);
     85     }
     86 
     87     public static Intent createIntent(Class<? extends Service> serviceClass, String extraKey, String extraValue) {
     88         Intent intent = createIntent(serviceClass);
     89         intent.putExtra(extraKey, extraValue);
     90         return intent;
     91     }
     92 
     93     public static Intent createIntent(Class<? extends Service> serviceClass, String action) {
     94         Intent intent = createIntent(serviceClass);
     95         intent.setAction(action);
     96         return intent;
     97     }
     98 
     99     public static Intent createIntent(Class<? extends Service> serviceClass) {
    100         Package pack = serviceClass.getPackage();
    101         String packageName = "android.service";
    102         // getPackage is returning null when run from tests
    103         if(pack != null) {
    104             pack.getName();
    105         }
    106         return createIntent(packageName, serviceClass);
    107     }
    108 
    109     public static Intent createIntent(String packageName, Class<? extends Service> serviceClass) {
    110         Intent intent = new Intent();
    111         intent.setClassName(packageName, serviceClass.getName());
    112         intent.setClass(getShadowApplication().getApplicationContext(), serviceClass);
    113         return intent;
    114     }
    115 }
    116