1/*
2 * Copyright (C) 2016 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
17package android.support.v4.graphics;
18
19import android.content.res.ColorStateList;
20import android.graphics.Color;
21import android.graphics.PorterDuff;
22import android.graphics.Rect;
23import android.graphics.drawable.Drawable;
24import android.graphics.drawable.GradientDrawable;
25import android.os.Build;
26import android.support.test.runner.AndroidJUnit4;
27import android.support.v4.graphics.drawable.DrawableCompat;
28import android.test.suitebuilder.annotation.SmallTest;
29import org.junit.Test;
30import org.junit.runner.RunWith;
31
32import static org.junit.Assert.*;
33import static org.mockito.Mockito.*;
34
35@RunWith(AndroidJUnit4.class)
36@SmallTest
37public class DrawableCompatTest {
38    @Test
39    public void testDrawableWrap() {
40        final Drawable original = new GradientDrawable();
41        final Drawable wrappedDrawable = DrawableCompat.wrap(original);
42
43        if (Build.VERSION.SDK_INT < 23) {
44            assertNotSame(original, wrappedDrawable);
45        } else {
46            assertSame(original, wrappedDrawable);
47        }
48    }
49
50    @Test
51    public void testDrawableUnwrap() {
52        final Drawable original = new GradientDrawable();
53        final Drawable wrappedDrawable = DrawableCompat.wrap(original);
54        assertSame(original, DrawableCompat.unwrap(wrappedDrawable));
55    }
56
57    @Test
58    public void testDrawableChangeBoundsCopy() {
59        final Rect bounds = new Rect(0, 0, 10, 10);
60
61        final Drawable drawable = new GradientDrawable();
62
63        final Drawable wrapper = DrawableCompat.wrap(drawable);
64        wrapper.setBounds(bounds);
65
66        // Assert that the bounds were given to the original drawable
67        assertEquals(bounds, drawable.getBounds());
68    }
69
70    @Test
71    public void testWrapCopiesDrawableState() {
72        final Rect bounds = new Rect(0, 0, 10, 10);
73
74        // Create a drawable and set some bounds
75        final Drawable drawable = new GradientDrawable();
76        drawable.setBounds(bounds);
77
78        // Now wrap it
79        final Drawable wrapper = DrawableCompat.wrap(drawable);
80
81        // Assert that the bounds were copied to the wrapper
82        assertEquals(bounds, wrapper.getBounds());
83    }
84
85    @Test
86    public void testDrawableWrapOnlyWrapsOnce() {
87        final Drawable wrappedDrawable = DrawableCompat.wrap(new GradientDrawable());
88        assertSame(wrappedDrawable, DrawableCompat.wrap(wrappedDrawable));
89    }
90
91    @Test
92    public void testWrapMutatedDrawableHasConstantState() {
93        // First create a Drawable, and mutated it so that it has a constant state
94        Drawable drawable = new GradientDrawable();
95        drawable = drawable.mutate();
96        assertNotNull(drawable.getConstantState());
97
98        // Now wrap and assert that the wrapper also returns a constant state
99        final Drawable wrapper = DrawableCompat.wrap(drawable);
100        assertNotNull(wrapper.getConstantState());
101    }
102
103    @Test
104    public void testWrappedDrawableHasCallbackSet() {
105        // First create a Drawable
106        final Drawable drawable = new GradientDrawable();
107
108        // Now wrap it and set a mock as the wrapper's callback
109        final Drawable wrapper = DrawableCompat.wrap(drawable);
110        final Drawable.Callback mockCallback = mock(Drawable.Callback.class);
111        wrapper.setCallback(mockCallback);
112
113        // Now make the wrapped drawable invalidate itself
114        drawable.invalidateSelf();
115
116        // ...and verify that the wrapper calls to be invalidated
117        verify(mockCallback, times(1)).invalidateDrawable(wrapper);
118    }
119
120    @Test
121    public void testDoesNotWrapTintAwareDrawable() {
122        final TestTintAwareDrawable tintAwareDrawable = new TestTintAwareDrawable();
123        final Drawable wrapped = DrawableCompat.wrap(tintAwareDrawable);
124        // Assert that the tint aware drawable was not wrapped
125        assertSame(tintAwareDrawable, wrapped);
126    }
127
128    @Test
129    public void testTintAwareDrawableGetsTintCallsDirectly() {
130        final TestTintAwareDrawable d = mock(TestTintAwareDrawable.class);
131
132        final ColorStateList tint = ColorStateList.valueOf(Color.BLACK);
133        final PorterDuff.Mode tintMode = PorterDuff.Mode.DST;
134
135        // Now set the tint list and mode using DrawableCompat
136        DrawableCompat.setTintList(d, tint);
137        DrawableCompat.setTintMode(d, tintMode);
138
139        // Verify that the calls were directly on to the TintAwareDrawable
140        verify(d).setTintList(tint);
141        verify(d).setTintMode(tintMode);
142    }
143
144}