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 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      */
     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
     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             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 
    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
    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 
    599     public void testSetCompletionHint() {
    600         mAutoCompleteTextView.setCompletionHint("TEST HINT");
    601     }
    602 
    603     public void testOnAttachedToWindow() {
    604         // implement details, do not test
    605     }
    606 
    607     public void testOnCommitCompletion() {
    608         // implement details, do not test
    609     }
    610 
    611     public void testOnDetachedFromWindow() {
    612         // implement details, do not test
    613     }
    614 
    615     public void testOnKeyPreIme() {
    616         // implement details, do not test
    617     }
    618 
    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 
    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 
    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 
    666         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    667             mOnItemClickedFlag = true;
    668             return;
    669         }
    670 
    671         public boolean isOnItemClicked() {
    672             return mOnItemClickedFlag;
    673         }
    674 
    675         public void clearItemClickedStatus() {
    676             mOnItemClickedFlag = false;
    677         }
    678     }
    679 
    680     private static class MockOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
    681         public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    682             return;
    683         }
    684 
    685         public void onNothingSelected(AdapterView<?> parent) {
    686             return;
    687         }
    688     }
    689 
    690     private class MockValidator implements AutoCompleteTextView.Validator {
    691         public CharSequence fixText(CharSequence invalidText) {
    692             return STRING_VALIDATED;
    693         }
    694 
    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 
    711         public void resetStatus() {
    712             mOnTextChangedFlag = false;
    713             mOnFilterCompleteFlag = false;
    714             mStart = 0;
    715             mBefore = 0;
    716             mAfter = 0;
    717         }
    718 
    719         public MockAutoCompleteTextView(Context context) {
    720             super(context);
    721             resetStatus();
    722         }
    723 
    724         public MockAutoCompleteTextView(Context context, AttributeSet attrs) {
    725             super(context, attrs);
    726         }
    727 
    728         protected MockAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
    729             super(context, attrs, defStyle);
    730         }
    731 
    732         @Override
    733         protected CharSequence convertSelectionToString(Object selectedItem) {
    734             return super.convertSelectionToString(selectedItem);
    735         }
    736 
    737         @Override
    738         protected Filter getFilter() {
    739             return super.getFilter();
    740         }
    741 
    742         @Override
    743         protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
    744             super.onFocusChanged(focused, direction, previouslyFocusedRect);
    745         }
    746 
    747         @Override
    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
    758         protected void performFiltering(CharSequence text, int keyCode) {
    759             super.performFiltering(text, keyCode);
    760         }
    761 
    762         @Override
    763         protected void replaceText(CharSequence text) {
    764             super.replaceText(text);
    765         }
    766 
    767         @Override
    768         protected boolean setFrame(int l, int t, int r, int b) {
    769             return super.setFrame(l, t, r, b);
    770         }
    771 
    772         @Override
    773         public void onFilterComplete(int count) {
    774             super.onFilterComplete(count);
    775             mOnFilterCompleteFlag = true;
    776         }
    777 
    778         protected boolean isOnTextChanged() {
    779             return mOnTextChangedFlag;
    780         }
    781 
    782         protected String getLastChangeText() {
    783             return lastChangeText;
    784         }
    785 
    786         protected boolean isOnFilterComplete() {
    787             return mOnFilterCompleteFlag;
    788         }
    789 
    790         protected int getStart() {
    791             return mStart;
    792         }
    793 
    794         protected int getBefore() {
    795             return mBefore;
    796         }
    797 
    798         protected int getAfter() {
    799             return mAfter;
    800         }
    801     }
    802 
    803     private static class MockFilter extends Filter {
    804         private String mFilterResult;
    805 
    806         @Override
    807         protected FilterResults performFiltering(CharSequence constraint) {
    808             if (constraint != null) {
    809                 mFilterResult = constraint.toString();
    810             }
    811             return null;
    812         }
    813 
    814         @Override
    815         protected void publishResults(CharSequence constraint, FilterResults results) {
    816         }
    817 
    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 
    826         public MockAdapter(Context context, int textViewResourceId, T[] objects) {
    827             super(context, textViewResourceId, objects);
    828         }
    829 
    830         @Override
    831         public Filter getFilter() {
    832             if (mFilter == null) {
    833                 mFilter = new MockFilter();
    834             }
    835             return mFilter;
    836         }
    837     }
    838 }
    839