package org.robolectric.shadows; import android.database.Cursor; import android.database.sqlite.SQLiteCursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import org.junit.After; 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 SQLiteCursorTest { private SQLiteDatabase database; private Cursor cursor; @Before public void setUp() throws Exception { database = SQLiteDatabase.create(null); database.execSQL("CREATE TABLE table_name(" + "id INTEGER PRIMARY KEY, " + "name VARCHAR(255), " + "long_value BIGINT," + "float_value REAL," + "double_value DOUBLE, " + "blob_value BINARY, " + "clob_value CLOB );"); addPeople(); cursor = createCursor(); } @After public void tearDown() throws Exception { database.close(); } @Test public void testGetColumnNames() throws Exception { String[] columnNames = cursor.getColumnNames(); assertColumnNames(columnNames); } @Test public void testGetColumnNamesEmpty() throws Exception { setupEmptyResult(); String[] columnNames = cursor.getColumnNames(); // Column names are present even with an empty result. assertThat(columnNames).isNotNull(); assertColumnNames(columnNames); } @Test public void testGetColumnIndex() throws Exception { assertThat(cursor.getColumnIndex("id")).isEqualTo(0); assertThat(cursor.getColumnIndex("name")).isEqualTo(1); } @Test public void testGetColumnIndexNotFound() throws Exception { assertThat(cursor.getColumnIndex("Fred")).isEqualTo(-1); } @Test public void testGetColumnIndexEmpty() throws Exception { setupEmptyResult(); assertThat(cursor.getColumnIndex("id")).isEqualTo(0); assertThat(cursor.getColumnIndex("name")).isEqualTo(1); } @Test public void testGetColumnIndexOrThrow() throws Exception { assertThat(cursor.getColumnIndexOrThrow("id")).isEqualTo(0); assertThat(cursor.getColumnIndexOrThrow("name")).isEqualTo(1); } @Test(expected = IllegalArgumentException.class) public void testGetColumnIndexOrThrowNotFound() throws Exception { cursor.getColumnIndexOrThrow("Fred"); } @Test public void testGetColumnIndexOrThrowEmpty() throws Exception { setupEmptyResult(); assertThat(cursor.getColumnIndexOrThrow("name")).isEqualTo(1); } @Test(expected = IllegalArgumentException.class) public void testGetColumnIndexOrThrowNotFoundEmpty() throws Exception { setupEmptyResult(); cursor.getColumnIndexOrThrow("Fred"); } @Test public void testMoveToFirst() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getInt(0)).isEqualTo(1234); assertThat(cursor.getString(1)).isEqualTo("Chuck"); } @Test public void testMoveToFirstEmpty() throws Exception { setupEmptyResult(); assertThat(cursor.moveToFirst()).isFalse(); } @Test public void testMoveToNext() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getInt(0)).isEqualTo(1235); assertThat(cursor.getString(1)).isEqualTo("Julie"); } @Test public void testMoveToNextPastEnd() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.moveToNext()).isFalse(); } @Test public void testMoveBackwards() throws Exception { assertThat(cursor.getPosition()).isEqualTo(-1); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(0); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(1); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(2); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(0); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(1); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(2); assertThat(cursor.moveToPosition(1)).isTrue(); assertThat(cursor.getPosition()).isEqualTo(1); } @Test public void testMoveToNextEmpty() throws Exception { setupEmptyResult(); assertThat(cursor.moveToFirst()).isFalse(); assertThat(cursor.moveToNext()).isFalse(); } @Test public void testMoveToPrevious() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.moveToPrevious()).isTrue(); assertThat(cursor.getInt(0)).isEqualTo(1234); assertThat(cursor.getString(1)).isEqualTo("Chuck"); } @Test public void testMoveToPreviousPastStart() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); // Impossible to move cursor before the first item assertThat(cursor.moveToPrevious()).isFalse(); } @Test public void testMoveToPreviousEmpty() throws Exception { setupEmptyResult(); assertThat(cursor.moveToFirst()).isFalse(); assertThat(cursor.moveToPrevious()).isFalse(); } @Test public void testGetPosition() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(0); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.getPosition()).isEqualTo(1); } @Test public void testGetBlob() throws Exception { String sql = "UPDATE table_name set blob_value=? where id=1234"; byte[] byteData = sql.getBytes(); database.execSQL(sql, new Object[]{byteData}); assertThat(cursor.moveToFirst()).isTrue(); byte[] retrievedByteData = cursor.getBlob(5); assertThat(byteData.length).isEqualTo(retrievedByteData.length); for (int i = 0; i < byteData.length; i++) { assertThat(byteData[i]).isEqualTo(retrievedByteData[i]); } } @Test public void testGetClob() throws Exception { String sql = "UPDATE table_name set clob_value=? where id=1234"; String s = "Don't CLOBber my data, please. Thank you."; database.execSQL(sql, new Object[]{s}); assertThat(cursor.moveToFirst()).isTrue(); String actual = cursor.getString(6); assertThat(s).isEqualTo(actual); } @Test public void testGetString() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); String[] data = {"Chuck", "Julie", "Chris"}; for (String aData : data) { assertThat(cursor.getString(1)).isEqualTo(aData); cursor.moveToNext(); } } @Test public void testGetStringWhenInteger() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getString(0)).isEqualTo("1234"); } @Test public void testGetStringWhenLong() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getString(2)).isEqualTo("3463"); } @Test public void testGetStringWhenFloat() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getString(3)).isEqualTo("1.5"); } @Test public void testGetStringWhenDouble() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getString(4)).isEqualTo("3.14159"); } @Test(expected = SQLiteException.class) public void testGetStringWhenBlob() throws Exception { String sql = "UPDATE table_name set blob_value=? where id=1234"; byte[] byteData = sql.getBytes(); database.execSQL(sql, new Object[]{byteData}); assertThat(cursor.moveToFirst()).isTrue(); cursor.getString(5); } @Test(expected = SQLiteException.class) public void testGetIntWhenBlob() throws Exception { String sql = "UPDATE table_name set blob_value=? where id=1234"; byte[] byteData = sql.getBytes(); database.execSQL(sql, new Object[]{byteData}); assertThat(cursor.moveToFirst()).isTrue(); cursor.getInt(5); } @Test public void testGetStringWhenNull() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getString(5)).isNull(); } @Test public void testGetInt() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); int[] data = {1234, 1235, 1236}; for (int aData : data) { assertThat(cursor.getInt(0)).isEqualTo(aData); cursor.moveToNext(); } } @Test public void testGetNumbersFromStringField() throws Exception { database.execSQL("update table_name set name = '1.2'"); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getInt(1)).isEqualTo(1); assertThat(cursor.getDouble(1)).isEqualTo(1.2d); assertThat(cursor.getFloat(1)).isEqualTo(1.2f); } @Test public void testGetNumbersFromBlobField() throws Exception { database.execSQL("update table_name set name = '1.2'"); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getInt(1)).isEqualTo(1); assertThat(cursor.getDouble(1)).isEqualTo(1.2d); assertThat(cursor.getFloat(1)).isEqualTo(1.2f); } @Test public void testGetLong() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getLong(2)).isEqualTo(3463L); } @Test public void testGetFloat() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getFloat(3)).isEqualTo((float) 1.5); } @Test public void testGetDouble() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getDouble(4)).isEqualTo(3.14159); } @Test public void testClose() throws Exception { assertThat(cursor.isClosed()).isFalse(); cursor.close(); assertThat(cursor.isClosed()).isTrue(); } @Test public void testIsNullWhenNull() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.moveToNext()).isTrue(); assertThat(cursor.isNull(cursor.getColumnIndex("id"))).isFalse(); assertThat(cursor.isNull(cursor.getColumnIndex("name"))).isFalse(); assertThat(cursor.isNull(cursor.getColumnIndex("long_value"))).isTrue(); assertThat(cursor.isNull(cursor.getColumnIndex("float_value"))).isTrue(); assertThat(cursor.isNull(cursor.getColumnIndex("double_value"))).isTrue(); } @Test public void testIsNullWhenNotNull() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); for (int i = 0; i < 5; i++) { assertThat(cursor.isNull(i)).isFalse(); } } @Test public void testIsNullWhenIndexOutOfBounds() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); // column index 5 is out-of-bounds assertThat(cursor.isNull(5)).isTrue(); } @Test public void testGetTypeWhenInteger() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(0)).isEqualTo(Cursor.FIELD_TYPE_INTEGER); } @Test public void testGetTypeWhenString() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(1)).isEqualTo(Cursor.FIELD_TYPE_STRING); } @Test public void testGetTypeWhenLong() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(2)).isEqualTo(Cursor.FIELD_TYPE_INTEGER); } @Test public void testGetTypeWhenFloat() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(3)).isEqualTo(Cursor.FIELD_TYPE_FLOAT); } @Test public void testGetTypeWhenDouble() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(4)).isEqualTo(Cursor.FIELD_TYPE_FLOAT); } @Test public void testGetTypeWhenBlob() throws Exception { String sql = "UPDATE table_name set blob_value=? where id=1234"; byte[] byteData = sql.getBytes(); database.execSQL(sql, new Object[]{byteData}); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(5)).isEqualTo(Cursor.FIELD_TYPE_BLOB); } @Test public void testGetTypeWhenNull() throws Exception { assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(5)).isEqualTo(Cursor.FIELD_TYPE_NULL); } @Test public void testGetNullNumberValues() throws Exception { String sql = "UPDATE table_name set long_value=NULL, float_value=NULL, double_value=NULL"; database.execSQL(sql); assertThat(cursor.moveToFirst()).isTrue(); assertThat(cursor.getType(2)).isEqualTo(Cursor.FIELD_TYPE_NULL); assertThat(cursor.getLong(2)).isEqualTo(0); assertThat(cursor.getType(3)).isEqualTo(Cursor.FIELD_TYPE_NULL); assertThat(cursor.getFloat(3)).isEqualTo(0f); assertThat(cursor.getType(4)).isEqualTo(Cursor.FIELD_TYPE_NULL); assertThat(cursor.getDouble(4)).isEqualTo(0d); } private void addPeople() throws Exception { String[] inserts = { "INSERT INTO table_name (id, name, long_value, float_value, double_value) VALUES(1234, 'Chuck', 3463, 1.5, 3.14159);", "INSERT INTO table_name (id, name) VALUES(1235, 'Julie');", "INSERT INTO table_name (id, name) VALUES(1236, 'Chris');" }; for (String insert : inserts) { database.execSQL(insert); } } private Cursor createCursor() throws Exception { String sql ="SELECT * FROM table_name;"; Cursor cursor = database.rawQuery(sql, null); assertThat(cursor).isInstanceOf(SQLiteCursor.class); return cursor; } private void setupEmptyResult() throws Exception { database.execSQL("DELETE FROM table_name;"); cursor = createCursor(); } private void assertColumnNames(String[] columnNames) { assertThat(columnNames.length).isEqualTo(7); assertThat(columnNames[0]).isEqualTo("id"); assertThat(columnNames[1]).isEqualTo("name"); assertThat(columnNames[2]).isEqualTo("long_value"); assertThat(columnNames[3]).isEqualTo("float_value"); assertThat(columnNames[4]).isEqualTo("double_value"); assertThat(columnNames[5]).isEqualTo("blob_value"); assertThat(columnNames[6]).isEqualTo("clob_value"); } }