ShadowResources.java revision ec63d3ad017965dc341bd0ce15f07c65f35b4a90
1package com.xtremelabs.robolectric.shadows; 2 3import android.content.res.AssetManager; 4import android.content.res.Configuration; 5import android.content.res.Resources; 6import android.content.res.TypedArray; 7import android.graphics.BitmapFactory; 8import android.graphics.drawable.BitmapDrawable; 9import android.graphics.drawable.Drawable; 10import android.util.AttributeSet; 11import android.util.DisplayMetrics; 12import com.xtremelabs.robolectric.Robolectric; 13import com.xtremelabs.robolectric.internal.Implementation; 14import com.xtremelabs.robolectric.internal.Implements; 15import com.xtremelabs.robolectric.internal.RealObject; 16import com.xtremelabs.robolectric.res.ResourceLoader; 17 18import java.io.InputStream; 19import java.util.Locale; 20 21import static com.xtremelabs.robolectric.Robolectric.newInstanceOf; 22import static com.xtremelabs.robolectric.Robolectric.shadowOf; 23 24/** 25 * Shadow of {@code Resources} that simulates the loading of resources 26 * 27 * @see com.xtremelabs.robolectric.RobolectricTestRunner#RobolectricTestRunner(Class, String, String) 28 */ 29@SuppressWarnings({"UnusedDeclaration"}) 30@Implements(Resources.class) 31public class ShadowResources { 32 static Resources bind(Resources resources, ResourceLoader resourceLoader) { 33 ShadowResources shadowResources = shadowOf(resources); 34 if (shadowResources.resourceLoader != null) throw new RuntimeException("ResourceLoader already set!"); 35 shadowResources.resourceLoader = resourceLoader; 36 return resources; 37 } 38 39 @RealObject Resources realResources; 40 private ResourceLoader resourceLoader; 41 42 @Implementation 43 public int getColor(int id) throws Resources.NotFoundException { 44 return resourceLoader.getColorValue(id); 45 } 46 47 @Implementation 48 public Configuration getConfiguration() { 49 Configuration configuration = new Configuration(); 50 configuration.setToDefaults(); 51 return configuration; 52 } 53 54 @Implementation 55 public String getString(int id) throws Resources.NotFoundException { 56 return resourceLoader.getStringValue(id); 57 } 58 59 @Implementation 60 public String getString(int id, Object... formatArgs) throws Resources.NotFoundException { 61 String raw = getString(id); 62 return String.format(Locale.ENGLISH, raw, formatArgs); 63 } 64 65 @Implementation 66 public InputStream openRawResource(int id) throws Resources.NotFoundException { 67 return resourceLoader.getRawValue(id); 68 } 69 70 @Implementation 71 public String[] getStringArray(int id) throws Resources.NotFoundException { 72 String[] arrayValue = resourceLoader.getStringArrayValue(id); 73 if (arrayValue == null) { 74 throw new Resources.NotFoundException(); 75 } 76 return arrayValue; 77 } 78 79 @Implementation 80 public CharSequence[] getTextArray(int id) throws Resources.NotFoundException { 81 return getStringArray(id); 82 } 83 84 @Implementation 85 public CharSequence getText(int id) throws Resources.NotFoundException { 86 return getString(id); 87 } 88 89 @Implementation 90 public DisplayMetrics getDisplayMetrics() { 91 return new DisplayMetrics(); 92 } 93 94 @Implementation 95 public Drawable getDrawable(int drawableResourceId) throws Resources.NotFoundException { 96 return new BitmapDrawable(BitmapFactory.decodeResource(realResources, drawableResourceId)); 97 } 98 99 @Implementation 100 public float getDimension(int id) throws Resources.NotFoundException { 101 // todo: get this value from the xml resources and scale it by display metrics [xw 20101011] 102 if (resourceLoader.dimensions.containsKey(id)) { 103 return resourceLoader.dimensions.get(id); 104 } 105 return id - 0x7f000000; 106 } 107 108 @Implementation 109 public int getDimensionPixelSize(int id) throws Resources.NotFoundException { 110 // The int value returned from here is probably going to be handed to TextView.setTextSize(), 111 // which takes a float. Avoid int-to-float conversion errors by returning a value generated from this 112 // resource ID but which isn't too big (resource values in R.java are all greater than 0x7f000000). 113 114 return (int) getDimension(id); 115 } 116 117 @Implementation 118 public int getDimensionPixelOffset(int id) throws Resources.NotFoundException { 119 return (int) getDimension(id); 120 } 121 122 @Implementation 123 public AssetManager getAssets() { 124 return ShadowAssetManager.bind(Robolectric.newInstanceOf(AssetManager.class), resourceLoader); 125 } 126 127 @Implementation 128 public final android.content.res.Resources.Theme newTheme() { 129 return newInstanceOf(Resources.Theme.class); 130 } 131 132 /** 133 * Non-Android accessor that sets the value to be returned by {@link #getDimension(int)} 134 * 135 * @param id ID to set the dimension for 136 * @param value value to be returned 137 */ 138 public void setDimension(int id, int value) { 139 resourceLoader.dimensions.put(id, value); 140 } 141 142 @Implements(Resources.Theme.class) 143 public static class ShadowTheme { 144 @Implementation 145 public TypedArray obtainStyledAttributes(int[] attrs) { 146 return obtainStyledAttributes(0, attrs); 147 } 148 149 @Implementation 150 public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws android.content.res.Resources.NotFoundException { 151 return obtainStyledAttributes(null, attrs, 0, 0); 152 } 153 154 @Implementation 155 public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { 156 return newInstanceOf(TypedArray.class); 157 } 158 } 159} 160