@Override public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { ResName resName = getAttrResName(namespace, attribute); Attribute attr = findByName(resName); if (attr == null) return defaultValue; String qualifiers = shadowOf(resources.getAssets()).getQualifiers(); TypedResource<AttrData> typedResource = resourceLoader.getValue(resName, qualifiers); if (typedResource == null) { System.out.println("WARN: no attr found for " + resName + ", assuming it's an integer..."); typedResource = new TypedResource<AttrData>(new AttrData(attribute, "integer", null), ResType.INTEGER); } TypedValue outValue = new TypedValue(); Converter.convertAndFill(attr, outValue, resourceLoader, qualifiers, typedResource.getData()); if (outValue.type == TypedValue.TYPE_NULL) { return defaultValue; } return outValue.data; }
@Test public void obtainStyledAttributes_shouldExtractAttributesFromAttributeSet() throws Exception { ResourceLoader resourceLoader = new PackageResourceLoader(TEST_RESOURCE_PATH); Resources resources = TestUtil.createResourcesFor(resourceLoader); RoboAttributeSet roboAttributeSet = new RoboAttributeSet(asList( new Attribute(TEST_PACKAGE + ":attr/itemType", "ungulate", TEST_PACKAGE), new Attribute(TEST_PACKAGE + ":attr/scrollBars", "horizontal|vertical", TEST_PACKAGE), new Attribute(TEST_PACKAGE + ":attr/quitKeyCombo", "^q", TEST_PACKAGE), new Attribute(TEST_PACKAGE + ":attr/aspectRatio", "1.5", TEST_PACKAGE), new Attribute(TEST_PACKAGE + ":attr/aspectRatioEnabled", "true", TEST_PACKAGE) ), resources, CustomView.class); TypedArray a = context.obtainStyledAttributes(roboAttributeSet, R.styleable.CustomView); assertThat(a.getInt(R.styleable.CustomView_itemType, -1234)).isEqualTo(1 /* ungulate */); assertThat(a.getInt(R.styleable.CustomView_scrollBars, -1234)).isEqualTo(0x300); assertThat(a.getString(R.styleable.CustomView_quitKeyCombo)).isEqualTo("^q"); assertThat(a.getText(R.styleable.CustomView_quitKeyCombo).toString()).isEqualTo("^q"); assertThat(a.getFloat(R.styleable.CustomView_aspectRatio, 1f)).isEqualTo(1.5f); assertThat(a.getBoolean(R.styleable.CustomView_aspectRatioEnabled, false)).isTrue(); TypedArray typedArray = context.obtainStyledAttributes(roboAttributeSet, new int[]{R.attr.quitKeyCombo, R.attr.itemType}); assertThat(typedArray.getString(0)).isEqualTo("^q"); assertThat(typedArray.getInt(1, -1234)).isEqualTo(1 /* ungulate */); }
@Test public void shouldInitializeFromAttributes() { String key = "key_value"; String title = "title_value"; String summary = "summary_value"; List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/key", key, R.class.getPackage().getName())); attributes.add(new Attribute("android:attr/title", title, R.class.getPackage().getName())); attributes.add(new Attribute("android:attr/summary", summary, R.class.getPackage().getName())); attrs = new RoboAttributeSet(attributes, TestUtil.emptyResources(), null); preference = new TestPreference(context, attrs); assertThat(preference.getKey()).isEqualTo(key); assertThat(preference.getTitle()).isEqualTo(title); assertThat(preference.getSummary()).isEqualTo(summary); }
public static void convertAndFill(Attribute attribute, TypedValue outValue, ResourceLoader resourceLoader, String qualifiers) { if (attribute == null || attribute.isNull()) { outValue.type = TypedValue.TYPE_NULL; return; } TypedResource attrTypeData = resourceLoader.getValue(attribute.resName, qualifiers); if (attrTypeData == null) { throw new Resources.NotFoundException("Couldn't find " + attribute.resName + " attr data"); } AttrData attrData = (AttrData) attrTypeData.getData(); convertAndFill(attribute, outValue, resourceLoader, qualifiers, attrData); }
@HiddenApi @Implementation public boolean getThemeValue(int theme, int ident, TypedValue outValue, boolean resolveRefs) { ResourceIndex resourceIndex = resourceLoader.getResourceIndex(); ResName resName = resourceIndex.getResName(ident); Resources.Theme theTheme = getThemeByInternalId(theme); // Load the style for the theme we represent. E.g. "@style/Theme.Robolectric" ResName themeStyleName = resourceIndex.getResName(shadowOf(theTheme).getStyleResourceId()); if (themeStyleName == null) return false; // is this right? Style themeStyle = resolveStyle(resourceLoader, themeStyleName, getQualifiers()); //// Load the theme attribute for the default style attributes. E.g., attr/buttonStyle //ResName defStyleName = resourceLoader.getResourceIndex().getResName(ident); // //// Load the style for the default style attribute. E.g. "@style/Widget.Robolectric.Button"; //String defStyleNameValue = themeStyle.getAttrValue(defStyleName); //ResName defStyleResName = new ResName(defStyleName.packageName, "style", defStyleName.name); //Style style = resolveStyle(resourceLoader, defStyleResName, getQualifiers()); if (themeStyle != null) { Attribute attrValue = themeStyle.getAttrValue(resName); if (attrValue == null) { System.out.println("Couldn't find " + resName + " in " + themeStyleName); } else { TypedResource attrDataValue = resourceLoader.getValue(resName, getQualifiers()); Converter.convertAndFill(attrValue, outValue, resourceLoader, getQualifiers()); return true; } } return false; }
@Override public Attribute getAttrValue(ResName resName) { resName.mustBe("attr"); StyleData currentStyle = leafStyle; while (currentStyle != null) { Attribute value = currentStyle.getAttrValue(resName); if (value != null) return value; currentStyle = getParent(currentStyle); } return null; }
@HiddenApi public void __constructor__(Context context) { field("mContext").ofType(Context.class).in(realView).set(context); this.attributeSet = new RoboAttributeSet(new ArrayList<Attribute>(), context.getResources(), null); getConstructor(View.class, realView, Context.class) .invoke(context); getConstructor(ViewGroup.class, realView, Context.class) .invoke(context); }
@Override public String getAttributeValue(String namespace, String attribute) { ResName resName = getAttrResName(namespace, attribute); Attribute attr = findByName(resName); if (attr != null && !attr.isNull()) { return attr.qualifiedValue(); } return null; }
@Override public String getAttributeValue(int index) { if (index > attributes.size()) return null; Attribute attr = attributes.get(index); if (attr != null && !attr.isNull()) { return attr.qualifiedValue(); } return null; }
@Override public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { ResName resName = getAttrResName(namespace, attribute); Attribute attr = findByName(resName); if (attr == null) return defaultValue; Integer resourceId = ResName.getResourceId(resourceLoader.getResourceIndex(), attr.value, attr.contextPackageName); return resourceId == null ? defaultValue : resourceId; }
@Override public int getAttributeResourceValue(int resourceId, int defaultValue) { String attrName = resourceLoader.getResourceIndex().getResourceName(resourceId); ResName resName = getAttrResName(null, attrName); Attribute attr = findByName(resName); if (attr == null) return defaultValue; Integer extracted = ResName.getResourceId(resourceLoader.getResourceIndex(), attr.value, attr.contextPackageName); return (extracted == null) ? defaultValue : extracted; }
@Override public int getStyleAttribute() { Attribute styleAttribute = Attribute.find(attributes, new ResName("", "attr", "style")); if (styleAttribute == null) { // Per Android specifications, return 0 if there is no style. return 0; } Integer i = ResName.getResourceId(resourceLoader.getResourceIndex(), styleAttribute.value, styleAttribute.contextPackageName); return i != null ? i : 0; }
public void validateStrictI18n() { for (ResName key : strictI18nAttrs) { Attribute attribute = findByName(key); if (attribute != null) { if (!attribute.value.startsWith("@string/")) { throw new I18nException("View class: " + (viewClass != null ? viewClass.getName() : "") + " has attribute: " + key + " with hardcoded value: \"" + attribute.value + "\" and is not i18n-safe."); } } } }
private Attribute findByName(ResName resName) { ResourceIndex resourceIndex = resourceLoader.getResourceIndex(); Integer resourceId = resourceIndex.getResourceId(resName); // canonicalize the attr name if we can, otherwise don't... // todo: this is awful; fix it. if (resourceId == null) { return Attribute.find(attributes, resName); } else { return Attribute.find(attributes, resourceId, resourceIndex); } }
public RoboAttributeSet createAttributeSet(List<Attribute> attributes, Class<? extends View> viewClass) { RoboAttributeSet attributeSet = new RoboAttributeSet(attributes, getResources(), viewClass); if (isStrictI18n()) { attributeSet.validateStrictI18n(); } return attributeSet; }
@Test public void shouldApplyAttributes() throws Exception { ViewStub viewStub = new ViewStub(ctxt, new RoboAttributeSet(asList( new Attribute("android:attr/inflatedId", "@+id/include_id", TEST_PACKAGE), new Attribute("android:attr/layout", "@layout/media", TEST_PACKAGE) ), Robolectric.application.getResources(), null) ); assertThat(viewStub.getInflatedId()).isEqualTo(R.id.include_id); assertThat(viewStub.getLayoutResource()).isEqualTo(R.layout.media); }
@Test public void shouldAddOnClickListenerFromAttribute() throws Exception { RoboAttributeSet attrs = new RoboAttributeSet(new ArrayList<Attribute>(), Robolectric.application.getResources(), null); attrs.put("android:attr/onClick", "clickMe", R.class.getPackage().getName()); view = new View(Robolectric.application, attrs); assertNotNull(shadowOf(view).getOnClickListener()); }
@Test public void shouldCallOnClickWithAttribute() throws Exception { MyActivity myActivity = buildActivity(MyActivity.class).create().get(); RoboAttributeSet attrs = new RoboAttributeSet(new ArrayList<Attribute>(), Robolectric.application.getResources(), null); attrs.put("android:attr/onClick", "clickMe", R.class.getPackage().getName()); view = new View(myActivity, attrs); view.performClick(); assertTrue("Should have been called", myActivity.called); }
@Test(expected = RuntimeException.class) public void shouldThrowExceptionWithBadMethodName() throws Exception { MyActivity myActivity = buildActivity(MyActivity.class).create().get(); RoboAttributeSet attrs = new RoboAttributeSet(new ArrayList<Attribute>(), Robolectric.application.getResources(), null); attrs.put("android:onClick", "clickYou", R.class.getPackage().getName()); view = new View(myActivity, attrs); view.performClick(); }
@Before public void setUp() throws Exception { context = buildActivity(Activity.class).create().get(); attrs = new RoboAttributeSet(new ArrayList<Attribute>(), TestUtil.emptyResources(), null); group = new TestPreferenceGroup(context, attrs); shadow = Robolectric.shadowOf(group); pref1 = new Preference(context); pref1.setKey("pref1"); pref2 = new Preference(context); pref2.setKey("pref2"); }
@Test public void getInt_withFlags_shouldReturnValue() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute("android:attr/gravity", "top|left", TestUtil.TEST_PACKAGE)), new int[]{android.R.attr.gravity}); assertThat(typedArray.getInt(0, -1)).isEqualTo(0x33); }
@Test public void getResourceId_shouldReturnActualValue() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute("android:attr/id", "@+id/snippet_text", TestUtil.TEST_PACKAGE)), new int[]{android.R.attr.id}); assertThat(typedArray.getResourceId(0, -1)).isEqualTo(R.id.snippet_text); }
@Test public void getFraction_shouldReturnGivenValue() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute(TestUtil.SYSTEM_PACKAGE + ":attr/width", "50%", TestUtil.SYSTEM_PACKAGE)), new int[]{android.R.attr.width}); assertThat(typedArray.getFraction(0, 100, 1, -1)).isEqualTo(50f); }
@Test public void getDimension_shouldReturnGivenValue() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute(TestUtil.SYSTEM_PACKAGE + ":attr/width", "50dp", TestUtil.SYSTEM_PACKAGE)), new int[]{android.R.attr.width}); assertThat(typedArray.getDimension(0, -1)).isEqualTo(50f); }
@Test public void getDrawable_withExplicitColorValue_shouldReturnColorDrawable() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute("android:attr/background", "#ff777777", TestUtil.TEST_PACKAGE)), new int[]{android.R.attr.background}); assertThat(typedArray.getDrawable(0)).isEqualTo(new ColorDrawable(0xff777777)); }
@Test public void getTextArray_whenNoSuchAttribute_shouldReturnNull() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute(TestUtil.TEST_PACKAGE + ":attr/keycode", "@array/greetings", TestUtil.TEST_PACKAGE)), new int[]{R.attr.items}); assertNull(typedArray.getTextArray(0)); }
@Test public void getTextArray_shouldReturnValues() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList(new Attribute(TestUtil.TEST_PACKAGE + ":attr/responses", "@array/greetings", TestUtil.TEST_PACKAGE)), new int[]{R.attr.responses}); assertThat(typedArray.getTextArray(0)).containsExactly("hola", "Hello"); }
@Test public void shouldEnumeratePresentValues() throws Exception { TypedArray typedArray = shadowOf(resources).createTypedArray( asList( new Attribute(TestUtil.TEST_PACKAGE + ":attr/responses", "@array/greetings", TestUtil.TEST_PACKAGE), new Attribute(TestUtil.TEST_PACKAGE + ":attr/aspectRatio", "1", TestUtil.TEST_PACKAGE) ), new int[]{R.attr.scrollBars, R.attr.responses, R.attr.isSugary}); assertThat(typedArray.getIndexCount()).isEqualTo(1); assertThat(typedArray.getIndex(0)).isEqualTo(1); }
@Before public void setUp() { progressBar = new ProgressBar(Robolectric.application, new RoboAttributeSet(asList( new Attribute(new ResName(TestUtil.SYSTEM_PACKAGE, "attr", "max"), "100", TestUtil.TEST_PACKAGE), new Attribute(new ResName(TestUtil.SYSTEM_PACKAGE, "attr", "indeterminate"), "false", TestUtil.TEST_PACKAGE), new Attribute(new ResName(TestUtil.SYSTEM_PACKAGE, "attr", "indeterminateOnly"), "false", TestUtil.TEST_PACKAGE) ), Robolectric.application.getResources(), null)); }
@Before public void setup() { List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/maxLength", "5", R.class.getPackage().getName())); RoboAttributeSet attributeSet = new RoboAttributeSet(attributes, Robolectric.application.getResources(), null); editText = new EditText(Robolectric.application, attributeSet); }
@Before public void setup() { List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/dialogMessage", TEST_DIALOG_MESSAGE, R.class.getPackage().getName())); context = Robolectric.application; attrs = new RoboAttributeSet(attributes, TestUtil.emptyResources(), null); preference = new TestDialogPreference(context, attrs); shadow = Robolectric.shadowOf(preference); }
@Before public void setup() { context = Robolectric.application; attrs = new RoboAttributeSet(new ArrayList<Attribute>(), TestUtil.emptyResources(), null); preference = new TestPreference(context, attrs); shadow = Robolectric.shadowOf(preference); }
@Test public void shouldInitializeDefaultValueFromAttribute() throws Exception { String defaultValue = "default_value"; List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/defaultValue", defaultValue, R.class.getPackage().getName())); attrs = new RoboAttributeSet(attributes, TestUtil.emptyResources(), null); preference = new TestPreference(context, attrs); assertThat(Robolectric.shadowOf(preference).getDefaultValue()).isEqualTo(defaultValue); }
@Test public void shouldInitializeAndResolveFromResourceAttributes() { List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/key", "@string/preference_resource_key", R.class.getPackage().getName())); attributes.add(new Attribute("android:attr/title", "@string/preference_resource_title", R.class.getPackage().getName())); attributes.add(new Attribute("android:attr/summary", "@string/preference_resource_summary", R.class.getPackage().getName())); attrs = new RoboAttributeSet(attributes, TestUtil.emptyResources(), null); preference = new TestPreference(context, attrs); assertThat(preference.getKey()).isEqualTo("preference_resource_key_value"); assertThat(preference.getTitle()).isEqualTo("preference_resource_title_value"); assertThat(preference.getSummary()).isEqualTo("preference_resource_summary_value"); }
@Test public void shouldInitializeAndResolveDefaultValueFromResourceAttribute() throws Exception { List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("android:attr/defaultValue", "@string/preference_resource_default_value", R.class.getPackage().getName())); attrs = new RoboAttributeSet(attributes, TestUtil.emptyResources(), null); preference = new TestPreference(context, attrs); assertThat(Robolectric.shadowOf(preference).getDefaultValue()) .isEqualTo("preference_resource_default_value"); }
public AttributeSetBuilder addAttribute(@NonNull String name, @NonNull String value) { attributes.add(new Attribute(new ResName(packageName, "attr", name), value, packageName)); return this; }
public RoboAttributeSet(List<Attribute> attributes, Resources resources, Class<? extends View> viewClass) { this.attributes = attributes; this.resources = resources; this.viewClass = viewClass; this.resourceLoader = shadowOf(resources).getResourceLoader(); }
public RoboAttributeSet put(String fullyQualifiedName, String value, String valuePackage) { return put(new Attribute(fullyQualifiedName, value, valuePackage)); }
public RoboAttributeSet put(Attribute attribute) { attributes.add(attribute); return this; }
@Override public boolean getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue) { ResName resName = getAttrResName(namespace, attribute); Attribute attr = findByName(resName); return (attr != null) ? Boolean.valueOf(attr.value) : defaultValue; }