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
17package android.support.v4.widget;
18
19import static android.support.test.espresso.Espresso.onView;
20import static android.support.test.espresso.matcher.ViewMatchers.withId;
21import static android.support.v4.testutils.LayoutDirectionActions.setLayoutDirection;
22import static android.support.v4.testutils.TextViewActions.setCompoundDrawablesRelative;
23import static android.support.v4.testutils.TextViewActions
24        .setCompoundDrawablesRelativeWithIntrinsicBounds;
25import static android.support.v4.testutils.TextViewActions.setMaxLines;
26import static android.support.v4.testutils.TextViewActions.setMinLines;
27import static android.support.v4.testutils.TextViewActions.setText;
28import static android.support.v4.testutils.TextViewActions.setTextAppearance;
29
30import static org.junit.Assert.assertEquals;
31import static org.junit.Assert.assertNull;
32import static org.junit.Assert.assertTrue;
33
34import android.content.res.Resources;
35import android.graphics.drawable.ColorDrawable;
36import android.graphics.drawable.Drawable;
37import android.support.annotation.ColorInt;
38import android.support.compat.test.R;
39import android.support.test.filters.SmallTest;
40import android.support.v4.BaseInstrumentationTestCase;
41import android.support.v4.testutils.TestUtils;
42import android.support.v4.view.ViewCompat;
43import android.widget.TextView;
44
45import org.junit.Before;
46import org.junit.Test;
47
48@SmallTest
49public class TextViewCompatTest extends BaseInstrumentationTestCase<TextViewTestActivity> {
50    private static final String TAG = "TextViewCompatTest";
51
52    private TextView mTextView;
53
54    private class TestDrawable extends ColorDrawable {
55        private int mWidth;
56        private int mHeight;
57
58        public TestDrawable(@ColorInt int color, int width, int height) {
59            super(color);
60            mWidth = width;
61            mHeight = height;
62        }
63
64        @Override
65        public int getIntrinsicWidth() {
66            return mWidth;
67        }
68
69        @Override
70        public int getIntrinsicHeight() {
71            return mHeight;
72        }
73    }
74
75    public TextViewCompatTest() {
76        super(TextViewTestActivity.class);
77    }
78
79    @Before
80    public void setUp() {
81        mTextView = (TextView) mActivityTestRule.getActivity().findViewById(R.id.text_view);
82    }
83
84    @Test
85    public void testMaxLines() throws Throwable {
86        final int maxLinesCount = 4;
87        onView(withId(R.id.text_view)).perform(setMaxLines(maxLinesCount));
88
89        assertEquals("Empty view: Max lines must match", TextViewCompat.getMaxLines(mTextView),
90                maxLinesCount);
91
92        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_short));
93        assertEquals("Short text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
94                maxLinesCount);
95
96        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
97        assertEquals("Medium text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
98                maxLinesCount);
99
100        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
101        assertEquals("Long text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
102                maxLinesCount);
103    }
104
105    @Test
106    public void testMinLines() throws Throwable {
107        final int minLinesCount = 3;
108        onView(withId(R.id.text_view)).perform(setMinLines(minLinesCount));
109
110        assertEquals("Empty view: Min lines must match", TextViewCompat.getMinLines(mTextView),
111                minLinesCount);
112
113        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_short));
114        assertEquals("Short text: Min lines must match", TextViewCompat.getMinLines(mTextView),
115                minLinesCount);
116
117        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
118        assertEquals("Medium text: Min lines must match", TextViewCompat.getMinLines(mTextView),
119                minLinesCount);
120
121        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
122        assertEquals("Long text: Min lines must match", TextViewCompat.getMinLines(mTextView),
123                minLinesCount);
124    }
125
126    @Test
127    public void testStyle() throws Throwable {
128        onView(withId(R.id.text_view)).perform(setTextAppearance(R.style.TextMediumStyle));
129
130        final Resources res = mActivityTestRule.getActivity().getResources();
131        assertTrue("Styled text view: style",
132                mTextView.getTypeface().isItalic() || (mTextView.getPaint().getTextSkewX() < 0));
133        assertEquals("Styled text view: color", mTextView.getTextColors().getDefaultColor(),
134                res.getColor(R.color.text_color));
135        assertEquals("Styled text view: size", mTextView.getTextSize(),
136                (float) res.getDimensionPixelSize(R.dimen.text_medium_size), 1.0f);
137    }
138
139    @Test
140    public void testCompoundDrawablesRelative() throws Throwable {
141        final Drawable drawableStart = new ColorDrawable(0xFFFF0000);
142        drawableStart.setBounds(0, 0, 20, 20);
143        final Drawable drawableTop = new ColorDrawable(0xFF00FF00);
144        drawableTop.setBounds(0, 0, 30, 25);
145        final Drawable drawableEnd = new ColorDrawable(0xFF0000FF);
146        drawableEnd.setBounds(0, 0, 25, 20);
147
148        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
149        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelative(drawableStart,
150                drawableTop, drawableEnd, null));
151
152        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
153
154        assertEquals("Compound drawable: left", drawablesAbsolute[0], drawableStart);
155        assertEquals("Compound drawable: left width",
156                drawablesAbsolute[0].getBounds().width(), 20);
157        assertEquals("Compound drawable: left height",
158                drawablesAbsolute[0].getBounds().height(), 20);
159
160        assertEquals("Compound drawable: top", drawablesAbsolute[1], drawableTop);
161        assertEquals("Compound drawable: top width",
162                drawablesAbsolute[1].getBounds().width(), 30);
163        assertEquals("Compound drawable: top height",
164                drawablesAbsolute[1].getBounds().height(), 25);
165
166        assertEquals("Compound drawable: right", drawablesAbsolute[2], drawableEnd);
167        assertEquals("Compound drawable: right width",
168                drawablesAbsolute[2].getBounds().width(), 25);
169        assertEquals("Compound drawable: right height",
170                drawablesAbsolute[2].getBounds().height(), 20);
171
172        assertNull("Compound drawable: bottom", drawablesAbsolute[3]);
173    }
174
175    @Test
176    public void testCompoundDrawablesRelativeRtl() throws Throwable {
177        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
178
179        final Drawable drawableStart = new ColorDrawable(0xFFFF0000);
180        drawableStart.setBounds(0, 0, 20, 20);
181        final Drawable drawableTop = new ColorDrawable(0xFF00FF00);
182        drawableTop.setBounds(0, 0, 30, 25);
183        final Drawable drawableEnd = new ColorDrawable(0xFF0000FF);
184        drawableEnd.setBounds(0, 0, 25, 20);
185
186        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
187        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelative(drawableStart,
188                drawableTop, drawableEnd, null));
189
190        // Check to see whether our text view is under RTL mode
191        if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
192            // This will happen on v17- devices
193            return;
194        }
195
196        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
197
198        // End drawable should be returned as left
199        assertEquals("Compound drawable: left", drawablesAbsolute[0], drawableEnd);
200        assertEquals("Compound drawable: left width",
201                drawablesAbsolute[0].getBounds().width(), 25);
202        assertEquals("Compound drawable: left height",
203                drawablesAbsolute[0].getBounds().height(), 20);
204
205        assertEquals("Compound drawable: top", drawablesAbsolute[1], drawableTop);
206        assertEquals("Compound drawable: left width",
207                drawablesAbsolute[1].getBounds().width(), 30);
208        assertEquals("Compound drawable: left height",
209                drawablesAbsolute[1].getBounds().height(), 25);
210
211        // Start drawable should be returned as right
212        assertEquals("Compound drawable: right", drawablesAbsolute[2], drawableStart);
213        assertEquals("Compound drawable: left width",
214                drawablesAbsolute[2].getBounds().width(), 20);
215        assertEquals("Compound drawable: left height",
216                drawablesAbsolute[2].getBounds().height(), 20);
217
218        assertNull("Compound drawable: bottom", drawablesAbsolute[3]);
219    }
220
221    @Test
222    public void testCompoundDrawablesRelativeWithIntrinsicBounds() throws Throwable {
223        final Drawable drawableStart = new TestDrawable(0xFFFF0000, 30, 20);
224        final Drawable drawableEnd = new TestDrawable(0xFF0000FF, 25, 45);
225        final Drawable drawableBottom = new TestDrawable(0xFF00FF00, 15, 35);
226
227        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
228        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
229                drawableStart, null, drawableEnd, drawableBottom));
230
231        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
232
233        assertEquals("Compound drawable: left", drawablesAbsolute[0], drawableStart);
234        assertEquals("Compound drawable: left width",
235                drawablesAbsolute[0].getBounds().width(), 30);
236        assertEquals("Compound drawable: left height",
237                drawablesAbsolute[0].getBounds().height(), 20);
238
239        assertNull("Compound drawable: top", drawablesAbsolute[1]);
240
241        assertEquals("Compound drawable: right", drawablesAbsolute[2], drawableEnd);
242        assertEquals("Compound drawable: right width",
243                drawablesAbsolute[2].getBounds().width(), 25);
244        assertEquals("Compound drawable: right height",
245                drawablesAbsolute[2].getBounds().height(), 45);
246
247        assertEquals("Compound drawable: bottom", drawablesAbsolute[3], drawableBottom);
248        assertEquals("Compound drawable: bottom width",
249                drawablesAbsolute[3].getBounds().width(), 15);
250        assertEquals("Compound drawable: bottom height",
251                drawablesAbsolute[3].getBounds().height(), 35);
252    }
253
254    @Test
255    public void testCompoundDrawablesRelativeWithIntrinsicBoundsRtl() throws Throwable {
256        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
257
258        final Drawable drawableStart = new TestDrawable(0xFFFF0000, 30, 20);
259        final Drawable drawableEnd = new TestDrawable(0xFF0000FF, 25, 45);
260        final Drawable drawableBottom = new TestDrawable(0xFF00FF00, 15, 35);
261
262        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
263        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
264                drawableStart, null, drawableEnd, drawableBottom));
265
266        // Check to see whether our text view is under RTL mode
267        if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
268            // This will happen on v17- devices
269            return;
270        }
271
272        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
273
274        // End drawable should be returned as left
275        assertEquals("Compound drawable: left", drawablesAbsolute[0], drawableEnd);
276        assertEquals("Compound drawable: left width",
277                drawablesAbsolute[0].getBounds().width(), 25);
278        assertEquals("Compound drawable: left height",
279                drawablesAbsolute[0].getBounds().height(), 45);
280
281        assertNull("Compound drawable: top", drawablesAbsolute[1]);
282
283        // Start drawable should be returned as right
284        assertEquals("Compound drawable: right", drawablesAbsolute[2], drawableStart);
285        assertEquals("Compound drawable: right width",
286                drawablesAbsolute[2].getBounds().width(), 30);
287        assertEquals("Compound drawable: right height",
288                drawablesAbsolute[2].getBounds().height(), 20);
289
290        assertEquals("Compound drawable: bottom", drawablesAbsolute[3], drawableBottom);
291        assertEquals("Compound drawable: bottom width",
292                drawablesAbsolute[3].getBounds().width(), 15);
293        assertEquals("Compound drawable: bottom height",
294                drawablesAbsolute[3].getBounds().height(), 35);
295    }
296
297    @Test
298    public void testCompoundDrawablesRelativeWithIntrinsicBoundsById() throws Throwable {
299        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
300        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
301                R.drawable.test_drawable_red, 0,
302                R.drawable.test_drawable_green, R.drawable.test_drawable_blue));
303
304        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
305        final Resources res = mActivityTestRule.getActivity().getResources();
306
307        // The entire left drawable should be the specific red color
308        TestUtils.assertAllPixelsOfColor("Compound drawable: left color",
309                drawablesAbsolute[0], res.getColor(R.color.test_red));
310        assertEquals("Compound drawable: left width",
311                drawablesAbsolute[0].getBounds().width(),
312                res.getDimensionPixelSize(R.dimen.drawable_small_size));
313        assertEquals("Compound drawable: left height",
314                drawablesAbsolute[0].getBounds().height(),
315                res.getDimensionPixelSize(R.dimen.drawable_medium_size));
316
317        assertNull("Compound drawable: top", drawablesAbsolute[1]);
318
319        // The entire right drawable should be the specific green color
320        TestUtils.assertAllPixelsOfColor("Compound drawable: right color",
321                drawablesAbsolute[2], res.getColor(R.color.test_green));
322        assertEquals("Compound drawable: right width",
323                drawablesAbsolute[2].getBounds().width(),
324                res.getDimensionPixelSize(R.dimen.drawable_medium_size));
325        assertEquals("Compound drawable: right height",
326                drawablesAbsolute[2].getBounds().height(),
327                res.getDimensionPixelSize(R.dimen.drawable_large_size));
328
329        // The entire bottom drawable should be the specific blue color
330        TestUtils.assertAllPixelsOfColor("Compound drawable: bottom color",
331                drawablesAbsolute[3], res.getColor(R.color.test_blue));
332        assertEquals("Compound drawable: bottom width",
333                drawablesAbsolute[3].getBounds().width(),
334                res.getDimensionPixelSize(R.dimen.drawable_large_size));
335        assertEquals("Compound drawable: bottom height",
336                drawablesAbsolute[3].getBounds().height(),
337                res.getDimensionPixelSize(R.dimen.drawable_small_size));
338    }
339
340    @Test
341    public void testCompoundDrawablesRelativeWithIntrinsicBoundsByIdRtl() throws Throwable {
342        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
343
344        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
345        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
346                R.drawable.test_drawable_red, 0,
347                R.drawable.test_drawable_green, R.drawable.test_drawable_blue));
348
349        // Check to see whether our text view is under RTL mode
350        if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
351            // This will happen on v17- devices
352            return;
353        }
354
355        final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
356        final Resources res = mActivityTestRule.getActivity().getResources();
357
358        // The entire left / end drawable should be the specific green color
359        TestUtils.assertAllPixelsOfColor("Compound drawable: left color",
360                drawablesAbsolute[0], res.getColor(R.color.test_green));
361        assertEquals("Compound drawable: left width",
362                drawablesAbsolute[0].getBounds().width(),
363                res.getDimensionPixelSize(R.dimen.drawable_medium_size));
364        assertEquals("Compound drawable: left height",
365                drawablesAbsolute[0].getBounds().height(),
366                res.getDimensionPixelSize(R.dimen.drawable_large_size));
367
368        assertNull("Compound drawable: top", drawablesAbsolute[1]);
369
370        // The entire right drawable should be the specific red color
371        TestUtils.assertAllPixelsOfColor("Compound drawable: right color",
372                drawablesAbsolute[2], res.getColor(R.color.test_red));
373        assertEquals("Compound drawable: right width",
374                drawablesAbsolute[2].getBounds().width(),
375                res.getDimensionPixelSize(R.dimen.drawable_small_size));
376        assertEquals("Compound drawable: right height",
377                drawablesAbsolute[2].getBounds().height(),
378                res.getDimensionPixelSize(R.dimen.drawable_medium_size));
379
380        // The entire bottom drawable should be the specific blue color
381        TestUtils.assertAllPixelsOfColor("Compound drawable: bottom color",
382                drawablesAbsolute[3], res.getColor(R.color.test_blue));
383        assertEquals("Compound drawable: bottom width",
384                drawablesAbsolute[3].getBounds().width(),
385                res.getDimensionPixelSize(R.dimen.drawable_large_size));
386        assertEquals("Compound drawable: bottom height",
387                drawablesAbsolute[3].getBounds().height(),
388                res.getDimensionPixelSize(R.dimen.drawable_small_size));
389    }
390
391    @Test
392    public void testCompoundDrawablesRelativeGetterAndSetter() {
393        final Drawable drawableStart = new TestDrawable(0xFFFF0000, 20, 20);
394        final Drawable drawableTop = new TestDrawable(0xFFFFFF00, 20, 20);
395        final Drawable drawableEnd = new TestDrawable(0xFF0000FF, 20, 20);
396        final Drawable drawableBottom = new TestDrawable(0xFF00FF00, 20, 20);
397
398        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
399        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelative(drawableStart,
400                drawableTop, drawableEnd, drawableBottom));
401
402        // Check to see whether our text view is under RTL mode
403        if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
404            // This will happen on v17- devices
405            return;
406        }
407
408        final Drawable[] drawablesRelative = TextViewCompat.getCompoundDrawablesRelative(mTextView);
409        assertEquals(drawableStart, drawablesRelative[0]);
410        assertEquals(drawableTop, drawablesRelative[1]);
411        assertEquals(drawableEnd, drawablesRelative[2]);
412        assertEquals(drawableBottom, drawablesRelative[3]);
413    }
414}
415