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