SimpleCursorAdapterTest.java revision 1d3165f10b12165f02b7015ac1a817c5f60e6399
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
17package android.widget;
18
19import com.android.common.ArrayListCursor;
20import com.google.android.collect.Lists;
21
22import android.content.Context;
23import android.database.Cursor;
24import android.test.AndroidTestCase;
25import android.test.suitebuilder.annotation.SmallTest;
26
27import java.util.ArrayList;
28import 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 */
37public 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"};
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 = new ArrayListCursor(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        }
81        return list;
82    }
83
84    /**
85     * Test creating with a live cursor
86     */
87    @SmallTest
88    public void testCreateLive() {
89        SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
90
91        // Now see if we can pull 2 rows from the adapter
92        assertEquals(2, ca.getCount());
93    }
94
95    /**
96     * Test creating with a null cursor
97     */
98    @SmallTest
99    public void testCreateNull() {
100        SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, mFrom, mTo);
101
102        // The adapter should report zero rows
103        assertEquals(0, ca.getCount());
104    }
105
106    /**
107     * Test changeCursor() with live cursor
108     */
109    @SmallTest
110    public void testChangeCursorLive() {
111        SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
112
113        // Now see if we can pull 2 rows from the adapter
114        assertEquals(2, ca.getCount());
115
116        // now put in a different cursor (5 rows)
117        ArrayList<ArrayList> data2 = createTestList(5, 2);
118        Cursor c2 = new ArrayListCursor(mFrom, data2);
119        ca.changeCursor(c2);
120
121        // Now see if we can pull 5 rows from the adapter
122        assertEquals(5, ca.getCount());
123    }
124
125    /**
126     * Test changeCursor() with null cursor
127     */
128    @SmallTest
129    public void testChangeCursorNull() {
130        SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
131
132        // Now see if we can pull 2 rows from the adapter
133        assertEquals(2, ca.getCount());
134
135        // now put in null
136        ca.changeCursor(null);
137
138        // The adapter should report zero rows
139        assertEquals(0, ca.getCount());
140    }
141
142    /**
143     * Test changeCursor() with differing column layout.  This confirms that the Adapter can
144     * deal with cursors that have the same essential data (as defined by the original mFrom
145     * array) but it's OK if the physical structure of the cursor changes (columns rearranged).
146     */
147    @SmallTest
148    public void testChangeCursorColumns() {
149        TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
150                mFrom, mTo);
151
152        // check columns of original - mFrom and mTo should line up
153        int[] columns = ca.getConvertedFrom();
154        assertEquals(columns[0], 0);
155        assertEquals(columns[1], 1);
156
157        // Now make a new cursor with similar data but rearrange the columns
158        String[] swappedFrom = new String[]{"Column2", "Column1"};
159        Cursor c2 = new ArrayListCursor(swappedFrom, mData2x2);
160        ca.changeCursor(c2);
161        assertEquals(2, ca.getCount());
162
163        // check columns to see if rearrangement tracked (should be swapped now)
164        columns = ca.getConvertedFrom();
165        assertEquals(columns[0], 1);
166        assertEquals(columns[1], 0);
167    }
168
169    /**
170     * Test that you can safely construct with a null cursor *and* null to/from arrays.
171     * This is new functionality added in 12/2008.
172     */
173    @SmallTest
174    public void testNullConstructor() {
175        SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, null, null);
176        assertEquals(0, ca.getCount());
177    }
178
179    /**
180     * Test going from a null cursor to a non-null cursor *and* setting the to/from arrays
181     * This is new functionality added in 12/2008.
182     */
183    @SmallTest
184    public void testChangeNullToMapped() {
185        TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, null, null, null);
186        assertEquals(0, ca.getCount());
187
188        ca.changeCursorAndColumns(mCursor2x2, mFrom, mTo);
189        assertEquals(2, ca.getCount());
190
191        // check columns of original - mFrom and mTo should line up
192        int[] columns = ca.getConvertedFrom();
193        assertEquals(2, columns.length);
194        assertEquals(0, columns[0]);
195        assertEquals(1, columns[1]);
196        int[] viewIds = ca.getTo();
197        assertEquals(2, viewIds.length);
198        assertEquals(com.android.internal.R.id.text1, viewIds[0]);
199        assertEquals(com.android.internal.R.id.text2, viewIds[1]);
200    }
201
202    /**
203     * Test going from one mapping to a different mapping
204     * This is new functionality added in 12/2008.
205     */
206    @SmallTest
207    public void testChangeMapping() {
208        TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
209                mFrom, mTo);
210        assertEquals(2, ca.getCount());
211
212        // Now create a new configuration with same cursor and just one column mapped
213        String[] singleFrom = new String[]{"Column1"};
214        int[] singleTo = new int[]{com.android.internal.R.id.text1};
215        ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
216
217        // And examine the results, make sure they're still consistent
218        int[] columns = ca.getConvertedFrom();
219        assertEquals(1, columns.length);
220        assertEquals(0, columns[0]);
221        int[] viewIds = ca.getTo();
222        assertEquals(1, viewIds.length);
223        assertEquals(com.android.internal.R.id.text1, viewIds[0]);
224
225        // And again, same cursor, different map
226        singleFrom = new String[]{"Column2"};
227        singleTo = new int[]{com.android.internal.R.id.text2};
228        ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
229
230        // And examine the results, make sure they're still consistent
231        columns = ca.getConvertedFrom();
232        assertEquals(1, columns.length);
233        assertEquals(1, columns[0]);
234        viewIds = ca.getTo();
235        assertEquals(1, viewIds.length);
236        assertEquals(com.android.internal.R.id.text2, viewIds[0]);
237    }
238
239    /**
240     * This is simply a way to sneak a look at the protected mFrom() array.  A more API-
241     * friendly way to do this would be to mock out a View and a ViewBinder and exercise
242     * it via those seams.
243     */
244    private static class TestSimpleCursorAdapter extends SimpleCursorAdapter {
245
246        public TestSimpleCursorAdapter(Context context, int layout, Cursor c,
247                String[] from, int[] to) {
248            super(context, layout, c, from, to);
249        }
250
251        int[] getConvertedFrom() {
252            return mFrom;
253        }
254
255        int[] getTo() {
256            return mTo;
257        }
258    }
259}
260