• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static com.google.common.truth.Truth.assertThat;
4 
5 import android.content.ContentValues;
6 import android.content.Context;
7 import android.database.sqlite.SQLiteDatabase;
8 import android.database.sqlite.SQLiteDatabase.CursorFactory;
9 import android.database.sqlite.SQLiteOpenHelper;
10 import androidx.test.core.app.ApplicationProvider;
11 import androidx.test.ext.junit.runners.AndroidJUnit4;
12 import org.junit.After;
13 import org.junit.Before;
14 import org.junit.Test;
15 import org.junit.runner.RunWith;
16 
17 @RunWith(AndroidJUnit4.class)
18 public class SQLiteOpenHelperTest {
19 
20   private TestOpenHelper helper;
21 
22   @Before
setUp()23   public void setUp() throws Exception {
24     helper = new TestOpenHelper(ApplicationProvider.getApplicationContext(), "path", null, 1);
25   }
26 
27   @After
tearDown()28   public void tearDown() {
29     helper.close();
30   }
31 
32   @Test
testConstructorWithNullPathShouldCreateInMemoryDatabase()33   public void testConstructorWithNullPathShouldCreateInMemoryDatabase() throws Exception {
34     TestOpenHelper helper = new TestOpenHelper(null, null, null, 1);
35     SQLiteDatabase database = helper.getReadableDatabase();
36     assertDatabaseOpened(database, helper);
37     assertInitialDB(database, helper);
38   }
39 
40   @Test
testInitialGetReadableDatabase()41   public void testInitialGetReadableDatabase() throws Exception {
42     SQLiteDatabase database = helper.getReadableDatabase();
43     assertInitialDB(database, helper);
44   }
45 
46   @Test
testSubsequentGetReadableDatabase()47   public void testSubsequentGetReadableDatabase() throws Exception {
48     helper.getReadableDatabase();
49     helper.close();
50     SQLiteDatabase database = helper.getReadableDatabase();
51 
52     assertSubsequentDB(database, helper);
53   }
54 
55   @Test
testSameDBInstanceSubsequentGetReadableDatabase()56   public void testSameDBInstanceSubsequentGetReadableDatabase() throws Exception {
57     SQLiteDatabase db1 = helper.getReadableDatabase();
58     SQLiteDatabase db2 = helper.getReadableDatabase();
59 
60     assertThat(db1).isSameAs(db2);
61   }
62 
63   @Test
testInitialGetWritableDatabase()64   public void testInitialGetWritableDatabase() throws Exception {
65     SQLiteDatabase database = helper.getWritableDatabase();
66     assertInitialDB(database, helper);
67   }
68 
69   @Test
testSubsequentGetWritableDatabase()70   public void testSubsequentGetWritableDatabase() throws Exception {
71     helper.getWritableDatabase();
72     helper.close();
73 
74     assertSubsequentDB(helper.getWritableDatabase(), helper);
75   }
76 
77   @Test
testSameDBInstanceSubsequentGetWritableDatabase()78   public void testSameDBInstanceSubsequentGetWritableDatabase() throws Exception {
79     SQLiteDatabase db1 = helper.getWritableDatabase();
80     SQLiteDatabase db2 = helper.getWritableDatabase();
81 
82     assertThat(db1).isSameAs(db2);
83   }
84 
85   @Test
testClose()86   public void testClose() throws Exception {
87     SQLiteDatabase database = helper.getWritableDatabase();
88 
89     assertThat(database.isOpen()).isTrue();
90     helper.close();
91     assertThat(database.isOpen()).isFalse();
92   }
93 
94   @Test
testGetPath()95   public void testGetPath() throws Exception {
96     final String path1 = "path1", path2 = "path2";
97 
98     TestOpenHelper helper1 =
99         new TestOpenHelper(ApplicationProvider.getApplicationContext(), path1, null, 1);
100     String expectedPath1 =
101         ApplicationProvider.getApplicationContext().getDatabasePath(path1).getAbsolutePath();
102     assertThat(helper1.getReadableDatabase().getPath()).isEqualTo(expectedPath1);
103 
104     TestOpenHelper helper2 =
105         new TestOpenHelper(ApplicationProvider.getApplicationContext(), path2, null, 1);
106     String expectedPath2 =
107         ApplicationProvider.getApplicationContext().getDatabasePath(path2).getAbsolutePath();
108     assertThat(helper2.getReadableDatabase().getPath()).isEqualTo(expectedPath2);
109   }
110 
111   @Test
testCloseMultipleDbs()112   public void testCloseMultipleDbs() throws Exception {
113     TestOpenHelper helper2 =
114         new TestOpenHelper(ApplicationProvider.getApplicationContext(), "path2", null, 1);
115     SQLiteDatabase database1 = helper.getWritableDatabase();
116     SQLiteDatabase database2 = helper2.getWritableDatabase();
117     assertThat(database1.isOpen()).isTrue();
118     assertThat(database2.isOpen()).isTrue();
119     helper.close();
120     assertThat(database1.isOpen()).isFalse();
121     assertThat(database2.isOpen()).isTrue();
122     helper2.close();
123     assertThat(database2.isOpen()).isFalse();
124   }
125 
126   @Test
testOpenMultipleDbsOnCreate()127   public void testOpenMultipleDbsOnCreate() throws Exception {
128     TestOpenHelper helper2 =
129         new TestOpenHelper(ApplicationProvider.getApplicationContext(), "path2", null, 1);
130     assertThat(helper.onCreateCalled).isFalse();
131     assertThat(helper2.onCreateCalled).isFalse();
132     helper.getWritableDatabase();
133     assertThat(helper.onCreateCalled).isTrue();
134     assertThat(helper2.onCreateCalled).isFalse();
135     helper2.getWritableDatabase();
136     assertThat(helper.onCreateCalled).isTrue();
137     assertThat(helper2.onCreateCalled).isTrue();
138     helper.close();
139     helper2.close();
140   }
141 
setupTable(SQLiteDatabase db, String table)142   private void setupTable(SQLiteDatabase db, String table) {
143     db.execSQL("CREATE TABLE " + table + " (" +
144         "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
145         "testVal INTEGER DEFAULT 0" +
146         ");");
147   }
insertData(SQLiteDatabase db, String table, int[] values)148   private void insertData(SQLiteDatabase db, String table, int[] values) {
149     for (int i : values) {
150       ContentValues cv = new ContentValues();
151       cv.put("testVal", i);
152       db.insert(table, null, cv);
153     }
154   }
155 
verifyData(SQLiteDatabase db, String table, int expectedVals)156   private void verifyData(SQLiteDatabase db, String table, int expectedVals) {
157     assertThat(db.query(table, null, null, null,
158           null, null, null).getCount()).isEqualTo(expectedVals);
159   }
160 
161   @Test
testMultipleDbsPreserveData()162   public void testMultipleDbsPreserveData() throws Exception {
163     final String TABLE_NAME1 = "fart", TABLE_NAME2 = "fart2";
164     SQLiteDatabase db1 = helper.getWritableDatabase();
165     setupTable(db1, TABLE_NAME1);
166     insertData(db1, TABLE_NAME1, new int[]{1, 2});
167     TestOpenHelper helper2 =
168         new TestOpenHelper(ApplicationProvider.getApplicationContext(), "path2", null, 1);
169     SQLiteDatabase db2 = helper2.getWritableDatabase();
170     setupTable(db2, TABLE_NAME2);
171     insertData(db2, TABLE_NAME2, new int[]{4, 5, 6});
172     verifyData(db1, TABLE_NAME1, 2);
173     verifyData(db2, TABLE_NAME2, 3);
174   }
175 
176   @Test
testCloseOneDbKeepsDataForOther()177   public void testCloseOneDbKeepsDataForOther() throws Exception {
178     final String TABLE_NAME1 = "fart", TABLE_NAME2 = "fart2";
179     TestOpenHelper helper2 =
180         new TestOpenHelper(ApplicationProvider.getApplicationContext(), "path2", null, 1);
181     SQLiteDatabase db1 = helper.getWritableDatabase();
182     SQLiteDatabase db2 = helper2.getWritableDatabase();
183     setupTable(db1, TABLE_NAME1);
184     setupTable(db2, TABLE_NAME2);
185     insertData(db1, TABLE_NAME1, new int[]{1, 2});
186     insertData(db2, TABLE_NAME2, new int[]{4, 5, 6});
187     verifyData(db1, TABLE_NAME1, 2);
188     verifyData(db2, TABLE_NAME2, 3);
189     db1.close();
190     verifyData(db2, TABLE_NAME2, 3);
191     db1 = helper.getWritableDatabase();
192     verifyData(db1, TABLE_NAME1, 2);
193     verifyData(db2, TABLE_NAME2, 3);
194   }
195 
196   @Test
testCreateAndDropTable()197   public void testCreateAndDropTable() throws Exception {
198     SQLiteDatabase database = helper.getWritableDatabase();
199     database.execSQL("CREATE TABLE foo(id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT);");
200     database.execSQL("DROP TABLE IF EXISTS foo;");
201   }
202 
203   @Test
testCloseThenOpen()204   public void testCloseThenOpen() throws Exception {
205     final String TABLE_NAME1 = "fart";
206     SQLiteDatabase db1 = helper.getWritableDatabase();
207     setupTable(db1, TABLE_NAME1);
208     insertData(db1, TABLE_NAME1, new int[]{1, 2});
209     verifyData(db1, TABLE_NAME1, 2);
210     db1.close();
211     db1 = helper.getWritableDatabase();
212     assertThat(db1.isOpen()).isTrue();
213   }
214 
assertInitialDB(SQLiteDatabase database, TestOpenHelper helper)215   private static void assertInitialDB(SQLiteDatabase database, TestOpenHelper helper) {
216     assertDatabaseOpened(database, helper);
217     assertThat(helper.onCreateCalled).isTrue();
218   }
219 
assertSubsequentDB(SQLiteDatabase database, TestOpenHelper helper)220   private static void assertSubsequentDB(SQLiteDatabase database, TestOpenHelper helper) {
221     assertDatabaseOpened(database, helper);
222     assertThat(helper.onCreateCalled).isFalse();
223   }
224 
assertDatabaseOpened(SQLiteDatabase database, TestOpenHelper helper)225   private static void assertDatabaseOpened(SQLiteDatabase database, TestOpenHelper helper) {
226     assertThat(database).isNotNull();
227     assertThat(database.isOpen()).isTrue();
228     assertThat(helper.onOpenCalled).isTrue();
229     assertThat(helper.onUpgradeCalled).isFalse();
230   }
231 
232   private static class TestOpenHelper extends SQLiteOpenHelper {
233     public boolean onCreateCalled;
234     public boolean onUpgradeCalled;
235     public boolean onOpenCalled;
236 
TestOpenHelper(Context context, String name, CursorFactory factory, int version)237     public TestOpenHelper(Context context, String name, CursorFactory factory, int version) {
238       super(context, name, factory, version);
239     }
240 
241     @Override
onCreate(SQLiteDatabase database)242       public void onCreate(SQLiteDatabase database) {
243         onCreateCalled = true;
244       }
245 
246     @Override
onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion)247     public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
248       onUpgradeCalled = true;
249     }
250 
251     @Override
onOpen(SQLiteDatabase database)252     public void onOpen(SQLiteDatabase database) {
253       onOpenCalled = true;
254     }
255 
256     @Override
close()257     public synchronized void close() {
258       onCreateCalled = false;
259       onUpgradeCalled = false;
260       onOpenCalled = false;
261 
262       super.close();
263     }
264   }
265 }
266