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 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.content.Context;
     30 import android.database.DataSetObserver;
     31 import android.graphics.Rect;
     32 import android.os.Parcelable;
     33 import android.test.ActivityInstrumentationTestCase2;
     34 import android.test.UiThreadTest;
     35 import android.util.AttributeSet;
     36 import android.util.Xml;
     37 import android.view.View;
     38 import android.view.ViewGroup;
     39 import android.widget.AbsSpinner;
     40 import android.widget.AdapterView;
     41 import android.widget.ArrayAdapter;
     42 import android.widget.Gallery;
     43 import android.widget.ImageView;
     44 import android.widget.Spinner;
     45 import android.widget.SpinnerAdapter;
     46 
     47 @TestTargetClass(AbsSpinner.class)
     48 public class AbsSpinnerTest extends ActivityInstrumentationTestCase2<RelativeLayoutStubActivity> {
     49     private Context mContext;
     50 
     51     public AbsSpinnerTest() {
     52         super("com.android.cts.stub", RelativeLayoutStubActivity.class);
     53     }
     54 
     55     @Override
     56     protected void setUp() throws Exception {
     57         super.setUp();
     58         mContext = getInstrumentation().getTargetContext();
     59     }
     60 
     61     @ToBeFixed(bug="1448885", explanation="AbsSpinner is an abstract class and its abstract " +
     62             "method layout(int, boolean) is package private, we can not extends it directly " +
     63             "to test. So, we use its subclass Spinner and Gallery to test")
     64 
     65     @TestTargets({
     66         @TestTargetNew(
     67             level = TestLevel.COMPLETE,
     68             notes = "",
     69             method = "AbsSpinner",
     70             args = {android.content.Context.class}
     71         ),
     72         @TestTargetNew(
     73             level = TestLevel.COMPLETE,
     74             notes = "",
     75             method = "AbsSpinner",
     76             args = {android.content.Context.class, android.util.AttributeSet.class}
     77         ),
     78         @TestTargetNew(
     79             level = TestLevel.COMPLETE,
     80             notes = "",
     81             method = "AbsSpinner",
     82             args = {android.content.Context.class, android.util.AttributeSet.class, int.class}
     83         )
     84     })
     85     public void testConstructor() {
     86         new Spinner(mContext);
     87 
     88         new Spinner(mContext, null);
     89 
     90         new Spinner(mContext, null, com.android.internal.R.attr.spinnerStyle);
     91 
     92         new Gallery(mContext);
     93         new Gallery(mContext, null);
     94         new Gallery(mContext, null, 0);
     95 
     96         XmlPullParser parser = mContext.getResources().getXml(R.layout.gallery_test);
     97         AttributeSet attrs = Xml.asAttributeSet(parser);
     98         new Gallery(mContext, attrs);
     99         new Gallery(mContext, attrs, 0);
    100     }
    101 
    102     @TestTargets({
    103         @TestTargetNew(
    104             level = TestLevel.COMPLETE,
    105             notes = "",
    106             method = "setSelection",
    107             args = {int.class, boolean.class}
    108         )
    109     })
    110     @ToBeFixed(bug = "1695243", explanation = "the javadoc for setSelection() is incomplete." +
    111             "1. no description about the @param and @return.")
    112     @UiThreadTest
    113     /**
    114      * Check points:
    115      * 1. Jump to the specific item.
    116      */
    117     public void testSetSelectionIntBoolean() {
    118         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
    119         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
    120                 com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);
    121         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    122         absSpinner.setAdapter(adapter);
    123         assertEquals(0, absSpinner.getSelectedItemPosition());
    124 
    125         absSpinner.setSelection(1, true);
    126         assertEquals(1, absSpinner.getSelectedItemPosition());
    127 
    128         absSpinner.setSelection(absSpinner.getCount() - 1, false);
    129         assertEquals(absSpinner.getCount() - 1, absSpinner.getSelectedItemPosition());
    130 
    131         // The animation effect depends on implementation in AbsSpinner's subClass.
    132         // It is not meaningful to check it.
    133     }
    134 
    135     @TestTargets({
    136         @TestTargetNew(
    137             level = TestLevel.COMPLETE,
    138             notes = "",
    139             method = "setSelection",
    140             args = {int.class}
    141         )
    142     })
    143     @ToBeFixed(bug = "1695243", explanation = "the javadoc for setSelection() is incomplete." +
    144             "1. no description about the @param and @return.")
    145     @UiThreadTest
    146     /**
    147      * Check points:
    148      * 1. the currently selected item should be the one which set using this method.
    149      */
    150     public void testSetSelectionInt() {
    151         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
    152         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
    153                 com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);
    154         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    155         absSpinner.setAdapter(adapter);
    156         assertEquals(0, absSpinner.getSelectedItemPosition());
    157 
    158         absSpinner.setSelection(1);
    159         assertEquals(1, absSpinner.getSelectedItemPosition());
    160 
    161         absSpinner.setSelection(absSpinner.getCount() - 1);
    162         assertEquals(absSpinner.getCount() - 1, absSpinner.getSelectedItemPosition());
    163     }
    164 
    165     @TestTargets({
    166         @TestTargetNew(
    167             level = TestLevel.COMPLETE,
    168             notes = "",
    169             method = "setAdapter",
    170             args = {android.widget.SpinnerAdapter.class}
    171         ),
    172         @TestTargetNew(
    173             level = TestLevel.COMPLETE,
    174             notes = "",
    175             method = "getAdapter",
    176             args = {}
    177         )
    178     })
    179     @ToBeFixed(bug = "1695243", explanation = "the javadoc for setAdapter() is incomplete." +
    180             "1. no description about the situation that adapter is null.")
    181     @UiThreadTest
    182     /**
    183      * Check points:
    184      * 1. the adapter returned from getAdapter() should be the one specified using setAdapter().
    185      * 2. the adapter provides methods to transform spinner items based on their position
    186      * relative to the selected item.
    187      */
    188     public void testAccessAdapter() {
    189         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
    190         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
    191                 com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);
    192         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    193 
    194         absSpinner.setAdapter(adapter);
    195         assertSame(adapter, absSpinner.getAdapter());
    196         assertEquals(adapter.getCount(), absSpinner.getCount());
    197         assertEquals(0, absSpinner.getSelectedItemPosition());
    198         assertEquals(adapter.getItemId(0), absSpinner.getSelectedItemId());
    199         absSpinner.setSelection(1);
    200         assertEquals(1, absSpinner.getSelectedItemPosition());
    201         assertEquals(adapter.getItemId(1), absSpinner.getSelectedItemId());
    202 
    203         // issue 1695243, if adapter is null, NullPointerException will be thrown when do layout.
    204         // There is neither limit in code nor description about it in javadoc.
    205     }
    206 
    207     @TestTargetNew(
    208         level = TestLevel.COMPLETE,
    209         notes = "",
    210         method = "requestLayout",
    211         args = {}
    212     )
    213     public void testRequestLayout() {
    214         AbsSpinner absSpinner = new Spinner(mContext);
    215         absSpinner.layout(0, 0, 200, 300);
    216         assertFalse(absSpinner.isLayoutRequested());
    217 
    218         absSpinner.requestLayout();
    219         assertTrue(absSpinner.isLayoutRequested());
    220     }
    221 
    222     @TestTargetNew(
    223         level = TestLevel.COMPLETE,
    224         notes = "",
    225         method = "getCount",
    226         args = {}
    227     )
    228     @UiThreadTest
    229     /**
    230      * Check points:
    231      * 1. The value returned from getCount() equals the count of Adapter associated with
    232      * this AdapterView.
    233      */
    234     public void testGetCount() {
    235         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
    236 
    237         ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(mContext,
    238                 com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);
    239 
    240         absSpinner.setAdapter(adapter1);
    241         assertEquals(adapter1.getCount(), absSpinner.getCount());
    242 
    243         CharSequence anotherStringArray[] = { "another array string 1", "another array string 2" };
    244         ArrayAdapter<CharSequence> adapter2 = new ArrayAdapter<CharSequence>(mContext,
    245                 android.R.layout.simple_spinner_item, anotherStringArray);
    246 
    247         absSpinner.setAdapter(adapter2);
    248         assertEquals(anotherStringArray.length, absSpinner.getCount());
    249     }
    250 
    251     @TestTargetNew(
    252         level = TestLevel.COMPLETE,
    253         notes = "",
    254         method = "pointToPosition",
    255         args = {int.class, int.class}
    256     )
    257     /**
    258      * Check points:
    259      * 1. Should return the position of the item which contains the specified point.
    260      * 2. Should return INVALID_POSITION if the point does not intersect an item
    261      */
    262     public void testPointToPosition() {
    263         AbsSpinner absSpinner = new Gallery(mContext);
    264         MockSpinnerAdapter adapter = new MockSpinnerAdapter();
    265         assertEquals(AdapterView.INVALID_POSITION, absSpinner.pointToPosition(10, 10));
    266 
    267         adapter.setCount(3);
    268         absSpinner.setAdapter(adapter);
    269         absSpinner.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    270         Rect rc = new Rect(0, 0, 100, 100);
    271         Rect rcChild0 = new Rect(0, 0, 20, rc.bottom);
    272         Rect rcChild1 = new Rect(rcChild0.right, 0, 70, rc.bottom);
    273         Rect rcChild2 = new Rect(rcChild1.right, 0, rc.right, rc.bottom);
    274         absSpinner.layout(rc.left, rc.top, rc.right, rc.bottom);
    275         absSpinner.getChildAt(0).layout(rcChild0.left, rcChild0.top,
    276                 rcChild0.right, rcChild0.bottom);
    277         absSpinner.getChildAt(1).layout(rcChild1.left, rcChild1.top,
    278                 rcChild1.right, rcChild1.bottom);
    279         absSpinner.getChildAt(2).layout(rcChild2.left, rcChild2.top,
    280                 rcChild2.right, rcChild2.bottom);
    281 
    282         assertEquals(AdapterView.INVALID_POSITION, absSpinner.pointToPosition(-1, -1));
    283         assertEquals(0, absSpinner.pointToPosition(rcChild0.left + 1, rc.bottom - 1));
    284         assertEquals(1, absSpinner.pointToPosition(rcChild1.left + 1, rc.bottom - 1));
    285         assertEquals(2, absSpinner.pointToPosition(rcChild2.left + 1, rc.bottom - 1));
    286         assertEquals(AdapterView.INVALID_POSITION,
    287                 absSpinner.pointToPosition(rc.right + 1, rc.bottom - 1));
    288 
    289     }
    290 
    291     @TestTargetNew(
    292         level = TestLevel.COMPLETE,
    293         notes = "",
    294         method = "getSelectedView",
    295         args = {}
    296     )
    297     /**
    298      * Check points:
    299      * 1. Should return the view corresponding to the currently selected item.
    300      * 2. Should return null if nothing is selected.
    301      */
    302     public void testGetSelectedView() {
    303         AbsSpinner absSpinner = new Gallery(mContext);
    304         MockSpinnerAdapter adapter = new MockSpinnerAdapter();
    305         assertNull(absSpinner.getSelectedView());
    306 
    307         absSpinner.setAdapter(adapter);
    308         absSpinner.layout(0, 0, 20, 20);
    309         assertSame(absSpinner.getChildAt(0), absSpinner.getSelectedView());
    310 
    311         absSpinner.setSelection(1, true);
    312         assertSame(absSpinner.getChildAt(1), absSpinner.getSelectedView());
    313 
    314     }
    315 
    316     @TestTargets({
    317         @TestTargetNew(
    318             level = TestLevel.COMPLETE,
    319             notes = "",
    320             method = "onSaveInstanceState",
    321             args = {}
    322         ),
    323         @TestTargetNew(
    324             level = TestLevel.COMPLETE,
    325             notes = "",
    326             method = "onRestoreInstanceState",
    327             args = {android.os.Parcelable.class}
    328         )
    329     })
    330     @UiThreadTest
    331     /**
    332      * Check points:
    333      * 1. the view's current state saved by onSaveInstanceState() should be correctly restored
    334      * after onRestoreInstanceState().
    335      */
    336     public void testOnSaveAndRestoreInstanceState() {
    337         AbsSpinner absSpinner = (AbsSpinner) getActivity().findViewById(R.id.spinner1);
    338         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mContext,
    339                 com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);
    340         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    341         absSpinner.setAdapter(adapter);
    342         assertEquals(0, absSpinner.getSelectedItemPosition());
    343         assertEquals(adapter.getItemId(0), absSpinner.getSelectedItemId());
    344         Parcelable parcelable = absSpinner.onSaveInstanceState();
    345 
    346         absSpinner.setSelection(1);
    347         assertEquals(1, absSpinner.getSelectedItemPosition());
    348         assertEquals(adapter.getItemId(1), absSpinner.getSelectedItemId());
    349 
    350         absSpinner.onRestoreInstanceState(parcelable);
    351         absSpinner.measure(View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
    352         absSpinner.layout(absSpinner.getLeft(), absSpinner.getTop(), absSpinner.getRight(),
    353                 absSpinner.getBottom());
    354         assertEquals(0, absSpinner.getSelectedItemPosition());
    355         assertEquals(adapter.getItemId(0), absSpinner.getSelectedItemId());
    356     }
    357 
    358     @TestTargetNew(
    359         level = TestLevel.COMPLETE,
    360         notes = "",
    361         method = "generateDefaultLayoutParams",
    362         args = {}
    363     )
    364     @ToBeFixed(bug = "1448885", explanation = "AbsSpinner#generateDefaultLayoutParams() is" +
    365             " protected method, we have to test it in MockSpinner which extends from" +
    366             " AbsSpinner. class MockSpinner must implement the inherited abstract method" +
    367             " AbsSpinner.layout(int, boolean), but cannot override it since it is not" +
    368             " visible from MockSpinner. So we cannot test this method.")
    369     public void testGenerateDefaultLayoutParams() {
    370 //        final MockSpinner absSpinner = new MockSpinner(mContext);
    371 //        LayoutParams layoutParams = (LayoutParams) absSpinner.generateDefaultLayoutParams();
    372 //        assertEquals(LayoutParams.MATCH_PARENT, layoutParams.width);
    373 //        assertEquals(LayoutParams.WRAP_CONTENT, layoutParams.height);
    374     }
    375 
    376     @TestTargetNew(
    377         level = TestLevel.NOT_NECESSARY,
    378         notes = "Test onMeasure(int, int) function.",
    379         method = "onMeasure",
    380         args = {int.class, int.class}
    381     )
    382     public void testOnMeasure() {
    383         // onMeasure() is implementation details, do NOT test
    384     }
    385 
    386     /*
    387      * The Mock class of SpinnerAdapter to be used in test.
    388      */
    389     private class MockSpinnerAdapter implements SpinnerAdapter {
    390         public static final int DEFAULT_COUNT = 1;
    391         private int mCount = DEFAULT_COUNT;
    392 
    393         public View getDropDownView(int position, View convertView,
    394                 ViewGroup parent) {
    395             return null;
    396         }
    397 
    398         public int getCount() {
    399             return mCount;
    400         }
    401 
    402         public void setCount(int count) {
    403             mCount = count;
    404         }
    405 
    406         public Object getItem(int position) {
    407             return null;
    408         }
    409 
    410         public long getItemId(int position) {
    411             return position;
    412         }
    413 
    414         public int getItemViewType(int position) {
    415             return 0;
    416         }
    417 
    418         public View getView(int position, View convertView, ViewGroup parent) {
    419             return new ImageView(mContext);
    420         }
    421 
    422         public int getViewTypeCount() {
    423             return 0;
    424         }
    425 
    426         public boolean hasStableIds() {
    427             return false;
    428         }
    429 
    430         public boolean isEmpty() {
    431             return false;
    432         }
    433 
    434         public void registerDataSetObserver(DataSetObserver observer) {
    435         }
    436 
    437         public void unregisterDataSetObserver(DataSetObserver observer) {
    438         }
    439     }
    440 }
    441