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.stub.R; 20 21 22 import org.xmlpull.v1.XmlPullParser; 23 24 import android.app.Activity; 25 import android.content.Context; 26 import android.test.ActivityInstrumentationTestCase2; 27 import android.test.UiThreadTest; 28 import android.text.SpannableString; 29 import android.text.Spanned; 30 import android.text.TextUtils; 31 import android.util.AttributeSet; 32 import android.util.Xml; 33 import android.view.KeyEvent; 34 import android.widget.ArrayAdapter; 35 import android.widget.Filter; 36 import android.widget.MultiAutoCompleteTextView; 37 import android.widget.MultiAutoCompleteTextView.CommaTokenizer; 38 import android.widget.MultiAutoCompleteTextView.Tokenizer; 39 40 public class MultiAutoCompleteTextViewTest extends ActivityInstrumentationTestCase2 41 <MultiAutoCompleteTextViewStubActivity> { 42 private MultiAutoCompleteTextView mMultiAutoCompleteTextView_country; 43 private MultiAutoCompleteTextView mMultiAutoCompleteTextView_name; 44 private Activity mActivity; 45 MultiAutoCompleteTextViewTest()46 public MultiAutoCompleteTextViewTest() { 47 super("com.android.cts.stub", MultiAutoCompleteTextViewStubActivity.class); 48 } 49 50 @Override setUp()51 protected void setUp() throws Exception { 52 super.setUp(); 53 54 mActivity = getActivity(); 55 56 mMultiAutoCompleteTextView_country = (MultiAutoCompleteTextView)mActivity 57 .findViewById(R.id.country_edit); 58 mMultiAutoCompleteTextView_name = (MultiAutoCompleteTextView)mActivity 59 .findViewById(R.id.name_edit); 60 } 61 testConstructor()62 public void testConstructor() { 63 XmlPullParser parser = mActivity.getResources() 64 .getXml(R.layout.multi_auto_complete_text_view_layout); 65 AttributeSet attr = Xml.asAttributeSet(parser); 66 67 new MultiAutoCompleteTextView(mActivity); 68 new MultiAutoCompleteTextView(mActivity, attr); 69 new MultiAutoCompleteTextView(mActivity, attr, 0); 70 71 try { 72 new MultiAutoCompleteTextView(null); 73 fail("There should be a NullPointerException thrown out."); 74 } catch (NullPointerException e) { 75 // expected, test success 76 } 77 78 try { 79 new MultiAutoCompleteTextView(null, null); 80 fail("There should be a NullPointerException thrown out."); 81 } catch (NullPointerException e) { 82 // expected, test success 83 } 84 85 try { 86 new MultiAutoCompleteTextView(null, null, -1); 87 fail("There should be a NullPointerException thrown out."); 88 } catch (NullPointerException e) { 89 // expected, test success 90 } 91 } 92 93 @UiThreadTest setText(MultiAutoCompleteTextView m, CharSequence c)94 private void setText(MultiAutoCompleteTextView m, CharSequence c) { 95 m.setText(c); 96 m.setSelection(0, c.length()); 97 } 98 99 @UiThreadTest testMultiAutoCompleteTextView()100 public void testMultiAutoCompleteTextView() { 101 mMultiAutoCompleteTextView_country.setTokenizer(new CommaTokenizer()); 102 mMultiAutoCompleteTextView_name.setTokenizer(new CommaTokenizer()); 103 104 mMultiAutoCompleteTextView_country.setThreshold(3); 105 mMultiAutoCompleteTextView_name.setThreshold(2); 106 107 assertFalse(mMultiAutoCompleteTextView_country.enoughToFilter()); 108 assertFalse(mMultiAutoCompleteTextView_name.enoughToFilter()); 109 110 setText(mMultiAutoCompleteTextView_country, "Ar"); 111 assertFalse(mMultiAutoCompleteTextView_country.enoughToFilter()); 112 113 setText(mMultiAutoCompleteTextView_country, "Arg"); 114 assertTrue(mMultiAutoCompleteTextView_country.enoughToFilter()); 115 116 setText(mMultiAutoCompleteTextView_country, "Argentina"); 117 assertTrue(mMultiAutoCompleteTextView_country.enoughToFilter()); 118 119 setText(mMultiAutoCompleteTextView_name, "J"); 120 assertFalse(mMultiAutoCompleteTextView_name.enoughToFilter()); 121 122 setText(mMultiAutoCompleteTextView_name, "Ja"); 123 assertTrue(mMultiAutoCompleteTextView_name.enoughToFilter()); 124 125 setText(mMultiAutoCompleteTextView_name, "Jacky"); 126 assertTrue(mMultiAutoCompleteTextView_name.enoughToFilter()); 127 128 MockValidator v = new MockValidator(); 129 v.setValid(true); 130 mMultiAutoCompleteTextView_name.setValidator(v); 131 132 // There will be an endless loop when using CommaTokenizer as the Tokenizer 133 // mMultiAutoCompleteTextView_name.performValidation(); 134 mMultiAutoCompleteTextView_name.setValidator(null); 135 } 136 137 @UiThreadTest testPerformValidation()138 public void testPerformValidation() { 139 MockValidator v = new MockValidator(); 140 v.setValid(true); 141 mMultiAutoCompleteTextView_country.setValidator(v); 142 MockTokenizer t = new MockTokenizer(); 143 mMultiAutoCompleteTextView_country.setTokenizer(t); 144 String str = new String("Foo, Android Test, OH"); 145 mMultiAutoCompleteTextView_country.setText(str); 146 mMultiAutoCompleteTextView_country.performValidation(); 147 assertEquals(str, mMultiAutoCompleteTextView_country.getText().toString()); 148 149 v.setValid(false); 150 mMultiAutoCompleteTextView_country.performValidation(); 151 assertEquals(str + ", ", mMultiAutoCompleteTextView_country.getText().toString()); 152 } 153 testPerformFiltering()154 public void testPerformFiltering() { 155 MyMultiAutoCompleteTextView multiAutoCompleteTextView = 156 new MyMultiAutoCompleteTextView(mActivity); 157 CommaTokenizer t = new CommaTokenizer(); 158 multiAutoCompleteTextView.setTokenizer(t); 159 160 ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity, 161 R.layout.simple_dropdown_item_1line); 162 assertNotNull(adapter); 163 164 multiAutoCompleteTextView.setAdapter(adapter); 165 assertNotNull(multiAutoCompleteTextView.getFilter()); 166 167 String text = "Android test."; 168 multiAutoCompleteTextView.setText(text); 169 multiAutoCompleteTextView.setSelection(0, 12); 170 171 multiAutoCompleteTextView.performFiltering(text, KeyEvent.KEYCODE_0); 172 assertNotNull(multiAutoCompleteTextView.getFilter()); 173 174 multiAutoCompleteTextView.performFiltering(text, 0, text.length(), KeyEvent.KEYCODE_E); 175 assertNotNull(multiAutoCompleteTextView.getFilter()); 176 } 177 testReplaceText()178 public void testReplaceText() { 179 MyMultiAutoCompleteTextView multiAutoCompleteTextView = 180 new MyMultiAutoCompleteTextView(mActivity); 181 CommaTokenizer t = new CommaTokenizer(); 182 multiAutoCompleteTextView.setTokenizer(t); 183 184 String text = "CTS."; 185 multiAutoCompleteTextView.setText(text); 186 assertEquals(text, multiAutoCompleteTextView.getText().toString()); 187 multiAutoCompleteTextView.setSelection(0, text.length()); 188 189 // set the selection range. 190 multiAutoCompleteTextView.replaceText("Android Test."); 191 assertEquals("Android Test., ", multiAutoCompleteTextView.getText().toString()); 192 193 // do not set the selection range. 194 multiAutoCompleteTextView.replaceText("replace test"); 195 assertEquals("Android Test., replace test, ", 196 multiAutoCompleteTextView.getText().toString()); 197 } 198 199 private class MockTokenizer implements Tokenizer { findTokenStart(CharSequence text, int cursor)200 public int findTokenStart(CharSequence text, int cursor) { 201 int i = cursor; 202 while (i > 0 && (text.charAt(i - 1) == ' ' || text.charAt(i - 1) == ',')) { 203 i--; 204 } 205 206 while (i > 0 && text.charAt(i - 1) != ',') { 207 i--; 208 } 209 210 while (i < cursor && text.charAt(i) == ' ') { 211 i++; 212 } 213 214 return i; 215 } 216 findTokenEnd(CharSequence text, int cursor)217 public int findTokenEnd(CharSequence text, int cursor) { 218 int i = cursor; 219 int len = text.length(); 220 221 while (i < len) { 222 if (text.charAt(i) == ',') { 223 return i; 224 } else { 225 i++; 226 } 227 } 228 229 return len; 230 } 231 terminateToken(CharSequence text)232 public CharSequence terminateToken(CharSequence text) { 233 int i = text.length(); 234 235 while (i > 0 && text.charAt(i - 1) == ' ') { 236 i--; 237 } 238 239 if (i > 0 && text.charAt(i - 1) == ',') { 240 return text; 241 } else { 242 if (text instanceof Spanned) { 243 SpannableString sp = new SpannableString(text + ", "); 244 TextUtils.copySpansFrom((Spanned)text, 0, text.length(), Object.class, sp, 0); 245 return sp; 246 } else { 247 return text + ", "; 248 } 249 } 250 } 251 } 252 253 private class MockValidator implements MultiAutoCompleteTextView.Validator { 254 private boolean mIsValid; 255 setValid(boolean b)256 public void setValid(boolean b) { 257 mIsValid = b; 258 } 259 isValid(CharSequence text)260 public boolean isValid(CharSequence text) { 261 return mIsValid; 262 } 263 fixText(CharSequence invalidText)264 public CharSequence fixText(CharSequence invalidText) { 265 return invalidText; 266 } 267 } 268 269 /** 270 * MyMultiAutoCompleteTextView 271 */ 272 private class MyMultiAutoCompleteTextView extends MultiAutoCompleteTextView { MyMultiAutoCompleteTextView(Context c)273 public MyMultiAutoCompleteTextView(Context c) { 274 super(c); 275 } 276 performFiltering(CharSequence text, int keyCode)277 protected void performFiltering(CharSequence text, int keyCode) { 278 super.performFiltering(text, keyCode); 279 } 280 performFiltering(CharSequence text, int start, int end, int keyCode)281 protected void performFiltering(CharSequence text, int start, int end, int keyCode) { 282 super.performFiltering(text, start, end, keyCode); 283 } 284 replaceText(CharSequence text)285 protected void replaceText(CharSequence text) { 286 super.replaceText(text); 287 } 288 getFilter()289 protected Filter getFilter() { 290 return super.getFilter(); 291 } 292 } 293 } 294