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