• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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