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.widget.cts.R;
20 
21 
22 import org.xmlpull.v1.XmlPullParser;
23 import org.xmlpull.v1.XmlPullParserException;
24 
25 import android.app.Activity;
26 import android.app.Instrumentation;
27 import android.app.UiModeManager;
28 import android.content.Context;
29 import android.content.res.Configuration;
30 import android.cts.util.PollingCheck;
31 import android.graphics.Rect;
32 import android.test.ActivityInstrumentationTestCase2;
33 import android.test.UiThreadTest;
34 import android.util.AttributeSet;
35 import android.util.Xml;
36 import android.view.KeyCharacterMap;
37 import android.view.KeyEvent;
38 import android.view.View;
39 import android.view.ViewGroup;
40 import android.widget.AdapterView;
41 import android.widget.ArrayAdapter;
42 import android.widget.AutoCompleteTextView;
43 import android.widget.Filter;
44 import android.widget.Filterable;
45 import android.widget.AutoCompleteTextView.Validator;
46 
47 import java.io.IOException;
48 
49 public class AutoCompleteTextViewTest extends
50         ActivityInstrumentationTestCase2<AutoCompleteCtsActivity> {
51 
52     /**
53      * Instantiates a new text view test.
54      */
AutoCompleteTextViewTest()55     public AutoCompleteTextViewTest() {
56         super("android.widget.cts", AutoCompleteCtsActivity.class);
57     }
58 
59     /** The m activity. */
60     private Activity mActivity;
61 
62     /** The m instrumentation. */
63     private Instrumentation mInstrumentation;
64     private AutoCompleteTextView mAutoCompleteTextView;
65     private boolean mNumeric = false;
66     ArrayAdapter<String> mAdapter;
67     private final String[] WORDS = new String[] { "testOne", "testTwo", "testThree", "testFour" };
68     boolean isOnFilterComplete = false;
69     final String STRING_TEST = "To be tested";
70     final String STRING_VALIDATED = "String Validated";
71     final String STRING_CHECK = "To be checked";
72     final String STRING_APPEND = "and be appended";
73     Validator mValidator = new Validator() {
74         public CharSequence fixText(CharSequence invalidText) {
75             return STRING_VALIDATED;
76         }
77 
78         public boolean isValid(CharSequence text) {
79             return false;
80         }
81     };
82 
83     /*
84      * (non-Javadoc)
85      *
86      * @see android.test.ActivityInstrumentationTestCase#setUp()
87      */
88     @Override
setUp()89     protected void setUp() throws Exception {
90         super.setUp();
91         mActivity = getActivity();
92         new PollingCheck() {
93             @Override
94                 protected boolean check() {
95                 return mActivity.hasWindowFocus();
96             }
97         }.run();
98         mInstrumentation = getInstrumentation();
99         mAutoCompleteTextView = (AutoCompleteTextView) mActivity
100                 .findViewById(R.id.autocompletetv_edit);
101         mAdapter = new ArrayAdapter<String>(mActivity,
102                 android.R.layout.simple_dropdown_item_1line, WORDS);
103         KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
104         if (keymap.getKeyboardType() == KeyCharacterMap.NUMERIC) {
105             mNumeric = true;
106         }
107     }
108 
isTvMode()109     boolean isTvMode() {
110         UiModeManager uiModeManager = (UiModeManager) getActivity().getSystemService(
111                 Context.UI_MODE_SERVICE);
112         return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
113     }
114 
115     @UiThreadTest
testConstructor()116     public void testConstructor() {
117         XmlPullParser parser;
118 
119         // new the AutoCompleteTextView instance
120         new AutoCompleteTextView(mActivity);
121 
122         // new the AutoCompleteTextView instance
123         parser = mActivity.getResources().getXml(R.layout.simple_dropdown_item_1line);
124         AttributeSet attributeSet = Xml.asAttributeSet(parser);
125         new AutoCompleteTextView(mActivity, attributeSet);
126         new AutoCompleteTextView(mActivity, null);
127 
128         // new the AutoCompleteTextView instance
129         parser = mActivity.getResources().getXml(R.layout.framelayout_layout);
130         attributeSet = Xml.asAttributeSet(parser);
131         new AutoCompleteTextView(mActivity, attributeSet, 0);
132         new AutoCompleteTextView(mActivity, null, 0);
133         // Test constructor with null Context, in fact, previous two functions will
134         // finally invoke this version.
135         try {
136             // Test with null Context
137             new AutoCompleteTextView(null, attributeSet, 0);
138             fail("should throw NullPointerException");
139         } catch (Exception e) {
140         }
141 
142         // Test for negative style resource ID
143         new AutoCompleteTextView(mActivity, attributeSet, -1);
144         // Test null AttributeSet
145         new AutoCompleteTextView(mActivity, null, -1);
146     }
147 
testEnoughToFilter()148     public void testEnoughToFilter() throws Throwable {
149         mAutoCompleteTextView.setThreshold(3);
150         assertEquals(3, mAutoCompleteTextView.getThreshold());
151 
152         runTestOnUiThread(new Runnable() {
153             public void run() {
154                 String testString = "TryToTest";
155                 mAutoCompleteTextView.setText(testString);
156             }
157         });
158         mInstrumentation.waitForIdleSync();
159         assertTrue(mAutoCompleteTextView.enoughToFilter());
160 
161         runTestOnUiThread(new Runnable() {
162             public void run() {
163                 String testString = "No";
164                 mAutoCompleteTextView.setText(testString);
165             }
166         });
167         mInstrumentation.waitForIdleSync();
168         assertFalse(mAutoCompleteTextView.enoughToFilter());
169     }
170 
171     @UiThreadTest
testAccessAdapter()172     public void testAccessAdapter() {
173         MockAutoCompleteTextView autoCompleteTextView = new MockAutoCompleteTextView(mActivity);
174 
175         // Set Threshold to 4 characters
176         autoCompleteTextView.setThreshold(4);
177 
178         ArrayAdapter<String> adapter = null;
179         autoCompleteTextView.setAdapter(adapter);
180         assertNull(autoCompleteTextView.getAdapter());
181         assertNull(autoCompleteTextView.getFilter());
182 
183         Filter filter = mAdapter.getFilter();
184         assertNotNull(filter);
185         autoCompleteTextView.setAdapter(mAdapter);
186         assertSame(mAdapter, autoCompleteTextView.getAdapter());
187         assertSame(filter, autoCompleteTextView.getFilter());
188 
189         // Re-set adapter to null
190         autoCompleteTextView.setAdapter(adapter);
191         assertNull(autoCompleteTextView.getAdapter());
192         assertNull(autoCompleteTextView.getFilter());
193     }
194 
195     @SuppressWarnings("deprecation")
testAccessItemClickListener()196     public void testAccessItemClickListener() {
197         final MockOnItemClickListener testOnItemClickListener = new MockOnItemClickListener();
198 
199         // To ensure null listener
200         mAutoCompleteTextView.setOnItemClickListener(null);
201         assertNull(mAutoCompleteTextView.getItemClickListener());
202         assertNull(mAutoCompleteTextView.getOnItemClickListener());
203 
204         assertNotNull(testOnItemClickListener);
205         mAutoCompleteTextView.setOnItemClickListener(testOnItemClickListener);
206         assertSame(testOnItemClickListener, mAutoCompleteTextView.getItemClickListener());
207         assertSame(testOnItemClickListener, mAutoCompleteTextView.getOnItemClickListener());
208 
209         // re-clear listener by setOnItemClickListener
210         mAutoCompleteTextView.setOnItemClickListener(null);
211         assertNull(mAutoCompleteTextView.getItemClickListener());
212         assertNull(mAutoCompleteTextView.getOnItemClickListener());
213     }
214 
215     @SuppressWarnings("deprecation")
testAccessItemSelectedListener()216     public void testAccessItemSelectedListener() {
217         MockOnItemSelectedListener testOnItemSelectedListener = new MockOnItemSelectedListener();
218 
219         // To ensure null listener
220         mAutoCompleteTextView.setOnItemSelectedListener(null);
221         assertNull(mAutoCompleteTextView.getItemSelectedListener());
222         assertNull(mAutoCompleteTextView.getOnItemSelectedListener());
223 
224         assertNotNull(testOnItemSelectedListener);
225         mAutoCompleteTextView.setOnItemSelectedListener(testOnItemSelectedListener);
226         assertSame(testOnItemSelectedListener, mAutoCompleteTextView.getItemSelectedListener());
227         assertSame(testOnItemSelectedListener, mAutoCompleteTextView.getOnItemSelectedListener());
228 
229         //re-clear listener by setOnItemClickListener
230         mAutoCompleteTextView.setOnItemSelectedListener(null);
231         assertNull(mAutoCompleteTextView.getItemSelectedListener());
232         assertNull(mAutoCompleteTextView.getOnItemSelectedListener());
233     }
234 
235     @UiThreadTest
testConvertSelectionToString()236     public void testConvertSelectionToString() {
237         MockAutoCompleteTextView autoCompleteTextView = new MockAutoCompleteTextView(mActivity);
238 
239         // Set Threshold to 4 characters
240         autoCompleteTextView.setThreshold(4);
241         autoCompleteTextView.setAdapter(mAdapter);
242         assertNotNull(autoCompleteTextView.getAdapter());
243 
244         assertEquals("", autoCompleteTextView.convertSelectionToString(null));
245         assertEquals(STRING_TEST, autoCompleteTextView.convertSelectionToString(STRING_TEST));
246     }
247 
248     @UiThreadTest
testOnTextChanged()249     public void testOnTextChanged() {
250         MockAutoCompleteTextView autoCompleteTextView = new MockAutoCompleteTextView(mActivity);
251 
252         assertFalse(autoCompleteTextView.isOnTextChanged());
253         assertEquals("", autoCompleteTextView.getLastChangeText());
254         assertEquals("", autoCompleteTextView.getText().toString());
255         assertEquals(0, autoCompleteTextView.getStart());
256         assertEquals(0, autoCompleteTextView.getBefore());
257         assertEquals(0, autoCompleteTextView.getAfter());
258 
259         autoCompleteTextView.setText(STRING_TEST);
260         assertEquals(STRING_TEST, autoCompleteTextView.getText().toString());
261         assertTrue(autoCompleteTextView.isOnTextChanged());
262         assertEquals(STRING_TEST, autoCompleteTextView.getLastChangeText());
263         assertEquals(0, autoCompleteTextView.getStart());
264         assertEquals(0, autoCompleteTextView.getBefore());
265         assertEquals(STRING_TEST.length(), autoCompleteTextView.getAfter());
266 
267         // Test replacing text.
268         autoCompleteTextView.resetStatus();
269         autoCompleteTextView.setText(STRING_CHECK);
270         assertEquals(STRING_CHECK, autoCompleteTextView.getText().toString());
271         assertEquals(STRING_CHECK, autoCompleteTextView.getLastChangeText());
272         assertEquals(0, autoCompleteTextView.getStart());
273         assertEquals(STRING_TEST.length(), autoCompleteTextView.getBefore());
274         assertEquals(STRING_CHECK.length(), autoCompleteTextView.getAfter());
275     }
276 
277     @UiThreadTest
testPopupWindow()278     public void testPopupWindow() throws XmlPullParserException, IOException {
279         assertFalse(mAutoCompleteTextView.isPopupShowing());
280         mAutoCompleteTextView.showDropDown();
281         assertTrue(mAutoCompleteTextView.isPopupShowing());
282 
283         mAutoCompleteTextView.dismissDropDown();
284         assertFalse(mAutoCompleteTextView.isPopupShowing());
285 
286         mAutoCompleteTextView.showDropDown();
287         assertTrue(mAutoCompleteTextView.isPopupShowing());
288 
289         final MockValidator validator = new MockValidator();
290         mAutoCompleteTextView.setValidator(validator);
291         mAutoCompleteTextView.requestFocus();
292         mAutoCompleteTextView.showDropDown();
293         assertTrue(mAutoCompleteTextView.isPopupShowing());
294         mAutoCompleteTextView.setText(STRING_TEST);
295         assertEquals(STRING_TEST, mAutoCompleteTextView.getText().toString());
296         // clearFocus will trigger onFocusChanged, and onFocusChanged will validate the text.
297         mAutoCompleteTextView.clearFocus();
298         assertFalse(mAutoCompleteTextView.isPopupShowing());
299         assertEquals(STRING_VALIDATED, mAutoCompleteTextView.getText().toString());
300     }
301 
302     @UiThreadTest
testReplaceText()303     public void testReplaceText() {
304         MockAutoCompleteTextView autoCompleteTextView = new MockAutoCompleteTextView(mActivity);
305 
306         assertEquals("", autoCompleteTextView.getText().toString());
307         assertFalse(autoCompleteTextView.isOnTextChanged());
308         autoCompleteTextView.replaceText("Text");
309         assertEquals("Text", autoCompleteTextView.getText().toString());
310         assertTrue(autoCompleteTextView.isOnTextChanged());
311 
312         autoCompleteTextView.resetStatus();
313         assertFalse(autoCompleteTextView.isOnTextChanged());
314         autoCompleteTextView.replaceText("Another");
315         assertEquals("Another", autoCompleteTextView.getText().toString());
316         assertTrue(autoCompleteTextView.isOnTextChanged());
317     }
318 
319     @UiThreadTest
testSetFrame()320     public void testSetFrame() {
321         MockAutoCompleteTextView autoCompleteTextView = new MockAutoCompleteTextView(mActivity);
322 
323         assertTrue(autoCompleteTextView.setFrame(0, 1, 2, 3));
324         assertEquals(0, autoCompleteTextView.getLeft());
325         assertEquals(1, autoCompleteTextView.getTop());
326         assertEquals(2, autoCompleteTextView.getRight());
327         assertEquals(3, autoCompleteTextView.getBottom());
328 
329         // If the values are the same as old ones, function will return false
330         assertFalse(autoCompleteTextView.setFrame(0, 1, 2, 3));
331         assertEquals(0, autoCompleteTextView.getLeft());
332         assertEquals(1, autoCompleteTextView.getTop());
333         assertEquals(2, autoCompleteTextView.getRight());
334         assertEquals(3, autoCompleteTextView.getBottom());
335 
336         // If the values are not the same as old ones, function will return true
337         assertTrue(autoCompleteTextView.setFrame(2, 3, 4, 5));
338         assertEquals(2, autoCompleteTextView.getLeft());
339         assertEquals(3, autoCompleteTextView.getTop());
340         assertEquals(4, autoCompleteTextView.getRight());
341         assertEquals(5, autoCompleteTextView.getBottom());
342     }
343 
testGetThreshold()344     public void testGetThreshold() {
345         final AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) mActivity
346                 .findViewById(R.id.autocompletetv_edit);
347         assertNotNull(autoCompleteTextView);
348 
349         assertEquals(1, autoCompleteTextView.getThreshold());
350         autoCompleteTextView.setThreshold(3);
351         assertEquals(3, autoCompleteTextView.getThreshold());
352 
353         // Test negative value input
354         autoCompleteTextView.setThreshold(-5);
355         assertEquals(1, autoCompleteTextView.getThreshold());
356 
357         // Test zero
358         autoCompleteTextView.setThreshold(0);
359         assertEquals(1, autoCompleteTextView.getThreshold());
360     }
361 
testAccessValidater()362     public void testAccessValidater() {
363         final MockValidator validator = new MockValidator();
364 
365         assertNull(mAutoCompleteTextView.getValidator());
366         mAutoCompleteTextView.setValidator(validator);
367         assertSame(validator, mAutoCompleteTextView.getValidator());
368 
369         // Set to null
370         mAutoCompleteTextView.setValidator(null);
371         assertNull(mAutoCompleteTextView.getValidator());
372     }
373 
testOnFilterComplete()374     public void testOnFilterComplete() throws Throwable {
375         // Set Threshold to 4 characters
376         mAutoCompleteTextView.setThreshold(4);
377 
378         String testString = "";
379         if (mNumeric) {
380             // "tes" in case of 12-key(NUMERIC) keyboard
381             testString = "8337777";
382         } else {
383             testString = "tes";
384         }
385 
386         // Test the filter if the input string is not long enough to threshold
387         runTestOnUiThread(new Runnable() {
388             public void run() {
389                 mAutoCompleteTextView.setAdapter(mAdapter);
390                 mAutoCompleteTextView.setText("");
391                 mAutoCompleteTextView.requestFocus();
392             }
393         });
394         mInstrumentation.sendStringSync(testString);
395 
396         // onFilterComplete will close the popup.
397         new PollingCheck() {
398             @Override
399             protected boolean check() {
400                 return !mAutoCompleteTextView.isPopupShowing();
401             }
402         }.run();
403 
404         if (mNumeric) {
405             // "that" in case of 12-key(NUMERIC) keyboard
406             testString = "84428";
407         } else {
408             testString = "that";
409         }
410         mInstrumentation.sendStringSync(testString);
411         new PollingCheck() {
412             @Override
413             protected boolean check() {
414                 return !mAutoCompleteTextView.isPopupShowing();
415             }
416         }.run();
417 
418         // Test the expected filter matching scene
419         runTestOnUiThread(new Runnable() {
420             public void run() {
421                 mAutoCompleteTextView.setFocusable(true);
422                 mAutoCompleteTextView.requestFocus();
423                 mAutoCompleteTextView.setText("");
424             }
425         });
426         if (mNumeric) {
427             // "test" in case of 12-key(NUMERIC) keyboard
428             mInstrumentation.sendStringSync("83377778");
429         } else {
430             mInstrumentation.sendStringSync("test");
431         }
432         assertTrue(mAutoCompleteTextView.hasFocus());
433         assertTrue(mAutoCompleteTextView.hasWindowFocus());
434         new PollingCheck() {
435             @Override
436             protected boolean check() {
437                 return mAutoCompleteTextView.isPopupShowing();
438             }
439         }.run();
440     }
441 
testPerformFiltering()442     public void testPerformFiltering() throws Throwable {
443         if (isTvMode()) {
444             return;
445         }
446         runTestOnUiThread(new Runnable() {
447             public void run() {
448                 mAutoCompleteTextView.setAdapter(mAdapter);
449                 mAutoCompleteTextView.setValidator(mValidator);
450 
451                 mAutoCompleteTextView.setText("test");
452                 mAutoCompleteTextView.setFocusable(true);
453                 mAutoCompleteTextView.requestFocus();
454                 mAutoCompleteTextView.showDropDown();
455             }
456         });
457         mInstrumentation.waitForIdleSync();
458         assertTrue(mAutoCompleteTextView.isPopupShowing());
459 
460         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
461         // KeyBack will close the popup.
462         assertFalse(mAutoCompleteTextView.isPopupShowing());
463 
464         runTestOnUiThread(new Runnable() {
465             public void run() {
466                 mAutoCompleteTextView.dismissDropDown();
467                 mAutoCompleteTextView.setText(STRING_TEST);
468             }
469         });
470         mInstrumentation.waitForIdleSync();
471 
472         assertEquals(STRING_TEST, mAutoCompleteTextView.getText().toString());
473         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
474         // If the popup is closed, onKeyDown will invoke performValidation.
475         assertEquals(STRING_VALIDATED, mAutoCompleteTextView.getText().toString());
476 
477         final MockAdapter<String> adapter = new MockAdapter<String>(mActivity,
478                 android.R.layout.simple_dropdown_item_1line, WORDS);
479 
480         // Set Threshold to 4 charactersonKeyDown
481         runTestOnUiThread(new Runnable() {
482             public void run() {
483                 mAutoCompleteTextView.setAdapter(adapter);
484                 mAutoCompleteTextView.requestFocus();
485                 mAutoCompleteTextView.setText("");
486             }
487         });
488         mInstrumentation.waitForIdleSync();
489         // Create and get the filter.
490         final MockFilter filter = (MockFilter) adapter.getFilter();
491 
492         // performFiltering will be indirectly invoked by onKeyDown
493         assertNull(filter.getResult());
494         // 12-key support
495         if (mNumeric) {
496             // "numeric" in case of 12-key(NUMERIC) keyboard
497             mInstrumentation.sendStringSync("6688633777444222");
498             new PollingCheck() {
499                 @Override
500                 protected boolean check() {
501                     return "numeric".equals(filter.getResult());
502                 }
503             }.run();
504         } else {
505             Thread.sleep(200);
506             mInstrumentation.sendStringSync(STRING_TEST);
507             new PollingCheck() {
508                 @Override
509                 protected boolean check() {
510                     return STRING_TEST.equals(filter.getResult());
511                 }
512             }.run();
513         }
514     }
515 
testPerformCompletion()516     public void testPerformCompletion() throws Throwable {
517         if (isTvMode()) {
518             return;
519         }
520         final MockOnItemClickListener listener = new MockOnItemClickListener();
521         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
522 
523         runTestOnUiThread(new Runnable() {
524             public void run() {
525                 mAutoCompleteTextView.setOnItemClickListener(listener);
526                 mAutoCompleteTextView.setAdapter(mAdapter);
527                 mAutoCompleteTextView.requestFocus();
528                 mAutoCompleteTextView.showDropDown();
529             }
530         });
531         mInstrumentation.waitForIdleSync();
532         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
533 
534         // Key is ENTER or DPAD_ENTER, will invoke completion
535         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
536         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
537         mInstrumentation.waitForIdleSync();
538         assertTrue(listener.isOnItemClicked());
539 
540         assertEquals(WORDS[0], mAutoCompleteTextView.getText().toString());
541 
542         // re-set 'clicked' flag to false
543         listener.clearItemClickedStatus();
544 
545         runTestOnUiThread(new Runnable() {
546             public void run() {
547                 mAutoCompleteTextView.showDropDown();
548             }
549         });
550         mInstrumentation.waitForIdleSync();
551         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
552         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
553         assertTrue(listener.isOnItemClicked());
554         assertEquals(WORDS[0], mAutoCompleteTextView.getText().toString());
555         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
556 
557         listener.clearItemClickedStatus();
558         runTestOnUiThread(new Runnable() {
559             public void run() {
560                 mAutoCompleteTextView.showDropDown();
561             }
562         });
563         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
564         // Test normal key code.
565         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
566         assertFalse(listener.isOnItemClicked());
567         assertNotSame("", mAutoCompleteTextView.getText().toString());
568         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
569 
570         listener.clearItemClickedStatus();
571 
572         // Test the method on the scene of popup is closed.
573         runTestOnUiThread(new Runnable() {
574             public void run() {
575                mAutoCompleteTextView.dismissDropDown();
576             }
577         });
578 
579         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
580         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
581         assertFalse(listener.isOnItemClicked());
582         assertNotSame("", mAutoCompleteTextView.getText().toString());
583         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
584     }
585 
586     @UiThreadTest
testPerformValidation()587     public void testPerformValidation() {
588         final CharSequence text = "this";
589 
590         mAutoCompleteTextView.setValidator(mValidator);
591         mAutoCompleteTextView.setAdapter((ArrayAdapter<String>) null);
592         mAutoCompleteTextView.setText(text);
593         mAutoCompleteTextView.performValidation();
594 
595         assertEquals(STRING_VALIDATED, mAutoCompleteTextView.getText().toString());
596         mAutoCompleteTextView.setValidator(null);
597     }
598 
testSetCompletionHint()599     public void testSetCompletionHint() {
600         mAutoCompleteTextView.setCompletionHint("TEST HINT");
601     }
602 
testOnAttachedToWindow()603     public void testOnAttachedToWindow() {
604         // implement details, do not test
605     }
606 
testOnCommitCompletion()607     public void testOnCommitCompletion() {
608         // implement details, do not test
609     }
610 
testOnDetachedFromWindow()611     public void testOnDetachedFromWindow() {
612         // implement details, do not test
613     }
614 
testOnKeyPreIme()615     public void testOnKeyPreIme() {
616         // implement details, do not test
617     }
618 
testAccessListSelection()619     public void testAccessListSelection() throws Throwable {
620         final MockOnItemClickListener listener = new MockOnItemClickListener();
621 
622         runTestOnUiThread(new Runnable() {
623             public void run() {
624                 mAutoCompleteTextView.setOnItemClickListener(listener);
625                 mAutoCompleteTextView.setAdapter(mAdapter);
626                 mAutoCompleteTextView.requestFocus();
627                 mAutoCompleteTextView.showDropDown();
628             }
629         });
630         mInstrumentation.waitForIdleSync();
631 
632         runTestOnUiThread(new Runnable() {
633             public void run() {
634                 mAutoCompleteTextView.setListSelection(1);
635                 assertEquals(1, mAutoCompleteTextView.getListSelection());
636 
637                 mAutoCompleteTextView.setListSelection(2);
638                 assertEquals(2, mAutoCompleteTextView.getListSelection());
639 
640                 mAutoCompleteTextView.clearListSelection();
641                 assertEquals(2, mAutoCompleteTextView.getListSelection());
642             }
643         });
644         mInstrumentation.waitForIdleSync();
645     }
646 
testAccessDropDownAnchor()647     public void testAccessDropDownAnchor() {
648         mAutoCompleteTextView.setDropDownAnchor(View.NO_ID);
649         assertEquals(View.NO_ID, mAutoCompleteTextView.getDropDownAnchor());
650 
651         mAutoCompleteTextView.setDropDownAnchor(0x5555);
652         assertEquals(0x5555, mAutoCompleteTextView.getDropDownAnchor());
653     }
654 
testAccessDropDownWidth()655     public void testAccessDropDownWidth() {
656         mAutoCompleteTextView.setDropDownWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
657         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, mAutoCompleteTextView.getDropDownWidth());
658 
659         mAutoCompleteTextView.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
660         assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, mAutoCompleteTextView.getDropDownWidth());
661     }
662 
663     private static class MockOnItemClickListener implements AdapterView.OnItemClickListener {
664         private boolean mOnItemClickedFlag = false;
665 
onItemClick(AdapterView<?> parent, View view, int position, long id)666         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
667             mOnItemClickedFlag = true;
668             return;
669         }
670 
isOnItemClicked()671         public boolean isOnItemClicked() {
672             return mOnItemClickedFlag;
673         }
674 
clearItemClickedStatus()675         public void clearItemClickedStatus() {
676             mOnItemClickedFlag = false;
677         }
678     }
679 
680     private static class MockOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
onItemSelected(AdapterView<?> parent, View view, int position, long id)681         public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
682             return;
683         }
684 
onNothingSelected(AdapterView<?> parent)685         public void onNothingSelected(AdapterView<?> parent) {
686             return;
687         }
688     }
689 
690     private class MockValidator implements AutoCompleteTextView.Validator {
fixText(CharSequence invalidText)691         public CharSequence fixText(CharSequence invalidText) {
692             return STRING_VALIDATED;
693         }
694 
isValid(CharSequence text)695         public boolean isValid(CharSequence text) {
696             if (text == STRING_TEST) {
697                 return true;
698             }
699             return false;
700         }
701     }
702 
703     private static class MockAutoCompleteTextView extends AutoCompleteTextView {
704         private boolean mOnTextChangedFlag = false;
705         private boolean mOnFilterCompleteFlag = false;
706         private String lastChangeText = "";
707         private int mStart = 0;
708         private int mBefore = 0;
709         private int mAfter = 0;
710 
resetStatus()711         public void resetStatus() {
712             mOnTextChangedFlag = false;
713             mOnFilterCompleteFlag = false;
714             mStart = 0;
715             mBefore = 0;
716             mAfter = 0;
717         }
718 
MockAutoCompleteTextView(Context context)719         public MockAutoCompleteTextView(Context context) {
720             super(context);
721             resetStatus();
722         }
723 
MockAutoCompleteTextView(Context context, AttributeSet attrs)724         public MockAutoCompleteTextView(Context context, AttributeSet attrs) {
725             super(context, attrs);
726         }
727 
MockAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle)728         protected MockAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
729             super(context, attrs, defStyle);
730         }
731 
732         @Override
convertSelectionToString(Object selectedItem)733         protected CharSequence convertSelectionToString(Object selectedItem) {
734             return super.convertSelectionToString(selectedItem);
735         }
736 
737         @Override
getFilter()738         protected Filter getFilter() {
739             return super.getFilter();
740         }
741 
742         @Override
onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)743         protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
744             super.onFocusChanged(focused, direction, previouslyFocusedRect);
745         }
746 
747         @Override
onTextChanged(CharSequence text, int start, int before, int after)748         protected void onTextChanged(CharSequence text, int start, int before, int after) {
749             super.onTextChanged(text, start, before, after);
750             mOnTextChangedFlag = true;
751             lastChangeText = text.toString();
752             mStart = start;
753             mBefore = before;
754             mAfter = after;
755         }
756 
757         @Override
performFiltering(CharSequence text, int keyCode)758         protected void performFiltering(CharSequence text, int keyCode) {
759             super.performFiltering(text, keyCode);
760         }
761 
762         @Override
replaceText(CharSequence text)763         protected void replaceText(CharSequence text) {
764             super.replaceText(text);
765         }
766 
767         @Override
setFrame(int l, int t, int r, int b)768         protected boolean setFrame(int l, int t, int r, int b) {
769             return super.setFrame(l, t, r, b);
770         }
771 
772         @Override
onFilterComplete(int count)773         public void onFilterComplete(int count) {
774             super.onFilterComplete(count);
775             mOnFilterCompleteFlag = true;
776         }
777 
isOnTextChanged()778         protected boolean isOnTextChanged() {
779             return mOnTextChangedFlag;
780         }
781 
getLastChangeText()782         protected String getLastChangeText() {
783             return lastChangeText;
784         }
785 
isOnFilterComplete()786         protected boolean isOnFilterComplete() {
787             return mOnFilterCompleteFlag;
788         }
789 
getStart()790         protected int getStart() {
791             return mStart;
792         }
793 
getBefore()794         protected int getBefore() {
795             return mBefore;
796         }
797 
getAfter()798         protected int getAfter() {
799             return mAfter;
800         }
801     }
802 
803     private static class MockFilter extends Filter {
804         private String mFilterResult;
805 
806         @Override
performFiltering(CharSequence constraint)807         protected FilterResults performFiltering(CharSequence constraint) {
808             if (constraint != null) {
809                 mFilterResult = constraint.toString();
810             }
811             return null;
812         }
813 
814         @Override
publishResults(CharSequence constraint, FilterResults results)815         protected void publishResults(CharSequence constraint, FilterResults results) {
816         }
817 
getResult()818         public String getResult() {
819             return mFilterResult;
820         }
821     }
822 
823     private static class MockAdapter<T> extends ArrayAdapter<T> implements Filterable {
824         private MockFilter mFilter;
825 
MockAdapter(Context context, int textViewResourceId, T[] objects)826         public MockAdapter(Context context, int textViewResourceId, T[] objects) {
827             super(context, textViewResourceId, objects);
828         }
829 
830         @Override
getFilter()831         public Filter getFilter() {
832             if (mFilter == null) {
833                 mFilter = new MockFilter();
834             }
835             return mFilter;
836         }
837     }
838 }
839