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