• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.widget.cts;
18 
19 import com.android.cts.stub.R;
20 import com.android.internal.util.FastMath;
21 
22 import dalvik.annotation.TestLevel;
23 import dalvik.annotation.TestTargetClass;
24 import dalvik.annotation.TestTargetNew;
25 import dalvik.annotation.TestTargets;
26 import dalvik.annotation.ToBeFixed;
27 
28 import org.xmlpull.v1.XmlPullParserException;
29 
30 import android.app.Activity;
31 import android.app.Instrumentation;
32 import android.app.Instrumentation.ActivityMonitor;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.res.ColorStateList;
36 import android.content.res.Resources.NotFoundException;
37 import android.graphics.Bitmap;
38 import android.graphics.Canvas;
39 import android.graphics.Color;
40 import android.graphics.Paint;
41 import android.graphics.Rect;
42 import android.graphics.Typeface;
43 import android.graphics.drawable.BitmapDrawable;
44 import android.graphics.drawable.Drawable;
45 import android.net.Uri;
46 import android.os.Bundle;
47 import android.test.ActivityInstrumentationTestCase2;
48 import android.test.TouchUtils;
49 import android.test.UiThreadTest;
50 import android.text.Editable;
51 import android.text.InputFilter;
52 import android.text.InputType;
53 import android.text.Layout;
54 import android.text.Selection;
55 import android.text.Spannable;
56 import android.text.SpannableString;
57 import android.text.TextPaint;
58 import android.text.TextUtils;
59 import android.text.TextWatcher;
60 import android.text.TextUtils.TruncateAt;
61 import android.text.method.ArrowKeyMovementMethod;
62 import android.text.method.DateKeyListener;
63 import android.text.method.DateTimeKeyListener;
64 import android.text.method.DialerKeyListener;
65 import android.text.method.DigitsKeyListener;
66 import android.text.method.KeyListener;
67 import android.text.method.LinkMovementMethod;
68 import android.text.method.MovementMethod;
69 import android.text.method.PasswordTransformationMethod;
70 import android.text.method.QwertyKeyListener;
71 import android.text.method.SingleLineTransformationMethod;
72 import android.text.method.TextKeyListener;
73 import android.text.method.TimeKeyListener;
74 import android.text.method.TransformationMethod;
75 import android.text.method.TextKeyListener.Capitalize;
76 import android.text.style.URLSpan;
77 import android.text.style.cts.MockURLSpanTestActivity;
78 import android.text.util.Linkify;
79 import android.util.DisplayMetrics;
80 import android.util.TypedValue;
81 import android.view.ContextMenu;
82 import android.view.Gravity;
83 import android.view.KeyEvent;
84 import android.view.View;
85 import android.view.WindowManager;
86 import android.view.ContextMenu.ContextMenuInfo;
87 import android.view.View.OnCreateContextMenuListener;
88 import android.view.View.OnLongClickListener;
89 import android.view.animation.cts.DelayedCheck;
90 import android.view.inputmethod.BaseInputConnection;
91 import android.view.inputmethod.EditorInfo;
92 import android.view.inputmethod.ExtractedText;
93 import android.view.inputmethod.ExtractedTextRequest;
94 import android.widget.Scroller;
95 import android.widget.TextView;
96 import android.widget.TextView.BufferType;
97 import android.widget.TextView.OnEditorActionListener;
98 
99 import java.io.IOException;
100 
101 /**
102  * Test {@link TextView}.
103  */
104 @TestTargetClass(TextView.class)
105 public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewStubActivity> {
106     private TextView mTextView;
107     private Activity mActivity;
108     private Instrumentation mInstrumentation;
109     private static final String LONG_TEXT = "This is a really long string which exceeds "
110             + "the width of the view.";
111     private static final long TIMEOUT = 5000;
112 
TextViewTest()113     public TextViewTest() {
114         super("com.android.cts.stub", TextViewStubActivity.class);
115     }
116 
117     @Override
setUp()118     protected void setUp() throws Exception {
119         super.setUp();
120         mActivity = getActivity();
121         mInstrumentation = getInstrumentation();
122     }
123 
124     @TestTargets({
125         @TestTargetNew(
126             level = TestLevel.COMPLETE,
127             method = "TextView",
128             args = {android.content.Context.class}
129         ),
130         @TestTargetNew(
131             level = TestLevel.COMPLETE,
132             method = "TextView",
133             args = {android.content.Context.class, android.util.AttributeSet.class}
134         ),
135         @TestTargetNew(
136             level = TestLevel.COMPLETE,
137             method = "TextView",
138             args = {android.content.Context.class, android.util.AttributeSet.class, int.class}
139         )
140     })
testConstructor()141     public void testConstructor() {
142         new TextView(mActivity);
143 
144         new TextView(mActivity, null);
145 
146         new TextView(mActivity, null, 0);
147     }
148 
149     @TestTargets({
150         @TestTargetNew(
151             level = TestLevel.COMPLETE,
152             method = "getText",
153             args = {}
154         ),
155         @TestTargetNew(
156             level = TestLevel.COMPLETE,
157             method = "setText",
158             args = {java.lang.CharSequence.class}
159         )
160     })
161     @UiThreadTest
testAccessText()162     public void testAccessText() {
163         TextView tv = findTextView(R.id.textview_text);
164 
165         String expected = mActivity.getResources().getString(R.string.text_view_hello);
166         tv.setText(expected);
167         assertEquals(expected, tv.getText().toString());
168 
169         tv.setText(null);
170         assertEquals("", tv.getText().toString());
171     }
172 
173     @TestTargetNew(
174         level = TestLevel.COMPLETE,
175         method = "getLineHeight",
176         args = {}
177     )
testGetLineHeight()178     public void testGetLineHeight() {
179         mTextView = new TextView(mActivity);
180         assertTrue(mTextView.getLineHeight() > 0);
181 
182         mTextView.setLineSpacing(1.2f, 1.5f);
183         assertTrue(mTextView.getLineHeight() > 0);
184     }
185 
186     @TestTargetNew(
187         level = TestLevel.COMPLETE,
188         method = "getLayout",
189         args = {}
190     )
testGetLayout()191     public void testGetLayout() {
192         mActivity.runOnUiThread(new Runnable() {
193             public void run() {
194                 mTextView = findTextView(R.id.textview_text);
195                 mTextView.setGravity(Gravity.CENTER);
196             }
197         });
198         mInstrumentation.waitForIdleSync();
199         assertNotNull(mTextView.getLayout());
200 
201         TestLayoutRunnable runnable = new TestLayoutRunnable(mTextView) {
202             public void run() {
203                 // change the text of TextView.
204                 mTextView.setText("Hello, Android!");
205                 saveLayout();
206             }
207         };
208         mActivity.runOnUiThread(runnable);
209         mInstrumentation.waitForIdleSync();
210         assertNull(runnable.getLayout());
211         assertNotNull(mTextView.getLayout());
212     }
213 
214     @TestTargets({
215         @TestTargetNew(
216             level = TestLevel.COMPLETE,
217             method = "getKeyListener",
218             args = {}
219         ),
220         @TestTargetNew(
221             level = TestLevel.COMPLETE,
222             method = "setKeyListener",
223             args = {android.text.method.KeyListener.class}
224         )
225     })
testAccessKeyListener()226     public void testAccessKeyListener() {
227         mActivity.runOnUiThread(new Runnable() {
228             public void run() {
229                 mTextView = findTextView(R.id.textview_text);
230                 mTextView.setText("");
231             }
232         });
233         mInstrumentation.waitForIdleSync();
234 
235         assertNull(mTextView.getKeyListener());
236 
237         final KeyListener digitsKeyListener = DigitsKeyListener.getInstance();
238 
239         mActivity.runOnUiThread(new Runnable() {
240             public void run() {
241                 mTextView.setKeyListener(digitsKeyListener);
242                 mTextView.requestFocus();
243             }
244         });
245         mInstrumentation.waitForIdleSync();
246         assertSame(digitsKeyListener, mTextView.getKeyListener());
247         assertEquals("", mTextView.getText().toString());
248 
249         // press '-' key.
250         sendKeys(KeyEvent.KEYCODE_MINUS);
251         assertEquals("", mTextView.getText().toString());
252 
253         // press '1' key.
254         sendKeys(KeyEvent.KEYCODE_1);
255         assertEquals("1", mTextView.getText().toString());
256 
257         // press '.' key.
258         sendKeys(KeyEvent.KEYCODE_PERIOD);
259         assertEquals("1", mTextView.getText().toString());
260 
261         // press 'a' key.
262         sendKeys(KeyEvent.KEYCODE_A);
263         assertEquals("1", mTextView.getText().toString());
264 
265         final QwertyKeyListener qwertyKeyListener
266                 = QwertyKeyListener.getInstance(false, Capitalize.NONE);
267         mActivity.runOnUiThread(new Runnable() {
268             public void run() {
269                 mTextView.setKeyListener(qwertyKeyListener);
270                 mTextView.requestFocus();
271             }
272         });
273         mInstrumentation.waitForIdleSync();
274         assertSame(qwertyKeyListener, mTextView.getKeyListener());
275         assertEquals("1", mTextView.getText().toString());
276 
277         // press 'a' key.
278         sendKeys(KeyEvent.KEYCODE_A);
279         assertEquals("1a", mTextView.getText().toString());
280     }
281 
282     @TestTargets({
283         @TestTargetNew(
284             level = TestLevel.COMPLETE,
285             method = "setMovementMethod",
286             args = {android.text.method.MovementMethod.class}
287         ),
288         @TestTargetNew(
289             level = TestLevel.COMPLETE,
290             method = "getMovementMethod",
291             args = {}
292         )
293     })
testAccessMovementMethod()294     public void testAccessMovementMethod() {
295         final CharSequence LONG_TEXT = "Scrolls the specified widget to the specified "
296                 + "coordinates, except constrains the X scrolling position to the horizontal "
297                 + "regions of the text that will be visible after scrolling to "
298                 + "the specified Y position.";
299         final int selectionStart = 10;
300         final int selectionEnd = LONG_TEXT.length();
301         final MovementMethod movementMethod = ArrowKeyMovementMethod.getInstance();
302         mActivity.runOnUiThread(new Runnable() {
303             public void run() {
304                 mTextView = findTextView(R.id.textview_text);
305                 mTextView.setMovementMethod(movementMethod);
306                 mTextView.setText(LONG_TEXT, BufferType.EDITABLE);
307                 Selection.setSelection((Editable) mTextView.getText(),
308                         selectionStart, selectionEnd);
309                 mTextView.requestFocus();
310             }
311         });
312         mInstrumentation.waitForIdleSync();
313 
314         assertSame(movementMethod, mTextView.getMovementMethod());
315         assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
316         assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
317         sendKeys(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
318                 KeyEvent.KEYCODE_DPAD_UP);
319         // the selection has been removed.
320         assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
321         assertEquals(selectionStart, Selection.getSelectionEnd(mTextView.getText()));
322 
323         mActivity.runOnUiThread(new Runnable() {
324             public void run() {
325                 mTextView.setMovementMethod(null);
326                 Selection.setSelection((Editable) mTextView.getText(),
327                         selectionStart, selectionEnd);
328                 mTextView.requestFocus();
329             }
330         });
331         mInstrumentation.waitForIdleSync();
332 
333         assertNull(mTextView.getMovementMethod());
334         assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
335         assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
336         sendKeys(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT,
337                 KeyEvent.KEYCODE_DPAD_UP);
338         // the selection will not be changed.
339         assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText()));
340         assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText()));
341     }
342 
343     @TestTargetNew(
344         level = TestLevel.COMPLETE,
345         method = "length",
346         args = {}
347     )
348     @UiThreadTest
testLength()349     public void testLength() {
350         mTextView = findTextView(R.id.textview_text);
351 
352         String content = "This is content";
353         mTextView.setText(content);
354         assertEquals(content.length(), mTextView.length());
355 
356         mTextView.setText("");
357         assertEquals(0, mTextView.length());
358 
359         mTextView.setText(null);
360         assertEquals(0, mTextView.length());
361     }
362 
363     @TestTargets({
364         @TestTargetNew(
365             level = TestLevel.COMPLETE,
366             method = "setGravity",
367             args = {int.class}
368         ),
369         @TestTargetNew(
370             level = TestLevel.COMPLETE,
371             method = "getGravity",
372             args = {}
373         )
374     })
375     @UiThreadTest
testAccessGravity()376     public void testAccessGravity() {
377         mActivity.setContentView(R.layout.textview_gravity);
378 
379         mTextView = findTextView(R.id.gravity_default);
380         assertEquals(Gravity.TOP | Gravity.LEFT, mTextView.getGravity());
381 
382         mTextView = findTextView(R.id.gravity_bottom);
383         assertEquals(Gravity.BOTTOM | Gravity.LEFT, mTextView.getGravity());
384 
385         mTextView = findTextView(R.id.gravity_right);
386         assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
387 
388         mTextView = findTextView(R.id.gravity_center);
389         assertEquals(Gravity.CENTER, mTextView.getGravity());
390 
391         mTextView = findTextView(R.id.gravity_fill);
392         assertEquals(Gravity.FILL, mTextView.getGravity());
393 
394         mTextView = findTextView(R.id.gravity_center_vertical_right);
395         assertEquals(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mTextView.getGravity());
396 
397         mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
398         assertEquals(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, mTextView.getGravity());
399         mTextView.setGravity(Gravity.FILL);
400         assertEquals(Gravity.FILL, mTextView.getGravity());
401         mTextView.setGravity(Gravity.CENTER);
402         assertEquals(Gravity.CENTER, mTextView.getGravity());
403 
404         mTextView.setGravity(Gravity.NO_GRAVITY);
405         assertEquals(Gravity.TOP | Gravity.LEFT, mTextView.getGravity());
406 
407         mTextView.setGravity(Gravity.RIGHT);
408         assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity());
409 
410         mTextView.setGravity(Gravity.FILL_VERTICAL);
411         assertEquals(Gravity.FILL_VERTICAL | Gravity.LEFT, mTextView.getGravity());
412 
413         //test negative input value.
414         mTextView.setGravity(-1);
415         assertEquals(-1, mTextView.getGravity());
416     }
417 
418     @TestTargets({
419         @TestTargetNew(
420             level = TestLevel.COMPLETE,
421             method = "setAutoLinkMask",
422             args = {int.class}
423         ),
424         @TestTargetNew(
425             level = TestLevel.COMPLETE,
426             method = "getAutoLinkMask",
427             args = {}
428         )
429     })
testAccessAutoLinkMask()430     public void testAccessAutoLinkMask() {
431         mTextView = findTextView(R.id.textview_text);
432         final CharSequence text1 =
433                 new SpannableString("URL: http://www.google.com. mailto: account@gmail.com");
434         mActivity.runOnUiThread(new Runnable() {
435             public void run() {
436                 mTextView.setAutoLinkMask(Linkify.ALL);
437                 mTextView.setText(text1, BufferType.EDITABLE);
438             }
439         });
440         mInstrumentation.waitForIdleSync();
441         assertEquals(Linkify.ALL, mTextView.getAutoLinkMask());
442 
443         Spannable spanString = (Spannable) mTextView.getText();
444         URLSpan[] spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
445         assertNotNull(spans);
446         assertEquals(2, spans.length);
447         assertEquals("http://www.google.com", spans[0].getURL());
448         assertEquals("mailto:account@gmail.com", spans[1].getURL());
449 
450         final CharSequence text2 =
451             new SpannableString("name: Jack. tel: +41 44 800 8999");
452         mActivity.runOnUiThread(new Runnable() {
453             public void run() {
454                 mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
455                 mTextView.setText(text2, BufferType.EDITABLE);
456             }
457         });
458         mInstrumentation.waitForIdleSync();
459         assertEquals(Linkify.PHONE_NUMBERS, mTextView.getAutoLinkMask());
460 
461         spanString = (Spannable) mTextView.getText();
462         spans = spanString.getSpans(0, spanString.length(), URLSpan.class);
463         assertNotNull(spans);
464         assertEquals(1, spans.length);
465         assertEquals("tel:+41448008999", spans[0].getURL());
466 
467         layout(R.layout.textview_autolink);
468         // 1 for web, 2 for email, 4 for phone, 7 for all(web|email|phone)
469         assertEquals(0, getAutoLinkMask(R.id.autolink_default));
470         assertEquals(Linkify.WEB_URLS, getAutoLinkMask(R.id.autolink_web));
471         assertEquals(Linkify.EMAIL_ADDRESSES, getAutoLinkMask(R.id.autolink_email));
472         assertEquals(Linkify.PHONE_NUMBERS, getAutoLinkMask(R.id.autolink_phone));
473         assertEquals(Linkify.ALL, getAutoLinkMask(R.id.autolink_all));
474         assertEquals(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES,
475                 getAutoLinkMask(R.id.autolink_compound1));
476         assertEquals(Linkify.WEB_URLS | Linkify.PHONE_NUMBERS,
477                 getAutoLinkMask(R.id.autolink_compound2));
478         assertEquals(Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS,
479                 getAutoLinkMask(R.id.autolink_compound3));
480         assertEquals(Linkify.PHONE_NUMBERS | Linkify.ALL,
481                 getAutoLinkMask(R.id.autolink_compound4));
482     }
483 
484     @TestTargets({
485         @TestTargetNew(
486             level = TestLevel.COMPLETE,
487             method = "setTextSize",
488             args = {float.class}
489         ),
490         @TestTargetNew(
491             level = TestLevel.COMPLETE,
492             method = "getTextSize",
493             args = {}
494         ),
495         @TestTargetNew(
496             level = TestLevel.COMPLETE,
497             method = "setTextSize",
498             args = {int.class, float.class}
499         )
500     })
testAccessTextSize()501     public void testAccessTextSize() {
502         DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
503 
504         mTextView = new TextView(mActivity);
505         mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20f);
506         assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20f, metrics),
507                 mTextView.getTextSize(), 0.01f);
508 
509         mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20f);
510         assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics),
511                 mTextView.getTextSize(), 0.01f);
512 
513         mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f);
514         assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
515                 mTextView.getTextSize(), 0.01f);
516 
517         // setTextSize by default unit "sp"
518         mTextView.setTextSize(20f);
519         assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics),
520                 mTextView.getTextSize(), 0.01f);
521 
522         mTextView.setTextSize(200f);
523         assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 200f, metrics),
524                 mTextView.getTextSize(), 0.01f);
525     }
526 
527     @TestTargets({
528         @TestTargetNew(
529             level = TestLevel.COMPLETE,
530             method = "setTextColor",
531             args = {int.class}
532         ),
533         @TestTargetNew(
534             level = TestLevel.COMPLETE,
535             method = "getCurrentTextColor",
536             args = {}
537         ),
538         @TestTargetNew(
539             level = TestLevel.COMPLETE,
540             method = "getTextColors",
541             args = {}
542         ),
543         @TestTargetNew(
544             level = TestLevel.COMPLETE,
545             method = "setTextColor",
546             args = {android.content.res.ColorStateList.class}
547         )
548     })
549     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
550             + "should add @throws clause into javadoc of "
551             + "TextView#setTextColor(ColorStateList) when param colors is null")
testAccessTextColor()552     public void testAccessTextColor() {
553         mTextView = new TextView(mActivity);
554 
555         mTextView.setTextColor(Color.GREEN);
556         assertEquals(Color.GREEN, mTextView.getCurrentTextColor());
557         assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getTextColors());
558 
559         mTextView.setTextColor(Color.BLACK);
560         assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
561         assertSame(ColorStateList.valueOf(Color.BLACK), mTextView.getTextColors());
562 
563         mTextView.setTextColor(Color.RED);
564         assertEquals(Color.RED, mTextView.getCurrentTextColor());
565         assertSame(ColorStateList.valueOf(Color.RED), mTextView.getTextColors());
566 
567         // using ColorStateList
568         // normal
569         ColorStateList colors = new ColorStateList(new int[][] {
570                 new int[] { android.R.attr.state_focused}, new int[0] },
571                 new int[] { Color.rgb(0, 255, 0), Color.BLACK });
572         mTextView.setTextColor(colors);
573         assertSame(colors, mTextView.getTextColors());
574         assertEquals(Color.BLACK, mTextView.getCurrentTextColor());
575 
576         // exceptional
577         try {
578             mTextView.setTextColor(null);
579             fail("Should thrown exception if the colors is null");
580         } catch (NullPointerException e){
581         }
582     }
583 
584     @TestTargetNew(
585         level = TestLevel.SUFFICIENT,
586         method = "getTextColor",
587         args = {android.content.Context.class, android.content.res.TypedArray.class, int.class}
588     )
589     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
590             + "should add @throws clause into javadoc of "
591             + "TextView#getTextColor(Context, TypedArray, int) when param attrs is null")
testGetTextColor()592     public void testGetTextColor() {
593         // TODO: How to get a suitable TypedArray to test this method.
594 
595         try {
596             TextView.getTextColor(mActivity, null, -1);
597             fail("There should be a NullPointerException thrown out.");
598         } catch (NullPointerException e) {
599         }
600     }
601 
602     @TestTargetNew(
603         level = TestLevel.COMPLETE,
604         method = "setHighlightColor",
605         args = {int.class}
606     )
607     @ToBeFixed(bug = "1386429", explanation = "No getter to check the value.")
testSetHighlightColor()608     public void testSetHighlightColor() {
609         mTextView = new TextView(mActivity);
610 
611         mTextView.setHighlightColor(0x00ff00ff);
612     }
613 
614     @TestTargets({
615         @TestTargetNew(
616             level = TestLevel.COMPLETE,
617             method = "setShadowLayer",
618             args = {float.class, float.class, float.class, int.class}
619         ),
620         @TestTargetNew(
621             level = TestLevel.COMPLETE,
622             method = "isPaddingOffsetRequired",
623             args = {}
624         ),
625         @TestTargetNew(
626             level = TestLevel.COMPLETE,
627             method = "getLeftPaddingOffset",
628             args = {}
629         ),
630         @TestTargetNew(
631             level = TestLevel.COMPLETE,
632             method = "getTopPaddingOffset",
633             args = {}
634         ),
635         @TestTargetNew(
636             level = TestLevel.COMPLETE,
637             method = "getRightPaddingOffset",
638             args = {}
639         ),
640         @TestTargetNew(
641             level = TestLevel.COMPLETE,
642             method = "getBottomPaddingOffset",
643             args = {}
644         )
645     })
646     @ToBeFixed(bug = "1386429", explanation = "No getter to check the shaow color value.")
testSetShadowLayer()647     public void testSetShadowLayer() {
648         MockTextView textView = new MockTextView(mActivity);
649 
650         // shadow is placed to the left and below the text
651         textView.setShadowLayer(1.0f, 0.3f, 0.3f, Color.CYAN);
652         assertTrue(textView.isPaddingOffsetRequired());
653         assertEquals(0, textView.getLeftPaddingOffset());
654         assertEquals(0, textView.getTopPaddingOffset());
655         assertEquals(1, textView.getRightPaddingOffset());
656         assertEquals(1, textView.getBottomPaddingOffset());
657 
658         // shadow is placed to the right and above the text
659         textView.setShadowLayer(1.0f, -0.8f, -0.8f, Color.CYAN);
660         assertTrue(textView.isPaddingOffsetRequired());
661         assertEquals(-1, textView.getLeftPaddingOffset());
662         assertEquals(-1, textView.getTopPaddingOffset());
663         assertEquals(0, textView.getRightPaddingOffset());
664         assertEquals(0, textView.getBottomPaddingOffset());
665 
666         // no shadow
667         textView.setShadowLayer(0.0f, 0.0f, 0.0f, Color.CYAN);
668         assertFalse(textView.isPaddingOffsetRequired());
669         assertEquals(0, textView.getLeftPaddingOffset());
670         assertEquals(0, textView.getTopPaddingOffset());
671         assertEquals(0, textView.getRightPaddingOffset());
672         assertEquals(0, textView.getBottomPaddingOffset());
673     }
674 
675     @TestTargetNew(
676         level = TestLevel.COMPLETE,
677         method = "setSelectAllOnFocus",
678         args = {boolean.class}
679     )
680     @UiThreadTest
testSetSelectAllOnFocus()681     public void testSetSelectAllOnFocus() {
682         mActivity.setContentView(R.layout.textview_selectallonfocus);
683         String content = "This is the content";
684         String blank = "";
685         mTextView = findTextView(R.id.selectAllOnFocus_default);
686         mTextView.setText(blank, BufferType.SPANNABLE);
687         // change the focus
688         findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
689         assertFalse(mTextView.isFocused());
690         mTextView.requestFocus();
691         assertTrue(mTextView.isFocused());
692 
693         assertEquals(-1, mTextView.getSelectionStart());
694         assertEquals(-1, mTextView.getSelectionEnd());
695 
696         mTextView.setText(content, BufferType.SPANNABLE);
697         mTextView.setSelectAllOnFocus(true);
698         // change the focus
699         findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
700         assertFalse(mTextView.isFocused());
701         mTextView.requestFocus();
702         assertTrue(mTextView.isFocused());
703 
704         assertEquals(0, mTextView.getSelectionStart());
705         assertEquals(content.length(), mTextView.getSelectionEnd());
706 
707         Selection.setSelection((Spannable) mTextView.getText(), 0);
708         mTextView.setSelectAllOnFocus(false);
709         // change the focus
710         findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
711         assertFalse(mTextView.isFocused());
712         mTextView.requestFocus();
713         assertTrue(mTextView.isFocused());
714 
715         assertEquals(0, mTextView.getSelectionStart());
716         assertEquals(0, mTextView.getSelectionEnd());
717 
718         mTextView.setText(blank, BufferType.SPANNABLE);
719         mTextView.setSelectAllOnFocus(true);
720         // change the focus
721         findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
722         assertFalse(mTextView.isFocused());
723         mTextView.requestFocus();
724         assertTrue(mTextView.isFocused());
725 
726         assertEquals(0, mTextView.getSelectionStart());
727         assertEquals(blank.length(), mTextView.getSelectionEnd());
728 
729         Selection.setSelection((Spannable) mTextView.getText(), 0);
730         mTextView.setSelectAllOnFocus(false);
731         // change the focus
732         findTextView(R.id.selectAllOnFocus_dummy).requestFocus();
733         assertFalse(mTextView.isFocused());
734         mTextView.requestFocus();
735         assertTrue(mTextView.isFocused());
736 
737         assertEquals(0, mTextView.getSelectionStart());
738         assertEquals(0, mTextView.getSelectionEnd());
739     }
740 
741     @TestTargetNew(
742         level = TestLevel.COMPLETE,
743         method = "getPaint",
744         args = {}
745     )
testGetPaint()746     public void testGetPaint() {
747         mTextView = new TextView(mActivity);
748         TextPaint tp = mTextView.getPaint();
749         assertNotNull(tp);
750 
751         assertEquals(mTextView.getPaintFlags(), tp.getFlags());
752     }
753 
754     @TestTargets({
755         @TestTargetNew(
756             level = TestLevel.COMPLETE,
757             method = "setLinksClickable",
758             args = {boolean.class}
759         ),
760         @TestTargetNew(
761             level = TestLevel.COMPLETE,
762             method = "getLinksClickable",
763             args = {}
764         )
765     })
766     @UiThreadTest
testAccessLinksClickable()767     public void testAccessLinksClickable() {
768         mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
769 
770         mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
771         assertTrue(mTextView.getLinksClickable());
772 
773         mTextView = findTextView(R.id.linksClickable_true);
774         assertTrue(mTextView.getLinksClickable());
775 
776         mTextView = findTextView(R.id.linksClickable_false);
777         assertFalse(mTextView.getLinksClickable());
778 
779         mTextView.setLinksClickable(false);
780         assertFalse(mTextView.getLinksClickable());
781 
782         mTextView.setLinksClickable(true);
783         assertTrue(mTextView.getLinksClickable());
784 
785         assertNull(mTextView.getMovementMethod());
786 
787         final CharSequence text = new SpannableString("name: Jack. tel: +41 44 800 8999");
788 
789         mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS);
790         mTextView.setText(text, BufferType.EDITABLE);
791 
792         // Movement method will be automatically set to LinkMovementMethod
793         assertTrue(mTextView.getMovementMethod() instanceof LinkMovementMethod);
794     }
795 
796     @TestTargets({
797         @TestTargetNew(
798             level = TestLevel.COMPLETE,
799             method = "setHintTextColor",
800             args = {int.class}
801         ),
802         @TestTargetNew(
803             level = TestLevel.COMPLETE,
804             method = "getHintTextColors",
805             args = {}
806         ),
807         @TestTargetNew(
808             level = TestLevel.COMPLETE,
809             method = "getCurrentHintTextColor",
810             args = {}
811         ),
812         @TestTargetNew(
813             level = TestLevel.COMPLETE,
814             method = "setHintTextColor",
815             args = {android.content.res.ColorStateList.class}
816         )
817     })
testAccessHintTextColor()818     public void testAccessHintTextColor() {
819         mTextView = new TextView(mActivity);
820         // using int values
821         // normal
822         mTextView.setHintTextColor(Color.GREEN);
823         assertEquals(Color.GREEN, mTextView.getCurrentHintTextColor());
824         assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getHintTextColors());
825 
826         mTextView.setHintTextColor(Color.BLUE);
827         assertSame(ColorStateList.valueOf(Color.BLUE), mTextView.getHintTextColors());
828         assertEquals(Color.BLUE, mTextView.getCurrentHintTextColor());
829 
830         mTextView.setHintTextColor(Color.RED);
831         assertSame(ColorStateList.valueOf(Color.RED), mTextView.getHintTextColors());
832         assertEquals(Color.RED, mTextView.getCurrentHintTextColor());
833 
834         // using ColorStateList
835         // normal
836         ColorStateList colors = new ColorStateList(new int[][] {
837                 new int[] { android.R.attr.state_focused}, new int[0] },
838                 new int[] { Color.rgb(0, 255, 0), Color.BLACK });
839         mTextView.setHintTextColor(colors);
840         assertSame(colors, mTextView.getHintTextColors());
841         assertEquals(Color.BLACK, mTextView.getCurrentHintTextColor());
842 
843         // exceptional
844         mTextView.setHintTextColor(null);
845         assertNull(mTextView.getHintTextColors());
846         assertEquals(mTextView.getCurrentTextColor(), mTextView.getCurrentHintTextColor());
847     }
848 
849     @TestTargets({
850         @TestTargetNew(
851             level = TestLevel.COMPLETE,
852             method = "setLinkTextColor",
853             args = {int.class}
854         ),
855         @TestTargetNew(
856             level = TestLevel.COMPLETE,
857             method = "getLinkTextColors",
858             args = {}
859         ),
860         @TestTargetNew(
861             level = TestLevel.COMPLETE,
862             method = "setLinkTextColor",
863             args = {android.content.res.ColorStateList.class}
864         )
865     })
testAccessLinkTextColor()866     public void testAccessLinkTextColor() {
867         mTextView = new TextView(mActivity);
868         // normal
869         mTextView.setLinkTextColor(Color.GRAY);
870         assertSame(ColorStateList.valueOf(Color.GRAY), mTextView.getLinkTextColors());
871         assertEquals(Color.GRAY, mTextView.getPaint().linkColor);
872 
873         mTextView.setLinkTextColor(Color.YELLOW);
874         assertSame(ColorStateList.valueOf(Color.YELLOW), mTextView.getLinkTextColors());
875         assertEquals(Color.YELLOW, mTextView.getPaint().linkColor);
876 
877         mTextView.setLinkTextColor(Color.WHITE);
878         assertSame(ColorStateList.valueOf(Color.WHITE), mTextView.getLinkTextColors());
879         assertEquals(Color.WHITE, mTextView.getPaint().linkColor);
880 
881         ColorStateList colors = new ColorStateList(new int[][] {
882                 new int[] { android.R.attr.state_expanded}, new int[0] },
883                 new int[] { Color.rgb(0, 255, 0), Color.BLACK });
884         mTextView.setLinkTextColor(colors);
885         assertSame(colors, mTextView.getLinkTextColors());
886         assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
887 
888         mTextView.setLinkTextColor(null);
889         assertNull(mTextView.getLinkTextColors());
890         assertEquals(Color.BLACK, mTextView.getPaint().linkColor);
891     }
892 
893     @TestTargets({
894         @TestTargetNew(
895             level = TestLevel.COMPLETE,
896             method = "setPaintFlags",
897             args = {int.class}
898         ),
899         @TestTargetNew(
900             level = TestLevel.COMPLETE,
901             method = "getPaintFlags",
902             args = {}
903         )
904     })
testAccessPaintFlags()905     public void testAccessPaintFlags() {
906         mTextView = new TextView(mActivity);
907         assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags());
908 
909         mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
910         assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG,
911                 mTextView.getPaintFlags());
912 
913         mTextView.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG);
914         assertEquals(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG,
915                 mTextView.getPaintFlags());
916 
917         // exceptional values, are these correct behaviors
918         mTextView.setPaintFlags(-1);
919         assertEquals(-1 & 0x1ff, mTextView.getPaintFlags());
920 
921         mTextView.setPaintFlags(333);
922         assertEquals(333 & 0x1ff, mTextView.getPaintFlags());
923 
924         mTextView.setPaintFlags(513);
925         assertEquals(513 & 0x1ff, mTextView.getPaintFlags());
926     }
927 
928     @TestTargets({
929         @TestTargetNew(
930             level = TestLevel.COMPLETE,
931             method = "setMinHeight",
932             args = {int.class}
933         ),
934         @TestTargetNew(
935             level = TestLevel.COMPLETE,
936             method = "setMaxHeight",
937             args = {int.class}
938         ),
939         @TestTargetNew(
940             level = TestLevel.COMPLETE,
941             method = "setHeight",
942             args = {int.class}
943         ),
944         @TestTargetNew(
945             level = TestLevel.COMPLETE,
946             method = "setMaxWidth",
947             args = {int.class}
948         ),
949         @TestTargetNew(
950             level = TestLevel.COMPLETE,
951             method = "setMinWidth",
952             args = {int.class}
953         ),
954         @TestTargetNew(
955             level = TestLevel.COMPLETE,
956             method = "setWidth",
957             args = {int.class}
958         )
959     })
testHeightAndWidth()960     public void testHeightAndWidth() {
961         mTextView = findTextView(R.id.textview_text);
962         int originalWidth = mTextView.getWidth();
963         setWidth(mTextView.getWidth() >> 3);
964         int originalHeight = mTextView.getHeight();
965 
966         setMaxHeight(originalHeight + 1);
967         assertEquals(originalHeight, mTextView.getHeight());
968 
969         setMaxHeight(originalHeight - 1);
970         assertEquals(originalHeight - 1, mTextView.getHeight());
971 
972         setMaxHeight(-1);
973         assertEquals(0, mTextView.getHeight());
974 
975         setMaxHeight(Integer.MAX_VALUE);
976         assertEquals(originalHeight, mTextView.getHeight());
977 
978         setMinHeight(originalHeight + 1);
979         assertEquals(originalHeight + 1, mTextView.getHeight());
980 
981         setMinHeight(originalHeight - 1);
982         assertEquals(originalHeight, mTextView.getHeight());
983 
984         setMinHeight(-1);
985         assertEquals(originalHeight, mTextView.getHeight());
986 
987         setMinHeight(Integer.MAX_VALUE);
988         assertEquals(Integer.MAX_VALUE, mTextView.getHeight());
989 
990         setMinHeight(0);
991         setMaxHeight(Integer.MAX_VALUE);
992 
993         setHeight(originalHeight + 1);
994         assertEquals(originalHeight + 1, mTextView.getHeight());
995 
996         setHeight(originalHeight - 1);
997         assertEquals(originalHeight - 1, mTextView.getHeight());
998 
999         setHeight(-1);
1000         assertEquals(0, mTextView.getHeight());
1001 
1002         setHeight(originalHeight);
1003         assertEquals(originalHeight, mTextView.getHeight());
1004 
1005         assertEquals(originalWidth >> 3, mTextView.getWidth());
1006 
1007         setMaxWidth(Integer.MAX_VALUE); // MAX
1008         assertEquals(1, mTextView.getLineCount());
1009         assertEquals(originalWidth, mTextView.getWidth());
1010         // Min Width
1011         // Normal input
1012         setMinWidth(originalWidth + 1);
1013         assertEquals(1, mTextView.getLineCount());
1014         assertEquals(originalWidth + 1, mTextView.getWidth());
1015 
1016         setMinWidth(originalWidth - 1);
1017         assertEquals(1, mTextView.getLineCount());
1018         assertEquals(originalWidth, mTextView.getWidth());
1019 
1020         // Edge input
1021         setMinWidth(-1);
1022         assertEquals(1, mTextView.getLineCount());
1023         assertEquals(originalWidth, mTextView.getWidth());
1024 
1025         setMinWidth(Integer.MAX_VALUE);
1026         assertEquals(1, mTextView.getLineCount());
1027         String name = Context.WINDOW_SERVICE;
1028         WindowManager wm = (WindowManager) mActivity.getSystemService(name);
1029         assertEquals(wm.getDefaultDisplay().getWidth(), mTextView.getWidth());
1030         // Width
1031         // Normal input
1032         setWidth(originalWidth + 1);
1033         assertEquals(1, mTextView.getLineCount());
1034         assertEquals(originalWidth + 1, mTextView.getWidth());
1035 
1036         setWidth(originalWidth - 1);
1037         assertTrue(1 < mTextView.getLineCount());
1038         assertEquals(originalWidth - 1, mTextView.getWidth());
1039 
1040         // Edge input
1041         setWidth(-1);
1042         assertTrue(1 < mTextView.getLineCount());
1043         assertEquals(0, mTextView.getWidth());
1044 
1045         setWidth(Integer.MAX_VALUE);
1046         assertEquals(1, mTextView.getLineCount());
1047         assertEquals(wm.getDefaultDisplay().getWidth(), mTextView.getWidth());
1048     }
1049 
1050     @TestTargetNew(
1051         level = TestLevel.COMPLETE,
1052         method = "setMinEms",
1053         args = {int.class}
1054     )
testSetMinEms()1055     public void testSetMinEms() {
1056         mTextView = findTextView(R.id.textview_text);
1057         assertEquals(1, mTextView.getLineCount());
1058         int originalWidth = mTextView.getWidth();
1059         int originalEms = originalWidth / mTextView.getLineHeight();
1060 
1061         // Normal input
1062         setMinEms(originalEms + 1);
1063         assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth());
1064 
1065         setMinEms(originalEms - 1);
1066         assertEquals(originalWidth, mTextView.getWidth());
1067 
1068         // Edge input
1069         setMinEms(-1);
1070         assertEquals(originalWidth, mTextView.getWidth());
1071 
1072         setMinEms(Integer.MAX_VALUE); // MAX
1073         assertEquals(originalWidth, mTextView.getWidth());
1074 
1075         setMinEms(Integer.MAX_VALUE / mTextView.getLineHeight());
1076         String name = Context.WINDOW_SERVICE;
1077         WindowManager wm = (WindowManager) mActivity.getSystemService(name);
1078         int expected = wm.getDefaultDisplay().getWidth();
1079         assertEquals(expected, mTextView.getWidth());
1080     }
1081 
1082     @TestTargetNew(
1083         level = TestLevel.COMPLETE,
1084         method = "setMaxEms",
1085         args = {int.class}
1086     )
testSetMaxEms()1087     public void testSetMaxEms() {
1088         mTextView = findTextView(R.id.textview_text);
1089         assertEquals(1, mTextView.getLineCount());
1090         int originalWidth = mTextView.getWidth();
1091         int originalEms = originalWidth / mTextView.getLineHeight();
1092 
1093         // Normal input
1094         setMaxEms(originalEms + 1);
1095         assertEquals(1, mTextView.getLineCount());
1096         assertEquals(originalWidth, mTextView.getWidth());
1097 
1098         setMaxEms(originalEms - 1);
1099         assertTrue(1 < mTextView.getLineCount());
1100         assertEquals((originalEms - 1) * mTextView.getLineHeight(),
1101                 mTextView.getWidth());
1102 
1103         // Edge input
1104         setMaxEms(-1);
1105         assertTrue(1 < mTextView.getLineCount());
1106         assertEquals(0, mTextView.getWidth());
1107 
1108         setMaxEms(Integer.MAX_VALUE); // MAX
1109         assertTrue(1 < mTextView.getLineCount());
1110         assertEquals(0, mTextView.getWidth());
1111 
1112         setMaxEms(Integer.MAX_VALUE / mTextView.getLineHeight());
1113         assertEquals(1, mTextView.getLineCount());
1114         assertEquals(originalWidth, mTextView.getWidth());
1115     }
1116 
1117     @TestTargetNew(
1118         level = TestLevel.COMPLETE,
1119         method = "setEms",
1120         args = {int.class}
1121     )
testSetEms()1122     public void testSetEms() {
1123         mTextView = findTextView(R.id.textview_text);
1124         assertEquals("check height", 1, mTextView.getLineCount());
1125         int originalWidth = mTextView.getWidth();
1126         int originalEms = originalWidth / mTextView.getLineHeight();
1127 
1128         // Normal input
1129         setEms(originalEms + 1);
1130         assertEquals(1, mTextView.getLineCount());
1131         assertEquals((originalEms + 1) * mTextView.getLineHeight(),
1132                 mTextView.getWidth());
1133 
1134         setEms(originalEms - 1);
1135         assertTrue((1 < mTextView.getLineCount()));
1136         assertEquals((originalEms - 1) * mTextView.getLineHeight(),
1137                 mTextView.getWidth());
1138 
1139         // Edge input
1140         setEms(-1);
1141         assertTrue((1 < mTextView.getLineCount()));
1142         assertEquals(0, mTextView.getWidth());
1143 
1144         setEms(Integer.MAX_VALUE); // MAX
1145         assertTrue((1 < mTextView.getLineCount()));
1146         assertEquals(0, mTextView.getWidth());
1147 
1148         setEms(Integer.MAX_VALUE / mTextView.getLineHeight());
1149         assertEquals(1, mTextView.getLineCount());
1150         String name = Context.WINDOW_SERVICE;
1151         WindowManager wm = (WindowManager) mActivity.getSystemService(name);
1152         int expected = wm.getDefaultDisplay().getWidth();
1153         assertEquals(expected, mTextView.getWidth());
1154     }
1155 
1156     @TestTargetNew(
1157         level = TestLevel.COMPLETE,
1158         method = "setLineSpacing",
1159         args = {float.class, float.class}
1160     )
testSetLineSpacing()1161     public void testSetLineSpacing() {
1162         mTextView = new TextView(mActivity);
1163         int originalLineHeight = mTextView.getLineHeight();
1164 
1165         // normal
1166         float add = 1.2f;
1167         float mult = 1.4f;
1168         setLineSpacing(add, mult);
1169         assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1170         add = 0.0f;
1171         mult = 1.4f;
1172         setLineSpacing(add, mult);
1173         assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1174 
1175         // abnormal
1176         add = -1.2f;
1177         mult = 1.4f;
1178         setLineSpacing(add, mult);
1179         assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1180         add = -1.2f;
1181         mult = -1.4f;
1182         setLineSpacing(add, mult);
1183         assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1184         add = 1.2f;
1185         mult = 0.0f;
1186         setLineSpacing(add, mult);
1187         assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
1188 
1189         // edge
1190         add = Float.MIN_VALUE;
1191         mult = Float.MIN_VALUE;
1192         setLineSpacing(add, mult);
1193         float expected = originalLineHeight * mult + add;
1194         assertEquals(FastMath.round(expected), mTextView.getLineHeight());
1195         add = Float.MAX_VALUE;
1196         mult = Float.MAX_VALUE;
1197         setLineSpacing(add, mult);
1198         expected = originalLineHeight * mult + add;
1199         assertEquals(FastMath.round(expected), mTextView.getLineHeight());
1200     }
1201 
1202     @TestTargets({
1203         @TestTargetNew(
1204             level = TestLevel.NOT_NECESSARY,
1205             method = "onSaveInstanceState",
1206             args = {}
1207         ),
1208         @TestTargetNew(
1209             level = TestLevel.NOT_NECESSARY,
1210             method = "onRestoreInstanceState",
1211             args = {android.os.Parcelable.class}
1212         )
1213     })
testInstanceState()1214     public void testInstanceState() {
1215         // Do not test. Implementation details.
1216     }
1217 
1218     @TestTargets({
1219         @TestTargetNew(
1220             level = TestLevel.PARTIAL_COMPLETE,
1221             method = "setFreezesText",
1222             args = {boolean.class}
1223         ),
1224         @TestTargetNew(
1225             level = TestLevel.PARTIAL_COMPLETE,
1226             method = "getFreezesText",
1227             args = {}
1228         )
1229     })
testAccessFreezesText()1230     public void testAccessFreezesText() throws Throwable {
1231         layout(R.layout.textview_hint_linksclickable_freezestext);
1232 
1233         mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
1234         assertFalse(mTextView.getFreezesText());
1235 
1236         mTextView = findTextView(R.id.freezesText_true);
1237         assertTrue(mTextView.getFreezesText());
1238 
1239         mTextView = findTextView(R.id.freezesText_false);
1240         assertFalse(mTextView.getFreezesText());
1241 
1242         mTextView.setFreezesText(false);
1243         assertFalse(mTextView.getFreezesText());
1244 
1245         final CharSequence text = "Hello, TextView.";
1246         mActivity.runOnUiThread(new Runnable() {
1247             public void run() {
1248                 mTextView.setText(text);
1249             }
1250         });
1251         mInstrumentation.waitForIdleSync();
1252 
1253         final URLSpan urlSpan = new URLSpan("ctstest://TextView/test");
1254         // TODO: How to simulate the TextView in frozen icicles.
1255         Instrumentation instrumentation = getInstrumentation();
1256         ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1257                 null, false);
1258 
1259         mActivity.runOnUiThread(new Runnable() {
1260             public void run() {
1261                 Uri uri = Uri.parse(urlSpan.getURL());
1262                 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1263                 mActivity.startActivity(intent);
1264             }
1265         });
1266 
1267         Activity newActivity = am.waitForActivityWithTimeout(TIMEOUT);
1268         assertNotNull(newActivity);
1269         newActivity.finish();
1270         instrumentation.removeMonitor(am);
1271         // the text of TextView is removed.
1272         mTextView = findTextView(R.id.freezesText_false);
1273 
1274         assertEquals(text.toString(), mTextView.getText().toString());
1275 
1276         mTextView.setFreezesText(true);
1277         assertTrue(mTextView.getFreezesText());
1278 
1279         mActivity.runOnUiThread(new Runnable() {
1280             public void run() {
1281                 mTextView.setText(text);
1282             }
1283         });
1284         mInstrumentation.waitForIdleSync();
1285         // TODO: How to simulate the TextView in frozen icicles.
1286         am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
1287                 null, false);
1288 
1289         mActivity.runOnUiThread(new Runnable() {
1290             public void run() {
1291                 Uri uri = Uri.parse(urlSpan.getURL());
1292                 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
1293                 mActivity.startActivity(intent);
1294             }
1295         });
1296 
1297         newActivity = am.waitForActivityWithTimeout(TIMEOUT);
1298         assertNotNull(newActivity);
1299         newActivity.finish();
1300         instrumentation.removeMonitor(am);
1301         // the text of TextView is still there.
1302         mTextView = findTextView(R.id.freezesText_false);
1303         assertEquals(text.toString(), mTextView.getText().toString());
1304     }
1305 
1306     @TestTargetNew(
1307         level = TestLevel.COMPLETE,
1308         method = "setEditableFactory",
1309         args = {android.text.Editable.Factory.class}
1310     )
1311     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1312             + "should add @throws clause into javadoc of "
1313             + "TextView#setEditableFactory(android.text.Editable.Factory) "
1314             + "when param factory is null")
testSetEditableFactory()1315     public void testSetEditableFactory() {
1316         mTextView = new TextView(mActivity);
1317         String text = "sample";
1318         MockEditableFactory factory = new MockEditableFactory();
1319         mTextView.setEditableFactory(factory);
1320 
1321         factory.reset();
1322         mTextView.setText(text);
1323         assertFalse(factory.hasCalledNewEditable());
1324 
1325         factory.reset();
1326         mTextView.setText(text, BufferType.SPANNABLE);
1327         assertFalse(factory.hasCalledNewEditable());
1328 
1329         factory.reset();
1330         mTextView.setText(text, BufferType.NORMAL);
1331         assertFalse(factory.hasCalledNewEditable());
1332 
1333         factory.reset();
1334         mTextView.setText(text, BufferType.EDITABLE);
1335         assertTrue(factory.hasCalledNewEditable());
1336         assertEquals(text, factory.getSource());
1337 
1338         mTextView.setKeyListener(DigitsKeyListener.getInstance());
1339         factory.reset();
1340         mTextView.setText(text, BufferType.EDITABLE);
1341         assertTrue(factory.hasCalledNewEditable());
1342         assertEquals(text, factory.getSource());
1343 
1344         try {
1345             mTextView.setEditableFactory(null);
1346             fail("The factory can not set to null!");
1347         } catch (NullPointerException e) {
1348         }
1349     }
1350 
1351     @TestTargetNew(
1352         level = TestLevel.COMPLETE,
1353         method = "setSpannableFactory",
1354         args = {android.text.Spannable.Factory.class}
1355     )
1356     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1357             + "should add @throws clause into javadoc of "
1358             + "TextView#setSpannableFactory(android.text.Spannable.Factory) "
1359             + "when param factory is null")
testSetSpannableFactory()1360     public void testSetSpannableFactory() {
1361         mTextView = new TextView(mActivity);
1362         String text = "sample";
1363         MockSpannableFactory factory = new MockSpannableFactory();
1364         mTextView.setSpannableFactory(factory);
1365 
1366         factory.reset();
1367         mTextView.setText(text);
1368         assertFalse(factory.getNewSpannableCalledCount());
1369 
1370         factory.reset();
1371         mTextView.setText(text, BufferType.EDITABLE);
1372         assertFalse(factory.getNewSpannableCalledCount());
1373 
1374         factory.reset();
1375         mTextView.setText(text, BufferType.NORMAL);
1376         assertFalse(factory.getNewSpannableCalledCount());
1377 
1378         factory.reset();
1379         mTextView.setText(text, BufferType.SPANNABLE);
1380         assertTrue(factory.getNewSpannableCalledCount());
1381         assertEquals(text, factory.getSource());
1382 
1383         mTextView.setMovementMethod(LinkMovementMethod.getInstance());
1384         factory.reset();
1385         mTextView.setText(text, BufferType.NORMAL);
1386         assertTrue(factory.getNewSpannableCalledCount());
1387         assertEquals(text, factory.getSource());
1388 
1389         try {
1390             mTextView.setSpannableFactory(null);
1391             fail("The factory can not set to null!");
1392         } catch (NullPointerException e) {
1393         }
1394     }
1395 
1396     @TestTargets({
1397         @TestTargetNew(
1398             level = TestLevel.COMPLETE,
1399             method = "addTextChangedListener",
1400             args = {android.text.TextWatcher.class}
1401         ),
1402         @TestTargetNew(
1403             level = TestLevel.COMPLETE,
1404             method = "removeTextChangedListener",
1405             args = {android.text.TextWatcher.class}
1406         )
1407     })
testTextChangedListener()1408     public void testTextChangedListener() {
1409         mTextView = new TextView(mActivity);
1410         MockTextWatcher watcher0 = new MockTextWatcher();
1411         MockTextWatcher watcher1 = new MockTextWatcher();
1412 
1413         mTextView.addTextChangedListener(watcher0);
1414         mTextView.addTextChangedListener(watcher1);
1415 
1416         watcher0.reset();
1417         watcher1.reset();
1418         mTextView.setText("Changed");
1419         assertTrue(watcher0.hasCalledBeforeTextChanged());
1420         assertTrue(watcher0.hasCalledOnTextChanged());
1421         assertTrue(watcher0.hasCalledAfterTextChanged());
1422         assertTrue(watcher1.hasCalledBeforeTextChanged());
1423         assertTrue(watcher1.hasCalledOnTextChanged());
1424         assertTrue(watcher1.hasCalledAfterTextChanged());
1425 
1426         watcher0.reset();
1427         watcher1.reset();
1428         // BeforeTextChanged and OnTextChanged are called though the strings are same
1429         mTextView.setText("Changed");
1430         assertTrue(watcher0.hasCalledBeforeTextChanged());
1431         assertTrue(watcher0.hasCalledOnTextChanged());
1432         assertTrue(watcher0.hasCalledAfterTextChanged());
1433         assertTrue(watcher1.hasCalledBeforeTextChanged());
1434         assertTrue(watcher1.hasCalledOnTextChanged());
1435         assertTrue(watcher1.hasCalledAfterTextChanged());
1436 
1437         watcher0.reset();
1438         watcher1.reset();
1439         // BeforeTextChanged and OnTextChanged are called twice (The text is not
1440         // Editable, so in Append() it calls setText() first)
1441         mTextView.append("and appended");
1442         assertTrue(watcher0.hasCalledBeforeTextChanged());
1443         assertTrue(watcher0.hasCalledOnTextChanged());
1444         assertTrue(watcher0.hasCalledAfterTextChanged());
1445         assertTrue(watcher1.hasCalledBeforeTextChanged());
1446         assertTrue(watcher1.hasCalledOnTextChanged());
1447         assertTrue(watcher1.hasCalledAfterTextChanged());
1448 
1449         watcher0.reset();
1450         watcher1.reset();
1451         // Methods are not called if the string does not change
1452         mTextView.append("");
1453         assertFalse(watcher0.hasCalledBeforeTextChanged());
1454         assertFalse(watcher0.hasCalledOnTextChanged());
1455         assertFalse(watcher0.hasCalledAfterTextChanged());
1456         assertFalse(watcher1.hasCalledBeforeTextChanged());
1457         assertFalse(watcher1.hasCalledOnTextChanged());
1458         assertFalse(watcher1.hasCalledAfterTextChanged());
1459 
1460         watcher0.reset();
1461         watcher1.reset();
1462         mTextView.removeTextChangedListener(watcher1);
1463         mTextView.setText(null);
1464         assertTrue(watcher0.hasCalledBeforeTextChanged());
1465         assertTrue(watcher0.hasCalledOnTextChanged());
1466         assertTrue(watcher0.hasCalledAfterTextChanged());
1467         assertFalse(watcher1.hasCalledBeforeTextChanged());
1468         assertFalse(watcher1.hasCalledOnTextChanged());
1469         assertFalse(watcher1.hasCalledAfterTextChanged());
1470     }
1471 
1472     @TestTargetNew(
1473         level = TestLevel.COMPLETE,
1474         method = "setTextKeepState",
1475         args = {java.lang.CharSequence.class}
1476     )
testSetTextKeepState1()1477     public void testSetTextKeepState1() {
1478         mTextView = new TextView(mActivity);
1479 
1480         String longString = "very long content";
1481         String shortString = "short";
1482 
1483         // selection is at the exact place which is inside the short string
1484         mTextView.setText(longString, BufferType.SPANNABLE);
1485         Selection.setSelection((Spannable) mTextView.getText(), 3);
1486         mTextView.setTextKeepState(shortString);
1487         assertEquals(shortString, mTextView.getText().toString());
1488         assertEquals(3, mTextView.getSelectionStart());
1489         assertEquals(3, mTextView.getSelectionEnd());
1490 
1491         // selection is at the exact place which is outside the short string
1492         mTextView.setText(longString);
1493         Selection.setSelection((Spannable) mTextView.getText(), shortString.length() + 1);
1494         mTextView.setTextKeepState(shortString);
1495         assertEquals(shortString, mTextView.getText().toString());
1496         assertEquals(shortString.length(), mTextView.getSelectionStart());
1497         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1498 
1499         // select the sub string which is inside the short string
1500         mTextView.setText(longString);
1501         Selection.setSelection((Spannable) mTextView.getText(), 1, 4);
1502         mTextView.setTextKeepState(shortString);
1503         assertEquals(shortString, mTextView.getText().toString());
1504         assertEquals(1, mTextView.getSelectionStart());
1505         assertEquals(4, mTextView.getSelectionEnd());
1506 
1507         // select the sub string which ends outside the short string
1508         mTextView.setText(longString);
1509         Selection.setSelection((Spannable) mTextView.getText(), 2, shortString.length() + 1);
1510         mTextView.setTextKeepState(shortString);
1511         assertEquals(shortString, mTextView.getText().toString());
1512         assertEquals(2, mTextView.getSelectionStart());
1513         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1514 
1515         // select the sub string which is outside the short string
1516         mTextView.setText(longString);
1517         Selection.setSelection((Spannable) mTextView.getText(),
1518                 shortString.length() + 1, shortString.length() + 3);
1519         mTextView.setTextKeepState(shortString);
1520         assertEquals(shortString, mTextView.getText().toString());
1521         assertEquals(shortString.length(), mTextView.getSelectionStart());
1522         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1523     }
1524 
1525     @TestTargetNew(
1526         level = TestLevel.COMPLETE,
1527         method = "getEditableText",
1528         args = {}
1529     )
1530     @UiThreadTest
testGetEditableText()1531     public void testGetEditableText() {
1532         TextView tv = findTextView(R.id.textview_text);
1533 
1534         String text = "Hello";
1535         tv.setText(text, BufferType.EDITABLE);
1536         assertEquals(text, tv.getText().toString());
1537         assertTrue(tv.getText() instanceof Editable);
1538         assertEquals(text, tv.getEditableText().toString());
1539 
1540         tv.setText(text, BufferType.SPANNABLE);
1541         assertEquals(text, tv.getText().toString());
1542         assertTrue(tv.getText() instanceof Spannable);
1543         assertNull(tv.getEditableText());
1544 
1545         tv.setText(null, BufferType.EDITABLE);
1546         assertEquals("", tv.getText().toString());
1547         assertTrue(tv.getText() instanceof Editable);
1548         assertEquals("", tv.getEditableText().toString());
1549 
1550         tv.setText(null, BufferType.SPANNABLE);
1551         assertEquals("", tv.getText().toString());
1552         assertTrue(tv.getText() instanceof Spannable);
1553         assertNull(tv.getEditableText());
1554     }
1555 
1556     @TestTargetNew(
1557         level = TestLevel.COMPLETE,
1558         method = "setText",
1559         args = {char[].class, int.class, int.class}
1560     )
1561     @UiThreadTest
1562     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1563             + "should add @throws clause into javadoc of "
1564             + "TextView#setText(char[], int, int) when param start or len makes "
1565             + "the index out of bounds")
testSetText2()1566     public void testSetText2() {
1567         String string = "This is a test for setting text content by char array";
1568         char[] input = string.toCharArray();
1569         TextView tv = findTextView(R.id.textview_text);
1570 
1571         tv.setText(input, 0, input.length);
1572         assertEquals(string, tv.getText().toString());
1573 
1574         tv.setText(input, 0, 5);
1575         assertEquals(string.substring(0, 5), tv.getText().toString());
1576 
1577         try {
1578             tv.setText(input, -1, input.length);
1579             fail("Should throw exception if the start position is negative!");
1580         } catch (IndexOutOfBoundsException exception) {
1581         }
1582 
1583         try {
1584             tv.setText(input, 0, -1);
1585             fail("Should throw exception if the length is negative!");
1586         } catch (IndexOutOfBoundsException exception) {
1587         }
1588 
1589         try {
1590             tv.setText(input, 1, input.length);
1591             fail("Should throw exception if the end position is out of index!");
1592         } catch (IndexOutOfBoundsException exception) {
1593         }
1594 
1595         tv.setText(input, 1, 0);
1596         assertEquals("", tv.getText().toString());
1597     }
1598 
1599     @TestTargets({
1600         @TestTargetNew(
1601             level = TestLevel.COMPLETE,
1602             method = "setText",
1603             args = {java.lang.CharSequence.class, android.widget.TextView.BufferType.class}
1604         ),
1605         @TestTargetNew(
1606             level = TestLevel.COMPLETE,
1607             method = "setTextKeepState",
1608             args = {java.lang.CharSequence.class, android.widget.TextView.BufferType.class}
1609         )
1610     })
1611     @UiThreadTest
testSetText1()1612     public void testSetText1() {
1613         mTextView = findTextView(R.id.textview_text);
1614 
1615         String longString = "very long content";
1616         String shortString = "short";
1617 
1618         // selection is at the exact place which is inside the short string
1619         mTextView.setText(longString, BufferType.SPANNABLE);
1620         Selection.setSelection((Spannable) mTextView.getText(), 3);
1621         mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1622         assertTrue(mTextView.getText() instanceof Editable);
1623         assertEquals(shortString, mTextView.getText().toString());
1624         assertEquals(shortString, mTextView.getEditableText().toString());
1625         assertEquals(3, mTextView.getSelectionStart());
1626         assertEquals(3, mTextView.getSelectionEnd());
1627 
1628         mTextView.setText(shortString, BufferType.EDITABLE);
1629         assertTrue(mTextView.getText() instanceof Editable);
1630         assertEquals(shortString, mTextView.getText().toString());
1631         assertEquals(shortString, mTextView.getEditableText().toString());
1632         // there is no selection.
1633         assertEquals(-1, mTextView.getSelectionStart());
1634         assertEquals(-1, mTextView.getSelectionEnd());
1635 
1636         // selection is at the exact place which is outside the short string
1637         mTextView.setText(longString);
1638         Selection.setSelection((Spannable) mTextView.getText(), longString.length());
1639         mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1640         assertTrue(mTextView.getText() instanceof Editable);
1641         assertEquals(shortString, mTextView.getText().toString());
1642         assertEquals(shortString, mTextView.getEditableText().toString());
1643         assertEquals(shortString.length(), mTextView.getSelectionStart());
1644         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1645 
1646         mTextView.setText(shortString, BufferType.EDITABLE);
1647         assertTrue(mTextView.getText() instanceof Editable);
1648         assertEquals(shortString, mTextView.getText().toString());
1649         assertEquals(shortString, mTextView.getEditableText().toString());
1650         // there is no selection.
1651         assertEquals(-1, mTextView.getSelectionStart());
1652         assertEquals(-1, mTextView.getSelectionEnd());
1653 
1654         // select the sub string which is inside the short string
1655         mTextView.setText(longString);
1656         Selection.setSelection((Spannable) mTextView.getText(), 1, shortString.length() - 1);
1657         mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1658         assertTrue(mTextView.getText() instanceof Editable);
1659         assertEquals(shortString, mTextView.getText().toString());
1660         assertEquals(shortString, mTextView.getEditableText().toString());
1661         assertEquals(1, mTextView.getSelectionStart());
1662         assertEquals(shortString.length() - 1, mTextView.getSelectionEnd());
1663 
1664         mTextView.setText(shortString, BufferType.EDITABLE);
1665         assertTrue(mTextView.getText() instanceof Editable);
1666         assertEquals(shortString, mTextView.getText().toString());
1667         assertEquals(shortString, mTextView.getEditableText().toString());
1668         // there is no selection.
1669         assertEquals(-1, mTextView.getSelectionStart());
1670         assertEquals(-1, mTextView.getSelectionEnd());
1671 
1672         // select the sub string which ends outside the short string
1673         mTextView.setText(longString);
1674         Selection.setSelection((Spannable) mTextView.getText(), 2, longString.length());
1675         mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1676         assertTrue(mTextView.getText() instanceof Editable);
1677         assertEquals(shortString, mTextView.getText().toString());
1678         assertEquals(shortString, mTextView.getEditableText().toString());
1679         assertEquals(2, mTextView.getSelectionStart());
1680         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1681 
1682         mTextView.setText(shortString, BufferType.EDITABLE);
1683         assertTrue(mTextView.getText() instanceof Editable);
1684         assertEquals(shortString, mTextView.getText().toString());
1685         assertEquals(shortString, mTextView.getEditableText().toString());
1686         // there is no selection.
1687         assertEquals(-1, mTextView.getSelectionStart());
1688         assertEquals(-1, mTextView.getSelectionEnd());
1689 
1690         // select the sub string which is outside the short string
1691         mTextView.setText(longString);
1692         Selection.setSelection((Spannable) mTextView.getText(),
1693                 shortString.length() + 1, shortString.length() + 3);
1694         mTextView.setTextKeepState(shortString, BufferType.EDITABLE);
1695         assertTrue(mTextView.getText() instanceof Editable);
1696         assertEquals(shortString, mTextView.getText().toString());
1697         assertEquals(shortString, mTextView.getEditableText().toString());
1698         assertEquals(shortString.length(), mTextView.getSelectionStart());
1699         assertEquals(shortString.length(), mTextView.getSelectionEnd());
1700 
1701         mTextView.setText(shortString, BufferType.EDITABLE);
1702         assertTrue(mTextView.getText() instanceof Editable);
1703         assertEquals(shortString, mTextView.getText().toString());
1704         assertEquals(shortString, mTextView.getEditableText().toString());
1705         // there is no selection.
1706         assertEquals(-1, mTextView.getSelectionStart());
1707         assertEquals(-1, mTextView.getSelectionEnd());
1708     }
1709 
1710     @TestTargetNew(
1711         level = TestLevel.COMPLETE,
1712         method = "setText",
1713         args = {int.class}
1714     )
1715     @UiThreadTest
1716     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1717             + "should add @throws clause into javadoc of "
1718             + "TextView#setText(int) when param resid is illegal")
testSetText3()1719     public void testSetText3() {
1720         TextView tv = findTextView(R.id.textview_text);
1721 
1722         int resId = R.string.text_view_hint;
1723         String result = mActivity.getResources().getString(resId);
1724 
1725         tv.setText(resId);
1726         assertEquals(result, tv.getText().toString());
1727 
1728         try {
1729             tv.setText(-1);
1730             fail("Should throw exception with illegal id");
1731         } catch (NotFoundException e) {
1732         }
1733     }
1734 
1735     @TestTargetNew(
1736         level = TestLevel.COMPLETE,
1737         method = "setText",
1738         args = {int.class, android.widget.TextView.BufferType.class}
1739     )
1740     @UiThreadTest
1741     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1742             + "should add @throws clause into javadoc of "
1743             + "TextView#setText(int, BufferType) when param resid is illegal")
testSetText()1744     public void testSetText() {
1745         TextView tv = findTextView(R.id.textview_text);
1746 
1747         int resId = R.string.text_view_hint;
1748         String result = mActivity.getResources().getString(resId);
1749 
1750         tv.setText(resId, BufferType.EDITABLE);
1751         assertEquals(result, tv.getText().toString());
1752         assertTrue(tv.getText() instanceof Editable);
1753 
1754         tv.setText(resId, BufferType.SPANNABLE);
1755         assertEquals(result, tv.getText().toString());
1756         assertTrue(tv.getText() instanceof Spannable);
1757 
1758         try {
1759             tv.setText(-1, BufferType.EDITABLE);
1760             fail("Should throw exception with illegal id");
1761         } catch (NotFoundException e) {
1762         }
1763     }
1764 
1765     @TestTargets({
1766         @TestTargetNew(
1767             level = TestLevel.COMPLETE,
1768             method = "setHint",
1769             args = {java.lang.CharSequence.class}
1770         ),
1771         @TestTargetNew(
1772             level = TestLevel.COMPLETE,
1773             method = "setHint",
1774             args = {int.class}
1775         ),
1776         @TestTargetNew(
1777             level = TestLevel.COMPLETE,
1778             method = "getHint",
1779             args = {}
1780         )
1781     })
1782     @UiThreadTest
testAccessHint()1783     public void testAccessHint() {
1784         mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext);
1785 
1786         mTextView = findTextView(R.id.hint_linksClickable_freezesText_default);
1787         assertNull(mTextView.getHint());
1788 
1789         mTextView = findTextView(R.id.hint_blank);
1790         assertEquals("", mTextView.getHint());
1791 
1792         mTextView = findTextView(R.id.hint_string);
1793         assertEquals(mActivity.getResources().getString(R.string.text_view_simple_hint),
1794                 mTextView.getHint());
1795 
1796         mTextView = findTextView(R.id.hint_resid);
1797         assertEquals(mActivity.getResources().getString(R.string.text_view_hint),
1798                 mTextView.getHint());
1799 
1800         mTextView.setHint("This is hint");
1801         assertEquals("This is hint", mTextView.getHint().toString());
1802 
1803         mTextView.setHint(R.string.text_view_hello);
1804         assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
1805                 mTextView.getHint().toString());
1806 
1807         // Non-exist resid
1808         try {
1809             mTextView.setHint(-1);
1810             fail("Should throw exception if id is illegal");
1811         } catch (NotFoundException e) {
1812         }
1813     }
1814 
1815     @TestTargets({
1816         @TestTargetNew(
1817             level = TestLevel.COMPLETE,
1818             method = "getError",
1819             args = {}
1820         ),
1821         @TestTargetNew(
1822             level = TestLevel.COMPLETE,
1823             method = "setError",
1824             args = {java.lang.CharSequence.class}
1825         ),
1826         @TestTargetNew(
1827             level = TestLevel.COMPLETE,
1828             method = "setError",
1829             args = {java.lang.CharSequence.class, android.graphics.drawable.Drawable.class}
1830         )
1831     })
testAccessError()1832     public void testAccessError() {
1833         mTextView = findTextView(R.id.textview_text);
1834         assertNull(mTextView.getError());
1835 
1836         final String errorText = "Opps! There is an error";
1837 
1838         mActivity.runOnUiThread(new Runnable() {
1839             public void run() {
1840                 mTextView.setError(null);
1841             }
1842         });
1843         mInstrumentation.waitForIdleSync();
1844         assertNull(mTextView.getError());
1845 
1846         final Drawable icon = mActivity.getResources().getDrawable(R.drawable.failed);
1847         mActivity.runOnUiThread(new Runnable() {
1848             public void run() {
1849                 mTextView.setError(errorText, icon);
1850             }
1851         });
1852         mInstrumentation.waitForIdleSync();
1853         assertEquals(errorText, mTextView.getError().toString());
1854         // can not check whether the drawable is set correctly
1855 
1856         mActivity.runOnUiThread(new Runnable() {
1857             public void run() {
1858                 mTextView.setError(null, null);
1859             }
1860         });
1861         mInstrumentation.waitForIdleSync();
1862         assertNull(mTextView.getError());
1863 
1864         final DigitsKeyListener digitsKeyListener = DigitsKeyListener.getInstance();
1865         mActivity.runOnUiThread(new Runnable() {
1866             public void run() {
1867                 mTextView.setKeyListener(digitsKeyListener);
1868                 mTextView.setText("", BufferType.EDITABLE);
1869                 mTextView.setError(errorText);
1870                 mTextView.requestFocus();
1871             }
1872         });
1873         mInstrumentation.waitForIdleSync();
1874 
1875         assertEquals(errorText, mTextView.getError().toString());
1876 
1877         sendKeys(KeyEvent.KEYCODE_A);
1878         // a key event that will not change the TextView's text
1879         assertEquals("", mTextView.getText().toString());
1880         // The icon and error message will not be reset to null
1881         assertNotNull(mTextView.getError());
1882 
1883         sendKeys(KeyEvent.KEYCODE_1);
1884         // a key event cause changes to the TextView's text
1885         assertEquals("1", mTextView.getText().toString());
1886         // the error message and icon will be cleared.
1887         assertNull(mTextView.getError());
1888     }
1889 
1890     @TestTargets({
1891         @TestTargetNew(
1892             level = TestLevel.COMPLETE,
1893             method = "setFilters",
1894             args = {android.text.InputFilter[].class}
1895         ),
1896         @TestTargetNew(
1897             level = TestLevel.COMPLETE,
1898             method = "getFilters",
1899             args = {}
1900         )
1901     })
1902     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
1903             + "should add @throws clause into javadoc of "
1904             + "TextView#setFilters(InputFilter[]) when param filters is null")
testAccessFilters()1905     public void testAccessFilters() {
1906         final InputFilter[] expected = { new InputFilter.AllCaps(),
1907                 new InputFilter.LengthFilter(2) };
1908 
1909         final QwertyKeyListener qwertyKeyListener
1910                 = QwertyKeyListener.getInstance(false, Capitalize.NONE);
1911         mActivity.runOnUiThread(new Runnable() {
1912             public void run() {
1913                 mTextView = findTextView(R.id.textview_text);
1914                 mTextView.setKeyListener(qwertyKeyListener);
1915                 mTextView.setText("", BufferType.EDITABLE);
1916                 mTextView.setFilters(expected);
1917                 mTextView.requestFocus();
1918             }
1919         });
1920         mInstrumentation.waitForIdleSync();
1921 
1922         assertSame(expected, mTextView.getFilters());
1923 
1924         sendKeys(KeyEvent.KEYCODE_A);
1925         // the text is capitalized by InputFilter.AllCaps
1926         assertEquals("A", mTextView.getText().toString());
1927         sendKeys(KeyEvent.KEYCODE_B);
1928         // the text is capitalized by InputFilter.AllCaps
1929         assertEquals("AB", mTextView.getText().toString());
1930         sendKeys(KeyEvent.KEYCODE_C);
1931         // 'C' could not be accepted, because there is a length filter.
1932         assertEquals("AB", mTextView.getText().toString());
1933 
1934         try {
1935             mTextView.setFilters(null);
1936             fail("Should throw IllegalArgumentException!");
1937         } catch (IllegalArgumentException e) {
1938         }
1939     }
1940 
1941     @TestTargetNew(
1942         level = TestLevel.COMPLETE,
1943         method = "getFocusedRect",
1944         args = {android.graphics.Rect.class}
1945     )
1946     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete,"
1947             + "should add @throws clause into javadoc of "
1948             + "TextView#getFocusedRect(Rect) when param rect is null")
testGetFocusedRect()1949     public void testGetFocusedRect() {
1950         Rect rc = new Rect();
1951 
1952         mTextView = new TextView(mActivity);
1953         mTextView.getFocusedRect(rc);
1954         assertEquals(mTextView.getScrollX(), rc.left);
1955         assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
1956         assertEquals(mTextView.getScrollY(), rc.top);
1957         assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
1958 
1959         mTextView = findTextView(R.id.textview_text);
1960         mTextView.getFocusedRect(rc);
1961         assertEquals(mTextView.getScrollX(), rc.left);
1962         assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right);
1963         assertEquals(mTextView.getScrollY(), rc.top);
1964         assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom);
1965 
1966         mActivity.runOnUiThread(new Runnable() {
1967             public void run() {
1968                 mTextView.setSelected(true);
1969                 SpannableString text = new SpannableString(mTextView.getText());
1970                 Selection.setSelection(text, 3, 13);
1971                 mTextView.setText(text);
1972             }
1973         });
1974         mInstrumentation.waitForIdleSync();
1975         mTextView.getFocusedRect(rc);
1976         assertNotNull(mTextView.getLayout());
1977         assertEquals(mTextView.getLayout().getPrimaryHorizontal(13),
1978                 (float) rc.left, 0.01f);
1979         // 'right' is one pixel larger than 'left'
1980         assertEquals(mTextView.getLayout().getPrimaryHorizontal(13) + 1,
1981                 (float) rc.right, 0.01f);
1982         assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
1983         assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
1984 
1985         // Exception
1986         try {
1987             mTextView.getFocusedRect(null);
1988             fail("Should throw NullPointerException!");
1989         } catch (NullPointerException e) {
1990         }
1991     }
1992 
1993     @TestTargetNew(
1994         level = TestLevel.COMPLETE,
1995         method = "getLineCount",
1996         args = {}
1997     )
testGetLineCount()1998     public void testGetLineCount() {
1999         mTextView = findTextView(R.id.textview_text);
2000         // this is an one line text with default setting.
2001         assertEquals(1, mTextView.getLineCount());
2002 
2003         // make it multi-lines
2004         setMaxWidth(mTextView.getWidth() / 3);
2005         assertTrue(1 < mTextView.getLineCount());
2006 
2007         // make it to an one line
2008         setMaxWidth(Integer.MAX_VALUE);
2009         assertEquals(1, mTextView.getLineCount());
2010 
2011         // set min lines don't effect the lines count for actual text.
2012         setMinLines(12);
2013         assertEquals(1, mTextView.getLineCount());
2014 
2015         mTextView = new TextView(mActivity);
2016         // the internal Layout has not been built.
2017         assertNull(mTextView.getLayout());
2018         assertEquals(0, mTextView.getLineCount());
2019     }
2020 
2021     @TestTargetNew(
2022         level = TestLevel.COMPLETE,
2023         method = "getLineBounds",
2024         args = {int.class, android.graphics.Rect.class}
2025     )
testGetLineBounds()2026     public void testGetLineBounds() {
2027         Rect rc = new Rect();
2028         mTextView = new TextView(mActivity);
2029         assertEquals(0, mTextView.getLineBounds(0, null));
2030 
2031         assertEquals(0, mTextView.getLineBounds(0, rc));
2032         assertEquals(0, rc.left);
2033         assertEquals(0, rc.right);
2034         assertEquals(0, rc.top);
2035         assertEquals(0, rc.bottom);
2036 
2037         mTextView = findTextView(R.id.textview_text);
2038         assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, null));
2039 
2040         assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2041         assertEquals(0, rc.left);
2042         assertEquals(mTextView.getWidth(), rc.right);
2043         assertEquals(0, rc.top);
2044         assertEquals(mTextView.getHeight(), rc.bottom);
2045 
2046         mActivity.runOnUiThread(new Runnable() {
2047             public void run() {
2048                 mTextView.setPadding(1, 2, 3, 4);
2049                 mTextView.setGravity(Gravity.BOTTOM);
2050             }
2051         });
2052         mInstrumentation.waitForIdleSync();
2053         assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc));
2054         assertEquals(mTextView.getTotalPaddingLeft(), rc.left);
2055         assertEquals(mTextView.getWidth() - mTextView.getTotalPaddingRight(), rc.right);
2056         assertEquals(mTextView.getTotalPaddingTop(), rc.top);
2057         assertEquals(mTextView.getHeight() - mTextView.getTotalPaddingBottom(), rc.bottom);
2058     }
2059 
2060     @TestTargetNew(
2061         level = TestLevel.COMPLETE,
2062         method = "getBaseline",
2063         args = {}
2064     )
testGetBaseLine()2065     public void testGetBaseLine() {
2066         mTextView = new TextView(mActivity);
2067         assertEquals(-1, mTextView.getBaseline());
2068 
2069         mTextView = findTextView(R.id.textview_text);
2070         assertEquals(mTextView.getLayout().getLineBaseline(0), mTextView.getBaseline());
2071 
2072         mActivity.runOnUiThread(new Runnable() {
2073             public void run() {
2074                 mTextView.setPadding(1, 2, 3, 4);
2075                 mTextView.setGravity(Gravity.BOTTOM);
2076             }
2077         });
2078         mInstrumentation.waitForIdleSync();
2079         int expected = mTextView.getTotalPaddingTop() + mTextView.getLayout().getLineBaseline(0);
2080         assertEquals(expected, mTextView.getBaseline());
2081     }
2082 
2083     @TestTargets({
2084         @TestTargetNew(
2085             level = TestLevel.COMPLETE,
2086             method = "onKeyDown",
2087             args = {int.class, android.view.KeyEvent.class}
2088         ),
2089         @TestTargetNew(
2090             level = TestLevel.COMPLETE,
2091             method = "onKeyUp",
2092             args = {int.class, android.view.KeyEvent.class}
2093         )
2094     })
testPressKey()2095     public void testPressKey() {
2096         final QwertyKeyListener qwertyKeyListener
2097                 = QwertyKeyListener.getInstance(false, Capitalize.NONE);
2098         mActivity.runOnUiThread(new Runnable() {
2099             public void run() {
2100                 mTextView = findTextView(R.id.textview_text);
2101                 mTextView.setKeyListener(qwertyKeyListener);
2102                 mTextView.setText("", BufferType.EDITABLE);
2103                 mTextView.requestFocus();
2104             }
2105         });
2106         mInstrumentation.waitForIdleSync();
2107 
2108         sendKeys(KeyEvent.KEYCODE_A);
2109         assertEquals("a", mTextView.getText().toString());
2110         sendKeys(KeyEvent.KEYCODE_B);
2111         assertEquals("ab", mTextView.getText().toString());
2112         sendKeys(KeyEvent.KEYCODE_DEL);
2113         assertEquals("a", mTextView.getText().toString());
2114     }
2115 
2116     @TestTargetNew(
2117         level = TestLevel.COMPLETE,
2118         method = "setIncludeFontPadding",
2119         args = {boolean.class}
2120     )
testSetIncludeFontPadding()2121     public void testSetIncludeFontPadding() {
2122         mTextView = findTextView(R.id.textview_text);
2123         mActivity.runOnUiThread(new Runnable() {
2124             public void run() {
2125                 mTextView.setWidth(mTextView.getWidth() / 3);
2126                 mTextView.setPadding(1, 2, 3, 4);
2127                 mTextView.setGravity(Gravity.BOTTOM);
2128             }
2129         });
2130         mInstrumentation.waitForIdleSync();
2131 
2132         int oldHeight = mTextView.getHeight();
2133         mActivity.runOnUiThread(new Runnable() {
2134             public void run() {
2135                 mTextView.setIncludeFontPadding(false);
2136             }
2137         });
2138         mInstrumentation.waitForIdleSync();
2139 
2140         assertTrue(mTextView.getHeight() < oldHeight);
2141     }
2142 
2143     @TestTargets({
2144         @TestTargetNew(
2145             level = TestLevel.COMPLETE,
2146             method = "computeScroll",
2147             args = {}
2148         ),
2149         @TestTargetNew(
2150             level = TestLevel.COMPLETE,
2151             method = "setScroller",
2152             args = {android.widget.Scroller.class}
2153         )
2154     })
2155     public void testScroll() {
2156         mTextView = new TextView(mActivity);
2157 
2158         assertEquals(0, mTextView.getScrollX());
2159         assertEquals(0, mTextView.getScrollY());
2160 
2161         //don't set the Scroller, nothing changed.
2162         mTextView.computeScroll();
2163         assertEquals(0, mTextView.getScrollX());
2164         assertEquals(0, mTextView.getScrollY());
2165 
2166         //set the Scroller
2167         Scroller s = new Scroller(mActivity);
2168         assertNotNull(s);
2169         s.startScroll(0, 0, 320, 480, 0);
2170         s.abortAnimation();
2171         s.forceFinished(false);
2172         mTextView.setScroller(s);
2173 
2174         mTextView.computeScroll();
2175         assertEquals(320, mTextView.getScrollX());
2176         assertEquals(480, mTextView.getScrollY());
2177     }
2178 
2179     @TestTargetNew(
2180         level = TestLevel.COMPLETE,
2181         method = "debug",
2182         args = {int.class}
2183     )
2184     public void testDebug() {
2185         mTextView = new TextView(mActivity);
2186         mTextView.debug(0);
2187 
2188         mTextView.setText("Hello!");
2189         layout(mTextView);
2190         mTextView.debug(1);
2191     }
2192 
2193     @TestTargets({
2194         @TestTargetNew(
2195             level = TestLevel.COMPLETE,
2196             method = "getSelectionStart",
2197             args = {}
2198         ),
2199         @TestTargetNew(
2200             level = TestLevel.COMPLETE,
2201             method = "getSelectionEnd",
2202             args = {}
2203         ),
2204         @TestTargetNew(
2205             level = TestLevel.COMPLETE,
2206             method = "hasSelection",
2207             args = {}
2208         )
2209     })
2210     public void testSelection() {
2211         mTextView = new TextView(mActivity);
2212         String text = "This is the content";
2213         mTextView.setText(text, BufferType.SPANNABLE);
2214         assertFalse(mTextView.hasSelection());
2215 
2216         Selection.selectAll((Spannable) mTextView.getText());
2217         assertEquals(0, mTextView.getSelectionStart());
2218         assertEquals(text.length(), mTextView.getSelectionEnd());
2219         assertTrue(mTextView.hasSelection());
2220 
2221         int selectionStart = 5;
2222         int selectionEnd = 7;
2223         Selection.setSelection((Spannable) mTextView.getText(), selectionStart);
2224         assertEquals(selectionStart, mTextView.getSelectionStart());
2225         assertEquals(selectionStart, mTextView.getSelectionEnd());
2226         assertFalse(mTextView.hasSelection());
2227 
2228         Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
2229         assertEquals(selectionStart, mTextView.getSelectionStart());
2230         assertEquals(selectionEnd, mTextView.getSelectionEnd());
2231         assertTrue(mTextView.hasSelection());
2232     }
2233 
2234     @TestTargets({
2235         @TestTargetNew(
2236             level = TestLevel.COMPLETE,
2237             method = "setEllipsize",
2238             args = {android.text.TextUtils.TruncateAt.class}
2239         ),
2240         @TestTargetNew(
2241             level = TestLevel.COMPLETE,
2242             method = "getEllipsize",
2243             args = {}
2244         )
2245     })
2246     @UiThreadTest
2247     public void testAccessEllipsize() {
2248         mActivity.setContentView(R.layout.textview_ellipsize);
2249 
2250         mTextView = findTextView(R.id.ellipsize_default);
2251         assertNull(mTextView.getEllipsize());
2252 
2253         mTextView = findTextView(R.id.ellipsize_none);
2254         assertNull(mTextView.getEllipsize());
2255 
2256         mTextView = findTextView(R.id.ellipsize_start);
2257         assertSame(TruncateAt.START, mTextView.getEllipsize());
2258 
2259         mTextView = findTextView(R.id.ellipsize_middle);
2260         assertSame(TruncateAt.MIDDLE, mTextView.getEllipsize());
2261 
2262         mTextView = findTextView(R.id.ellipsize_end);
2263         assertSame(TruncateAt.END, mTextView.getEllipsize());
2264 
2265         mTextView.setEllipsize(TextUtils.TruncateAt.START);
2266         assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2267 
2268         mTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
2269         assertSame(TextUtils.TruncateAt.MIDDLE, mTextView.getEllipsize());
2270 
2271         mTextView.setEllipsize(TextUtils.TruncateAt.END);
2272         assertSame(TextUtils.TruncateAt.END, mTextView.getEllipsize());
2273 
2274         mTextView.setEllipsize(null);
2275         assertNull(mTextView.getEllipsize());
2276 
2277         mTextView.setWidth(10);
2278         mTextView.setEllipsize(TextUtils.TruncateAt.START);
2279         mTextView.setText("ThisIsAVeryLongVeryLongVeryLongVeryLongVeryLongWord");
2280         mTextView.invalidate();
2281 
2282         assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize());
2283         // there is no method to check if '...yLongVeryLongWord' is painted in the screen.
2284     }
2285 
2286     @TestTargetNew(
2287         level = TestLevel.COMPLETE,
2288         method = "setCursorVisible",
2289         args = {boolean.class}
2290     )
2291     @ToBeFixed(bug = "1386429", explanation="No getter to check the value.")
2292     public void testSetCursorVisible() {
2293         mTextView = new TextView(mActivity);
2294 
2295         mTextView.setCursorVisible(true);
2296         mTextView.setCursorVisible(false);
2297     }
2298 
2299     @TestTargetNew(
2300         level = TestLevel.NOT_NECESSARY,
2301         method = "onWindowFocusChanged",
2302         args = {boolean.class}
2303     )
2304     public void testOnWindowFocusChanged() {
2305         // Do not test. Implementation details.
2306     }
2307 
2308     @TestTargetNew(
2309         level = TestLevel.NOT_NECESSARY,
2310         method = "onTouchEvent",
2311         args = {android.view.MotionEvent.class}
2312     )
2313     public void testOnTouchEvent() {
2314         // Do not test. Implementation details.
2315     }
2316 
2317     @TestTargetNew(
2318         level = TestLevel.NOT_NECESSARY,
2319         method = "onTrackballEvent",
2320         args = {android.view.MotionEvent.class}
2321     )
2322     public void testOnTrackballEvent() {
2323         // Do not test. Implementation details.
2324     }
2325 
2326     @TestTargetNew(
2327         level = TestLevel.SUFFICIENT,
2328         method = "getTextColors",
2329         args = {android.content.Context.class, android.content.res.TypedArray.class}
2330     )
2331     public void testGetTextColors() {
2332         // TODO: How to get a suitable TypedArray to test this method.
2333     }
2334 
2335     @TestTargetNew(
2336         level = TestLevel.NOT_NECESSARY,
2337         method = "onKeyShortcut",
2338         args = {int.class, android.view.KeyEvent.class}
2339     )
2340     public void testOnKeyShortcut() {
2341         // Do not test. Implementation details.
2342     }
2343 
2344     @TestTargetNew(
2345         level = TestLevel.COMPLETE,
2346         method = "performLongClick",
2347         args = {}
2348     )
2349     @UiThreadTest
2350     public void testPerformLongClick() {
2351         mTextView = findTextView(R.id.textview_text);
2352         mTextView.setText("This is content");
2353         MockOnLongClickListener onLongClickListener = new MockOnLongClickListener(true);
2354         MockOnCreateContextMenuListener onCreateContextMenuListener
2355                 = new MockOnCreateContextMenuListener(false);
2356         mTextView.setOnLongClickListener(onLongClickListener);
2357         mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener);
2358         assertTrue(mTextView.performLongClick());
2359         assertTrue(onLongClickListener.hasLongClicked());
2360         assertFalse(onCreateContextMenuListener.hasCreatedContextMenu());
2361 
2362         onLongClickListener = new MockOnLongClickListener(false);
2363         mTextView.setOnLongClickListener(onLongClickListener);
2364         mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener);
2365         assertTrue(mTextView.performLongClick());
2366         assertTrue(onLongClickListener.hasLongClicked());
2367         assertTrue(onCreateContextMenuListener.hasCreatedContextMenu());
2368 
2369         mTextView.setOnLongClickListener(null);
2370         onCreateContextMenuListener = new MockOnCreateContextMenuListener(true);
2371         mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener);
2372         assertFalse(mTextView.performLongClick());
2373         assertTrue(onCreateContextMenuListener.hasCreatedContextMenu());
2374     }
2375 
2376     @TestTargets({
2377         @TestTargetNew(
2378             level = TestLevel.COMPLETE,
2379             method = "getText",
2380             args = {}
2381         ),
2382         @TestTargetNew(
2383             level = TestLevel.COMPLETE,
2384             method = "getCurrentHintTextColor",
2385             args = {}
2386         ),
2387         @TestTargetNew(
2388             level = TestLevel.COMPLETE,
2389             method = "getCurrentTextColor",
2390             args = {}
2391         ),
2392         @TestTargetNew(
2393             level = TestLevel.COMPLETE,
2394             method = "getLinkTextColors",
2395             args = {}
2396         ),
2397         @TestTargetNew(
2398             level = TestLevel.COMPLETE,
2399             method = "getTextScaleX",
2400             args = {}
2401         ),
2402         @TestTargetNew(
2403             level = TestLevel.COMPLETE,
2404             method = "getTextSize",
2405             args = {}
2406         ),
2407         @TestTargetNew(
2408             level = TestLevel.COMPLETE,
2409             method = "getTypeface",
2410             args = {}
2411         ),
2412         @TestTargetNew(
2413             level = TestLevel.COMPLETE,
2414             method = "getHintTextColors",
2415             args = {}
2416         ),
2417         @TestTargetNew(
2418             level = TestLevel.COMPLETE,
2419             method = "setTextScaleX",
2420             args = {float.class}
2421         ),
2422         @TestTargetNew(
2423             level = TestLevel.COMPLETE,
2424             method = "setTypeface",
2425             args = {android.graphics.Typeface.class}
2426         ),
2427         @TestTargetNew(
2428             level = TestLevel.COMPLETE,
2429             method = "setTypeface",
2430             args = {android.graphics.Typeface.class, int.class}
2431         )
2432     })
2433     @UiThreadTest
2434     @ToBeFixed(bug = "1386429", explanation = "mTextView.getTypeface() will be null "
2435             + "if typeface didn't be set or set to normal "
2436             + "and style didn't set or set to normal in xml."
2437             + "And there is no getter to check the highlight colour.")
2438     public void testTextAttr() {
2439         mTextView = findTextView(R.id.textview_textAttr);
2440         // getText
2441         assertEquals(mActivity.getString(R.string.text_view_hello), mTextView.getText().toString());
2442 
2443         // getCurrentTextColor
2444         assertEquals(mActivity.getResources().getColor(R.drawable.black),
2445                 mTextView.getCurrentTextColor());
2446         assertEquals(mActivity.getResources().getColor(R.drawable.red),
2447                 mTextView.getCurrentHintTextColor());
2448         assertEquals(mActivity.getResources().getColor(R.drawable.red),
2449                 mTextView.getHintTextColors().getDefaultColor());
2450         assertEquals(mActivity.getResources().getColor(R.drawable.blue),
2451                 mTextView.getLinkTextColors().getDefaultColor());
2452 
2453         // getTextScaleX
2454         assertEquals(1.2f, mTextView.getTextScaleX(), 0.01f);
2455 
2456         // setTextScaleX
2457         mTextView.setTextScaleX(2.4f);
2458         assertEquals(2.4f, mTextView.getTextScaleX(), 0.01f);
2459 
2460         mTextView.setTextScaleX(0f);
2461         assertEquals(0f, mTextView.getTextScaleX(), 0.01f);
2462 
2463         mTextView.setTextScaleX(- 2.4f);
2464         assertEquals(- 2.4f, mTextView.getTextScaleX(), 0.01f);
2465 
2466         // getTextSize
2467         assertEquals(20f, mTextView.getTextSize(), 0.01f);
2468 
2469         // getTypeface
2470         // getTypeface will be null if android:typeface is not set or is set to normal,
2471         // and android:style is not set or is set to normal
2472         assertNull(mTextView.getTypeface());
2473 
2474         mTextView.setTypeface(Typeface.DEFAULT);
2475         assertSame(Typeface.DEFAULT, mTextView.getTypeface());
2476         // null type face
2477         mTextView.setTypeface(null);
2478         assertNull(mTextView.getTypeface());
2479 
2480         // default type face, bold style, note: the type face will be changed
2481         // after call set method
2482         mTextView.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
2483         assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
2484 
2485         // null type face, BOLD style
2486         mTextView.setTypeface(null, Typeface.BOLD);
2487         assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle());
2488 
2489         // old type face, null style
2490         mTextView.setTypeface(Typeface.DEFAULT, 0);
2491         assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
2492     }
2493 
2494     @TestTargets({
2495         @TestTargetNew(
2496             level = TestLevel.COMPLETE,
2497             method = "append",
2498             args = {java.lang.CharSequence.class}
2499         ),
2500         @TestTargetNew(
2501             level = TestLevel.COMPLETE,
2502             method = "append",
2503             args = {java.lang.CharSequence.class, int.class, int.class}
2504         )
2505     })
2506     @UiThreadTest
2507     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
2508             + "should add @throws clause into javadoc of "
2509             + "TextView#append(CharSequence) when param text is null and should "
2510             + "add @throws clause into javadoc of TextView#append(CharSequence, int, int) "
2511             + "when param start or end is out of bounds")
2512     public void testAppend() {
2513         mTextView = new TextView(mActivity);
2514 
2515         // 1: check the original length, should be blank as initialised.
2516         assertEquals(0, mTextView.getText().length());
2517 
2518         // 2: append a string use append(CharSquence) into the original blank
2519         // buffer, check the content. And upgrading it to BufferType.EDITABLE if it was
2520         // not already editable.
2521         assertFalse(mTextView.getText() instanceof Editable);
2522         mTextView.append("Append.");
2523         assertEquals("Append.", mTextView.getText().toString());
2524         assertTrue(mTextView.getText() instanceof Editable);
2525 
2526         // 3: append a string from 0~3.
2527         mTextView.append("Append", 0, 3);
2528         assertEquals("Append.App", mTextView.getText().toString());
2529         assertTrue(mTextView.getText() instanceof Editable);
2530 
2531         // 4: append a string from 0~0, nothing will be append as expected.
2532         mTextView.append("Append", 0, 0);
2533         assertEquals("Append.App", mTextView.getText().toString());
2534         assertTrue(mTextView.getText() instanceof Editable);
2535 
2536         // 5: append a string from -3~3. check the wrong left edge.
2537         try {
2538             mTextView.append("Append", -3, 3);
2539             fail("Should throw StringIndexOutOfBoundsException");
2540         } catch (StringIndexOutOfBoundsException e) {
2541         }
2542 
2543         // 6: append a string from 3~10. check the wrong right edge.
2544         try {
2545             mTextView.append("Append", 3, 10);
2546             fail("Should throw StringIndexOutOfBoundsException");
2547         } catch (StringIndexOutOfBoundsException e) {
2548         }
2549 
2550         // 7: append a null string.
2551         try {
2552             mTextView.append(null);
2553             fail("Should throw NullPointerException");
2554         } catch (NullPointerException e) {
2555         }
2556     }
2557 
2558     @TestTargets({
2559         @TestTargetNew(
2560             level = TestLevel.COMPLETE,
2561             method = "getTransformationMethod",
2562             args = {}
2563         ),
2564         @TestTargetNew(
2565             level = TestLevel.COMPLETE,
2566             method = "setTransformationMethod",
2567             args = {android.text.method.TransformationMethod.class}
2568         )
2569     })
2570     public void testAccessTransformationMethod() {
2571         // check the password attribute in xml
2572         mTextView = findTextView(R.id.textview_password);
2573         assertNotNull(mTextView);
2574         assertSame(PasswordTransformationMethod.getInstance(),
2575                 mTextView.getTransformationMethod());
2576 
2577         // check the singleLine attribute in xml
2578         mTextView = findTextView(R.id.textview_singleLine);
2579         assertNotNull(mTextView);
2580         assertSame(SingleLineTransformationMethod.getInstance(),
2581                 mTextView.getTransformationMethod());
2582 
2583         final QwertyKeyListener qwertyKeyListener = QwertyKeyListener.getInstance(false,
2584                 Capitalize.NONE);
2585         final TransformationMethod method = PasswordTransformationMethod.getInstance();
2586         // change transformation method by function
2587         mActivity.runOnUiThread(new Runnable() {
2588             public void run() {
2589                 mTextView.setKeyListener(qwertyKeyListener);
2590                 mTextView.setTransformationMethod(method);
2591 
2592                 mTextView.requestFocus();
2593             }
2594         });
2595         mInstrumentation.waitForIdleSync();
2596         assertSame(PasswordTransformationMethod.getInstance(),
2597                 mTextView.getTransformationMethod());
2598 
2599         sendKeys("H E 2*L O");
2600         mActivity.runOnUiThread(new Runnable() {
2601             public void run() {
2602                 mTextView.append(" ");
2603             }
2604         });
2605         mInstrumentation.waitForIdleSync();
2606 
2607         // it will get transformed after a while
2608         new DelayedCheck(TIMEOUT) {
2609             @Override
2610             protected boolean check() {
2611                 String transformed =
2612                     method.getTransformation(mTextView.getText(), mTextView).toString();
2613                 // "******"
2614                 return transformed.equals("\u2022\u2022\u2022\u2022\u2022\u2022");
2615             }
2616         }.run();
2617 
2618         // set null
2619         mActivity.runOnUiThread(new Runnable() {
2620             public void run() {
2621                 mTextView.setTransformationMethod(null);
2622             }
2623         });
2624         mInstrumentation.waitForIdleSync();
2625         assertNull(mTextView.getTransformationMethod());
2626     }
2627 
2628     @TestTargets({
2629         @TestTargetNew(
2630             level = TestLevel.COMPLETE,
2631             method = "setCompoundDrawablePadding",
2632             args = {int.class}
2633         ),
2634         @TestTargetNew(
2635             level = TestLevel.COMPLETE,
2636             method = "setCompoundDrawables",
2637             args = {Drawable.class, Drawable.class, Drawable.class, Drawable.class}
2638         ),
2639         @TestTargetNew(
2640             level = TestLevel.COMPLETE,
2641             method = "setCompoundDrawablesWithIntrinsicBounds",
2642             args = {Drawable.class, Drawable.class, Drawable.class, Drawable.class}
2643         ),
2644         @TestTargetNew(
2645             level = TestLevel.COMPLETE,
2646             method = "setCompoundDrawablesWithIntrinsicBounds",
2647             args = {int.class, int.class, int.class, int.class}
2648         ),
2649         @TestTargetNew(
2650             level = TestLevel.COMPLETE,
2651             method = "getCompoundDrawablePadding",
2652             args = {}
2653         ),
2654         @TestTargetNew(
2655             level = TestLevel.COMPLETE,
2656             method = "getCompoundDrawables",
2657             args = {}
2658         ),
2659         @TestTargetNew(
2660             level = TestLevel.COMPLETE,
2661             method = "getCompoundPaddingBottom",
2662             args = {}
2663         ),
2664         @TestTargetNew(
2665             level = TestLevel.COMPLETE,
2666             method = "getCompoundPaddingLeft",
2667             args = {}
2668         ),
2669         @TestTargetNew(
2670             level = TestLevel.COMPLETE,
2671             method = "getCompoundPaddingRight",
2672             args = {}
2673         ),
2674         @TestTargetNew(
2675             level = TestLevel.COMPLETE,
2676             method = "getCompoundPaddingTop",
2677             args = {}
2678         )
2679     })
2680     @UiThreadTest
2681     public void testCompound() {
2682         mTextView = new TextView(mActivity);
2683         int padding = 3;
2684         Drawable[] drawables = mTextView.getCompoundDrawables();
2685         assertNull(drawables[0]);
2686         assertNull(drawables[1]);
2687         assertNull(drawables[2]);
2688         assertNull(drawables[3]);
2689 
2690         // test setCompoundDrawablePadding and getCompoundDrawablePadding
2691         mTextView.setCompoundDrawablePadding(padding);
2692         assertEquals(padding, mTextView.getCompoundDrawablePadding());
2693 
2694         // using resid, 0 represents null
2695         mTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.start, R.drawable.pass,
2696                 R.drawable.failed, 0);
2697         drawables = mTextView.getCompoundDrawables();
2698 
2699         // drawableLeft
2700         WidgetTestUtils.assertEquals(getBitmap(R.drawable.start),
2701                 ((BitmapDrawable) drawables[0]).getBitmap());
2702         // drawableTop
2703         WidgetTestUtils.assertEquals(getBitmap(R.drawable.pass),
2704                 ((BitmapDrawable) drawables[1]).getBitmap());
2705         // drawableRight
2706         WidgetTestUtils.assertEquals(getBitmap(R.drawable.failed),
2707                 ((BitmapDrawable) drawables[2]).getBitmap());
2708         // drawableBottom
2709         assertNull(drawables[3]);
2710 
2711         Drawable left = mActivity.getResources().getDrawable(R.drawable.blue);
2712         Drawable right = mActivity.getResources().getDrawable(R.drawable.yellow);
2713         Drawable top = mActivity.getResources().getDrawable(R.drawable.red);
2714 
2715         // using drawables directly
2716         mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, null);
2717         drawables = mTextView.getCompoundDrawables();
2718 
2719         // drawableLeft
2720         assertSame(left, drawables[0]);
2721         // drawableTop
2722         assertSame(top, drawables[1]);
2723         // drawableRight
2724         assertSame(right, drawables[2]);
2725         // drawableBottom
2726         assertNull(drawables[3]);
2727 
2728         // check compound padding
2729         assertEquals(mTextView.getPaddingLeft() + padding + left.getIntrinsicWidth(),
2730                 mTextView.getCompoundPaddingLeft());
2731         assertEquals(mTextView.getPaddingTop() + padding + top.getIntrinsicHeight(),
2732                 mTextView.getCompoundPaddingTop());
2733         assertEquals(mTextView.getPaddingRight() + padding + right.getIntrinsicWidth(),
2734                 mTextView.getCompoundPaddingRight());
2735         assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
2736 
2737         // set bounds to drawables and set them again.
2738         left.setBounds(0, 0, 1, 2);
2739         right.setBounds(0, 0, 3, 4);
2740         top.setBounds(0, 0, 5, 6);
2741         // usinf drawables
2742         mTextView.setCompoundDrawables(left, top, right, null);
2743         drawables = mTextView.getCompoundDrawables();
2744 
2745         // drawableLeft
2746         assertSame(left, drawables[0]);
2747         // drawableTop
2748         assertSame(top, drawables[1]);
2749         // drawableRight
2750         assertSame(right, drawables[2]);
2751         // drawableBottom
2752         assertNull(drawables[3]);
2753 
2754         // check compound padding
2755         assertEquals(mTextView.getPaddingLeft() + padding + left.getBounds().width(),
2756                 mTextView.getCompoundPaddingLeft());
2757         assertEquals(mTextView.getPaddingTop() + padding + top.getBounds().height(),
2758                 mTextView.getCompoundPaddingTop());
2759         assertEquals(mTextView.getPaddingRight() + padding + right.getBounds().width(),
2760                 mTextView.getCompoundPaddingRight());
2761         assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom());
2762     }
2763 
2764     @TestTargets({
2765         @TestTargetNew(
2766             level = TestLevel.COMPLETE,
2767             method = "setSingleLine",
2768             args = {}
2769         ),
2770         @TestTargetNew(
2771             level = TestLevel.COMPLETE,
2772             method = "setSingleLine",
2773             args = {boolean.class}
2774         )
2775     })
2776     public void testSingleLine() {
2777         // singleLine
2778         mTextView = findTextView(R.id.textview_singleLine);
2779         setSpannableText(mTextView, "This is a really long sentence"
2780                         + " which can not be placed in one line on the screen.");
2781 
2782         assertEquals(SingleLineTransformationMethod.getInstance(),
2783                 mTextView.getTransformationMethod());
2784         int singleLineWidth = mTextView.getLayout().getWidth();
2785         int singleLineHeight = mTextView.getLayout().getHeight();
2786 
2787         mActivity.runOnUiThread(new Runnable() {
2788             public void run() {
2789                 mTextView.setSingleLine(false);
2790             }
2791         });
2792         mInstrumentation.waitForIdleSync();
2793         assertEquals(null, mTextView.getTransformationMethod());
2794         assertTrue(mTextView.getLayout().getHeight() > singleLineHeight);
2795         assertTrue(mTextView.getLayout().getWidth() < singleLineWidth);
2796 
2797         // same behaviours as setSingLine(true)
2798         mActivity.runOnUiThread(new Runnable() {
2799             public void run() {
2800                 mTextView.setSingleLine();
2801             }
2802         });
2803         mInstrumentation.waitForIdleSync();
2804         assertEquals(SingleLineTransformationMethod.getInstance(),
2805                 mTextView.getTransformationMethod());
2806         assertEquals(singleLineHeight, mTextView.getLayout().getHeight());
2807         assertEquals(singleLineWidth, mTextView.getLayout().getWidth());
2808     }
2809 
2810     @TestTargetNew(
2811         level = TestLevel.COMPLETE,
2812         method = "setMaxLines",
2813         args = {int.class}
2814     )
2815     @UiThreadTest
2816     public void testSetMaxLines() {
2817         mTextView = findTextView(R.id.textview_text);
2818 
2819         float[] widths = new float[LONG_TEXT.length()];
2820         mTextView.getPaint().getTextWidths(LONG_TEXT, widths);
2821         float totalWidth = 0.0f;
2822         for (float f : widths) {
2823             totalWidth += f;
2824         }
2825         final int stringWidth = (int) totalWidth;
2826         mTextView.setWidth(stringWidth >> 2);
2827         mTextView.setText(LONG_TEXT);
2828 
2829         final int maxLines = 2;
2830         assertTrue(mTextView.getLineCount() > maxLines);
2831 
2832         mTextView.setMaxLines(maxLines);
2833         mTextView.requestLayout();
2834 
2835         assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight());
2836     }
2837 
2838     @TestTargetNew(
2839         level = TestLevel.COMPLETE,
2840         method = "setMaxLines",
2841         args = {int.class}
2842     )
2843     @UiThreadTest
2844     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
2845             + "this method should not accept neagtive values as maximum line count")
testSetMaxLinesException()2846     public void testSetMaxLinesException() {
2847         mTextView = new TextView(mActivity);
2848         mActivity.setContentView(mTextView);
2849         mTextView.setWidth(mTextView.getWidth() >> 3);
2850         mTextView.setMaxLines(-1);
2851     }
2852 
2853     @TestTargetNew(
2854         level = TestLevel.COMPLETE,
2855         method = "setMinLines",
2856         args = {int.class}
2857     )
testSetMinLines()2858     public void testSetMinLines() {
2859         mTextView = findTextView(R.id.textview_text);
2860         setWidth(mTextView.getWidth() >> 3);
2861         int originalHeight = mTextView.getHeight();
2862         int originalLines = mTextView.getLineCount();
2863 
2864         // Normal input
2865         setMinLines(originalLines - 1);
2866         assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
2867 
2868         setMinLines(originalLines + 1);
2869         assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
2870 
2871         // Edge input
2872         setMinLines(-1);
2873         assertEquals(originalHeight, mTextView.getHeight());
2874 
2875         setMinLines(Integer.MAX_VALUE);
2876         assertEquals(0, mTextView.getHeight());
2877     }
2878 
2879     @TestTargetNew(
2880         level = TestLevel.COMPLETE,
2881         method = "setLines",
2882         args = {int.class}
2883     )
testSetLines()2884     public void testSetLines() {
2885         mTextView = findTextView(R.id.textview_text);
2886         // make it multiple lines
2887         setWidth(mTextView.getWidth() >> 3);
2888         int originalLines = mTextView.getLineCount();
2889 
2890         setLines(originalLines - 1);
2891         assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight());
2892 
2893         setLines(originalLines + 1);
2894         assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight());
2895     }
2896 
2897     @TestTargetNew(
2898         level = TestLevel.COMPLETE,
2899         method = "setLines",
2900         args = {int.class}
2901     )
2902     @UiThreadTest
2903     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete, "
2904             + "this method should not accept neagtive values as maximum line count")
testSetLinesException()2905     public void testSetLinesException() {
2906         mTextView = new TextView(mActivity);
2907         mActivity.setContentView(mTextView);
2908         mTextView.setWidth(mTextView.getWidth() >> 3);
2909         mTextView.setLines(-1);
2910     }
2911 
2912     @TestTargetNew(
2913         level = TestLevel.COMPLETE,
2914         method = "getExtendedPaddingTop",
2915         args = {}
2916     )
2917     @UiThreadTest
testGetExtendedPaddingTop()2918     public void testGetExtendedPaddingTop() {
2919         mTextView = findTextView(R.id.textview_text);
2920         // Initialized value
2921         assertEquals(0, mTextView.getExtendedPaddingTop());
2922 
2923         // After Set a Drawable
2924         final Drawable top = mActivity.getResources().getDrawable(R.drawable.red);
2925         top.setBounds(0, 0, 100, 10);
2926         mTextView.setCompoundDrawables(null, top, null, null);
2927         assertEquals(mTextView.getCompoundPaddingTop(), mTextView.getExtendedPaddingTop());
2928 
2929         // Change line count
2930         mTextView.setLines(mTextView.getLineCount() - 1);
2931         mTextView.setGravity(Gravity.BOTTOM);
2932 
2933         assertTrue(mTextView.getExtendedPaddingTop() > 0);
2934     }
2935 
2936     @TestTargetNew(
2937         level = TestLevel.COMPLETE,
2938         method = "getExtendedPaddingBottom",
2939         args = {}
2940     )
2941     @UiThreadTest
testGetExtendedPaddingBottom()2942     public void testGetExtendedPaddingBottom() {
2943         mTextView = findTextView(R.id.textview_text);
2944         // Initialized value
2945         assertEquals(0, mTextView.getExtendedPaddingBottom());
2946 
2947         // After Set a Drawable
2948         final Drawable bottom = mActivity.getResources().getDrawable(R.drawable.red);
2949         bottom.setBounds(0, 0, 100, 10);
2950         mTextView.setCompoundDrawables(null, null, null, bottom);
2951         assertEquals(mTextView.getCompoundPaddingBottom(), mTextView.getExtendedPaddingBottom());
2952 
2953         // Change line count
2954         mTextView.setLines(mTextView.getLineCount() - 1);
2955         mTextView.setGravity(Gravity.CENTER_VERTICAL);
2956 
2957         assertTrue(mTextView.getExtendedPaddingBottom() > 0);
2958     }
2959 
2960     @TestTargetNew(
2961         level = TestLevel.COMPLETE,
2962         method = "getTotalPaddingTop",
2963         args = {}
2964     )
testGetTotalPaddingTop()2965     public void testGetTotalPaddingTop() {
2966         mTextView = findTextView(R.id.textview_text);
2967         // Initialized value
2968         assertEquals(0, mTextView.getTotalPaddingTop());
2969 
2970         // After Set a Drawable
2971         final Drawable top = mActivity.getResources().getDrawable(R.drawable.red);
2972         top.setBounds(0, 0, 100, 10);
2973         mActivity.runOnUiThread(new Runnable() {
2974             public void run() {
2975                 mTextView.setCompoundDrawables(null, top, null, null);
2976                 mTextView.setLines(mTextView.getLineCount() - 1);
2977                 mTextView.setGravity(Gravity.BOTTOM);
2978             }
2979         });
2980         mInstrumentation.waitForIdleSync();
2981         assertEquals(mTextView.getExtendedPaddingTop(), mTextView.getTotalPaddingTop());
2982 
2983         // Change line count
2984         setLines(mTextView.getLineCount() + 1);
2985         int expected = mTextView.getHeight()
2986                 - mTextView.getExtendedPaddingBottom()
2987                 - mTextView.getLayout().getLineTop(mTextView.getLineCount());
2988         assertEquals(expected, mTextView.getTotalPaddingTop());
2989     }
2990 
2991     @TestTargetNew(
2992         level = TestLevel.COMPLETE,
2993         method = "getTotalPaddingBottom",
2994         args = {}
2995     )
testGetTotalPaddingBottom()2996     public void testGetTotalPaddingBottom() {
2997         mTextView = findTextView(R.id.textview_text);
2998         // Initialized value
2999         assertEquals(0, mTextView.getTotalPaddingBottom());
3000 
3001         // After Set a Drawable
3002         final Drawable bottom = mActivity.getResources().getDrawable(R.drawable.red);
3003         bottom.setBounds(0, 0, 100, 10);
3004         mActivity.runOnUiThread(new Runnable() {
3005             public void run() {
3006                 mTextView.setCompoundDrawables(null, null, null, bottom);
3007                 mTextView.setLines(mTextView.getLineCount() - 1);
3008                 mTextView.setGravity(Gravity.CENTER_VERTICAL);
3009             }
3010         });
3011         mInstrumentation.waitForIdleSync();
3012         assertEquals(mTextView.getExtendedPaddingBottom(), mTextView.getTotalPaddingBottom());
3013 
3014         // Change line count
3015         setLines(mTextView.getLineCount() + 1);
3016         int expected = ((mTextView.getHeight()
3017                 - mTextView.getExtendedPaddingBottom()
3018                 - mTextView.getExtendedPaddingTop()
3019                 - mTextView.getLayout().getLineBottom(mTextView.getLineCount())) >> 1)
3020                 + mTextView.getExtendedPaddingBottom();
3021         assertEquals(expected, mTextView.getTotalPaddingBottom());
3022     }
3023 
3024     @TestTargetNew(
3025         level = TestLevel.COMPLETE,
3026         method = "getTotalPaddingLeft",
3027         args = {}
3028     )
3029     @UiThreadTest
testGetTotalPaddingLeft()3030     public void testGetTotalPaddingLeft() {
3031         mTextView = findTextView(R.id.textview_text);
3032         // Initialized value
3033         assertEquals(0, mTextView.getTotalPaddingLeft());
3034 
3035         // After Set a Drawable
3036         Drawable left = mActivity.getResources().getDrawable(R.drawable.red);
3037         left.setBounds(0, 0, 10, 100);
3038         mTextView.setCompoundDrawables(left, null, null, null);
3039         mTextView.setGravity(Gravity.RIGHT);
3040         assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3041 
3042         // Change width
3043         mTextView.setWidth(Integer.MAX_VALUE);
3044         assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft());
3045     }
3046 
3047     @TestTargetNew(
3048         level = TestLevel.COMPLETE,
3049         method = "getTotalPaddingRight",
3050         args = {}
3051     )
3052     @UiThreadTest
testGetTotalPaddingRight()3053     public void testGetTotalPaddingRight() {
3054         mTextView = findTextView(R.id.textview_text);
3055         // Initialized value
3056         assertEquals(0, mTextView.getTotalPaddingRight());
3057 
3058         // After Set a Drawable
3059         Drawable right = mActivity.getResources().getDrawable(R.drawable.red);
3060         right.setBounds(0, 0, 10, 100);
3061         mTextView.setCompoundDrawables(null, null, right, null);
3062         mTextView.setGravity(Gravity.CENTER_HORIZONTAL);
3063         assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
3064 
3065         // Change width
3066         mTextView.setWidth(Integer.MAX_VALUE);
3067         assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight());
3068     }
3069 
3070     @TestTargetNew(
3071         level = TestLevel.COMPLETE,
3072         method = "getUrls",
3073         args = {}
3074     )
testGetUrls()3075     public void testGetUrls() {
3076         mTextView = new TextView(mActivity);
3077 
3078         URLSpan[] spans = mTextView.getUrls();
3079         assertEquals(0, spans.length);
3080 
3081         String url = "http://www.google.com";
3082         String email = "name@gmail.com";
3083         String string = url + " mailto:" + email;
3084         SpannableString spannable = new SpannableString(string);
3085         spannable.setSpan(new URLSpan(url), 0, url.length(), 0);
3086         mTextView.setText(spannable, BufferType.SPANNABLE);
3087         spans = mTextView.getUrls();
3088         assertEquals(1, spans.length);
3089         assertEquals(url, spans[0].getURL());
3090 
3091         spannable.setSpan(new URLSpan(email), 0, email.length(), 0);
3092         mTextView.setText(spannable, BufferType.SPANNABLE);
3093 
3094         spans = mTextView.getUrls();
3095         assertEquals(2, spans.length);
3096         assertEquals(url, spans[0].getURL());
3097         assertEquals(email, spans[1].getURL());
3098 
3099         // test the situation that param what is not a URLSpan
3100         spannable.setSpan(new Object(), 0, 9, 0);
3101         mTextView.setText(spannable, BufferType.SPANNABLE);
3102         spans = mTextView.getUrls();
3103         assertEquals(2, spans.length);
3104     }
3105 
3106     @TestTargetNew(
3107         level = TestLevel.COMPLETE,
3108         method = "setPadding",
3109         args = {int.class, int.class, int.class, int.class}
3110     )
testSetPadding()3111     public void testSetPadding() {
3112         mTextView = new TextView(mActivity);
3113 
3114         mTextView.setPadding(0, 1, 2, 4);
3115         assertEquals(0, mTextView.getPaddingLeft());
3116         assertEquals(1, mTextView.getPaddingTop());
3117         assertEquals(2, mTextView.getPaddingRight());
3118         assertEquals(4, mTextView.getPaddingBottom());
3119 
3120         mTextView.setPadding(10, 20, 30, 40);
3121         assertEquals(10, mTextView.getPaddingLeft());
3122         assertEquals(20, mTextView.getPaddingTop());
3123         assertEquals(30, mTextView.getPaddingRight());
3124         assertEquals(40, mTextView.getPaddingBottom());
3125     }
3126 
3127     @TestTargetNew(
3128         level = TestLevel.COMPLETE,
3129         method = "setTextAppearance",
3130         args = {android.content.Context.class, int.class}
3131     )
3132     @ToBeFixed(bug = "1386429", explanation = "There is no getter to check "
3133             + "the Highlight color value.")
testSetTextAppearance()3134     public void testSetTextAppearance() {
3135         mTextView = new TextView(mActivity);
3136 
3137         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
3138         assertEquals(mActivity.getResources().getColor(R.drawable.black),
3139                 mTextView.getCurrentTextColor());
3140         assertEquals(20f, mTextView.getTextSize(), 0.01f);
3141         assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
3142         assertEquals(mActivity.getResources().getColor(R.drawable.red),
3143                 mTextView.getCurrentHintTextColor());
3144         assertEquals(mActivity.getResources().getColor(R.drawable.blue),
3145                 mTextView.getLinkTextColors().getDefaultColor());
3146 
3147         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Colors);
3148         assertEquals(mActivity.getResources().getColor(R.drawable.black),
3149                 mTextView.getCurrentTextColor());
3150         assertEquals(mActivity.getResources().getColor(R.drawable.blue),
3151                 mTextView.getCurrentHintTextColor());
3152         assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
3153                 mTextView.getLinkTextColors().getDefaultColor());
3154 
3155         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_NotColors);
3156         assertEquals(17f, mTextView.getTextSize(), 0.01f);
3157         assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
3158 
3159         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Style);
3160         assertEquals(null, mTextView.getTypeface());
3161     }
3162 
3163     @TestTargetNew(
3164         level = TestLevel.NOT_NECESSARY,
3165         method = "onPreDraw",
3166         args = {}
3167     )
testOnPreDraw()3168     public void testOnPreDraw() {
3169         // Do not test. Implementation details.
3170     }
3171 
3172     @TestTargetNew(
3173         level = TestLevel.COMPLETE,
3174         method = "setHorizontallyScrolling",
3175         args = {boolean.class}
3176     )
testSetHorizontallyScrolling()3177     public void testSetHorizontallyScrolling() {
3178         // make the text view has more than one line
3179         mTextView = findTextView(R.id.textview_text);
3180         setWidth(mTextView.getWidth() >> 1);
3181         assertTrue(mTextView.getLineCount() > 1);
3182 
3183         setHorizontallyScrolling(true);
3184         assertEquals(1, mTextView.getLineCount());
3185 
3186         setHorizontallyScrolling(false);
3187         assertTrue(mTextView.getLineCount() > 1);
3188     }
3189 
3190     @TestTargetNew(
3191         level = TestLevel.COMPLETE,
3192         method = "computeHorizontalScrollRange",
3193         args = {}
3194     )
testComputeHorizontalScrollRange()3195     public void testComputeHorizontalScrollRange() {
3196         MockTextView textView = new MockTextView(mActivity);
3197         // test when layout is null
3198         assertNull(textView.getLayout());
3199         assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
3200 
3201         textView.setFrame(0, 0, 40, 50);
3202         assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange());
3203 
3204         // set the layout
3205         layout(textView);
3206         assertEquals(textView.getLayout().getWidth(), textView.computeHorizontalScrollRange());
3207     }
3208 
3209     @TestTargetNew(
3210         level = TestLevel.COMPLETE,
3211         method = "computeVerticalScrollRange",
3212         args = {}
3213     )
testComputeVerticalScrollRange()3214     public void testComputeVerticalScrollRange() {
3215         MockTextView textView = new MockTextView(mActivity);
3216         // test when layout is null
3217         assertNull(textView.getLayout());
3218         assertEquals(0, textView.computeVerticalScrollRange());
3219 
3220         textView.setFrame(0, 0, 40, 50);
3221         assertEquals(textView.getHeight(), textView.computeVerticalScrollRange());
3222 
3223         //set the layout
3224         layout(textView);
3225         assertEquals(textView.getLayout().getHeight(), textView.computeVerticalScrollRange());
3226     }
3227 
3228     @TestTargetNew(
3229         level = TestLevel.COMPLETE,
3230         method = "drawableStateChanged",
3231         args = {}
3232     )
testDrawableStateChanged()3233     public void testDrawableStateChanged() {
3234         MockTextView textView = new MockTextView(mActivity);
3235 
3236         textView.reset();
3237         textView.refreshDrawableState();
3238         assertTrue(textView.hasCalledDrawableStateChanged());
3239     }
3240 
3241     @TestTargetNew(
3242         level = TestLevel.COMPLETE,
3243         notes = "This method always returns false.",
3244         method = "getDefaultEditable",
3245         args = {}
3246     )
testGetDefaultEditable()3247     public void testGetDefaultEditable() {
3248         MockTextView textView = new MockTextView(mActivity);
3249 
3250         //the TextView#getDefaultEditable() does nothing, and always return false.
3251         assertFalse(textView.getDefaultEditable());
3252     }
3253 
3254     @TestTargetNew(
3255         level = TestLevel.COMPLETE,
3256         notes = "This method always returns null.",
3257         method = "getDefaultMovementMethod",
3258         args = {}
3259     )
testGetDefaultMovementMethod()3260     public void testGetDefaultMovementMethod() {
3261         MockTextView textView = new MockTextView(mActivity);
3262 
3263         //the TextView#getDefaultMovementMethod() does nothing, and always return null.
3264         assertNull(textView.getDefaultMovementMethod());
3265     }
3266 
3267     @TestTargetNew(
3268         level = TestLevel.NOT_NECESSARY,
3269         method = "onCreateContextMenu",
3270         args = {android.view.ContextMenu.class}
3271     )
testOnCreateContextMenu()3272     public void testOnCreateContextMenu() {
3273         // Do not test. Implementation details.
3274     }
3275 
3276     @TestTargetNew(
3277         level = TestLevel.NOT_NECESSARY,
3278         method = "onDetachedFromWindow",
3279         args = {}
3280     )
testOnDetachedFromWindow()3281     public void testOnDetachedFromWindow() {
3282         // Do not test. Implementation details.
3283     }
3284 
3285     @TestTargetNew(
3286         level = TestLevel.NOT_NECESSARY,
3287         method = "onDraw",
3288         args = {android.graphics.Canvas.class}
3289     )
testOnDraw()3290     public void testOnDraw() {
3291         // Do not test. Implementation details.
3292     }
3293 
3294     @TestTargetNew(
3295         level = TestLevel.NOT_NECESSARY,
3296         method = "onFocusChanged",
3297         args = {boolean.class, int.class, android.graphics.Rect.class}
3298     )
testOnFocusChanged()3299     public void testOnFocusChanged() {
3300         // Do not test. Implementation details.
3301     }
3302 
3303     @TestTargetNew(
3304         level = TestLevel.NOT_NECESSARY,
3305         method = "onMeasure",
3306         args = {int.class, int.class}
3307     )
testOnMeasure()3308     public void testOnMeasure() {
3309         // Do not test. Implementation details.
3310     }
3311 
3312     @TestTargetNew(
3313         level = TestLevel.NOT_NECESSARY,
3314         method = "onTextChanged",
3315         args = {java.lang.CharSequence.class, int.class, int.class, int.class}
3316     )
testOnTextChanged()3317     public void testOnTextChanged() {
3318         // Do not test. Implementation details.
3319     }
3320 
3321     @TestTargetNew(
3322         level = TestLevel.COMPLETE,
3323         method = "setFrame",
3324         args = {int.class, int.class, int.class, int.class}
3325     )
testSetFrame()3326     public void testSetFrame() {
3327         MockTextView textView = new MockTextView(mActivity);
3328 
3329         //Assign a new size to this view
3330         assertTrue(textView.setFrame(0, 0, 320, 480));
3331         assertEquals(0, textView.getFrameLeft());
3332         assertEquals(0, textView.getFrameTop());
3333         assertEquals(320, textView.getFrameRight());
3334         assertEquals(480, textView.getFrameBottom());
3335 
3336         //Assign a same size to this view
3337         assertFalse(textView.setFrame(0, 0, 320, 480));
3338 
3339         //negative input
3340         assertTrue(textView.setFrame(-1, -1, -1, -1));
3341         assertEquals(-1, textView.getFrameLeft());
3342         assertEquals(-1, textView.getFrameTop());
3343         assertEquals(-1, textView.getFrameRight());
3344         assertEquals(-1, textView.getFrameBottom());
3345     }
3346 
3347     @TestTargets({
3348         @TestTargetNew(
3349             level = TestLevel.COMPLETE,
3350             method = "getRightFadingEdgeStrength",
3351             args = {}
3352         ),
3353         @TestTargetNew(
3354             level = TestLevel.COMPLETE,
3355             method = "getLeftFadingEdgeStrength",
3356             args = {}
3357         )
3358     })
testGetFadingEdgeStrength()3359     public void testGetFadingEdgeStrength() {
3360         final MockTextView textView = new MockTextView(mActivity);
3361         textView.setText(LONG_TEXT);
3362         textView.setSingleLine();
3363         // make the fading to be shown
3364         textView.setHorizontalFadingEdgeEnabled(true);
3365 
3366         mActivity.runOnUiThread(new Runnable() {
3367             public void run() {
3368                 mActivity.setContentView(textView);
3369                 textView.setGravity(Gravity.LEFT);
3370             }
3371         });
3372         mInstrumentation.waitForIdleSync();
3373 
3374         // fading is shown on right side if the text aligns left
3375         assertEquals(0.0f, textView.getLeftFadingEdgeStrength(), 0.01f);
3376         assertEquals(1.0f, textView.getRightFadingEdgeStrength(), 0.01f);
3377 
3378         mActivity.runOnUiThread(new Runnable() {
3379             public void run() {
3380                 textView.setGravity(Gravity.RIGHT);
3381             }
3382         });
3383         mInstrumentation.waitForIdleSync();
3384         // fading is shown on left side if the text aligns right
3385         assertEquals(1.0f, textView.getLeftFadingEdgeStrength(), 0.01f);
3386         assertEquals(0.0f, textView.getRightFadingEdgeStrength(), 0.01f);
3387 
3388         mActivity.runOnUiThread(new Runnable() {
3389             public void run() {
3390                 textView.setGravity(Gravity.CENTER_HORIZONTAL);
3391             }
3392         });
3393         mInstrumentation.waitForIdleSync();
3394         // fading is shown on both sides if the text aligns center
3395         assertEquals(1.0f, textView.getLeftFadingEdgeStrength(), 0.01f);
3396         assertEquals(1.0f, textView.getRightFadingEdgeStrength(), 0.01f);
3397     }
3398 
3399     @TestTargets({
3400         @TestTargetNew(
3401             level = TestLevel.COMPLETE,
3402             method = "getRightFadingEdgeStrength",
3403             args = {}
3404         ),
3405         @TestTargetNew(
3406             level = TestLevel.COMPLETE,
3407             method = "getLeftFadingEdgeStrength",
3408             args = {}
3409         ),
3410         @TestTargetNew(
3411             level = TestLevel.COMPLETE,
3412             method = "setMarqueeRepeatLimit",
3413             args = {int.class}
3414         ),
3415         @TestTargetNew(
3416             level = TestLevel.COMPLETE,
3417             method = "setSelected",
3418             args = {boolean.class}
3419         )
3420     })
testMarquee()3421     public void testMarquee() {
3422         final MockTextView textView = new MockTextView(mActivity);
3423         textView.setText(LONG_TEXT);
3424         textView.setSingleLine();
3425         textView.setEllipsize(TruncateAt.MARQUEE);
3426         // make the fading to be shown
3427         textView.setHorizontalFadingEdgeEnabled(true);
3428 
3429         mActivity.runOnUiThread(new Runnable() {
3430             public void run() {
3431                 mActivity.setContentView(textView);
3432             }
3433         });
3434         mInstrumentation.waitForIdleSync();
3435 
3436         TestSelectedRunnable runnable = new TestSelectedRunnable(textView) {
3437             public void run() {
3438                 textView.setMarqueeRepeatLimit(-1);
3439                 // force the marquee to start
3440                 saveIsSelected1();
3441                 textView.setSelected(true);
3442                 saveIsSelected2();
3443             }
3444         };
3445         mActivity.runOnUiThread(runnable);
3446 
3447         // wait for the marquee to run
3448         // fading is shown on both sides if the marquee runs for a while
3449         new DelayedCheck(TIMEOUT) {
3450             @Override
3451             protected boolean check() {
3452                 return textView.getLeftFadingEdgeStrength() > 0.0f
3453                         && textView.getRightFadingEdgeStrength() > 0.0f;
3454             }
3455         }.run();
3456 
3457         final float leftFadingEdgeStrength = textView.getLeftFadingEdgeStrength();
3458         final float rightFadingEdgeStrength = textView.getRightFadingEdgeStrength();
3459 
3460         // wait for the marquee to continue
3461         // the left fading becomes thicker while the right fading becomes thiner
3462         // as the text moves towards left
3463         new DelayedCheck(TIMEOUT) {
3464             @Override
3465             protected boolean check() {
3466                 return leftFadingEdgeStrength < textView.getLeftFadingEdgeStrength()
3467                         && rightFadingEdgeStrength > textView.getRightFadingEdgeStrength();
3468             }
3469         }.run();
3470         assertFalse(runnable.getIsSelected1());
3471         assertTrue(runnable.getIsSelected2());
3472 
3473         runnable = new TestSelectedRunnable(textView) {
3474             public void run() {
3475                 textView.setMarqueeRepeatLimit(0);
3476                 // force the marquee to stop
3477                 saveIsSelected1();
3478                 textView.setSelected(false);
3479                 saveIsSelected2();
3480                 textView.setGravity(Gravity.LEFT);
3481             }
3482         };
3483         // force the marquee to stop
3484         mActivity.runOnUiThread(runnable);
3485         mInstrumentation.waitForIdleSync();
3486         assertTrue(runnable.getIsSelected1());
3487         assertFalse(runnable.getIsSelected2());
3488         assertEquals(0.0f, textView.getLeftFadingEdgeStrength(), 0.01f);
3489         assertTrue(textView.getRightFadingEdgeStrength() > 0.0f);
3490 
3491         mActivity.runOnUiThread(new Runnable() {
3492             public void run() {
3493                 textView.setGravity(Gravity.RIGHT);
3494             }
3495         });
3496         mInstrumentation.waitForIdleSync();
3497         assertTrue(textView.getLeftFadingEdgeStrength() > 0.0f);
3498         assertEquals(0.0f, textView.getRightFadingEdgeStrength(), 0.01f);
3499 
3500         mActivity.runOnUiThread(new Runnable() {
3501             public void run() {
3502                 textView.setGravity(Gravity.CENTER_HORIZONTAL);
3503             }
3504         });
3505         mInstrumentation.waitForIdleSync();
3506         // there is no left fading (Is it correct?)
3507         assertEquals(0.0f, textView.getLeftFadingEdgeStrength(), 0.01f);
3508         assertTrue(textView.getRightFadingEdgeStrength() > 0.0f);
3509     }
3510 
3511     @TestTargetNew(
3512         level = TestLevel.NOT_NECESSARY,
3513         method = "onKeyMultiple",
3514         args = {int.class, int.class, android.view.KeyEvent.class}
3515     )
testOnKeyMultiple()3516     public void testOnKeyMultiple() {
3517         // Do not test. Implementation details.
3518     }
3519 
3520     @TestTargets({
3521         @TestTargetNew(
3522             level = TestLevel.COMPLETE,
3523             method = "setInputExtras",
3524             args = {int.class}
3525         ),
3526         @TestTargetNew(
3527             level = TestLevel.COMPLETE,
3528             method = "getInputExtras",
3529             args = {boolean.class}
3530         )
3531     })
3532     @ToBeFixed(bug = "1569298", explanation = "NullPointerException occurs when we call "
3533             + "android.widget.TextView#setInputExtras(int xmlResId)")
testAccessInputExtras()3534     public void testAccessInputExtras() throws XmlPullParserException, IOException {
3535         TextView textView = new TextView(mActivity);
3536         textView.setText(null, BufferType.EDITABLE);
3537         textView.setInputType(InputType.TYPE_CLASS_TEXT);
3538 
3539         // do not create the extras
3540         assertNull(textView.getInputExtras(false));
3541 
3542         // create if it does not exist
3543         Bundle inputExtras = textView.getInputExtras(true);
3544         assertNotNull(inputExtras);
3545         assertTrue(inputExtras.isEmpty());
3546 
3547         // it is created already
3548         assertNotNull(textView.getInputExtras(false));
3549 
3550         try {
3551             textView.setInputExtras(R.xml.input_extras);
3552             fail("Should throw NullPointerException!");
3553         } catch (NullPointerException e) {
3554         }
3555     }
3556 
3557     @TestTargets({
3558         @TestTargetNew(
3559             level = TestLevel.COMPLETE,
3560             method = "setInputType",
3561             args = {int.class}
3562         ),
3563         @TestTargetNew(
3564             level = TestLevel.COMPLETE,
3565             method = "getInputType",
3566             args = {}
3567         )
3568     })
testAccessContentType()3569     public void testAccessContentType() {
3570         TextView textView = new TextView(mActivity);
3571         textView.setText(null, BufferType.EDITABLE);
3572         textView.setKeyListener(null);
3573         textView.setTransformationMethod(null);
3574 
3575         textView.setInputType(InputType.TYPE_CLASS_DATETIME
3576                 | InputType.TYPE_DATETIME_VARIATION_NORMAL);
3577         assertEquals(InputType.TYPE_CLASS_DATETIME
3578                 | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
3579         assertTrue(textView.getKeyListener() instanceof DateTimeKeyListener);
3580 
3581         textView.setInputType(InputType.TYPE_CLASS_DATETIME
3582                 | InputType.TYPE_DATETIME_VARIATION_DATE);
3583         assertEquals(InputType.TYPE_CLASS_DATETIME
3584                 | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
3585         assertTrue(textView.getKeyListener() instanceof DateKeyListener);
3586 
3587         textView.setInputType(InputType.TYPE_CLASS_DATETIME
3588                 | InputType.TYPE_DATETIME_VARIATION_TIME);
3589         assertEquals(InputType.TYPE_CLASS_DATETIME
3590                 | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
3591         assertTrue(textView.getKeyListener() instanceof TimeKeyListener);
3592 
3593         textView.setInputType(InputType.TYPE_CLASS_NUMBER
3594                 | InputType.TYPE_NUMBER_FLAG_DECIMAL
3595                 | InputType.TYPE_NUMBER_FLAG_SIGNED);
3596         assertEquals(InputType.TYPE_CLASS_NUMBER
3597                 | InputType.TYPE_NUMBER_FLAG_DECIMAL
3598                 | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
3599         assertSame(textView.getKeyListener(), DigitsKeyListener.getInstance(true, true));
3600 
3601         textView.setInputType(InputType.TYPE_CLASS_PHONE);
3602         assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
3603         assertTrue(textView.getKeyListener() instanceof DialerKeyListener);
3604 
3605         textView.setInputType(InputType.TYPE_CLASS_TEXT
3606                 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
3607         assertEquals(InputType.TYPE_CLASS_TEXT
3608                 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
3609         assertSame(textView.getKeyListener(), TextKeyListener.getInstance(true, Capitalize.NONE));
3610 
3611         textView.setSingleLine();
3612         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3613         textView.setInputType(InputType.TYPE_CLASS_TEXT
3614                 | InputType.TYPE_TEXT_FLAG_MULTI_LINE
3615                 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
3616         assertEquals(InputType.TYPE_CLASS_TEXT
3617                 | InputType.TYPE_TEXT_FLAG_MULTI_LINE
3618                 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
3619         assertSame(textView.getKeyListener(),
3620                 TextKeyListener.getInstance(false, Capitalize.CHARACTERS));
3621         assertNull(textView.getTransformationMethod());
3622 
3623         textView.setInputType(InputType.TYPE_CLASS_TEXT
3624                 | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
3625         assertEquals(InputType.TYPE_CLASS_TEXT
3626                 | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
3627         assertSame(textView.getKeyListener(),
3628                 TextKeyListener.getInstance(false, Capitalize.WORDS));
3629         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3630 
3631         textView.setInputType(InputType.TYPE_CLASS_TEXT
3632                 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
3633         assertEquals(InputType.TYPE_CLASS_TEXT
3634                 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
3635         assertSame(textView.getKeyListener(),
3636                 TextKeyListener.getInstance(false, Capitalize.SENTENCES));
3637 
3638         textView.setInputType(InputType.TYPE_NULL);
3639         assertEquals(InputType.TYPE_NULL, textView.getInputType());
3640         assertTrue(textView.getKeyListener() instanceof TextKeyListener);
3641     }
3642 
3643     @TestTargets({
3644         @TestTargetNew(
3645             level = TestLevel.COMPLETE,
3646             method = "getInputType",
3647             args = {}
3648         ),
3649         @TestTargetNew(
3650             level = TestLevel.COMPLETE,
3651             method = "setRawInputType",
3652             args = {int.class}
3653         )
3654     })
testAccessRawContentType()3655     public void testAccessRawContentType() {
3656         TextView textView = new TextView(mActivity);
3657         textView.setText(null, BufferType.EDITABLE);
3658         textView.setKeyListener(null);
3659         textView.setTransformationMethod(null);
3660 
3661         textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
3662                 | InputType.TYPE_DATETIME_VARIATION_NORMAL);
3663         assertEquals(InputType.TYPE_CLASS_DATETIME
3664                 | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType());
3665         assertNull(textView.getTransformationMethod());
3666         assertNull(textView.getKeyListener());
3667 
3668         textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
3669                 | InputType.TYPE_DATETIME_VARIATION_DATE);
3670         assertEquals(InputType.TYPE_CLASS_DATETIME
3671                 | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType());
3672         assertNull(textView.getTransformationMethod());
3673         assertNull(textView.getKeyListener());
3674 
3675         textView.setRawInputType(InputType.TYPE_CLASS_DATETIME
3676                 | InputType.TYPE_DATETIME_VARIATION_TIME);
3677         assertEquals(InputType.TYPE_CLASS_DATETIME
3678                 | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType());
3679         assertNull(textView.getTransformationMethod());
3680         assertNull(textView.getKeyListener());
3681 
3682         textView.setRawInputType(InputType.TYPE_CLASS_NUMBER
3683                 | InputType.TYPE_NUMBER_FLAG_DECIMAL
3684                 | InputType.TYPE_NUMBER_FLAG_SIGNED);
3685         assertEquals(InputType.TYPE_CLASS_NUMBER
3686                 | InputType.TYPE_NUMBER_FLAG_DECIMAL
3687                 | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType());
3688         assertNull(textView.getTransformationMethod());
3689         assertNull(textView.getKeyListener());
3690 
3691         textView.setRawInputType(InputType.TYPE_CLASS_PHONE);
3692         assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType());
3693         assertNull(textView.getTransformationMethod());
3694         assertNull(textView.getKeyListener());
3695 
3696         textView.setRawInputType(InputType.TYPE_CLASS_TEXT
3697                 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
3698         assertEquals(InputType.TYPE_CLASS_TEXT
3699                 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType());
3700         assertNull(textView.getTransformationMethod());
3701         assertNull(textView.getKeyListener());
3702 
3703         textView.setSingleLine();
3704         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3705         textView.setRawInputType(InputType.TYPE_CLASS_TEXT
3706                 | InputType.TYPE_TEXT_FLAG_MULTI_LINE
3707                 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
3708         assertEquals(InputType.TYPE_CLASS_TEXT
3709                 | InputType.TYPE_TEXT_FLAG_MULTI_LINE
3710                 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType());
3711         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3712         assertNull(textView.getKeyListener());
3713 
3714         textView.setRawInputType(InputType.TYPE_CLASS_TEXT
3715                 | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
3716         assertEquals(InputType.TYPE_CLASS_TEXT
3717                 | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType());
3718         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3719         assertNull(textView.getKeyListener());
3720 
3721         textView.setRawInputType(InputType.TYPE_CLASS_TEXT
3722                 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
3723         assertEquals(InputType.TYPE_CLASS_TEXT
3724                 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType());
3725         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3726         assertNull(textView.getKeyListener());
3727 
3728         textView.setRawInputType(InputType.TYPE_NULL);
3729         assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod);
3730         assertNull(textView.getKeyListener());
3731     }
3732 
3733     @TestTargetNew(
3734         level = TestLevel.NOT_NECESSARY,
3735         method = "onPrivateIMECommand",
3736         args = {String.class, Bundle.class}
3737     )
testOnPrivateIMECommand()3738     public void testOnPrivateIMECommand() {
3739         // Do not test. Implementation details.
3740     }
3741 
3742     @TestTargets({
3743         @TestTargetNew(
3744             level = TestLevel.NOT_NECESSARY,
3745             method = "onAttachedToWindow",
3746             args = {}
3747         ),
3748         @TestTargetNew(
3749             level = TestLevel.NOT_NECESSARY,
3750             method = "onBeginBatchEdit",
3751             args = {}
3752         ),
3753         @TestTargetNew(
3754             level = TestLevel.NOT_NECESSARY,
3755             method = "onCheckIsTextEditor",
3756             args = {}
3757         ),
3758         @TestTargetNew(
3759             level = TestLevel.NOT_NECESSARY,
3760             method = "onCommitCompletion",
3761             args = {android.view.inputmethod.CompletionInfo.class}
3762         ),
3763         @TestTargetNew(
3764             level = TestLevel.NOT_NECESSARY,
3765             method = "onCreateInputConnection",
3766             args = {android.view.inputmethod.EditorInfo.class}
3767         ),
3768         @TestTargetNew(
3769             level = TestLevel.NOT_NECESSARY,
3770             method = "onEditorAction",
3771             args = {int.class}
3772         ),
3773         @TestTargetNew(
3774             level = TestLevel.NOT_NECESSARY,
3775             method = "onEndBatchEdit",
3776             args = {}
3777         ),
3778         @TestTargetNew(
3779             level = TestLevel.NOT_NECESSARY,
3780             method = "onFinishTemporaryDetach",
3781             args = {}
3782         ),
3783         @TestTargetNew(
3784             level = TestLevel.NOT_NECESSARY,
3785             method = "onSelectionChanged",
3786             args = {int.class, int.class}
3787         ),
3788         @TestTargetNew(
3789             level = TestLevel.NOT_NECESSARY,
3790             method = "onStartTemporaryDetach",
3791             args = {}
3792         ),
3793         @TestTargetNew(
3794             level = TestLevel.NOT_NECESSARY,
3795             method = "onTextContextMenuItem",
3796             args = {int.class}
3797         )
3798     })
testFoo()3799     public void testFoo() {
3800         // Do not test. Implementation details.
3801     }
3802 
3803     @TestTargetNew(
3804         level = TestLevel.COMPLETE,
3805         method = "verifyDrawable",
3806         args = {android.graphics.drawable.Drawable.class}
3807     )
testVerifyDrawable()3808     public void testVerifyDrawable() {
3809         MockTextView textView = new MockTextView(mActivity);
3810 
3811         Drawable d = mActivity.getResources().getDrawable(R.drawable.pass);
3812         assertFalse(textView.verifyDrawable(d));
3813 
3814         textView.setCompoundDrawables(null, d, null, null);
3815         assertTrue(textView.verifyDrawable(d));
3816     }
3817 
3818     @TestTargets({
3819         @TestTargetNew(
3820             level = TestLevel.COMPLETE,
3821             method = "setPrivateImeOptions",
3822             args = {java.lang.String.class}
3823         ),
3824         @TestTargetNew(
3825             level = TestLevel.COMPLETE,
3826             method = "getPrivateImeOptions",
3827             args = {}
3828         )
3829     })
testAccessPrivateImeOptions()3830     public void testAccessPrivateImeOptions() {
3831         mTextView = findTextView(R.id.textview_text);
3832         assertNull(mTextView.getPrivateImeOptions());
3833 
3834         mTextView.setPrivateImeOptions("com.example.myapp.SpecialMode=3");
3835         assertEquals("com.example.myapp.SpecialMode=3", mTextView.getPrivateImeOptions());
3836 
3837         mTextView.setPrivateImeOptions(null);
3838         assertNull(mTextView.getPrivateImeOptions());
3839     }
3840 
3841     @TestTargetNew(
3842         level = TestLevel.COMPLETE,
3843         method = "setOnEditorActionListener",
3844         args = {android.widget.TextView.OnEditorActionListener.class}
3845     )
testSetOnEditorActionListener()3846     public void testSetOnEditorActionListener() {
3847         mTextView = findTextView(R.id.textview_text);
3848 
3849         MockOnEditorActionListener listener = new MockOnEditorActionListener();
3850         assertFalse(listener.isOnEditorActionCalled());
3851 
3852         mTextView.setOnEditorActionListener(listener);
3853         assertFalse(listener.isOnEditorActionCalled());
3854 
3855         mTextView.onEditorAction(EditorInfo.IME_ACTION_DONE);
3856         assertTrue(listener.isOnEditorActionCalled());
3857     }
3858 
3859     @TestTargets({
3860         @TestTargetNew(
3861             level = TestLevel.COMPLETE,
3862             method = "setImeOptions",
3863             args = {int.class}
3864         ),
3865         @TestTargetNew(
3866             level = TestLevel.COMPLETE,
3867             method = "getImeOptions",
3868             args = {}
3869         )
3870     })
testAccessImeOptions()3871     public void testAccessImeOptions() {
3872         mTextView = findTextView(R.id.textview_text);
3873         assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
3874 
3875         mTextView.setImeOptions(EditorInfo.IME_ACTION_GO);
3876         assertEquals(EditorInfo.IME_ACTION_GO, mTextView.getImeOptions());
3877 
3878         mTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
3879         assertEquals(EditorInfo.IME_ACTION_DONE, mTextView.getImeOptions());
3880 
3881         mTextView.setImeOptions(EditorInfo.IME_NULL);
3882         assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions());
3883     }
3884 
3885     @TestTargets({
3886         @TestTargetNew(
3887             level = TestLevel.COMPLETE,
3888             method = "setImeActionLabel",
3889             args = {java.lang.CharSequence.class, int.class}
3890         ),
3891         @TestTargetNew(
3892             level = TestLevel.COMPLETE,
3893             method = "getImeActionLabel",
3894             args = {}
3895         ),
3896         @TestTargetNew(
3897             level = TestLevel.COMPLETE,
3898             method = "getImeActionId",
3899             args = {}
3900         )
3901     })
testAccessImeActionLabel()3902     public void testAccessImeActionLabel() {
3903         mTextView = findTextView(R.id.textview_text);
3904         assertNull(mTextView.getImeActionLabel());
3905         assertEquals(0, mTextView.getImeActionId());
3906 
3907         mTextView.setImeActionLabel("pinyin", 1);
3908         assertEquals("pinyin", mTextView.getImeActionLabel().toString());
3909         assertEquals(1, mTextView.getImeActionId());
3910     }
3911 
3912     @TestTargetNew(
3913         level = TestLevel.COMPLETE,
3914         method = "setExtractedText",
3915         args = {android.view.inputmethod.ExtractedText.class}
3916     )
3917     @UiThreadTest
testSetExtractedText()3918     public void testSetExtractedText() {
3919         mTextView = findTextView(R.id.textview_text);
3920         assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
3921                 mTextView.getText().toString());
3922 
3923         ExtractedText et = new ExtractedText();
3924         et.text = "test";
3925 
3926         mTextView.setExtractedText(et);
3927         assertEquals("test", mTextView.getText().toString());
3928     }
3929 
3930     @TestTargetNew(
3931         level = TestLevel.COMPLETE,
3932         method = "moveCursorToVisibleOffset",
3933         args = {}
3934     )
testMoveCursorToVisibleOffset()3935     public void testMoveCursorToVisibleOffset() throws Throwable {
3936         mTextView = findTextView(R.id.textview_text);
3937 
3938         // not a spannable text
3939         runTestOnUiThread(new Runnable() {
3940             public void run() {
3941                 assertFalse(mTextView.moveCursorToVisibleOffset());
3942             }
3943         });
3944         mInstrumentation.waitForIdleSync();
3945 
3946         // a selection range
3947         final String spannableText = "text";
3948         mTextView = new TextView(mActivity);
3949 
3950         runTestOnUiThread(new Runnable() {
3951             public void run() {
3952                 mTextView.setText(spannableText, BufferType.SPANNABLE);
3953             }
3954         });
3955         mInstrumentation.waitForIdleSync();
3956         Selection.setSelection((Spannable) mTextView.getText(), 0, spannableText.length());
3957 
3958         assertEquals(0, mTextView.getSelectionStart());
3959         assertEquals(spannableText.length(), mTextView.getSelectionEnd());
3960         runTestOnUiThread(new Runnable() {
3961             public void run() {
3962                 assertFalse(mTextView.moveCursorToVisibleOffset());
3963             }
3964         });
3965         mInstrumentation.waitForIdleSync();
3966 
3967         // a spannable without range
3968         runTestOnUiThread(new Runnable() {
3969             public void run() {
3970                 mTextView = findTextView(R.id.textview_text);
3971                 mTextView.setText(spannableText, BufferType.SPANNABLE);
3972             }
3973         });
3974         mInstrumentation.waitForIdleSync();
3975 
3976         runTestOnUiThread(new Runnable() {
3977             public void run() {
3978                 assertTrue(mTextView.moveCursorToVisibleOffset());
3979             }
3980         });
3981         mInstrumentation.waitForIdleSync();
3982     }
3983 
3984     @TestTargetNew(
3985         level = TestLevel.COMPLETE,
3986         method = "isInputMethodTarget",
3987         args = {}
3988     )
3989     @UiThreadTest
testIsInputMethodTarget()3990     public void testIsInputMethodTarget() {
3991         mTextView = findTextView(R.id.textview_text);
3992         assertFalse(mTextView.isInputMethodTarget());
3993 
3994         assertFalse(mTextView.isFocused());
3995         mTextView.setFocusable(true);
3996         mTextView.requestFocus();
3997         assertTrue(mTextView.isFocused());
3998 
3999         assertTrue(mTextView.isInputMethodTarget());
4000     }
4001 
4002     @TestTargets({
4003         @TestTargetNew(
4004             level = TestLevel.COMPLETE,
4005             method = "beginBatchEdit",
4006             args = {}
4007         ),
4008         @TestTargetNew(
4009             level = TestLevel.COMPLETE,
4010             method = "endBatchEdit",
4011             args = {}
4012         )
4013     })
4014     @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete")
testBeginEndBatchEdit()4015     public void testBeginEndBatchEdit() {
4016         mTextView = findTextView(R.id.textview_text);
4017 
4018         mTextView.beginBatchEdit();
4019         mTextView.endBatchEdit();
4020     }
4021 
4022     @TestTargetNew(
4023         level = TestLevel.NOT_FEASIBLE,
4024         notes = "it's hard to do unit test, should be tested by functional test",
4025         method = "bringPointIntoView",
4026         args = {int.class}
4027     )
4028     @UiThreadTest
testBringPointIntoView()4029     public void testBringPointIntoView() throws Throwable {
4030         mTextView = findTextView(R.id.textview_text);
4031         assertFalse(mTextView.bringPointIntoView(1));
4032 
4033         mTextView.layout(0, 0, 100, 100);
4034         assertFalse(mTextView.bringPointIntoView(2));
4035     }
4036 
4037     @TestTargetNew(
4038         level = TestLevel.NOT_FEASIBLE,
4039         notes = "it's hard to do unit test, should be tested by functional test",
4040         method = "cancelLongPress",
4041         args = {}
4042     )
testCancelLongPress()4043     public void testCancelLongPress() {
4044         mTextView = findTextView(R.id.textview_text);
4045         TouchUtils.longClickView(this, mTextView);
4046         mTextView.cancelLongPress();
4047     }
4048 
4049     @TestTargetNew(
4050         level = TestLevel.COMPLETE,
4051         method = "clearComposingText",
4052         args = {}
4053     )
4054     @UiThreadTest
testClearComposingText()4055     public void testClearComposingText() {
4056         mTextView = findTextView(R.id.textview_text);
4057         mTextView.setText("Hello world!", BufferType.SPANNABLE);
4058         Spannable text = (Spannable) mTextView.getText();
4059 
4060         assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
4061         assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
4062 
4063         BaseInputConnection.setComposingSpans((Spannable) mTextView.getText());
4064         assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
4065         assertEquals(0, BaseInputConnection.getComposingSpanStart(text));
4066 
4067         mTextView.clearComposingText();
4068         assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
4069         assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
4070     }
4071 
4072     @TestTargetNew(
4073         level = TestLevel.NOT_FEASIBLE,
4074         notes = "it's hard to do unit test, should be tested by functional test",
4075         method = "computeVerticalScrollExtent",
4076         args = {}
4077     )
testComputeVerticalScrollExtent()4078     public void testComputeVerticalScrollExtent() {
4079         MockTextView textView = new MockTextView(mActivity);
4080         assertEquals(0, textView.computeVerticalScrollExtent());
4081 
4082         Drawable d = mActivity.getResources().getDrawable(R.drawable.pass);
4083         textView.setCompoundDrawables(null, d, null, d);
4084 
4085         assertEquals(0, textView.computeVerticalScrollExtent());
4086     }
4087 
4088     @TestTargetNew(
4089         level = TestLevel.COMPLETE,
4090         method = "didTouchFocusSelect",
4091         args = {}
4092     )
4093     @UiThreadTest
testDidTouchFocusSelect()4094     public void testDidTouchFocusSelect() {
4095         mTextView = new TextView(mActivity);
4096         assertFalse(mTextView.didTouchFocusSelect());
4097 
4098         mTextView.setFocusable(true);
4099         mTextView.requestFocus();
4100         assertTrue(mTextView.didTouchFocusSelect());
4101     }
4102 
4103     @TestTargetNew(
4104         level = TestLevel.COMPLETE,
4105         method = "extractText",
4106         args = {android.view.inputmethod.ExtractedTextRequest.class,
4107                 android.view.inputmethod.ExtractedText.class}
4108     )
4109     @ToBeFixed(bug = "", explanation = "even the TextView did not contains editable content, " +
4110             "it also returns true.")
testExtractText()4111     public void testExtractText() {
4112         mTextView = new TextView(mActivity);
4113 
4114         ExtractedTextRequest request = new ExtractedTextRequest();
4115         ExtractedText outText = new ExtractedText();
4116 
4117         request.token = 0;
4118         request.flags = 10;
4119         request.hintMaxLines = 2;
4120         request.hintMaxChars = 20;
4121         assertTrue(mTextView.extractText(request, outText));
4122 
4123         mTextView = findTextView(R.id.textview_text);
4124         assertTrue(mTextView.extractText(request, outText));
4125 
4126         assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
4127                 outText.text.toString());
4128     }
4129 
4130     private static class MockOnEditorActionListener implements OnEditorActionListener {
4131         private boolean isOnEditorActionCalled;
4132 
onEditorAction(TextView v, int actionId, KeyEvent event)4133         public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
4134             isOnEditorActionCalled = true;
4135             return true;
4136         }
4137 
isOnEditorActionCalled()4138         public boolean isOnEditorActionCalled() {
4139             return isOnEditorActionCalled;
4140         }
4141     }
4142 
layout(final TextView textView)4143     private void layout(final TextView textView) {
4144         mActivity.runOnUiThread(new Runnable() {
4145             public void run() {
4146                 mActivity.setContentView(textView);
4147             }
4148         });
4149         mInstrumentation.waitForIdleSync();
4150     }
4151 
layout(final int layoutId)4152     private void layout(final int layoutId) {
4153         mActivity.runOnUiThread(new Runnable() {
4154             public void run() {
4155                 mActivity.setContentView(layoutId);
4156             }
4157         });
4158         mInstrumentation.waitForIdleSync();
4159     }
4160 
findTextView(int id)4161     private TextView findTextView(int id) {
4162         return (TextView) mActivity.findViewById(id);
4163     }
4164 
getAutoLinkMask(int id)4165     private int getAutoLinkMask(int id) {
4166         return findTextView(id).getAutoLinkMask();
4167     }
4168 
getBitmap(int resid)4169     private Bitmap getBitmap(int resid) {
4170         return ((BitmapDrawable) mActivity.getResources().getDrawable(resid)).getBitmap();
4171     }
4172 
setMaxWidth(final int pixels)4173     private void setMaxWidth(final int pixels) {
4174         mActivity.runOnUiThread(new Runnable() {
4175             public void run() {
4176                 mTextView.setMaxWidth(pixels);
4177             }
4178         });
4179         mInstrumentation.waitForIdleSync();
4180     }
4181 
setMinWidth(final int pixels)4182     private void setMinWidth(final int pixels) {
4183         mActivity.runOnUiThread(new Runnable() {
4184             public void run() {
4185                 mTextView.setMinWidth(pixels);
4186             }
4187         });
4188         mInstrumentation.waitForIdleSync();
4189     }
4190 
setMaxHeight(final int pixels)4191     private void setMaxHeight(final int pixels) {
4192         mActivity.runOnUiThread(new Runnable() {
4193             public void run() {
4194                 mTextView.setMaxHeight(pixels);
4195             }
4196         });
4197         mInstrumentation.waitForIdleSync();
4198     }
4199 
setMinHeight(final int pixels)4200     private void setMinHeight(final int pixels) {
4201         mActivity.runOnUiThread(new Runnable() {
4202             public void run() {
4203                 mTextView.setMinHeight(pixels);
4204             }
4205         });
4206         mInstrumentation.waitForIdleSync();
4207     }
4208 
setMinLines(final int minlines)4209     private void setMinLines(final int minlines) {
4210         mActivity.runOnUiThread(new Runnable() {
4211             public void run() {
4212                 mTextView.setMinLines(minlines);
4213             }
4214         });
4215         mInstrumentation.waitForIdleSync();
4216     }
4217 
4218     /**
4219      * Convenience for {@link TextView#setText(CharSequence, BufferType)}. And
4220      * the buffer type is fixed to SPANNABLE.
4221      *
4222      * @param tv the text view
4223      * @param content the content
4224      */
setSpannableText(final TextView tv, final String content)4225     private void setSpannableText(final TextView tv, final String content) {
4226         mActivity.runOnUiThread(new Runnable() {
4227             public void run() {
4228                 tv.setText(content, BufferType.SPANNABLE);
4229             }
4230         });
4231         mInstrumentation.waitForIdleSync();
4232     }
4233 
setLines(final int lines)4234     private void setLines(final int lines) {
4235         mActivity.runOnUiThread(new Runnable() {
4236             public void run() {
4237                 mTextView.setLines(lines);
4238             }
4239         });
4240         mInstrumentation.waitForIdleSync();
4241     }
4242 
setHorizontallyScrolling(final boolean whether)4243     private void setHorizontallyScrolling(final boolean whether) {
4244         mActivity.runOnUiThread(new Runnable() {
4245             public void run() {
4246                 mTextView.setHorizontallyScrolling(whether);
4247             }
4248         });
4249         mInstrumentation.waitForIdleSync();
4250     }
4251 
setWidth(final int pixels)4252     private void setWidth(final int pixels) {
4253         mActivity.runOnUiThread(new Runnable() {
4254             public void run() {
4255                 mTextView.setWidth(pixels);
4256             }
4257         });
4258         mInstrumentation.waitForIdleSync();
4259     }
4260 
setHeight(final int pixels)4261     private void setHeight(final int pixels) {
4262         mActivity.runOnUiThread(new Runnable() {
4263             public void run() {
4264                 mTextView.setHeight(pixels);
4265             }
4266         });
4267         mInstrumentation.waitForIdleSync();
4268     }
4269 
setMinEms(final int ems)4270     private void setMinEms(final int ems) {
4271         mActivity.runOnUiThread(new Runnable() {
4272             public void run() {
4273                 mTextView.setMinEms(ems);
4274             }
4275         });
4276         mInstrumentation.waitForIdleSync();
4277     }
4278 
setMaxEms(final int ems)4279     private void setMaxEms(final int ems) {
4280         mActivity.runOnUiThread(new Runnable() {
4281             public void run() {
4282                 mTextView.setMaxEms(ems);
4283             }
4284         });
4285         mInstrumentation.waitForIdleSync();
4286     }
4287 
setEms(final int ems)4288     private void setEms(final int ems) {
4289         mActivity.runOnUiThread(new Runnable() {
4290             public void run() {
4291                 mTextView.setEms(ems);
4292             }
4293         });
4294         mInstrumentation.waitForIdleSync();
4295     }
4296 
setLineSpacing(final float add, final float mult)4297     private void setLineSpacing(final float add, final float mult) {
4298         mActivity.runOnUiThread(new Runnable() {
4299             public void run() {
4300                 mTextView.setLineSpacing(add, mult);
4301             }
4302         });
4303         mInstrumentation.waitForIdleSync();
4304     }
4305 
4306     private static abstract class TestSelectedRunnable implements Runnable {
4307         private TextView mTextView;
4308         private boolean mIsSelected1;
4309         private boolean mIsSelected2;
4310 
TestSelectedRunnable(TextView textview)4311         public TestSelectedRunnable(TextView textview) {
4312             mTextView = textview;
4313         }
4314 
getIsSelected1()4315         public boolean getIsSelected1() {
4316             return mIsSelected1;
4317         }
4318 
getIsSelected2()4319         public boolean getIsSelected2() {
4320             return mIsSelected2;
4321         }
4322 
saveIsSelected1()4323         public void saveIsSelected1() {
4324             mIsSelected1 = mTextView.isSelected();
4325         }
4326 
saveIsSelected2()4327         public void saveIsSelected2() {
4328             mIsSelected2 = mTextView.isSelected();
4329         }
4330     }
4331 
4332     private static abstract class TestLayoutRunnable implements Runnable {
4333         private TextView mTextView;
4334         private Layout mLayout;
4335 
TestLayoutRunnable(TextView textview)4336         public TestLayoutRunnable(TextView textview) {
4337             mTextView = textview;
4338         }
4339 
getLayout()4340         public Layout getLayout() {
4341             return mLayout;
4342         }
4343 
saveLayout()4344         public void saveLayout() {
4345             mLayout = mTextView.getLayout();
4346         }
4347     }
4348 
4349     private class MockEditableFactory extends Editable.Factory {
4350         private boolean mhasCalledNewEditable;
4351         private CharSequence mSource;
4352 
hasCalledNewEditable()4353         public boolean hasCalledNewEditable() {
4354             return mhasCalledNewEditable;
4355         }
4356 
reset()4357         public void reset() {
4358             mhasCalledNewEditable = false;
4359             mSource = null;
4360         }
4361 
getSource()4362         public CharSequence getSource() {
4363             return mSource;
4364         }
4365 
4366         @Override
newEditable(CharSequence source)4367         public Editable newEditable(CharSequence source) {
4368             mhasCalledNewEditable = true;
4369             mSource = source;
4370             return super.newEditable(source);
4371         }
4372     }
4373 
4374     private class MockSpannableFactory extends Spannable.Factory {
4375         private boolean mHasCalledNewSpannable;
4376         private CharSequence mSource;
4377 
getNewSpannableCalledCount()4378         public boolean getNewSpannableCalledCount() {
4379             return mHasCalledNewSpannable;
4380         }
4381 
reset()4382         public void reset() {
4383             mHasCalledNewSpannable = false;
4384             mSource = null;
4385         }
4386 
getSource()4387         public CharSequence getSource() {
4388             return mSource;
4389         }
4390 
4391         @Override
newSpannable(CharSequence source)4392         public Spannable newSpannable(CharSequence source) {
4393             mHasCalledNewSpannable = true;
4394             mSource = source;
4395             return super.newSpannable(source);
4396         }
4397     }
4398 
4399     private static class MockTextWatcher implements TextWatcher {
4400         private boolean mHasCalledAfterTextChanged;
4401         private boolean mHasCalledBeforeTextChanged;
4402         private boolean mHasOnTextChanged;
4403 
reset()4404         public void reset(){
4405             mHasCalledAfterTextChanged = false;
4406             mHasCalledBeforeTextChanged = false;
4407             mHasOnTextChanged = false;
4408         }
4409 
hasCalledAfterTextChanged()4410         public boolean hasCalledAfterTextChanged() {
4411             return mHasCalledAfterTextChanged;
4412         }
4413 
hasCalledBeforeTextChanged()4414         public boolean hasCalledBeforeTextChanged() {
4415             return mHasCalledBeforeTextChanged;
4416         }
4417 
hasCalledOnTextChanged()4418         public boolean hasCalledOnTextChanged() {
4419             return mHasOnTextChanged;
4420         }
4421 
afterTextChanged(Editable s)4422         public void afterTextChanged(Editable s) {
4423             mHasCalledAfterTextChanged = true;
4424         }
4425 
beforeTextChanged(CharSequence s, int start, int count, int after)4426         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
4427             mHasCalledBeforeTextChanged = true;
4428         }
4429 
onTextChanged(CharSequence s, int start, int before, int count)4430         public void onTextChanged(CharSequence s, int start, int before, int count) {
4431             mHasOnTextChanged = true;
4432         }
4433     }
4434 
4435     /**
4436      * The listener interface for receiving mockOnLongClick events. The class
4437      * that is interested in processing a mockOnLongClick event implements this
4438      * interface, and the object created with that class is registered with a
4439      * component using the component's
4440      * <code>addMockOnLongClickListener<code> method. When
4441      * the mockOnLongClick event occurs, that object's appropriate
4442      * method is invoked.
4443      *
4444      * @see MockOnLongClickEvent
4445      */
4446     private static class MockOnLongClickListener implements OnLongClickListener {
4447         private boolean mExpectedOnLongClickResult;
4448         private boolean mHasLongClicked;
4449 
MockOnLongClickListener(boolean result)4450         MockOnLongClickListener(boolean result) {
4451             mExpectedOnLongClickResult = result;
4452         }
4453 
hasLongClicked()4454         public boolean hasLongClicked() {
4455             return mHasLongClicked;
4456         }
4457 
onLongClick(View v)4458         public boolean onLongClick(View v) {
4459             mHasLongClicked = true;
4460             return mExpectedOnLongClickResult;
4461         }
4462     }
4463 
4464     /**
4465      * The listener interface for receiving mockOnCreateContextMenu events. The
4466      * class that is interested in processing a mockOnCreateContextMenu event
4467      * implements this interface, and the object created with that class is
4468      * registered with a component using the component's
4469      * <code>addMockOnCreateContextMenuListener<code> method. When the
4470      * mockOnCreateContextMenu event occurs, that object's appropriate method is
4471      * invoked.
4472      *
4473      * @see MockOnCreateContextMenuEvent
4474      */
4475     private static class MockOnCreateContextMenuListener implements OnCreateContextMenuListener {
4476         private boolean mIsMenuItemsBlank;
4477         private boolean mHasCreatedContextMenu;
4478 
MockOnCreateContextMenuListener(boolean isBlank)4479         MockOnCreateContextMenuListener(boolean isBlank) {
4480             this.mIsMenuItemsBlank = isBlank;
4481         }
4482 
hasCreatedContextMenu()4483         public boolean hasCreatedContextMenu() {
4484             return mHasCreatedContextMenu;
4485         }
4486 
reset()4487         public void reset() {
4488             mHasCreatedContextMenu = false;
4489         }
4490 
onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)4491         public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
4492             mHasCreatedContextMenu = true;
4493             if (!mIsMenuItemsBlank) {
4494                 menu.add("menu item");
4495             }
4496         }
4497     }
4498 
4499     private static class MockTextView extends TextView {
4500         private boolean mHasCalledOnCreateContextMenu;
4501         private boolean mHasCalledOnFocusChanged;
4502         private boolean mHasCalledOnMeasure;
4503         private boolean mHasCalledOnTextChanged;
4504         private boolean mHasCalledDrawableStateChanged;
4505         private boolean mHasCalledOnWindowFocusChanged;
4506         private boolean mHasCalledOnPrivateIMECommand;
4507         private boolean mHasCalledOnKeyMultiple;
4508 
hasCalledOnWindowFocusChanged()4509         public boolean hasCalledOnWindowFocusChanged() {
4510             return mHasCalledOnWindowFocusChanged;
4511         }
4512 
hasCalledOnCreateContextMenu()4513         public boolean hasCalledOnCreateContextMenu() {
4514             return mHasCalledOnCreateContextMenu;
4515         }
4516 
hasCalledDrawableStateChanged()4517         public boolean hasCalledDrawableStateChanged() {
4518             return mHasCalledDrawableStateChanged;
4519         }
4520 
hasCalledOnFocusChanged()4521         public boolean hasCalledOnFocusChanged() {
4522             return mHasCalledOnFocusChanged;
4523         }
4524 
hasCalledOnMeasure()4525         public boolean hasCalledOnMeasure() {
4526             return mHasCalledOnMeasure;
4527         }
4528 
hasCalledOnTextChanged()4529         public boolean hasCalledOnTextChanged() {
4530             return mHasCalledOnTextChanged;
4531         }
4532 
hasCalledOnPrivateIMECommand()4533         public boolean hasCalledOnPrivateIMECommand() {
4534             return mHasCalledOnPrivateIMECommand;
4535         }
4536 
hasCalledOnKeyMultiple()4537         public boolean hasCalledOnKeyMultiple(){
4538             return mHasCalledOnKeyMultiple;
4539         }
4540 
MockTextView(Context context)4541         public MockTextView(Context context) {
4542             super(context);
4543         }
4544 
reset()4545         public void reset() {
4546             mHasCalledOnWindowFocusChanged = false;
4547             mHasCalledDrawableStateChanged = false;
4548             mHasCalledOnCreateContextMenu = false;
4549             mHasCalledOnFocusChanged = false;
4550             mHasCalledOnMeasure = false;
4551             mHasCalledOnTextChanged = false;
4552             mHasCalledOnPrivateIMECommand = false;
4553             mHasCalledOnKeyMultiple = false;
4554         }
4555 
4556         @Override
computeHorizontalScrollRange()4557         protected int computeHorizontalScrollRange() {
4558             return super.computeHorizontalScrollRange();
4559         }
4560 
4561         @Override
computeVerticalScrollRange()4562         protected int computeVerticalScrollRange() {
4563             return super.computeVerticalScrollRange();
4564         }
4565 
4566         @Override
drawableStateChanged()4567         protected void drawableStateChanged() {
4568             super.drawableStateChanged();
4569             mHasCalledDrawableStateChanged = true;
4570         }
4571 
4572         @Override
getDefaultEditable()4573         protected boolean getDefaultEditable() {
4574             return super.getDefaultEditable();
4575         }
4576 
4577         @Override
getDefaultMovementMethod()4578         protected MovementMethod getDefaultMovementMethod() {
4579             return super.getDefaultMovementMethod();
4580         }
4581 
4582         @Override
onCreateContextMenu(ContextMenu menu)4583         protected void onCreateContextMenu(ContextMenu menu) {
4584             super.onCreateContextMenu(menu);
4585             mHasCalledOnCreateContextMenu = true;
4586         }
4587 
4588         @Override
onDetachedFromWindow()4589         protected void onDetachedFromWindow() {
4590             super.onDetachedFromWindow();
4591         }
4592 
4593         @Override
onDraw(Canvas canvas)4594         protected void onDraw(Canvas canvas) {
4595             super.onDraw(canvas);
4596         }
4597 
4598         @Override
onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)4599         protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
4600             super.onFocusChanged(focused, direction, previouslyFocusedRect);
4601             mHasCalledOnFocusChanged = true;
4602         }
4603 
4604         @Override
onKeyMultiple(int keyCode, int repeatCount, KeyEvent event)4605         public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
4606             mHasCalledOnKeyMultiple = true;
4607             return super.onKeyMultiple(keyCode, repeatCount, event);
4608         }
4609 
4610         @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)4611         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
4612             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
4613             mHasCalledOnMeasure = true;
4614         }
4615 
4616         @Override
onTextChanged(CharSequence text, int start, int before, int after)4617         protected void onTextChanged(CharSequence text, int start, int before, int after) {
4618             super.onTextChanged(text, start, before, after);
4619             mHasCalledOnTextChanged = true;
4620         }
4621 
4622         @Override
setFrame(int l, int t, int r, int b)4623         protected boolean setFrame(int l, int t, int r, int b) {
4624             return super.setFrame(l, t, r, b);
4625         }
4626 
4627         @Override
onWindowFocusChanged(boolean hasWindowFocus)4628         public void onWindowFocusChanged(boolean hasWindowFocus) {
4629             super.onWindowFocusChanged(hasWindowFocus);
4630             mHasCalledOnWindowFocusChanged = true;
4631         }
4632 
4633         @Override
getLeftFadingEdgeStrength()4634         protected float getLeftFadingEdgeStrength() {
4635             return super.getLeftFadingEdgeStrength();
4636         }
4637 
4638         @Override
getRightFadingEdgeStrength()4639         protected float getRightFadingEdgeStrength() {
4640             return super.getRightFadingEdgeStrength();
4641         }
4642 
4643         @Override
onPrivateIMECommand(String action, Bundle data)4644         public boolean onPrivateIMECommand(String action, Bundle data) {
4645             mHasCalledOnPrivateIMECommand = true;
4646             return super.onPrivateIMECommand(action, data);
4647         }
4648 
getFrameLeft()4649         public int getFrameLeft() {
4650             return mLeft;
4651         }
4652 
getFrameTop()4653         public int getFrameTop() {
4654             return mTop;
4655         }
4656 
getFrameRight()4657         public int getFrameRight() {
4658             return mRight;
4659         }
4660 
getFrameBottom()4661         public int getFrameBottom() {
4662             return mBottom;
4663         }
4664 
4665         @Override
getBottomPaddingOffset()4666         protected int getBottomPaddingOffset() {
4667             return super.getBottomPaddingOffset();
4668         }
4669 
4670         @Override
getLeftPaddingOffset()4671         protected int getLeftPaddingOffset() {
4672             return super.getLeftPaddingOffset();
4673         }
4674 
4675         @Override
getRightPaddingOffset()4676         protected int getRightPaddingOffset() {
4677             return super.getRightPaddingOffset();
4678         }
4679 
4680         @Override
getTopPaddingOffset()4681         protected int getTopPaddingOffset() {
4682             return super.getTopPaddingOffset();
4683         }
4684 
4685         @Override
isPaddingOffsetRequired()4686         protected boolean isPaddingOffsetRequired() {
4687             return super.isPaddingOffsetRequired();
4688         }
4689 
4690         @Override
verifyDrawable(Drawable who)4691         protected boolean verifyDrawable(Drawable who) {
4692             return super.verifyDrawable(who);
4693         }
4694 
4695         @Override
computeVerticalScrollExtent()4696         protected int computeVerticalScrollExtent() {
4697             return super.computeVerticalScrollExtent();
4698         }
4699     }
4700 }
4701