1/* 2 * Copyright (C) 2016 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 17package androidx.room; 18 19import static org.hamcrest.CoreMatchers.instanceOf; 20import static org.hamcrest.CoreMatchers.is; 21import static org.hamcrest.CoreMatchers.notNullValue; 22import static org.hamcrest.CoreMatchers.nullValue; 23import static org.hamcrest.MatcherAssert.assertThat; 24import static org.mockito.Mockito.mock; 25 26import static java.util.Arrays.asList; 27 28import android.content.Context; 29 30import androidx.annotation.NonNull; 31import androidx.room.migration.Migration; 32import androidx.sqlite.db.SupportSQLiteDatabase; 33import androidx.sqlite.db.SupportSQLiteOpenHelper; 34import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory; 35 36import org.hamcrest.CoreMatchers; 37import org.junit.Test; 38import org.junit.runner.RunWith; 39import org.junit.runners.JUnit4; 40 41import java.util.List; 42 43@SuppressWarnings("ArraysAsListWithZeroOrOneArgument") 44@RunWith(JUnit4.class) 45public class BuilderTest { 46 @Test(expected = IllegalArgumentException.class) 47 public void nullContext() { 48 //noinspection ConstantConditions 49 Room.databaseBuilder(null, RoomDatabase.class, "bla").build(); 50 } 51 52 @Test(expected = IllegalArgumentException.class) 53 public void nullContext2() { 54 //noinspection ConstantConditions 55 Room.inMemoryDatabaseBuilder(null, RoomDatabase.class).build(); 56 } 57 58 @Test(expected = IllegalArgumentException.class) 59 public void nullName() { 60 //noinspection ConstantConditions 61 Room.databaseBuilder(mock(Context.class), RoomDatabase.class, null).build(); 62 } 63 64 @Test(expected = IllegalArgumentException.class) 65 public void emptyName() { 66 Room.databaseBuilder(mock(Context.class), RoomDatabase.class, " ").build(); 67 } 68 69 @Test 70 public void migration() { 71 Migration m1 = new EmptyMigration(0, 1); 72 Migration m2 = new EmptyMigration(1, 2); 73 TestDatabase db = Room.databaseBuilder(mock(Context.class), TestDatabase.class, "foo") 74 .addMigrations(m1, m2).build(); 75 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 76 RoomDatabase.MigrationContainer migrations = config.migrationContainer; 77 assertThat(migrations.findMigrationPath(0, 1), is(asList(m1))); 78 assertThat(migrations.findMigrationPath(1, 2), is(asList(m2))); 79 assertThat(migrations.findMigrationPath(0, 2), is(asList(m1, m2))); 80 assertThat(migrations.findMigrationPath(2, 0), CoreMatchers.<List<Migration>>nullValue()); 81 assertThat(migrations.findMigrationPath(0, 3), CoreMatchers.<List<Migration>>nullValue()); 82 } 83 84 @Test 85 public void migrationOverride() { 86 Migration m1 = new EmptyMigration(0, 1); 87 Migration m2 = new EmptyMigration(1, 2); 88 Migration m3 = new EmptyMigration(0, 1); 89 TestDatabase db = Room.databaseBuilder(mock(Context.class), TestDatabase.class, "foo") 90 .addMigrations(m1, m2, m3).build(); 91 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 92 RoomDatabase.MigrationContainer migrations = config.migrationContainer; 93 assertThat(migrations.findMigrationPath(0, 1), is(asList(m3))); 94 assertThat(migrations.findMigrationPath(1, 2), is(asList(m2))); 95 assertThat(migrations.findMigrationPath(0, 3), CoreMatchers.<List<Migration>>nullValue()); 96 } 97 98 @Test 99 public void migrationJump() { 100 Migration m1 = new EmptyMigration(0, 1); 101 Migration m2 = new EmptyMigration(1, 2); 102 Migration m3 = new EmptyMigration(2, 3); 103 Migration m4 = new EmptyMigration(0, 3); 104 TestDatabase db = Room.databaseBuilder(mock(Context.class), TestDatabase.class, "foo") 105 .addMigrations(m1, m2, m3, m4).build(); 106 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 107 RoomDatabase.MigrationContainer migrations = config.migrationContainer; 108 assertThat(migrations.findMigrationPath(0, 3), is(asList(m4))); 109 assertThat(migrations.findMigrationPath(1, 3), is(asList(m2, m3))); 110 } 111 112 @Test 113 public void migrationDowngrade() { 114 Migration m1_2 = new EmptyMigration(1, 2); 115 Migration m2_3 = new EmptyMigration(2, 3); 116 Migration m3_4 = new EmptyMigration(3, 4); 117 Migration m3_2 = new EmptyMigration(3, 2); 118 Migration m2_1 = new EmptyMigration(2, 1); 119 TestDatabase db = Room.databaseBuilder(mock(Context.class), TestDatabase.class, "foo") 120 .addMigrations(m1_2, m2_3, m3_4, m3_2, m2_1).build(); 121 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 122 RoomDatabase.MigrationContainer migrations = config.migrationContainer; 123 assertThat(migrations.findMigrationPath(3, 2), is(asList(m3_2))); 124 assertThat(migrations.findMigrationPath(3, 1), is(asList(m3_2, m2_1))); 125 } 126 127 @Test 128 public void skipMigration() { 129 Context context = mock(Context.class); 130 131 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 132 .fallbackToDestructiveMigration() 133 .build(); 134 135 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 136 assertThat(config.requireMigration, is(false)); 137 } 138 139 @Test 140 public void fallbackToDestructiveMigrationFrom_calledOnce_migrationsNotRequiredForValues() { 141 Context context = mock(Context.class); 142 143 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 144 .fallbackToDestructiveMigrationFrom(1, 2).build(); 145 146 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 147 assertThat(config.isMigrationRequiredFrom(1), is(false)); 148 assertThat(config.isMigrationRequiredFrom(2), is(false)); 149 } 150 151 @Test 152 public void fallbackToDestructiveMigrationFrom_calledTwice_migrationsNotRequiredForValues() { 153 Context context = mock(Context.class); 154 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 155 .fallbackToDestructiveMigrationFrom(1, 2) 156 .fallbackToDestructiveMigrationFrom(3, 4) 157 .build(); 158 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 159 160 assertThat(config.isMigrationRequiredFrom(1), is(false)); 161 assertThat(config.isMigrationRequiredFrom(2), is(false)); 162 assertThat(config.isMigrationRequiredFrom(3), is(false)); 163 assertThat(config.isMigrationRequiredFrom(4), is(false)); 164 } 165 166 @Test 167 public void isMigrationRequiredFrom_fallBackToDestructiveCalled_alwaysReturnsFalse() { 168 Context context = mock(Context.class); 169 170 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 171 .fallbackToDestructiveMigration() 172 .build(); 173 174 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 175 assertThat(config.isMigrationRequiredFrom(0), is(false)); 176 assertThat(config.isMigrationRequiredFrom(1), is(false)); 177 assertThat(config.isMigrationRequiredFrom(5), is(false)); 178 assertThat(config.isMigrationRequiredFrom(12), is(false)); 179 assertThat(config.isMigrationRequiredFrom(132), is(false)); 180 } 181 182 @Test 183 public void isMigrationRequiredFrom_byDefault_alwaysReturnsTrue() { 184 Context context = mock(Context.class); 185 186 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 187 .build(); 188 189 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 190 assertThat(config.isMigrationRequiredFrom(0), is(true)); 191 assertThat(config.isMigrationRequiredFrom(1), is(true)); 192 assertThat(config.isMigrationRequiredFrom(5), is(true)); 193 assertThat(config.isMigrationRequiredFrom(12), is(true)); 194 assertThat(config.isMigrationRequiredFrom(132), is(true)); 195 } 196 197 @Test 198 public void isMigrationRequiredFrom_fallBackToDestFromCalled_falseForProvidedValues() { 199 Context context = mock(Context.class); 200 201 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 202 .fallbackToDestructiveMigrationFrom(1, 4, 81) 203 .build(); 204 205 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 206 assertThat(config.isMigrationRequiredFrom(1), is(false)); 207 assertThat(config.isMigrationRequiredFrom(4), is(false)); 208 assertThat(config.isMigrationRequiredFrom(81), is(false)); 209 } 210 211 @Test 212 public void isMigrationRequiredFrom_fallBackToDestFromCalled_trueForNonProvidedValues() { 213 Context context = mock(Context.class); 214 215 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 216 .fallbackToDestructiveMigrationFrom(1, 4, 81) 217 .build(); 218 219 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 220 assertThat(config.isMigrationRequiredFrom(2), is(true)); 221 assertThat(config.isMigrationRequiredFrom(3), is(true)); 222 assertThat(config.isMigrationRequiredFrom(73), is(true)); 223 } 224 225 @Test 226 public void createBasic() { 227 Context context = mock(Context.class); 228 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build(); 229 assertThat(db, instanceOf(BuilderTest_TestDatabase_Impl.class)); 230 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 231 assertThat(config, notNullValue()); 232 assertThat(config.context, is(context)); 233 assertThat(config.name, is(nullValue())); 234 assertThat(config.allowMainThreadQueries, is(false)); 235 assertThat(config.journalMode, is(RoomDatabase.JournalMode.TRUNCATE)); 236 assertThat(config.sqliteOpenHelperFactory, 237 instanceOf(FrameworkSQLiteOpenHelperFactory.class)); 238 } 239 240 @Test 241 public void createAllowMainThread() { 242 Context context = mock(Context.class); 243 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 244 .allowMainThreadQueries() 245 .build(); 246 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 247 assertThat(config.allowMainThreadQueries, is(true)); 248 } 249 250 @Test 251 public void createWriteAheadLogging() { 252 Context context = mock(Context.class); 253 TestDatabase db = Room.databaseBuilder(context, TestDatabase.class, "foo") 254 .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING).build(); 255 assertThat(db, instanceOf(BuilderTest_TestDatabase_Impl.class)); 256 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 257 assertThat(config.journalMode, is(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING)); 258 } 259 260 @Test 261 public void createWithFactoryAndVersion() { 262 Context context = mock(Context.class); 263 SupportSQLiteOpenHelper.Factory factory = mock(SupportSQLiteOpenHelper.Factory.class); 264 265 TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class) 266 .openHelperFactory(factory) 267 .build(); 268 assertThat(db, instanceOf(BuilderTest_TestDatabase_Impl.class)); 269 DatabaseConfiguration config = ((BuilderTest_TestDatabase_Impl) db).mConfig; 270 assertThat(config, notNullValue()); 271 assertThat(config.sqliteOpenHelperFactory, is(factory)); 272 } 273 274 abstract static class TestDatabase extends RoomDatabase { 275 } 276 277 static class EmptyMigration extends Migration { 278 EmptyMigration(int start, int end) { 279 super(start, end); 280 } 281 282 @Override 283 public void migrate(@NonNull SupportSQLiteDatabase database) { 284 } 285 } 286 287} 288