Home | History | Annotate | Download | only in shadows
      1 package org.robolectric.shadows;
      2 
      3 import static org.assertj.core.api.Assertions.assertThat;
      4 import static org.junit.Assert.fail;
      5 import static org.robolectric.Robolectric.buildActivity;
      6 import static org.robolectric.Shadows.shadowOf;
      7 
      8 import android.app.Activity;
      9 import android.content.res.Resources;
     10 import android.content.res.TypedArray;
     11 import android.graphics.Color;
     12 import android.graphics.drawable.ColorDrawable;
     13 import android.os.Bundle;
     14 import android.util.AttributeSet;
     15 import android.util.TypedValue;
     16 import android.view.View;
     17 import android.widget.Button;
     18 import org.junit.Before;
     19 import org.junit.Test;
     20 import org.junit.runner.RunWith;
     21 import org.robolectric.R;
     22 import org.robolectric.Robolectric;
     23 import org.robolectric.RobolectricTestRunner;
     24 import org.robolectric.RuntimeEnvironment;
     25 import org.robolectric.android.controller.ActivityController;
     26 
     27 @RunWith(RobolectricTestRunner.class)
     28 public class ShadowThemeTest {
     29 
     30   private Resources resources;
     31 
     32   @Before
     33   public void setUp() throws Exception {
     34     resources = RuntimeEnvironment.application.getResources();
     35   }
     36 
     37   @Test public void withEmptyTheme_returnsEmptyAttributes() throws Exception {
     38     assertThat(resources.newTheme().obtainStyledAttributes(new int[] {R.attr.string1}).hasValue(0)).isFalse();
     39   }
     40 
     41   @Test public void whenExplicitlySetOnActivity_afterSetContentView_activityGetsThemeFromActivityInManifest() throws Exception {
     42     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
     43     activity.setTheme(R.style.Theme_Robolectric);
     44     Button theButton = (Button) activity.findViewById(R.id.button);
     45     ColorDrawable background = (ColorDrawable) theButton.getBackground();
     46     assertThat(background.getColor()).isEqualTo(0xffff0000);
     47   }
     48 
     49   @Test public void whenExplicitlySetOnActivity_beforeSetContentView_activityUsesNewTheme() throws Exception {
     50     ActivityController<TestActivityWithAnotherTheme> activityController = buildActivity(TestActivityWithAnotherTheme.class);
     51     TestActivity activity = activityController.get();
     52     activity.setTheme(R.style.Theme_Robolectric);
     53     activityController.create();
     54     Button theButton = (Button) activity.findViewById(R.id.button);
     55     ColorDrawable background = (ColorDrawable) theButton.getBackground();
     56     assertThat(background.getColor()).isEqualTo(0xff00ff00);
     57   }
     58 
     59   @Test public void whenSetOnActivityInManifest_activityGetsThemeFromActivityInManifest() throws Exception {
     60     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
     61     Button theButton = (Button) activity.findViewById(R.id.button);
     62     ColorDrawable background = (ColorDrawable) theButton.getBackground();
     63     assertThat(background.getColor()).isEqualTo(0xffff0000);
     64   }
     65 
     66   @Test public void whenNotSetOnActivityInManifest_activityGetsThemeFromApplicationInManifest() throws Exception {
     67     TestActivity activity = buildActivity(TestActivity.class).create().get();
     68     Button theButton = (Button) activity.findViewById(R.id.button);
     69     ColorDrawable background = (ColorDrawable) theButton.getBackground();
     70     assertThat(background.getColor()).isEqualTo(0xff00ff00);
     71   }
     72 
     73   @Test public void shouldResolveReferencesThatStartWithAQuestionMark() throws Exception {
     74     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
     75     Button theButton = (Button) activity.findViewById(R.id.button);
     76     assertThat(theButton.getMinWidth()).isEqualTo(8);
     77     assertThat(theButton.getMinHeight()).isEqualTo(8);
     78   }
     79 
     80   @Test public void shouldLookUpStylesFromStyleResId() throws Exception {
     81     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
     82     TypedArray a = activity.obtainStyledAttributes(null, R.styleable.CustomView, 0, R.style.MyCustomView);
     83     boolean enabled = a.getBoolean(R.styleable.CustomView_aspectRatioEnabled, false);
     84     assertThat(enabled).isTrue();
     85   }
     86 
     87   @Test public void shouldApplyStylesFromResourceReference() throws Exception {
     88     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
     89     TypedArray a = activity.obtainStyledAttributes(null, R.styleable.CustomView, 0, R.attr.animalStyle);
     90     int animalStyleId = a.getResourceId(R.styleable.CustomView_animalStyle, 0);
     91     assertThat(animalStyleId).isEqualTo(R.style.Gastropod);
     92     assertThat(a.getFloat(R.styleable.CustomView_aspectRatio, 0.2f)).isEqualTo(1.69f);
     93   }
     94 
     95   @Test public void shouldApplyStylesFromAttributeReference() throws Exception {
     96     TestActivity activity = buildActivity(TestActivityWithAThirdTheme.class).create().get();
     97     TypedArray a = activity.obtainStyledAttributes(null, R.styleable.CustomView, 0, R.attr.animalStyle);
     98     int animalStyleId = a.getResourceId(R.styleable.CustomView_animalStyle, 0);
     99     assertThat(animalStyleId).isEqualTo(R.style.Gastropod);
    100     assertThat(a.getFloat(R.styleable.CustomView_aspectRatio, 0.2f)).isEqualTo(1.69f);
    101   }
    102 
    103   @Test public void obtainStyledAttributes_findsAttributeValueDefinedInDependencyLibrary() throws Exception {
    104     TestActivity activity = buildActivity(TestActivityWithAThirdTheme.class).create().get();
    105 
    106     TypedArray a  = activity.getTheme().obtainStyledAttributes(new int[]{org.robolectric.R.attr.attrFromLib1});
    107     assertThat(a.getString(0)).isEqualTo("value from theme");
    108   }
    109 
    110   @Test public void shouldGetValuesFromAttributeReference() throws Exception {
    111     TestActivity activity = buildActivity(TestActivityWithAThirdTheme.class).create().get();
    112 
    113     TypedValue value1 = new TypedValue();
    114     TypedValue value2 = new TypedValue();
    115     boolean resolved1 = activity.getTheme().resolveAttribute(R.attr.someLayoutOne, value1, true);
    116     boolean resolved2 = activity.getTheme().resolveAttribute(R.attr.someLayoutTwo, value2, true);
    117 
    118     assertThat(resolved1).isTrue();
    119     assertThat(resolved2).isTrue();
    120     assertThat(value1.resourceId).isEqualTo(R.layout.activity_main);
    121     assertThat(value2.resourceId).isEqualTo(R.layout.activity_main);
    122     assertThat(value1.coerceToString()).isEqualTo(value2.coerceToString());
    123   }
    124 
    125   @Test public void withResolveRefsFalse_shouldResolveValue() throws Exception {
    126     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
    127 
    128     TypedValue value = new TypedValue();
    129     boolean resolved = activity.getTheme().resolveAttribute(R.attr.logoWidth, value, false);
    130 
    131     assertThat(resolved).isTrue();
    132     assertThat(value.type).isEqualTo(TypedValue.TYPE_REFERENCE);
    133     assertThat(value.data).isEqualTo(R.dimen.test_dp_dimen);
    134   }
    135 
    136   @Test public void withResolveRefsFalse_shouldNotResolveResource() throws Exception {
    137     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
    138 
    139     TypedValue value = new TypedValue();
    140     boolean resolved = activity.getTheme().resolveAttribute(R.attr.logoHeight, value, false);
    141 
    142     assertThat(resolved).isTrue();
    143     assertThat(value.type).isEqualTo(TypedValue.TYPE_REFERENCE);
    144     assertThat(value.data).isEqualTo(R.dimen.test_dp_dimen);
    145   }
    146 
    147   @Test public void withResolveRefsTrue_shouldResolveResource() throws Exception {
    148     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
    149 
    150     TypedValue value = new TypedValue();
    151     boolean resolved = activity.getTheme().resolveAttribute(R.attr.logoHeight, value, true);
    152 
    153     assertThat(resolved).isTrue();
    154     assertThat(value.type).isEqualTo(TypedValue.TYPE_DIMENSION);
    155     assertThat(value.resourceId).isEqualTo(R.dimen.test_dp_dimen);
    156     assertThat(value.coerceToString()).isEqualTo("8.0dip");
    157   }
    158 
    159   @Test public void failToResolveCircularReference() throws Exception {
    160     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
    161 
    162     TypedValue value = new TypedValue();
    163     boolean resolved = activity.getTheme().resolveAttribute(R.attr.isSugary, value, false);
    164 
    165     assertThat(resolved).isFalse();
    166   }
    167 
    168   @Test public void canResolveAttrReferenceToDifferentPackage() throws Exception {
    169     TestActivity activity = buildActivity(TestActivityWithAnotherTheme.class).create().get();
    170 
    171     TypedValue value = new TypedValue();
    172     boolean resolved = activity.getTheme().resolveAttribute(R.attr.styleReference, value, false);
    173 
    174     assertThat(resolved).isTrue();
    175     assertThat(value.type).isEqualTo(TypedValue.TYPE_REFERENCE);
    176     assertThat(value.data).isEqualTo(R.style.Widget_AnotherTheme_Button);
    177   }
    178 
    179   @Test public void forStylesWithImplicitParents_shouldInheritValuesNotDefinedInChild() throws Exception {
    180     Resources.Theme theme = resources.newTheme();
    181     theme.applyStyle(R.style.Theme_Robolectric_ImplicitChild, true);
    182     assertThat(theme.obtainStyledAttributes(new int[] {R.attr.string1}).getString(0))
    183         .isEqualTo("string 1 from Theme.Robolectric");
    184     assertThat(theme.obtainStyledAttributes(new int[] {R.attr.string3}).getString(0))
    185         .isEqualTo("string 3 from Theme.Robolectric.ImplicitChild");
    186   }
    187 
    188   @Test public void whenAThemeHasExplicitlyEmptyParentAttr_shouldHaveNoParent() throws Exception {
    189     Resources.Theme theme = resources.newTheme();
    190     theme.applyStyle(R.style.Theme_Robolectric_EmptyParent, true);
    191     assertThat(theme.obtainStyledAttributes(new int[] {R.attr.string1}).hasValue(0)).isFalse();
    192   }
    193 
    194   @Test public void shouldApplyParentStylesFromAttrs() throws Exception {
    195     Resources.Theme theme = resources.newTheme();
    196     theme.applyStyle(R.style.Theme_AnotherTheme, true);
    197     assertThat(theme.obtainStyledAttributes(new int[] {R.attr.string1}).getString(0))
    198         .isEqualTo("string 1 from Theme.AnotherTheme");
    199     assertThat(theme.obtainStyledAttributes(new int[] {R.attr.string3}).getString(0))
    200         .isEqualTo("string 3 from Theme.Robolectric");
    201   }
    202 
    203   @Test
    204   public void setTo_shouldCopyAllAttributesToEmptyTheme() throws Exception {
    205     Resources.Theme theme1 = resources.newTheme();
    206     theme1.applyStyle(R.style.Theme_Robolectric, false);
    207     assertThat(theme1.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    208         .isEqualTo("string 1 from Theme.Robolectric");
    209 
    210     Resources.Theme theme2 = resources.newTheme();
    211     theme2.setTo(theme1);
    212 
    213     assertThat(theme2.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    214         .isEqualTo("string 1 from Theme.Robolectric");
    215   }
    216 
    217   @Test
    218   public void setTo_whenDestThemeIsModified_sourceThemeShouldNotMutate() throws Exception {
    219     Resources.Theme sourceTheme = resources.newTheme();
    220     sourceTheme.applyStyle(R.style.Theme_Robolectric, false);
    221     assertThat(sourceTheme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    222         .isEqualTo("string 1 from Theme.Robolectric");
    223 
    224     Resources.Theme destTheme = resources.newTheme();
    225     destTheme.setTo(sourceTheme);
    226     destTheme.applyStyle(R.style.Theme_AnotherTheme, true);
    227 
    228     assertThat(sourceTheme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    229         .isEqualTo("string 1 from Theme.Robolectric");
    230   }
    231 
    232   @Test
    233   public void setTo_whenSourceThemeIsModified_destThemeShouldNotMutate() throws Exception {
    234     Resources.Theme sourceTheme = resources.newTheme();
    235     sourceTheme.applyStyle(R.style.Theme_Robolectric, false);
    236     assertThat(sourceTheme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    237         .isEqualTo("string 1 from Theme.Robolectric");
    238 
    239     Resources.Theme destTheme = resources.newTheme();
    240     destTheme.setTo(sourceTheme);
    241     sourceTheme.applyStyle(R.style.Theme_AnotherTheme, true);
    242 
    243     assertThat(destTheme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    244         .isEqualTo("string 1 from Theme.Robolectric");
    245   }
    246 
    247   @Test
    248   public void applyStyle_withForceFalse_shouldApplyButNotOverwriteExistingAttributeValues() throws Exception {
    249     Resources.Theme theme = resources.newTheme();
    250     theme.applyStyle(R.style.Theme_Robolectric, false);
    251     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    252         .isEqualTo("string 1 from Theme.Robolectric");
    253 
    254     theme.applyStyle(R.style.Theme_AnotherTheme, false);
    255     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    256         .isEqualTo("string 1 from Theme.Robolectric");
    257     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string2}).getString(0))
    258         .isEqualTo("string 2 from Theme.AnotherTheme");
    259   }
    260 
    261   @Test
    262   public void applyStyle_withForceTrue_shouldApplyAndOverwriteExistingAttributeValues() throws Exception {
    263     Resources.Theme theme = resources.newTheme();
    264     theme.applyStyle(R.style.Theme_Robolectric, false);
    265     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    266         .isEqualTo("string 1 from Theme.Robolectric");
    267 
    268     theme.applyStyle(R.style.Theme_AnotherTheme, true);
    269     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    270         .isEqualTo("string 1 from Theme.AnotherTheme");
    271 
    272     // force apply the original theme; values should be overwritten
    273     theme.applyStyle(R.style.Theme_Robolectric, true);
    274     assertThat(theme.obtainStyledAttributes(new int[]{R.attr.string1}).getString(0))
    275         .isEqualTo("string 1 from Theme.Robolectric");
    276   }
    277 
    278   @Test
    279   public void whenStyleSpecifiesAttr_obtainStyledAttribute_findsCorrectValue() throws Exception {
    280     Resources.Theme theme = resources.newTheme();
    281     theme.applyStyle(R.style.Theme_Robolectric, false);
    282     theme.applyStyle(R.style.Theme_ThemeContainingStyleReferences, true);
    283 
    284     assertThat(theme.obtainStyledAttributes(
    285         Robolectric.buildAttributeSet().setStyleAttribute("?attr/styleReference").build(), new int[]{R.attr.string2}, 0, 0).getString(0))
    286         .isEqualTo("string 2 from StyleReferredToByParentAttrReference");
    287 
    288     assertThat(theme.obtainStyledAttributes(
    289         Robolectric.buildAttributeSet().setStyleAttribute("?styleReference").build(), new int[]{R.attr.string2}, 0, 0).getString(0))
    290         .isEqualTo("string 2 from StyleReferredToByParentAttrReference");
    291   }
    292 
    293   @Test
    294   public void whenStyleSpecifiesAttrWithoutExplicitType_obtainStyledAttribute_findsCorrectValue() throws Exception {
    295     Resources.Theme theme = resources.newTheme();
    296     theme.applyStyle(R.style.Theme_Robolectric, false);
    297     theme.applyStyle(R.style.Theme_ThemeContainingStyleReferences, true);
    298 
    299     assertThat(theme.obtainStyledAttributes(
    300         Robolectric.buildAttributeSet().setStyleAttribute("?attr/styleReferenceWithoutExplicitType").build(), new int[]{R.attr.string2}, 0, 0).getString(0))
    301         .isEqualTo("string 2 from StyleReferredToByParentAttrReference");
    302 
    303     assertThat(theme.obtainStyledAttributes(
    304         Robolectric.buildAttributeSet().setStyleAttribute("?styleReferenceWithoutExplicitType").build(), new int[]{R.attr.string2}, 0, 0).getString(0))
    305         .isEqualTo("string 2 from StyleReferredToByParentAttrReference");
    306   }
    307 
    308   @Test
    309   public void whenAttrSetAttrSpecifiesAttr_obtainStyledAttribute_returnsItsValue() throws Exception {
    310     Resources.Theme theme = resources.newTheme();
    311     theme.applyStyle(R.style.Theme_Robolectric, false);
    312     theme.applyStyle(R.style.Theme_ThemeContainingStyleReferences, true);
    313 
    314     assertThat(theme.obtainStyledAttributes(
    315         Robolectric.buildAttributeSet().addAttribute(R.attr.string2, "?attr/string1").build(), new int[]{R.attr.string2}, 0, 0).getString(0))
    316         .isEqualTo("string 1 from Theme.Robolectric");
    317   }
    318 
    319   @Test
    320   public void whenAttrSetAttrSpecifiesUnknownAttr_obtainStyledAttribute_usesNull() throws Exception {
    321     Resources.Theme theme = resources.newTheme();
    322     theme.applyStyle(R.style.Theme_Robolectric, false);
    323     theme.applyStyle(R.style.Theme_ThemeContainingStyleReferences, true);
    324 
    325     assertThat(theme.obtainStyledAttributes(
    326         Robolectric.buildAttributeSet().addAttribute(R.attr.string2, "?attr/noSuchAttr").build(),
    327         new int[]{R.attr.string2}, 0, 0).getString(0))
    328         .isNull();
    329 
    330     // todo: assert that a strict warning was displayed
    331   }
    332 
    333   @Test
    334   public void forStrict_whenAttrSetAttrSpecifiesUnknownAttr_obtainStyledAttribute_throwsException() throws Exception {
    335     shadowOf(resources.getAssets()).strictErrors = true;
    336 
    337     Resources.Theme theme = resources.newTheme();
    338     theme.applyStyle(R.style.Theme_Robolectric, false);
    339     theme.applyStyle(R.style.Theme_ThemeContainingStyleReferences, true);
    340 
    341     try {
    342       theme.obtainStyledAttributes(
    343           Robolectric.buildAttributeSet().addAttribute(R.attr.string2, "?attr/noSuchAttr").build(),
    344           new int[]{R.attr.string2}, 0, 0);
    345       fail();
    346     } catch (Exception e) {
    347       assertThat(e.getMessage()).contains("no such attr ?org.robolectric:attr/noSuchAttr");
    348       assertThat(e.getMessage()).contains("Theme_ThemeContainingStyleReferences");
    349       assertThat(e.getMessage()).contains("Theme_Robolectric");
    350       assertThat(e.getMessage()).contains("while resolving value for org.robolectric:attr/string2");
    351     }
    352   }
    353 
    354   @Test
    355   public void shouldFindInheritedAndroidAttributeInTheme() throws Exception {
    356     RuntimeEnvironment.application.setTheme(R.style.Theme_AnotherTheme);
    357     Resources.Theme theme1 = RuntimeEnvironment.application.getTheme();
    358 
    359 //    Resources.Theme theme1 = resources.newTheme();
    360 //    theme1.setTo(RuntimeEnvironment.application.getTheme());
    361 //    theme1.applyStyle(R.style.Theme_AnotherTheme, false);
    362 
    363     TypedArray typedArray = theme1.obtainStyledAttributes(
    364         new int[]{R.attr.typeface, android.R.attr.buttonStyle});
    365     assertThat(typedArray.hasValue(0)).isTrue(); // animalStyle
    366     assertThat(typedArray.hasValue(1)).isTrue(); // layout_height
    367   }
    368 
    369   public static class TestActivity extends Activity {
    370     @Override protected void onCreate(Bundle savedInstanceState) {
    371       super.onCreate(savedInstanceState);
    372       setContentView(R.layout.styles_button_layout);
    373     }
    374   }
    375 
    376   @Test
    377   public void themesShouldBeApplyableAcrossResources() throws Exception {
    378     Resources.Theme themeFromSystem = Resources.getSystem().newTheme();
    379     themeFromSystem.applyStyle(android.R.style.Theme_Light, true);
    380 
    381     Resources.Theme themeFromApp = RuntimeEnvironment.application.getResources().newTheme();
    382     themeFromApp.applyStyle(android.R.style.Theme, true);
    383 
    384     // themeFromSystem is Theme_Light, which has a white background...
    385     assertThat(shadowOf(themeFromSystem).obtainStyledAttributes(new int[]{android.R.attr.colorBackground}).getColor(0, 123))
    386         .isEqualTo(Color.WHITE);
    387 
    388     // themeFromApp is Theme, which has a black background...
    389     assertThat(shadowOf(themeFromApp).obtainStyledAttributes(new int[]{android.R.attr.colorBackground}).getColor(0, 123))
    390         .isEqualTo(Color.BLACK);
    391 
    392     themeFromApp.setTo(themeFromSystem);
    393 
    394     // themeFromApp now has style values from themeFromSystem, so now it has a black background...
    395     assertThat(shadowOf(themeFromApp).obtainStyledAttributes(new int[]{android.R.attr.colorBackground}).getColor(0, 123))
    396         .isEqualTo(Color.WHITE);
    397   }
    398 
    399   @Test
    400   public void styleResolutionShouldIgnoreThemes() throws Exception {
    401     Resources.Theme themeFromSystem = resources.newTheme();
    402     themeFromSystem.applyStyle(android.R.style.Theme_DeviceDefault, true);
    403     themeFromSystem.applyStyle(R.style.ThemeWithSelfReferencingTextAttr, true);
    404     assertThat(themeFromSystem.obtainStyledAttributes(new int[]{android.R.attr.textAppearance})
    405         .getResourceId(0, 0)).isEqualTo(0);
    406   }
    407 
    408   @Test
    409   public void dimenRef() throws Exception {
    410     AttributeSet attributeSet = Robolectric.buildAttributeSet()
    411         .addAttribute(android.R.attr.layout_height, "@dimen/test_px_dimen")
    412         .build();
    413     TypedArray typedArray = resources.newTheme().obtainStyledAttributes(
    414         attributeSet, new int[]{android.R.attr.layout_height}, 0, 0);
    415     assertThat(typedArray.getDimensionPixelSize(0, -1)).isEqualTo(15);
    416   }
    417 
    418   @Test
    419   public void dimenRefRef() throws Exception {
    420     AttributeSet attributeSet = Robolectric.buildAttributeSet()
    421         .addAttribute(android.R.attr.layout_height, "@dimen/ref_to_px_dimen")
    422         .build();
    423     TypedArray typedArray = resources.newTheme().obtainStyledAttributes(
    424         attributeSet, new int[]{android.R.attr.layout_height}, 0, 0);
    425     assertThat(typedArray.getDimensionPixelSize(0, -1)).isEqualTo(15);
    426   }
    427 
    428   public static class TestActivityWithAnotherTheme extends TestActivity {
    429   }
    430 
    431   public static class TestActivityWithAThirdTheme extends TestActivity {
    432   }
    433 
    434   @Test public void shouldApplyFromStyleAttribute() throws Exception {
    435     TestWithStyleAttrActivity activity = buildActivity(TestWithStyleAttrActivity.class).create().get();
    436     View button = activity.findViewById(R.id.button);
    437     assertThat(button.getLayoutParams().width).isEqualTo(42); // comes via style attr
    438   }
    439 
    440   public static class TestWithStyleAttrActivity extends Activity {
    441     @Override protected void onCreate(Bundle savedInstanceState) {
    442       super.onCreate(savedInstanceState);
    443       setContentView(R.layout.styles_button_with_style_layout);
    444     }
    445   }
    446 }
    447