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