package org.robolectric.shadows; import android.database.Cursor; import android.database.MergeCursor; import android.database.sqlite.SQLiteCursor; import android.database.sqlite.SQLiteDatabase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.TestRunners; import static org.assertj.core.api.Assertions.assertThat; @RunWith(TestRunners.MultiApiSelfTest.class) public class ShadowMergeCursorTest { private SQLiteDatabase database; private MergeCursor cursor; private SQLiteCursor dbCursor1; private SQLiteCursor dbCursor2; private static String[] TABLE_1_INSERTS = { "INSERT INTO table_1 (id, name_1, value_1, float_value_1, double_value_1) VALUES(1234, 'Chuck', 3463, 1.5, 3.14159);", "INSERT INTO table_1 (id, name_1) VALUES(1235, 'Julie');", "INSERT INTO table_1 (id, name_1) VALUES(1236, 'Chris');" }; private static String[] TABLE_2_INSERTS = { "INSERT INTO table_2 (id, name_2, value_2, float_value_2, double_value_2) VALUES(4321, 'Mary', 3245, 5.4, 2.7818);", "INSERT INTO table_2 (id, name_2) VALUES(4322, 'Elizabeth');", "INSERT INTO table_2 (id, name_2) VALUES(4323, 'Chester');" }; @Before public void setUp() throws Exception { database = SQLiteDatabase.create(null); dbCursor1 = setupTable( "CREATE TABLE table_1(" + "id INTEGER PRIMARY KEY, name_1 VARCHAR(255), value_1 INTEGER," + "float_value_1 REAL, double_value_1 DOUBLE, blob_value_1 BINARY, clob_value_1 CLOB );", TABLE_1_INSERTS, "SELECT * FROM table_1;" ); dbCursor2 = setupTable( "CREATE TABLE table_2(" + "id INTEGER PRIMARY KEY, name_2 VARCHAR(255), value_2 INTEGER," + "float_value_2 REAL, double_value_2 DOUBLE, blob_value_2 BINARY, clob_value_2 CLOB );", TABLE_2_INSERTS, "SELECT * FROM table_2;" ); } private SQLiteCursor setupTable(final String createSql, final String[] insertions, final String selectSql) { database.execSQL(createSql); for (String insert : insertions) { database.execSQL(insert); } Cursor cursor = database.rawQuery(selectSql, null); assertThat(cursor).isInstanceOf(SQLiteCursor.class); return (SQLiteCursor) cursor; } @Test(expected = NullPointerException.class) public void shouldThrowIfConstructorArgumentIsNull() { new MergeCursor(null); } @Test public void testEmptyCursors() throws Exception { // cursor list with null contents cursor = new MergeCursor( new Cursor[1] ); assertThat(cursor.getCount()).isEqualTo(0); assertThat(cursor.moveToFirst()).isFalse(); assertThat(cursor.getColumnNames()).isNotNull(); // cursor list with partially null contents Cursor[] cursors = new Cursor[2]; cursors[0] = null; cursors[1] = dbCursor1; cursor = new MergeCursor( cursors ); assertThat(cursor.getCount()).isEqualTo(TABLE_1_INSERTS.length); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getColumnNames()).isNotNull(); } @Test public void testMoveToPositionEmptyCursor() throws Exception { Cursor[] cursors = new Cursor[2]; cursors[0] = null; cursors[1] = null; cursor = new MergeCursor( cursors ); assertThat(cursor.getCount()).isEqualTo(0); assertThat(cursor.getColumnNames()).isNotNull(); cursor.moveToPosition(0); assertThat(cursor.getColumnNames()).isNotNull(); } @Test public void testBoundsSingleCursor() throws Exception { Cursor[] cursors = new Cursor[1]; cursors[0] = dbCursor1; assertBounds( cursors, TABLE_1_INSERTS.length ); } @Test public void testBoundsMultipleCursor() throws Exception { Cursor[] cursors = new Cursor[2]; cursors[0] = dbCursor1; cursors[1] = dbCursor2; assertBounds( cursors, TABLE_1_INSERTS.length + TABLE_2_INSERTS.length ); } private void assertBounds( Cursor[] cursors, int expectedLength ) { cursor = new MergeCursor( cursors ); assertThat(cursor.getCount()).isEqualTo(expectedLength); assertThat(cursor.moveToFirst()).isTrue(); for ( int i = 0; i < expectedLength; i++ ) { assertThat(cursor.moveToPosition(i)).isTrue(); assertThat(cursor.isAfterLast()).isFalse(); } assertThat(cursor.moveToNext()).isFalse(); assertThat(cursor.isAfterLast()).isTrue(); assertThat(cursor.moveToPosition(expectedLength)).isFalse(); } @Test public void testGetDataSingleCursor() throws Exception { Cursor[] cursors = new Cursor[1]; cursors[0] = dbCursor1; cursor = new MergeCursor( cursors ); cursor.moveToFirst(); assertDataCursor1(); } @Test public void testGetDataMultipleCursor() throws Exception { Cursor[] cursors = new Cursor[2]; cursors[0] = dbCursor1; cursors[1] = dbCursor2; cursor = new MergeCursor( cursors ); cursor.moveToFirst(); assertDataCursor1(); cursor.moveToNext(); assertDataCursor2(); } private void assertDataCursor1() throws Exception { assertThat(cursor.getInt(0)).isEqualTo(1234); assertThat(cursor.getString(1)).isEqualTo("Chuck"); assertThat(cursor.getInt(2)).isEqualTo(3463); assertThat(cursor.getFloat(3)).isEqualTo(1.5f); assertThat(cursor.getDouble(4)).isEqualTo(3.14159); cursor.moveToNext(); assertThat(cursor.getInt(0)).isEqualTo(1235); assertThat(cursor.getString(1)).isEqualTo("Julie"); cursor.moveToNext(); assertThat(cursor.getInt(0)).isEqualTo(1236); assertThat(cursor.getString(1)).isEqualTo("Chris"); } private void assertDataCursor2() throws Exception { assertThat(cursor.getInt(0)).isEqualTo(4321); assertThat(cursor.getString(1)).isEqualTo("Mary"); assertThat(cursor.getInt(2)).isEqualTo(3245); assertThat(cursor.getFloat(3)).isEqualTo(5.4f); assertThat(cursor.getDouble(4)).isEqualTo(2.7818); cursor.moveToNext(); assertThat(cursor.getInt(0)).isEqualTo(4322); assertThat(cursor.getString(1)).isEqualTo("Elizabeth"); cursor.moveToNext(); assertThat(cursor.getInt(0)).isEqualTo(4323); assertThat(cursor.getString(1)).isEqualTo("Chester"); } @Test public void testColumnNamesSingleCursor() throws Exception { Cursor[] cursors = new Cursor[1]; cursors[0] = dbCursor1; cursor = new MergeCursor( cursors ); for ( int i = 0; i < TABLE_1_INSERTS.length; i++ ) { cursor.moveToPosition(i); String[] columnNames = cursor.getColumnNames(); assertColumnNamesCursor1(columnNames); } } @Test public void testColumnNamesMultipleCursors() throws Exception { Cursor[] cursors = new Cursor[2]; cursors[0] = dbCursor1; cursors[1] = dbCursor2; cursor = new MergeCursor( cursors ); for ( int i = 0; i < TABLE_1_INSERTS.length; i++ ) { cursor.moveToPosition(i); String[] columnNames = cursor.getColumnNames(); assertColumnNamesCursor1(columnNames); } for ( int i = 0; i < TABLE_2_INSERTS.length; i++ ) { cursor.moveToPosition(i + TABLE_1_INSERTS.length); String[] columnNames = cursor.getColumnNames(); assertColumnNamesCursor2(columnNames); } } private void assertColumnNamesCursor1(String[] columnNames) { assertThat(columnNames.length).isEqualTo(7); assertThat(columnNames[0]).isEqualTo("id"); assertThat(columnNames[1]).isEqualTo("name_1"); assertThat(columnNames[2]).isEqualTo("value_1"); assertThat(columnNames[3]).isEqualTo("float_value_1"); assertThat(columnNames[4]).isEqualTo("double_value_1"); assertThat(columnNames[5]).isEqualTo("blob_value_1"); assertThat(columnNames[6]).isEqualTo("clob_value_1"); } private void assertColumnNamesCursor2(String[] columnNames) { assertThat(columnNames.length).isEqualTo(7); assertThat(columnNames[0]).isEqualTo("id"); assertThat(columnNames[1]).isEqualTo("name_2"); assertThat(columnNames[2]).isEqualTo("value_2"); assertThat(columnNames[3]).isEqualTo("float_value_2"); assertThat(columnNames[4]).isEqualTo("double_value_2"); assertThat(columnNames[5]).isEqualTo("blob_value_2"); assertThat(columnNames[6]).isEqualTo("clob_value_2"); } @Test public void testCloseCursors() throws Exception { Cursor[] cursors = new Cursor[2]; cursors[0] = dbCursor1; cursors[1] = dbCursor2; cursor = new MergeCursor( cursors ); assertThat(cursor.isClosed()).isFalse(); assertThat(dbCursor1.isClosed()).isFalse(); assertThat(dbCursor2.isClosed()).isFalse(); cursor.close(); assertThat(cursor.isClosed()).isTrue(); assertThat(dbCursor1.isClosed()).isTrue(); assertThat(dbCursor2.isClosed()).isTrue(); } }