Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.graphics.drawable.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertSame;
     22 import static org.junit.Assert.assertTrue;
     23 import static org.mockito.Matchers.any;
     24 import static org.mockito.Matchers.anyBoolean;
     25 import static org.mockito.Matchers.anyInt;
     26 import static org.mockito.Matchers.anyLong;
     27 import static org.mockito.Mockito.doNothing;
     28 import static org.mockito.Mockito.mock;
     29 import static org.mockito.Mockito.never;
     30 import static org.mockito.Mockito.reset;
     31 import static org.mockito.Mockito.spy;
     32 import static org.mockito.Mockito.times;
     33 import static org.mockito.Mockito.verify;
     34 
     35 import android.graphics.Canvas;
     36 import android.graphics.Color;
     37 import android.graphics.ColorFilter;
     38 import android.graphics.PixelFormat;
     39 import android.graphics.PorterDuff;
     40 import android.graphics.PorterDuffColorFilter;
     41 import android.graphics.Rect;
     42 import android.graphics.cts.R;
     43 import android.graphics.drawable.BitmapDrawable;
     44 import android.graphics.drawable.ColorDrawable;
     45 import android.graphics.drawable.Drawable;
     46 import android.graphics.drawable.DrawableWrapper;
     47 import android.support.test.InstrumentationRegistry;
     48 import android.support.test.filters.SmallTest;
     49 import android.support.test.runner.AndroidJUnit4;
     50 import android.util.StateSet;
     51 
     52 import org.junit.Test;
     53 import org.junit.runner.RunWith;
     54 
     55 import java.util.Arrays;
     56 
     57 @SmallTest
     58 @RunWith(AndroidJUnit4.class)
     59 public class DrawableWrapperTest {
     60     static class MyWrapper extends DrawableWrapper {
     61         public MyWrapper(Drawable dr) {
     62             super(dr);
     63         }
     64     }
     65 
     66     @SuppressWarnings("deprecation")
     67     @Test
     68     public void testConstructor() {
     69         Drawable d = new BitmapDrawable();
     70         DrawableWrapper wrapper = new MyWrapper(d);
     71         assertSame(d, wrapper.getDrawable());
     72 
     73         new MyWrapper(null);
     74     }
     75 
     76     @SuppressWarnings("deprecation")
     77     @Test
     78     public void testGetDrawable() {
     79         Drawable d = new BitmapDrawable();
     80         DrawableWrapper wrapper = new MyWrapper(d);
     81         assertSame(d, wrapper.getDrawable());
     82     }
     83 
     84     @SuppressWarnings("deprecation")
     85     @Test
     86     public void testSetDrawable() {
     87         Drawable d = new BitmapDrawable();
     88         DrawableWrapper wrapper = new MyWrapper(null);
     89         assertSame(null, wrapper.getDrawable());
     90 
     91         wrapper.setDrawable(d);
     92         assertSame(d, wrapper.getDrawable());
     93     }
     94 
     95     @SuppressWarnings("deprecation")
     96     @Test
     97     public void testInvalidateDrawable() {
     98         DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
     99 
    100         Drawable.Callback cb = mock(Drawable.Callback.class);
    101         wrapper.setCallback(cb);
    102         wrapper.invalidateDrawable(null);
    103         verify(cb, times(1)).invalidateDrawable(any());
    104 
    105         reset(cb);
    106         wrapper.invalidateDrawable(new BitmapDrawable());
    107         verify(cb, times(1)).invalidateDrawable(any());
    108 
    109         reset(cb);
    110         wrapper.setCallback(null);
    111         wrapper.invalidateDrawable(null);
    112         verify(cb, never()).invalidateDrawable(any());
    113     }
    114 
    115     @SuppressWarnings("deprecation")
    116     @Test
    117     public void testScheduleDrawable() {
    118         DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
    119 
    120         Drawable.Callback cb = mock(Drawable.Callback.class);
    121         wrapper.setCallback(cb);
    122         wrapper.scheduleDrawable(null, null, 0);
    123         verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());
    124 
    125         reset(cb);
    126         wrapper.scheduleDrawable(new BitmapDrawable(), () -> {}, 1000L);
    127         verify(cb, times(1)).scheduleDrawable(any(), any(), anyLong());
    128 
    129         reset(cb);
    130         wrapper.setCallback(null);
    131         wrapper.scheduleDrawable(null, null, 0);
    132         verify(cb, never()).scheduleDrawable(any(), any(), anyLong());
    133     }
    134 
    135     @SuppressWarnings("deprecation")
    136     @Test
    137     public void testUnscheduleDrawable() {
    138         DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
    139 
    140         Drawable.Callback cb = mock(Drawable.Callback.class);
    141         wrapper.setCallback(cb);
    142         wrapper.unscheduleDrawable(null, null);
    143         verify(cb, times(1)).unscheduleDrawable(any(), any());
    144 
    145         reset(cb);
    146         wrapper.unscheduleDrawable(new BitmapDrawable(), () -> {});
    147         verify(cb, times(1)).unscheduleDrawable(any(), any());
    148 
    149         reset(cb);
    150         wrapper.setCallback(null);
    151         wrapper.unscheduleDrawable(null, null);
    152         verify(cb, never()).unscheduleDrawable(any(), any());
    153     }
    154 
    155     @Test
    156     public void testDraw() {
    157         Drawable mockDrawable = spy(new ColorDrawable(Color.BLUE));
    158         doNothing().when(mockDrawable).draw(any());
    159         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    160 
    161         wrapper.draw(new Canvas());
    162         verify(mockDrawable, times(1)).draw(any());
    163 
    164         reset(mockDrawable);
    165         doNothing().when(mockDrawable).draw(any());
    166         wrapper.draw(null);
    167         verify(mockDrawable, times(1)).draw(any());
    168     }
    169 
    170     @Test
    171     public void testGetChangingConfigurations() {
    172         final int SUPER_CONFIG = 1;
    173         final int CONTAINED_DRAWABLE_CONFIG = 2;
    174 
    175         MockDrawable mockDrawable = new MockDrawable();
    176         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    177 
    178         assertEquals(0, wrapper.getChangingConfigurations());
    179 
    180         mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
    181         assertEquals(CONTAINED_DRAWABLE_CONFIG, wrapper.getChangingConfigurations());
    182 
    183         wrapper.setChangingConfigurations(SUPER_CONFIG);
    184         assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
    185                 wrapper.getChangingConfigurations());
    186     }
    187 
    188     @Test
    189     public void testGetPadding() {
    190         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    191         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    192 
    193         // this method will call contained drawable's getPadding method.
    194         wrapper.getPadding(new Rect());
    195         verify(mockDrawable, times(1)).getPadding(any());
    196     }
    197 
    198     @Test
    199     public void testColorFilter() {
    200         Drawable wrappedDrawable = new MockDrawable();
    201         DrawableWrapper wrapper = new MyWrapper(wrappedDrawable);
    202         PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(Color.BLUE,
    203                 PorterDuff.Mode.SRC_OVER);
    204         wrapper.setColorFilter(colorFilter);
    205         ColorFilter obtainedColorFilter = wrapper.getColorFilter();
    206         assertEquals("Color filters are not properly returned", colorFilter, obtainedColorFilter);
    207     }
    208 
    209     @Test(expected=NullPointerException.class)
    210     public void testGetPaddingNull() {
    211         DrawableWrapper wrapper = new MyWrapper(new ColorDrawable(Color.RED));
    212 
    213         wrapper.getPadding(null);
    214     }
    215 
    216     @Test
    217     public void testSetVisible() {
    218         Drawable mockDrawable = spy(new ColorDrawable(Color.YELLOW));
    219         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    220         assertTrue(wrapper.isVisible());
    221 
    222         assertTrue(wrapper.setVisible(false, false));
    223         assertFalse(wrapper.isVisible());
    224         verify(mockDrawable, times(1)).setVisible(anyBoolean(), anyBoolean());
    225 
    226         reset(mockDrawable);
    227         assertFalse(wrapper.setVisible(false, false));
    228         assertFalse(wrapper.isVisible());
    229         verify(mockDrawable, times(1)).setVisible(anyBoolean(), anyBoolean());
    230 
    231         reset(mockDrawable);
    232         assertTrue(wrapper.setVisible(true, false));
    233         assertTrue(wrapper.isVisible());
    234         verify(mockDrawable, times(1)).setVisible(anyBoolean(), anyBoolean());
    235     }
    236 
    237     @Test
    238     public void testSetAlpha() {
    239         Drawable mockDrawable = spy(new ColorDrawable(Color.MAGENTA));
    240         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    241 
    242         // this method will call contained drawable's setAlpha method.
    243         wrapper.setAlpha(100);
    244         verify(mockDrawable, times(1)).setAlpha(anyInt());
    245 
    246         reset(mockDrawable);
    247         wrapper.setAlpha(Integer.MAX_VALUE);
    248         verify(mockDrawable, times(1)).setAlpha(anyInt());
    249 
    250         reset(mockDrawable);
    251         wrapper.setAlpha(-1);
    252         verify(mockDrawable, times(1)).setAlpha(anyInt());
    253     }
    254 
    255     @Test
    256     public void testSetColorFilter() {
    257         Drawable mockDrawable = spy(new ColorDrawable(Color.GRAY));
    258         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    259 
    260         // this method will call contained drawable's setColorFilter method.
    261         wrapper.setColorFilter(new ColorFilter());
    262         verify(mockDrawable, times(1)).setColorFilter(any());
    263 
    264         reset(mockDrawable);
    265         wrapper.setColorFilter(null);
    266         verify(mockDrawable, times(1)).setColorFilter(any());
    267     }
    268 
    269     @Test
    270     public void testGetOpacity() {
    271         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    272         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    273 
    274         // This method will call contained drawable's getOpacity method.
    275         wrapper.setLevel(1);
    276         wrapper.getOpacity();
    277         verify(mockDrawable, times(1)).getOpacity();
    278     }
    279 
    280     @Test
    281     public void testIsStateful() {
    282         Drawable mockDrawable = spy(new ColorDrawable(Color.BLACK));
    283         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    284 
    285         // this method will call contained drawable's isStateful method.
    286         wrapper.isStateful();
    287         verify(mockDrawable, times(1)).isStateful();
    288     }
    289 
    290     @Test
    291     public void testOnStateChange() {
    292         Drawable d = new MockDrawable();
    293         MockDrawableWrapper wrapper = new MockDrawableWrapper(d);
    294         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
    295 
    296         int[] state = new int[] {1, 2, 3};
    297         assertFalse("child did not change", wrapper.onStateChange(state));
    298         assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
    299 
    300         d = InstrumentationRegistry.getTargetContext().getDrawable(R.drawable.statelistdrawable);
    301         wrapper = new MockDrawableWrapper(d);
    302         assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
    303         wrapper.onStateChange(state);
    304         assertTrue("child state changed", Arrays.equals(state, d.getState()));
    305 
    306         // input null as param
    307         wrapper.onStateChange(null);
    308         // expected, no Exception thrown out, test success
    309     }
    310 
    311     @Test
    312     public void testOnLevelChange() {
    313         MockDrawable mockDrawable = new MockDrawable();
    314         MockDrawableWrapper mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
    315 
    316         assertEquals(0, mockDrawable.getLevel());
    317         assertFalse(mockDrawableWrapper.onLevelChange(0));
    318         assertFalse(mockDrawable.hasCalledOnLevelChange());
    319 
    320         assertFalse(mockDrawableWrapper.onLevelChange(1000));
    321         assertTrue(mockDrawable.hasCalledOnLevelChange());
    322         assertEquals(1000, mockDrawable.getLevel());
    323 
    324         mockDrawable.reset();
    325         assertFalse(mockDrawableWrapper.onLevelChange(Integer.MIN_VALUE));
    326         assertTrue(mockDrawable.hasCalledOnLevelChange());
    327     }
    328 
    329     @Test
    330     public void testOnBoundsChange() {
    331         MockDrawable mockDrawable = new MockDrawable();
    332         MockDrawableWrapper mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
    333         Rect bounds = new Rect(2, 2, 26, 32);
    334         mockDrawable.setBounds(bounds);
    335         mockDrawableWrapper.onBoundsChange(bounds);
    336 
    337         mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
    338         mockDrawable.setBounds(bounds);
    339         mockDrawableWrapper.onBoundsChange(bounds);
    340         assertEquals(bounds.left, mockDrawable.getBounds().left);
    341         assertEquals(bounds.top, mockDrawable.getBounds().top);
    342         assertEquals(bounds.right, mockDrawable.getBounds().right);
    343         assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);
    344 
    345         bounds = mockDrawable.getBounds();
    346         assertEquals(2, bounds.left);
    347         assertEquals(2, bounds.top);
    348         assertEquals(26, bounds.right);
    349         assertEquals(32, bounds.bottom);
    350     }
    351 
    352     @Test(expected=NullPointerException.class)
    353     public void testOnBoundsChangeNull() {
    354         MockDrawable mockDrawable = new MockDrawable();
    355         MockDrawableWrapper mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
    356 
    357         mockDrawableWrapper.onBoundsChange(null);
    358     }
    359 
    360     @Test
    361     public void testGetIntrinsicWidth() {
    362         Drawable mockDrawable = spy(new ColorDrawable(Color.WHITE));
    363         MyWrapper wrapper = new MyWrapper(mockDrawable);
    364 
    365         // this method will call contained drawable's getIntrinsicWidth method.
    366         wrapper.getIntrinsicWidth();
    367         verify(mockDrawable, times(1)).getIntrinsicWidth();
    368     }
    369 
    370     @Test
    371     public void testGetIntrinsicHeight() {
    372         Drawable mockDrawable = spy(new ColorDrawable(Color.RED));
    373         DrawableWrapper wrapper = new MyWrapper(mockDrawable);
    374 
    375         // this method will call contained drawable's getIntrinsicHeight method.
    376         wrapper.getIntrinsicHeight();
    377         verify(mockDrawable, times(1)).getIntrinsicHeight();
    378     }
    379 
    380     @SuppressWarnings("deprecation")
    381     @Test
    382     public void testGetConstantState() {
    383         DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
    384         wrapper.getConstantState();
    385     }
    386 
    387     // Since Mockito can't mock or spy on protected methods, we have a custom extension
    388     // of Drawable to track calls to protected methods. This class also has empty implementations
    389     // of the base abstract methods.
    390     private static class MockDrawable extends Drawable {
    391         private boolean mCalledOnLevelChange = false;
    392         private ColorFilter mColorFilter;
    393 
    394         @Override
    395         public void draw(Canvas canvas) {
    396         }
    397 
    398         @Override
    399         public int getOpacity() {
    400             return PixelFormat.OPAQUE;
    401         }
    402 
    403         @Override
    404         public void setAlpha(int alpha) {
    405         }
    406 
    407         @Override
    408         public void setColorFilter(ColorFilter cf) {
    409             mColorFilter = cf;
    410         }
    411 
    412         @Override
    413         public ColorFilter getColorFilter() {
    414             return mColorFilter;
    415         }
    416 
    417         @Override
    418         protected boolean onLevelChange(int level) {
    419             mCalledOnLevelChange = true;
    420             return super.onLevelChange(level);
    421         }
    422 
    423         public boolean hasCalledOnLevelChange() {
    424             return mCalledOnLevelChange;
    425         }
    426 
    427         public void reset() {
    428             mCalledOnLevelChange = false;
    429         }
    430     }
    431 
    432     private static class MockDrawableWrapper extends DrawableWrapper {
    433         MockDrawableWrapper() {
    434             super(null);
    435         }
    436 
    437         public MockDrawableWrapper(Drawable drawable) {
    438             super(drawable);
    439         }
    440 
    441         @Override
    442         protected boolean onStateChange(int[] state) {
    443             return super.onStateChange(state);
    444         }
    445 
    446         @Override
    447         protected boolean onLevelChange(int level) {
    448             return super.onLevelChange(level);
    449         }
    450 
    451         @Override
    452         protected void onBoundsChange(Rect bounds) {
    453             super.onBoundsChange(bounds);
    454         }
    455     }
    456 }
    457