1 /* <lambda>null2 * 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 package androidx.room 17 18 import android.content.Context 19 import androidx.kruth.assertThat 20 import androidx.kruth.assertThrows 21 import androidx.room.Room.databaseBuilder 22 import androidx.room.Room.inMemoryDatabaseBuilder 23 import androidx.room.migration.Migration 24 import androidx.sqlite.SQLiteDriver 25 import androidx.sqlite.db.SupportSQLiteDatabase 26 import androidx.sqlite.db.SupportSQLiteOpenHelper 27 import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory 28 import instantiateImpl 29 import java.io.File 30 import java.util.concurrent.Executor 31 import java.util.concurrent.TimeUnit 32 import kotlin.coroutines.EmptyCoroutineContext 33 import kotlinx.coroutines.Dispatchers 34 import org.junit.Assert 35 import org.junit.Test 36 import org.junit.runner.RunWith 37 import org.junit.runners.JUnit4 38 import org.mockito.kotlin.any 39 import org.mockito.kotlin.mock 40 import org.mockito.kotlin.whenever 41 42 @RunWith(JUnit4::class) 43 class BuilderTest { 44 @Test 45 fun nullName() { 46 try { 47 databaseBuilder(mock(), RoomDatabase::class.java, null).build() 48 } catch (e: IllegalArgumentException) { 49 assertThat(e.message) 50 .isEqualTo( 51 "Cannot build a database with null or empty name. If you are trying to create an " + 52 "in memory database, use Room.inMemoryDatabaseBuilder" 53 ) 54 } 55 } 56 57 @Test 58 fun databaseBuilderWithFactory() { 59 val db = 60 databaseBuilder( 61 context = mock(), 62 name = "TestDatabase", 63 factory = { TestDatabase::class.instantiateImpl() } 64 ) 65 .build() 66 // Assert that the db is built successfully. 67 assertThat(db).isInstanceOf<TestDatabase>() 68 } 69 70 @Test 71 fun emptyName() { 72 try { 73 databaseBuilder(mock(), RoomDatabase::class.java, " ").build() 74 } catch (e: IllegalArgumentException) { 75 assertThat(e.message) 76 .isEqualTo( 77 "Cannot build a database with null or empty name. If you are trying to create an " + 78 "in memory database, use Room.inMemoryDatabaseBuilder" 79 ) 80 } 81 } 82 83 @Test 84 fun specialMemoryName() { 85 try { 86 databaseBuilder(mock(), RoomDatabase::class.java, ":memory:").build() 87 } catch (e: IllegalArgumentException) { 88 assertThat(e.message) 89 .isEqualTo( 90 "Cannot build a database with the special name ':memory:'. If you are trying " + 91 "to create an in memory database, use Room.inMemoryDatabaseBuilder" 92 ) 93 } 94 } 95 96 @Test 97 fun executors_setQueryExecutor() { 98 val executor: Executor = mock() 99 val db = 100 databaseBuilder(mock(), TestDatabase::class.java, "foo") 101 .setQueryExecutor(executor) 102 .build() 103 104 assertThat(db.databaseConfiguration.queryExecutor).isEqualTo(executor) 105 assertThat(db.databaseConfiguration.transactionExecutor).isEqualTo(executor) 106 } 107 108 @Test 109 fun executors_setTransactionExecutor() { 110 val executor: Executor = mock() 111 val db = 112 databaseBuilder(mock(), TestDatabase::class.java, "foo") 113 .setTransactionExecutor(executor) 114 .build() 115 116 assertThat(db.databaseConfiguration.queryExecutor).isEqualTo(executor) 117 assertThat(db.databaseConfiguration.transactionExecutor).isEqualTo(executor) 118 } 119 120 @Test 121 fun executors_setBothExecutors() { 122 val executor1: Executor = mock() 123 val executor2: Executor = mock() 124 val db = 125 databaseBuilder(mock(), TestDatabase::class.java, "foo") 126 .setQueryExecutor(executor1) 127 .setTransactionExecutor(executor2) 128 .build() 129 130 assertThat(db.databaseConfiguration.queryExecutor).isEqualTo(executor1) 131 assertThat(db.databaseConfiguration.transactionExecutor).isEqualTo(executor2) 132 } 133 134 @Test 135 fun executors_setCoroutineContext() { 136 assertThrows<IllegalArgumentException> { 137 databaseBuilder(mock(), TestDatabase::class.java, "foo") 138 .setQueryCoroutineContext(Dispatchers.IO) 139 .setTransactionExecutor(mock()) 140 .build() 141 } 142 .hasMessageThat() 143 .contains("This builder has already been configured with a CoroutineContext.") 144 } 145 146 @Test 147 fun coroutineContext_setQueryExecutor() { 148 assertThrows<IllegalArgumentException> { 149 databaseBuilder(mock(), TestDatabase::class.java, "foo") 150 .setQueryExecutor(mock()) 151 .setQueryCoroutineContext(Dispatchers.IO) 152 .build() 153 } 154 .hasMessageThat() 155 .contains("This builder has already been configured with an Executor.") 156 } 157 158 @Test 159 fun coroutineContext_setTransactionExecutor() { 160 assertThrows<IllegalArgumentException> { 161 databaseBuilder(mock(), TestDatabase::class.java, "foo") 162 .setTransactionExecutor(mock()) 163 .setQueryCoroutineContext(Dispatchers.IO) 164 .build() 165 } 166 .hasMessageThat() 167 .contains("This builder has already been configured with an Executor.") 168 } 169 170 @Test 171 fun coroutineContext_missingDispatcher() { 172 assertThrows<IllegalArgumentException> { 173 databaseBuilder(mock(), TestDatabase::class.java, "foo") 174 .setQueryCoroutineContext(EmptyCoroutineContext) 175 .build() 176 } 177 .hasMessageThat() 178 .contains("It is required that the coroutine context contain a dispatcher.") 179 } 180 181 @Test 182 fun migration() { 183 val m1: Migration = EmptyMigration(0, 1) 184 val m2: Migration = EmptyMigration(1, 2) 185 val db = 186 databaseBuilder(mock(), TestDatabase::class.java, "foo").addMigrations(m1, m2).build() 187 188 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 189 val migrations = config.migrationContainer 190 191 assertThat(migrations.findMigrationPath(0, 1)).containsExactlyElementsIn(listOf(m1)) 192 assertThat(migrations.findMigrationPath(1, 2)).containsExactlyElementsIn(listOf(m2)) 193 assertThat(migrations.findMigrationPath(0, 2)).containsExactlyElementsIn(listOf(m1, m2)) 194 assertThat(migrations.findMigrationPath(2, 0)).isNull() 195 assertThat(migrations.findMigrationPath(0, 3)).isNull() 196 } 197 198 @Test 199 fun migrationOverride() { 200 val m1: Migration = EmptyMigration(0, 1) 201 val m2: Migration = EmptyMigration(1, 2) 202 val m3: Migration = EmptyMigration(0, 1) 203 val db = 204 databaseBuilder(mock(), TestDatabase::class.java, "foo") 205 .addMigrations(m1, m2, m3) 206 .build() 207 208 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 209 val migrations = config.migrationContainer 210 211 assertThat(migrations.findMigrationPath(0, 1)).containsExactlyElementsIn(listOf(m3)) 212 assertThat(migrations.findMigrationPath(1, 2)).containsExactlyElementsIn(listOf(m2)) 213 assertThat(migrations.findMigrationPath(0, 3)).isNull() 214 } 215 216 @Test 217 fun migrationJump() { 218 val m1: Migration = EmptyMigration(0, 1) 219 val m2: Migration = EmptyMigration(1, 2) 220 val m3: Migration = EmptyMigration(2, 3) 221 val m4: Migration = EmptyMigration(0, 3) 222 val db = 223 databaseBuilder(mock(), TestDatabase::class.java, "foo") 224 .addMigrations(m1, m2, m3, m4) 225 .build() 226 227 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 228 val migrations = config.migrationContainer 229 230 assertThat(migrations.findMigrationPath(0, 3)).containsExactlyElementsIn(listOf(m4)) 231 assertThat(migrations.findMigrationPath(1, 3)).containsExactlyElementsIn(listOf(m2, m3)) 232 } 233 234 @Test 235 fun migrationDowngrade() { 236 val m1_2: Migration = EmptyMigration(1, 2) 237 val m2_3: Migration = EmptyMigration(2, 3) 238 val m3_4: Migration = EmptyMigration(3, 4) 239 val m3_2: Migration = EmptyMigration(3, 2) 240 val m2_1: Migration = EmptyMigration(2, 1) 241 val db = 242 databaseBuilder(mock(), TestDatabase::class.java, "foo") 243 .addMigrations(m1_2, m2_3, m3_4, m3_2, m2_1) 244 .build() 245 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 246 val migrations = config.migrationContainer 247 assertThat(migrations.findMigrationPath(3, 2)).containsExactlyElementsIn(listOf(m3_2)) 248 assertThat(migrations.findMigrationPath(3, 1)).containsExactlyElementsIn(listOf(m3_2, m2_1)) 249 } 250 251 @Test 252 fun skipMigration() { 253 val context: Context = mock() 254 val db = 255 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 256 .fallbackToDestructiveMigration(false) 257 .build() 258 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 259 assertThat(config.requireMigration).isFalse() 260 } 261 262 @Test 263 fun fallbackToDestructiveMigrationFrom_calledOnce_migrationsNotRequiredForValues() { 264 val context: Context = mock() 265 val db = 266 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 267 .fallbackToDestructiveMigrationFrom(true, 1, 2) 268 .build() 269 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 270 assertThat(config.isMigrationRequired(1, 2)).isFalse() 271 assertThat(config.isMigrationRequired(2, 3)).isFalse() 272 } 273 274 @Test 275 fun fallbackToDestructiveMigrationFrom_calledTwice_migrationsNotRequiredForValues() { 276 val context: Context = mock() 277 val db = 278 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 279 .fallbackToDestructiveMigrationFrom(true, 1, 2) 280 .fallbackToDestructiveMigrationFrom(true, 3, 4) 281 .build() 282 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 283 assertThat(config.isMigrationRequired(1, 2)).isFalse() 284 assertThat(config.isMigrationRequired(2, 3)).isFalse() 285 assertThat(config.isMigrationRequired(3, 4)).isFalse() 286 assertThat(config.isMigrationRequired(4, 5)).isFalse() 287 } 288 289 @Test 290 fun isMigrationRequiredFrom_fallBackToDestructiveCalled_alwaysReturnsFalse() { 291 val context: Context = mock() 292 val db = 293 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 294 .fallbackToDestructiveMigration(false) 295 .build() 296 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 297 298 assertThat(config.isMigrationRequired(0, 1)).isFalse() 299 assertThat(config.isMigrationRequired(1, 2)).isFalse() 300 assertThat(config.isMigrationRequired(5, 6)).isFalse() 301 assertThat(config.isMigrationRequired(7, 12)).isFalse() 302 assertThat(config.isMigrationRequired(132, 150)).isFalse() 303 304 assertThat(config.isMigrationRequired(1, 0)).isFalse() 305 assertThat(config.isMigrationRequired(2, 1)).isFalse() 306 assertThat(config.isMigrationRequired(6, 5)).isFalse() 307 assertThat(config.isMigrationRequired(7, 12)).isFalse() 308 assertThat(config.isMigrationRequired(150, 132)).isFalse() 309 } 310 311 // isMigrationRequiredFrom doesn't know about downgrade only so it always returns true 312 @Test 313 fun isMigrationRequired_destructiveMigrationOnDowngrade_returnTrueWhenUpgrading() { 314 val context: Context = mock() 315 val db = 316 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 317 .fallbackToDestructiveMigrationOnDowngrade(false) 318 .build() 319 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 320 321 // isMigrationRequiredFrom doesn't know about downgrade only so it always returns true 322 assertThat(config.isMigrationRequired(0, 1)).isTrue() 323 assertThat(config.isMigrationRequired(1, 2)).isTrue() 324 assertThat(config.isMigrationRequired(5, 6)).isTrue() 325 assertThat(config.isMigrationRequired(7, 12)).isTrue() 326 assertThat(config.isMigrationRequired(132, 150)).isTrue() 327 } 328 329 // isMigrationRequiredFrom doesn't know about downgrade only so it always returns true 330 @Test 331 fun isMigrationRequired_destructiveMigrationOnDowngrade_returnFalseWhenDowngrading() { 332 val context: Context = mock() 333 val db = 334 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 335 .fallbackToDestructiveMigrationOnDowngrade(false) 336 .build() 337 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 338 339 // isMigrationRequiredFrom doesn't know about downgrade only so it always returns true 340 assertThat(config.isMigrationRequired(1, 0)).isFalse() 341 assertThat(config.isMigrationRequired(2, 1)).isFalse() 342 assertThat(config.isMigrationRequired(6, 5)).isFalse() 343 assertThat(config.isMigrationRequired(12, 7)).isFalse() 344 assertThat(config.isMigrationRequired(150, 132)).isFalse() 345 } 346 347 @Test 348 fun isMigrationRequiredFrom_byDefault_alwaysReturnsTrue() { 349 val context: Context = mock() 350 val db = inMemoryDatabaseBuilder(context, TestDatabase::class.java).build() 351 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 352 353 assertThat(config.isMigrationRequired(0, 1)).isTrue() 354 assertThat(config.isMigrationRequired(1, 2)).isTrue() 355 assertThat(config.isMigrationRequired(5, 6)).isTrue() 356 assertThat(config.isMigrationRequired(7, 12)).isTrue() 357 assertThat(config.isMigrationRequired(132, 150)).isTrue() 358 359 assertThat(config.isMigrationRequired(1, 0)).isTrue() 360 assertThat(config.isMigrationRequired(2, 1)).isTrue() 361 assertThat(config.isMigrationRequired(6, 5)).isTrue() 362 assertThat(config.isMigrationRequired(7, 12)).isTrue() 363 assertThat(config.isMigrationRequired(150, 132)).isTrue() 364 } 365 366 @Test 367 fun isMigrationRequiredFrom_fallBackToDestFromCalled_falseForProvidedValues() { 368 val context: Context = mock() 369 val db = 370 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 371 .fallbackToDestructiveMigrationFrom(true, 1, 4, 81) 372 .build() 373 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 374 assertThat(config.isMigrationRequired(1, 2)).isFalse() 375 assertThat(config.isMigrationRequired(4, 8)).isFalse() 376 assertThat(config.isMigrationRequired(81, 90)).isFalse() 377 } 378 379 @Test 380 fun isMigrationRequiredFrom_fallBackToDestFromCalled_trueForNonProvidedValues() { 381 val context: Context = mock() 382 val db = 383 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 384 .fallbackToDestructiveMigrationFrom(true, 1, 4, 81) 385 .build() 386 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 387 assertThat(config.isMigrationRequired(2, 3)).isTrue() 388 assertThat(config.isMigrationRequired(3, 4)).isTrue() 389 assertThat(config.isMigrationRequired(73, 80)).isTrue() 390 } 391 392 @Test 393 fun autoMigrationShouldBeAddedToMigrations_WhenManualDowngradeMigrationIsPresent() { 394 val context: Context = mock() 395 val db = 396 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 397 .addMigrations(EmptyMigration(1, 0)) 398 .build() as BuilderTest_TestDatabase_Impl 399 val config: DatabaseConfiguration = db.databaseConfiguration 400 assertThat(config.migrationContainer.findMigrationPath(1, 2)) 401 .isEqualTo((db.mAutoMigrations)) 402 } 403 404 @Test 405 fun fallbackToDestructiveMigrationOnDowngrade_withProvidedValues_falseForDowngrades() { 406 val context: Context = mock() 407 val db = 408 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 409 .fallbackToDestructiveMigrationOnDowngrade(false) 410 .fallbackToDestructiveMigrationFrom(true, 2, 4) 411 .build() 412 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 413 assertThat(config.isMigrationRequired(1, 2)).isTrue() 414 assertThat(config.isMigrationRequired(2, 3)).isFalse() 415 assertThat(config.isMigrationRequired(3, 4)).isTrue() 416 assertThat(config.isMigrationRequired(4, 5)).isFalse() 417 assertThat(config.isMigrationRequired(5, 6)).isTrue() 418 assertThat(config.isMigrationRequired(2, 1)).isFalse() 419 assertThat(config.isMigrationRequired(3, 2)).isFalse() 420 assertThat(config.isMigrationRequired(4, 3)).isFalse() 421 assertThat(config.isMigrationRequired(5, 4)).isFalse() 422 assertThat(config.isMigrationRequired(6, 5)).isFalse() 423 } 424 425 @Test 426 fun createBasic() { 427 val context: Context = mock() 428 val db = inMemoryDatabaseBuilder(context, TestDatabase::class.java).build() 429 assertThat(db).isInstanceOf<BuilderTest_TestDatabase_Impl>() 430 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 431 assertThat(config).isNotNull() 432 assertThat(config.context).isEqualTo(context) 433 assertThat(config.name).isNull() 434 assertThat(config.allowMainThreadQueries).isFalse() 435 assertThat(config.journalMode).isEqualTo(RoomDatabase.JournalMode.TRUNCATE) 436 assertThat(config.sqliteOpenHelperFactory).isInstanceOf<FrameworkSQLiteOpenHelperFactory>() 437 } 438 439 @Test 440 fun createAllowMainThread() { 441 val context: Context = mock() 442 val db = 443 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 444 .allowMainThreadQueries() 445 .build() 446 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 447 assertThat(config.allowMainThreadQueries).isTrue() 448 } 449 450 @Test 451 fun createWriteAheadLogging() { 452 val context: Context = mock() 453 val db = 454 databaseBuilder(context, TestDatabase::class.java, "foo") 455 .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING) 456 .build() 457 assertThat(db).isInstanceOf<BuilderTest_TestDatabase_Impl>() 458 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 459 assertThat(config.journalMode).isEqualTo(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING) 460 } 461 462 @Test 463 fun createWithFactoryAndVersion() { 464 val context: Context = mock() 465 val factory: SupportSQLiteOpenHelper.Factory = mock() 466 whenever(factory.create(any())).thenReturn(mock()) 467 val db = 468 inMemoryDatabaseBuilder(context, TestDatabase::class.java) 469 .openHelperFactory(factory) 470 .build() 471 assertThat(db).isInstanceOf<BuilderTest_TestDatabase_Impl>() 472 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 473 assertThat(config).isNotNull() 474 assertThat(config.sqliteOpenHelperFactory).isEqualTo(factory) 475 } 476 477 @Test 478 fun createFromAssetAndFromFile() { 479 var exception: Exception? = null 480 try { 481 databaseBuilder(mock(), TestDatabase::class.java, "foo") 482 .createFromAsset("assets-path") 483 .createFromFile(File("not-a--real-file")) 484 .build() 485 Assert.fail("Build should have thrown") 486 } catch (e: Exception) { 487 exception = e 488 } 489 assertThat(exception).isInstanceOf<IllegalArgumentException>() 490 assertThat(exception) 491 .hasMessageThat() 492 .contains( 493 "More than one of createFromAsset(), " + 494 "createFromInputStream(), and createFromFile() were called on this Builder" 495 ) 496 } 497 498 @Test 499 fun createInMemoryFromAsset() { 500 var exception: Exception? = null 501 try { 502 inMemoryDatabaseBuilder(mock(), TestDatabase::class.java) 503 .createFromAsset("assets-path") 504 .build() 505 Assert.fail("Build should have thrown") 506 } catch (e: Exception) { 507 exception = e 508 } 509 assertThat(exception).isInstanceOf<IllegalArgumentException>() 510 assertThat(exception) 511 .hasMessageThat() 512 .contains("Cannot create from asset or file for an in-memory") 513 } 514 515 @Test 516 fun createInMemoryFromFile() { 517 var exception: Exception? = null 518 try { 519 inMemoryDatabaseBuilder(mock(), TestDatabase::class.java) 520 .createFromFile(File("not-a--real-file")) 521 .build() 522 Assert.fail("Build should have thrown") 523 } catch (e: Exception) { 524 exception = e 525 } 526 assertThat(exception).isInstanceOf<IllegalArgumentException>() 527 assertThat(exception) 528 .hasMessageThat() 529 .contains("Cannot create from asset or file for an in-memory") 530 } 531 532 @Test 533 fun driverProvided() { 534 val driver: SQLiteDriver = mock() 535 val db = inMemoryDatabaseBuilder(mock(), TestDatabase::class.java).setDriver(driver).build() 536 assertThat(db).isInstanceOf<BuilderTest_TestDatabase_Impl>() 537 val config: DatabaseConfiguration = (db as BuilderTest_TestDatabase_Impl).mConfig 538 assertThat(config.sqliteDriver).isEqualTo(driver) 539 assertThat(config.sqliteOpenHelperFactory).isNull() 540 } 541 542 @Test 543 fun bothDriverAndFactoryProvided() { 544 try { 545 inMemoryDatabaseBuilder(mock(), RoomDatabase::class.java) 546 .setDriver(mock()) 547 .openHelperFactory(mock()) 548 .build() 549 } catch (e: IllegalArgumentException) { 550 assertThat(e.message) 551 .isEqualTo( 552 "A RoomDatabase cannot be configured with both a SQLiteDriver and a " + 553 "SupportOpenHelper.Factory." 554 ) 555 } 556 } 557 558 @OptIn(ExperimentalRoomApi::class) 559 @Test 560 fun driverProvidedAutoClose() { 561 assertThrows<IllegalArgumentException> { 562 inMemoryDatabaseBuilder(mock(), TestDatabase::class.java) 563 .setAutoCloseTimeout(3, TimeUnit.SECONDS) 564 .setDriver(mock()) 565 .build() 566 } 567 .hasMessageThat() 568 .isEqualTo("Auto Closing Database is not supported when an SQLiteDriver is configured.") 569 } 570 571 @OptIn(ExperimentalRoomApi::class) 572 @Test 573 fun driverProvidedPrePackaged() { 574 assertThrows<IllegalArgumentException> { 575 inMemoryDatabaseBuilder(mock(), TestDatabase::class.java) 576 .createFromAsset("asset.db") 577 .setDriver(mock()) 578 .build() 579 } 580 .hasMessageThat() 581 .isEqualTo("Pre-Package Database is not supported when an SQLiteDriver is configured.") 582 } 583 584 @OptIn(ExperimentalRoomApi::class) 585 @Test 586 fun driverProvidedQueryCallback() { 587 assertThrows<IllegalArgumentException> { 588 inMemoryDatabaseBuilder(mock(), TestDatabase::class.java) 589 .setQueryCallback(Dispatchers.IO) { _, _ -> } 590 .setDriver(mock()) 591 .build() 592 } 593 .hasMessageThat() 594 .isEqualTo("Query Callback is not supported when an SQLiteDriver is configured.") 595 } 596 597 internal abstract class TestDatabase : RoomDatabase() { 598 lateinit var databaseConfiguration: DatabaseConfiguration 599 600 override fun init(configuration: DatabaseConfiguration) { 601 super.init(configuration) 602 databaseConfiguration = configuration 603 } 604 } 605 606 internal class EmptyMigration(start: Int, end: Int) : Migration(start, end) { 607 override fun migrate(db: SupportSQLiteDatabase) {} 608 } 609 } 610