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 android.app.Activity; 20 import android.app.Instrumentation; 21 import android.app.Instrumentation.ActivityMonitor; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.res.ColorStateList; 25 import android.content.res.Resources.NotFoundException; 26 import android.cts.util.KeyEventUtil; 27 import android.cts.util.PollingCheck; 28 import android.cts.util.WidgetTestUtils; 29 import android.graphics.Bitmap; 30 import android.graphics.Color; 31 import android.graphics.Paint; 32 import android.graphics.Path; 33 import android.graphics.PorterDuff; 34 import android.graphics.Rect; 35 import android.graphics.RectF; 36 import android.graphics.Typeface; 37 import android.graphics.drawable.BitmapDrawable; 38 import android.graphics.drawable.ColorDrawable; 39 import android.graphics.drawable.Drawable; 40 import android.net.Uri; 41 import android.os.Bundle; 42 import android.os.LocaleList; 43 import android.os.Parcelable; 44 import android.test.ActivityInstrumentationTestCase2; 45 import android.test.TouchUtils; 46 import android.test.UiThreadTest; 47 import android.test.suitebuilder.annotation.MediumTest; 48 import android.test.suitebuilder.annotation.SmallTest; 49 import android.text.Editable; 50 import android.text.InputFilter; 51 import android.text.InputType; 52 import android.text.Layout; 53 import android.text.Selection; 54 import android.text.Spannable; 55 import android.text.SpannableString; 56 import android.text.Spanned; 57 import android.text.TextPaint; 58 import android.text.TextUtils; 59 import android.text.TextUtils.TruncateAt; 60 import android.text.TextWatcher; 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.TextKeyListener.Capitalize; 74 import android.text.method.TimeKeyListener; 75 import android.text.method.TransformationMethod; 76 import android.text.style.ImageSpan; 77 import android.text.style.URLSpan; 78 import android.text.style.UnderlineSpan; 79 import android.text.util.Linkify; 80 import android.util.DisplayMetrics; 81 import android.util.TypedValue; 82 import android.view.ActionMode; 83 import android.view.ContextMenu; 84 import android.view.ContextMenu.ContextMenuInfo; 85 import android.view.Gravity; 86 import android.view.KeyEvent; 87 import android.view.Menu; 88 import android.view.MenuItem; 89 import android.view.View; 90 import android.view.View.OnCreateContextMenuListener; 91 import android.view.View.OnLongClickListener; 92 import android.view.ViewGroup; 93 import android.view.accessibility.AccessibilityNodeInfo; 94 import android.view.inputmethod.BaseInputConnection; 95 import android.view.inputmethod.EditorInfo; 96 import android.view.inputmethod.ExtractedText; 97 import android.view.inputmethod.ExtractedTextRequest; 98 import android.view.inputmethod.InputConnection; 99 import android.widget.EditText; 100 import android.widget.FrameLayout; 101 import android.widget.LinearLayout; 102 import android.widget.Scroller; 103 import android.widget.TextView; 104 import android.widget.TextView.BufferType; 105 import android.widget.TextView.OnEditorActionListener; 106 107 import org.xmlpull.v1.XmlPullParserException; 108 109 import java.io.IOException; 110 import java.util.Locale; 111 112 /** 113 * Test {@link TextView}. 114 */ 115 public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewCtsActivity> { 116 117 private TextView mTextView; 118 private Activity mActivity; 119 private Instrumentation mInstrumentation; 120 private static final String LONG_TEXT = "This is a really long string which exceeds " 121 + "the width of the view. New devices have a much larger screen which " 122 + "actually enables long strings to be displayed with no fading. " 123 + "I have made this string longer to fix this case. If you are correcting " 124 + "this text, I would love to see the kind of devices you guys now use!"; 125 private static final long TIMEOUT = 5000; 126 private CharSequence mTransformedText; 127 private KeyEventUtil mKeyEventUtil; 128 TextViewTest()129 public TextViewTest() { 130 super("android.widget.cts", TextViewCtsActivity.class); 131 } 132 133 @Override setUp()134 protected void setUp() throws Exception { 135 super.setUp(); 136 mActivity = getActivity(); 137 new PollingCheck() { 138 @Override 139 protected boolean check() { 140 return mActivity.hasWindowFocus(); 141 } 142 }.run(); 143 mInstrumentation = getInstrumentation(); 144 mKeyEventUtil = new KeyEventUtil(mInstrumentation); 145 } 146 147 /** 148 * Promotes the TextView to editable and places focus in it to allow simulated typing. 149 */ initTextViewForTyping()150 private void initTextViewForTyping() { 151 mActivity.runOnUiThread(new Runnable() { 152 public void run() { 153 mTextView = findTextView(R.id.textview_text); 154 mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE)); 155 mTextView.setText("", BufferType.EDITABLE); 156 mTextView.requestFocus(); 157 } 158 }); 159 mInstrumentation.waitForIdleSync(); 160 } 161 testConstructor()162 public void testConstructor() { 163 new TextView(mActivity); 164 165 new TextView(mActivity, null); 166 167 new TextView(mActivity, null, 0); 168 } 169 170 @UiThreadTest testAccessText()171 public void testAccessText() { 172 TextView tv = findTextView(R.id.textview_text); 173 174 String expected = mActivity.getResources().getString(R.string.text_view_hello); 175 tv.setText(expected); 176 assertEquals(expected, tv.getText().toString()); 177 178 tv.setText(null); 179 assertEquals("", tv.getText().toString()); 180 } 181 testGetLineHeight()182 public void testGetLineHeight() { 183 mTextView = new TextView(mActivity); 184 assertTrue(mTextView.getLineHeight() > 0); 185 186 mTextView.setLineSpacing(1.2f, 1.5f); 187 assertTrue(mTextView.getLineHeight() > 0); 188 } 189 testGetLayout()190 public void testGetLayout() { 191 mActivity.runOnUiThread(new Runnable() { 192 public void run() { 193 mTextView = findTextView(R.id.textview_text); 194 mTextView.setGravity(Gravity.CENTER); 195 } 196 }); 197 mInstrumentation.waitForIdleSync(); 198 assertNotNull(mTextView.getLayout()); 199 200 TestLayoutRunnable runnable = new TestLayoutRunnable(mTextView) { 201 public void run() { 202 // change the text of TextView. 203 mTextView.setText("Hello, Android!"); 204 saveLayout(); 205 } 206 }; 207 mActivity.runOnUiThread(runnable); 208 mInstrumentation.waitForIdleSync(); 209 assertNull(runnable.getLayout()); 210 assertNotNull(mTextView.getLayout()); 211 } 212 testAccessKeyListener()213 public void testAccessKeyListener() { 214 mActivity.runOnUiThread(new Runnable() { 215 public void run() { 216 mTextView = findTextView(R.id.textview_text); 217 } 218 }); 219 mInstrumentation.waitForIdleSync(); 220 221 assertNull(mTextView.getKeyListener()); 222 223 final KeyListener digitsKeyListener = DigitsKeyListener.getInstance(); 224 225 mActivity.runOnUiThread(new Runnable() { 226 public void run() { 227 mTextView.setKeyListener(digitsKeyListener); 228 } 229 }); 230 mInstrumentation.waitForIdleSync(); 231 assertSame(digitsKeyListener, mTextView.getKeyListener()); 232 233 final QwertyKeyListener qwertyKeyListener 234 = QwertyKeyListener.getInstance(false, Capitalize.NONE); 235 mActivity.runOnUiThread(new Runnable() { 236 public void run() { 237 mTextView.setKeyListener(qwertyKeyListener); 238 } 239 }); 240 mInstrumentation.waitForIdleSync(); 241 assertSame(qwertyKeyListener, mTextView.getKeyListener()); 242 } 243 testAccessMovementMethod()244 public void testAccessMovementMethod() { 245 final CharSequence LONG_TEXT = "Scrolls the specified widget to the specified " 246 + "coordinates, except constrains the X scrolling position to the horizontal " 247 + "regions of the text that will be visible after scrolling to " 248 + "the specified Y position."; 249 final int selectionStart = 10; 250 final int selectionEnd = LONG_TEXT.length(); 251 final MovementMethod movementMethod = ArrowKeyMovementMethod.getInstance(); 252 mActivity.runOnUiThread(new Runnable() { 253 public void run() { 254 mTextView = findTextView(R.id.textview_text); 255 mTextView.setMovementMethod(movementMethod); 256 mTextView.setText(LONG_TEXT, BufferType.EDITABLE); 257 Selection.setSelection((Editable) mTextView.getText(), 258 selectionStart, selectionEnd); 259 mTextView.requestFocus(); 260 } 261 }); 262 mInstrumentation.waitForIdleSync(); 263 264 assertSame(movementMethod, mTextView.getMovementMethod()); 265 assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText())); 266 assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText())); 267 sendKeys(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT, 268 KeyEvent.KEYCODE_DPAD_UP); 269 // the selection has been removed. 270 assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText())); 271 assertEquals(selectionStart, Selection.getSelectionEnd(mTextView.getText())); 272 273 mActivity.runOnUiThread(new Runnable() { 274 public void run() { 275 mTextView.setMovementMethod(null); 276 Selection.setSelection((Editable) mTextView.getText(), 277 selectionStart, selectionEnd); 278 mTextView.requestFocus(); 279 } 280 }); 281 mInstrumentation.waitForIdleSync(); 282 283 assertNull(mTextView.getMovementMethod()); 284 assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText())); 285 assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText())); 286 sendKeys(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_ALT_LEFT, 287 KeyEvent.KEYCODE_DPAD_UP); 288 // the selection will not be changed. 289 assertEquals(selectionStart, Selection.getSelectionStart(mTextView.getText())); 290 assertEquals(selectionEnd, Selection.getSelectionEnd(mTextView.getText())); 291 } 292 293 @UiThreadTest testLength()294 public void testLength() { 295 mTextView = findTextView(R.id.textview_text); 296 297 String content = "This is content"; 298 mTextView.setText(content); 299 assertEquals(content.length(), mTextView.length()); 300 301 mTextView.setText(""); 302 assertEquals(0, mTextView.length()); 303 304 mTextView.setText(null); 305 assertEquals(0, mTextView.length()); 306 } 307 308 @UiThreadTest testAccessGravity()309 public void testAccessGravity() { 310 mActivity.setContentView(R.layout.textview_gravity); 311 312 mTextView = findTextView(R.id.gravity_default); 313 assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity()); 314 315 mTextView = findTextView(R.id.gravity_bottom); 316 assertEquals(Gravity.BOTTOM | Gravity.START, mTextView.getGravity()); 317 318 mTextView = findTextView(R.id.gravity_right); 319 assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity()); 320 321 mTextView = findTextView(R.id.gravity_center); 322 assertEquals(Gravity.CENTER, mTextView.getGravity()); 323 324 mTextView = findTextView(R.id.gravity_fill); 325 assertEquals(Gravity.FILL, mTextView.getGravity()); 326 327 mTextView = findTextView(R.id.gravity_center_vertical_right); 328 assertEquals(Gravity.CENTER_VERTICAL | Gravity.RIGHT, mTextView.getGravity()); 329 330 mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); 331 assertEquals(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, mTextView.getGravity()); 332 mTextView.setGravity(Gravity.FILL); 333 assertEquals(Gravity.FILL, mTextView.getGravity()); 334 mTextView.setGravity(Gravity.CENTER); 335 assertEquals(Gravity.CENTER, mTextView.getGravity()); 336 337 mTextView.setGravity(Gravity.NO_GRAVITY); 338 assertEquals(Gravity.TOP | Gravity.START, mTextView.getGravity()); 339 340 mTextView.setGravity(Gravity.RIGHT); 341 assertEquals(Gravity.TOP | Gravity.RIGHT, mTextView.getGravity()); 342 343 mTextView.setGravity(Gravity.FILL_VERTICAL); 344 assertEquals(Gravity.FILL_VERTICAL | Gravity.START, mTextView.getGravity()); 345 346 //test negative input value. 347 mTextView.setGravity(-1); 348 assertEquals(-1, mTextView.getGravity()); 349 } 350 testAccessAutoLinkMask()351 public void testAccessAutoLinkMask() { 352 mTextView = findTextView(R.id.textview_text); 353 final CharSequence text1 = 354 new SpannableString("URL: http://www.google.com. mailto: account@gmail.com"); 355 mActivity.runOnUiThread(new Runnable() { 356 public void run() { 357 mTextView.setAutoLinkMask(Linkify.ALL); 358 mTextView.setText(text1, BufferType.EDITABLE); 359 } 360 }); 361 mInstrumentation.waitForIdleSync(); 362 assertEquals(Linkify.ALL, mTextView.getAutoLinkMask()); 363 364 Spannable spanString = (Spannable) mTextView.getText(); 365 URLSpan[] spans = spanString.getSpans(0, spanString.length(), URLSpan.class); 366 assertNotNull(spans); 367 assertEquals(2, spans.length); 368 assertEquals("http://www.google.com", spans[0].getURL()); 369 assertEquals("mailto:account@gmail.com", spans[1].getURL()); 370 371 final CharSequence text2 = 372 new SpannableString("name: Jack. tel: +41 44 800 8999"); 373 mActivity.runOnUiThread(new Runnable() { 374 public void run() { 375 mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS); 376 mTextView.setText(text2, BufferType.EDITABLE); 377 } 378 }); 379 mInstrumentation.waitForIdleSync(); 380 assertEquals(Linkify.PHONE_NUMBERS, mTextView.getAutoLinkMask()); 381 382 spanString = (Spannable) mTextView.getText(); 383 spans = spanString.getSpans(0, spanString.length(), URLSpan.class); 384 assertNotNull(spans); 385 assertEquals(1, spans.length); 386 assertEquals("tel:+41448008999", spans[0].getURL()); 387 388 layout(R.layout.textview_autolink); 389 // 1 for web, 2 for email, 4 for phone, 7 for all(web|email|phone) 390 assertEquals(0, getAutoLinkMask(R.id.autolink_default)); 391 assertEquals(Linkify.WEB_URLS, getAutoLinkMask(R.id.autolink_web)); 392 assertEquals(Linkify.EMAIL_ADDRESSES, getAutoLinkMask(R.id.autolink_email)); 393 assertEquals(Linkify.PHONE_NUMBERS, getAutoLinkMask(R.id.autolink_phone)); 394 assertEquals(Linkify.ALL, getAutoLinkMask(R.id.autolink_all)); 395 assertEquals(Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES, 396 getAutoLinkMask(R.id.autolink_compound1)); 397 assertEquals(Linkify.WEB_URLS | Linkify.PHONE_NUMBERS, 398 getAutoLinkMask(R.id.autolink_compound2)); 399 assertEquals(Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS, 400 getAutoLinkMask(R.id.autolink_compound3)); 401 assertEquals(Linkify.PHONE_NUMBERS | Linkify.ALL, 402 getAutoLinkMask(R.id.autolink_compound4)); 403 } 404 testAccessTextSize()405 public void testAccessTextSize() { 406 DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics(); 407 408 mTextView = new TextView(mActivity); 409 mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20f); 410 assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20f, metrics), 411 mTextView.getTextSize(), 0.01f); 412 413 mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20f); 414 assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics), 415 mTextView.getTextSize(), 0.01f); 416 417 mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20f); 418 assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics), 419 mTextView.getTextSize(), 0.01f); 420 421 // setTextSize by default unit "sp" 422 mTextView.setTextSize(20f); 423 assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics), 424 mTextView.getTextSize(), 0.01f); 425 426 mTextView.setTextSize(200f); 427 assertEquals(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 200f, metrics), 428 mTextView.getTextSize(), 0.01f); 429 } 430 testAccessTextColor()431 public void testAccessTextColor() { 432 mTextView = new TextView(mActivity); 433 434 mTextView.setTextColor(Color.GREEN); 435 assertEquals(Color.GREEN, mTextView.getCurrentTextColor()); 436 assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getTextColors()); 437 438 mTextView.setTextColor(Color.BLACK); 439 assertEquals(Color.BLACK, mTextView.getCurrentTextColor()); 440 assertSame(ColorStateList.valueOf(Color.BLACK), mTextView.getTextColors()); 441 442 mTextView.setTextColor(Color.RED); 443 assertEquals(Color.RED, mTextView.getCurrentTextColor()); 444 assertSame(ColorStateList.valueOf(Color.RED), mTextView.getTextColors()); 445 446 // using ColorStateList 447 // normal 448 ColorStateList colors = new ColorStateList(new int[][] { 449 new int[] { android.R.attr.state_focused}, new int[0] }, 450 new int[] { Color.rgb(0, 255, 0), Color.BLACK }); 451 mTextView.setTextColor(colors); 452 assertSame(colors, mTextView.getTextColors()); 453 assertEquals(Color.BLACK, mTextView.getCurrentTextColor()); 454 455 // exceptional 456 try { 457 mTextView.setTextColor(null); 458 fail("Should thrown exception if the colors is null"); 459 } catch (NullPointerException e){ 460 } 461 } 462 testGetTextColor()463 public void testGetTextColor() { 464 // TODO: How to get a suitable TypedArray to test this method. 465 466 try { 467 TextView.getTextColor(mActivity, null, -1); 468 fail("There should be a NullPointerException thrown out."); 469 } catch (NullPointerException e) { 470 } 471 } 472 testSetHighlightColor()473 public void testSetHighlightColor() { 474 mTextView = new TextView(mActivity); 475 476 mTextView.setHighlightColor(0x00ff00ff); 477 } 478 testSetShadowLayer()479 public void testSetShadowLayer() { 480 MockTextView textView = new MockTextView(mActivity); 481 482 // shadow is placed to the left and below the text 483 textView.setShadowLayer(1.0f, 0.3f, 0.3f, Color.CYAN); 484 assertTrue(textView.isPaddingOffsetRequired()); 485 assertEquals(0, textView.getLeftPaddingOffset()); 486 assertEquals(0, textView.getTopPaddingOffset()); 487 assertEquals(1, textView.getRightPaddingOffset()); 488 assertEquals(1, textView.getBottomPaddingOffset()); 489 490 // shadow is placed to the right and above the text 491 textView.setShadowLayer(1.0f, -0.8f, -0.8f, Color.CYAN); 492 assertTrue(textView.isPaddingOffsetRequired()); 493 assertEquals(-1, textView.getLeftPaddingOffset()); 494 assertEquals(-1, textView.getTopPaddingOffset()); 495 assertEquals(0, textView.getRightPaddingOffset()); 496 assertEquals(0, textView.getBottomPaddingOffset()); 497 498 // no shadow 499 textView.setShadowLayer(0.0f, 0.0f, 0.0f, Color.CYAN); 500 assertFalse(textView.isPaddingOffsetRequired()); 501 assertEquals(0, textView.getLeftPaddingOffset()); 502 assertEquals(0, textView.getTopPaddingOffset()); 503 assertEquals(0, textView.getRightPaddingOffset()); 504 assertEquals(0, textView.getBottomPaddingOffset()); 505 } 506 507 @UiThreadTest testSetSelectAllOnFocus()508 public void testSetSelectAllOnFocus() { 509 mActivity.setContentView(R.layout.textview_selectallonfocus); 510 String content = "This is the content"; 511 String blank = ""; 512 mTextView = findTextView(R.id.selectAllOnFocus_default); 513 mTextView.setText(blank, BufferType.SPANNABLE); 514 // change the focus 515 findTextView(R.id.selectAllOnFocus_dummy).requestFocus(); 516 assertFalse(mTextView.isFocused()); 517 mTextView.requestFocus(); 518 assertTrue(mTextView.isFocused()); 519 520 assertEquals(-1, mTextView.getSelectionStart()); 521 assertEquals(-1, mTextView.getSelectionEnd()); 522 523 mTextView.setText(content, BufferType.SPANNABLE); 524 mTextView.setSelectAllOnFocus(true); 525 // change the focus 526 findTextView(R.id.selectAllOnFocus_dummy).requestFocus(); 527 assertFalse(mTextView.isFocused()); 528 mTextView.requestFocus(); 529 assertTrue(mTextView.isFocused()); 530 531 assertEquals(0, mTextView.getSelectionStart()); 532 assertEquals(content.length(), mTextView.getSelectionEnd()); 533 534 Selection.setSelection((Spannable) mTextView.getText(), 0); 535 mTextView.setSelectAllOnFocus(false); 536 // change the focus 537 findTextView(R.id.selectAllOnFocus_dummy).requestFocus(); 538 assertFalse(mTextView.isFocused()); 539 mTextView.requestFocus(); 540 assertTrue(mTextView.isFocused()); 541 542 assertEquals(0, mTextView.getSelectionStart()); 543 assertEquals(0, mTextView.getSelectionEnd()); 544 545 mTextView.setText(blank, BufferType.SPANNABLE); 546 mTextView.setSelectAllOnFocus(true); 547 // change the focus 548 findTextView(R.id.selectAllOnFocus_dummy).requestFocus(); 549 assertFalse(mTextView.isFocused()); 550 mTextView.requestFocus(); 551 assertTrue(mTextView.isFocused()); 552 553 assertEquals(0, mTextView.getSelectionStart()); 554 assertEquals(blank.length(), mTextView.getSelectionEnd()); 555 556 Selection.setSelection((Spannable) mTextView.getText(), 0); 557 mTextView.setSelectAllOnFocus(false); 558 // change the focus 559 findTextView(R.id.selectAllOnFocus_dummy).requestFocus(); 560 assertFalse(mTextView.isFocused()); 561 mTextView.requestFocus(); 562 assertTrue(mTextView.isFocused()); 563 564 assertEquals(0, mTextView.getSelectionStart()); 565 assertEquals(0, mTextView.getSelectionEnd()); 566 } 567 testGetPaint()568 public void testGetPaint() { 569 mTextView = new TextView(mActivity); 570 TextPaint tp = mTextView.getPaint(); 571 assertNotNull(tp); 572 573 assertEquals(mTextView.getPaintFlags(), tp.getFlags()); 574 } 575 576 @UiThreadTest testAccessLinksClickable()577 public void testAccessLinksClickable() { 578 mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext); 579 580 mTextView = findTextView(R.id.hint_linksClickable_freezesText_default); 581 assertTrue(mTextView.getLinksClickable()); 582 583 mTextView = findTextView(R.id.linksClickable_true); 584 assertTrue(mTextView.getLinksClickable()); 585 586 mTextView = findTextView(R.id.linksClickable_false); 587 assertFalse(mTextView.getLinksClickable()); 588 589 mTextView.setLinksClickable(false); 590 assertFalse(mTextView.getLinksClickable()); 591 592 mTextView.setLinksClickable(true); 593 assertTrue(mTextView.getLinksClickable()); 594 595 assertNull(mTextView.getMovementMethod()); 596 597 final CharSequence text = new SpannableString("name: Jack. tel: +41 44 800 8999"); 598 599 mTextView.setAutoLinkMask(Linkify.PHONE_NUMBERS); 600 mTextView.setText(text, BufferType.EDITABLE); 601 602 // Movement method will be automatically set to LinkMovementMethod 603 assertTrue(mTextView.getMovementMethod() instanceof LinkMovementMethod); 604 } 605 testAccessHintTextColor()606 public void testAccessHintTextColor() { 607 mTextView = new TextView(mActivity); 608 // using int values 609 // normal 610 mTextView.setHintTextColor(Color.GREEN); 611 assertEquals(Color.GREEN, mTextView.getCurrentHintTextColor()); 612 assertSame(ColorStateList.valueOf(Color.GREEN), mTextView.getHintTextColors()); 613 614 mTextView.setHintTextColor(Color.BLUE); 615 assertSame(ColorStateList.valueOf(Color.BLUE), mTextView.getHintTextColors()); 616 assertEquals(Color.BLUE, mTextView.getCurrentHintTextColor()); 617 618 mTextView.setHintTextColor(Color.RED); 619 assertSame(ColorStateList.valueOf(Color.RED), mTextView.getHintTextColors()); 620 assertEquals(Color.RED, mTextView.getCurrentHintTextColor()); 621 622 // using ColorStateList 623 // normal 624 ColorStateList colors = new ColorStateList(new int[][] { 625 new int[] { android.R.attr.state_focused}, new int[0] }, 626 new int[] { Color.rgb(0, 255, 0), Color.BLACK }); 627 mTextView.setHintTextColor(colors); 628 assertSame(colors, mTextView.getHintTextColors()); 629 assertEquals(Color.BLACK, mTextView.getCurrentHintTextColor()); 630 631 // exceptional 632 mTextView.setHintTextColor(null); 633 assertNull(mTextView.getHintTextColors()); 634 assertEquals(mTextView.getCurrentTextColor(), mTextView.getCurrentHintTextColor()); 635 } 636 testAccessLinkTextColor()637 public void testAccessLinkTextColor() { 638 mTextView = new TextView(mActivity); 639 // normal 640 mTextView.setLinkTextColor(Color.GRAY); 641 assertSame(ColorStateList.valueOf(Color.GRAY), mTextView.getLinkTextColors()); 642 assertEquals(Color.GRAY, mTextView.getPaint().linkColor); 643 644 mTextView.setLinkTextColor(Color.YELLOW); 645 assertSame(ColorStateList.valueOf(Color.YELLOW), mTextView.getLinkTextColors()); 646 assertEquals(Color.YELLOW, mTextView.getPaint().linkColor); 647 648 mTextView.setLinkTextColor(Color.WHITE); 649 assertSame(ColorStateList.valueOf(Color.WHITE), mTextView.getLinkTextColors()); 650 assertEquals(Color.WHITE, mTextView.getPaint().linkColor); 651 652 ColorStateList colors = new ColorStateList(new int[][] { 653 new int[] { android.R.attr.state_expanded}, new int[0] }, 654 new int[] { Color.rgb(0, 255, 0), Color.BLACK }); 655 mTextView.setLinkTextColor(colors); 656 assertSame(colors, mTextView.getLinkTextColors()); 657 assertEquals(Color.BLACK, mTextView.getPaint().linkColor); 658 659 mTextView.setLinkTextColor(null); 660 assertNull(mTextView.getLinkTextColors()); 661 assertEquals(Color.BLACK, mTextView.getPaint().linkColor); 662 } 663 testAccessPaintFlags()664 public void testAccessPaintFlags() { 665 mTextView = new TextView(mActivity); 666 assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG 667 | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags()); 668 669 mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG); 670 assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG, 671 mTextView.getPaintFlags()); 672 673 mTextView.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG); 674 assertEquals(Paint.STRIKE_THRU_TEXT_FLAG | Paint.LINEAR_TEXT_FLAG, 675 mTextView.getPaintFlags()); 676 } 677 testHeightAndWidth()678 public void testHeightAndWidth() { 679 mTextView = findTextView(R.id.textview_text); 680 int originalWidth = mTextView.getWidth(); 681 setWidth(mTextView.getWidth() >> 3); 682 int originalHeight = mTextView.getHeight(); 683 684 setMaxHeight(originalHeight + 1); 685 assertEquals(originalHeight, mTextView.getHeight()); 686 687 setMaxHeight(originalHeight - 1); 688 assertEquals(originalHeight - 1, mTextView.getHeight()); 689 690 setMaxHeight(-1); 691 assertEquals(0, mTextView.getHeight()); 692 693 setMaxHeight(Integer.MAX_VALUE); 694 assertEquals(originalHeight, mTextView.getHeight()); 695 696 setMinHeight(originalHeight + 1); 697 assertEquals(originalHeight + 1, mTextView.getHeight()); 698 699 setMinHeight(originalHeight - 1); 700 assertEquals(originalHeight, mTextView.getHeight()); 701 702 setMinHeight(-1); 703 assertEquals(originalHeight, mTextView.getHeight()); 704 705 setMinHeight(0); 706 setMaxHeight(Integer.MAX_VALUE); 707 708 setHeight(originalHeight + 1); 709 assertEquals(originalHeight + 1, mTextView.getHeight()); 710 711 setHeight(originalHeight - 1); 712 assertEquals(originalHeight - 1, mTextView.getHeight()); 713 714 setHeight(-1); 715 assertEquals(0, mTextView.getHeight()); 716 717 setHeight(originalHeight); 718 assertEquals(originalHeight, mTextView.getHeight()); 719 720 assertEquals(originalWidth >> 3, mTextView.getWidth()); 721 722 // Min Width 723 setMinWidth(originalWidth + 1); 724 assertEquals(1, mTextView.getLineCount()); 725 assertEquals(originalWidth + 1, mTextView.getWidth()); 726 727 setMinWidth(originalWidth - 1); 728 assertEquals(2, mTextView.getLineCount()); 729 assertEquals(originalWidth - 1, mTextView.getWidth()); 730 731 // Width 732 setWidth(originalWidth + 1); 733 assertEquals(1, mTextView.getLineCount()); 734 assertEquals(originalWidth + 1, mTextView.getWidth()); 735 736 setWidth(originalWidth - 1); 737 assertEquals(2, mTextView.getLineCount()); 738 assertEquals(originalWidth - 1, mTextView.getWidth()); 739 } 740 testSetMinEms()741 public void testSetMinEms() { 742 mTextView = findTextView(R.id.textview_text); 743 assertEquals(1, mTextView.getLineCount()); 744 745 int originalWidth = mTextView.getWidth(); 746 int originalEms = originalWidth / mTextView.getLineHeight(); 747 748 setMinEms(originalEms + 1); 749 assertEquals((originalEms + 1) * mTextView.getLineHeight(), mTextView.getWidth()); 750 751 setMinEms(originalEms - 1); 752 assertEquals(originalWidth, mTextView.getWidth()); 753 } 754 testSetMaxEms()755 public void testSetMaxEms() { 756 mTextView = findTextView(R.id.textview_text); 757 assertEquals(1, mTextView.getLineCount()); 758 int originalWidth = mTextView.getWidth(); 759 int originalEms = originalWidth / mTextView.getLineHeight(); 760 761 setMaxEms(originalEms + 1); 762 assertEquals(1, mTextView.getLineCount()); 763 assertEquals(originalWidth, mTextView.getWidth()); 764 765 setMaxEms(originalEms - 1); 766 assertTrue(1 < mTextView.getLineCount()); 767 assertEquals((originalEms - 1) * mTextView.getLineHeight(), 768 mTextView.getWidth()); 769 } 770 testSetEms()771 public void testSetEms() { 772 mTextView = findTextView(R.id.textview_text); 773 assertEquals("check height", 1, mTextView.getLineCount()); 774 int originalWidth = mTextView.getWidth(); 775 int originalEms = originalWidth / mTextView.getLineHeight(); 776 777 setEms(originalEms + 1); 778 assertEquals(1, mTextView.getLineCount()); 779 assertEquals((originalEms + 1) * mTextView.getLineHeight(), 780 mTextView.getWidth()); 781 782 setEms(originalEms - 1); 783 assertTrue((1 < mTextView.getLineCount())); 784 assertEquals((originalEms - 1) * mTextView.getLineHeight(), 785 mTextView.getWidth()); 786 } 787 testSetLineSpacing()788 public void testSetLineSpacing() { 789 mTextView = new TextView(mActivity); 790 int originalLineHeight = mTextView.getLineHeight(); 791 792 // normal 793 float add = 1.2f; 794 float mult = 1.4f; 795 setLineSpacing(add, mult); 796 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 797 add = 0.0f; 798 mult = 1.4f; 799 setLineSpacing(add, mult); 800 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 801 802 // abnormal 803 add = -1.2f; 804 mult = 1.4f; 805 setLineSpacing(add, mult); 806 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 807 add = -1.2f; 808 mult = -1.4f; 809 setLineSpacing(add, mult); 810 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 811 add = 1.2f; 812 mult = 0.0f; 813 setLineSpacing(add, mult); 814 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 815 816 // edge 817 add = Float.MIN_VALUE; 818 mult = Float.MIN_VALUE; 819 setLineSpacing(add, mult); 820 assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight()); 821 822 // edge case where the behavior of Math.round() deviates from 823 // FastMath.round(), requiring us to use an explicit 0 value 824 add = Float.MAX_VALUE; 825 mult = Float.MAX_VALUE; 826 setLineSpacing(add, mult); 827 assertEquals(0, mTextView.getLineHeight()); 828 } 829 testSetElegantLineHeight()830 public void testSetElegantLineHeight() { 831 mTextView = findTextView(R.id.textview_text); 832 assertFalse(mTextView.getPaint().isElegantTextHeight()); 833 mActivity.runOnUiThread(new Runnable() { 834 public void run() { 835 mTextView.setWidth(mTextView.getWidth() / 3); 836 mTextView.setPadding(1, 2, 3, 4); 837 mTextView.setGravity(Gravity.BOTTOM); 838 } 839 }); 840 mInstrumentation.waitForIdleSync(); 841 842 int oldHeight = mTextView.getHeight(); 843 mActivity.runOnUiThread(new Runnable() { 844 public void run() { 845 mTextView.setElegantTextHeight(true); 846 } 847 }); 848 mInstrumentation.waitForIdleSync(); 849 850 assertTrue(mTextView.getPaint().isElegantTextHeight()); 851 assertTrue(mTextView.getHeight() > oldHeight); 852 853 mActivity.runOnUiThread(new Runnable() { 854 public void run() { 855 mTextView.setElegantTextHeight(false); 856 } 857 }); 858 mInstrumentation.waitForIdleSync(); 859 assertFalse(mTextView.getPaint().isElegantTextHeight()); 860 assertTrue(mTextView.getHeight() == oldHeight); 861 } 862 testInstanceState()863 public void testInstanceState() { 864 // Do not test. Implementation details. 865 } 866 testAccessFreezesText()867 public void testAccessFreezesText() throws Throwable { 868 layout(R.layout.textview_hint_linksclickable_freezestext); 869 870 mTextView = findTextView(R.id.hint_linksClickable_freezesText_default); 871 assertFalse(mTextView.getFreezesText()); 872 873 mTextView = findTextView(R.id.freezesText_true); 874 assertTrue(mTextView.getFreezesText()); 875 876 mTextView = findTextView(R.id.freezesText_false); 877 assertFalse(mTextView.getFreezesText()); 878 879 mTextView.setFreezesText(false); 880 assertFalse(mTextView.getFreezesText()); 881 882 final CharSequence text = "Hello, TextView."; 883 mActivity.runOnUiThread(new Runnable() { 884 public void run() { 885 mTextView.setText(text); 886 } 887 }); 888 mInstrumentation.waitForIdleSync(); 889 890 final URLSpan urlSpan = new URLSpan("ctstest://TextView/test"); 891 // TODO: How to simulate the TextView in frozen icicles. 892 Instrumentation instrumentation = getInstrumentation(); 893 ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(), 894 null, false); 895 896 mActivity.runOnUiThread(new Runnable() { 897 public void run() { 898 Uri uri = Uri.parse(urlSpan.getURL()); 899 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 900 mActivity.startActivity(intent); 901 } 902 }); 903 904 Activity newActivity = am.waitForActivityWithTimeout(TIMEOUT); 905 assertNotNull(newActivity); 906 newActivity.finish(); 907 instrumentation.removeMonitor(am); 908 // the text of TextView is removed. 909 mTextView = findTextView(R.id.freezesText_false); 910 911 assertEquals(text.toString(), mTextView.getText().toString()); 912 913 mTextView.setFreezesText(true); 914 assertTrue(mTextView.getFreezesText()); 915 916 mActivity.runOnUiThread(new Runnable() { 917 public void run() { 918 mTextView.setText(text); 919 } 920 }); 921 mInstrumentation.waitForIdleSync(); 922 // TODO: How to simulate the TextView in frozen icicles. 923 am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(), 924 null, false); 925 926 mActivity.runOnUiThread(new Runnable() { 927 public void run() { 928 Uri uri = Uri.parse(urlSpan.getURL()); 929 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 930 mActivity.startActivity(intent); 931 } 932 }); 933 934 Activity oldActivity = newActivity; 935 while (true) { 936 newActivity = am.waitForActivityWithTimeout(TIMEOUT); 937 assertNotNull(newActivity); 938 if (newActivity != oldActivity) { 939 break; 940 } 941 } 942 newActivity.finish(); 943 instrumentation.removeMonitor(am); 944 // the text of TextView is still there. 945 mTextView = findTextView(R.id.freezesText_false); 946 assertEquals(text.toString(), mTextView.getText().toString()); 947 } 948 testSetEditableFactory()949 public void testSetEditableFactory() { 950 mTextView = new TextView(mActivity); 951 String text = "sample"; 952 MockEditableFactory factory = new MockEditableFactory(); 953 mTextView.setEditableFactory(factory); 954 955 factory.reset(); 956 mTextView.setText(text); 957 assertFalse(factory.hasCalledNewEditable()); 958 959 factory.reset(); 960 mTextView.setText(text, BufferType.SPANNABLE); 961 assertFalse(factory.hasCalledNewEditable()); 962 963 factory.reset(); 964 mTextView.setText(text, BufferType.NORMAL); 965 assertFalse(factory.hasCalledNewEditable()); 966 967 factory.reset(); 968 mTextView.setText(text, BufferType.EDITABLE); 969 assertTrue(factory.hasCalledNewEditable()); 970 assertEquals(text, factory.getSource()); 971 972 mTextView.setKeyListener(DigitsKeyListener.getInstance()); 973 factory.reset(); 974 mTextView.setText(text, BufferType.EDITABLE); 975 assertTrue(factory.hasCalledNewEditable()); 976 assertEquals(text, factory.getSource()); 977 978 try { 979 mTextView.setEditableFactory(null); 980 fail("The factory can not set to null!"); 981 } catch (NullPointerException e) { 982 } 983 } 984 testSetSpannableFactory()985 public void testSetSpannableFactory() { 986 mTextView = new TextView(mActivity); 987 String text = "sample"; 988 MockSpannableFactory factory = new MockSpannableFactory(); 989 mTextView.setSpannableFactory(factory); 990 991 factory.reset(); 992 mTextView.setText(text); 993 assertFalse(factory.hasCalledNewSpannable()); 994 995 factory.reset(); 996 mTextView.setText(text, BufferType.EDITABLE); 997 assertFalse(factory.hasCalledNewSpannable()); 998 999 factory.reset(); 1000 mTextView.setText(text, BufferType.NORMAL); 1001 assertFalse(factory.hasCalledNewSpannable()); 1002 1003 factory.reset(); 1004 mTextView.setText(text, BufferType.SPANNABLE); 1005 assertTrue(factory.hasCalledNewSpannable()); 1006 assertEquals(text, factory.getSource()); 1007 1008 mTextView.setMovementMethod(LinkMovementMethod.getInstance()); 1009 factory.reset(); 1010 mTextView.setText(text, BufferType.NORMAL); 1011 assertTrue(factory.hasCalledNewSpannable()); 1012 assertEquals(text, factory.getSource()); 1013 1014 try { 1015 mTextView.setSpannableFactory(null); 1016 fail("The factory can not set to null!"); 1017 } catch (NullPointerException e) { 1018 } 1019 } 1020 testTextChangedListener()1021 public void testTextChangedListener() { 1022 mTextView = new TextView(mActivity); 1023 MockTextWatcher watcher0 = new MockTextWatcher(); 1024 MockTextWatcher watcher1 = new MockTextWatcher(); 1025 1026 mTextView.addTextChangedListener(watcher0); 1027 mTextView.addTextChangedListener(watcher1); 1028 1029 watcher0.reset(); 1030 watcher1.reset(); 1031 mTextView.setText("Changed"); 1032 assertTrue(watcher0.hasCalledBeforeTextChanged()); 1033 assertTrue(watcher0.hasCalledOnTextChanged()); 1034 assertTrue(watcher0.hasCalledAfterTextChanged()); 1035 assertTrue(watcher1.hasCalledBeforeTextChanged()); 1036 assertTrue(watcher1.hasCalledOnTextChanged()); 1037 assertTrue(watcher1.hasCalledAfterTextChanged()); 1038 1039 watcher0.reset(); 1040 watcher1.reset(); 1041 // BeforeTextChanged and OnTextChanged are called though the strings are same 1042 mTextView.setText("Changed"); 1043 assertTrue(watcher0.hasCalledBeforeTextChanged()); 1044 assertTrue(watcher0.hasCalledOnTextChanged()); 1045 assertTrue(watcher0.hasCalledAfterTextChanged()); 1046 assertTrue(watcher1.hasCalledBeforeTextChanged()); 1047 assertTrue(watcher1.hasCalledOnTextChanged()); 1048 assertTrue(watcher1.hasCalledAfterTextChanged()); 1049 1050 watcher0.reset(); 1051 watcher1.reset(); 1052 // BeforeTextChanged and OnTextChanged are called twice (The text is not 1053 // Editable, so in Append() it calls setText() first) 1054 mTextView.append("and appended"); 1055 assertTrue(watcher0.hasCalledBeforeTextChanged()); 1056 assertTrue(watcher0.hasCalledOnTextChanged()); 1057 assertTrue(watcher0.hasCalledAfterTextChanged()); 1058 assertTrue(watcher1.hasCalledBeforeTextChanged()); 1059 assertTrue(watcher1.hasCalledOnTextChanged()); 1060 assertTrue(watcher1.hasCalledAfterTextChanged()); 1061 1062 watcher0.reset(); 1063 watcher1.reset(); 1064 // Methods are not called if the string does not change 1065 mTextView.append(""); 1066 assertFalse(watcher0.hasCalledBeforeTextChanged()); 1067 assertFalse(watcher0.hasCalledOnTextChanged()); 1068 assertFalse(watcher0.hasCalledAfterTextChanged()); 1069 assertFalse(watcher1.hasCalledBeforeTextChanged()); 1070 assertFalse(watcher1.hasCalledOnTextChanged()); 1071 assertFalse(watcher1.hasCalledAfterTextChanged()); 1072 1073 watcher0.reset(); 1074 watcher1.reset(); 1075 mTextView.removeTextChangedListener(watcher1); 1076 mTextView.setText(null); 1077 assertTrue(watcher0.hasCalledBeforeTextChanged()); 1078 assertTrue(watcher0.hasCalledOnTextChanged()); 1079 assertTrue(watcher0.hasCalledAfterTextChanged()); 1080 assertFalse(watcher1.hasCalledBeforeTextChanged()); 1081 assertFalse(watcher1.hasCalledOnTextChanged()); 1082 assertFalse(watcher1.hasCalledAfterTextChanged()); 1083 } 1084 testSetTextKeepState1()1085 public void testSetTextKeepState1() { 1086 mTextView = new TextView(mActivity); 1087 1088 String longString = "very long content"; 1089 String shortString = "short"; 1090 1091 // selection is at the exact place which is inside the short string 1092 mTextView.setText(longString, BufferType.SPANNABLE); 1093 Selection.setSelection((Spannable) mTextView.getText(), 3); 1094 mTextView.setTextKeepState(shortString); 1095 assertEquals(shortString, mTextView.getText().toString()); 1096 assertEquals(3, mTextView.getSelectionStart()); 1097 assertEquals(3, mTextView.getSelectionEnd()); 1098 1099 // selection is at the exact place which is outside the short string 1100 mTextView.setText(longString); 1101 Selection.setSelection((Spannable) mTextView.getText(), shortString.length() + 1); 1102 mTextView.setTextKeepState(shortString); 1103 assertEquals(shortString, mTextView.getText().toString()); 1104 assertEquals(shortString.length(), mTextView.getSelectionStart()); 1105 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1106 1107 // select the sub string which is inside the short string 1108 mTextView.setText(longString); 1109 Selection.setSelection((Spannable) mTextView.getText(), 1, 4); 1110 mTextView.setTextKeepState(shortString); 1111 assertEquals(shortString, mTextView.getText().toString()); 1112 assertEquals(1, mTextView.getSelectionStart()); 1113 assertEquals(4, mTextView.getSelectionEnd()); 1114 1115 // select the sub string which ends outside the short string 1116 mTextView.setText(longString); 1117 Selection.setSelection((Spannable) mTextView.getText(), 2, shortString.length() + 1); 1118 mTextView.setTextKeepState(shortString); 1119 assertEquals(shortString, mTextView.getText().toString()); 1120 assertEquals(2, mTextView.getSelectionStart()); 1121 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1122 1123 // select the sub string which is outside the short string 1124 mTextView.setText(longString); 1125 Selection.setSelection((Spannable) mTextView.getText(), 1126 shortString.length() + 1, shortString.length() + 3); 1127 mTextView.setTextKeepState(shortString); 1128 assertEquals(shortString, mTextView.getText().toString()); 1129 assertEquals(shortString.length(), mTextView.getSelectionStart()); 1130 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1131 } 1132 1133 @UiThreadTest testGetEditableText()1134 public void testGetEditableText() { 1135 TextView tv = findTextView(R.id.textview_text); 1136 1137 String text = "Hello"; 1138 tv.setText(text, BufferType.EDITABLE); 1139 assertEquals(text, tv.getText().toString()); 1140 assertTrue(tv.getText() instanceof Editable); 1141 assertEquals(text, tv.getEditableText().toString()); 1142 1143 tv.setText(text, BufferType.SPANNABLE); 1144 assertEquals(text, tv.getText().toString()); 1145 assertTrue(tv.getText() instanceof Spannable); 1146 assertNull(tv.getEditableText()); 1147 1148 tv.setText(null, BufferType.EDITABLE); 1149 assertEquals("", tv.getText().toString()); 1150 assertTrue(tv.getText() instanceof Editable); 1151 assertEquals("", tv.getEditableText().toString()); 1152 1153 tv.setText(null, BufferType.SPANNABLE); 1154 assertEquals("", tv.getText().toString()); 1155 assertTrue(tv.getText() instanceof Spannable); 1156 assertNull(tv.getEditableText()); 1157 } 1158 1159 @UiThreadTest testSetText2()1160 public void testSetText2() { 1161 String string = "This is a test for setting text content by char array"; 1162 char[] input = string.toCharArray(); 1163 TextView tv = findTextView(R.id.textview_text); 1164 1165 tv.setText(input, 0, input.length); 1166 assertEquals(string, tv.getText().toString()); 1167 1168 tv.setText(input, 0, 5); 1169 assertEquals(string.substring(0, 5), tv.getText().toString()); 1170 1171 try { 1172 tv.setText(input, -1, input.length); 1173 fail("Should throw exception if the start position is negative!"); 1174 } catch (IndexOutOfBoundsException exception) { 1175 } 1176 1177 try { 1178 tv.setText(input, 0, -1); 1179 fail("Should throw exception if the length is negative!"); 1180 } catch (IndexOutOfBoundsException exception) { 1181 } 1182 1183 try { 1184 tv.setText(input, 1, input.length); 1185 fail("Should throw exception if the end position is out of index!"); 1186 } catch (IndexOutOfBoundsException exception) { 1187 } 1188 1189 tv.setText(input, 1, 0); 1190 assertEquals("", tv.getText().toString()); 1191 } 1192 1193 @UiThreadTest testSetText1()1194 public void testSetText1() { 1195 mTextView = findTextView(R.id.textview_text); 1196 1197 String longString = "very long content"; 1198 String shortString = "short"; 1199 1200 // selection is at the exact place which is inside the short string 1201 mTextView.setText(longString, BufferType.SPANNABLE); 1202 Selection.setSelection((Spannable) mTextView.getText(), 3); 1203 mTextView.setTextKeepState(shortString, BufferType.EDITABLE); 1204 assertTrue(mTextView.getText() instanceof Editable); 1205 assertEquals(shortString, mTextView.getText().toString()); 1206 assertEquals(shortString, mTextView.getEditableText().toString()); 1207 assertEquals(3, mTextView.getSelectionStart()); 1208 assertEquals(3, mTextView.getSelectionEnd()); 1209 1210 mTextView.setText(shortString, BufferType.EDITABLE); 1211 assertTrue(mTextView.getText() instanceof Editable); 1212 assertEquals(shortString, mTextView.getText().toString()); 1213 assertEquals(shortString, mTextView.getEditableText().toString()); 1214 // there is no selection. 1215 assertEquals(-1, mTextView.getSelectionStart()); 1216 assertEquals(-1, mTextView.getSelectionEnd()); 1217 1218 // selection is at the exact place which is outside the short string 1219 mTextView.setText(longString); 1220 Selection.setSelection((Spannable) mTextView.getText(), longString.length()); 1221 mTextView.setTextKeepState(shortString, BufferType.EDITABLE); 1222 assertTrue(mTextView.getText() instanceof Editable); 1223 assertEquals(shortString, mTextView.getText().toString()); 1224 assertEquals(shortString, mTextView.getEditableText().toString()); 1225 assertEquals(shortString.length(), mTextView.getSelectionStart()); 1226 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1227 1228 mTextView.setText(shortString, BufferType.EDITABLE); 1229 assertTrue(mTextView.getText() instanceof Editable); 1230 assertEquals(shortString, mTextView.getText().toString()); 1231 assertEquals(shortString, mTextView.getEditableText().toString()); 1232 // there is no selection. 1233 assertEquals(-1, mTextView.getSelectionStart()); 1234 assertEquals(-1, mTextView.getSelectionEnd()); 1235 1236 // select the sub string which is inside the short string 1237 mTextView.setText(longString); 1238 Selection.setSelection((Spannable) mTextView.getText(), 1, shortString.length() - 1); 1239 mTextView.setTextKeepState(shortString, BufferType.EDITABLE); 1240 assertTrue(mTextView.getText() instanceof Editable); 1241 assertEquals(shortString, mTextView.getText().toString()); 1242 assertEquals(shortString, mTextView.getEditableText().toString()); 1243 assertEquals(1, mTextView.getSelectionStart()); 1244 assertEquals(shortString.length() - 1, mTextView.getSelectionEnd()); 1245 1246 mTextView.setText(shortString, BufferType.EDITABLE); 1247 assertTrue(mTextView.getText() instanceof Editable); 1248 assertEquals(shortString, mTextView.getText().toString()); 1249 assertEquals(shortString, mTextView.getEditableText().toString()); 1250 // there is no selection. 1251 assertEquals(-1, mTextView.getSelectionStart()); 1252 assertEquals(-1, mTextView.getSelectionEnd()); 1253 1254 // select the sub string which ends outside the short string 1255 mTextView.setText(longString); 1256 Selection.setSelection((Spannable) mTextView.getText(), 2, longString.length()); 1257 mTextView.setTextKeepState(shortString, BufferType.EDITABLE); 1258 assertTrue(mTextView.getText() instanceof Editable); 1259 assertEquals(shortString, mTextView.getText().toString()); 1260 assertEquals(shortString, mTextView.getEditableText().toString()); 1261 assertEquals(2, mTextView.getSelectionStart()); 1262 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1263 1264 mTextView.setText(shortString, BufferType.EDITABLE); 1265 assertTrue(mTextView.getText() instanceof Editable); 1266 assertEquals(shortString, mTextView.getText().toString()); 1267 assertEquals(shortString, mTextView.getEditableText().toString()); 1268 // there is no selection. 1269 assertEquals(-1, mTextView.getSelectionStart()); 1270 assertEquals(-1, mTextView.getSelectionEnd()); 1271 1272 // select the sub string which is outside the short string 1273 mTextView.setText(longString); 1274 Selection.setSelection((Spannable) mTextView.getText(), 1275 shortString.length() + 1, shortString.length() + 3); 1276 mTextView.setTextKeepState(shortString, BufferType.EDITABLE); 1277 assertTrue(mTextView.getText() instanceof Editable); 1278 assertEquals(shortString, mTextView.getText().toString()); 1279 assertEquals(shortString, mTextView.getEditableText().toString()); 1280 assertEquals(shortString.length(), mTextView.getSelectionStart()); 1281 assertEquals(shortString.length(), mTextView.getSelectionEnd()); 1282 1283 mTextView.setText(shortString, BufferType.EDITABLE); 1284 assertTrue(mTextView.getText() instanceof Editable); 1285 assertEquals(shortString, mTextView.getText().toString()); 1286 assertEquals(shortString, mTextView.getEditableText().toString()); 1287 // there is no selection. 1288 assertEquals(-1, mTextView.getSelectionStart()); 1289 assertEquals(-1, mTextView.getSelectionEnd()); 1290 } 1291 1292 @UiThreadTest testSetText3()1293 public void testSetText3() { 1294 TextView tv = findTextView(R.id.textview_text); 1295 1296 int resId = R.string.text_view_hint; 1297 String result = mActivity.getResources().getString(resId); 1298 1299 tv.setText(resId); 1300 assertEquals(result, tv.getText().toString()); 1301 1302 try { 1303 tv.setText(-1); 1304 fail("Should throw exception with illegal id"); 1305 } catch (NotFoundException e) { 1306 } 1307 } 1308 1309 @MediumTest testSetText_updatesHeightAfterRemovingImageSpan()1310 public void testSetText_updatesHeightAfterRemovingImageSpan() { 1311 // Height calculation had problems when TextView had width: match_parent 1312 final int textViewWidth = ViewGroup.LayoutParams.MATCH_PARENT; 1313 final Spannable text = new SpannableString("some text"); 1314 final int spanHeight = 100; 1315 1316 // prepare TextView, width: MATCH_PARENT 1317 TextView textView = new TextView(getActivity()); 1318 textView.setSingleLine(true); 1319 textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 2); 1320 textView.setPadding(0, 0, 0, 0); 1321 textView.setIncludeFontPadding(false); 1322 textView.setText(text); 1323 final FrameLayout layout = new FrameLayout(mActivity); 1324 final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(textViewWidth, 1325 ViewGroup.LayoutParams.WRAP_CONTENT); 1326 layout.addView(textView, layoutParams); 1327 layout.setLayoutParams(layoutParams); 1328 mActivity.runOnUiThread(new Runnable() { 1329 @Override 1330 public void run() { 1331 getActivity().setContentView(layout); 1332 } 1333 }); 1334 getInstrumentation().waitForIdleSync(); 1335 1336 // measure height of text with no span 1337 final int heightWithoutSpan = textView.getHeight(); 1338 assertTrue("Text height should be smaller than span height", 1339 heightWithoutSpan < spanHeight); 1340 1341 // add ImageSpan to text 1342 Drawable drawable = mInstrumentation.getContext().getDrawable(R.drawable.scenery); 1343 drawable.setBounds(0, 0, spanHeight, spanHeight); 1344 ImageSpan span = new ImageSpan(drawable); 1345 text.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 1346 mActivity.runOnUiThread(new Runnable() { 1347 @Override 1348 public void run() { 1349 textView.setText(text); 1350 } 1351 }); 1352 mInstrumentation.waitForIdleSync(); 1353 1354 // measure height with span 1355 final int heightWithSpan = textView.getHeight(); 1356 assertTrue("Text height should be greater or equal than span height", 1357 heightWithSpan >= spanHeight); 1358 1359 // remove the span 1360 text.removeSpan(span); 1361 mActivity.runOnUiThread(new Runnable() { 1362 @Override 1363 public void run() { 1364 textView.setText(text); 1365 } 1366 }); 1367 mInstrumentation.waitForIdleSync(); 1368 1369 final int heightAfterRemoveSpan = textView.getHeight(); 1370 assertEquals("Text height should be same after removing the span", 1371 heightWithoutSpan, heightAfterRemoveSpan); 1372 } 1373 testRemoveSelectionWithSelectionHandles()1374 public void testRemoveSelectionWithSelectionHandles() { 1375 initTextViewForTyping(); 1376 1377 mActivity.runOnUiThread(new Runnable() { 1378 @Override 1379 public void run() { 1380 mTextView.setTextIsSelectable(true); 1381 mTextView.setText("abcd", BufferType.EDITABLE); 1382 } 1383 }); 1384 mInstrumentation.waitForIdleSync(); 1385 1386 // Long click on the text selects all text and shows selection handlers. The view has an 1387 // attribute layout_width="wrap_content", so clicked location (the center of the view) 1388 // should be on the text. 1389 TouchUtils.longClickView(this, mTextView); 1390 1391 mActivity.runOnUiThread(new Runnable() { 1392 @Override 1393 public void run() { 1394 Selection.removeSelection((Spannable) mTextView.getText()); 1395 } 1396 }); 1397 1398 // Make sure that a crash doesn't happen with {@link Selection#removeSelection}. 1399 mInstrumentation.waitForIdleSync(); 1400 } 1401 testUndo_insert()1402 public void testUndo_insert() { 1403 initTextViewForTyping(); 1404 1405 // Type some text. 1406 mKeyEventUtil.sendString(mTextView, "abc"); 1407 mActivity.runOnUiThread(new Runnable() { 1408 public void run() { 1409 // Precondition: The cursor is at the end of the text. 1410 assertEquals(3, mTextView.getSelectionStart()); 1411 1412 // Undo removes the typed string in one step. 1413 mTextView.onTextContextMenuItem(android.R.id.undo); 1414 assertEquals("", mTextView.getText().toString()); 1415 assertEquals(0, mTextView.getSelectionStart()); 1416 1417 // Redo restores the text and cursor position. 1418 mTextView.onTextContextMenuItem(android.R.id.redo); 1419 assertEquals("abc", mTextView.getText().toString()); 1420 assertEquals(3, mTextView.getSelectionStart()); 1421 1422 // Undoing the redo clears the text again. 1423 mTextView.onTextContextMenuItem(android.R.id.undo); 1424 assertEquals("", mTextView.getText().toString()); 1425 1426 // Undo when the undo stack is empty does nothing. 1427 mTextView.onTextContextMenuItem(android.R.id.undo); 1428 assertEquals("", mTextView.getText().toString()); 1429 } 1430 }); 1431 mInstrumentation.waitForIdleSync(); 1432 } 1433 testUndo_delete()1434 public void testUndo_delete() { 1435 initTextViewForTyping(); 1436 1437 // Simulate deleting text and undoing it. 1438 mKeyEventUtil.sendString(mTextView, "xyz"); 1439 mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 1440 KeyEvent.KEYCODE_DEL); 1441 mActivity.runOnUiThread(new Runnable() { 1442 public void run() { 1443 // Precondition: The text was actually deleted. 1444 assertEquals("", mTextView.getText().toString()); 1445 assertEquals(0, mTextView.getSelectionStart()); 1446 1447 // Undo restores the typed string and cursor position in one step. 1448 mTextView.onTextContextMenuItem(android.R.id.undo); 1449 assertEquals("xyz", mTextView.getText().toString()); 1450 assertEquals(3, mTextView.getSelectionStart()); 1451 1452 // Redo removes the text in one step. 1453 mTextView.onTextContextMenuItem(android.R.id.redo); 1454 assertEquals("", mTextView.getText().toString()); 1455 assertEquals(0, mTextView.getSelectionStart()); 1456 1457 // Undoing the redo restores the text again. 1458 mTextView.onTextContextMenuItem(android.R.id.undo); 1459 assertEquals("xyz", mTextView.getText().toString()); 1460 assertEquals(3, mTextView.getSelectionStart()); 1461 1462 // Undoing again undoes the original typing. 1463 mTextView.onTextContextMenuItem(android.R.id.undo); 1464 assertEquals("", mTextView.getText().toString()); 1465 assertEquals(0, mTextView.getSelectionStart()); 1466 } 1467 }); 1468 mInstrumentation.waitForIdleSync(); 1469 } 1470 1471 // Initialize the text view for simulated IME typing. Must be called on UI thread. initTextViewForSimulatedIme()1472 private InputConnection initTextViewForSimulatedIme() { 1473 mTextView = findTextView(R.id.textview_text); 1474 mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE)); 1475 mTextView.setText("", BufferType.EDITABLE); 1476 return mTextView.onCreateInputConnection(new EditorInfo()); 1477 } 1478 1479 // Simulates IME composing text behavior. setComposingTextInBatch(InputConnection input, CharSequence text)1480 private void setComposingTextInBatch(InputConnection input, CharSequence text) { 1481 input.beginBatchEdit(); 1482 input.setComposingText(text, 1); // Leave cursor at end. 1483 input.endBatchEdit(); 1484 } 1485 1486 @UiThreadTest testUndo_imeInsertLatin()1487 public void testUndo_imeInsertLatin() { 1488 InputConnection input = initTextViewForSimulatedIme(); 1489 1490 // Simulate IME text entry behavior. The Latin IME enters text by replacing partial words, 1491 // such as "c" -> "ca" -> "cat" -> "cat ". 1492 setComposingTextInBatch(input, "c"); 1493 setComposingTextInBatch(input, "ca"); 1494 1495 // The completion and space are added in the same batch. 1496 input.beginBatchEdit(); 1497 input.commitText("cat", 1); 1498 input.commitText(" ", 1); 1499 input.endBatchEdit(); 1500 1501 // The repeated replacements undo in a single step. 1502 mTextView.onTextContextMenuItem(android.R.id.undo); 1503 assertEquals("", mTextView.getText().toString()); 1504 } 1505 1506 @UiThreadTest testUndo_imeInsertJapanese()1507 public void testUndo_imeInsertJapanese() { 1508 InputConnection input = initTextViewForSimulatedIme(); 1509 1510 // The Japanese IME does repeated replacements of Latin characters to hiragana to kanji. 1511 final String HA = "\u306F"; // HIRAGANA LETTER HA 1512 final String NA = "\u306A"; // HIRAGANA LETTER NA 1513 setComposingTextInBatch(input, "h"); 1514 setComposingTextInBatch(input, HA); 1515 setComposingTextInBatch(input, HA + "n"); 1516 setComposingTextInBatch(input, HA + NA); 1517 1518 // The result may be a surrogate pair. The composition ends in the same batch. 1519 input.beginBatchEdit(); 1520 input.commitText("\uD83C\uDF37", 1); // U+1F337 TULIP 1521 input.setComposingText("", 1); 1522 input.endBatchEdit(); 1523 1524 // The repeated replacements are a single undo step. 1525 mTextView.onTextContextMenuItem(android.R.id.undo); 1526 assertEquals("", mTextView.getText().toString()); 1527 } 1528 1529 @UiThreadTest testUndo_imeCancel()1530 public void testUndo_imeCancel() { 1531 InputConnection input = initTextViewForSimulatedIme(); 1532 mTextView.setText("flower"); 1533 1534 // Start typing a composition. 1535 final String HA = "\u306F"; // HIRAGANA LETTER HA 1536 setComposingTextInBatch(input, "h"); 1537 setComposingTextInBatch(input, HA); 1538 setComposingTextInBatch(input, HA + "n"); 1539 1540 // Cancel the composition. 1541 setComposingTextInBatch(input, ""); 1542 1543 // Undo and redo do nothing. 1544 mTextView.onTextContextMenuItem(android.R.id.undo); 1545 assertEquals("flower", mTextView.getText().toString()); 1546 mTextView.onTextContextMenuItem(android.R.id.redo); 1547 assertEquals("flower", mTextView.getText().toString()); 1548 } 1549 1550 @UiThreadTest testUndo_imeEmptyBatch()1551 public void testUndo_imeEmptyBatch() { 1552 InputConnection input = initTextViewForSimulatedIme(); 1553 mTextView.setText("flower"); 1554 1555 // Send an empty batch edit. This happens if the IME is hidden and shown. 1556 input.beginBatchEdit(); 1557 input.endBatchEdit(); 1558 1559 // Undo and redo do nothing. 1560 mTextView.onTextContextMenuItem(android.R.id.undo); 1561 assertEquals("flower", mTextView.getText().toString()); 1562 mTextView.onTextContextMenuItem(android.R.id.redo); 1563 assertEquals("flower", mTextView.getText().toString()); 1564 } 1565 testUndo_setText()1566 public void testUndo_setText() { 1567 initTextViewForTyping(); 1568 1569 // Create two undo operations, an insert and a delete. 1570 mKeyEventUtil.sendString(mTextView, "xyz"); 1571 mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 1572 KeyEvent.KEYCODE_DEL); 1573 mActivity.runOnUiThread(new Runnable() { 1574 public void run() { 1575 // Calling setText() clears both undo operations, so undo doesn't happen. 1576 mTextView.setText("Hello", BufferType.EDITABLE); 1577 mTextView.onTextContextMenuItem(android.R.id.undo); 1578 assertEquals("Hello", mTextView.getText().toString()); 1579 1580 // Clearing text programmatically does not undo either. 1581 mTextView.setText("", BufferType.EDITABLE); 1582 mTextView.onTextContextMenuItem(android.R.id.undo); 1583 assertEquals("", mTextView.getText().toString()); 1584 } 1585 }); 1586 mInstrumentation.waitForIdleSync(); 1587 } 1588 testRedo_setText()1589 public void testRedo_setText() { 1590 initTextViewForTyping(); 1591 1592 // Type some text. This creates an undo entry. 1593 mKeyEventUtil.sendString(mTextView, "abc"); 1594 mActivity.runOnUiThread(new Runnable() { 1595 public void run() { 1596 // Undo the typing to create a redo entry. 1597 mTextView.onTextContextMenuItem(android.R.id.undo); 1598 1599 // Calling setText() clears the redo stack, so redo doesn't happen. 1600 mTextView.setText("Hello", BufferType.EDITABLE); 1601 mTextView.onTextContextMenuItem(android.R.id.redo); 1602 assertEquals("Hello", mTextView.getText().toString()); 1603 } 1604 }); 1605 mInstrumentation.waitForIdleSync(); 1606 } 1607 testUndo_directAppend()1608 public void testUndo_directAppend() { 1609 initTextViewForTyping(); 1610 1611 // Type some text. 1612 mKeyEventUtil.sendString(mTextView, "abc"); 1613 mActivity.runOnUiThread(new Runnable() { 1614 public void run() { 1615 // Programmatically append some text. 1616 mTextView.append("def"); 1617 assertEquals("abcdef", mTextView.getText().toString()); 1618 1619 // Undo removes the append as a separate step. 1620 mTextView.onTextContextMenuItem(android.R.id.undo); 1621 assertEquals("abc", mTextView.getText().toString()); 1622 1623 // Another undo removes the original typing. 1624 mTextView.onTextContextMenuItem(android.R.id.undo); 1625 assertEquals("", mTextView.getText().toString()); 1626 } 1627 }); 1628 mInstrumentation.waitForIdleSync(); 1629 } 1630 testUndo_directInsert()1631 public void testUndo_directInsert() { 1632 initTextViewForTyping(); 1633 1634 // Type some text. 1635 mKeyEventUtil.sendString(mTextView, "abc"); 1636 mActivity.runOnUiThread(new Runnable() { 1637 public void run() { 1638 // Directly modify the underlying Editable to insert some text. 1639 // NOTE: This is a violation of the API of getText() which specifies that the 1640 // returned object should not be modified. However, some apps do this anyway and 1641 // the framework needs to handle it. 1642 Editable text = (Editable) mTextView.getText(); 1643 text.insert(0, "def"); 1644 assertEquals("defabc", mTextView.getText().toString()); 1645 1646 // Undo removes the insert as a separate step. 1647 mTextView.onTextContextMenuItem(android.R.id.undo); 1648 assertEquals("abc", mTextView.getText().toString()); 1649 1650 // Another undo removes the original typing. 1651 mTextView.onTextContextMenuItem(android.R.id.undo); 1652 assertEquals("", mTextView.getText().toString()); 1653 } 1654 }); 1655 mInstrumentation.waitForIdleSync(); 1656 } 1657 testUndo_noCursor()1658 public void testUndo_noCursor() { 1659 initTextViewForTyping(); 1660 1661 mActivity.runOnUiThread(new Runnable() { 1662 public void run() { 1663 // Append some text to create an undo operation. There is no cursor present. 1664 mTextView.append("cat"); 1665 1666 // Place the cursor at the end of the text so the undo will have to change it. 1667 Selection.setSelection((Spannable) mTextView.getText(), 3); 1668 1669 // Undo the append. This should not crash, despite not having a valid cursor 1670 // position in the undo operation. 1671 mTextView.onTextContextMenuItem(android.R.id.undo); 1672 } 1673 }); 1674 mInstrumentation.waitForIdleSync(); 1675 } 1676 testUndo_textWatcher()1677 public void testUndo_textWatcher() { 1678 initTextViewForTyping(); 1679 1680 // Add a TextWatcher that converts the text to spaces on each change. 1681 mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher()); 1682 1683 // Type some text. 1684 mKeyEventUtil.sendString(mTextView, "abc"); 1685 mActivity.runOnUiThread(new Runnable() { 1686 public void run() { 1687 // TextWatcher altered the text. 1688 assertEquals(" ", mTextView.getText().toString()); 1689 1690 // Undo reverses both changes in one step. 1691 mTextView.onTextContextMenuItem(android.R.id.undo); 1692 assertEquals("", mTextView.getText().toString()); 1693 } 1694 }); 1695 mInstrumentation.waitForIdleSync(); 1696 } 1697 testUndo_textWatcherDirectAppend()1698 public void testUndo_textWatcherDirectAppend() { 1699 initTextViewForTyping(); 1700 1701 // Add a TextWatcher that converts the text to spaces on each change. 1702 mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher()); 1703 1704 mActivity.runOnUiThread(new Runnable() { 1705 public void run() { 1706 // Programmatically append some text. The TextWatcher changes it to spaces. 1707 mTextView.append("abc"); 1708 assertEquals(" ", mTextView.getText().toString()); 1709 1710 // Undo reverses both changes in one step. 1711 mTextView.onTextContextMenuItem(android.R.id.undo); 1712 assertEquals("", mTextView.getText().toString()); 1713 } 1714 }); 1715 mInstrumentation.waitForIdleSync(); 1716 } 1717 testUndo_shortcuts()1718 public void testUndo_shortcuts() { 1719 initTextViewForTyping(); 1720 1721 // Type some text. 1722 mKeyEventUtil.sendString(mTextView, "abc"); 1723 mActivity.runOnUiThread(new Runnable() { 1724 public void run() { 1725 // Pressing Control-Z triggers undo. 1726 KeyEvent control = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 0, 1727 KeyEvent.META_CTRL_LEFT_ON); 1728 assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, control)); 1729 assertEquals("", mTextView.getText().toString()); 1730 1731 // Pressing Control-Shift-Z triggers redo. 1732 KeyEvent controlShift = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 1733 0, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON); 1734 assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, controlShift)); 1735 assertEquals("abc", mTextView.getText().toString()); 1736 } 1737 }); 1738 mInstrumentation.waitForIdleSync(); 1739 } 1740 testUndo_saveInstanceState()1741 public void testUndo_saveInstanceState() { 1742 initTextViewForTyping(); 1743 1744 // Type some text to create an undo operation. 1745 mKeyEventUtil.sendString(mTextView, "abc"); 1746 mActivity.runOnUiThread(new Runnable() { 1747 public void run() { 1748 // Parcel and unparcel the TextView. 1749 Parcelable state = mTextView.onSaveInstanceState(); 1750 mTextView.onRestoreInstanceState(state); 1751 } 1752 }); 1753 mInstrumentation.waitForIdleSync(); 1754 1755 // Delete a character to create a new undo operation. 1756 mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL); 1757 mActivity.runOnUiThread(new Runnable() { 1758 public void run() { 1759 assertEquals("ab", mTextView.getText().toString()); 1760 1761 // Undo the delete. 1762 mTextView.onTextContextMenuItem(android.R.id.undo); 1763 assertEquals("abc", mTextView.getText().toString()); 1764 1765 // Undo the typing, which verifies that the original undo operation was parceled 1766 // correctly. 1767 mTextView.onTextContextMenuItem(android.R.id.undo); 1768 assertEquals("", mTextView.getText().toString()); 1769 1770 // Parcel and unparcel the undo stack (which is empty but has been used and may 1771 // contain other state). 1772 Parcelable state = mTextView.onSaveInstanceState(); 1773 mTextView.onRestoreInstanceState(state); 1774 } 1775 }); 1776 mInstrumentation.waitForIdleSync(); 1777 } 1778 testUndo_saveInstanceStateEmpty()1779 public void testUndo_saveInstanceStateEmpty() { 1780 initTextViewForTyping(); 1781 1782 // Type and delete to create two new undo operations. 1783 mKeyEventUtil.sendString(mTextView, "a"); 1784 mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL); 1785 mActivity.runOnUiThread(new Runnable() { 1786 public void run() { 1787 // Empty the undo stack then parcel and unparcel the TextView. While the undo 1788 // stack contains no operations it may contain other state. 1789 mTextView.onTextContextMenuItem(android.R.id.undo); 1790 mTextView.onTextContextMenuItem(android.R.id.undo); 1791 Parcelable state = mTextView.onSaveInstanceState(); 1792 mTextView.onRestoreInstanceState(state); 1793 } 1794 }); 1795 mInstrumentation.waitForIdleSync(); 1796 1797 // Create two more undo operations. 1798 mKeyEventUtil.sendString(mTextView, "b"); 1799 mKeyEventUtil.sendKeys(mTextView, KeyEvent.KEYCODE_DEL); 1800 mActivity.runOnUiThread(new Runnable() { 1801 public void run() { 1802 // Verify undo still works. 1803 mTextView.onTextContextMenuItem(android.R.id.undo); 1804 assertEquals("b", mTextView.getText().toString()); 1805 mTextView.onTextContextMenuItem(android.R.id.undo); 1806 assertEquals("", mTextView.getText().toString()); 1807 } 1808 }); 1809 mInstrumentation.waitForIdleSync(); 1810 } 1811 testCopyAndPaste()1812 public void testCopyAndPaste() { 1813 initTextViewForTyping(); 1814 mActivity.runOnUiThread(new Runnable() { 1815 public void run() { 1816 mTextView.setText("abcd", BufferType.EDITABLE); 1817 mTextView.setSelected(true); 1818 1819 // Copy "bc". 1820 Selection.setSelection((Spannable) mTextView.getText(), 1, 3); 1821 mTextView.onTextContextMenuItem(android.R.id.copy); 1822 1823 // Paste "bc" between "b" and "c". 1824 Selection.setSelection((Spannable) mTextView.getText(), 2, 2); 1825 mTextView.onTextContextMenuItem(android.R.id.paste); 1826 assertEquals("abbccd", mTextView.getText().toString()); 1827 1828 // Select entire text and paste "bc". 1829 Selection.selectAll((Spannable) mTextView.getText()); 1830 mTextView.onTextContextMenuItem(android.R.id.paste); 1831 assertEquals("bc", mTextView.getText().toString()); 1832 } 1833 }); 1834 mInstrumentation.waitForIdleSync(); 1835 } 1836 testCopyAndPaste_byKey()1837 public void testCopyAndPaste_byKey() { 1838 initTextViewForTyping(); 1839 1840 // Type "abc". 1841 mInstrumentation.sendStringSync("abc"); 1842 mActivity.runOnUiThread(new Runnable() { 1843 public void run() { 1844 // Select "bc" 1845 Selection.setSelection((Spannable) mTextView.getText(), 1, 3); 1846 } 1847 }); 1848 mInstrumentation.waitForIdleSync(); 1849 // Copy "bc" 1850 sendKeys(KeyEvent.KEYCODE_COPY); 1851 1852 mActivity.runOnUiThread(new Runnable() { 1853 public void run() { 1854 // Set cursor between 'b' and 'c'. 1855 Selection.setSelection((Spannable) mTextView.getText(), 2, 2); 1856 } 1857 }); 1858 mInstrumentation.waitForIdleSync(); 1859 // Paste "bc" 1860 sendKeys(KeyEvent.KEYCODE_PASTE); 1861 assertEquals("abbcc", mTextView.getText().toString()); 1862 1863 mActivity.runOnUiThread(new Runnable() { 1864 public void run() { 1865 Selection.selectAll((Spannable) mTextView.getText()); 1866 KeyEvent copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, 1867 KeyEvent.KEYCODE_COPY, 0, KeyEvent.META_SHIFT_LEFT_ON); 1868 // Shift + copy doesn't perform copy. 1869 mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta); 1870 Selection.setSelection((Spannable) mTextView.getText(), 0, 0); 1871 mTextView.onTextContextMenuItem(android.R.id.paste); 1872 assertEquals("bcabbcc", mTextView.getText().toString()); 1873 1874 Selection.selectAll((Spannable) mTextView.getText()); 1875 copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0, 1876 KeyEvent.META_CTRL_LEFT_ON); 1877 // Control + copy doesn't perform copy. 1878 mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta); 1879 Selection.setSelection((Spannable) mTextView.getText(), 0, 0); 1880 mTextView.onTextContextMenuItem(android.R.id.paste); 1881 assertEquals("bcbcabbcc", mTextView.getText().toString()); 1882 1883 Selection.selectAll((Spannable) mTextView.getText()); 1884 copyWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_COPY, 0, 1885 KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON); 1886 // Control + Shift + copy doesn't perform copy. 1887 mTextView.onKeyDown(KeyEvent.KEYCODE_COPY, copyWithMeta); 1888 Selection.setSelection((Spannable) mTextView.getText(), 0, 0); 1889 mTextView.onTextContextMenuItem(android.R.id.paste); 1890 assertEquals("bcbcbcabbcc", mTextView.getText().toString()); 1891 } 1892 }); 1893 mInstrumentation.waitForIdleSync(); 1894 } 1895 testCutAndPaste()1896 public void testCutAndPaste() { 1897 initTextViewForTyping(); 1898 mActivity.runOnUiThread(new Runnable() { 1899 public void run() { 1900 mTextView.setText("abcd", BufferType.EDITABLE); 1901 mTextView.setSelected(true); 1902 1903 // Cut "bc". 1904 Selection.setSelection((Spannable) mTextView.getText(), 1, 3); 1905 mTextView.onTextContextMenuItem(android.R.id.cut); 1906 assertEquals("ad", mTextView.getText().toString()); 1907 1908 // Cut "ad". 1909 Selection.setSelection((Spannable) mTextView.getText(), 0, 2); 1910 mTextView.onTextContextMenuItem(android.R.id.cut); 1911 assertEquals("", mTextView.getText().toString()); 1912 1913 // Paste "ad". 1914 mTextView.onTextContextMenuItem(android.R.id.paste); 1915 assertEquals("ad", mTextView.getText().toString()); 1916 } 1917 }); 1918 mInstrumentation.waitForIdleSync(); 1919 } 1920 testCutAndPaste_byKey()1921 public void testCutAndPaste_byKey() { 1922 initTextViewForTyping(); 1923 1924 // Type "abc". 1925 mInstrumentation.sendStringSync("abc"); 1926 mActivity.runOnUiThread(new Runnable() { 1927 public void run() { 1928 // Select "bc" 1929 Selection.setSelection((Spannable) mTextView.getText(), 1, 3); 1930 } 1931 }); 1932 mInstrumentation.waitForIdleSync(); 1933 // Cut "bc" 1934 sendKeys(KeyEvent.KEYCODE_CUT); 1935 1936 mActivity.runOnUiThread(new Runnable() { 1937 public void run() { 1938 assertEquals("a", mTextView.getText().toString()); 1939 // Move cursor to the head 1940 Selection.setSelection((Spannable) mTextView.getText(), 0, 0); 1941 } 1942 }); 1943 mInstrumentation.waitForIdleSync(); 1944 // Paste "bc" 1945 sendKeys(KeyEvent.KEYCODE_PASTE); 1946 assertEquals("bca", mTextView.getText().toString()); 1947 1948 mActivity.runOnUiThread(new Runnable() { 1949 public void run() { 1950 Selection.selectAll((Spannable) mTextView.getText()); 1951 KeyEvent cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, 1952 KeyEvent.KEYCODE_CUT, 0, KeyEvent.META_SHIFT_LEFT_ON); 1953 // Shift + cut doesn't perform cut. 1954 mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta); 1955 assertEquals("bca", mTextView.getText().toString()); 1956 1957 cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0, 1958 KeyEvent.META_CTRL_LEFT_ON); 1959 // Control + cut doesn't perform cut. 1960 mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta); 1961 assertEquals("bca", mTextView.getText().toString()); 1962 1963 cutWithMeta = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CUT, 0, 1964 KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_CTRL_LEFT_ON); 1965 // Control + Shift + cut doesn't perform cut. 1966 mTextView.onKeyDown(KeyEvent.KEYCODE_CUT, cutWithMeta); 1967 assertEquals("bca", mTextView.getText().toString()); 1968 } 1969 }); 1970 } 1971 hasSpansAtMiddleOfText(final TextView textView, final Class<?> type)1972 private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) { 1973 final Spannable spannable = (Spannable)textView.getText(); 1974 final int at = spannable.length() / 2; 1975 return spannable.getSpans(at, at, type).length > 0; 1976 } 1977 testCutAndPaste_withAndWithoutStyle()1978 public void testCutAndPaste_withAndWithoutStyle() { 1979 initTextViewForTyping(); 1980 mActivity.runOnUiThread(new Runnable() { 1981 public void run() { 1982 mTextView.setText("example", BufferType.EDITABLE); 1983 mTextView.setSelected(true); 1984 1985 // Set URLSpan. 1986 final Spannable spannable = (Spannable) mTextView.getText(); 1987 spannable.setSpan(new URLSpan("http://example.com"), 0, spannable.length(), 0); 1988 assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class)); 1989 1990 // Cut entire text. 1991 Selection.selectAll((Spannable) mTextView.getText()); 1992 mTextView.onTextContextMenuItem(android.R.id.cut); 1993 assertEquals("", mTextView.getText().toString()); 1994 1995 // Paste without style. 1996 mTextView.onTextContextMenuItem(android.R.id.pasteAsPlainText); 1997 assertEquals("example", mTextView.getText().toString()); 1998 // Check that the text doesn't have URLSpan. 1999 assertFalse(hasSpansAtMiddleOfText(mTextView, URLSpan.class)); 2000 2001 // Paste with style. 2002 Selection.selectAll((Spannable) mTextView.getText()); 2003 mTextView.onTextContextMenuItem(android.R.id.paste); 2004 assertEquals("example", mTextView.getText().toString()); 2005 // Check that the text has URLSpan. 2006 assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class)); 2007 } 2008 }); 2009 mInstrumentation.waitForIdleSync(); 2010 } 2011 2012 @UiThreadTest testSaveInstanceState()2013 public void testSaveInstanceState() { 2014 // should save text when freezesText=true 2015 TextView originalTextView = new TextView(mActivity); 2016 final String text = "This is a string"; 2017 originalTextView.setText(text); 2018 originalTextView.setFreezesText(true); // needed to actually save state 2019 Parcelable state = originalTextView.onSaveInstanceState(); 2020 2021 TextView restoredTextView = new TextView(mActivity); 2022 restoredTextView.onRestoreInstanceState(state); 2023 assertEquals(text, restoredTextView.getText().toString()); 2024 } 2025 2026 @UiThreadTest testOnSaveInstanceState_whenFreezesTextIsFalse()2027 public void testOnSaveInstanceState_whenFreezesTextIsFalse() { 2028 final String text = "This is a string"; 2029 { // should not save text when freezesText=false 2030 // prepare TextView for before saveInstanceState 2031 TextView textView1 = new TextView(mActivity); 2032 textView1.setFreezesText(false); 2033 textView1.setText(text); 2034 2035 // prepare TextView for after saveInstanceState 2036 TextView textView2 = new TextView(mActivity); 2037 textView2.setFreezesText(false); 2038 2039 textView2.onRestoreInstanceState(textView1.onSaveInstanceState()); 2040 2041 assertEquals("", textView2.getText().toString()); 2042 } 2043 2044 { // should not save text even when textIsSelectable=true 2045 // prepare TextView for before saveInstanceState 2046 TextView textView1 = new TextView(mActivity); 2047 textView1.setFreezesText(false); 2048 textView1.setTextIsSelectable(true); 2049 textView1.setText(text); 2050 2051 // prepare TextView for after saveInstanceState 2052 TextView textView2 = new TextView(mActivity); 2053 textView2.setFreezesText(false); 2054 textView2.setTextIsSelectable(true); 2055 2056 textView2.onRestoreInstanceState(textView1.onSaveInstanceState()); 2057 2058 assertEquals("", textView2.getText().toString()); 2059 } 2060 } 2061 2062 @UiThreadTest 2063 @SmallTest testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist()2064 public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() { 2065 // prepare TextView for before saveInstanceState 2066 final String text = "This is a string"; 2067 TextView textView1 = new TextView(mActivity); 2068 textView1.setFreezesText(true); 2069 textView1.setText(text); 2070 2071 // prepare TextView for after saveInstanceState 2072 TextView textView2 = new TextView(mActivity); 2073 textView2.setFreezesText(true); 2074 2075 textView2.onRestoreInstanceState(textView1.onSaveInstanceState()); 2076 2077 assertEquals(-1, textView2.getSelectionStart()); 2078 assertEquals(-1, textView2.getSelectionEnd()); 2079 } 2080 2081 @UiThreadTest 2082 @SmallTest testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent()2083 public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() { 2084 // prepare TextView for before saveInstanceState 2085 final String text = "This is a string"; 2086 TextView textView1 = new TextView(mActivity); 2087 textView1.setFreezesText(false); 2088 textView1.setTextIsSelectable(true); 2089 textView1.setText(text); 2090 Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2); 2091 2092 // prepare TextView for after saveInstanceState 2093 TextView textView2 = new TextView(mActivity); 2094 textView2.setFreezesText(false); 2095 textView2.setTextIsSelectable(true); 2096 2097 textView2.onRestoreInstanceState(textView1.onSaveInstanceState()); 2098 2099 assertEquals("", textView2.getText().toString()); 2100 //when textIsSelectable, selection start and end are initialized to 0 2101 assertEquals(0, textView2.getSelectionStart()); 2102 assertEquals(0, textView2.getSelectionEnd()); 2103 } 2104 2105 @UiThreadTest 2106 @SmallTest testOnSaveInstanceState_savesSelectionWhenExists()2107 public void testOnSaveInstanceState_savesSelectionWhenExists() { 2108 final String text = "This is a string"; 2109 // prepare TextView for before saveInstanceState 2110 TextView textView1 = new TextView(mActivity); 2111 textView1.setFreezesText(true); 2112 textView1.setTextIsSelectable(true); 2113 textView1.setText(text); 2114 Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2); 2115 2116 // prepare TextView for after saveInstanceState 2117 TextView textView2 = new TextView(mActivity); 2118 textView2.setFreezesText(true); 2119 textView2.setTextIsSelectable(true); 2120 2121 textView2.onRestoreInstanceState(textView1.onSaveInstanceState()); 2122 2123 assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart()); 2124 assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd()); 2125 } 2126 2127 @UiThreadTest testSetText()2128 public void testSetText() { 2129 TextView tv = findTextView(R.id.textview_text); 2130 2131 int resId = R.string.text_view_hint; 2132 String result = mActivity.getResources().getString(resId); 2133 2134 tv.setText(resId, BufferType.EDITABLE); 2135 assertEquals(result, tv.getText().toString()); 2136 assertTrue(tv.getText() instanceof Editable); 2137 2138 tv.setText(resId, BufferType.SPANNABLE); 2139 assertEquals(result, tv.getText().toString()); 2140 assertTrue(tv.getText() instanceof Spannable); 2141 2142 try { 2143 tv.setText(-1, BufferType.EDITABLE); 2144 fail("Should throw exception with illegal id"); 2145 } catch (NotFoundException e) { 2146 } 2147 } 2148 2149 @UiThreadTest testAccessHint()2150 public void testAccessHint() { 2151 mActivity.setContentView(R.layout.textview_hint_linksclickable_freezestext); 2152 2153 mTextView = findTextView(R.id.hint_linksClickable_freezesText_default); 2154 assertNull(mTextView.getHint()); 2155 2156 mTextView = findTextView(R.id.hint_blank); 2157 assertEquals("", mTextView.getHint()); 2158 2159 mTextView = findTextView(R.id.hint_string); 2160 assertEquals(mActivity.getResources().getString(R.string.text_view_simple_hint), 2161 mTextView.getHint()); 2162 2163 mTextView = findTextView(R.id.hint_resid); 2164 assertEquals(mActivity.getResources().getString(R.string.text_view_hint), 2165 mTextView.getHint()); 2166 2167 mTextView.setHint("This is hint"); 2168 assertEquals("This is hint", mTextView.getHint().toString()); 2169 2170 mTextView.setHint(R.string.text_view_hello); 2171 assertEquals(mActivity.getResources().getString(R.string.text_view_hello), 2172 mTextView.getHint().toString()); 2173 2174 // Non-exist resid 2175 try { 2176 mTextView.setHint(-1); 2177 fail("Should throw exception if id is illegal"); 2178 } catch (NotFoundException e) { 2179 } 2180 } 2181 testAccessError()2182 public void testAccessError() { 2183 mTextView = findTextView(R.id.textview_text); 2184 assertNull(mTextView.getError()); 2185 2186 final String errorText = "Oops! There is an error"; 2187 2188 mActivity.runOnUiThread(new Runnable() { 2189 public void run() { 2190 mTextView.setError(null); 2191 } 2192 }); 2193 mInstrumentation.waitForIdleSync(); 2194 assertNull(mTextView.getError()); 2195 2196 final Drawable icon = getDrawable(R.drawable.failed); 2197 mActivity.runOnUiThread(new Runnable() { 2198 public void run() { 2199 mTextView.setError(errorText, icon); 2200 } 2201 }); 2202 mInstrumentation.waitForIdleSync(); 2203 assertEquals(errorText, mTextView.getError().toString()); 2204 // can not check whether the drawable is set correctly 2205 2206 mActivity.runOnUiThread(new Runnable() { 2207 public void run() { 2208 mTextView.setError(null, null); 2209 } 2210 }); 2211 mInstrumentation.waitForIdleSync(); 2212 assertNull(mTextView.getError()); 2213 2214 mActivity.runOnUiThread(new Runnable() { 2215 public void run() { 2216 mTextView.setKeyListener(DigitsKeyListener.getInstance("")); 2217 mTextView.setText("", BufferType.EDITABLE); 2218 mTextView.setError(errorText); 2219 mTextView.requestFocus(); 2220 } 2221 }); 2222 mInstrumentation.waitForIdleSync(); 2223 2224 assertEquals(errorText, mTextView.getError().toString()); 2225 2226 mInstrumentation.sendStringSync("a"); 2227 // a key event that will not change the TextView's text 2228 assertEquals("", mTextView.getText().toString()); 2229 // The icon and error message will not be reset to null 2230 assertEquals(errorText, mTextView.getError().toString()); 2231 2232 mActivity.runOnUiThread(new Runnable() { 2233 public void run() { 2234 mTextView.setKeyListener(DigitsKeyListener.getInstance()); 2235 mTextView.setText("", BufferType.EDITABLE); 2236 mTextView.setError(errorText); 2237 mTextView.requestFocus(); 2238 } 2239 }); 2240 mInstrumentation.waitForIdleSync(); 2241 2242 mInstrumentation.sendStringSync("1"); 2243 // a key event cause changes to the TextView's text 2244 assertEquals("1", mTextView.getText().toString()); 2245 // the error message and icon will be cleared. 2246 assertNull(mTextView.getError()); 2247 } 2248 testAccessFilters()2249 public void testAccessFilters() { 2250 final InputFilter[] expected = { new InputFilter.AllCaps(), 2251 new InputFilter.LengthFilter(2) }; 2252 2253 final QwertyKeyListener qwertyKeyListener 2254 = QwertyKeyListener.getInstance(false, Capitalize.NONE); 2255 mActivity.runOnUiThread(new Runnable() { 2256 public void run() { 2257 mTextView = findTextView(R.id.textview_text); 2258 mTextView.setKeyListener(qwertyKeyListener); 2259 mTextView.setText("", BufferType.EDITABLE); 2260 mTextView.setFilters(expected); 2261 mTextView.requestFocus(); 2262 } 2263 }); 2264 mInstrumentation.waitForIdleSync(); 2265 2266 assertSame(expected, mTextView.getFilters()); 2267 2268 mInstrumentation.sendStringSync("a"); 2269 // the text is capitalized by InputFilter.AllCaps 2270 assertEquals("A", mTextView.getText().toString()); 2271 mInstrumentation.sendStringSync("b"); 2272 // the text is capitalized by InputFilter.AllCaps 2273 assertEquals("AB", mTextView.getText().toString()); 2274 mInstrumentation.sendStringSync("c"); 2275 // 'C' could not be accepted, because there is a length filter. 2276 assertEquals("AB", mTextView.getText().toString()); 2277 2278 try { 2279 mTextView.setFilters(null); 2280 fail("Should throw IllegalArgumentException!"); 2281 } catch (IllegalArgumentException e) { 2282 } 2283 } 2284 testGetFocusedRect()2285 public void testGetFocusedRect() { 2286 Rect rc = new Rect(); 2287 2288 // Basic 2289 mTextView = new TextView(mActivity); 2290 mTextView.getFocusedRect(rc); 2291 assertEquals(mTextView.getScrollX(), rc.left); 2292 assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right); 2293 assertEquals(mTextView.getScrollY(), rc.top); 2294 assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom); 2295 2296 // Single line 2297 mTextView = findTextView(R.id.textview_text); 2298 mTextView.getFocusedRect(rc); 2299 assertEquals(mTextView.getScrollX(), rc.left); 2300 assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right); 2301 assertEquals(mTextView.getScrollY(), rc.top); 2302 assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom); 2303 2304 mActivity.runOnUiThread(new Runnable() { 2305 public void run() { 2306 mTextView.setSelected(true); 2307 SpannableString text = new SpannableString(mTextView.getText()); 2308 Selection.setSelection(text, 3, 13); 2309 mTextView.setText(text); 2310 } 2311 }); 2312 mInstrumentation.waitForIdleSync(); 2313 mTextView.getFocusedRect(rc); 2314 assertNotNull(mTextView.getLayout()); 2315 /* Cursor coordinates from getPrimaryHorizontal() may have a fractional 2316 * component, while the result of getFocusedRect is in int coordinates. 2317 * It's not practical for these to match exactly, so we compare that the 2318 * integer components match - there can be a fractional pixel 2319 * discrepancy, which should be okay for all practical applications. */ 2320 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3), rc.left); 2321 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(13), rc.right); 2322 assertEquals(mTextView.getLayout().getLineTop(0), rc.top); 2323 assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom); 2324 2325 mActivity.runOnUiThread(new Runnable() { 2326 public void run() { 2327 mTextView.setSelected(true); 2328 SpannableString text = new SpannableString(mTextView.getText()); 2329 Selection.setSelection(text, 13, 3); 2330 mTextView.setText(text); 2331 } 2332 }); 2333 mInstrumentation.waitForIdleSync(); 2334 mTextView.getFocusedRect(rc); 2335 assertNotNull(mTextView.getLayout()); 2336 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) - 2, rc.left); 2337 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) + 2, rc.right); 2338 assertEquals(mTextView.getLayout().getLineTop(0), rc.top); 2339 assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom); 2340 2341 // Multi lines 2342 mTextView = findTextView(R.id.textview_text_two_lines); 2343 mTextView.getFocusedRect(rc); 2344 assertEquals(mTextView.getScrollX(), rc.left); 2345 assertEquals(mTextView.getScrollX() + mTextView.getWidth(), rc.right); 2346 assertEquals(mTextView.getScrollY(), rc.top); 2347 assertEquals(mTextView.getScrollY() + mTextView.getHeight(), rc.bottom); 2348 2349 mActivity.runOnUiThread(new Runnable() { 2350 public void run() { 2351 mTextView.setSelected(true); 2352 SpannableString text = new SpannableString(mTextView.getText()); 2353 Selection.setSelection(text, 2, 4); 2354 mTextView.setText(text); 2355 } 2356 }); 2357 mInstrumentation.waitForIdleSync(); 2358 mTextView.getFocusedRect(rc); 2359 assertNotNull(mTextView.getLayout()); 2360 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(2), rc.left); 2361 assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(4), rc.right); 2362 assertEquals(mTextView.getLayout().getLineTop(0), rc.top); 2363 assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom); 2364 2365 mActivity.runOnUiThread(new Runnable() { 2366 public void run() { 2367 mTextView.setSelected(true); 2368 SpannableString text = new SpannableString(mTextView.getText()); 2369 Selection.setSelection(text, 2, 10); // cross the "\n" and two lines 2370 mTextView.setText(text); 2371 } 2372 }); 2373 mInstrumentation.waitForIdleSync(); 2374 mTextView.getFocusedRect(rc); 2375 Path path = new Path(); 2376 mTextView.getLayout().getSelectionPath(2, 10, path); 2377 RectF rcf = new RectF(); 2378 path.computeBounds(rcf, true); 2379 assertNotNull(mTextView.getLayout()); 2380 assertEquals(rcf.left - 1, (float) rc.left); 2381 assertEquals(rcf.right + 1, (float) rc.right); 2382 assertEquals(mTextView.getLayout().getLineTop(0), rc.top); 2383 assertEquals(mTextView.getLayout().getLineBottom(1), rc.bottom); 2384 2385 // Exception 2386 try { 2387 mTextView.getFocusedRect(null); 2388 fail("Should throw NullPointerException!"); 2389 } catch (NullPointerException e) { 2390 } 2391 } 2392 testGetLineCount()2393 public void testGetLineCount() { 2394 mTextView = findTextView(R.id.textview_text); 2395 // this is an one line text with default setting. 2396 assertEquals(1, mTextView.getLineCount()); 2397 2398 // make it multi-lines 2399 setMaxWidth(mTextView.getWidth() / 3); 2400 assertTrue(1 < mTextView.getLineCount()); 2401 2402 // make it to an one line 2403 setMaxWidth(Integer.MAX_VALUE); 2404 assertEquals(1, mTextView.getLineCount()); 2405 2406 // set min lines don't effect the lines count for actual text. 2407 setMinLines(12); 2408 assertEquals(1, mTextView.getLineCount()); 2409 2410 mTextView = new TextView(mActivity); 2411 // the internal Layout has not been built. 2412 assertNull(mTextView.getLayout()); 2413 assertEquals(0, mTextView.getLineCount()); 2414 } 2415 testGetLineBounds()2416 public void testGetLineBounds() { 2417 Rect rc = new Rect(); 2418 mTextView = new TextView(mActivity); 2419 assertEquals(0, mTextView.getLineBounds(0, null)); 2420 2421 assertEquals(0, mTextView.getLineBounds(0, rc)); 2422 assertEquals(0, rc.left); 2423 assertEquals(0, rc.right); 2424 assertEquals(0, rc.top); 2425 assertEquals(0, rc.bottom); 2426 2427 mTextView = findTextView(R.id.textview_text); 2428 assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, null)); 2429 2430 assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc)); 2431 assertEquals(0, rc.left); 2432 assertEquals(mTextView.getWidth(), rc.right); 2433 assertEquals(0, rc.top); 2434 assertEquals(mTextView.getHeight(), rc.bottom); 2435 2436 mActivity.runOnUiThread(new Runnable() { 2437 public void run() { 2438 mTextView.setPadding(1, 2, 3, 4); 2439 mTextView.setGravity(Gravity.BOTTOM); 2440 } 2441 }); 2442 mInstrumentation.waitForIdleSync(); 2443 assertEquals(mTextView.getBaseline(), mTextView.getLineBounds(0, rc)); 2444 assertEquals(mTextView.getTotalPaddingLeft(), rc.left); 2445 assertEquals(mTextView.getWidth() - mTextView.getTotalPaddingRight(), rc.right); 2446 assertEquals(mTextView.getTotalPaddingTop(), rc.top); 2447 assertEquals(mTextView.getHeight() - mTextView.getTotalPaddingBottom(), rc.bottom); 2448 } 2449 testGetBaseLine()2450 public void testGetBaseLine() { 2451 mTextView = new TextView(mActivity); 2452 assertEquals(-1, mTextView.getBaseline()); 2453 2454 mTextView = findTextView(R.id.textview_text); 2455 assertEquals(mTextView.getLayout().getLineBaseline(0), mTextView.getBaseline()); 2456 2457 mActivity.runOnUiThread(new Runnable() { 2458 public void run() { 2459 mTextView.setPadding(1, 2, 3, 4); 2460 mTextView.setGravity(Gravity.BOTTOM); 2461 } 2462 }); 2463 mInstrumentation.waitForIdleSync(); 2464 int expected = mTextView.getTotalPaddingTop() + mTextView.getLayout().getLineBaseline(0); 2465 assertEquals(expected, mTextView.getBaseline()); 2466 } 2467 testPressKey()2468 public void testPressKey() { 2469 initTextViewForTyping(); 2470 2471 mInstrumentation.sendStringSync("a"); 2472 assertEquals("a", mTextView.getText().toString()); 2473 mInstrumentation.sendStringSync("b"); 2474 assertEquals("ab", mTextView.getText().toString()); 2475 sendKeys(KeyEvent.KEYCODE_DEL); 2476 assertEquals("a", mTextView.getText().toString()); 2477 } 2478 testSetIncludeFontPadding()2479 public void testSetIncludeFontPadding() { 2480 mTextView = findTextView(R.id.textview_text); 2481 assertTrue(mTextView.getIncludeFontPadding()); 2482 mActivity.runOnUiThread(new Runnable() { 2483 public void run() { 2484 mTextView.setWidth(mTextView.getWidth() / 3); 2485 mTextView.setPadding(1, 2, 3, 4); 2486 mTextView.setGravity(Gravity.BOTTOM); 2487 } 2488 }); 2489 mInstrumentation.waitForIdleSync(); 2490 2491 int oldHeight = mTextView.getHeight(); 2492 mActivity.runOnUiThread(new Runnable() { 2493 public void run() { 2494 mTextView.setIncludeFontPadding(false); 2495 } 2496 }); 2497 mInstrumentation.waitForIdleSync(); 2498 2499 assertTrue(mTextView.getHeight() < oldHeight); 2500 assertFalse(mTextView.getIncludeFontPadding()); 2501 } 2502 2503 public void testScroll() { 2504 mTextView = new TextView(mActivity); 2505 2506 assertEquals(0, mTextView.getScrollX()); 2507 assertEquals(0, mTextView.getScrollY()); 2508 2509 //don't set the Scroller, nothing changed. 2510 mTextView.computeScroll(); 2511 assertEquals(0, mTextView.getScrollX()); 2512 assertEquals(0, mTextView.getScrollY()); 2513 2514 //set the Scroller 2515 Scroller s = new Scroller(mActivity); 2516 assertNotNull(s); 2517 s.startScroll(0, 0, 320, 480, 0); 2518 s.abortAnimation(); 2519 s.forceFinished(false); 2520 mTextView.setScroller(s); 2521 2522 mTextView.computeScroll(); 2523 assertEquals(320, mTextView.getScrollX()); 2524 assertEquals(480, mTextView.getScrollY()); 2525 } 2526 2527 public void testDebug() { 2528 mTextView = new TextView(mActivity); 2529 mTextView.debug(0); 2530 2531 mTextView.setText("Hello!"); 2532 layout(mTextView); 2533 mTextView.debug(1); 2534 } 2535 2536 public void testSelection() { 2537 mTextView = new TextView(mActivity); 2538 String text = "This is the content"; 2539 mTextView.setText(text, BufferType.SPANNABLE); 2540 assertFalse(mTextView.hasSelection()); 2541 2542 Selection.selectAll((Spannable) mTextView.getText()); 2543 assertEquals(0, mTextView.getSelectionStart()); 2544 assertEquals(text.length(), mTextView.getSelectionEnd()); 2545 assertTrue(mTextView.hasSelection()); 2546 2547 int selectionStart = 5; 2548 int selectionEnd = 7; 2549 Selection.setSelection((Spannable) mTextView.getText(), selectionStart); 2550 assertEquals(selectionStart, mTextView.getSelectionStart()); 2551 assertEquals(selectionStart, mTextView.getSelectionEnd()); 2552 assertFalse(mTextView.hasSelection()); 2553 2554 Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd); 2555 assertEquals(selectionStart, mTextView.getSelectionStart()); 2556 assertEquals(selectionEnd, mTextView.getSelectionEnd()); 2557 assertTrue(mTextView.hasSelection()); 2558 } 2559 2560 @UiThreadTest 2561 public void testAccessEllipsize() { 2562 mActivity.setContentView(R.layout.textview_ellipsize); 2563 2564 mTextView = findTextView(R.id.ellipsize_default); 2565 assertNull(mTextView.getEllipsize()); 2566 2567 mTextView = findTextView(R.id.ellipsize_none); 2568 assertNull(mTextView.getEllipsize()); 2569 2570 mTextView = findTextView(R.id.ellipsize_start); 2571 assertSame(TruncateAt.START, mTextView.getEllipsize()); 2572 2573 mTextView = findTextView(R.id.ellipsize_middle); 2574 assertSame(TruncateAt.MIDDLE, mTextView.getEllipsize()); 2575 2576 mTextView = findTextView(R.id.ellipsize_end); 2577 assertSame(TruncateAt.END, mTextView.getEllipsize()); 2578 2579 mTextView.setEllipsize(TextUtils.TruncateAt.START); 2580 assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize()); 2581 2582 mTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE); 2583 assertSame(TextUtils.TruncateAt.MIDDLE, mTextView.getEllipsize()); 2584 2585 mTextView.setEllipsize(TextUtils.TruncateAt.END); 2586 assertSame(TextUtils.TruncateAt.END, mTextView.getEllipsize()); 2587 2588 mTextView.setEllipsize(null); 2589 assertNull(mTextView.getEllipsize()); 2590 2591 mTextView.setWidth(10); 2592 mTextView.setEllipsize(TextUtils.TruncateAt.START); 2593 mTextView.setText("ThisIsAVeryLongVeryLongVeryLongVeryLongVeryLongWord"); 2594 mTextView.invalidate(); 2595 2596 assertSame(TextUtils.TruncateAt.START, mTextView.getEllipsize()); 2597 // there is no method to check if '...yLongVeryLongWord' is painted in the screen. 2598 } 2599 2600 public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForSingleLine() { 2601 int textWidth = calculateTextWidth(LONG_TEXT); 2602 2603 TextView tvEllipsizeEnd = new TextView(getActivity()); 2604 tvEllipsizeEnd.setEllipsize(TruncateAt.END); 2605 tvEllipsizeEnd.setMaxLines(1); 2606 tvEllipsizeEnd.setWidth(textWidth >> 2); 2607 tvEllipsizeEnd.setText(LONG_TEXT); 2608 2609 TextView tvEllipsizeNone = new TextView(getActivity()); 2610 tvEllipsizeNone.setWidth(textWidth >> 2); 2611 tvEllipsizeNone.setText("a"); 2612 2613 final FrameLayout layout = new FrameLayout(mActivity); 2614 ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 2615 ViewGroup.LayoutParams.MATCH_PARENT, 2616 ViewGroup.LayoutParams.MATCH_PARENT); 2617 layout.addView(tvEllipsizeEnd, layoutParams); 2618 layout.addView(tvEllipsizeNone, layoutParams); 2619 layout.setLayoutParams(layoutParams); 2620 2621 mActivity.runOnUiThread(new Runnable() { 2622 @Override 2623 public void run() { 2624 getActivity().setContentView(layout); 2625 } 2626 }); 2627 getInstrumentation().waitForIdleSync(); 2628 2629 assertEquals("Ellipsized and non ellipsized single line texts should have the same " + 2630 "baseline", 2631 tvEllipsizeEnd.getLayout().getLineBaseline(0), 2632 tvEllipsizeNone.getLayout().getLineBaseline(0)); 2633 } 2634 testEllipsizeEndAndNoEllipsizeHasSameBaselineForMultiLine()2635 public void testEllipsizeEndAndNoEllipsizeHasSameBaselineForMultiLine() { 2636 int textWidth = calculateTextWidth(LONG_TEXT); 2637 2638 TextView tvEllipsizeEnd = new TextView(getActivity()); 2639 tvEllipsizeEnd.setEllipsize(TruncateAt.END); 2640 tvEllipsizeEnd.setMaxLines(2); 2641 tvEllipsizeEnd.setWidth(textWidth >> 2); 2642 tvEllipsizeEnd.setText(LONG_TEXT); 2643 2644 TextView tvEllipsizeNone = new TextView(getActivity()); 2645 tvEllipsizeNone.setMaxLines(2); 2646 tvEllipsizeNone.setWidth(textWidth >> 2); 2647 tvEllipsizeNone.setText(LONG_TEXT); 2648 2649 final FrameLayout layout = new FrameLayout(mActivity); 2650 ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 2651 ViewGroup.LayoutParams.MATCH_PARENT, 2652 ViewGroup.LayoutParams.MATCH_PARENT); 2653 2654 layout.addView(tvEllipsizeEnd, layoutParams); 2655 layout.addView(tvEllipsizeNone, layoutParams); 2656 layout.setLayoutParams(layoutParams); 2657 2658 mActivity.runOnUiThread(new Runnable() { 2659 @Override 2660 public void run() { 2661 getActivity().setContentView(layout); 2662 } 2663 }); 2664 getInstrumentation().waitForIdleSync(); 2665 2666 for (int i = 0; i < tvEllipsizeEnd.getLineCount(); i++) { 2667 assertEquals("Ellipsized and non ellipsized multi line texts should have the same " + 2668 "baseline for line " + i, 2669 tvEllipsizeEnd.getLayout().getLineBaseline(i), 2670 tvEllipsizeNone.getLayout().getLineBaseline(i)); 2671 } 2672 } 2673 testSetCursorVisible()2674 public void testSetCursorVisible() { 2675 mTextView = new TextView(mActivity); 2676 2677 mTextView.setCursorVisible(true); 2678 mTextView.setCursorVisible(false); 2679 } 2680 testOnWindowFocusChanged()2681 public void testOnWindowFocusChanged() { 2682 // Do not test. Implementation details. 2683 } 2684 testOnTouchEvent()2685 public void testOnTouchEvent() { 2686 // Do not test. Implementation details. 2687 } 2688 testOnTrackballEvent()2689 public void testOnTrackballEvent() { 2690 // Do not test. Implementation details. 2691 } 2692 testGetTextColors()2693 public void testGetTextColors() { 2694 // TODO: How to get a suitable TypedArray to test this method. 2695 } 2696 testOnKeyShortcut()2697 public void testOnKeyShortcut() { 2698 // Do not test. Implementation details. 2699 } 2700 2701 @UiThreadTest testPerformLongClick()2702 public void testPerformLongClick() { 2703 mTextView = findTextView(R.id.textview_text); 2704 mTextView.setText("This is content"); 2705 MockOnLongClickListener onLongClickListener = new MockOnLongClickListener(true); 2706 MockOnCreateContextMenuListener onCreateContextMenuListener 2707 = new MockOnCreateContextMenuListener(false); 2708 mTextView.setOnLongClickListener(onLongClickListener); 2709 mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener); 2710 assertTrue(mTextView.performLongClick()); 2711 assertTrue(onLongClickListener.hasLongClicked()); 2712 assertFalse(onCreateContextMenuListener.hasCreatedContextMenu()); 2713 2714 onLongClickListener = new MockOnLongClickListener(false); 2715 mTextView.setOnLongClickListener(onLongClickListener); 2716 mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener); 2717 assertTrue(mTextView.performLongClick()); 2718 assertTrue(onLongClickListener.hasLongClicked()); 2719 assertTrue(onCreateContextMenuListener.hasCreatedContextMenu()); 2720 2721 mTextView.setOnLongClickListener(null); 2722 onCreateContextMenuListener = new MockOnCreateContextMenuListener(true); 2723 mTextView.setOnCreateContextMenuListener(onCreateContextMenuListener); 2724 assertFalse(mTextView.performLongClick()); 2725 assertTrue(onCreateContextMenuListener.hasCreatedContextMenu()); 2726 } 2727 2728 @UiThreadTest testTextAttr()2729 public void testTextAttr() { 2730 mTextView = findTextView(R.id.textview_textAttr); 2731 // getText 2732 assertEquals(mActivity.getString(R.string.text_view_hello), mTextView.getText().toString()); 2733 2734 // getCurrentTextColor 2735 assertEquals(mActivity.getResources().getColor(R.drawable.black), 2736 mTextView.getCurrentTextColor()); 2737 assertEquals(mActivity.getResources().getColor(R.drawable.red), 2738 mTextView.getCurrentHintTextColor()); 2739 assertEquals(mActivity.getResources().getColor(R.drawable.red), 2740 mTextView.getHintTextColors().getDefaultColor()); 2741 assertEquals(mActivity.getResources().getColor(R.drawable.blue), 2742 mTextView.getLinkTextColors().getDefaultColor()); 2743 2744 // getTextScaleX 2745 assertEquals(1.2f, mTextView.getTextScaleX(), 0.01f); 2746 2747 // setTextScaleX 2748 mTextView.setTextScaleX(2.4f); 2749 assertEquals(2.4f, mTextView.getTextScaleX(), 0.01f); 2750 2751 mTextView.setTextScaleX(0f); 2752 assertEquals(0f, mTextView.getTextScaleX(), 0.01f); 2753 2754 mTextView.setTextScaleX(- 2.4f); 2755 assertEquals(- 2.4f, mTextView.getTextScaleX(), 0.01f); 2756 2757 // getTextSize 2758 assertEquals(20f, mTextView.getTextSize(), 0.01f); 2759 2760 // getTypeface 2761 // getTypeface will be null if android:typeface is set to normal, 2762 // and android:style is not set or is set to normal, and 2763 // android:fontFamily is not set 2764 assertNull(mTextView.getTypeface()); 2765 2766 mTextView.setTypeface(Typeface.DEFAULT); 2767 assertSame(Typeface.DEFAULT, mTextView.getTypeface()); 2768 // null type face 2769 mTextView.setTypeface(null); 2770 assertNull(mTextView.getTypeface()); 2771 2772 // default type face, bold style, note: the type face will be changed 2773 // after call set method 2774 mTextView.setTypeface(Typeface.DEFAULT, Typeface.BOLD); 2775 assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle()); 2776 2777 // null type face, BOLD style 2778 mTextView.setTypeface(null, Typeface.BOLD); 2779 assertSame(Typeface.BOLD, mTextView.getTypeface().getStyle()); 2780 2781 // old type face, null style 2782 mTextView.setTypeface(Typeface.DEFAULT, 0); 2783 assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle()); 2784 } 2785 2786 @UiThreadTest testAppend()2787 public void testAppend() { 2788 mTextView = new TextView(mActivity); 2789 2790 // 1: check the original length, should be blank as initialised. 2791 assertEquals(0, mTextView.getText().length()); 2792 2793 // 2: append a string use append(CharSquence) into the original blank 2794 // buffer, check the content. And upgrading it to BufferType.EDITABLE if it was 2795 // not already editable. 2796 assertFalse(mTextView.getText() instanceof Editable); 2797 mTextView.append("Append."); 2798 assertEquals("Append.", mTextView.getText().toString()); 2799 assertTrue(mTextView.getText() instanceof Editable); 2800 2801 // 3: append a string from 0~3. 2802 mTextView.append("Append", 0, 3); 2803 assertEquals("Append.App", mTextView.getText().toString()); 2804 assertTrue(mTextView.getText() instanceof Editable); 2805 2806 // 4: append a string from 0~0, nothing will be append as expected. 2807 mTextView.append("Append", 0, 0); 2808 assertEquals("Append.App", mTextView.getText().toString()); 2809 assertTrue(mTextView.getText() instanceof Editable); 2810 2811 // 5: append a string from -3~3. check the wrong left edge. 2812 try { 2813 mTextView.append("Append", -3, 3); 2814 fail("Should throw StringIndexOutOfBoundsException"); 2815 } catch (StringIndexOutOfBoundsException e) { 2816 } 2817 2818 // 6: append a string from 3~10. check the wrong right edge. 2819 try { 2820 mTextView.append("Append", 3, 10); 2821 fail("Should throw StringIndexOutOfBoundsException"); 2822 } catch (StringIndexOutOfBoundsException e) { 2823 } 2824 2825 // 7: append a null string. 2826 try { 2827 mTextView.append(null); 2828 fail("Should throw NullPointerException"); 2829 } catch (NullPointerException e) { 2830 } 2831 } 2832 2833 @UiThreadTest testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks()2834 public void testAppend_doesNotAddLinksWhenAppendedTextDoesNotContainLinks() { 2835 mTextView = new TextView(mActivity); 2836 mTextView.setAutoLinkMask(Linkify.ALL); 2837 mTextView.setText("text without URL"); 2838 2839 mTextView.append(" another text without URL"); 2840 2841 Spannable text = (Spannable) mTextView.getText(); 2842 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2843 assertEquals("URLSpan count should be zero", 0, urlSpans.length); 2844 assertEquals("text without URL another text without URL", text.toString()); 2845 } 2846 2847 @UiThreadTest testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled()2848 public void testAppend_doesNotAddLinksWhenAutoLinkIsNotEnabled() { 2849 mTextView = new TextView(mActivity); 2850 mTextView.setText("text without URL"); 2851 2852 mTextView.append(" text with URL http://android.com"); 2853 2854 Spannable text = (Spannable) mTextView.getText(); 2855 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2856 assertEquals("URLSpan count should be zero", 0, urlSpans.length); 2857 assertEquals("text without URL text with URL http://android.com", text.toString()); 2858 } 2859 2860 @UiThreadTest testAppend_addsLinksWhenAutoLinkIsEnabled()2861 public void testAppend_addsLinksWhenAutoLinkIsEnabled() { 2862 mTextView = new TextView(mActivity); 2863 mTextView.setAutoLinkMask(Linkify.ALL); 2864 mTextView.setText("text without URL"); 2865 2866 mTextView.append(" text with URL http://android.com"); 2867 2868 Spannable text = (Spannable) mTextView.getText(); 2869 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2870 assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length); 2871 assertEquals("URLSpan URL should be same as the appended URL", 2872 urlSpans[0].getURL(), "http://android.com"); 2873 assertEquals("text without URL text with URL http://android.com", text.toString()); 2874 } 2875 2876 @UiThreadTest testAppend_addsLinksEvenWhenThereAreUrlsSetBefore()2877 public void testAppend_addsLinksEvenWhenThereAreUrlsSetBefore() { 2878 mTextView = new TextView(mActivity); 2879 mTextView.setAutoLinkMask(Linkify.ALL); 2880 mTextView.setText("text with URL http://android.com/before"); 2881 2882 mTextView.append(" text with URL http://android.com"); 2883 2884 Spannable text = (Spannable) mTextView.getText(); 2885 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2886 assertEquals("URLSpan count should be two after appending another URL", 2, urlSpans.length); 2887 assertEquals("First URLSpan URL should be same", 2888 urlSpans[0].getURL(), "http://android.com/before"); 2889 assertEquals("URLSpan URL should be same as the appended URL", 2890 urlSpans[1].getURL(), "http://android.com"); 2891 assertEquals("text with URL http://android.com/before text with URL http://android.com", 2892 text.toString()); 2893 } 2894 2895 @UiThreadTest testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled()2896 public void testAppend_setsMovementMethodWhenTextContainsUrlAndAutoLinkIsEnabled() { 2897 mTextView = new TextView(mActivity); 2898 mTextView.setAutoLinkMask(Linkify.ALL); 2899 mTextView.setText("text without a URL"); 2900 2901 mTextView.append(" text with a url: http://android.com"); 2902 2903 assertNotNull("MovementMethod should not be null when text contains url", 2904 mTextView.getMovementMethod()); 2905 assertTrue("MovementMethod should be instance of LinkMovementMethod when text contains url", 2906 mTextView.getMovementMethod() instanceof LinkMovementMethod); 2907 } 2908 2909 @UiThreadTest testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled()2910 public void testAppend_addsLinksWhenTextIsSpannableAndContainsUrlAndAutoLinkIsEnabled() { 2911 mTextView = new TextView(mActivity); 2912 mTextView.setAutoLinkMask(Linkify.ALL); 2913 mTextView.setText("text without a URL"); 2914 2915 mTextView.append(new SpannableString(" text with a url: http://android.com")); 2916 2917 Spannable text = (Spannable) mTextView.getText(); 2918 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2919 assertEquals("URLSpan count should be one after appending a URL", 1, urlSpans.length); 2920 assertEquals("URLSpan URL should be same as the appended URL", 2921 urlSpans[0].getURL(), "http://android.com"); 2922 } 2923 2924 @UiThreadTest testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText()2925 public void testAppend_addsLinkIfAppendedTextCompletesPartialUrlAtTheEndOfExistingText() { 2926 mTextView = new TextView(mActivity); 2927 mTextView.setAutoLinkMask(Linkify.ALL); 2928 mTextView.setText("text with a partial url android."); 2929 2930 mTextView.append("com"); 2931 2932 Spannable text = (Spannable) mTextView.getText(); 2933 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2934 assertEquals("URLSpan count should be one after appending to partial URL", 2935 1, urlSpans.length); 2936 assertEquals("URLSpan URL should be same as the appended URL", 2937 urlSpans[0].getURL(), "http://android.com"); 2938 } 2939 2940 @UiThreadTest testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText()2941 public void testAppend_addsLinkIfAppendedTextUpdatesUrlAtTheEndOfExistingText() { 2942 mTextView = new TextView(mActivity); 2943 mTextView.setAutoLinkMask(Linkify.ALL); 2944 mTextView.setText("text with a url http://android.com"); 2945 2946 mTextView.append("/textview"); 2947 2948 Spannable text = (Spannable) mTextView.getText(); 2949 URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class); 2950 assertEquals("URLSpan count should still be one after extending a URL", 1, urlSpans.length); 2951 assertEquals("URLSpan URL should be same as the new URL", 2952 urlSpans[0].getURL(), "http://android.com/textview"); 2953 } 2954 2955 testAccessTransformationMethod()2956 public void testAccessTransformationMethod() { 2957 // check the password attribute in xml 2958 mTextView = findTextView(R.id.textview_password); 2959 assertNotNull(mTextView); 2960 assertSame(PasswordTransformationMethod.getInstance(), 2961 mTextView.getTransformationMethod()); 2962 2963 // check the singleLine attribute in xml 2964 mTextView = findTextView(R.id.textview_singleLine); 2965 assertNotNull(mTextView); 2966 assertSame(SingleLineTransformationMethod.getInstance(), 2967 mTextView.getTransformationMethod()); 2968 2969 final QwertyKeyListener qwertyKeyListener = QwertyKeyListener.getInstance(false, 2970 Capitalize.NONE); 2971 final TransformationMethod method = PasswordTransformationMethod.getInstance(); 2972 // change transformation method by function 2973 mActivity.runOnUiThread(new Runnable() { 2974 public void run() { 2975 mTextView.setKeyListener(qwertyKeyListener); 2976 mTextView.setTransformationMethod(method); 2977 mTransformedText = method.getTransformation(mTextView.getText(), mTextView); 2978 2979 mTextView.requestFocus(); 2980 } 2981 }); 2982 mInstrumentation.waitForIdleSync(); 2983 assertSame(PasswordTransformationMethod.getInstance(), 2984 mTextView.getTransformationMethod()); 2985 2986 sendKeys("H E 2*L O"); 2987 mActivity.runOnUiThread(new Runnable() { 2988 public void run() { 2989 mTextView.append(" "); 2990 } 2991 }); 2992 mInstrumentation.waitForIdleSync(); 2993 2994 // it will get transformed after a while 2995 new PollingCheck(TIMEOUT) { 2996 @Override 2997 protected boolean check() { 2998 // "******" 2999 return mTransformedText.toString() 3000 .equals("\u2022\u2022\u2022\u2022\u2022\u2022"); 3001 } 3002 }.run(); 3003 3004 // set null 3005 mActivity.runOnUiThread(new Runnable() { 3006 public void run() { 3007 mTextView.setTransformationMethod(null); 3008 } 3009 }); 3010 mInstrumentation.waitForIdleSync(); 3011 assertNull(mTextView.getTransformationMethod()); 3012 } 3013 3014 @UiThreadTest testCompound()3015 public void testCompound() { 3016 mTextView = new TextView(mActivity); 3017 int padding = 3; 3018 Drawable[] drawables = mTextView.getCompoundDrawables(); 3019 assertNull(drawables[0]); 3020 assertNull(drawables[1]); 3021 assertNull(drawables[2]); 3022 assertNull(drawables[3]); 3023 3024 // test setCompoundDrawablePadding and getCompoundDrawablePadding 3025 mTextView.setCompoundDrawablePadding(padding); 3026 assertEquals(padding, mTextView.getCompoundDrawablePadding()); 3027 3028 // using resid, 0 represents null 3029 mTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.start, R.drawable.pass, 3030 R.drawable.failed, 0); 3031 drawables = mTextView.getCompoundDrawables(); 3032 3033 // drawableLeft 3034 WidgetTestUtils.assertEquals(getBitmap(R.drawable.start), 3035 ((BitmapDrawable) drawables[0]).getBitmap()); 3036 // drawableTop 3037 WidgetTestUtils.assertEquals(getBitmap(R.drawable.pass), 3038 ((BitmapDrawable) drawables[1]).getBitmap()); 3039 // drawableRight 3040 WidgetTestUtils.assertEquals(getBitmap(R.drawable.failed), 3041 ((BitmapDrawable) drawables[2]).getBitmap()); 3042 // drawableBottom 3043 assertNull(drawables[3]); 3044 3045 Drawable left = getDrawable(R.drawable.blue); 3046 Drawable right = getDrawable(R.drawable.yellow); 3047 Drawable top = getDrawable(R.drawable.red); 3048 3049 // using drawables directly 3050 mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, null); 3051 drawables = mTextView.getCompoundDrawables(); 3052 3053 // drawableLeft 3054 assertSame(left, drawables[0]); 3055 // drawableTop 3056 assertSame(top, drawables[1]); 3057 // drawableRight 3058 assertSame(right, drawables[2]); 3059 // drawableBottom 3060 assertNull(drawables[3]); 3061 3062 // check compound padding 3063 assertEquals(mTextView.getPaddingLeft() + padding + left.getIntrinsicWidth(), 3064 mTextView.getCompoundPaddingLeft()); 3065 assertEquals(mTextView.getPaddingTop() + padding + top.getIntrinsicHeight(), 3066 mTextView.getCompoundPaddingTop()); 3067 assertEquals(mTextView.getPaddingRight() + padding + right.getIntrinsicWidth(), 3068 mTextView.getCompoundPaddingRight()); 3069 assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom()); 3070 3071 // set bounds to drawables and set them again. 3072 left.setBounds(0, 0, 1, 2); 3073 right.setBounds(0, 0, 3, 4); 3074 top.setBounds(0, 0, 5, 6); 3075 // usinf drawables 3076 mTextView.setCompoundDrawables(left, top, right, null); 3077 drawables = mTextView.getCompoundDrawables(); 3078 3079 // drawableLeft 3080 assertSame(left, drawables[0]); 3081 // drawableTop 3082 assertSame(top, drawables[1]); 3083 // drawableRight 3084 assertSame(right, drawables[2]); 3085 // drawableBottom 3086 assertNull(drawables[3]); 3087 3088 // check compound padding 3089 assertEquals(mTextView.getPaddingLeft() + padding + left.getBounds().width(), 3090 mTextView.getCompoundPaddingLeft()); 3091 assertEquals(mTextView.getPaddingTop() + padding + top.getBounds().height(), 3092 mTextView.getCompoundPaddingTop()); 3093 assertEquals(mTextView.getPaddingRight() + padding + right.getBounds().width(), 3094 mTextView.getCompoundPaddingRight()); 3095 assertEquals(mTextView.getPaddingBottom(), mTextView.getCompoundPaddingBottom()); 3096 } 3097 testSingleLine()3098 public void testSingleLine() { 3099 final TextView textView = new TextView(mActivity); 3100 setSpannableText(textView, "This is a really long sentence" 3101 + " which can not be placed in one line on the screen."); 3102 3103 // Narrow layout assures that the text will get wrapped. 3104 FrameLayout innerLayout = new FrameLayout(mActivity); 3105 innerLayout.setLayoutParams(new ViewGroup.LayoutParams(100, 100)); 3106 innerLayout.addView(textView); 3107 3108 final FrameLayout layout = new FrameLayout(mActivity); 3109 layout.addView(innerLayout); 3110 3111 mActivity.runOnUiThread(new Runnable() { 3112 public void run() { 3113 mActivity.setContentView(layout); 3114 textView.setSingleLine(true); 3115 } 3116 }); 3117 mInstrumentation.waitForIdleSync(); 3118 3119 assertEquals(SingleLineTransformationMethod.getInstance(), 3120 textView.getTransformationMethod()); 3121 3122 int singleLineWidth = 0; 3123 int singleLineHeight = 0; 3124 3125 if (textView.getLayout() != null) { 3126 singleLineWidth = textView.getLayout().getWidth(); 3127 singleLineHeight = textView.getLayout().getHeight(); 3128 } 3129 3130 mActivity.runOnUiThread(new Runnable() { 3131 public void run() { 3132 textView.setSingleLine(false); 3133 } 3134 }); 3135 mInstrumentation.waitForIdleSync(); 3136 assertEquals(null, textView.getTransformationMethod()); 3137 3138 if (textView.getLayout() != null) { 3139 assertTrue(textView.getLayout().getHeight() > singleLineHeight); 3140 assertTrue(textView.getLayout().getWidth() < singleLineWidth); 3141 } 3142 3143 // same behaviours as setSingLine(true) 3144 mActivity.runOnUiThread(new Runnable() { 3145 public void run() { 3146 textView.setSingleLine(); 3147 } 3148 }); 3149 mInstrumentation.waitForIdleSync(); 3150 assertEquals(SingleLineTransformationMethod.getInstance(), 3151 textView.getTransformationMethod()); 3152 3153 if (textView.getLayout() != null) { 3154 assertEquals(singleLineHeight, textView.getLayout().getHeight()); 3155 assertEquals(singleLineWidth, textView.getLayout().getWidth()); 3156 } 3157 } 3158 3159 @UiThreadTest 3160 public void testSetMaxLines() { 3161 mTextView = findTextView(R.id.textview_text); 3162 3163 float[] widths = new float[LONG_TEXT.length()]; 3164 mTextView.getPaint().getTextWidths(LONG_TEXT, widths); 3165 float totalWidth = 0.0f; 3166 for (float f : widths) { 3167 totalWidth += f; 3168 } 3169 final int stringWidth = (int) totalWidth; 3170 mTextView.setWidth(stringWidth >> 2); 3171 mTextView.setText(LONG_TEXT); 3172 3173 final int maxLines = 2; 3174 assertTrue(mTextView.getLineCount() > maxLines); 3175 3176 mTextView.setMaxLines(maxLines); 3177 mTextView.requestLayout(); 3178 3179 assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight()); 3180 } 3181 calculateTextWidth(String text)3182 public int calculateTextWidth(String text) { 3183 mTextView = findTextView(R.id.textview_text); 3184 3185 // Set the TextView width as the half of the whole text. 3186 float[] widths = new float[text.length()]; 3187 mTextView.getPaint().getTextWidths(text, widths); 3188 float textfieldWidth = 0.0f; 3189 for (int i = 0; i < text.length(); ++i) { 3190 textfieldWidth += widths[i]; 3191 } 3192 return (int)textfieldWidth; 3193 3194 } 3195 3196 @UiThreadTest testHyphenationNotHappen_frequencyNone()3197 public void testHyphenationNotHappen_frequencyNone() { 3198 final int[] BREAK_STRATEGIES = { 3199 Layout.BREAK_STRATEGY_SIMPLE, Layout.BREAK_STRATEGY_HIGH_QUALITY, 3200 Layout.BREAK_STRATEGY_BALANCED }; 3201 3202 mTextView = findTextView(R.id.textview_text); 3203 3204 for (int breakStrategy : BREAK_STRATEGIES) { 3205 for (int charWidth = 10; charWidth < 120; charWidth += 5) { 3206 // Change the text view's width to charWidth width. 3207 mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth))); 3208 3209 mTextView.setText(LONG_TEXT); 3210 mTextView.setBreakStrategy(breakStrategy); 3211 3212 mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE); 3213 3214 mTextView.requestLayout(); 3215 mTextView.onPreDraw(); // For freezing the layout. 3216 Layout layout = mTextView.getLayout(); 3217 3218 final int lineCount = layout.getLineCount(); 3219 for (int line = 0; line < lineCount; ++line) { 3220 final int lineEnd = layout.getLineEnd(line); 3221 // In any width, any break strategy, hyphenation should not happen if 3222 // HYPHENATION_FREQUENCY_NONE is specified. 3223 assertTrue(lineEnd == LONG_TEXT.length() || 3224 Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1))); 3225 } 3226 } 3227 } 3228 } 3229 3230 @UiThreadTest testHyphenationNotHappen_breakStrategySimple()3231 public void testHyphenationNotHappen_breakStrategySimple() { 3232 final int[] HYPHENATION_FREQUENCIES = { 3233 Layout.HYPHENATION_FREQUENCY_NORMAL, Layout.HYPHENATION_FREQUENCY_FULL, 3234 Layout.HYPHENATION_FREQUENCY_NONE }; 3235 3236 mTextView = findTextView(R.id.textview_text); 3237 3238 for (int hyphenationFrequency: HYPHENATION_FREQUENCIES) { 3239 for (int charWidth = 10; charWidth < 120; charWidth += 5) { 3240 // Change the text view's width to charWidth width. 3241 mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth))); 3242 3243 mTextView.setText(LONG_TEXT); 3244 mTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE); 3245 3246 mTextView.setHyphenationFrequency(hyphenationFrequency); 3247 3248 mTextView.requestLayout(); 3249 mTextView.onPreDraw(); // For freezing the layout. 3250 Layout layout = mTextView.getLayout(); 3251 3252 final int lineCount = layout.getLineCount(); 3253 for (int line = 0; line < lineCount; ++line) { 3254 final int lineEnd = layout.getLineEnd(line); 3255 // In any width, any hyphenation frequency, hyphenation should not happen if 3256 // BREAK_STRATEGY_SIMPLE is specified. 3257 assertTrue(lineEnd == LONG_TEXT.length() || 3258 Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1))); 3259 } 3260 } 3261 } 3262 } 3263 3264 @UiThreadTest testSetMaxLinesException()3265 public void testSetMaxLinesException() { 3266 mTextView = new TextView(mActivity); 3267 mActivity.setContentView(mTextView); 3268 mTextView.setWidth(mTextView.getWidth() >> 3); 3269 mTextView.setMaxLines(-1); 3270 } 3271 testSetMinLines()3272 public void testSetMinLines() { 3273 mTextView = findTextView(R.id.textview_text); 3274 setWidth(mTextView.getWidth() >> 3); 3275 int originalHeight = mTextView.getHeight(); 3276 int originalLines = mTextView.getLineCount(); 3277 3278 setMinLines(originalLines - 1); 3279 assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight()); 3280 3281 setMinLines(originalLines + 1); 3282 assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight()); 3283 } 3284 testSetLines()3285 public void testSetLines() { 3286 mTextView = findTextView(R.id.textview_text); 3287 // make it multiple lines 3288 setWidth(mTextView.getWidth() >> 3); 3289 int originalLines = mTextView.getLineCount(); 3290 3291 setLines(originalLines - 1); 3292 assertTrue((originalLines - 1) * mTextView.getLineHeight() <= mTextView.getHeight()); 3293 3294 setLines(originalLines + 1); 3295 assertTrue((originalLines + 1) * mTextView.getLineHeight() <= mTextView.getHeight()); 3296 } 3297 3298 @UiThreadTest testSetLinesException()3299 public void testSetLinesException() { 3300 mTextView = new TextView(mActivity); 3301 mActivity.setContentView(mTextView); 3302 mTextView.setWidth(mTextView.getWidth() >> 3); 3303 mTextView.setLines(-1); 3304 } 3305 3306 @UiThreadTest testGetExtendedPaddingTop()3307 public void testGetExtendedPaddingTop() { 3308 mTextView = findTextView(R.id.textview_text); 3309 // Initialized value 3310 assertEquals(0, mTextView.getExtendedPaddingTop()); 3311 3312 // After Set a Drawable 3313 final Drawable top = getDrawable(R.drawable.red); 3314 top.setBounds(0, 0, 100, 10); 3315 mTextView.setCompoundDrawables(null, top, null, null); 3316 assertEquals(mTextView.getCompoundPaddingTop(), mTextView.getExtendedPaddingTop()); 3317 3318 // Change line count 3319 mTextView.setLines(mTextView.getLineCount() - 1); 3320 mTextView.setGravity(Gravity.BOTTOM); 3321 3322 assertTrue(mTextView.getExtendedPaddingTop() > 0); 3323 } 3324 3325 @UiThreadTest testGetExtendedPaddingBottom()3326 public void testGetExtendedPaddingBottom() { 3327 mTextView = findTextView(R.id.textview_text); 3328 // Initialized value 3329 assertEquals(0, mTextView.getExtendedPaddingBottom()); 3330 3331 // After Set a Drawable 3332 final Drawable bottom = getDrawable(R.drawable.red); 3333 bottom.setBounds(0, 0, 100, 10); 3334 mTextView.setCompoundDrawables(null, null, null, bottom); 3335 assertEquals(mTextView.getCompoundPaddingBottom(), mTextView.getExtendedPaddingBottom()); 3336 3337 // Change line count 3338 mTextView.setLines(mTextView.getLineCount() - 1); 3339 mTextView.setGravity(Gravity.CENTER_VERTICAL); 3340 3341 assertTrue(mTextView.getExtendedPaddingBottom() > 0); 3342 } 3343 testGetTotalPaddingTop()3344 public void testGetTotalPaddingTop() { 3345 mTextView = findTextView(R.id.textview_text); 3346 // Initialized value 3347 assertEquals(0, mTextView.getTotalPaddingTop()); 3348 3349 // After Set a Drawable 3350 final Drawable top = getDrawable(R.drawable.red); 3351 top.setBounds(0, 0, 100, 10); 3352 mActivity.runOnUiThread(new Runnable() { 3353 public void run() { 3354 mTextView.setCompoundDrawables(null, top, null, null); 3355 mTextView.setLines(mTextView.getLineCount() - 1); 3356 mTextView.setGravity(Gravity.BOTTOM); 3357 } 3358 }); 3359 mInstrumentation.waitForIdleSync(); 3360 assertEquals(mTextView.getExtendedPaddingTop(), mTextView.getTotalPaddingTop()); 3361 3362 // Change line count 3363 setLines(mTextView.getLineCount() + 1); 3364 int expected = mTextView.getHeight() 3365 - mTextView.getExtendedPaddingBottom() 3366 - mTextView.getLayout().getLineTop(mTextView.getLineCount()); 3367 assertEquals(expected, mTextView.getTotalPaddingTop()); 3368 } 3369 testGetTotalPaddingBottom()3370 public void testGetTotalPaddingBottom() { 3371 mTextView = findTextView(R.id.textview_text); 3372 // Initialized value 3373 assertEquals(0, mTextView.getTotalPaddingBottom()); 3374 3375 // After Set a Drawable 3376 final Drawable bottom = getDrawable(R.drawable.red); 3377 bottom.setBounds(0, 0, 100, 10); 3378 mActivity.runOnUiThread(new Runnable() { 3379 public void run() { 3380 mTextView.setCompoundDrawables(null, null, null, bottom); 3381 mTextView.setLines(mTextView.getLineCount() - 1); 3382 mTextView.setGravity(Gravity.CENTER_VERTICAL); 3383 } 3384 }); 3385 mInstrumentation.waitForIdleSync(); 3386 assertEquals(mTextView.getExtendedPaddingBottom(), mTextView.getTotalPaddingBottom()); 3387 3388 // Change line count 3389 setLines(mTextView.getLineCount() + 1); 3390 int expected = ((mTextView.getHeight() 3391 - mTextView.getExtendedPaddingBottom() 3392 - mTextView.getExtendedPaddingTop() 3393 - mTextView.getLayout().getLineBottom(mTextView.getLineCount())) >> 1) 3394 + mTextView.getExtendedPaddingBottom(); 3395 assertEquals(expected, mTextView.getTotalPaddingBottom()); 3396 } 3397 3398 @UiThreadTest testGetTotalPaddingLeft()3399 public void testGetTotalPaddingLeft() { 3400 mTextView = findTextView(R.id.textview_text); 3401 // Initialized value 3402 assertEquals(0, mTextView.getTotalPaddingLeft()); 3403 3404 // After Set a Drawable 3405 Drawable left = getDrawable(R.drawable.red); 3406 left.setBounds(0, 0, 10, 100); 3407 mTextView.setCompoundDrawables(left, null, null, null); 3408 mTextView.setGravity(Gravity.RIGHT); 3409 assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft()); 3410 3411 // Change width 3412 mTextView.setWidth(Integer.MAX_VALUE); 3413 assertEquals(mTextView.getCompoundPaddingLeft(), mTextView.getTotalPaddingLeft()); 3414 } 3415 3416 @UiThreadTest testGetTotalPaddingRight()3417 public void testGetTotalPaddingRight() { 3418 mTextView = findTextView(R.id.textview_text); 3419 // Initialized value 3420 assertEquals(0, mTextView.getTotalPaddingRight()); 3421 3422 // After Set a Drawable 3423 Drawable right = getDrawable(R.drawable.red); 3424 right.setBounds(0, 0, 10, 100); 3425 mTextView.setCompoundDrawables(null, null, right, null); 3426 mTextView.setGravity(Gravity.CENTER_HORIZONTAL); 3427 assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight()); 3428 3429 // Change width 3430 mTextView.setWidth(Integer.MAX_VALUE); 3431 assertEquals(mTextView.getCompoundPaddingRight(), mTextView.getTotalPaddingRight()); 3432 } 3433 testGetUrls()3434 public void testGetUrls() { 3435 mTextView = new TextView(mActivity); 3436 3437 URLSpan[] spans = mTextView.getUrls(); 3438 assertEquals(0, spans.length); 3439 3440 String url = "http://www.google.com"; 3441 String email = "name@gmail.com"; 3442 String string = url + " mailto:" + email; 3443 SpannableString spannable = new SpannableString(string); 3444 spannable.setSpan(new URLSpan(url), 0, url.length(), 0); 3445 mTextView.setText(spannable, BufferType.SPANNABLE); 3446 spans = mTextView.getUrls(); 3447 assertEquals(1, spans.length); 3448 assertEquals(url, spans[0].getURL()); 3449 3450 spannable.setSpan(new URLSpan(email), 0, email.length(), 0); 3451 mTextView.setText(spannable, BufferType.SPANNABLE); 3452 3453 spans = mTextView.getUrls(); 3454 assertEquals(2, spans.length); 3455 assertEquals(url, spans[0].getURL()); 3456 assertEquals(email, spans[1].getURL()); 3457 3458 // test the situation that param what is not a URLSpan 3459 spannable.setSpan(new Object(), 0, 9, 0); 3460 mTextView.setText(spannable, BufferType.SPANNABLE); 3461 spans = mTextView.getUrls(); 3462 assertEquals(2, spans.length); 3463 } 3464 testSetPadding()3465 public void testSetPadding() { 3466 mTextView = new TextView(mActivity); 3467 3468 mTextView.setPadding(0, 1, 2, 4); 3469 assertEquals(0, mTextView.getPaddingLeft()); 3470 assertEquals(1, mTextView.getPaddingTop()); 3471 assertEquals(2, mTextView.getPaddingRight()); 3472 assertEquals(4, mTextView.getPaddingBottom()); 3473 3474 mTextView.setPadding(10, 20, 30, 40); 3475 assertEquals(10, mTextView.getPaddingLeft()); 3476 assertEquals(20, mTextView.getPaddingTop()); 3477 assertEquals(30, mTextView.getPaddingRight()); 3478 assertEquals(40, mTextView.getPaddingBottom()); 3479 } 3480 testDeprecatedSetTextAppearance()3481 public void testDeprecatedSetTextAppearance() { 3482 mTextView = new TextView(mActivity); 3483 3484 mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All); 3485 assertEquals(mActivity.getResources().getColor(R.drawable.black), 3486 mTextView.getCurrentTextColor()); 3487 assertEquals(20f, mTextView.getTextSize(), 0.01f); 3488 assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle()); 3489 assertEquals(mActivity.getResources().getColor(R.drawable.red), 3490 mTextView.getCurrentHintTextColor()); 3491 assertEquals(mActivity.getResources().getColor(R.drawable.blue), 3492 mTextView.getLinkTextColors().getDefaultColor()); 3493 3494 mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Colors); 3495 assertEquals(mActivity.getResources().getColor(R.drawable.black), 3496 mTextView.getCurrentTextColor()); 3497 assertEquals(mActivity.getResources().getColor(R.drawable.blue), 3498 mTextView.getCurrentHintTextColor()); 3499 assertEquals(mActivity.getResources().getColor(R.drawable.yellow), 3500 mTextView.getLinkTextColors().getDefaultColor()); 3501 3502 mTextView.setTextAppearance(mActivity, R.style.TextAppearance_NotColors); 3503 assertEquals(17f, mTextView.getTextSize(), 0.01f); 3504 assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle()); 3505 3506 mTextView.setTextAppearance(mActivity, R.style.TextAppearance_Style); 3507 assertEquals(null, mTextView.getTypeface()); 3508 } 3509 testSetTextAppearance()3510 public void testSetTextAppearance() { 3511 mTextView = new TextView(mActivity); 3512 3513 mTextView.setTextAppearance(R.style.TextAppearance_All); 3514 assertEquals(mActivity.getResources().getColor(R.drawable.black), 3515 mTextView.getCurrentTextColor()); 3516 assertEquals(20f, mTextView.getTextSize(), 0.01f); 3517 assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle()); 3518 assertEquals(mActivity.getResources().getColor(R.drawable.red), 3519 mTextView.getCurrentHintTextColor()); 3520 assertEquals(mActivity.getResources().getColor(R.drawable.blue), 3521 mTextView.getLinkTextColors().getDefaultColor()); 3522 3523 mTextView.setTextAppearance(R.style.TextAppearance_Colors); 3524 assertEquals(mActivity.getResources().getColor(R.drawable.black), 3525 mTextView.getCurrentTextColor()); 3526 assertEquals(mActivity.getResources().getColor(R.drawable.blue), 3527 mTextView.getCurrentHintTextColor()); 3528 assertEquals(mActivity.getResources().getColor(R.drawable.yellow), 3529 mTextView.getLinkTextColors().getDefaultColor()); 3530 3531 mTextView.setTextAppearance(R.style.TextAppearance_NotColors); 3532 assertEquals(17f, mTextView.getTextSize(), 0.01f); 3533 assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle()); 3534 3535 mTextView.setTextAppearance(R.style.TextAppearance_Style); 3536 assertEquals(null, mTextView.getTypeface()); 3537 } 3538 testOnPreDraw()3539 public void testOnPreDraw() { 3540 // Do not test. Implementation details. 3541 } 3542 testAccessCompoundDrawableTint()3543 public void testAccessCompoundDrawableTint() { 3544 mTextView = new TextView(mActivity); 3545 3546 ColorStateList colors = ColorStateList.valueOf(Color.RED); 3547 mTextView.setCompoundDrawableTintList(colors); 3548 mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR); 3549 assertSame(colors, mTextView.getCompoundDrawableTintList()); 3550 assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode()); 3551 3552 // Ensure the tint is preserved across drawable changes. 3553 mTextView.setCompoundDrawablesRelative(null, null, null, null); 3554 assertSame(colors, mTextView.getCompoundDrawableTintList()); 3555 assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode()); 3556 3557 mTextView.setCompoundDrawables(null, null, null, null); 3558 assertSame(colors, mTextView.getCompoundDrawableTintList()); 3559 assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode()); 3560 3561 ColorDrawable dr1 = new ColorDrawable(Color.RED); 3562 ColorDrawable dr2 = new ColorDrawable(Color.GREEN); 3563 ColorDrawable dr3 = new ColorDrawable(Color.BLUE); 3564 ColorDrawable dr4 = new ColorDrawable(Color.YELLOW); 3565 mTextView.setCompoundDrawables(dr1, dr2, dr3, dr4); 3566 assertSame(colors, mTextView.getCompoundDrawableTintList()); 3567 assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode()); 3568 } 3569 testSetHorizontallyScrolling()3570 public void testSetHorizontallyScrolling() { 3571 // make the text view has more than one line 3572 mTextView = findTextView(R.id.textview_text); 3573 setWidth(mTextView.getWidth() >> 1); 3574 assertTrue(mTextView.getLineCount() > 1); 3575 3576 setHorizontallyScrolling(true); 3577 assertEquals(1, mTextView.getLineCount()); 3578 3579 setHorizontallyScrolling(false); 3580 assertTrue(mTextView.getLineCount() > 1); 3581 } 3582 testComputeHorizontalScrollRange()3583 public void testComputeHorizontalScrollRange() { 3584 MockTextView textView = new MockTextView(mActivity); 3585 // test when layout is null 3586 assertNull(textView.getLayout()); 3587 assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange()); 3588 3589 textView.setFrame(0, 0, 40, 50); 3590 assertEquals(textView.getWidth(), textView.computeHorizontalScrollRange()); 3591 3592 // set the layout 3593 layout(textView); 3594 assertEquals(textView.getLayout().getWidth(), textView.computeHorizontalScrollRange()); 3595 } 3596 testComputeVerticalScrollRange()3597 public void testComputeVerticalScrollRange() { 3598 MockTextView textView = new MockTextView(mActivity); 3599 // test when layout is null 3600 assertNull(textView.getLayout()); 3601 assertEquals(0, textView.computeVerticalScrollRange()); 3602 3603 textView.setFrame(0, 0, 40, 50); 3604 assertEquals(textView.getHeight(), textView.computeVerticalScrollRange()); 3605 3606 //set the layout 3607 layout(textView); 3608 assertEquals(textView.getLayout().getHeight(), textView.computeVerticalScrollRange()); 3609 } 3610 testDrawableStateChanged()3611 public void testDrawableStateChanged() { 3612 MockTextView textView = new MockTextView(mActivity); 3613 3614 textView.reset(); 3615 textView.refreshDrawableState(); 3616 assertTrue(textView.hasCalledDrawableStateChanged()); 3617 } 3618 testGetDefaultEditable()3619 public void testGetDefaultEditable() { 3620 MockTextView textView = new MockTextView(mActivity); 3621 3622 //the TextView#getDefaultEditable() does nothing, and always return false. 3623 assertFalse(textView.getDefaultEditable()); 3624 } 3625 testGetDefaultMovementMethod()3626 public void testGetDefaultMovementMethod() { 3627 MockTextView textView = new MockTextView(mActivity); 3628 3629 //the TextView#getDefaultMovementMethod() does nothing, and always return null. 3630 assertNull(textView.getDefaultMovementMethod()); 3631 } 3632 testOnCreateContextMenu()3633 public void testOnCreateContextMenu() { 3634 // Do not test. Implementation details. 3635 } 3636 testOnDetachedFromWindow()3637 public void testOnDetachedFromWindow() { 3638 // Do not test. Implementation details. 3639 } 3640 testOnDraw()3641 public void testOnDraw() { 3642 // Do not test. Implementation details. 3643 } 3644 testOnFocusChanged()3645 public void testOnFocusChanged() { 3646 // Do not test. Implementation details. 3647 } 3648 testOnMeasure()3649 public void testOnMeasure() { 3650 // Do not test. Implementation details. 3651 } 3652 testOnTextChanged()3653 public void testOnTextChanged() { 3654 // Do not test. Implementation details. 3655 } 3656 testSetFrame()3657 public void testSetFrame() { 3658 MockTextView textView = new MockTextView(mActivity); 3659 3660 //Assign a new size to this view 3661 assertTrue(textView.setFrame(0, 0, 320, 480)); 3662 assertEquals(0, textView.getFrameLeft()); 3663 assertEquals(0, textView.getFrameTop()); 3664 assertEquals(320, textView.getFrameRight()); 3665 assertEquals(480, textView.getFrameBottom()); 3666 3667 //Assign a same size to this view 3668 assertFalse(textView.setFrame(0, 0, 320, 480)); 3669 3670 //negative input 3671 assertTrue(textView.setFrame(-1, -1, -1, -1)); 3672 assertEquals(-1, textView.getFrameLeft()); 3673 assertEquals(-1, textView.getFrameTop()); 3674 assertEquals(-1, textView.getFrameRight()); 3675 assertEquals(-1, textView.getFrameBottom()); 3676 } 3677 testMarquee()3678 public void testMarquee() { 3679 final MockTextView textView = new MockTextView(mActivity); 3680 textView.setText(LONG_TEXT); 3681 textView.setSingleLine(); 3682 textView.setEllipsize(TruncateAt.MARQUEE); 3683 textView.setLayoutParams(new ViewGroup.LayoutParams(100, 100)); 3684 3685 final FrameLayout layout = new FrameLayout(mActivity); 3686 layout.addView(textView); 3687 3688 // make the fading to be shown 3689 textView.setHorizontalFadingEdgeEnabled(true); 3690 3691 mActivity.runOnUiThread(new Runnable() { 3692 public void run() { 3693 mActivity.setContentView(layout); 3694 } 3695 }); 3696 mInstrumentation.waitForIdleSync(); 3697 3698 TestSelectedRunnable runnable = new TestSelectedRunnable(textView) { 3699 public void run() { 3700 textView.setMarqueeRepeatLimit(-1); 3701 // force the marquee to start 3702 saveIsSelected1(); 3703 textView.setSelected(true); 3704 saveIsSelected2(); 3705 } 3706 }; 3707 mActivity.runOnUiThread(runnable); 3708 3709 // wait for the marquee to run 3710 // fading is shown on both sides if the marquee runs for a while 3711 new PollingCheck(TIMEOUT) { 3712 @Override 3713 protected boolean check() { 3714 return textView.getLeftFadingEdgeStrength() > 0.0f 3715 && textView.getRightFadingEdgeStrength() > 0.0f; 3716 } 3717 }.run(); 3718 3719 // wait for left marquee to fully apply 3720 new PollingCheck(TIMEOUT) { 3721 @Override 3722 protected boolean check() { 3723 return textView.getLeftFadingEdgeStrength() > 0.99f; 3724 } 3725 }.run(); 3726 assertFalse(runnable.getIsSelected1()); 3727 assertTrue(runnable.getIsSelected2()); 3728 3729 runnable = new TestSelectedRunnable(textView) { 3730 public void run() { 3731 textView.setMarqueeRepeatLimit(0); 3732 // force the marquee to stop 3733 saveIsSelected1(); 3734 textView.setSelected(false); 3735 saveIsSelected2(); 3736 textView.setGravity(Gravity.LEFT); 3737 } 3738 }; 3739 // force the marquee to stop 3740 mActivity.runOnUiThread(runnable); 3741 mInstrumentation.waitForIdleSync(); 3742 assertTrue(runnable.getIsSelected1()); 3743 assertFalse(runnable.getIsSelected2()); 3744 assertEquals(0.0f, textView.getLeftFadingEdgeStrength(), 0.01f); 3745 assertTrue(textView.getRightFadingEdgeStrength() > 0.0f); 3746 3747 mActivity.runOnUiThread(new Runnable() { 3748 public void run() { 3749 textView.setGravity(Gravity.RIGHT); 3750 } 3751 }); 3752 mInstrumentation.waitForIdleSync(); 3753 assertTrue(textView.getLeftFadingEdgeStrength() > 0.0f); 3754 assertEquals(0.0f, textView.getRightFadingEdgeStrength(), 0.01f); 3755 3756 mActivity.runOnUiThread(new Runnable() { 3757 public void run() { 3758 textView.setGravity(Gravity.CENTER_HORIZONTAL); 3759 } 3760 }); 3761 mInstrumentation.waitForIdleSync(); 3762 // there is no left fading (Is it correct?) 3763 assertEquals(0.0f, textView.getLeftFadingEdgeStrength(), 0.01f); 3764 assertTrue(textView.getRightFadingEdgeStrength() > 0.0f); 3765 } 3766 testOnKeyMultiple()3767 public void testOnKeyMultiple() { 3768 // Do not test. Implementation details. 3769 } 3770 testAccessInputExtras()3771 public void testAccessInputExtras() throws XmlPullParserException, IOException { 3772 TextView textView = new TextView(mActivity); 3773 textView.setText(null, BufferType.EDITABLE); 3774 textView.setInputType(InputType.TYPE_CLASS_TEXT); 3775 3776 // do not create the extras 3777 assertNull(textView.getInputExtras(false)); 3778 3779 // create if it does not exist 3780 Bundle inputExtras = textView.getInputExtras(true); 3781 assertNotNull(inputExtras); 3782 assertTrue(inputExtras.isEmpty()); 3783 3784 // it is created already 3785 assertNotNull(textView.getInputExtras(false)); 3786 3787 try { 3788 textView.setInputExtras(R.xml.input_extras); 3789 fail("Should throw NullPointerException!"); 3790 } catch (NullPointerException e) { 3791 } 3792 } 3793 testAccessContentType()3794 public void testAccessContentType() { 3795 TextView textView = new TextView(mActivity); 3796 textView.setText(null, BufferType.EDITABLE); 3797 textView.setKeyListener(null); 3798 textView.setTransformationMethod(null); 3799 3800 textView.setInputType(InputType.TYPE_CLASS_DATETIME 3801 | InputType.TYPE_DATETIME_VARIATION_NORMAL); 3802 assertEquals(InputType.TYPE_CLASS_DATETIME 3803 | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType()); 3804 assertTrue(textView.getKeyListener() instanceof DateTimeKeyListener); 3805 3806 textView.setInputType(InputType.TYPE_CLASS_DATETIME 3807 | InputType.TYPE_DATETIME_VARIATION_DATE); 3808 assertEquals(InputType.TYPE_CLASS_DATETIME 3809 | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType()); 3810 assertTrue(textView.getKeyListener() instanceof DateKeyListener); 3811 3812 textView.setInputType(InputType.TYPE_CLASS_DATETIME 3813 | InputType.TYPE_DATETIME_VARIATION_TIME); 3814 assertEquals(InputType.TYPE_CLASS_DATETIME 3815 | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType()); 3816 assertTrue(textView.getKeyListener() instanceof TimeKeyListener); 3817 3818 textView.setInputType(InputType.TYPE_CLASS_NUMBER 3819 | InputType.TYPE_NUMBER_FLAG_DECIMAL 3820 | InputType.TYPE_NUMBER_FLAG_SIGNED); 3821 assertEquals(InputType.TYPE_CLASS_NUMBER 3822 | InputType.TYPE_NUMBER_FLAG_DECIMAL 3823 | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType()); 3824 assertSame(textView.getKeyListener(), DigitsKeyListener.getInstance(true, true)); 3825 3826 textView.setInputType(InputType.TYPE_CLASS_PHONE); 3827 assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType()); 3828 assertTrue(textView.getKeyListener() instanceof DialerKeyListener); 3829 3830 textView.setInputType(InputType.TYPE_CLASS_TEXT 3831 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); 3832 assertEquals(InputType.TYPE_CLASS_TEXT 3833 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType()); 3834 assertSame(textView.getKeyListener(), TextKeyListener.getInstance(true, Capitalize.NONE)); 3835 3836 textView.setSingleLine(); 3837 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3838 textView.setInputType(InputType.TYPE_CLASS_TEXT 3839 | InputType.TYPE_TEXT_FLAG_MULTI_LINE 3840 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS); 3841 assertEquals(InputType.TYPE_CLASS_TEXT 3842 | InputType.TYPE_TEXT_FLAG_MULTI_LINE 3843 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType()); 3844 assertSame(textView.getKeyListener(), 3845 TextKeyListener.getInstance(false, Capitalize.CHARACTERS)); 3846 assertNull(textView.getTransformationMethod()); 3847 3848 textView.setInputType(InputType.TYPE_CLASS_TEXT 3849 | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 3850 assertEquals(InputType.TYPE_CLASS_TEXT 3851 | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType()); 3852 assertSame(textView.getKeyListener(), 3853 TextKeyListener.getInstance(false, Capitalize.WORDS)); 3854 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3855 3856 textView.setInputType(InputType.TYPE_CLASS_TEXT 3857 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); 3858 assertEquals(InputType.TYPE_CLASS_TEXT 3859 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType()); 3860 assertSame(textView.getKeyListener(), 3861 TextKeyListener.getInstance(false, Capitalize.SENTENCES)); 3862 3863 textView.setInputType(InputType.TYPE_NULL); 3864 assertEquals(InputType.TYPE_NULL, textView.getInputType()); 3865 assertTrue(textView.getKeyListener() instanceof TextKeyListener); 3866 } 3867 testAccessRawContentType()3868 public void testAccessRawContentType() { 3869 TextView textView = new TextView(mActivity); 3870 textView.setText(null, BufferType.EDITABLE); 3871 textView.setKeyListener(null); 3872 textView.setTransformationMethod(null); 3873 3874 textView.setRawInputType(InputType.TYPE_CLASS_DATETIME 3875 | InputType.TYPE_DATETIME_VARIATION_NORMAL); 3876 assertEquals(InputType.TYPE_CLASS_DATETIME 3877 | InputType.TYPE_DATETIME_VARIATION_NORMAL, textView.getInputType()); 3878 assertNull(textView.getTransformationMethod()); 3879 assertNull(textView.getKeyListener()); 3880 3881 textView.setRawInputType(InputType.TYPE_CLASS_DATETIME 3882 | InputType.TYPE_DATETIME_VARIATION_DATE); 3883 assertEquals(InputType.TYPE_CLASS_DATETIME 3884 | InputType.TYPE_DATETIME_VARIATION_DATE, textView.getInputType()); 3885 assertNull(textView.getTransformationMethod()); 3886 assertNull(textView.getKeyListener()); 3887 3888 textView.setRawInputType(InputType.TYPE_CLASS_DATETIME 3889 | InputType.TYPE_DATETIME_VARIATION_TIME); 3890 assertEquals(InputType.TYPE_CLASS_DATETIME 3891 | InputType.TYPE_DATETIME_VARIATION_TIME, textView.getInputType()); 3892 assertNull(textView.getTransformationMethod()); 3893 assertNull(textView.getKeyListener()); 3894 3895 textView.setRawInputType(InputType.TYPE_CLASS_NUMBER 3896 | InputType.TYPE_NUMBER_FLAG_DECIMAL 3897 | InputType.TYPE_NUMBER_FLAG_SIGNED); 3898 assertEquals(InputType.TYPE_CLASS_NUMBER 3899 | InputType.TYPE_NUMBER_FLAG_DECIMAL 3900 | InputType.TYPE_NUMBER_FLAG_SIGNED, textView.getInputType()); 3901 assertNull(textView.getTransformationMethod()); 3902 assertNull(textView.getKeyListener()); 3903 3904 textView.setRawInputType(InputType.TYPE_CLASS_PHONE); 3905 assertEquals(InputType.TYPE_CLASS_PHONE, textView.getInputType()); 3906 assertNull(textView.getTransformationMethod()); 3907 assertNull(textView.getKeyListener()); 3908 3909 textView.setRawInputType(InputType.TYPE_CLASS_TEXT 3910 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); 3911 assertEquals(InputType.TYPE_CLASS_TEXT 3912 | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT, textView.getInputType()); 3913 assertNull(textView.getTransformationMethod()); 3914 assertNull(textView.getKeyListener()); 3915 3916 textView.setSingleLine(); 3917 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3918 textView.setRawInputType(InputType.TYPE_CLASS_TEXT 3919 | InputType.TYPE_TEXT_FLAG_MULTI_LINE 3920 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS); 3921 assertEquals(InputType.TYPE_CLASS_TEXT 3922 | InputType.TYPE_TEXT_FLAG_MULTI_LINE 3923 | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, textView.getInputType()); 3924 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3925 assertNull(textView.getKeyListener()); 3926 3927 textView.setRawInputType(InputType.TYPE_CLASS_TEXT 3928 | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 3929 assertEquals(InputType.TYPE_CLASS_TEXT 3930 | InputType.TYPE_TEXT_FLAG_CAP_WORDS, textView.getInputType()); 3931 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3932 assertNull(textView.getKeyListener()); 3933 3934 textView.setRawInputType(InputType.TYPE_CLASS_TEXT 3935 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); 3936 assertEquals(InputType.TYPE_CLASS_TEXT 3937 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, textView.getInputType()); 3938 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3939 assertNull(textView.getKeyListener()); 3940 3941 textView.setRawInputType(InputType.TYPE_NULL); 3942 assertTrue(textView.getTransformationMethod() instanceof SingleLineTransformationMethod); 3943 assertNull(textView.getKeyListener()); 3944 } 3945 testOnPrivateIMECommand()3946 public void testOnPrivateIMECommand() { 3947 // Do not test. Implementation details. 3948 } 3949 testFoo()3950 public void testFoo() { 3951 // Do not test. Implementation details. 3952 } 3953 testVerifyDrawable()3954 public void testVerifyDrawable() { 3955 MockTextView textView = new MockTextView(mActivity); 3956 3957 Drawable d = getDrawable(R.drawable.pass); 3958 assertFalse(textView.verifyDrawable(d)); 3959 3960 textView.setCompoundDrawables(null, d, null, null); 3961 assertTrue(textView.verifyDrawable(d)); 3962 } 3963 testAccessPrivateImeOptions()3964 public void testAccessPrivateImeOptions() { 3965 mTextView = findTextView(R.id.textview_text); 3966 assertNull(mTextView.getPrivateImeOptions()); 3967 3968 mTextView.setPrivateImeOptions("com.example.myapp.SpecialMode=3"); 3969 assertEquals("com.example.myapp.SpecialMode=3", mTextView.getPrivateImeOptions()); 3970 3971 mTextView.setPrivateImeOptions(null); 3972 assertNull(mTextView.getPrivateImeOptions()); 3973 } 3974 testSetOnEditorActionListener()3975 public void testSetOnEditorActionListener() { 3976 mTextView = findTextView(R.id.textview_text); 3977 3978 MockOnEditorActionListener listener = new MockOnEditorActionListener(); 3979 assertFalse(listener.isOnEditorActionCalled()); 3980 3981 mTextView.setOnEditorActionListener(listener); 3982 assertFalse(listener.isOnEditorActionCalled()); 3983 3984 mTextView.onEditorAction(EditorInfo.IME_ACTION_DONE); 3985 assertTrue(listener.isOnEditorActionCalled()); 3986 } 3987 testAccessImeOptions()3988 public void testAccessImeOptions() { 3989 mTextView = findTextView(R.id.textview_text); 3990 assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions()); 3991 3992 mTextView.setImeOptions(EditorInfo.IME_ACTION_GO); 3993 assertEquals(EditorInfo.IME_ACTION_GO, mTextView.getImeOptions()); 3994 3995 mTextView.setImeOptions(EditorInfo.IME_ACTION_DONE); 3996 assertEquals(EditorInfo.IME_ACTION_DONE, mTextView.getImeOptions()); 3997 3998 mTextView.setImeOptions(EditorInfo.IME_NULL); 3999 assertEquals(EditorInfo.IME_NULL, mTextView.getImeOptions()); 4000 } 4001 testAccessImeActionLabel()4002 public void testAccessImeActionLabel() { 4003 mTextView = findTextView(R.id.textview_text); 4004 assertNull(mTextView.getImeActionLabel()); 4005 assertEquals(0, mTextView.getImeActionId()); 4006 4007 mTextView.setImeActionLabel("pinyin", 1); 4008 assertEquals("pinyin", mTextView.getImeActionLabel().toString()); 4009 assertEquals(1, mTextView.getImeActionId()); 4010 } 4011 testAccessImeHintLocales()4012 public void testAccessImeHintLocales() { 4013 final TextView textView = new TextView(mActivity); 4014 textView.setText("", BufferType.EDITABLE); 4015 textView.setKeyListener(null); 4016 textView.setRawInputType(InputType.TYPE_CLASS_TEXT); 4017 assertNull(textView.getImeHintLocales()); 4018 { 4019 final EditorInfo editorInfo = new EditorInfo(); 4020 textView.onCreateInputConnection(editorInfo); 4021 assertNull(editorInfo.hintLocales); 4022 } 4023 4024 final LocaleList localeList = LocaleList.forLanguageTags("en-PH,en-US"); 4025 textView.setImeHintLocales(localeList); 4026 assertEquals(localeList, textView.getImeHintLocales()); 4027 { 4028 final EditorInfo editorInfo = new EditorInfo(); 4029 textView.onCreateInputConnection(editorInfo); 4030 assertEquals(localeList, editorInfo.hintLocales); 4031 } 4032 } 4033 4034 @UiThreadTest testSetExtractedText()4035 public void testSetExtractedText() { 4036 mTextView = findTextView(R.id.textview_text); 4037 assertEquals(mActivity.getResources().getString(R.string.text_view_hello), 4038 mTextView.getText().toString()); 4039 4040 ExtractedText et = new ExtractedText(); 4041 4042 // Update text and selection. 4043 et.text = "test"; 4044 et.selectionStart = 0; 4045 et.selectionEnd = 2; 4046 4047 mTextView.setExtractedText(et); 4048 assertEquals("test", mTextView.getText().toString()); 4049 assertEquals(0, mTextView.getSelectionStart()); 4050 assertEquals(2, mTextView.getSelectionEnd()); 4051 4052 // Use partialStartOffset and partialEndOffset 4053 et.partialStartOffset = 2; 4054 et.partialEndOffset = 3; 4055 et.text = "x"; 4056 et.selectionStart = 2; 4057 et.selectionEnd = 3; 4058 4059 mTextView.setExtractedText(et); 4060 assertEquals("text", mTextView.getText().toString()); 4061 assertEquals(2, mTextView.getSelectionStart()); 4062 assertEquals(3, mTextView.getSelectionEnd()); 4063 4064 // Update text with spans. 4065 final SpannableString ss = new SpannableString("ex"); 4066 ss.setSpan(new UnderlineSpan(), 0, 2, 0); 4067 ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0); 4068 4069 et.text = ss; 4070 et.partialStartOffset = 1; 4071 et.partialEndOffset = 3; 4072 mTextView.setExtractedText(et); 4073 4074 assertEquals("text", mTextView.getText().toString()); 4075 final Editable editable = mTextView.getEditableText(); 4076 final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans( 4077 0, editable.length(), UnderlineSpan.class); 4078 assertEquals(1, underlineSpans.length); 4079 assertEquals(1, editable.getSpanStart(underlineSpans[0])); 4080 assertEquals(3, editable.getSpanEnd(underlineSpans[0])); 4081 4082 final URLSpan[] urlSpans = mTextView.getEditableText().getSpans( 4083 0, editable.length(), URLSpan.class); 4084 assertEquals(1, urlSpans.length); 4085 assertEquals(2, editable.getSpanStart(urlSpans[0])); 4086 assertEquals(3, editable.getSpanEnd(urlSpans[0])); 4087 assertEquals("ctstest://TextView/test", urlSpans[0].getURL()); 4088 } 4089 testMoveCursorToVisibleOffset()4090 public void testMoveCursorToVisibleOffset() throws Throwable { 4091 mTextView = findTextView(R.id.textview_text); 4092 4093 // not a spannable text 4094 runTestOnUiThread(new Runnable() { 4095 public void run() { 4096 assertFalse(mTextView.moveCursorToVisibleOffset()); 4097 } 4098 }); 4099 mInstrumentation.waitForIdleSync(); 4100 4101 // a selection range 4102 final String spannableText = "text"; 4103 mTextView = new TextView(mActivity); 4104 4105 runTestOnUiThread(new Runnable() { 4106 public void run() { 4107 mTextView.setText(spannableText, BufferType.SPANNABLE); 4108 } 4109 }); 4110 mInstrumentation.waitForIdleSync(); 4111 Selection.setSelection((Spannable) mTextView.getText(), 0, spannableText.length()); 4112 4113 assertEquals(0, mTextView.getSelectionStart()); 4114 assertEquals(spannableText.length(), mTextView.getSelectionEnd()); 4115 runTestOnUiThread(new Runnable() { 4116 public void run() { 4117 assertFalse(mTextView.moveCursorToVisibleOffset()); 4118 } 4119 }); 4120 mInstrumentation.waitForIdleSync(); 4121 4122 // a spannable without range 4123 runTestOnUiThread(new Runnable() { 4124 public void run() { 4125 mTextView = findTextView(R.id.textview_text); 4126 mTextView.setText(spannableText, BufferType.SPANNABLE); 4127 } 4128 }); 4129 mInstrumentation.waitForIdleSync(); 4130 4131 runTestOnUiThread(new Runnable() { 4132 public void run() { 4133 assertTrue(mTextView.moveCursorToVisibleOffset()); 4134 } 4135 }); 4136 mInstrumentation.waitForIdleSync(); 4137 } 4138 testIsInputMethodTarget()4139 public void testIsInputMethodTarget() throws Throwable { 4140 mTextView = findTextView(R.id.textview_text); 4141 assertFalse(mTextView.isInputMethodTarget()); 4142 4143 assertFalse(mTextView.isFocused()); 4144 runTestOnUiThread(new Runnable() { 4145 @Override 4146 public void run() { 4147 mTextView.setFocusable(true); 4148 mTextView.requestFocus(); 4149 } 4150 }); 4151 mInstrumentation.waitForIdleSync(); 4152 assertTrue(mTextView.isFocused()); 4153 4154 new PollingCheck() { 4155 @Override 4156 protected boolean check() { 4157 return mTextView.isInputMethodTarget(); 4158 } 4159 }.run(); 4160 } 4161 testBeginEndBatchEdit()4162 public void testBeginEndBatchEdit() { 4163 mTextView = findTextView(R.id.textview_text); 4164 4165 mTextView.beginBatchEdit(); 4166 mTextView.endBatchEdit(); 4167 } 4168 4169 @UiThreadTest testBringPointIntoView()4170 public void testBringPointIntoView() throws Throwable { 4171 mTextView = findTextView(R.id.textview_text); 4172 assertFalse(mTextView.bringPointIntoView(1)); 4173 4174 mTextView.layout(0, 0, 100, 100); 4175 assertFalse(mTextView.bringPointIntoView(2)); 4176 } 4177 testCancelLongPress()4178 public void testCancelLongPress() { 4179 mTextView = findTextView(R.id.textview_text); 4180 TouchUtils.longClickView(this, mTextView); 4181 mTextView.cancelLongPress(); 4182 } 4183 4184 @UiThreadTest testClearComposingText()4185 public void testClearComposingText() { 4186 mTextView = findTextView(R.id.textview_text); 4187 mTextView.setText("Hello world!", BufferType.SPANNABLE); 4188 Spannable text = (Spannable) mTextView.getText(); 4189 4190 assertEquals(-1, BaseInputConnection.getComposingSpanStart(text)); 4191 assertEquals(-1, BaseInputConnection.getComposingSpanStart(text)); 4192 4193 BaseInputConnection.setComposingSpans((Spannable) mTextView.getText()); 4194 assertEquals(0, BaseInputConnection.getComposingSpanStart(text)); 4195 assertEquals(0, BaseInputConnection.getComposingSpanStart(text)); 4196 4197 mTextView.clearComposingText(); 4198 assertEquals(-1, BaseInputConnection.getComposingSpanStart(text)); 4199 assertEquals(-1, BaseInputConnection.getComposingSpanStart(text)); 4200 } 4201 testComputeVerticalScrollExtent()4202 public void testComputeVerticalScrollExtent() { 4203 MockTextView textView = new MockTextView(mActivity); 4204 assertEquals(0, textView.computeVerticalScrollExtent()); 4205 4206 Drawable d = getDrawable(R.drawable.pass); 4207 textView.setCompoundDrawables(null, d, null, d); 4208 4209 assertEquals(0, textView.computeVerticalScrollExtent()); 4210 } 4211 4212 @UiThreadTest testDidTouchFocusSelect()4213 public void testDidTouchFocusSelect() { 4214 mTextView = new EditText(mActivity); 4215 assertFalse(mTextView.didTouchFocusSelect()); 4216 4217 mTextView.setFocusable(true); 4218 mTextView.requestFocus(); 4219 assertTrue(mTextView.didTouchFocusSelect()); 4220 } 4221 testSelectAllJustAfterTap()4222 public void testSelectAllJustAfterTap() { 4223 // Prepare an EditText with focus. 4224 mActivity.runOnUiThread(new Runnable() { 4225 public void run() { 4226 mTextView = new EditText(mActivity); 4227 mActivity.setContentView(mTextView); 4228 4229 assertFalse(mTextView.didTouchFocusSelect()); 4230 mTextView.setFocusable(true); 4231 mTextView.requestFocus(); 4232 assertTrue(mTextView.didTouchFocusSelect()); 4233 4234 mTextView.setText("Hello, World.", BufferType.SPANNABLE); 4235 } 4236 }); 4237 mInstrumentation.waitForIdleSync(); 4238 4239 // Tap the view to show InsertPointController. 4240 TouchUtils.tapView(this, mTextView); 4241 // bad workaround for waiting onStartInputView of LeanbackIme.apk done 4242 try { 4243 Thread.sleep(1000); 4244 } catch (InterruptedException e) { 4245 e.printStackTrace(); 4246 } 4247 4248 // Execute SelectAll context menu. 4249 mActivity.runOnUiThread(new Runnable() { 4250 public void run() { 4251 mTextView.onTextContextMenuItem(android.R.id.selectAll); 4252 } 4253 }); 4254 mInstrumentation.waitForIdleSync(); 4255 4256 // The selection must be whole of the text contents. 4257 assertEquals(0, mTextView.getSelectionStart()); 4258 assertEquals("Hello, World.", mTextView.getText().toString()); 4259 assertEquals(mTextView.length(), mTextView.getSelectionEnd()); 4260 } 4261 testExtractText()4262 public void testExtractText() { 4263 mTextView = new TextView(mActivity); 4264 4265 ExtractedTextRequest request = new ExtractedTextRequest(); 4266 ExtractedText outText = new ExtractedText(); 4267 4268 request.token = 0; 4269 request.flags = 10; 4270 request.hintMaxLines = 2; 4271 request.hintMaxChars = 20; 4272 assertTrue(mTextView.extractText(request, outText)); 4273 4274 mTextView = findTextView(R.id.textview_text); 4275 assertTrue(mTextView.extractText(request, outText)); 4276 4277 assertEquals(mActivity.getResources().getString(R.string.text_view_hello), 4278 outText.text.toString()); 4279 4280 // Tests for invalid arguments. 4281 assertFalse(mTextView.extractText(request, null)); 4282 assertFalse(mTextView.extractText(null, outText)); 4283 assertFalse(mTextView.extractText(null, null)); 4284 } 4285 4286 @UiThreadTest testTextDirectionDefault()4287 public void testTextDirectionDefault() { 4288 TextView tv = new TextView(mActivity); 4289 assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection()); 4290 } 4291 4292 @UiThreadTest testSetGetTextDirection()4293 public void testSetGetTextDirection() { 4294 TextView tv = new TextView(mActivity); 4295 4296 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4297 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getRawTextDirection()); 4298 4299 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4300 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getRawTextDirection()); 4301 4302 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4303 assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection()); 4304 4305 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4306 assertEquals(View.TEXT_DIRECTION_LTR, tv.getRawTextDirection()); 4307 4308 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4309 assertEquals(View.TEXT_DIRECTION_RTL, tv.getRawTextDirection()); 4310 4311 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4312 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection()); 4313 4314 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4315 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getRawTextDirection()); 4316 4317 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4318 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getRawTextDirection()); 4319 } 4320 4321 @UiThreadTest testGetResolvedTextDirectionLtr()4322 public void testGetResolvedTextDirectionLtr() { 4323 TextView tv = new TextView(mActivity); 4324 tv.setText("this is a test"); 4325 4326 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4327 4328 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4329 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4330 4331 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4332 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4333 4334 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4335 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4336 4337 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4338 assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection()); 4339 4340 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4341 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4342 4343 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4344 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection()); 4345 4346 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4347 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4348 4349 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4350 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4351 } 4352 4353 @UiThreadTest testGetResolvedTextDirectionLtrWithInheritance()4354 public void testGetResolvedTextDirectionLtrWithInheritance() { 4355 LinearLayout ll = new LinearLayout(mActivity); 4356 ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4357 4358 TextView tv = new TextView(mActivity); 4359 tv.setText("this is a test"); 4360 ll.addView(tv); 4361 4362 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4363 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4364 4365 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4366 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4367 4368 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4369 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4370 4371 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4372 assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection()); 4373 4374 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4375 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4376 4377 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4378 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection()); 4379 4380 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4381 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4382 4383 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4384 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4385 } 4386 4387 @UiThreadTest testGetResolvedTextDirectionRtl()4388 public void testGetResolvedTextDirectionRtl() { 4389 TextView tv = new TextView(mActivity); 4390 tv.setText("\u05DD\u05DE"); // hebrew 4391 4392 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4393 4394 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4395 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4396 4397 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4398 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4399 4400 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4401 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4402 4403 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4404 assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection()); 4405 4406 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4407 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4408 4409 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4410 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection()); 4411 4412 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4413 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4414 4415 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4416 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4417 } 4418 4419 @UiThreadTest testGetResolvedTextDirectionRtlWithInheritance()4420 public void testGetResolvedTextDirectionRtlWithInheritance() { 4421 LinearLayout ll = new LinearLayout(mActivity); 4422 ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4423 4424 TextView tv = new TextView(mActivity); 4425 tv.setText("\u05DD\u05DE"); // hebrew 4426 ll.addView(tv); 4427 4428 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4429 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4430 4431 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4432 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4433 4434 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4435 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4436 4437 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4438 assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection()); 4439 4440 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4441 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4442 4443 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4444 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection()); 4445 4446 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4447 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4448 4449 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4450 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4451 4452 // Force to RTL text direction on the layout 4453 ll.setTextDirection(View.TEXT_DIRECTION_RTL); 4454 4455 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG); 4456 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4457 4458 tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL); 4459 assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection()); 4460 4461 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4462 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4463 4464 tv.setTextDirection(View.TEXT_DIRECTION_LTR); 4465 assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection()); 4466 4467 tv.setTextDirection(View.TEXT_DIRECTION_RTL); 4468 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4469 4470 tv.setTextDirection(View.TEXT_DIRECTION_LOCALE); 4471 assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection()); 4472 4473 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4474 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4475 4476 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4477 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4478 } 4479 4480 @UiThreadTest testResetTextDirection()4481 public void testResetTextDirection() { 4482 LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest); 4483 TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl); 4484 4485 ll.setTextDirection(View.TEXT_DIRECTION_RTL); 4486 tv.setTextDirection(View.TEXT_DIRECTION_INHERIT); 4487 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4488 4489 // No reset when we remove the view 4490 ll.removeView(tv); 4491 assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection()); 4492 4493 // Reset is done when we add the view 4494 ll.addView(tv); 4495 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection()); 4496 } 4497 4498 @UiThreadTest testTextDirectionFirstStrongLtr()4499 public void testTextDirectionFirstStrongLtr() { 4500 { 4501 // The first directional character is LTR, the paragraph direction is LTR. 4502 LinearLayout ll = new LinearLayout(mActivity); 4503 4504 TextView tv = new TextView(mActivity); 4505 tv.setText("this is a test"); 4506 ll.addView(tv); 4507 4508 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4509 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4510 4511 tv.onPreDraw(); // For freezing layout. 4512 Layout layout = tv.getLayout(); 4513 assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0)); 4514 } 4515 { 4516 // The first directional character is RTL, the paragraph direction is RTL. 4517 LinearLayout ll = new LinearLayout(mActivity); 4518 4519 TextView tv = new TextView(mActivity); 4520 tv.setText("\u05DD\u05DE"); // Hebrew 4521 ll.addView(tv); 4522 4523 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4524 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4525 4526 tv.onPreDraw(); // For freezing layout. 4527 Layout layout = tv.getLayout(); 4528 assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0)); 4529 } 4530 { 4531 // The first directional character is not a strong directional character, the paragraph 4532 // direction is LTR. 4533 LinearLayout ll = new LinearLayout(mActivity); 4534 4535 TextView tv = new TextView(mActivity); 4536 tv.setText("\uFFFD"); // REPLACEMENT CHARACTER. Neutral direction. 4537 ll.addView(tv); 4538 4539 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR); 4540 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection()); 4541 4542 tv.onPreDraw(); // For freezing layout. 4543 Layout layout = tv.getLayout(); 4544 assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0)); 4545 } 4546 } 4547 4548 @UiThreadTest testTextDirectionFirstStrongRtl()4549 public void testTextDirectionFirstStrongRtl() { 4550 { 4551 // The first directional character is LTR, the paragraph direction is LTR. 4552 LinearLayout ll = new LinearLayout(mActivity); 4553 4554 TextView tv = new TextView(mActivity); 4555 tv.setText("this is a test"); 4556 ll.addView(tv); 4557 4558 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4559 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4560 4561 tv.onPreDraw(); // For freezing layout. 4562 Layout layout = tv.getLayout(); 4563 assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0)); 4564 } 4565 { 4566 // The first directional character is RTL, the paragraph direction is RTL. 4567 LinearLayout ll = new LinearLayout(mActivity); 4568 4569 TextView tv = new TextView(mActivity); 4570 tv.setText("\u05DD\u05DE"); // Hebrew 4571 ll.addView(tv); 4572 4573 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4574 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4575 4576 tv.onPreDraw(); // For freezing layout. 4577 Layout layout = tv.getLayout(); 4578 assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0)); 4579 } 4580 { 4581 // The first directional character is not a strong directional character, the paragraph 4582 // direction is RTL. 4583 LinearLayout ll = new LinearLayout(mActivity); 4584 4585 TextView tv = new TextView(mActivity); 4586 tv.setText("\uFFFD"); // REPLACEMENT CHARACTER. Neutral direction. 4587 ll.addView(tv); 4588 4589 tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL); 4590 assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection()); 4591 4592 tv.onPreDraw(); // For freezing layout. 4593 Layout layout = tv.getLayout(); 4594 assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0)); 4595 } 4596 } 4597 testTextLocales()4598 public void testTextLocales() { 4599 TextView tv = new TextView(mActivity); 4600 assertEquals(Locale.getDefault(), tv.getTextLocale()); 4601 assertEquals(LocaleList.getDefault(), tv.getTextLocales()); 4602 4603 tv.setTextLocale(Locale.CHINESE); 4604 assertEquals(Locale.CHINESE, tv.getTextLocale()); 4605 assertEquals(new LocaleList(Locale.CHINESE), tv.getTextLocales()); 4606 4607 tv.setTextLocales(LocaleList.forLanguageTags("en,ja")); 4608 assertEquals(Locale.forLanguageTag("en"), tv.getTextLocale()); 4609 assertEquals(LocaleList.forLanguageTags("en,ja"), tv.getTextLocales()); 4610 4611 try { 4612 tv.setTextLocale(null); 4613 fail("Setting the text locale to null should throw"); 4614 } catch (Throwable e) { 4615 assertEquals(IllegalArgumentException.class, e.getClass()); 4616 } 4617 4618 try { 4619 tv.setTextLocales(null); 4620 fail("Setting the text locales to null should throw"); 4621 } catch (Throwable e) { 4622 assertEquals(IllegalArgumentException.class, e.getClass()); 4623 } 4624 4625 try { 4626 tv.setTextLocales(new LocaleList()); 4627 fail("Setting the text locale to an empty list should throw"); 4628 } catch (Throwable e) { 4629 assertEquals(IllegalArgumentException.class, e.getClass()); 4630 } 4631 } 4632 testAllCapsLocalization()4633 public void testAllCapsLocalization() { 4634 String testString = "abcdefghijklmnopqrstuvwxyz"; 4635 4636 // The capitalized characters of "i" on Turkish and Azerbaijani are different from English. 4637 Locale[] testLocales = { 4638 new Locale("az", "AZ"), 4639 new Locale("tr", "TR"), 4640 new Locale("en", "US"), 4641 }; 4642 4643 TextView tv = new TextView(mActivity); 4644 tv.setAllCaps(true); 4645 for (Locale locale: testLocales) { 4646 tv.setTextLocale(locale); 4647 assertEquals("Locale: " + locale.getDisplayName(), 4648 testString.toUpperCase(locale), 4649 tv.getTransformationMethod().getTransformation(testString, tv).toString()); 4650 } 4651 } 4652 4653 @UiThreadTest testTextAlignmentDefault()4654 public void testTextAlignmentDefault() { 4655 TextView tv = new TextView(getActivity()); 4656 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment()); 4657 // resolved default text alignment is GRAVITY 4658 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment()); 4659 } 4660 4661 @UiThreadTest testSetGetTextAlignment()4662 public void testSetGetTextAlignment() { 4663 TextView tv = new TextView(getActivity()); 4664 4665 tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY); 4666 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment()); 4667 4668 tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4669 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getRawTextAlignment()); 4670 4671 tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); 4672 assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getRawTextAlignment()); 4673 4674 tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); 4675 assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getRawTextAlignment()); 4676 4677 tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 4678 assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getRawTextAlignment()); 4679 4680 tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); 4681 assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getRawTextAlignment()); 4682 } 4683 4684 @UiThreadTest testGetResolvedTextAlignment()4685 public void testGetResolvedTextAlignment() { 4686 TextView tv = new TextView(getActivity()); 4687 4688 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment()); 4689 4690 // Test center alignment first so that we dont hit the default case 4691 tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4692 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4693 4694 // Test the default case too 4695 tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY); 4696 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment()); 4697 4698 tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); 4699 assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment()); 4700 4701 tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); 4702 assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment()); 4703 4704 tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 4705 assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment()); 4706 4707 tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); 4708 assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment()); 4709 } 4710 4711 @UiThreadTest testGetResolvedTextAlignmentWithInheritance()4712 public void testGetResolvedTextAlignmentWithInheritance() { 4713 LinearLayout ll = new LinearLayout(getActivity()); 4714 ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY); 4715 4716 TextView tv = new TextView(getActivity()); 4717 ll.addView(tv); 4718 4719 // check defaults 4720 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment()); 4721 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment()); 4722 4723 // set inherit and check that child is following parent 4724 tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); 4725 assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getRawTextAlignment()); 4726 4727 ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4728 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4729 4730 ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); 4731 assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment()); 4732 4733 ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); 4734 assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment()); 4735 4736 ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 4737 assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment()); 4738 4739 ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); 4740 assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment()); 4741 4742 // now get rid of the inheritance but still change the parent 4743 tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4744 4745 ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4746 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4747 4748 ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); 4749 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4750 4751 ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); 4752 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4753 4754 ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 4755 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4756 4757 ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); 4758 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4759 } 4760 4761 @UiThreadTest testResetTextAlignment()4762 public void testResetTextAlignment() { 4763 TextViewCtsActivity activity = getActivity(); 4764 4765 LinearLayout ll = (LinearLayout) activity.findViewById(R.id.layout_textviewtest); 4766 TextView tv = (TextView) activity.findViewById(R.id.textview_rtl); 4767 4768 ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 4769 tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); 4770 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4771 4772 // No reset when we remove the view 4773 ll.removeView(tv); 4774 assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment()); 4775 4776 // Reset is done when we add the view 4777 // Default text alignment is GRAVITY 4778 ll.addView(tv); 4779 assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment()); 4780 } 4781 4782 @UiThreadTest testDrawableResolution()4783 public void testDrawableResolution() { 4784 final int LEFT = 0; 4785 final int TOP = 1; 4786 final int RIGHT = 2; 4787 final int BOTTOM = 3; 4788 4789 TextViewCtsActivity activity = getActivity(); 4790 4791 // Case 1.1: left / right drawable defined in default LTR mode 4792 TextView tv = (TextView) activity.findViewById(R.id.textview_drawable_1_1); 4793 Drawable[] drawables = tv.getCompoundDrawables(); 4794 4795 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4796 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4797 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4798 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4799 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4800 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4801 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4802 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4803 4804 // Case 1.2: left / right drawable defined in default RTL mode 4805 tv = (TextView) activity.findViewById(R.id.textview_drawable_1_2); 4806 drawables = tv.getCompoundDrawables(); 4807 4808 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4809 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4810 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4811 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4812 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4813 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4814 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4815 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4816 4817 // Case 2.1: start / end drawable defined in LTR mode 4818 tv = (TextView) activity.findViewById(R.id.textview_drawable_2_1); 4819 drawables = tv.getCompoundDrawables(); 4820 4821 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4822 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4823 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4824 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4825 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4826 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4827 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4828 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4829 4830 // Case 2.2: start / end drawable defined in RTL mode 4831 tv = (TextView) activity.findViewById(R.id.textview_drawable_2_2); 4832 drawables = tv.getCompoundDrawables(); 4833 4834 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4835 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4836 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4837 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4838 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4839 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4840 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4841 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4842 4843 // Case 3.1: left / right / start / end drawable defined in LTR mode 4844 tv = (TextView) activity.findViewById(R.id.textview_drawable_3_1); 4845 drawables = tv.getCompoundDrawables(); 4846 4847 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4848 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4849 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4850 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4851 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4852 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4853 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4854 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4855 4856 // Case 3.2: left / right / start / end drawable defined in RTL mode 4857 tv = (TextView) activity.findViewById(R.id.textview_drawable_3_2); 4858 drawables = tv.getCompoundDrawables(); 4859 4860 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4861 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4862 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4863 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4864 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4865 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4866 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4867 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4868 4869 // Case 4.1: start / end drawable defined in LTR mode inside a layout 4870 // that defines the layout direction 4871 tv = (TextView) activity.findViewById(R.id.textview_drawable_4_1); 4872 drawables = tv.getCompoundDrawables(); 4873 4874 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4875 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4876 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4877 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4878 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4879 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4880 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4881 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4882 4883 // Case 4.2: start / end drawable defined in RTL mode inside a layout 4884 // that defines the layout direction 4885 tv = (TextView) activity.findViewById(R.id.textview_drawable_4_2); 4886 drawables = tv.getCompoundDrawables(); 4887 4888 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4889 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4890 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4891 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4892 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4893 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4894 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4895 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4896 4897 // Case 5.1: left / right / start / end drawable defined in LTR mode inside a layout 4898 // that defines the layout direction 4899 tv = (TextView) activity.findViewById(R.id.textview_drawable_3_1); 4900 drawables = tv.getCompoundDrawables(); 4901 4902 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4903 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4904 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4905 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4906 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4907 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4908 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4909 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4910 4911 // Case 5.2: left / right / start / end drawable defined in RTL mode inside a layout 4912 // that defines the layout direction 4913 tv = (TextView) activity.findViewById(R.id.textview_drawable_3_2); 4914 drawables = tv.getCompoundDrawables(); 4915 4916 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4917 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4918 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4919 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4920 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4921 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4922 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4923 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4924 } 4925 4926 @UiThreadTest testDrawableResolution2()4927 public void testDrawableResolution2() { 4928 final int LEFT = 0; 4929 final int TOP = 1; 4930 final int RIGHT = 2; 4931 final int BOTTOM = 3; 4932 4933 TextViewCtsActivity activity = getActivity(); 4934 4935 // Case 1.1: left / right drawable defined in default LTR mode 4936 TextView tv = (TextView) activity.findViewById(R.id.textview_drawable_1_1); 4937 Drawable[] drawables = tv.getCompoundDrawables(); 4938 4939 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4940 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4941 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4942 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4943 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4944 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4945 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4946 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4947 4948 tv.setCompoundDrawables(null, null, getDrawable(R.drawable.icon_yellow), null); 4949 drawables = tv.getCompoundDrawables(); 4950 4951 assertNull(drawables[LEFT]); 4952 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4953 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4954 assertNull(drawables[TOP]); 4955 assertNull(drawables[BOTTOM]); 4956 4957 tv = (TextView) activity.findViewById(R.id.textview_drawable_1_2); 4958 drawables = tv.getCompoundDrawables(); 4959 4960 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4961 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4962 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4963 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4964 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green), 4965 ((BitmapDrawable) drawables[TOP]).getBitmap()); 4966 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4967 ((BitmapDrawable) drawables[BOTTOM]).getBitmap()); 4968 4969 tv.setCompoundDrawables(getDrawable(R.drawable.icon_yellow), null, null, null); 4970 drawables = tv.getCompoundDrawables(); 4971 4972 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 4973 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4974 assertNull(drawables[RIGHT]); 4975 assertNull(drawables[TOP]); 4976 assertNull(drawables[BOTTOM]); 4977 4978 tv = (TextView) activity.findViewById(R.id.textview_ltr); 4979 drawables = tv.getCompoundDrawables(); 4980 4981 assertNull(drawables[LEFT]); 4982 assertNull(drawables[RIGHT]); 4983 assertNull(drawables[TOP]); 4984 assertNull(drawables[BOTTOM]); 4985 4986 tv.setCompoundDrawables(getDrawable(R.drawable.icon_blue), null, getDrawable(R.drawable.icon_red), null); 4987 drawables = tv.getCompoundDrawables(); 4988 4989 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue), 4990 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 4991 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red), 4992 ((BitmapDrawable) drawables[RIGHT]).getBitmap()); 4993 assertNull(drawables[TOP]); 4994 assertNull(drawables[BOTTOM]); 4995 4996 tv.setCompoundDrawablesRelative(getDrawable(R.drawable.icon_yellow), null, null, null); 4997 drawables = tv.getCompoundDrawables(); 4998 4999 WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow), 5000 ((BitmapDrawable) drawables[LEFT]).getBitmap()); 5001 assertNull(drawables[RIGHT]); 5002 assertNull(drawables[TOP]); 5003 assertNull(drawables[BOTTOM]); 5004 } 5005 testSetGetBreakStrategy()5006 public void testSetGetBreakStrategy() { 5007 TextView tv = new TextView(mActivity); 5008 5009 final PackageManager pm = getInstrumentation().getTargetContext().getPackageManager(); 5010 5011 // The default value is from the theme, here the default is BREAK_STRATEGY_HIGH_QUALITY for 5012 // TextView except for Android Wear. The default value for Android Wear is 5013 // BREAK_STRATEGY_BALANCED. 5014 if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) { 5015 // Android Wear 5016 assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy()); 5017 } else { 5018 // All other form factor. 5019 assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy()); 5020 } 5021 5022 tv.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE); 5023 assertEquals(Layout.BREAK_STRATEGY_SIMPLE, tv.getBreakStrategy()); 5024 5025 tv.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY); 5026 assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy()); 5027 5028 tv.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); 5029 assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy()); 5030 5031 EditText et = new EditText(mActivity); 5032 5033 // The default value is from the theme, here the default is BREAK_STRATEGY_SIMPLE for 5034 // EditText. 5035 assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy()); 5036 5037 et.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE); 5038 assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy()); 5039 5040 et.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY); 5041 assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, et.getBreakStrategy()); 5042 5043 et.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED); 5044 assertEquals(Layout.BREAK_STRATEGY_BALANCED, et.getBreakStrategy()); 5045 } 5046 testSetGetHyphenationFrequency()5047 public void testSetGetHyphenationFrequency() { 5048 TextView tv = new TextView(mActivity); 5049 5050 assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency()); 5051 5052 tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE); 5053 assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, tv.getHyphenationFrequency()); 5054 5055 tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL); 5056 assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency()); 5057 5058 tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); 5059 assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency()); 5060 } 5061 testSetAndGetCustomSelectionActionModeCallback()5062 public void testSetAndGetCustomSelectionActionModeCallback() { 5063 final String text = "abcde"; 5064 mActivity.runOnUiThread(new Runnable() { 5065 public void run() { 5066 mTextView = new EditText(mActivity); 5067 mActivity.setContentView(mTextView); 5068 mTextView.setText(text, BufferType.SPANNABLE); 5069 mTextView.setTextIsSelectable(true); 5070 mTextView.requestFocus(); 5071 mTextView.setSelected(true); 5072 } 5073 }); 5074 mInstrumentation.waitForIdleSync(); 5075 5076 // Check default value. 5077 assertNull(mTextView.getCustomSelectionActionModeCallback()); 5078 5079 MockActionModeCallback callbackBlockActionMode = new MockActionModeCallback(false); 5080 mTextView.setCustomSelectionActionModeCallback(callbackBlockActionMode); 5081 assertEquals(callbackBlockActionMode, 5082 mTextView.getCustomSelectionActionModeCallback()); 5083 5084 mActivity.runOnUiThread(new Runnable() { 5085 public void run() { 5086 // Set selection and try to start action mode. 5087 final Bundle args = new Bundle(); 5088 args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0); 5089 args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length()); 5090 mTextView.performAccessibilityAction( 5091 AccessibilityNodeInfo.ACTION_SET_SELECTION, args); 5092 } 5093 }); 5094 mInstrumentation.waitForIdleSync(); 5095 5096 assertEquals(1, callbackBlockActionMode.getCreateCount()); 5097 5098 mActivity.runOnUiThread(new Runnable() { 5099 public void run() { 5100 // Remove selection and stop action mode. 5101 mTextView.onTextContextMenuItem(android.R.id.copy); 5102 } 5103 }); 5104 mInstrumentation.waitForIdleSync(); 5105 5106 // Action mode was blocked. 5107 assertEquals(0, callbackBlockActionMode.getDestroyCount()); 5108 5109 // Overwrite callback. 5110 MockActionModeCallback callbackStartActionMode = new MockActionModeCallback(true); 5111 mTextView.setCustomSelectionActionModeCallback(callbackStartActionMode); 5112 assertEquals(callbackStartActionMode, mTextView.getCustomSelectionActionModeCallback()); 5113 5114 mActivity.runOnUiThread(new Runnable() { 5115 public void run() { 5116 // Set selection and try to start action mode. 5117 final Bundle args = new Bundle(); 5118 args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0); 5119 args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length()); 5120 mTextView.performAccessibilityAction( 5121 AccessibilityNodeInfo.ACTION_SET_SELECTION, args); 5122 5123 } 5124 }); 5125 mInstrumentation.waitForIdleSync(); 5126 5127 assertEquals(1, callbackStartActionMode.getCreateCount()); 5128 5129 mActivity.runOnUiThread(new Runnable() { 5130 public void run() { 5131 // Remove selection and stop action mode. 5132 mTextView.onTextContextMenuItem(android.R.id.copy); 5133 } 5134 }); 5135 mInstrumentation.waitForIdleSync(); 5136 5137 // Action mode was started 5138 assertEquals(1, callbackStartActionMode.getDestroyCount()); 5139 } 5140 testSetAndGetCustomInseltionActionMode()5141 public void testSetAndGetCustomInseltionActionMode() { 5142 initTextViewForTyping(); 5143 // Check default value. 5144 assertNull(mTextView.getCustomInsertionActionModeCallback()); 5145 5146 MockActionModeCallback callback = new MockActionModeCallback(false); 5147 mTextView.setCustomInsertionActionModeCallback(callback); 5148 assertEquals(callback, mTextView.getCustomInsertionActionModeCallback()); 5149 // TODO(Bug: 22033189): Tests the set callback is actually used. 5150 } 5151 5152 private static class MockActionModeCallback implements ActionMode.Callback { 5153 private int mCreateCount = 0; 5154 private int mDestroyCount = 0; 5155 private final boolean mAllowToStartActionMode; 5156 MockActionModeCallback(boolean allowToStartActionMode)5157 public MockActionModeCallback(boolean allowToStartActionMode) { 5158 mAllowToStartActionMode = allowToStartActionMode; 5159 } 5160 getCreateCount()5161 public int getCreateCount() { 5162 return mCreateCount; 5163 } 5164 getDestroyCount()5165 public int getDestroyCount() { 5166 return mDestroyCount; 5167 } 5168 5169 @Override onPrepareActionMode(ActionMode mode, Menu menu)5170 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 5171 return false; 5172 } 5173 5174 @Override onDestroyActionMode(ActionMode mode)5175 public void onDestroyActionMode(ActionMode mode) { 5176 mDestroyCount++; 5177 } 5178 5179 @Override onCreateActionMode(ActionMode mode, Menu menu)5180 public boolean onCreateActionMode(ActionMode mode, Menu menu) { 5181 mCreateCount++; 5182 return mAllowToStartActionMode; 5183 } 5184 5185 @Override onActionItemClicked(ActionMode mode, MenuItem item)5186 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 5187 return false; 5188 } 5189 }; 5190 5191 private static class MockOnEditorActionListener implements OnEditorActionListener { 5192 private boolean isOnEditorActionCalled; 5193 onEditorAction(TextView v, int actionId, KeyEvent event)5194 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 5195 isOnEditorActionCalled = true; 5196 return true; 5197 } 5198 isOnEditorActionCalled()5199 public boolean isOnEditorActionCalled() { 5200 return isOnEditorActionCalled; 5201 } 5202 } 5203 layout(final TextView textView)5204 private void layout(final TextView textView) { 5205 mActivity.runOnUiThread(new Runnable() { 5206 public void run() { 5207 mActivity.setContentView(textView); 5208 } 5209 }); 5210 mInstrumentation.waitForIdleSync(); 5211 } 5212 layout(final int layoutId)5213 private void layout(final int layoutId) { 5214 mActivity.runOnUiThread(new Runnable() { 5215 public void run() { 5216 mActivity.setContentView(layoutId); 5217 } 5218 }); 5219 mInstrumentation.waitForIdleSync(); 5220 } 5221 findTextView(int id)5222 private TextView findTextView(int id) { 5223 return (TextView) mActivity.findViewById(id); 5224 } 5225 getAutoLinkMask(int id)5226 private int getAutoLinkMask(int id) { 5227 return findTextView(id).getAutoLinkMask(); 5228 } 5229 getBitmap(int resid)5230 private Bitmap getBitmap(int resid) { 5231 return ((BitmapDrawable) getDrawable(resid)).getBitmap(); 5232 } 5233 getDrawable(int resid)5234 private Drawable getDrawable(int resid) { 5235 return mActivity.getResources().getDrawable(resid); 5236 } 5237 setMaxWidth(final int pixels)5238 private void setMaxWidth(final int pixels) { 5239 mActivity.runOnUiThread(new Runnable() { 5240 public void run() { 5241 mTextView.setMaxWidth(pixels); 5242 } 5243 }); 5244 mInstrumentation.waitForIdleSync(); 5245 } 5246 setMinWidth(final int pixels)5247 private void setMinWidth(final int pixels) { 5248 mActivity.runOnUiThread(new Runnable() { 5249 public void run() { 5250 mTextView.setMinWidth(pixels); 5251 } 5252 }); 5253 mInstrumentation.waitForIdleSync(); 5254 } 5255 setMaxHeight(final int pixels)5256 private void setMaxHeight(final int pixels) { 5257 mActivity.runOnUiThread(new Runnable() { 5258 public void run() { 5259 mTextView.setMaxHeight(pixels); 5260 } 5261 }); 5262 mInstrumentation.waitForIdleSync(); 5263 } 5264 setMinHeight(final int pixels)5265 private void setMinHeight(final int pixels) { 5266 mActivity.runOnUiThread(new Runnable() { 5267 public void run() { 5268 mTextView.setMinHeight(pixels); 5269 } 5270 }); 5271 mInstrumentation.waitForIdleSync(); 5272 } 5273 setMinLines(final int minlines)5274 private void setMinLines(final int minlines) { 5275 mActivity.runOnUiThread(new Runnable() { 5276 public void run() { 5277 mTextView.setMinLines(minlines); 5278 } 5279 }); 5280 mInstrumentation.waitForIdleSync(); 5281 } 5282 5283 /** 5284 * Convenience for {@link TextView#setText(CharSequence, BufferType)}. And 5285 * the buffer type is fixed to SPANNABLE. 5286 * 5287 * @param tv the text view 5288 * @param content the content 5289 */ setSpannableText(final TextView tv, final String content)5290 private void setSpannableText(final TextView tv, final String content) { 5291 mActivity.runOnUiThread(new Runnable() { 5292 public void run() { 5293 tv.setText(content, BufferType.SPANNABLE); 5294 } 5295 }); 5296 mInstrumentation.waitForIdleSync(); 5297 } 5298 setLines(final int lines)5299 private void setLines(final int lines) { 5300 mActivity.runOnUiThread(new Runnable() { 5301 public void run() { 5302 mTextView.setLines(lines); 5303 } 5304 }); 5305 mInstrumentation.waitForIdleSync(); 5306 } 5307 setHorizontallyScrolling(final boolean whether)5308 private void setHorizontallyScrolling(final boolean whether) { 5309 mActivity.runOnUiThread(new Runnable() { 5310 public void run() { 5311 mTextView.setHorizontallyScrolling(whether); 5312 } 5313 }); 5314 mInstrumentation.waitForIdleSync(); 5315 } 5316 setWidth(final int pixels)5317 private void setWidth(final int pixels) { 5318 mActivity.runOnUiThread(new Runnable() { 5319 public void run() { 5320 mTextView.setWidth(pixels); 5321 } 5322 }); 5323 mInstrumentation.waitForIdleSync(); 5324 } 5325 setHeight(final int pixels)5326 private void setHeight(final int pixels) { 5327 mActivity.runOnUiThread(new Runnable() { 5328 public void run() { 5329 mTextView.setHeight(pixels); 5330 } 5331 }); 5332 mInstrumentation.waitForIdleSync(); 5333 } 5334 setMinEms(final int ems)5335 private void setMinEms(final int ems) { 5336 mActivity.runOnUiThread(new Runnable() { 5337 public void run() { 5338 mTextView.setMinEms(ems); 5339 } 5340 }); 5341 mInstrumentation.waitForIdleSync(); 5342 } 5343 setMaxEms(final int ems)5344 private void setMaxEms(final int ems) { 5345 mActivity.runOnUiThread(new Runnable() { 5346 public void run() { 5347 mTextView.setMaxEms(ems); 5348 } 5349 }); 5350 mInstrumentation.waitForIdleSync(); 5351 } 5352 setEms(final int ems)5353 private void setEms(final int ems) { 5354 mActivity.runOnUiThread(new Runnable() { 5355 public void run() { 5356 mTextView.setEms(ems); 5357 } 5358 }); 5359 mInstrumentation.waitForIdleSync(); 5360 } 5361 setLineSpacing(final float add, final float mult)5362 private void setLineSpacing(final float add, final float mult) { 5363 mActivity.runOnUiThread(new Runnable() { 5364 public void run() { 5365 mTextView.setLineSpacing(add, mult); 5366 } 5367 }); 5368 mInstrumentation.waitForIdleSync(); 5369 } 5370 5371 private static abstract class TestSelectedRunnable implements Runnable { 5372 private TextView mTextView; 5373 private boolean mIsSelected1; 5374 private boolean mIsSelected2; 5375 TestSelectedRunnable(TextView textview)5376 public TestSelectedRunnable(TextView textview) { 5377 mTextView = textview; 5378 } 5379 getIsSelected1()5380 public boolean getIsSelected1() { 5381 return mIsSelected1; 5382 } 5383 getIsSelected2()5384 public boolean getIsSelected2() { 5385 return mIsSelected2; 5386 } 5387 saveIsSelected1()5388 public void saveIsSelected1() { 5389 mIsSelected1 = mTextView.isSelected(); 5390 } 5391 saveIsSelected2()5392 public void saveIsSelected2() { 5393 mIsSelected2 = mTextView.isSelected(); 5394 } 5395 } 5396 5397 private static abstract class TestLayoutRunnable implements Runnable { 5398 private TextView mTextView; 5399 private Layout mLayout; 5400 TestLayoutRunnable(TextView textview)5401 public TestLayoutRunnable(TextView textview) { 5402 mTextView = textview; 5403 } 5404 getLayout()5405 public Layout getLayout() { 5406 return mLayout; 5407 } 5408 saveLayout()5409 public void saveLayout() { 5410 mLayout = mTextView.getLayout(); 5411 } 5412 } 5413 5414 private class MockEditableFactory extends Editable.Factory { 5415 private boolean mhasCalledNewEditable; 5416 private CharSequence mSource; 5417 hasCalledNewEditable()5418 public boolean hasCalledNewEditable() { 5419 return mhasCalledNewEditable; 5420 } 5421 reset()5422 public void reset() { 5423 mhasCalledNewEditable = false; 5424 mSource = null; 5425 } 5426 getSource()5427 public CharSequence getSource() { 5428 return mSource; 5429 } 5430 5431 @Override newEditable(CharSequence source)5432 public Editable newEditable(CharSequence source) { 5433 mhasCalledNewEditable = true; 5434 mSource = source; 5435 return super.newEditable(source); 5436 } 5437 } 5438 5439 private class MockSpannableFactory extends Spannable.Factory { 5440 private boolean mHasCalledNewSpannable; 5441 private CharSequence mSource; 5442 hasCalledNewSpannable()5443 public boolean hasCalledNewSpannable() { 5444 return mHasCalledNewSpannable; 5445 } 5446 reset()5447 public void reset() { 5448 mHasCalledNewSpannable = false; 5449 mSource = null; 5450 } 5451 getSource()5452 public CharSequence getSource() { 5453 return mSource; 5454 } 5455 5456 @Override newSpannable(CharSequence source)5457 public Spannable newSpannable(CharSequence source) { 5458 mHasCalledNewSpannable = true; 5459 mSource = source; 5460 return super.newSpannable(source); 5461 } 5462 } 5463 5464 private static class MockTextWatcher implements TextWatcher { 5465 private boolean mHasCalledAfterTextChanged; 5466 private boolean mHasCalledBeforeTextChanged; 5467 private boolean mHasOnTextChanged; 5468 reset()5469 public void reset(){ 5470 mHasCalledAfterTextChanged = false; 5471 mHasCalledBeforeTextChanged = false; 5472 mHasOnTextChanged = false; 5473 } 5474 hasCalledAfterTextChanged()5475 public boolean hasCalledAfterTextChanged() { 5476 return mHasCalledAfterTextChanged; 5477 } 5478 hasCalledBeforeTextChanged()5479 public boolean hasCalledBeforeTextChanged() { 5480 return mHasCalledBeforeTextChanged; 5481 } 5482 hasCalledOnTextChanged()5483 public boolean hasCalledOnTextChanged() { 5484 return mHasOnTextChanged; 5485 } 5486 afterTextChanged(Editable s)5487 public void afterTextChanged(Editable s) { 5488 mHasCalledAfterTextChanged = true; 5489 } 5490 beforeTextChanged(CharSequence s, int start, int count, int after)5491 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 5492 mHasCalledBeforeTextChanged = true; 5493 } 5494 onTextChanged(CharSequence s, int start, int before, int count)5495 public void onTextChanged(CharSequence s, int start, int before, int count) { 5496 mHasOnTextChanged = true; 5497 } 5498 } 5499 5500 /** 5501 * The listener interface for receiving mockOnLongClick events. The class 5502 * that is interested in processing a mockOnLongClick event implements this 5503 * interface, and the object created with that class is registered with a 5504 * component using the component's 5505 * <code>addMockOnLongClickListener<code> method. When 5506 * the mockOnLongClick event occurs, that object's appropriate 5507 * method is invoked. 5508 * 5509 * @see MockOnLongClickEvent 5510 */ 5511 private static class MockOnLongClickListener implements OnLongClickListener { 5512 private boolean mExpectedOnLongClickResult; 5513 private boolean mHasLongClicked; 5514 MockOnLongClickListener(boolean result)5515 MockOnLongClickListener(boolean result) { 5516 mExpectedOnLongClickResult = result; 5517 } 5518 hasLongClicked()5519 public boolean hasLongClicked() { 5520 return mHasLongClicked; 5521 } 5522 onLongClick(View v)5523 public boolean onLongClick(View v) { 5524 mHasLongClicked = true; 5525 return mExpectedOnLongClickResult; 5526 } 5527 } 5528 5529 /** 5530 * The listener interface for receiving mockOnCreateContextMenu events. The 5531 * class that is interested in processing a mockOnCreateContextMenu event 5532 * implements this interface, and the object created with that class is 5533 * registered with a component using the component's 5534 * <code>addMockOnCreateContextMenuListener<code> method. When the 5535 * mockOnCreateContextMenu event occurs, that object's appropriate method is 5536 * invoked. 5537 * 5538 * @see MockOnCreateContextMenuEvent 5539 */ 5540 private static class MockOnCreateContextMenuListener implements OnCreateContextMenuListener { 5541 private boolean mIsMenuItemsBlank; 5542 private boolean mHasCreatedContextMenu; 5543 MockOnCreateContextMenuListener(boolean isBlank)5544 MockOnCreateContextMenuListener(boolean isBlank) { 5545 this.mIsMenuItemsBlank = isBlank; 5546 } 5547 hasCreatedContextMenu()5548 public boolean hasCreatedContextMenu() { 5549 return mHasCreatedContextMenu; 5550 } 5551 reset()5552 public void reset() { 5553 mHasCreatedContextMenu = false; 5554 } 5555 onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)5556 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 5557 mHasCreatedContextMenu = true; 5558 if (!mIsMenuItemsBlank) { 5559 menu.add("menu item"); 5560 } 5561 } 5562 } 5563 5564 /** 5565 * A TextWatcher that converts the text to spaces whenever the text changes. 5566 */ 5567 private static class ConvertToSpacesTextWatcher implements TextWatcher { 5568 boolean mChangingText; 5569 5570 @Override beforeTextChanged(CharSequence s, int start, int count, int after)5571 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 5572 } 5573 5574 @Override onTextChanged(CharSequence s, int start, int before, int count)5575 public void onTextChanged(CharSequence s, int start, int before, int count) { 5576 } 5577 5578 @Override afterTextChanged(Editable s)5579 public void afterTextChanged(Editable s) { 5580 // Avoid infinite recursion. 5581 if (mChangingText) { 5582 return; 5583 } 5584 mChangingText = true; 5585 // Create a string of s.length() spaces. 5586 StringBuilder builder = new StringBuilder(s.length()); 5587 for (int i = 0; i < s.length(); i++) { 5588 builder.append(' '); 5589 } 5590 s.replace(0, s.length(), builder.toString()); 5591 mChangingText = false; 5592 } 5593 } 5594 } 5595