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