package org.robolectric.shadows; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDoneException; import android.database.sqlite.SQLiteStatement; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.TestRunners; import java.io.File; import static org.assertj.core.api.Assertions.assertThat; @RunWith(TestRunners.MultiApiSelfTest.class) public class SQLiteStatementTest { private SQLiteDatabase database; @Before public void setUp() throws Exception { final File databasePath = RuntimeEnvironment.application.getDatabasePath("path"); databasePath.getParentFile().mkdirs(); database = SQLiteDatabase.openOrCreateDatabase(databasePath.getPath(), null); SQLiteStatement createStatement = database.compileStatement("CREATE TABLE `routine` (`id` INTEGER PRIMARY KEY AUTOINCREMENT , `name` VARCHAR , `lastUsed` INTEGER DEFAULT 0 , UNIQUE (`name`)) ;"); createStatement.execute(); SQLiteStatement createStatement2 = database.compileStatement("CREATE TABLE `countme` (`id` INTEGER PRIMARY KEY AUTOINCREMENT , `name` VARCHAR , `lastUsed` INTEGER DEFAULT 0 , UNIQUE (`name`)) ;"); createStatement2.execute(); } @After public void tearDown() throws Exception { database.close(); } @Test public void testExecuteInsert() throws Exception { SQLiteStatement insertStatement = database.compileStatement("INSERT INTO `routine` (`name` ,`lastUsed` ) VALUES (?,?)"); insertStatement.bindString(1, "Leg Press"); insertStatement.bindLong(2, 0); long pkeyOne = insertStatement.executeInsert(); insertStatement.clearBindings(); insertStatement.bindString(1, "Bench Press"); insertStatement.bindLong(2, 1); long pkeyTwo = insertStatement.executeInsert(); assertThat(pkeyOne).isEqualTo(1L); assertThat(pkeyTwo).isEqualTo(2L); Cursor dataCursor = database.rawQuery("SELECT COUNT(*) FROM `routine`", null); assertThat(dataCursor.moveToFirst()).isTrue(); assertThat(dataCursor.getInt(0)).isEqualTo(2); dataCursor.close(); dataCursor = database.rawQuery("SELECT `id`, `name` ,`lastUsed` FROM `routine`", null); assertThat(dataCursor.moveToNext()).isTrue(); assertThat(dataCursor.getInt(0)).isEqualTo(1); assertThat(dataCursor.getString(1)).isEqualTo("Leg Press"); assertThat(dataCursor.getInt(2)).isEqualTo(0); assertThat(dataCursor.moveToNext()).isTrue(); assertThat(dataCursor.getLong(0)).isEqualTo(2L); assertThat(dataCursor.getString(1)).isEqualTo("Bench Press"); assertThat(dataCursor.getInt(2)).isEqualTo(1); dataCursor.close(); } @Test public void testExecuteInsertShouldCloseGeneratedKeysResultSet() throws Exception { // NOTE: // As a side-effect we will get "database locked" exception // on rollback if generatedKeys wasn't closed // // Don't know how suitable to use Mockito here, but // it will be a little bit simpler to test ShadowSQLiteStatement // if actualDBStatement will be mocked database.beginTransaction(); try { SQLiteStatement insertStatement = database.compileStatement("INSERT INTO `routine` " + "(`name` ,`lastUsed`) VALUES ('test',0)"); try { insertStatement.executeInsert(); } finally { insertStatement.close(); } } finally { database.endTransaction(); } } @Test public void testExecuteUpdateDelete() throws Exception { SQLiteStatement insertStatement = database.compileStatement("INSERT INTO `routine` (`name`) VALUES (?)"); insertStatement.bindString(1, "Hand Press"); long pkeyOne = insertStatement.executeInsert(); assertThat(pkeyOne).isEqualTo(1); SQLiteStatement updateStatement = database.compileStatement("UPDATE `routine` SET `name`=? WHERE `id`=?"); updateStatement.bindString(1, "Head Press"); updateStatement.bindLong(2, pkeyOne); assertThat(updateStatement.executeUpdateDelete()).isEqualTo(1); Cursor dataCursor = database.rawQuery("SELECT `name` FROM `routine`", null); assertThat(dataCursor.moveToNext()).isTrue(); assertThat(dataCursor.getString(0)).isEqualTo("Head Press"); } @Test public void simpleQueryTest() throws Exception { SQLiteStatement stmt = database.compileStatement("SELECT count(*) FROM `countme`"); assertThat(stmt.simpleQueryForLong()).isEqualTo(0L); assertThat(stmt.simpleQueryForString()).isEqualTo("0"); SQLiteStatement insertStatement = database.compileStatement("INSERT INTO `countme` (`name` ,`lastUsed` ) VALUES (?,?)"); insertStatement.bindString(1, "Leg Press"); insertStatement.bindLong(2, 0); insertStatement.executeInsert(); assertThat(stmt.simpleQueryForLong()).isEqualTo(1L); assertThat(stmt.simpleQueryForString()).isEqualTo("1"); insertStatement.bindString(1, "Bench Press"); insertStatement.bindLong(2, 1); insertStatement.executeInsert(); assertThat(stmt.simpleQueryForLong()).isEqualTo(2L); assertThat(stmt.simpleQueryForString()).isEqualTo("2"); } @Test(expected = SQLiteDoneException.class) public void simpleQueryForStringThrowsSQLiteDoneExceptionTest() throws Exception { //throw SQLiteDOneException if no rows returned. SQLiteStatement stmt = database.compileStatement("SELECT * FROM `countme` where `name`= 'cessationoftime'"); assertThat(stmt.simpleQueryForString()).isEqualTo("0"); } @Test(expected = SQLiteDoneException.class) public void simpleQueryForLongThrowsSQLiteDoneExceptionTest() throws Exception { //throw SQLiteDOneException if no rows returned. SQLiteStatement stmt = database.compileStatement("SELECT * FROM `countme` where `name`= 'cessationoftime'"); stmt.simpleQueryForLong(); } @Test public void testCloseShouldCloseUnderlyingPreparedStatement() throws Exception { SQLiteStatement insertStatement = database.compileStatement("INSERT INTO `routine` (`name`) VALUES (?)"); insertStatement.bindString(1, "Hand Press"); insertStatement.close(); try { insertStatement.executeInsert(); } catch (Exception e) { assertThat(e).isInstanceOf(IllegalStateException.class); } } }