Home | History | Annotate | Download | only in widget
      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;
     18 
     19 import com.google.android.collect.Lists;
     20 
     21 import android.content.Context;
     22 import android.database.Cursor;
     23 import android.database.MatrixCursor;
     24 import android.test.AndroidTestCase;
     25 import android.test.suitebuilder.annotation.SmallTest;
     26 
     27 import java.util.ArrayList;
     28 import java.util.Random;
     29 
     30 /**
     31  * This is a series of tests of basic API contracts for SimpleCursorAdapter.  It is
     32  * incomplete and can use work.
     33  *
     34  * NOTE:  This contract holds for underlying cursor types too and these should
     35  * be extracted into a set of tests that can be run on any descendant of CursorAdapter.
     36  */
     37 public class SimpleCursorAdapterTest extends AndroidTestCase {
     38 
     39     String[] mFrom;
     40     int[] mTo;
     41     int mLayout;
     42     Context mContext;
     43 
     44     ArrayList<ArrayList> mData2x2;
     45     Cursor mCursor2x2;
     46 
     47     /**
     48      * Set up basic columns and cursor for the tests
     49      */
     50     @Override
     51     public void setUp() throws Exception {
     52         super.setUp();
     53 
     54         // all the pieces needed for the various tests
     55         mFrom = new String[]{"Column1", "Column2", "_id"};
     56         mTo = new int[]{com.android.internal.R.id.text1, com.android.internal.R.id.text2};
     57         mLayout = com.android.internal.R.layout.simple_list_item_2;
     58         mContext = getContext();
     59 
     60         // raw data for building a basic test cursor
     61         mData2x2 = createTestList(2, 2);
     62         mCursor2x2 = createCursor(mFrom, mData2x2);
     63     }
     64 
     65     /**
     66      * Borrowed from CursorWindowTest.java
     67      */
     68     private ArrayList<ArrayList> createTestList(int rows, int cols) {
     69         ArrayList<ArrayList> list = Lists.newArrayList();
     70         Random generator = new Random();
     71 
     72         for (int i = 0; i < rows; i++) {
     73             ArrayList<Integer> col = Lists.newArrayList();
     74             list.add(col);
     75             for (int j = 0; j < cols; j++) {
     76                 // generate random number
     77                 Integer r = generator.nextInt();
     78                 col.add(r);
     79             }
     80             col.add(i);
     81         }
     82         return list;
     83     }
     84 
     85     /**
     86      * Test creating with a live cursor
     87      */
     88     @SmallTest
     89     public void testCreateLive() {
     90         SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
     91 
     92         // Now see if we can pull 2 rows from the adapter
     93         assertEquals(2, ca.getCount());
     94     }
     95 
     96     /**
     97      * Test creating with a null cursor
     98      */
     99     @SmallTest
    100     public void testCreateNull() {
    101         SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, mFrom, mTo);
    102 
    103         // The adapter should report zero rows
    104         assertEquals(0, ca.getCount());
    105     }
    106 
    107     /**
    108      * Test changeCursor() with live cursor
    109      */
    110     @SmallTest
    111     public void testChangeCursorLive() {
    112         SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
    113 
    114         // Now see if we can pull 2 rows from the adapter
    115         assertEquals(2, ca.getCount());
    116 
    117         // now put in a different cursor (5 rows)
    118         ArrayList<ArrayList> data2 = createTestList(5, 2);
    119         Cursor c2 = createCursor(mFrom, data2);
    120         ca.changeCursor(c2);
    121 
    122         // Now see if we can pull 5 rows from the adapter
    123         assertEquals(5, ca.getCount());
    124     }
    125 
    126     /**
    127      * Test changeCursor() with null cursor
    128      */
    129     @SmallTest
    130     public void testChangeCursorNull() {
    131         SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
    132 
    133         // Now see if we can pull 2 rows from the adapter
    134         assertEquals(2, ca.getCount());
    135 
    136         // now put in null
    137         ca.changeCursor(null);
    138 
    139         // The adapter should report zero rows
    140         assertEquals(0, ca.getCount());
    141     }
    142 
    143     /**
    144      * Test changeCursor() with differing column layout.  This confirms that the Adapter can
    145      * deal with cursors that have the same essential data (as defined by the original mFrom
    146      * array) but it's OK if the physical structure of the cursor changes (columns rearranged).
    147      */
    148     @SmallTest
    149     public void testChangeCursorColumns() {
    150         TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
    151                 mFrom, mTo);
    152 
    153         // check columns of original - mFrom and mTo should line up
    154         int[] columns = ca.getConvertedFrom();
    155         assertEquals(columns[0], 0);
    156         assertEquals(columns[1], 1);
    157 
    158         // Now make a new cursor with similar data but rearrange the columns
    159         String[] swappedFrom = new String[]{"Column2", "Column1", "_id"};
    160         Cursor c2 = createCursor(swappedFrom, mData2x2);
    161         ca.changeCursor(c2);
    162         assertEquals(2, ca.getCount());
    163 
    164         // check columns to see if rearrangement tracked (should be swapped now)
    165         columns = ca.getConvertedFrom();
    166         assertEquals(columns[0], 1);
    167         assertEquals(columns[1], 0);
    168     }
    169 
    170     /**
    171      * Test that you can safely construct with a null cursor *and* null to/from arrays.
    172      * This is new functionality added in 12/2008.
    173      */
    174     @SmallTest
    175     public void testNullConstructor() {
    176         SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, null, null);
    177         assertEquals(0, ca.getCount());
    178     }
    179 
    180     /**
    181      * Test going from a null cursor to a non-null cursor *and* setting the to/from arrays
    182      * This is new functionality added in 12/2008.
    183      */
    184     @SmallTest
    185     public void testChangeNullToMapped() {
    186         TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, null, null, null);
    187         assertEquals(0, ca.getCount());
    188 
    189         ca.changeCursorAndColumns(mCursor2x2, mFrom, mTo);
    190         assertEquals(2, ca.getCount());
    191 
    192         // check columns of original - mFrom and mTo should line up
    193         int[] columns = ca.getConvertedFrom();
    194         assertEquals(2, columns.length);
    195         assertEquals(0, columns[0]);
    196         assertEquals(1, columns[1]);
    197         int[] viewIds = ca.getTo();
    198         assertEquals(2, viewIds.length);
    199         assertEquals(com.android.internal.R.id.text1, viewIds[0]);
    200         assertEquals(com.android.internal.R.id.text2, viewIds[1]);
    201     }
    202 
    203     /**
    204      * Test going from one mapping to a different mapping
    205      * This is new functionality added in 12/2008.
    206      */
    207     @SmallTest
    208     public void testChangeMapping() {
    209         TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
    210                 mFrom, mTo);
    211         assertEquals(2, ca.getCount());
    212 
    213         // Now create a new configuration with same cursor and just one column mapped
    214         String[] singleFrom = new String[]{"Column1"};
    215         int[] singleTo = new int[]{com.android.internal.R.id.text1};
    216         ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
    217 
    218         // And examine the results, make sure they're still consistent
    219         int[] columns = ca.getConvertedFrom();
    220         assertEquals(1, columns.length);
    221         assertEquals(0, columns[0]);
    222         int[] viewIds = ca.getTo();
    223         assertEquals(1, viewIds.length);
    224         assertEquals(com.android.internal.R.id.text1, viewIds[0]);
    225 
    226         // And again, same cursor, different map
    227         singleFrom = new String[]{"Column2"};
    228         singleTo = new int[]{com.android.internal.R.id.text2};
    229         ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
    230 
    231         // And examine the results, make sure they're still consistent
    232         columns = ca.getConvertedFrom();
    233         assertEquals(1, columns.length);
    234         assertEquals(1, columns[0]);
    235         viewIds = ca.getTo();
    236         assertEquals(1, viewIds.length);
    237         assertEquals(com.android.internal.R.id.text2, viewIds[0]);
    238     }
    239 
    240     private static MatrixCursor createCursor(String[] columns, ArrayList<ArrayList> list) {
    241         MatrixCursor cursor = new MatrixCursor(columns, list.size());
    242         for (ArrayList row : list) {
    243             cursor.addRow(row);
    244         }
    245         return cursor;
    246     }
    247 
    248     /**
    249      * This is simply a way to sneak a look at the protected mFrom() array.  A more API-
    250      * friendly way to do this would be to mock out a View and a ViewBinder and exercise
    251      * it via those seams.
    252      */
    253     private static class TestSimpleCursorAdapter extends SimpleCursorAdapter {
    254 
    255         public TestSimpleCursorAdapter(Context context, int layout, Cursor c,
    256                 String[] from, int[] to) {
    257             super(context, layout, c, from, to);
    258         }
    259 
    260         int[] getConvertedFrom() {
    261             return mFrom;
    262         }
    263 
    264         int[] getTo() {
    265             return mTo;
    266         }
    267     }
    268 }
    269