Home | History | Annotate | Download | only in cts
      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 com.android.cts.widget.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      */
     55     public AutoCompleteTextViewTest() {
     56         super("com.android.cts.widget", 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
     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 
    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
    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 
    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
    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")
    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")
    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
    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
    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
    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
    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
    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 
    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 
    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 
    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 
    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             mInstrumentation.sendStringSync(STRING_TEST);
    506             new PollingCheck() {
    507                 @Override
    508                 protected boolean check() {
    509                     return STRING_TEST.equals(filter.getResult());
    510                 }
    511             }.run();
    512         }
    513     }
    514 
    515     public void testPerformCompletion() throws Throwable {
    516         if (isTvMode()) {
    517             return;
    518         }
    519         final MockOnItemClickListener listener = new MockOnItemClickListener();
    520         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
    521 
    522         runTestOnUiThread(new Runnable() {
    523             public void run() {
    524                 mAutoCompleteTextView.setOnItemClickListener(listener);
    525                 mAutoCompleteTextView.setAdapter(mAdapter);
    526                 mAutoCompleteTextView.requestFocus();
    527                 mAutoCompleteTextView.showDropDown();
    528             }
    529         });
    530         mInstrumentation.waitForIdleSync();
    531         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
    532 
    533         // Key is ENTER or DPAD_ENTER, will invoke completion
    534         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
    535         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
    536         mInstrumentation.waitForIdleSync();
    537         assertTrue(listener.isOnItemClicked());
    538 
    539         assertEquals(WORDS[0], mAutoCompleteTextView.getText().toString());
    540 
    541         // re-set 'clicked' flag to false
    542         listener.clearItemClickedStatus();
    543 
    544         runTestOnUiThread(new Runnable() {
    545             public void run() {
    546                 mAutoCompleteTextView.showDropDown();
    547             }
    548         });
    549         mInstrumentation.waitForIdleSync();
    550         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
    551         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
    552         assertTrue(listener.isOnItemClicked());
    553         assertEquals(WORDS[0], mAutoCompleteTextView.getText().toString());
    554         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
    555 
    556         listener.clearItemClickedStatus();
    557         runTestOnUiThread(new Runnable() {
    558             public void run() {
    559                 mAutoCompleteTextView.showDropDown();
    560             }
    561         });
    562         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
    563         // Test normal key code.
    564         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
    565         assertFalse(listener.isOnItemClicked());
    566         assertNotSame("", mAutoCompleteTextView.getText().toString());
    567         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
    568 
    569         listener.clearItemClickedStatus();
    570 
    571         // Test the method on the scene of popup is closed.
    572         runTestOnUiThread(new Runnable() {
    573             public void run() {
    574                mAutoCompleteTextView.dismissDropDown();
    575             }
    576         });
    577 
    578         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
    579         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
    580         assertFalse(listener.isOnItemClicked());
    581         assertNotSame("", mAutoCompleteTextView.getText().toString());
    582         assertFalse(mAutoCompleteTextView.isPerformingCompletion());
    583     }
    584 
    585     @UiThreadTest
    586     public void testPerformValidation() {
    587         final CharSequence text = "this";
    588 
    589         mAutoCompleteTextView.setValidator(mValidator);
    590         mAutoCompleteTextView.setAdapter((ArrayAdapter<String>) null);
    591         mAutoCompleteTextView.setText(text);
    592         mAutoCompleteTextView.performValidation();
    593 
    594         assertEquals(STRING_VALIDATED, mAutoCompleteTextView.getText().toString());
    595         mAutoCompleteTextView.setValidator(null);
    596     }
    597 
    598     public void testSetCompletionHint() {
    599         mAutoCompleteTextView.setCompletionHint("TEST HINT");
    600     }
    601 
    602     public void testOnAttachedToWindow() {
    603         // implement details, do not test
    604     }
    605 
    606     public void testOnCommitCompletion() {
    607         // implement details, do not test
    608     }
    609 
    610     public void testOnDetachedFromWindow() {
    611         // implement details, do not test
    612     }
    613 
    614     public void testOnKeyPreIme() {
    615         // implement details, do not test
    616     }
    617 
    618     public void testAccessListSelection() throws Throwable {
    619         final MockOnItemClickListener listener = new MockOnItemClickListener();
    620 
    621         runTestOnUiThread(new Runnable() {
    622             public void run() {
    623                 mAutoCompleteTextView.setOnItemClickListener(listener);
    624                 mAutoCompleteTextView.setAdapter(mAdapter);
    625                 mAutoCompleteTextView.requestFocus();
    626                 mAutoCompleteTextView.showDropDown();
    627             }
    628         });
    629         mInstrumentation.waitForIdleSync();
    630 
    631         runTestOnUiThread(new Runnable() {
    632             public void run() {
    633                 mAutoCompleteTextView.setListSelection(1);
    634                 assertEquals(1, mAutoCompleteTextView.getListSelection());
    635 
    636                 mAutoCompleteTextView.setListSelection(2);
    637                 assertEquals(2, mAutoCompleteTextView.getListSelection());
    638 
    639                 mAutoCompleteTextView.clearListSelection();
    640                 assertEquals(2, mAutoCompleteTextView.getListSelection());
    641             }
    642         });
    643         mInstrumentation.waitForIdleSync();
    644     }
    645 
    646     public void testAccessDropDownAnchor() {
    647         mAutoCompleteTextView.setDropDownAnchor(View.NO_ID);
    648         assertEquals(View.NO_ID, mAutoCompleteTextView.getDropDownAnchor());
    649 
    650         mAutoCompleteTextView.setDropDownAnchor(0x5555);
    651         assertEquals(0x5555, mAutoCompleteTextView.getDropDownAnchor());
    652     }
    653 
    654     public void testAccessDropDownWidth() {
    655         mAutoCompleteTextView.setDropDownWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
    656         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, mAutoCompleteTextView.getDropDownWidth());
    657 
    658         mAutoCompleteTextView.setDropDownWidth(ViewGroup.LayoutParams.MATCH_PARENT);
    659         assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, mAutoCompleteTextView.getDropDownWidth());
    660     }
    661 
    662     private static class MockOnItemClickListener implements AdapterView.OnItemClickListener {
    663         private boolean mOnItemClickedFlag = false;
    664 
    665         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    666             mOnItemClickedFlag = true;
    667             return;
    668         }
    669 
    670         public boolean isOnItemClicked() {
    671             return mOnItemClickedFlag;
    672         }
    673 
    674         public void clearItemClickedStatus() {
    675             mOnItemClickedFlag = false;
    676         }
    677     }
    678 
    679     private static class MockOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
    680         public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    681             return;
    682         }
    683 
    684         public void onNothingSelected(AdapterView<?> parent) {
    685             return;
    686         }
    687     }
    688 
    689     private class MockValidator implements AutoCompleteTextView.Validator {
    690         public CharSequence fixText(CharSequence invalidText) {
    691             return STRING_VALIDATED;
    692         }
    693 
    694         public boolean isValid(CharSequence text) {
    695             if (text == STRING_TEST) {
    696                 return true;
    697             }
    698             return false;
    699         }
    700     }
    701 
    702     private static class MockAutoCompleteTextView extends AutoCompleteTextView {
    703         private boolean mOnTextChangedFlag = false;
    704         private boolean mOnFilterCompleteFlag = false;
    705         private String lastChangeText = "";
    706         private int mStart = 0;
    707         private int mBefore = 0;
    708         private int mAfter = 0;
    709 
    710         public void resetStatus() {
    711             mOnTextChangedFlag = false;
    712             mOnFilterCompleteFlag = false;
    713             mStart = 0;
    714             mBefore = 0;
    715             mAfter = 0;
    716         }
    717 
    718         public MockAutoCompleteTextView(Context context) {
    719             super(context);
    720             resetStatus();
    721         }
    722 
    723         public MockAutoCompleteTextView(Context context, AttributeSet attrs) {
    724             super(context, attrs);
    725         }
    726 
    727         protected MockAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
    728             super(context, attrs, defStyle);
    729         }
    730 
    731         @Override
    732         protected CharSequence convertSelectionToString(Object selectedItem) {
    733             return super.convertSelectionToString(selectedItem);
    734         }
    735 
    736         @Override
    737         protected Filter getFilter() {
    738             return super.getFilter();
    739         }
    740 
    741         @Override
    742         protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
    743             super.onFocusChanged(focused, direction, previouslyFocusedRect);
    744         }
    745 
    746         @Override
    747         protected void onTextChanged(CharSequence text, int start, int before, int after) {
    748             super.onTextChanged(text, start, before, after);
    749             mOnTextChangedFlag = true;
    750             lastChangeText = text.toString();
    751             mStart = start;
    752             mBefore = before;
    753             mAfter = after;
    754         }
    755 
    756         @Override
    757         protected void performFiltering(CharSequence text, int keyCode) {
    758             super.performFiltering(text, keyCode);
    759         }
    760 
    761         @Override
    762         protected void replaceText(CharSequence text) {
    763             super.replaceText(text);
    764         }
    765 
    766         @Override
    767         protected boolean setFrame(int l, int t, int r, int b) {
    768             return super.setFrame(l, t, r, b);
    769         }
    770 
    771         @Override
    772         public void onFilterComplete(int count) {
    773             super.onFilterComplete(count);
    774             mOnFilterCompleteFlag = true;
    775         }
    776 
    777         protected boolean isOnTextChanged() {
    778             return mOnTextChangedFlag;
    779         }
    780 
    781         protected String getLastChangeText() {
    782             return lastChangeText;
    783         }
    784 
    785         protected boolean isOnFilterComplete() {
    786             return mOnFilterCompleteFlag;
    787         }
    788 
    789         protected int getStart() {
    790             return mStart;
    791         }
    792 
    793         protected int getBefore() {
    794             return mBefore;
    795         }
    796 
    797         protected int getAfter() {
    798             return mAfter;
    799         }
    800     }
    801 
    802     private static class MockFilter extends Filter {
    803         private String mFilterResult;
    804 
    805         @Override
    806         protected FilterResults performFiltering(CharSequence constraint) {
    807             if (constraint != null) {
    808                 mFilterResult = constraint.toString();
    809             }
    810             return null;
    811         }
    812 
    813         @Override
    814         protected void publishResults(CharSequence constraint, FilterResults results) {
    815         }
    816 
    817         public String getResult() {
    818             return mFilterResult;
    819         }
    820     }
    821 
    822     private static class MockAdapter<T> extends ArrayAdapter<T> implements Filterable {
    823         private MockFilter mFilter;
    824 
    825         public MockAdapter(Context context, int textViewResourceId, T[] objects) {
    826             super(context, textViewResourceId, objects);
    827         }
    828 
    829         @Override
    830         public Filter getFilter() {
    831             if (mFilter == null) {
    832                 mFilter = new MockFilter();
    833             }
    834             return mFilter;
    835         }
    836     }
    837 }
    838