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 java.util.ArrayList;
     20 import java.util.Comparator;
     21 import java.util.List;
     22 
     23 import android.database.DataSetObserver;
     24 import android.test.AndroidTestCase;
     25 import android.widget.ArrayAdapter;
     26 import android.widget.Filter;
     27 import android.widget.TextView;
     28 
     29 import com.android.cts.stub.R;
     30 
     31 import dalvik.annotation.TestLevel;
     32 import dalvik.annotation.TestTargetClass;
     33 import dalvik.annotation.TestTargetNew;
     34 import dalvik.annotation.TestTargets;
     35 import dalvik.annotation.ToBeFixed;
     36 
     37 @TestTargetClass(ArrayAdapter.class)
     38 public class ArrayAdapterTest extends AndroidTestCase {
     39 
     40     private static final int INVALD_ID = -1;
     41     private static final String STR1 = "string1";
     42     private static final String STR2 = "string2";
     43     private static final String STR3 = "string3";
     44 
     45     private ArrayAdapter<String> mArrayAdapter;
     46     @Override
     47     protected void setUp() throws Exception {
     48         super.setUp();
     49           mArrayAdapter = new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line);
     50     }
     51 
     52     @TestTargets({
     53         @TestTargetNew(
     54             level = TestLevel.COMPLETE,
     55             method = "ArrayAdapter",
     56             args = {android.content.Context.class, int.class}
     57         ),
     58         @TestTargetNew(
     59             level = TestLevel.COMPLETE,
     60             method = "ArrayAdapter",
     61             args = {android.content.Context.class, int.class, int.class}
     62         ),
     63         @TestTargetNew(
     64             level = TestLevel.COMPLETE,
     65             method = "ArrayAdapter",
     66             args = {android.content.Context.class, int.class, int.class, java.util.List.class}
     67         ),
     68         @TestTargetNew(
     69             level = TestLevel.COMPLETE,
     70             method = "ArrayAdapter",
     71             args = {android.content.Context.class, int.class, java.util.List.class}
     72         ),
     73         @TestTargetNew(
     74             level = TestLevel.COMPLETE,
     75             method = "ArrayAdapter",
     76             args = {android.content.Context.class, int.class, int.class, java.lang.Object[].class}
     77         ),
     78         @TestTargetNew(
     79             level = TestLevel.COMPLETE,
     80             method = "ArrayAdapter",
     81             args = {android.content.Context.class, int.class, java.lang.Object[].class}
     82         )
     83     })
     84     @ToBeFixed(bug = "1695243", explanation = "should add NullPointerException @throws"
     85         + " clause into javadoc.")
     86     public void testConstructor() {
     87 
     88         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line);
     89         new ArrayAdapter<String>(mContext, INVALD_ID);// invalid resource id
     90 
     91         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1);
     92         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, INVALD_ID);
     93 
     94         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line,
     95                 new String[] {"str1", "str2"});
     96 
     97         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1,
     98                 new String[] {"str1", "str2"});
     99 
    100         List<String> list = new ArrayList<String>();
    101         list.add(STR1);
    102         list.add(STR2);
    103 
    104         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, list);
    105 
    106         new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1, list);
    107 
    108         // invalid input
    109         try {
    110             new ArrayAdapter<String>(null, R.layout.simple_dropdown_item_1line);
    111             fail("should throw NullPointerException");
    112         } catch (NullPointerException e) {
    113             // expected exception
    114         }
    115     }
    116 
    117     @TestTargets({
    118         @TestTargetNew(
    119             level = TestLevel.COMPLETE,
    120             method = "setNotifyOnChange",
    121             args = {boolean.class}
    122         ),
    123         @TestTargetNew(
    124             level = TestLevel.COMPLETE,
    125             method = "notifyDataSetChanged",
    126             args = {}
    127         ),
    128         @TestTargetNew(
    129             level = TestLevel.COMPLETE,
    130             method = "add",
    131             args = {java.lang.Object.class}
    132         ),
    133         @TestTargetNew(
    134                 level = TestLevel.COMPLETE,
    135                 method = "clear",
    136                 args = {}
    137         )
    138 
    139     })
    140     public void testDataChangeEvent() {
    141         final MockDataSetObserver mockDataSetObserver = new MockDataSetObserver();
    142         mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
    143 
    144         // enable automatically notifying.
    145         mArrayAdapter.setNotifyOnChange(true);
    146         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    147         mArrayAdapter.add(STR1);
    148         assertEquals(1, mArrayAdapter.getCount());
    149         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    150         mArrayAdapter.add(STR2);
    151         assertEquals(2, mArrayAdapter.getCount());
    152         assertEquals(2, mockDataSetObserver.getCalledOnChangedCount());
    153 
    154         // reset data
    155         mArrayAdapter.clear();
    156         // clear notify changed
    157         assertEquals(3, mockDataSetObserver.getCalledOnChangedCount());
    158         assertEquals(0, mArrayAdapter.getCount());
    159         // if empty before, clear also notify changed
    160         mArrayAdapter.clear();
    161         assertEquals(4, mockDataSetObserver.getCalledOnChangedCount());
    162         mockDataSetObserver.clearCount();
    163         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    164 
    165         // disable auto notify
    166         mArrayAdapter.setNotifyOnChange(false);
    167 
    168         mArrayAdapter.add(STR3);
    169         assertEquals(1, mArrayAdapter.getCount());
    170         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    171 
    172         // manually notify
    173         mArrayAdapter.notifyDataSetChanged();
    174         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    175         // no data changed, but force notify
    176         mArrayAdapter.notifyDataSetChanged();
    177         assertEquals(2, mockDataSetObserver.getCalledOnChangedCount());
    178         // once called notify, auto notify enabled
    179         mArrayAdapter.add(STR3);
    180         assertEquals(3, mockDataSetObserver.getCalledOnChangedCount());
    181     }
    182 
    183     @TestTargets({
    184         @TestTargetNew(
    185                 level = TestLevel.COMPLETE,
    186                 method = "getContext",
    187                 args = {}
    188             ),
    189         @TestTargetNew(
    190             level = TestLevel.COMPLETE,
    191             method = "getCount",
    192             args = {}
    193         ),
    194         @TestTargetNew(
    195             level = TestLevel.COMPLETE,
    196             method = "getView",
    197             args = {int.class, android.view.View.class, android.view.ViewGroup.class}
    198         ),
    199         @TestTargetNew(
    200             level = TestLevel.COMPLETE,
    201             method = "getDropDownView",
    202             args = {int.class, android.view.View.class, android.view.ViewGroup.class}
    203         )
    204     })
    205     @ToBeFixed(bug = "1695243", explanation = "should add NullPointerException @throws"
    206         + " clause into javadoc.")
    207     public void testAccessView() {
    208         final TextView textView = new TextView(mContext);
    209         textView.setText(STR3);
    210 
    211         assertNotNull(mArrayAdapter.getContext());
    212 
    213         assertEquals(0, mArrayAdapter.getCount());
    214 
    215         mArrayAdapter.add(STR1);
    216         mArrayAdapter.add(STR2);
    217         mArrayAdapter.add(STR3);
    218 
    219         assertEquals(3, mArrayAdapter.getCount());
    220 
    221         assertEquals(STR1, ((TextView) mArrayAdapter.getView(0, null, null)).getText());
    222         assertEquals(STR2, ((TextView) mArrayAdapter.getView(1, null, null)).getText());
    223         assertEquals(STR3, ((TextView) mArrayAdapter.getDropDownView(2, null, null)).getText());
    224 
    225         assertEquals(STR3, textView.getText());
    226         assertSame(textView, mArrayAdapter.getView(0, textView, null));
    227         assertSame(textView, mArrayAdapter.getDropDownView(0, textView, null));
    228         assertEquals(STR1, textView.getText());
    229 
    230         try {
    231             assertEquals(textView, mArrayAdapter.getView(-1, textView, null));
    232             fail("should throw IndexOutOfBoundsException");
    233         } catch (IndexOutOfBoundsException e) {
    234         }
    235 
    236         try {
    237             assertEquals(textView, mArrayAdapter.getDropDownView(-1, textView, null));
    238             fail("should throw IndexOutOfBoundsException");
    239         } catch (IndexOutOfBoundsException e) {
    240         }
    241 
    242         try {
    243             assertEquals(textView,
    244                     mArrayAdapter.getView(mArrayAdapter.getCount(), textView, null));
    245             fail("should throw IndexOutOfBoundsException");
    246         } catch (IndexOutOfBoundsException e) {
    247         }
    248 
    249         try {
    250             assertEquals(textView,
    251                     mArrayAdapter.getDropDownView(mArrayAdapter.getCount(), textView, null));
    252             fail("should throw IndexOutOfBoundsException");
    253         } catch (IndexOutOfBoundsException e) {
    254         }
    255     }
    256 
    257     @TestTargetNew(
    258         level = TestLevel.COMPLETE,
    259         method = "getFilter",
    260         args = {}
    261     )
    262     @ToBeFixed(bug = "", explanation = "Can not check the filter's filting result.")
    263     public void testGetFilter() {
    264         Filter filter = mArrayAdapter.getFilter();
    265 
    266         assertNotNull(mArrayAdapter.getFilter());
    267         assertSame(filter, mArrayAdapter.getFilter());
    268     }
    269 
    270     /**
    271      * just simple change the resource id from which the drop view inflate from
    272      * we set a xml that not contain a textview, so exception should throw to lete us know
    273      * sucessfully change the dropdown xml, but should not affect the normal view by getview
    274      */
    275     @TestTargetNew(
    276         level = TestLevel.COMPLETE,
    277         method = "setDropDownViewResource",
    278         args = {int.class}
    279     )
    280     public void testSetDropDownViewResouce() {
    281         mArrayAdapter.add(STR1);
    282 
    283         mArrayAdapter.getDropDownView(0, null, null);
    284 
    285         mArrayAdapter.setDropDownViewResource(R.layout.tabhost_layout);
    286         // getview is ok
    287         mArrayAdapter.getView(0, null, null);
    288         // getDropDownView error for it changed
    289         try {
    290             mArrayAdapter.getDropDownView(0, null, null);
    291             fail("should throw IllegalStateException");
    292         } catch (IllegalStateException e) {
    293             // expected exception
    294         }
    295 
    296         mArrayAdapter.setDropDownViewResource(INVALD_ID);
    297     }
    298 
    299     /**
    300      * insert the item to the specific position, notify data changed
    301      * check -1, normal, > count
    302      */
    303     @TestTargets({
    304         @TestTargetNew(
    305             level = TestLevel.COMPLETE,
    306             method = "insert",
    307             args = {java.lang.Object.class, int.class}
    308         )
    309     })
    310     public void testInsert() {
    311         mArrayAdapter.setNotifyOnChange(true);
    312         final MockDataSetObserver mockDataSetObserver = new MockDataSetObserver();
    313         mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
    314 
    315         mArrayAdapter.insert(STR1, 0);
    316         assertEquals(1, mArrayAdapter.getCount());
    317         assertEquals(0, mArrayAdapter.getPosition(STR1));
    318         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    319 
    320         mArrayAdapter.insert(STR2, 0);
    321         assertEquals(2, mArrayAdapter.getCount());
    322         assertEquals(1, mArrayAdapter.getPosition(STR1));
    323         assertEquals(0, mArrayAdapter.getPosition(STR2));
    324 
    325         mArrayAdapter.insert(STR3, mArrayAdapter.getCount());
    326         assertEquals(mArrayAdapter.getCount() - 1, mArrayAdapter.getPosition(STR3));
    327 
    328         mArrayAdapter.insert(null, 0);
    329         assertEquals(0, mArrayAdapter.getPosition(null));
    330 
    331         try {
    332             mArrayAdapter.insert(STR1, -1);
    333             fail("should throw IndexOutOfBoundsException");
    334         } catch (IndexOutOfBoundsException e) {
    335             // expected exception
    336         }
    337 
    338         try {
    339             mArrayAdapter.insert(STR1, mArrayAdapter.getCount() + 1);
    340             fail("should throw IndexOutOfBoundsException");
    341         } catch (IndexOutOfBoundsException e) {
    342             // expected exception
    343         }
    344     }
    345 
    346     /**
    347      * return the given position obj
    348      * test range: -1, normal, > count
    349      */
    350     @TestTargetNew(
    351         level = TestLevel.COMPLETE,
    352         method = "getItem",
    353         args = {int.class}
    354     )
    355     public void testGetItem() {
    356         mArrayAdapter.add(STR1);
    357         mArrayAdapter.add(STR2);
    358         mArrayAdapter.add(STR3);
    359 
    360         assertSame(STR1, mArrayAdapter.getItem(0));
    361         assertSame(STR2, mArrayAdapter.getItem(1));
    362         assertSame(STR3, mArrayAdapter.getItem(2));
    363 
    364         // test invalid input
    365         try {
    366             mArrayAdapter.getItem(-1);
    367             fail("should throw IndexOutOfBoundsException");
    368         } catch (IndexOutOfBoundsException e) {
    369             // expected exception
    370         }
    371 
    372         try {
    373             mArrayAdapter.getItem(mArrayAdapter.getCount());
    374             fail("should throw IndexOutOfBoundsException");
    375         } catch (IndexOutOfBoundsException e) {
    376             // expected exception
    377         }
    378     }
    379 
    380     /**
    381      * just return the given position
    382      */
    383     @TestTargetNew(
    384         level = TestLevel.COMPLETE,
    385         method = "getItemId",
    386         args = {int.class}
    387     )
    388     public void testGetItemId() {
    389         mArrayAdapter.add(STR1);
    390         mArrayAdapter.add(STR2);
    391         mArrayAdapter.add(STR3);
    392 
    393         assertEquals(0, mArrayAdapter.getItemId(0));
    394         assertEquals(1, mArrayAdapter.getItemId(1));
    395         assertEquals(2, mArrayAdapter.getItemId(2));
    396 
    397         // test invalid input
    398         assertEquals(-1, mArrayAdapter.getItemId(-1));
    399         assertEquals(mArrayAdapter.getCount(),
    400                 mArrayAdapter.getItemId(mArrayAdapter.getCount()));
    401     }
    402 
    403     /*
    404      * return the obj position that in the array, if there are same objs, return the first one
    405      */
    406     @TestTargetNew(
    407         level = TestLevel.COMPLETE,
    408         method = "getPosition",
    409         args = {java.lang.Object.class}
    410     )
    411     public void testGetPosition() {
    412         mArrayAdapter.add(STR1);
    413         mArrayAdapter.add(STR2);
    414         mArrayAdapter.add(STR1);
    415 
    416         assertEquals(0, mArrayAdapter.getPosition(STR1));
    417         assertEquals(1, mArrayAdapter.getPosition(STR2));
    418         // return the first one if same obj exsit
    419         assertEquals(0, mArrayAdapter.getPosition(STR1));
    420 
    421         assertEquals(-1, mArrayAdapter.getPosition(STR3));
    422 
    423         // test invalid input
    424         assertEquals(-1, mArrayAdapter.getPosition(null));
    425     }
    426 
    427     /**
    428      * Removes the specified object from the array. notify data changed
    429      * remove first one if duplicated string in the array
    430      */
    431     @TestTargetNew(
    432         level = TestLevel.COMPLETE,
    433         method = "remove",
    434         args = {java.lang.Object.class}
    435     )
    436     public void testRemove() {
    437         final MockDataSetObserver mockDataSetObserver = new MockDataSetObserver();
    438         mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
    439         mArrayAdapter.setNotifyOnChange(true);
    440 
    441         // remove the not exist one
    442         assertEquals(0, mArrayAdapter.getCount());
    443         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    444         // remove the item not exist also notify change
    445         mArrayAdapter.remove(STR1);
    446         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    447 
    448         mArrayAdapter.add(STR1);
    449         mArrayAdapter.add(STR2);
    450         mArrayAdapter.add(STR3);
    451         mArrayAdapter.add(STR2);
    452         mockDataSetObserver.clearCount();
    453         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    454         assertEquals(4, mArrayAdapter.getCount());
    455 
    456         mArrayAdapter.remove(STR1);
    457         assertEquals(3, mArrayAdapter.getCount());
    458         assertEquals(-1, mArrayAdapter.getPosition(STR1));
    459         assertEquals(0, mArrayAdapter.getPosition(STR2));
    460         assertEquals(1, mArrayAdapter.getPosition(STR3));
    461         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    462 
    463         mArrayAdapter.remove(STR2);
    464         assertEquals(2, mArrayAdapter.getCount());
    465         // remove the first one if dumplicated
    466         assertEquals(1, mArrayAdapter.getPosition(STR2));
    467         assertEquals(0, mArrayAdapter.getPosition(STR3));
    468 
    469         mArrayAdapter.remove(STR2);
    470         assertEquals(1, mArrayAdapter.getCount());
    471         assertEquals(-1, mArrayAdapter.getPosition(STR2));
    472         assertEquals(0, mArrayAdapter.getPosition(STR3));
    473     }
    474 
    475     /*
    476      * Creates a new ArrayAdapter from external resources. The content of the array is
    477      * obtained through {@link android.content.res.Resources#getTextArray(int)}.
    478      */
    479     @TestTargetNew(
    480         level = TestLevel.COMPLETE,
    481         method = "createFromResource",
    482         args = {android.content.Context.class, int.class, int.class}
    483     )
    484     @ToBeFixed(bug = "1695243", explanation = "should add NullPointerException @throws"
    485         + " clause into javadoc.")
    486     public void testCreateFromResource() {
    487         ArrayAdapter.createFromResource(mContext, R.array.string, R.layout.simple_spinner_item);
    488 
    489         // invalid input
    490         try {
    491             ArrayAdapter.createFromResource(null, R.array.string, R.layout.simple_spinner_item);
    492             fail("should throw NullPointerException");
    493         } catch (NullPointerException e) {
    494             // expected exception
    495         }
    496 
    497         try {
    498             ArrayAdapter.createFromResource(mContext, INVALD_ID, R.layout.simple_spinner_item);
    499             fail("should throw NullPointerException");
    500         } catch (NullPointerException e) {
    501             // expected exception
    502         }
    503 
    504        ArrayAdapter.createFromResource(mContext, R.array.string, INVALD_ID);
    505     }
    506 
    507     @TestTargetNew(
    508         level = TestLevel.COMPLETE,
    509         method = "createFromResource",
    510         args = {android.content.Context.class, int.class, int.class}
    511     )
    512     public void testSort() {
    513         final MockDataSetObserver mockDataSetObserver = new MockDataSetObserver();
    514         mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
    515         mArrayAdapter.setNotifyOnChange(true);
    516         assertEquals(0, mockDataSetObserver.getCalledOnChangedCount());
    517 
    518         mArrayAdapter.sort( new Comparator<String>() {
    519             public int compare(String o1, String o2) {
    520                 return 0;
    521             }
    522         });
    523         assertEquals(1, mockDataSetObserver.getCalledOnChangedCount());
    524 
    525         mArrayAdapter.sort(null);
    526         assertEquals(2, mockDataSetObserver.getCalledOnChangedCount());
    527     }
    528 
    529     private static class MockDataSetObserver extends DataSetObserver {
    530 
    531         private int mCalledOnChangedCount;
    532         private int mOnCalledInvalidatedCount;
    533 
    534         public MockDataSetObserver() {
    535             clearCount();
    536         }
    537 
    538         public int getCalledOnChangedCount() {
    539             return mCalledOnChangedCount;
    540         }
    541 
    542         public int getCalledOnInvalidatedCount() {
    543             return mOnCalledInvalidatedCount;
    544         }
    545 
    546         public void clearCount() {
    547             mCalledOnChangedCount = 0;
    548             mOnCalledInvalidatedCount = 0;
    549         }
    550 
    551         public void onChanged() {
    552             mCalledOnChangedCount++;
    553         }
    554 
    555         public void onInvalidated() {
    556             mOnCalledInvalidatedCount++;
    557         }
    558     }
    559 }
    560