1 package org.robolectric.shadows; 2 3 import static com.google.common.truth.Truth.assertThat; 4 import static java.util.Arrays.asList; 5 import static org.junit.Assert.assertEquals; 6 import static org.junit.Assert.assertFalse; 7 import static org.junit.Assert.assertNotNull; 8 import static org.junit.Assert.assertNull; 9 import static org.junit.Assert.assertSame; 10 import static org.junit.Assert.assertTrue; 11 import static org.mockito.ArgumentMatchers.eq; 12 import static org.mockito.Mockito.mock; 13 import static org.mockito.Mockito.verify; 14 import static org.robolectric.Robolectric.buildActivity; 15 import static org.robolectric.Shadows.shadowOf; 16 17 import android.app.Activity; 18 import android.graphics.Typeface; 19 import android.text.Editable; 20 import android.text.InputFilter; 21 import android.text.InputType; 22 import android.text.Selection; 23 import android.text.Spannable; 24 import android.text.SpannableStringBuilder; 25 import android.text.TextWatcher; 26 import android.text.method.ArrowKeyMovementMethod; 27 import android.text.method.MovementMethod; 28 import android.text.method.PasswordTransformationMethod; 29 import android.text.style.URLSpan; 30 import android.text.util.Linkify; 31 import android.util.TypedValue; 32 import android.view.Gravity; 33 import android.view.KeyEvent; 34 import android.view.MotionEvent; 35 import android.view.inputmethod.EditorInfo; 36 import android.widget.FrameLayout; 37 import android.widget.TextView; 38 import androidx.test.core.app.ApplicationProvider; 39 import androidx.test.ext.junit.runners.AndroidJUnit4; 40 import java.util.ArrayList; 41 import java.util.List; 42 import java.util.Locale; 43 import java.util.Random; 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.robolectric.R; 49 import org.robolectric.android.controller.ActivityController; 50 import org.robolectric.shadow.api.Shadow; 51 52 @RunWith(AndroidJUnit4.class) 53 public class ShadowTextViewTest { 54 55 private static final String INITIAL_TEXT = "initial text"; 56 private static final String NEW_TEXT = "new text"; 57 private TextView textView; 58 private ActivityController<Activity> activityController; 59 60 @Before setUp()61 public void setUp() throws Exception { 62 activityController = buildActivity(Activity.class); 63 Activity activity = activityController.create().get(); 64 textView = new TextView(activity); 65 activity.setContentView(textView); 66 activityController.start().resume().visible(); 67 } 68 69 @Test shouldTriggerTheImeListener()70 public void shouldTriggerTheImeListener() { 71 TestOnEditorActionListener actionListener = new TestOnEditorActionListener(); 72 textView.setOnEditorActionListener(actionListener); 73 74 textView.onEditorAction(EditorInfo.IME_ACTION_GO); 75 76 assertThat(actionListener.textView).isSameInstanceAs(textView); 77 assertThat(actionListener.sentImeId).isEqualTo(EditorInfo.IME_ACTION_GO); 78 } 79 80 @Test shouldCreateGetterForEditorActionListener()81 public void shouldCreateGetterForEditorActionListener() { 82 TestOnEditorActionListener actionListener = new TestOnEditorActionListener(); 83 84 textView.setOnEditorActionListener(actionListener); 85 86 assertThat(shadowOf(textView).getOnEditorActionListener()).isSameInstanceAs(actionListener); 87 } 88 89 @Test testGetUrls()90 public void testGetUrls() { 91 Locale.setDefault(Locale.ENGLISH); 92 textView.setAutoLinkMask(Linkify.ALL); 93 textView.setText("here's some text http://google.com/\nblah\thttp://another.com/123?456 blah"); 94 95 assertThat(urlStringsFrom(textView.getUrls())).isEqualTo(asList( 96 "http://google.com", 97 "http://another.com/123?456" 98 )); 99 } 100 101 @Test testGetGravity()102 public void testGetGravity() { 103 assertThat(textView.getGravity()).isNotEqualTo(Gravity.CENTER); 104 textView.setGravity(Gravity.CENTER); 105 assertThat(textView.getGravity()).isEqualTo(Gravity.CENTER); 106 } 107 108 @Test testMovementMethod()109 public void testMovementMethod() { 110 MovementMethod movement = new ArrowKeyMovementMethod(); 111 112 assertNull(textView.getMovementMethod()); 113 textView.setMovementMethod(movement); 114 assertThat(textView.getMovementMethod()).isSameInstanceAs(movement); 115 } 116 117 @Test testLinksClickable()118 public void testLinksClickable() { 119 assertThat(textView.getLinksClickable()).isTrue(); 120 121 textView.setLinksClickable(false); 122 assertThat(textView.getLinksClickable()).isFalse(); 123 124 textView.setLinksClickable(true); 125 assertThat(textView.getLinksClickable()).isTrue(); 126 } 127 128 @Test testGetTextAppearanceId()129 public void testGetTextAppearanceId() { 130 textView.setTextAppearance( 131 ApplicationProvider.getApplicationContext(), android.R.style.TextAppearance_Small); 132 133 assertThat(shadowOf(textView).getTextAppearanceId()).isEqualTo(android.R.style.TextAppearance_Small); 134 } 135 136 @Test shouldSetTextAndTextColorWhileInflatingXmlLayout()137 public void shouldSetTextAndTextColorWhileInflatingXmlLayout() { 138 Activity activity = activityController.get(); 139 activity.setContentView(R.layout.text_views); 140 141 TextView black = activity.findViewById(R.id.black_text_view); 142 assertThat(black.getText().toString()).isEqualTo("Black Text"); 143 assertThat(black.getCurrentTextColor()).isEqualTo(0xff000000); 144 145 TextView white = activity.findViewById(R.id.white_text_view); 146 assertThat(white.getText().toString()).isEqualTo("White Text"); 147 assertThat(white.getCurrentTextColor()).isEqualTo(activity.getResources().getColor(android.R.color.white)); 148 149 TextView grey = activity.findViewById(R.id.grey_text_view); 150 assertThat(grey.getText().toString()).isEqualTo("Grey Text"); 151 assertThat(grey.getCurrentTextColor()).isEqualTo(activity.getResources().getColor(R.color.grey42)); 152 } 153 154 @Test shouldSetHintAndHintColorWhileInflatingXmlLayout()155 public void shouldSetHintAndHintColorWhileInflatingXmlLayout() { 156 Activity activity = activityController.get(); 157 activity.setContentView(R.layout.text_views_hints); 158 159 TextView black = activity.findViewById(R.id.black_text_view_hint); 160 assertThat(black.getHint().toString()).isEqualTo("Black Hint"); 161 assertThat(black.getCurrentHintTextColor()).isEqualTo(0xff000000); 162 163 TextView white = activity.findViewById(R.id.white_text_view_hint); 164 assertThat(white.getHint().toString()).isEqualTo("White Hint"); 165 assertThat(white.getCurrentHintTextColor()).isEqualTo(activity.getResources().getColor(android.R.color.white)); 166 167 TextView grey = activity.findViewById(R.id.grey_text_view_hint); 168 assertThat(grey.getHint().toString()).isEqualTo("Grey Hint"); 169 assertThat(grey.getCurrentHintTextColor()).isEqualTo(activity.getResources().getColor(R.color.grey42)); 170 } 171 172 @Test shouldNotHaveTransformationMethodByDefault()173 public void shouldNotHaveTransformationMethodByDefault() { 174 assertThat(textView.getTransformationMethod()).isNull(); 175 } 176 177 @Test shouldAllowSettingATransformationMethod()178 public void shouldAllowSettingATransformationMethod() { 179 textView.setTransformationMethod(PasswordTransformationMethod.getInstance()); 180 assertThat(textView.getTransformationMethod()).isInstanceOf(PasswordTransformationMethod.class); 181 } 182 183 @Test testGetInputType()184 public void testGetInputType() { 185 assertThat(textView.getInputType()).isNotEqualTo(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); 186 textView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); 187 assertThat(textView.getInputType()).isEqualTo(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); 188 } 189 190 @Test givenATextViewWithATextWatcherAdded_WhenSettingTextWithTextResourceId_ShouldNotifyTextWatcher()191 public void givenATextViewWithATextWatcherAdded_WhenSettingTextWithTextResourceId_ShouldNotifyTextWatcher() { 192 MockTextWatcher mockTextWatcher = new MockTextWatcher(); 193 textView.addTextChangedListener(mockTextWatcher); 194 195 textView.setText(R.string.hello); 196 197 assertEachTextWatcherEventWasInvoked(mockTextWatcher); 198 } 199 200 @Test givenATextViewWithATextWatcherAdded_WhenSettingTextWithCharSequence_ShouldNotifyTextWatcher()201 public void givenATextViewWithATextWatcherAdded_WhenSettingTextWithCharSequence_ShouldNotifyTextWatcher() { 202 MockTextWatcher mockTextWatcher = new MockTextWatcher(); 203 textView.addTextChangedListener(mockTextWatcher); 204 205 textView.setText("text"); 206 207 assertEachTextWatcherEventWasInvoked(mockTextWatcher); 208 } 209 210 @Test givenATextViewWithATextWatcherAdded_WhenSettingNullText_ShouldNotifyTextWatcher()211 public void givenATextViewWithATextWatcherAdded_WhenSettingNullText_ShouldNotifyTextWatcher() { 212 MockTextWatcher mockTextWatcher = new MockTextWatcher(); 213 textView.addTextChangedListener(mockTextWatcher); 214 215 textView.setText(null); 216 217 assertEachTextWatcherEventWasInvoked(mockTextWatcher); 218 } 219 220 @Test givenATextViewWithMultipleTextWatchersAdded_WhenSettingText_ShouldNotifyEachTextWatcher()221 public void givenATextViewWithMultipleTextWatchersAdded_WhenSettingText_ShouldNotifyEachTextWatcher() { 222 List<MockTextWatcher> mockTextWatchers = anyNumberOfTextWatchers(); 223 for (MockTextWatcher textWatcher : mockTextWatchers) { 224 textView.addTextChangedListener(textWatcher); 225 } 226 227 textView.setText("text"); 228 229 for (MockTextWatcher textWatcher : mockTextWatchers) { 230 assertEachTextWatcherEventWasInvoked(textWatcher); 231 } 232 } 233 234 @Test whenSettingText_ShouldFireBeforeTextChangedWithCorrectArguments()235 public void whenSettingText_ShouldFireBeforeTextChangedWithCorrectArguments() { 236 textView.setText(INITIAL_TEXT); 237 TextWatcher mockTextWatcher = mock(TextWatcher.class); 238 textView.addTextChangedListener(mockTextWatcher); 239 240 textView.setText(NEW_TEXT); 241 242 verify(mockTextWatcher).beforeTextChanged(INITIAL_TEXT, 0, INITIAL_TEXT.length(), NEW_TEXT.length()); 243 } 244 245 @Test whenSettingText_ShouldFireOnTextChangedWithCorrectArguments()246 public void whenSettingText_ShouldFireOnTextChangedWithCorrectArguments() { 247 textView.setText(INITIAL_TEXT); 248 TextWatcher mockTextWatcher = mock(TextWatcher.class); 249 textView.addTextChangedListener(mockTextWatcher); 250 251 textView.setText(NEW_TEXT); 252 253 ArgumentCaptor<SpannableStringBuilder> builderCaptor = ArgumentCaptor.forClass(SpannableStringBuilder.class); 254 verify(mockTextWatcher).onTextChanged(builderCaptor.capture(), eq(0), eq(INITIAL_TEXT.length()), eq(NEW_TEXT.length())); 255 assertThat(builderCaptor.getValue().toString()).isEqualTo(NEW_TEXT); 256 } 257 258 @Test whenSettingText_ShouldFireAfterTextChangedWithCorrectArgument()259 public void whenSettingText_ShouldFireAfterTextChangedWithCorrectArgument() { 260 MockTextWatcher mockTextWatcher = new MockTextWatcher(); 261 textView.addTextChangedListener(mockTextWatcher); 262 263 textView.setText(NEW_TEXT); 264 265 assertThat(mockTextWatcher.afterTextChangeArgument.toString()).isEqualTo(NEW_TEXT); 266 } 267 268 @Test whenAppendingText_ShouldAppendNewTextAfterOldOne()269 public void whenAppendingText_ShouldAppendNewTextAfterOldOne() { 270 textView.setText(INITIAL_TEXT); 271 textView.append(NEW_TEXT); 272 273 assertThat(textView.getText().toString()).isEqualTo(INITIAL_TEXT + NEW_TEXT); 274 } 275 276 @Test whenAppendingText_ShouldFireBeforeTextChangedWithCorrectArguments()277 public void whenAppendingText_ShouldFireBeforeTextChangedWithCorrectArguments() { 278 textView.setText(INITIAL_TEXT); 279 TextWatcher mockTextWatcher = mock(TextWatcher.class); 280 textView.addTextChangedListener(mockTextWatcher); 281 282 textView.append(NEW_TEXT); 283 284 verify(mockTextWatcher).beforeTextChanged(eq(INITIAL_TEXT), eq(0), eq(INITIAL_TEXT.length()), eq(INITIAL_TEXT.length())); 285 } 286 287 @Test whenAppendingText_ShouldFireOnTextChangedWithCorrectArguments()288 public void whenAppendingText_ShouldFireOnTextChangedWithCorrectArguments() { 289 textView.setText(INITIAL_TEXT); 290 TextWatcher mockTextWatcher = mock(TextWatcher.class); 291 textView.addTextChangedListener(mockTextWatcher); 292 293 textView.append(NEW_TEXT); 294 295 ArgumentCaptor<SpannableStringBuilder> builderCaptor = ArgumentCaptor.forClass(SpannableStringBuilder.class); 296 verify(mockTextWatcher).onTextChanged(builderCaptor.capture(), eq(0), eq(INITIAL_TEXT.length()), eq(INITIAL_TEXT.length())); 297 assertThat(builderCaptor.getValue().toString()).isEqualTo(INITIAL_TEXT + NEW_TEXT); 298 } 299 300 @Test whenAppendingText_ShouldFireAfterTextChangedWithCorrectArgument()301 public void whenAppendingText_ShouldFireAfterTextChangedWithCorrectArgument() { 302 textView.setText(INITIAL_TEXT); 303 MockTextWatcher mockTextWatcher = new MockTextWatcher(); 304 textView.addTextChangedListener(mockTextWatcher); 305 306 textView.append(NEW_TEXT); 307 308 assertThat(mockTextWatcher.afterTextChangeArgument.toString()).isEqualTo(INITIAL_TEXT + NEW_TEXT); 309 } 310 311 @Test removeTextChangedListener_shouldRemoveTheListener()312 public void removeTextChangedListener_shouldRemoveTheListener() { 313 MockTextWatcher watcher = new MockTextWatcher(); 314 textView.addTextChangedListener(watcher); 315 assertTrue(shadowOf(textView).getWatchers().contains(watcher)); 316 317 textView.removeTextChangedListener(watcher); 318 assertFalse(shadowOf(textView).getWatchers().contains(watcher)); 319 } 320 321 @Test getPaint_returnsMeasureTextEnabledObject()322 public void getPaint_returnsMeasureTextEnabledObject() { 323 assertThat(textView.getPaint().measureText("12345")).isEqualTo(5f); 324 } 325 326 @Test append_whenSelectionIsAtTheEnd_shouldKeepSelectionAtTheEnd()327 public void append_whenSelectionIsAtTheEnd_shouldKeepSelectionAtTheEnd() { 328 textView.setText("1", TextView.BufferType.EDITABLE); 329 Selection.setSelection(textView.getEditableText(), 0, 0); 330 textView.append("2"); 331 assertEquals(0, textView.getSelectionEnd()); 332 assertEquals(0, textView.getSelectionStart()); 333 334 Selection.setSelection(textView.getEditableText(), 2, 2); 335 textView.append("3"); 336 assertEquals(3, textView.getSelectionEnd()); 337 assertEquals(3, textView.getSelectionStart()); 338 } 339 340 @Test append_whenSelectionReachesToEnd_shouldExtendSelectionToTheEnd()341 public void append_whenSelectionReachesToEnd_shouldExtendSelectionToTheEnd() { 342 textView.setText("12", TextView.BufferType.EDITABLE); 343 Selection.setSelection(textView.getEditableText(), 0, 2); 344 textView.append("3"); 345 assertEquals(3, textView.getSelectionEnd()); 346 assertEquals(0, textView.getSelectionStart()); 347 } 348 349 @Test 350 public void testSetCompountDrawablesWithIntrinsicBounds_int_shouldCreateDrawablesWithResourceIds()351 testSetCompountDrawablesWithIntrinsicBounds_int_shouldCreateDrawablesWithResourceIds() { 352 textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.an_image, R.drawable.an_other_image, R.drawable.third_image, R.drawable.fourth_image); 353 354 assertEquals(R.drawable.an_image, shadowOf(textView.getCompoundDrawables()[0]).getCreatedFromResId()); 355 assertEquals(R.drawable.an_other_image, shadowOf(textView.getCompoundDrawables()[1]).getCreatedFromResId()); 356 assertEquals(R.drawable.third_image, shadowOf(textView.getCompoundDrawables()[2]).getCreatedFromResId()); 357 assertEquals(R.drawable.fourth_image, shadowOf(textView.getCompoundDrawables()[3]).getCreatedFromResId()); 358 } 359 360 @Test testSetCompountDrawablesWithIntrinsicBounds_int_shouldNotCreateDrawablesForZero()361 public void testSetCompountDrawablesWithIntrinsicBounds_int_shouldNotCreateDrawablesForZero() { 362 textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); 363 364 assertNull(textView.getCompoundDrawables()[0]); 365 assertNull(textView.getCompoundDrawables()[1]); 366 assertNull(textView.getCompoundDrawables()[2]); 367 assertNull(textView.getCompoundDrawables()[3]); 368 } 369 370 @Test canSetAndGetTypeface()371 public void canSetAndGetTypeface() { 372 Typeface typeface = Shadow.newInstanceOf(Typeface.class); 373 textView.setTypeface(typeface); 374 assertSame(typeface, textView.getTypeface()); 375 } 376 377 @Test onTouchEvent_shouldCallMovementMethodOnTouchEventWithSetMotionEvent()378 public void onTouchEvent_shouldCallMovementMethodOnTouchEventWithSetMotionEvent() { 379 TestMovementMethod testMovementMethod = new TestMovementMethod(); 380 textView.setMovementMethod(testMovementMethod); 381 textView.setLayoutParams(new FrameLayout.LayoutParams(100, 100)); 382 textView.measure(100, 100); 383 384 MotionEvent event = MotionEvent.obtain(0, 0, 0, 0, 0, 0); 385 textView.dispatchTouchEvent(event); 386 387 assertEquals(testMovementMethod.event, event); 388 } 389 390 @Test testGetError()391 public void testGetError() { 392 assertNull(textView.getError()); 393 CharSequence error = "myError"; 394 textView.setError(error); 395 assertEquals(error.toString(), textView.getError().toString()); 396 } 397 398 @Test canSetAndGetInputFilters()399 public void canSetAndGetInputFilters() { 400 final InputFilter[] expectedFilters = new InputFilter[]{new InputFilter.LengthFilter(1)}; 401 textView.setFilters(expectedFilters); 402 assertThat(textView.getFilters()).isSameInstanceAs(expectedFilters); 403 } 404 405 @Test testHasSelectionReturnsTrue()406 public void testHasSelectionReturnsTrue() { 407 textView.setText("1", TextView.BufferType.SPANNABLE); 408 textView.onTextContextMenuItem(android.R.id.selectAll); 409 assertTrue(textView.hasSelection()); 410 } 411 412 @Test testHasSelectionReturnsFalse()413 public void testHasSelectionReturnsFalse() { 414 textView.setText("1", TextView.BufferType.SPANNABLE); 415 assertFalse(textView.hasSelection()); 416 } 417 418 @Test whenSettingTextToNull_WatchersSeeEmptyString()419 public void whenSettingTextToNull_WatchersSeeEmptyString() { 420 TextWatcher mockTextWatcher = mock(TextWatcher.class); 421 textView.addTextChangedListener(mockTextWatcher); 422 423 textView.setText(null); 424 425 ArgumentCaptor<SpannableStringBuilder> builderCaptor = ArgumentCaptor.forClass(SpannableStringBuilder.class); 426 verify(mockTextWatcher).onTextChanged(builderCaptor.capture(), eq(0), eq(0), eq(0)); 427 assertThat(builderCaptor.getValue().toString()).isEmpty(); 428 } 429 430 @Test getPaint_returnsNonNull()431 public void getPaint_returnsNonNull() { 432 assertNotNull(textView.getPaint()); 433 } 434 435 @Test testNoArgAppend()436 public void testNoArgAppend() { 437 textView.setText("a"); 438 textView.append("b"); 439 assertThat(textView.getText().toString()).isEqualTo("ab"); 440 } 441 442 @Test setTextSize_shouldHandleDips()443 public void setTextSize_shouldHandleDips() { 444 textView.getContext().getResources().getDisplayMetrics().density = 1.5f; 445 textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10); 446 assertThat(textView.getTextSize()).isEqualTo(15f); 447 textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); 448 assertThat(textView.getTextSize()).isEqualTo(30f); 449 } 450 451 @Test setTextSize_shouldHandleSp()452 public void setTextSize_shouldHandleSp() { 453 textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10); 454 assertThat(textView.getTextSize()).isEqualTo(10f); 455 456 textView.getContext().getResources().getDisplayMetrics().scaledDensity = 1.5f; 457 458 textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10); 459 assertThat(textView.getTextSize()).isEqualTo(15f); 460 } 461 462 @Test setTextSize_shouldHandlePixels()463 public void setTextSize_shouldHandlePixels() { 464 textView.getContext().getResources().getDisplayMetrics().density = 1.5f; 465 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 10); 466 assertThat(textView.getTextSize()).isEqualTo(10f); 467 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20); 468 assertThat(textView.getTextSize()).isEqualTo(20f); 469 } 470 471 @Test getPaintFlagsAndSetPaintFlags_shouldWork()472 public void getPaintFlagsAndSetPaintFlags_shouldWork() { 473 textView.setPaintFlags(100); 474 assertThat(textView.getPaintFlags()).isEqualTo(100); 475 } 476 477 @Test setCompoundDrawablesWithIntrinsicBounds_setsValues()478 public void setCompoundDrawablesWithIntrinsicBounds_setsValues() { 479 textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.l0_red, R.drawable.l1_orange, R.drawable.l2_yellow, R.drawable.l3_green); 480 assertThat(shadowOf(textView).getCompoundDrawablesWithIntrinsicBoundsLeft()).isEqualTo(R.drawable.l0_red); 481 assertThat(shadowOf(textView).getCompoundDrawablesWithIntrinsicBoundsTop()).isEqualTo(R.drawable.l1_orange); 482 assertThat(shadowOf(textView).getCompoundDrawablesWithIntrinsicBoundsRight()).isEqualTo(R.drawable.l2_yellow); 483 assertThat(shadowOf(textView).getCompoundDrawablesWithIntrinsicBoundsBottom()).isEqualTo(R.drawable.l3_green); 484 } 485 anyNumberOfTextWatchers()486 private List<MockTextWatcher> anyNumberOfTextWatchers() { 487 List<MockTextWatcher> mockTextWatchers = new ArrayList<>(); 488 int numberBetweenOneAndTen = new Random().nextInt(10) + 1; 489 for (int i = 0; i < numberBetweenOneAndTen; i++) { 490 mockTextWatchers.add(new MockTextWatcher()); 491 } 492 return mockTextWatchers; 493 } 494 assertEachTextWatcherEventWasInvoked(MockTextWatcher mockTextWatcher)495 private void assertEachTextWatcherEventWasInvoked(MockTextWatcher mockTextWatcher) { 496 assertTrue("Expected each TextWatcher event to" 497 + " have" 498 + " been" 499 + " invoked" 500 + " once", mockTextWatcher.methodsCalled.size() == 3); 501 502 assertThat(mockTextWatcher.methodsCalled.get(0)).isEqualTo("beforeTextChanged"); 503 assertThat(mockTextWatcher.methodsCalled.get(1)).isEqualTo("onTextChanged"); 504 assertThat(mockTextWatcher.methodsCalled.get(2)).isEqualTo("afterTextChanged"); 505 } 506 urlStringsFrom(URLSpan[] urlSpans)507 private List<String> urlStringsFrom(URLSpan[] urlSpans) { 508 List<String> urls = new ArrayList<>(); 509 for (URLSpan urlSpan : urlSpans) { 510 urls.add(urlSpan.getURL()); 511 } 512 return urls; 513 } 514 515 private static class TestOnEditorActionListener implements TextView.OnEditorActionListener { 516 private TextView textView; 517 private int sentImeId; 518 519 @Override onEditorAction(TextView textView, int sentImeId, KeyEvent keyEvent)520 public boolean onEditorAction(TextView textView, int sentImeId, KeyEvent keyEvent) { 521 this.textView = textView; 522 this.sentImeId = sentImeId; 523 return false; 524 } 525 } 526 527 private static class MockTextWatcher implements TextWatcher { 528 529 List<String> methodsCalled = new ArrayList<>(); 530 Editable afterTextChangeArgument; 531 532 @Override beforeTextChanged(CharSequence s, int start, int count, int after)533 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 534 methodsCalled.add("beforeTextChanged"); 535 } 536 537 @Override onTextChanged(CharSequence s, int start, int before, int count)538 public void onTextChanged(CharSequence s, int start, int before, int count) { 539 methodsCalled.add("onTextChanged"); 540 } 541 542 @Override afterTextChanged(Editable s)543 public void afterTextChanged(Editable s) { 544 methodsCalled.add("afterTextChanged"); 545 afterTextChangeArgument = s; 546 } 547 548 } 549 550 private static class TestMovementMethod implements MovementMethod { 551 public MotionEvent event; 552 553 @Override initialize(TextView widget, Spannable text)554 public void initialize(TextView widget, Spannable text) {} 555 556 @Override onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event)557 public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) { 558 return false; 559 } 560 561 @Override onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event)562 public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) { 563 return false; 564 } 565 566 @Override onKeyOther(TextView view, Spannable text, KeyEvent event)567 public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) { 568 return false; 569 } 570 571 @Override onTakeFocus(TextView widget, Spannable text, int direction)572 public void onTakeFocus(TextView widget, Spannable text, int direction) { 573 } 574 575 @Override onTrackballEvent(TextView widget, Spannable text, MotionEvent event)576 public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) { 577 return false; 578 } 579 580 @Override onTouchEvent(TextView widget, Spannable text, MotionEvent event)581 public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event) { 582 this.event = event; 583 return false; 584 } 585 586 @Override canSelectArbitrarily()587 public boolean canSelectArbitrarily() { 588 return false; 589 } 590 591 @Override onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event)592 public boolean onGenericMotionEvent(TextView widget, Spannable text, 593 MotionEvent event) { 594 return false; 595 } 596 } 597 } 598