From 2ca239781c87d0271078a96d13db33c1790fcf6a Mon Sep 17 00:00:00 2001 From: Vinita Murthi Date: Tue, 16 Jun 2020 22:03:02 +0530 Subject: [PATCH] Limit the characters to 100 per line in the utility and data modules (#1315) * Fix line length errors * Fix lint errors in data module * Update circleci ktlint method * Change import ordering to follow intelliJ optimized imports * Only lint src files of modules * New line at EOF in editorconfig * Fix lint issues in merged PRs * Fix parser error * Reformat DataProvidersTest * Review changes * Add space after end comment --- .circleci/config.yml | 2 +- .editorconfig | 1 + .../backends/gae/api/ExplorationService.kt | 4 +- .../data/backends/gae/api/SubtopicService.kt | 5 +- .../gae/model/GaeExplorationContainer.kt | 30 +- .../gae/model/GaeWrittenTranslations.kt | 3 +- .../data/persistence/PersistentCacheStore.kt | 49 +- .../backends/test/NetworkInterceptorTest.kt | 30 +- .../persistence/PersistentCacheStoreTest.kt | 166 +++- .../org/oppia/util/caching/AssetRepository.kt | 9 +- .../java/org/oppia/util/data/AsyncResult.kt | 23 +- .../java/org/oppia/util/data/DataProviders.kt | 11 +- .../oppia/util/data/InMemoryBlockingCache.kt | 23 +- .../util/networking/NetworkConnectionUtil.kt | 15 +- .../java/org/oppia/util/parser/HtmlParser.kt | 37 +- .../util/parser/RepositoryGlideModule.kt | 6 +- .../util/parser/RepositoryModelLoader.kt | 8 +- .../org/oppia/util/data/AsyncResultTest.kt | 165 ++-- .../org/oppia/util/data/DataProvidersTest.kt | 751 ++++++++++++------ .../util/data/InMemoryBlockingCacheTest.kt | 363 +++++---- .../oppia/util/datetime/DateTimeUtilTest.kt | 8 +- .../networking/NetworkConnectionUtilTest.kt | 54 +- .../profile/DirectoryManagementUtilTest.kt | 8 +- 23 files changed, 1196 insertions(+), 575 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d84c8f9e550..07e8a302b8c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -80,7 +80,7 @@ jobs: chmod +x /home/circleci/oppia-android/buf - run: name: Kotlin tests - Data, Utility - command: ./ktlint utility/**/*.kt data/**/*.kt && echo "Lint completed successfully" + command: ./ktlint --android utility/src/**/*.kt data/src/**/*.kt && echo "Lint completed successfully" - run: name: Protobuf lint check command: ./buf check lint --input=model/src/main/proto --input-config buf.yaml && echo "Protobuf lint check completed successfully" diff --git a/.editorconfig b/.editorconfig index 683c9e91d7a..16f61bea844 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,4 @@ [*.{kt,kts}] # possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely) indent_size=2 +kotlin_imports_layout=idea diff --git a/data/src/main/java/org/oppia/data/backends/gae/api/ExplorationService.kt b/data/src/main/java/org/oppia/data/backends/gae/api/ExplorationService.kt index 8b4434ae9f4..b1d8cc4335b 100755 --- a/data/src/main/java/org/oppia/data/backends/gae/api/ExplorationService.kt +++ b/data/src/main/java/org/oppia/data/backends/gae/api/ExplorationService.kt @@ -9,5 +9,7 @@ import retrofit2.http.Path interface ExplorationService { @GET("explorehandler/init/{exploration_id}") - fun getExplorationById(@Path("exploration_id") explorationId: String): Call + fun getExplorationById( + @Path("exploration_id") explorationId: String + ): Call } diff --git a/data/src/main/java/org/oppia/data/backends/gae/api/SubtopicService.kt b/data/src/main/java/org/oppia/data/backends/gae/api/SubtopicService.kt index 9b50decf7b6..6f92e5bfa0d 100644 --- a/data/src/main/java/org/oppia/data/backends/gae/api/SubtopicService.kt +++ b/data/src/main/java/org/oppia/data/backends/gae/api/SubtopicService.kt @@ -9,5 +9,8 @@ import retrofit2.http.Path interface SubtopicService { @GET("subtopic_data_handler/{topic_name}/{subtopic_id}") - fun getSubtopic(@Path("topic_name") topicName: String, @Path("subtopic_id") subtopicId: String): Call + fun getSubtopic( + @Path("topic_name") topicName: String, + @Path("subtopic_id") subtopicId: String + ): Call } diff --git a/data/src/main/java/org/oppia/data/backends/gae/model/GaeExplorationContainer.kt b/data/src/main/java/org/oppia/data/backends/gae/model/GaeExplorationContainer.kt index 78ba3ce6e5a..8f82c34982b 100755 --- a/data/src/main/java/org/oppia/data/backends/gae/model/GaeExplorationContainer.kt +++ b/data/src/main/java/org/oppia/data/backends/gae/model/GaeExplorationContainer.kt @@ -10,15 +10,25 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class GaeExplorationContainer( - @Json(name = "record_playthrough_probability") val recordPlaythroughProbability: Float?, - @Json(name = "exploration_id") val explorationId: String?, - @Json(name = "state_classifier_mapping") val stateClassifierMapping: Map?, - @Json(name = "user_email") val userEmail: String?, - @Json(name = "version") val version: Int?, - @Json(name = "correctness_feedback_enabled") val isCorrectnessFeedbackEnabled: Boolean?, - @Json(name = "username") val username: String?, - @Json(name = "is_logged_in") val isLoggedIn: Boolean?, - @Json(name = "exploration") val exploration: GaeExploration?, - @Json(name = "session_id") val sessionId: String? + @Json(name = "record_playthrough_probability") + val recordPlaythroughProbability: Float?, + @Json(name = "exploration_id") + val explorationId: String?, + @Json(name = "state_classifier_mapping") + val stateClassifierMapping: Map?, + @Json(name = "user_email") + val userEmail: String?, + @Json(name = "version") + val version: Int?, + @Json(name = "correctness_feedback_enabled") + val isCorrectnessFeedbackEnabled: Boolean?, + @Json(name = "username") + val username: String?, + @Json(name = "is_logged_in") + val isLoggedIn: Boolean?, + @Json(name = "exploration") + val exploration: GaeExploration?, + @Json(name = "session_id") + val sessionId: String? ) diff --git a/data/src/main/java/org/oppia/data/backends/gae/model/GaeWrittenTranslations.kt b/data/src/main/java/org/oppia/data/backends/gae/model/GaeWrittenTranslations.kt index 085b7453558..7d33487e3e2 100755 --- a/data/src/main/java/org/oppia/data/backends/gae/model/GaeWrittenTranslations.kt +++ b/data/src/main/java/org/oppia/data/backends/gae/model/GaeWrittenTranslations.kt @@ -10,6 +10,7 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class GaeWrittenTranslations( - @Json(name = "translations_mapping") val translationsMapping: Map>? + @Json(name = "translations_mapping") + val translationsMapping: Map>? ) diff --git a/data/src/main/java/org/oppia/data/persistence/PersistentCacheStore.kt b/data/src/main/java/org/oppia/data/persistence/PersistentCacheStore.kt index deac52cc6e9..e28186a3297 100644 --- a/data/src/main/java/org/oppia/data/persistence/PersistentCacheStore.kt +++ b/data/src/main/java/org/oppia/data/persistence/PersistentCacheStore.kt @@ -43,8 +43,10 @@ class PersistentCacheStore private constructor( private val failureLock = ReentrantLock() private val cacheFile = File(directory, cacheFileName) - @GuardedBy("failureLock") private var deferredLoadCacheFailure: Throwable? = null - private val cache = cacheFactory.create(CachePayload(state = CacheState.UNLOADED, value = initialValue)) + @GuardedBy("failureLock") + private var deferredLoadCacheFailure: Throwable? = null + private val cache = + cacheFactory.create(CachePayload(state = CacheState.UNLOADED, value = initialValue)) init { cache.observeChanges { @@ -146,10 +148,16 @@ class PersistentCacheStore private constructor( } /** See [storeDataAsync]. Stores data and allows for a custom deferred result. */ - fun storeDataWithCustomChannelAsync(updateInMemoryCache: Boolean = true, update: (T) -> Pair): Deferred { + fun storeDataWithCustomChannelAsync( + updateInMemoryCache: Boolean = true, + update: (T) -> Pair + ): Deferred { return cache.updateWithCustomChannelIfPresentAsync { cachedPayload -> val (updatedPayload, customResult) = storeFileCacheWithCustomChannel(cachedPayload, update) - if (updateInMemoryCache) Pair(updatedPayload, customResult) else Pair(cachedPayload, customResult) + if (updateInMemoryCache) Pair(updatedPayload, customResult) else Pair( + cachedPayload, + customResult + ) } } @@ -222,10 +230,16 @@ class PersistentCacheStore private constructor( } /** See [storeFileCache]. Returns payload and custom result. */ - private fun storeFileCacheWithCustomChannel(currentPayload: CachePayload, update: (T) -> Pair): Pair, V> { + private fun storeFileCacheWithCustomChannel( + currentPayload: CachePayload, + update: (T) -> Pair + ): Pair, V> { val (updatedCacheValue, customResult) = update(currentPayload.value) FileOutputStream(cacheFile).use { updatedCacheValue.writeTo(it) } - return Pair(CachePayload(state = CacheState.IN_MEMORY_AND_ON_DISK, value = updatedCacheValue), customResult) + return Pair( + CachePayload(state = CacheState.IN_MEMORY_AND_ON_DISK, value = updatedCacheValue), + customResult + ) } private data class PersistentCacheStoreId(private val id: String) @@ -268,16 +282,33 @@ class PersistentCacheStore private constructor( * Use this method when data is shared by all profiles. */ fun create(cacheName: String, initialValue: T): PersistentCacheStore { - return PersistentCacheStore(context, cacheFactory, asyncDataSubscriptionManager, cacheName, initialValue) + return PersistentCacheStore( + context, + cacheFactory, + asyncDataSubscriptionManager, + cacheName, + initialValue + ) } /** * Returns a new [PersistentCacheStore] with the specified cache name and initial value under the directory specified by profileId. * Use this method when data is unique to each profile. */ - fun createPerProfile(cacheName: String, initialValue: T, profileId: ProfileId): PersistentCacheStore { + fun createPerProfile( + cacheName: String, + initialValue: T, + profileId: ProfileId + ): PersistentCacheStore { val profileDirectory = directoryManagementUtil.getOrCreateDir(profileId.internalId.toString()) - return PersistentCacheStore(context, cacheFactory, asyncDataSubscriptionManager, cacheName, initialValue, profileDirectory) + return PersistentCacheStore( + context, + cacheFactory, + asyncDataSubscriptionManager, + cacheName, + initialValue, + profileDirectory + ) } } } diff --git a/data/src/test/java/org/oppia/data/backends/test/NetworkInterceptorTest.kt b/data/src/test/java/org/oppia/data/backends/test/NetworkInterceptorTest.kt index 8ecc00692e9..ab3cd9455c1 100755 --- a/data/src/test/java/org/oppia/data/backends/test/NetworkInterceptorTest.kt +++ b/data/src/test/java/org/oppia/data/backends/test/NetworkInterceptorTest.kt @@ -24,7 +24,8 @@ import javax.inject.Singleton @RunWith(AndroidJUnit4::class) class NetworkInterceptorTest { - @Inject lateinit var networkInterceptor: NetworkInterceptor + @Inject + lateinit var networkInterceptor: NetworkInterceptor @Before fun setUp() { @@ -38,17 +39,33 @@ class NetworkInterceptorTest { @Test fun testNetworkInterceptor_withXssiPrefix_removesXssiPrefix() { val rawJson: String = - networkInterceptor.removeXSSIPrefix(ApiUtils.getFakeJson("dummy_response_with_xssi_prefix.json")).trim() + networkInterceptor.removeXSSIPrefix( + ApiUtils.getFakeJson( + "dummy_response_with_xssi_prefix.json" + ) + ).trim() - assertThat(removeSpaces(rawJson)).isEqualTo(ApiUtils.getFakeJson("dummy_response_without_xssi_prefix.json")) + assertThat(removeSpaces(rawJson)).isEqualTo( + ApiUtils.getFakeJson( + "dummy_response_without_xssi_prefix.json" + ) + ) } @Test fun testNetworkInterceptor_withoutXssiPrefix_removesXssiPrefix() { val rawJson: String = - networkInterceptor.removeXSSIPrefix(ApiUtils.getFakeJson("dummy_response_without_xssi_prefix.json")) + networkInterceptor.removeXSSIPrefix( + ApiUtils.getFakeJson( + "dummy_response_without_xssi_prefix.json" + ) + ) - assertThat(rawJson).isEqualTo(ApiUtils.getFakeJson("dummy_response_without_xssi_prefix.json")) + assertThat(rawJson).isEqualTo( + ApiUtils.getFakeJson( + "dummy_response_without_xssi_prefix.json" + ) + ) } private fun setUpTestApplicationComponent() { @@ -58,7 +75,8 @@ class NetworkInterceptorTest { .inject(this) } - @Qualifier annotation class OppiaRetrofit + @Qualifier + annotation class OppiaRetrofit // TODO(#89): Move this to a common test application component. @Module diff --git a/data/src/test/java/org/oppia/data/persistence/PersistentCacheStoreTest.kt b/data/src/test/java/org/oppia/data/persistence/PersistentCacheStoreTest.kt index 15f9411ab13..829db51012b 100644 --- a/data/src/test/java/org/oppia/data/persistence/PersistentCacheStoreTest.kt +++ b/data/src/test/java/org/oppia/data/persistence/PersistentCacheStoreTest.kt @@ -60,13 +60,19 @@ class PersistentCacheStoreTest { @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule() - @Inject lateinit var cacheFactory: PersistentCacheStore.Factory + @Inject + lateinit var cacheFactory: PersistentCacheStore.Factory - @Inject lateinit var dataProviders: DataProviders + @Inject + lateinit var dataProviders: DataProviders - @InternalCoroutinesApi @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + @InternalCoroutinesApi + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers - @Inject @field:BackgroundDispatcher lateinit var backgroundDispatcher: CoroutineDispatcher + @Inject + @field:BackgroundDispatcher + lateinit var backgroundDispatcher: CoroutineDispatcher @Mock lateinit var mockUserAppHistoryObserver1: Observer> @@ -122,9 +128,14 @@ class PersistentCacheStoreTest { observeCache(cacheStore, mockUserAppHistoryObserver1) // The initial cache state should be the default cache value. - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -136,7 +147,10 @@ class PersistentCacheStoreTest { observeCache(cacheStore, mockUserAppHistoryObserver1) // Caches can have non-default initial states. - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -208,7 +222,10 @@ class PersistentCacheStoreTest { // NB: This may not be ideal behavior long-term; the store may need to be updated to be more resilient to these // types of scenarios. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -229,7 +246,10 @@ class PersistentCacheStoreTest { // simulating something closer to an app restart or non-UI Dagger component refresh since UI components should share // the same cache instance via an application-bound controller object. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -251,7 +271,10 @@ class PersistentCacheStoreTest { // simulating something closer to an app restart or non-UI Dagger component refresh since UI components should share // the same cache instance via an application-bound controller object. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -261,12 +284,14 @@ class PersistentCacheStoreTest { @InternalCoroutinesApi fun testExistingDiskCache_newCacheObject_updateNoMemThenRead_receivesNewValue() { val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - val storeOp1 = cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } + val storeOp1 = + cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } testCoroutineDispatchers.advanceUntilIdle() // Create a new cache with the same name and update it, then observe it. val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_2 } + val storeOp2 = + cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_2 } testCoroutineDispatchers.advanceUntilIdle() observeCache(cacheStore2, mockUserAppHistoryObserver1) @@ -274,7 +299,10 @@ class PersistentCacheStoreTest { // before the read occurred. assertThat(storeOp1.isCompleted).isTrue() assertThat(storeOp2.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_2) } @@ -284,14 +312,16 @@ class PersistentCacheStoreTest { @InternalCoroutinesApi fun testExistingDiskCache_newObject_updateNoMemThenRead_primed_receivesPrevVal() { val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - val storeOp1 = cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } + val storeOp1 = + cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } testCoroutineDispatchers.advanceUntilIdle() // Create a new cache with the same name and update it, then observe it. However, first prime it. val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) val primeOp = cacheStore2.primeCacheAsync() testCoroutineDispatchers.advanceUntilIdle() - val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_2 } + val storeOp2 = + cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_2 } testCoroutineDispatchers.advanceUntilIdle() observeCache(cacheStore2, mockUserAppHistoryObserver1) @@ -300,7 +330,10 @@ class PersistentCacheStoreTest { assertThat(storeOp1.isCompleted).isTrue() assertThat(storeOp2.isCompleted).isTrue() assertThat(primeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -310,7 +343,8 @@ class PersistentCacheStoreTest { @InternalCoroutinesApi fun testExistingDiskCache_newObject_updateMemThenRead_primed_receivesNewVal() { val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - val storeOp1 = cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } + val storeOp1 = + cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } testCoroutineDispatchers.advanceUntilIdle() // Create a new cache with the same name and update it, then observe it. However, first prime it. @@ -326,7 +360,10 @@ class PersistentCacheStoreTest { assertThat(storeOp1.isCompleted).isTrue() assertThat(storeOp2.isCompleted).isTrue() assertThat(primeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_2) } @@ -336,7 +373,10 @@ class PersistentCacheStoreTest { @InternalCoroutinesApi fun testCache_primed_afterStoreUpdateWithoutMemUpdate_notForced_observesOldValue() { val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - observeCache(cacheStore, mockUserAppHistoryObserver1) // Force initializing the store's in-memory cache + observeCache( + cacheStore, + mockUserAppHistoryObserver1 + ) // Force initializing the store's in-memory cache val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } testCoroutineDispatchers.advanceUntilIdle() @@ -348,9 +388,14 @@ class PersistentCacheStoreTest { // cache, and the prime no-oping due to the cache already being initialized. assertThat(storeOp.isCompleted).isTrue() assertThat(primeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver2, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver2, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -358,7 +403,10 @@ class PersistentCacheStoreTest { @InternalCoroutinesApi fun testCache_primed_afterStoreUpdateWithoutMemoryUpdate_forced_observesNewValue() { val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance()) - observeCache(cacheStore, mockUserAppHistoryObserver1) // Force initializing the store's in-memory cache + observeCache( + cacheStore, + mockUserAppHistoryObserver1 + ) // Force initializing the store's in-memory cache val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_VERSION_1 } testCoroutineDispatchers.advanceUntilIdle() @@ -370,7 +418,10 @@ class PersistentCacheStoreTest { // now up-to-date with the on-disk representation. assertThat(storeOp.isCompleted).isTrue() assertThat(primeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver2, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver2, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -387,9 +438,14 @@ class PersistentCacheStoreTest { // The new observer should observe the store with its default state since nothing needed to be cleared. assertThat(clearOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -407,9 +463,14 @@ class PersistentCacheStoreTest { // The new observer should observe that the store is cleared. assertThat(storeOp.isCompleted).isTrue() assertThat(clearOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -428,9 +489,14 @@ class PersistentCacheStoreTest { // The observer should not be notified the cache was cleared. assertThat(storeOp.isCompleted).isTrue() assertThat(clearOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -450,7 +516,10 @@ class PersistentCacheStoreTest { // that would only be used if there wasn't already on-disk storage. assertThat(storeOp.isCompleted).isTrue() assertThat(clearOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_2) } @@ -471,7 +540,10 @@ class PersistentCacheStoreTest { // a possible edge case that should at least have established behavior that can be adjusted later if it isn't // desirable in some circumstances. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) } @@ -512,12 +584,20 @@ class PersistentCacheStoreTest { // Only the observer of the first cache should notice the update since they are different caches. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) - verify(mockUserAppHistoryObserver2, atLeastOnce()).onChanged(userAppHistoryResultCaptor2.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver2, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor2.capture()) assertThat(userAppHistoryResultCaptor1.value.isSuccess()).isTrue() assertThat(userAppHistoryResultCaptor1.value.getOrThrow()).isEqualTo(TEST_MESSAGE_VERSION_1) assertThat(userAppHistoryResultCaptor2.value.isSuccess()).isTrue() - assertThat(userAppHistoryResultCaptor2.value.getOrThrow()).isEqualTo(TestMessage.getDefaultInstance()) + assertThat(userAppHistoryResultCaptor2.value.getOrThrow()).isEqualTo( + TestMessage.getDefaultInstance() + ) } @Test @@ -535,14 +615,22 @@ class PersistentCacheStoreTest { // The new observer should receive an IOException error when trying to read the file. assertThat(storeOp.isCompleted).isTrue() - verify(mockUserAppHistoryObserver1, atLeastOnce()).onChanged(userAppHistoryResultCaptor1.capture()) + verify( + mockUserAppHistoryObserver1, + atLeastOnce() + ).onChanged(userAppHistoryResultCaptor1.capture()) assertThat(userAppHistoryResultCaptor1.value.isFailure()).isTrue() - assertThat(userAppHistoryResultCaptor1.value.getErrorOrNull()).isInstanceOf(IOException::class.java) + assertThat(userAppHistoryResultCaptor1.value.getErrorOrNull()).isInstanceOf( + IOException::class.java + ) } @ExperimentalCoroutinesApi @InternalCoroutinesApi - private fun observeCache(cacheStore: PersistentCacheStore, observer: Observer>) { + private fun observeCache( + cacheStore: PersistentCacheStore, + observer: Observer> + ) { dataProviders.convertToLiveData(cacheStore).observeForever(observer) testCoroutineDispatchers.advanceUntilIdle() } @@ -553,7 +641,9 @@ class PersistentCacheStoreTest { // retrieve the file cache. This may also be needed for downstream profile work if per-profile data stores are done // via subdirectories or altered filenames. val cacheFileName = "$cacheName.cache" - val cacheFile = File(ApplicationProvider.getApplicationContext().filesDir, cacheFileName) + val cacheFile = File( + ApplicationProvider.getApplicationContext().filesDir, cacheFileName + ) FileOutputStream(cacheFile).use { it.write(byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)) } diff --git a/utility/src/main/java/org/oppia/util/caching/AssetRepository.kt b/utility/src/main/java/org/oppia/util/caching/AssetRepository.kt index 67f358857a7..4ce3add6396 100644 --- a/utility/src/main/java/org/oppia/util/caching/AssetRepository.kt +++ b/utility/src/main/java/org/oppia/util/caching/AssetRepository.kt @@ -20,7 +20,10 @@ import kotlin.concurrent.withLock * quickly and synchronously. */ @Singleton -class AssetRepository @Inject constructor(private val context: Context, private val logger: Logger) { +class AssetRepository @Inject constructor( + private val context: Context, + private val logger: Logger +) { private val repositoryLock = ReentrantLock() /** Map of asset names to file contents for text file assets. */ @@ -39,7 +42,9 @@ class AssetRepository @Inject constructor(private val context: Context, private repositoryLock.withLock { if (assetName !in textFileAssets) { logger.d("AssetRepo", "Caching local text asset: $assetName") - textFileAssets[assetName] = context.assets.open(assetName).bufferedReader().use { it.readText() } + textFileAssets[assetName] = context.assets.open(assetName).bufferedReader().use { + it.readText() + } } } } diff --git a/utility/src/main/java/org/oppia/util/data/AsyncResult.kt b/utility/src/main/java/org/oppia/util/data/AsyncResult.kt index b4a6518662c..d262121ff99 100644 --- a/utility/src/main/java/org/oppia/util/data/AsyncResult.kt +++ b/utility/src/main/java/org/oppia/util/data/AsyncResult.kt @@ -13,8 +13,10 @@ class AsyncResult private constructor( enum class Status { /** Indicates that the asynchronous operation is not yet completed. */ PENDING, + /** Indicates that the asynchronous operation completed successfully and has a result. */ SUCCEEDED, + /** Indicates that the asynchronous operation failed and has an error. */ FAILED } @@ -101,7 +103,10 @@ class AsyncResult private constructor( * * Note also that the specified combine function should have no side effects, and be non-blocking. */ - fun combineWith(otherResult: AsyncResult, combineFunction: (T, T2) -> O): AsyncResult { + fun combineWith( + otherResult: AsyncResult, + combineFunction: (T, T2) -> O + ): AsyncResult { return transformWithResult { value1 -> otherResult.transformWithResult { value2 -> success(combineFunction(value1, value2)) @@ -133,7 +138,9 @@ class AsyncResult private constructor( } } - private suspend fun transformWithResultAsync(transformFunction: suspend (T) -> AsyncResult): AsyncResult { + private suspend fun transformWithResultAsync( + transformFunction: suspend (T) -> AsyncResult + ): AsyncResult { return when (status) { Status.PENDING -> pending() Status.FAILED -> failed(ChainedFailureException(error!!)) @@ -176,12 +183,20 @@ class AsyncResult private constructor( /** Returns a successful result with the specified payload. */ fun success(value: T): AsyncResult { - return AsyncResult(status = Status.SUCCEEDED, resultTimeMillis = SystemClock.uptimeMillis(), value = value) + return AsyncResult( + status = Status.SUCCEEDED, + resultTimeMillis = SystemClock.uptimeMillis(), + value = value + ) } /** Returns a failed result with the specified error. */ fun failed(error: Throwable): AsyncResult { - return AsyncResult(status = Status.FAILED, resultTimeMillis = SystemClock.uptimeMillis(), error = error) + return AsyncResult( + status = Status.FAILED, + resultTimeMillis = SystemClock.uptimeMillis(), + error = error + ) } } diff --git a/utility/src/main/java/org/oppia/util/data/DataProviders.kt b/utility/src/main/java/org/oppia/util/data/DataProviders.kt index 9965b399446..1b058ff2221 100644 --- a/utility/src/main/java/org/oppia/util/data/DataProviders.kt +++ b/utility/src/main/java/org/oppia/util/data/DataProviders.kt @@ -36,7 +36,11 @@ class DataProviders @Inject constructor( * it may be called on different background threads at different times. It should perform no UI operations or * otherwise interact with UI components. */ - fun transform(newId: Any, dataProvider: DataProvider, function: (T1) -> T2): DataProvider { + fun transform( + newId: Any, + dataProvider: DataProvider, + function: (T1) -> T2 + ): DataProvider { asyncDataSubscriptionManager.associateIds(newId, dataProvider.getId()) return object : DataProvider { override fun getId(): Any { @@ -179,7 +183,10 @@ class DataProviders @Inject constructor( * Returns a new in-memory [DataProvider] in the same way as [createInMemoryDataProvider] except the load function can * be blocking. */ - fun createInMemoryDataProviderAsync(id: Any, loadFromMemoryAsync: suspend () -> AsyncResult): DataProvider { + fun createInMemoryDataProviderAsync( + id: Any, + loadFromMemoryAsync: suspend () -> AsyncResult + ): DataProvider { return object : DataProvider { override fun getId(): Any { return id diff --git a/utility/src/main/java/org/oppia/util/data/InMemoryBlockingCache.kt b/utility/src/main/java/org/oppia/util/data/InMemoryBlockingCache.kt index 99fc374a26e..26fd20d6d65 100644 --- a/utility/src/main/java/org/oppia/util/data/InMemoryBlockingCache.kt +++ b/utility/src/main/java/org/oppia/util/data/InMemoryBlockingCache.kt @@ -16,7 +16,10 @@ import javax.inject.Singleton * This cache is primarily intended to be used with immutable payloads, but mutable payloads can be used if calling code * takes caution to restrict all read/write access to those mutable values to operations invoked by this class. */ -class InMemoryBlockingCache private constructor(blockingDispatcher: CoroutineDispatcher, initialValue: T?) { +class InMemoryBlockingCache private constructor( + blockingDispatcher: CoroutineDispatcher, + initialValue: T? +) { private val blockingScope = CoroutineScope(blockingDispatcher) /** @@ -91,14 +94,24 @@ class InMemoryBlockingCache private constructor(blockingDispatcher: Cor */ fun updateIfPresentAsync(update: suspend (T) -> T): Deferred { return blockingScope.async { - setCache(update(checkNotNull(value) { "Expected to update the cache only after it's been created" })) + setCache( + update( + checkNotNull(value) { + "Expected to update the cache only after it's been created" + } + ) + ) } } /** See [updateIfPresentAsync]. Returns a custom deferred result. */ fun updateWithCustomChannelIfPresentAsync(update: suspend (T) -> Pair): Deferred { return blockingScope.async { - val (updatedValue, customResult) = update(checkNotNull(value) { "Expected to update the cache only after it's been created" }) + val (updatedValue, customResult) = update( + checkNotNull(value) { + "Expected to update the cache only after it's been created" + } + ) setCache(updatedValue) customResult } @@ -167,7 +180,9 @@ class InMemoryBlockingCache private constructor(blockingDispatcher: Cor /** An injectable factory for [InMemoryBlockingCache]es. */ @Singleton - class Factory @Inject constructor(@BlockingDispatcher private val blockingDispatcher: CoroutineDispatcher) { + class Factory @Inject constructor( + @BlockingDispatcher private val blockingDispatcher: CoroutineDispatcher + ) { /** Returns a new [InMemoryBlockingCache] with, optionally, the specified initial value. */ fun create(initialValue: T? = null): InMemoryBlockingCache { return InMemoryBlockingCache(blockingDispatcher, initialValue) diff --git a/utility/src/main/java/org/oppia/util/networking/NetworkConnectionUtil.kt b/utility/src/main/java/org/oppia/util/networking/NetworkConnectionUtil.kt index 7f8b08c0a60..045a95b6275 100644 --- a/utility/src/main/java/org/oppia/util/networking/NetworkConnectionUtil.kt +++ b/utility/src/main/java/org/oppia/util/networking/NetworkConnectionUtil.kt @@ -13,22 +13,31 @@ class NetworkConnectionUtil @Inject constructor(private val context: Context) { enum class ConnectionStatus { /** Connected to WIFI or Ethernet. */ LOCAL, + /** Connected to Mobile or WiMax. */ CELLULAR, + /** Not connected to a network. */ NONE } + private var testConnectionStatus: ConnectionStatus? = null fun getCurrentConnectionStatus(): ConnectionStatus { testConnectionStatus?.let { return it } - val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val connectivityManager = context.getSystemService( + Context.CONNECTIVITY_SERVICE + ) as ConnectivityManager return connectivityManager.activeNetworkInfo?.let { activeNetwork -> val isConnected = activeNetwork.isConnected - val isLocal = activeNetwork.type == ConnectivityManager.TYPE_WIFI || activeNetwork.type == ConnectivityManager.TYPE_ETHERNET - val isCellular = activeNetwork.type == ConnectivityManager.TYPE_MOBILE || activeNetwork.type == ConnectivityManager.TYPE_WIMAX + val isLocal = activeNetwork.type == + ConnectivityManager.TYPE_WIFI || + activeNetwork.type == ConnectivityManager.TYPE_ETHERNET + val isCellular = activeNetwork.type == + ConnectivityManager.TYPE_MOBILE || + activeNetwork.type == ConnectivityManager.TYPE_WIMAX return@let when { isConnected && isLocal -> ConnectionStatus.LOCAL isConnected && isCellular -> ConnectionStatus.CELLULAR diff --git a/utility/src/main/java/org/oppia/util/parser/HtmlParser.kt b/utility/src/main/java/org/oppia/util/parser/HtmlParser.kt index d6bb9e23d4f..6eb3291de7a 100755 --- a/utility/src/main/java/org/oppia/util/parser/HtmlParser.kt +++ b/utility/src/main/java/org/oppia/util/parser/HtmlParser.kt @@ -38,10 +38,15 @@ class HtmlParser private constructor( } if (htmlContent.contains(CUSTOM_IMG_TAG)) { - htmlContent = htmlContent.replace(CUSTOM_IMG_TAG, REPLACE_IMG_TAG, /* ignoreCase= */false) + htmlContent = htmlContent.replace( + CUSTOM_IMG_TAG, + REPLACE_IMG_TAG, + /* ignoreCase= */ false + ) htmlContent = htmlContent.replace( CUSTOM_IMG_FILE_PATH_ATTRIBUTE, - REPLACE_IMG_FILE_PATH_ATTRIBUTE, /* ignoreCase= */false + REPLACE_IMG_FILE_PATH_ATTRIBUTE, + /* ignoreCase= */ false ) htmlContent = htmlContent.replace(""", "") } @@ -50,10 +55,19 @@ class HtmlParser private constructor( htmlContentTextView, gcsResourceName, entityType, entityId, imageCenterAlign ) - val htmlSpannable = HtmlCompat.fromHtml(htmlContent, HtmlCompat.FROM_HTML_MODE_LEGACY, imageGetter, LiTagHandler()) as Spannable + val htmlSpannable = HtmlCompat.fromHtml( + htmlContent, + HtmlCompat.FROM_HTML_MODE_LEGACY, + imageGetter, + LiTagHandler() + ) as Spannable val spannableBuilder = SpannableStringBuilder(htmlSpannable) - val bulletSpans = spannableBuilder.getSpans(0, spannableBuilder.length, BulletSpan::class.java) + val bulletSpans = spannableBuilder.getSpans( + /* queryStart= */ 0, + spannableBuilder.length, + BulletSpan::class.java + ) bulletSpans.forEach { val start = spannableBuilder.getSpanStart(it) val end = spannableBuilder.getSpanEnd(it) @@ -88,8 +102,19 @@ class HtmlParser private constructor( } class Factory @Inject constructor(private val urlImageParserFactory: UrlImageParser.Factory) { - fun create(gcsResourceName: String, entityType: String, entityId: String, imageCenterAlign: Boolean): HtmlParser { - return HtmlParser(urlImageParserFactory, gcsResourceName, entityType, entityId, imageCenterAlign) + fun create( + gcsResourceName: String, + entityType: String, + entityId: String, + imageCenterAlign: Boolean + ): HtmlParser { + return HtmlParser( + urlImageParserFactory, + gcsResourceName, + entityType, + entityId, + imageCenterAlign + ) } } } diff --git a/utility/src/main/java/org/oppia/util/parser/RepositoryGlideModule.kt b/utility/src/main/java/org/oppia/util/parser/RepositoryGlideModule.kt index 3d56c71d267..6de29e49d6d 100644 --- a/utility/src/main/java/org/oppia/util/parser/RepositoryGlideModule.kt +++ b/utility/src/main/java/org/oppia/util/parser/RepositoryGlideModule.kt @@ -17,6 +17,10 @@ class RepositoryGlideModule : AppGlideModule() { // TODO(#1039): Introduce custom type OppiaImage for rendering Bitmap and Svg. registry.register(SVG::class.java, Picture::class.java, SvgDrawableTranscoder()) .append(InputStream::class.java, SVG::class.java, SvgDecoder()) - .append(ImageAssetFetcher::class.java, InputStream::class.java, RepositoryModelLoader.Factory()) + .append( + ImageAssetFetcher::class.java, + InputStream::class.java, + RepositoryModelLoader.Factory() + ) } } diff --git a/utility/src/main/java/org/oppia/util/parser/RepositoryModelLoader.kt b/utility/src/main/java/org/oppia/util/parser/RepositoryModelLoader.kt index 91d6c2a99d3..be03fa289c6 100644 --- a/utility/src/main/java/org/oppia/util/parser/RepositoryModelLoader.kt +++ b/utility/src/main/java/org/oppia/util/parser/RepositoryModelLoader.kt @@ -25,7 +25,9 @@ internal class RepositoryModelLoader : ModelLoader { + private class RepositoryDataFetcher( + private val fetcher: ImageAssetFetcher + ) : DataFetcher { override fun getDataClass(): Class = InputStream::class.java override fun cleanup() {} @@ -42,7 +44,9 @@ internal class RepositoryModelLoader : ModelLoader { - override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { + override fun build( + multiFactory: MultiModelLoaderFactory + ): ModelLoader { return RepositoryModelLoader() } diff --git a/utility/src/test/java/org/oppia/util/data/AsyncResultTest.kt b/utility/src/test/java/org/oppia/util/data/AsyncResultTest.kt index f590a34c669..66423e269ed 100644 --- a/utility/src/test/java/org/oppia/util/data/AsyncResultTest.kt +++ b/utility/src/test/java/org/oppia/util/data/AsyncResultTest.kt @@ -22,7 +22,8 @@ import kotlin.test.assertFailsWith @LooperMode(LooperMode.Mode.PAUSED) class AsyncResultTest { - @Inject lateinit var fakeSystemClock: FakeSystemClock + @Inject + lateinit var fakeSystemClock: FakeSystemClock @Before fun setUp() { @@ -203,7 +204,11 @@ class AsyncResultTest { fun testPendingResult_hashCode_isNotEqualToFailedResult() { val resultHash = AsyncResult.pending().hashCode() - assertThat(resultHash).isNotEqualTo(AsyncResult.failed(UnsupportedOperationException()).hashCode()) + assertThat(resultHash).isNotEqualTo( + AsyncResult.failed( + UnsupportedOperationException() + ).hashCode() + ) } @Test @@ -352,7 +357,9 @@ class AsyncResultTest { fun testSucceededAsyncResult_transformedAsyncFailed_isFailure() = runBlockingTest { val original = AsyncResult.success("value") - val transformed = original.transformAsync { AsyncResult.failed(UnsupportedOperationException()) } + val transformed = original.transformAsync { + AsyncResult.failed(UnsupportedOperationException()) + } // Note that the failure is not chained since the transform function was responsible for 'throwing' it. assertThat(transformed.getErrorOrNull()).isInstanceOf(UnsupportedOperationException::class.java) @@ -376,7 +383,9 @@ class AsyncResultTest { val combined = result1.combineWith(result2) { _, _ -> 0 } assertThat(combined.isFailure()).isTrue() - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(RuntimeException::class.java) } @@ -404,27 +413,33 @@ class AsyncResultTest { @Test @ExperimentalCoroutinesApi - fun testSucceededAsyncResult_combinedAsyncWithFailure_isFailedWithCorrectChainedFailure() = runBlockingTest { - val result1 = AsyncResult.success("value") - val result2 = AsyncResult.failed(RuntimeException()) - - val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.success(0) } - - assertThat(combined.isFailure()).isTrue() - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(RuntimeException::class.java) - } + fun testSucceededAsyncResult_combinedAsyncWithFailure_isFailedWithCorrectChainedFailure() = + runBlockingTest { + val result1 = AsyncResult.success("value") + val result2 = AsyncResult.failed(RuntimeException()) + + val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.success(0) } + + assertThat(combined.isFailure()).isTrue() + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + RuntimeException::class.java + ) + } @Test @ExperimentalCoroutinesApi - fun testSucceededAsyncResult_combinedAsyncWithSuccess_resultPending_isPending() = runBlockingTest { - val result1 = AsyncResult.success("value") - val result2 = AsyncResult.success(1.0) + fun testSucceededAsyncResult_combinedAsyncWithSuccess_resultPending_isPending() = + runBlockingTest { + val result1 = AsyncResult.success("value") + val result2 = AsyncResult.success(1.0) - val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.pending() } + val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.pending() } - assertThat(combined.isPending()).isTrue() - } + assertThat(combined.isPending()).isTrue() + } @Test @ExperimentalCoroutinesApi @@ -432,7 +447,9 @@ class AsyncResultTest { val result1 = AsyncResult.success("value") val result2 = AsyncResult.success(1.0) - val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.failed(RuntimeException()) } + val combined = result1.combineWithAsync(result2) { _, _ -> + AsyncResult.failed(RuntimeException()) + } // Note that the failure is not chained since the transform function was responsible for 'throwing' it. assertThat(combined.isFailure()).isTrue() @@ -441,15 +458,18 @@ class AsyncResultTest { @Test @ExperimentalCoroutinesApi - fun testSucceededAsyncResult_combinedAsyncWithSuccess_resultSuccess_hasCombinedSuccessValue() = runBlockingTest { - val result1 = AsyncResult.success("value") - val result2 = AsyncResult.success(1.0) + fun testSucceededAsyncResult_combinedAsyncWithSuccess_resultSuccess_hasCombinedSuccessValue() = + runBlockingTest { + val result1 = AsyncResult.success("value") + val result2 = AsyncResult.success(1.0) - val combined = result1.combineWithAsync(result2) { v1, v2 -> AsyncResult.success(v1 + v2) } + val combined = result1.combineWithAsync(result2) { v1, v2 -> + AsyncResult.success(v1 + v2) + } - assertThat(combined.getOrThrow()).contains("value") - assertThat(combined.getOrThrow()).contains("1.0") - } + assertThat(combined.getOrThrow()).contains("value") + assertThat(combined.getOrThrow()).contains("1.0") + } @Test fun testSucceededResult_isNotEqualToPendingResult() { @@ -519,7 +539,9 @@ class AsyncResultTest { fun testSucceededResult_hashCode_isNotEqualToFailedResult() { val resultHash = AsyncResult.success("Success").hashCode() - assertThat(resultHash).isNotEqualTo(AsyncResult.failed(UnsupportedOperationException()).hashCode()) + assertThat(resultHash).isNotEqualTo( + AsyncResult.failed(UnsupportedOperationException()).hashCode() + ) } @Test @@ -640,20 +662,29 @@ class AsyncResultTest { val transformed = result.transform { 0 } - assertThat(transformed.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(transformed.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(transformed.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(transformed.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @ExperimentalCoroutinesApi - fun testFailedAsyncResult_transformedAsync_throwsChainedFailureException_withCorrectRootCause() = runBlockingTest { - val result = AsyncResult.failed(UnsupportedOperationException()) - - val transformed = result.transformAsync { AsyncResult.success(0) } - - assertThat(transformed.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(transformed.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) - } + fun testFailedAsyncResult_transformedAsync_throwsChainedFailureException_withCorrectRootCause() = + runBlockingTest { + val result = AsyncResult.failed(UnsupportedOperationException()) + + val transformed = result.transformAsync { AsyncResult.success(0) } + + assertThat(transformed.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(transformed.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) + } @Test fun testFailedAsyncResult_combinedWithPending_isStillChainedFailure() { @@ -662,8 +693,12 @@ class AsyncResultTest { val combined = result1.combineWith(result2) { _, _ -> 0 } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -673,8 +708,12 @@ class AsyncResultTest { val combined = result1.combineWith(result2) { _, _ -> 0 } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -684,8 +723,12 @@ class AsyncResultTest { val combined = result1.combineWith(result2) { _, _ -> 0 } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -696,8 +739,12 @@ class AsyncResultTest { val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.success(0) } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -708,8 +755,12 @@ class AsyncResultTest { val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.success(0) } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -720,8 +771,12 @@ class AsyncResultTest { val combined = result1.combineWithAsync(result2) { _, _ -> AsyncResult.success(0) } - assertThat(combined.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf(UnsupportedOperationException::class.java) + assertThat(combined.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(combined.getErrorOrNull()).hasCauseThat().isInstanceOf( + UnsupportedOperationException::class.java + ) } @Test @@ -752,7 +807,9 @@ class AsyncResultTest { val result = AsyncResult.failed(UnsupportedOperationException("Reason")) // Different exceptions have different stack traces, so they can't be equal despite similar constructions. - assertThat(result).isNotEqualTo(AsyncResult.failed(UnsupportedOperationException("Reason"))) + assertThat(result).isNotEqualTo( + AsyncResult.failed(UnsupportedOperationException("Reason")) + ) } @Test @@ -784,7 +841,9 @@ class AsyncResultTest { val resultHash = AsyncResult.failed(UnsupportedOperationException("Reason")).hashCode() // Different exceptions have different stack traces, so they can't be equal despite similar constructions. - assertThat(resultHash).isNotEqualTo(AsyncResult.failed(UnsupportedOperationException("Reason")).hashCode()) + assertThat(resultHash).isNotEqualTo( + AsyncResult.failed(UnsupportedOperationException("Reason")).hashCode() + ) } @Test diff --git a/utility/src/test/java/org/oppia/util/data/DataProvidersTest.kt b/utility/src/test/java/org/oppia/util/data/DataProvidersTest.kt index 6b5213446bb..83a380e9b3c 100644 --- a/utility/src/test/java/org/oppia/util/data/DataProvidersTest.kt +++ b/utility/src/test/java/org/oppia/util/data/DataProvidersTest.kt @@ -64,15 +64,21 @@ class DataProvidersTest { @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule() - @Inject lateinit var dataProviders: DataProviders + @Inject + lateinit var dataProviders: DataProviders - @Inject lateinit var asyncDataSubscriptionManager: AsyncDataSubscriptionManager + @Inject + lateinit var asyncDataSubscriptionManager: AsyncDataSubscriptionManager - @Inject lateinit var fakeExceptionLogger: FakeExceptionLogger + @Inject + lateinit var fakeExceptionLogger: FakeExceptionLogger - @InternalCoroutinesApi @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + @InternalCoroutinesApi + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers - @Inject @field:BackgroundDispatcher + @Inject + @field:BackgroundDispatcher lateinit var backgroundCoroutineDispatcher: CoroutineDispatcher @Mock @@ -301,7 +307,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testInMemoryDataProvider_toLiveData_withChangedValue_beforeReg_deliversSecondValue() { inMemoryCachedStr = STR_VALUE_0 - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } inMemoryCachedStr = STR_VALUE_1 dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -317,7 +324,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testInMemoryDataProvider_toLiveData_withChangedValue_afterReg_deliversFirstValue() { inMemoryCachedStr = STR_VALUE_0 - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } // Ensure the initial state is sent before changing the cache. dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -336,7 +344,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testInMemoryDataProvider_changedValueAfterReg_notified_deliversSecondValue() { inMemoryCachedStr = STR_VALUE_0 - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_1 @@ -353,7 +362,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testInMemoryDataProvider_changedValue_notifiesDiffProvider_deliversFirstVal() { inMemoryCachedStr = STR_VALUE_0 - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } // Ensure the initial state is sent before changing the cache. dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -380,7 +390,8 @@ class DataProvidersTest { fakeLoadMemoryCallbackCalled = true STR_VALUE_0 } - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -398,7 +409,8 @@ class DataProvidersTest { fakeLoadMemoryCallbackCalled = true STR_VALUE_0 } - val dataProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) + val dataProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) dataProviders.convertToLiveData(dataProvider) testCoroutineDispatchers.advanceUntilIdle() @@ -411,13 +423,16 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testInMemoryDataProvider_toLiveData_throwsException_deliversFailure() { - val dataProvider = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failed")) + val dataProvider = + createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failed")) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) } @Test @@ -541,7 +556,8 @@ class DataProvidersTest { fakeLoadMemoryCallbackCalled = true AsyncResult.success(STR_VALUE_0) } - val dataProvider = dataProviders.createInMemoryDataProviderAsync(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) + val dataProvider = + dataProviders.createInMemoryDataProviderAsync(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -559,7 +575,8 @@ class DataProvidersTest { fakeLoadMemoryCallbackCalled = true AsyncResult.success(STR_VALUE_0) } - val dataProvider = dataProviders.createInMemoryDataProviderAsync(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) + val dataProvider = + dataProviders.createInMemoryDataProviderAsync(BASE_PROVIDER_ID_0, fakeLoadMemoryCallback) dataProviders.convertToLiveData(dataProvider) testCoroutineDispatchers.advanceUntilIdle() @@ -585,14 +602,17 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testAsyncInMemoryDataProvider_toLiveData_failure_deliversFailure() { - val dataProvider = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failure")) + val dataProvider = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failure")) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) } @Test @@ -600,7 +620,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_toLiveData_deliversTransformedValue() { val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -615,8 +636,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_toLiveData_differentValue_notifiesBase_deliversXformedValueTwo() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) inMemoryCachedStr = STR_VALUE_1 @@ -634,8 +657,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_toLiveData_diffValue_notifiesXform_deliversXformedValueTwo() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) inMemoryCachedStr = STR_VALUE_1 @@ -653,8 +678,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_differentValue_notifiesBase_observeBase_deliversSecondValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(baseProvider).observeForever(mockStringLiveDataObserver) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) @@ -673,8 +700,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_differentValue_notifiesXformed_observeBase_deliversFirstValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } // Ensure the initial state is sent before changing the cache. dataProviders.convertToLiveData(baseProvider).observeForever(mockStringLiveDataObserver) @@ -697,7 +726,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransform_toLiveData_basePending_deliversPending() { val baseProvider = createPendingDataProvider(BASE_PROVIDER_ID_0) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -710,16 +740,21 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testTransform_toLiveData_baseFailure_deliversFailure() { - val baseProvider = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failure")) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } + val baseProvider = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Failure")) + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockIntLiveDataObserver).onChanged(intResultCaptor.capture()) assertThat(intResultCaptor.value.isFailure()).isTrue() - assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -732,7 +767,8 @@ class DataProvidersTest { transformString(it) } val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -751,7 +787,8 @@ class DataProvidersTest { transformString(it) } val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider) testCoroutineDispatchers.advanceUntilIdle() @@ -770,7 +807,8 @@ class DataProvidersTest { transformString(it) } val baseProvider = createPendingDataProvider(BASE_PROVIDER_ID_0) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -788,8 +826,10 @@ class DataProvidersTest { fakeTransformCallbackCalled = true transformString(it) } - val baseProvider = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) - val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val baseProvider = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) + val dataProvider = + dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -813,15 +853,19 @@ class DataProvidersTest { // Note that the exception type here is not chained since the failure occurred in the transform function. verify(mockIntLiveDataObserver).onChanged(intResultCaptor.capture()) assertThat(intResultCaptor.value.isFailure()).isTrue() - assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasMessageThat().contains("Transform failure") + assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) + assertThat(intResultCaptor.value.getErrorOrNull()).hasMessageThat() + .contains("Transform failure") } @Test @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testTransform_toLiveData_baseThrowsException_deliversFailure() { - val baseProvider = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) + val baseProvider = + createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) val dataProvider = dataProviders.transform(TRANSFORMED_PROVIDER_ID, baseProvider) { transformString(it) } @@ -831,9 +875,13 @@ class DataProvidersTest { verify(mockIntLiveDataObserver).onChanged(intResultCaptor.capture()) assertThat(intResultCaptor.value.isFailure()).isTrue() - assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().hasMessageThat().contains("Base failure") + assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) + assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().hasMessageThat() + .contains("Base failure") } @Test @@ -841,7 +889,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_deliversTransformedValue() { val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -856,8 +907,12 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_diffValue_notifiesBase_deliversXformedValueTwo() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) inMemoryCachedStr = STR_VALUE_1 @@ -875,8 +930,12 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_diffVal_notifiesXform_deliversXformedValueTwo() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) inMemoryCachedStr = STR_VALUE_1 @@ -894,8 +953,12 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_differentValue_notifiesBase_observeBase_deliversSecondVal() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(baseProvider).observeForever(mockStringLiveDataObserver) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) @@ -914,8 +977,12 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_diffValue_notifiesXformed_observeBase_deliversFirstVal() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val baseProvider = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } // Ensure the initial state is sent before changing the cache. dataProviders.convertToLiveData(baseProvider).observeForever(mockStringLiveDataObserver) @@ -939,7 +1006,10 @@ class DataProvidersTest { fun testTransformAsync_toLiveData_blockingFunction_doesNotDeliverValue() { // Block transformStringAsync(). val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) @@ -953,7 +1023,10 @@ class DataProvidersTest { fun testTransformAsync_toLiveData_blockingFunction_completed_deliversXformedVal() { // Block transformStringAsync(). val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() // Run transformStringAsync() @@ -970,7 +1043,10 @@ class DataProvidersTest { fun testTransformAsync_toLiveData_blockingFunction_baseObserved_deliversFirstVal() { // Block transformStringAsync(). val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } // Observe the base provider & let it complete, but don't complete the derived data provider. dataProviders.convertToLiveData(baseProvider).observeForever(mockStringLiveDataObserver) @@ -988,9 +1064,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_transformedPending_deliversPending() { val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { - AsyncResult.pending() - } + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { + AsyncResult.pending() + } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1005,9 +1082,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_transformedFailure_deliversFailure() { val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { - AsyncResult.failed(IllegalStateException("Transform failure")) - } + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { + AsyncResult.failed(IllegalStateException("Transform failure")) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1015,8 +1093,11 @@ class DataProvidersTest { // Note that the failure exception in this case is not chained since the failure occurred in the transform function. verify(mockIntLiveDataObserver).onChanged(intResultCaptor.capture()) assertThat(intResultCaptor.value.isFailure()).isTrue() - assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasMessageThat().contains("Transform failure") + assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) + assertThat(intResultCaptor.value.getErrorOrNull()).hasMessageThat() + .contains("Transform failure") } @Test @@ -1024,7 +1105,10 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_basePending_deliversPending() { val baseProvider = createPendingDataProvider(BASE_PROVIDER_ID_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } + val dataProvider = dataProviders.transformAsync( + TRANSFORMED_PROVIDER_ID, + baseProvider + ) { transformStringAsync(it) } dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1038,7 +1122,8 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testTransformAsync_toLiveData_baseFailure_deliversFailure() { - val baseProvider = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) + val baseProvider = + createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider) { transformStringAsync(it) } @@ -1049,9 +1134,13 @@ class DataProvidersTest { // Note that the failure exception in this case is not chained since the failure occurred in the transform function. verify(mockIntLiveDataObserver).onChanged(intResultCaptor.capture()) assertThat(intResultCaptor.value.isFailure()).isTrue() - assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) - assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().hasMessageThat().contains("Base failure") + assertThat(intResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) + assertThat(intResultCaptor.value.getErrorOrNull()).hasCauseThat().hasMessageThat() + .contains("Base failure") } @Test @@ -1064,7 +1153,8 @@ class DataProvidersTest { transformStringAsync(it) } val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1083,7 +1173,8 @@ class DataProvidersTest { transformStringAsync(it) } val baseProvider = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider) testCoroutineDispatchers.advanceUntilIdle() @@ -1102,7 +1193,8 @@ class DataProvidersTest { transformStringAsync(it) } val baseProvider = createPendingDataProvider(BASE_PROVIDER_ID_0) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1120,8 +1212,10 @@ class DataProvidersTest { fakeTransformCallbackCalled = true transformStringAsync(it) } - val baseProvider = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) - val dataProvider = dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) + val baseProvider = + createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base failure")) + val dataProvider = + dataProviders.transformAsync(TRANSFORMED_PROVIDER_ID, baseProvider, fakeTransformCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockIntLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1136,9 +1230,10 @@ class DataProvidersTest { fun testCombine_toLiveData_deliversCombinedValue() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1153,11 +1248,13 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_firstProviderChanges_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1175,11 +1272,13 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_firstProviderChanges_notifiesCombined_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1197,7 +1296,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_firstProviderChanges_observeBase_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStrings(v1, v2) @@ -1219,7 +1319,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_firstProvChanges_observeBase_notifiesCombined_deliversOldValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStrings(v1, v2) @@ -1246,10 +1347,12 @@ class DataProvidersTest { fun testCombine_secondProviderChanges_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1268,10 +1371,12 @@ class DataProvidersTest { fun testCombine_secondProviderChanges_notifiesCombined_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1290,7 +1395,8 @@ class DataProvidersTest { fun testCombine_secondProviderChanges_observeBase_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStrings(v1, v2) } @@ -1312,7 +1418,8 @@ class DataProvidersTest { fun testCombine_secondProvChanges_observeBase_notifiesCombined_deliversOldValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStrings(v1, v2) } @@ -1338,9 +1445,10 @@ class DataProvidersTest { fun testCombine_firstProviderPending_deliversPending() { val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1355,9 +1463,10 @@ class DataProvidersTest { fun testCombine_secondProviderPending_deliversPending() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1372,9 +1481,10 @@ class DataProvidersTest { fun testCombine_bothProvidersPending_deliversPending() { val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1387,19 +1497,24 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombine_firstProviderFailing_deliversFailure() { - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -1407,37 +1522,48 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_secondProviderFailing_deliversFailure() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombine_bothProvidersFailing_deliversFailure() { - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -1451,7 +1577,8 @@ class DataProvidersTest { } val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1471,7 +1598,8 @@ class DataProvidersTest { } val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1491,7 +1619,8 @@ class DataProvidersTest { } val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1511,7 +1640,8 @@ class DataProvidersTest { } val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1529,9 +1659,11 @@ class DataProvidersTest { fakeCombineCallbackCalled = true combineStrings(str1, str2) } - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1550,8 +1682,10 @@ class DataProvidersTest { combineStrings(str1, str2) } val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1569,9 +1703,12 @@ class DataProvidersTest { fakeCombineCallbackCalled = true combineStrings(str1, str2) } - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback) dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1584,19 +1721,26 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombine_firstProviderThrowsException_deliversFailure() { - val baseProvider1 = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = createThrowingDataProvider( + BASE_PROVIDER_ID_0, + IllegalStateException("Base 1 failure") + ) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -1604,37 +1748,54 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombine_secondProviderThrowsException_deliversFailure() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createThrowingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider2 = createThrowingDataProvider( + BASE_PROVIDER_ID_1, + IllegalStateException("Base 2 failure") + ) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombine_bothProvidersThrowExceptions_deliversFailure() { - val baseProvider1 = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createThrowingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStrings(v1, v2) - } + val baseProvider1 = createThrowingDataProvider( + BASE_PROVIDER_ID_0, + IllegalStateException("Base 1 failure") + ) + val baseProvider2 = createThrowingDataProvider( + BASE_PROVIDER_ID_1, + IllegalStateException("Base 2 failure") + ) + val dataProvider = + dataProviders.combine(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStrings(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -1654,7 +1815,9 @@ class DataProvidersTest { verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) } @Test @@ -1663,9 +1826,10 @@ class DataProvidersTest { fun testCombineAsync_toLiveData_deliversCombinedValue() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1680,11 +1844,13 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_firstProviderChanges_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1702,11 +1868,13 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_firstProviderChanges_notifiesCombined_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1724,7 +1892,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_firstProvChanges_observeBase_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStringsAsync(v1, v2) @@ -1746,7 +1915,8 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_firstProvChanges_obsrvBase_notifiesCombined_deliversOldVal() { inMemoryCachedStr = STR_VALUE_0 - val baseProvider1 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } + val baseProvider1 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_0) { inMemoryCachedStr!! } val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStringsAsync(v1, v2) @@ -1773,10 +1943,12 @@ class DataProvidersTest { fun testCombineAsync_secondProviderChanges_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1795,10 +1967,12 @@ class DataProvidersTest { fun testCombineAsync_secondProviderChanges_notifiesCombined_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) inMemoryCachedStr = STR_VALUE_2 @@ -1817,7 +1991,8 @@ class DataProvidersTest { fun testCombineAsync_secondProvChanges_observeBase_notifiesBase_deliversNewValue() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStringsAsync(v1, v2) } @@ -1839,7 +2014,8 @@ class DataProvidersTest { fun testCombineAsync_secondProvChanges_obsrvBase_notifiesCombined_deliversOldVal() { inMemoryCachedStr = STR_VALUE_1 val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } + val baseProvider2 = + dataProviders.createInMemoryDataProvider(BASE_PROVIDER_ID_1) { inMemoryCachedStr!! } dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> combineStringsAsync(v1, v2) } @@ -1865,9 +2041,10 @@ class DataProvidersTest { fun testCombineAsync_firstProviderPending_deliversPending() { val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1882,9 +2059,10 @@ class DataProvidersTest { fun testCombineAsync_secondProviderPending_deliversPending() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1899,9 +2077,10 @@ class DataProvidersTest { fun testCombineAsync_bothProvidersPending_deliversPending() { val baseProvider1 = createPendingDataProvider(BASE_PROVIDER_ID_0) val baseProvider2 = createPendingDataProvider(BASE_PROVIDER_ID_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() @@ -1914,19 +2093,24 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombineAsync_firstProviderFailing_deliversFailure() { - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -1934,37 +2118,48 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_secondProviderFailing_deliversFailure() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombineAsync_bothProvidersFailing_deliversFailure() { - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -2064,7 +2259,8 @@ class DataProvidersTest { fakeCombineCallbackCalled = true combineStringsAsync(str1, str2) } - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) val dataProvider = dataProviders.combineAsync( COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback @@ -2087,7 +2283,8 @@ class DataProvidersTest { combineStringsAsync(str1, str2) } val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) val dataProvider = dataProviders.combineAsync( COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback ) @@ -2108,8 +2305,10 @@ class DataProvidersTest { fakeCombineCallbackCalled = true combineStringsAsync(str1, str2) } - val baseProvider1 = createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) + val baseProvider1 = + createFailingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider2 = + createFailingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) val dataProvider = dataProviders.combineAsync( COMBINED_PROVIDER_ID, baseProvider1, baseProvider2, fakeCombineCallback ) @@ -2125,19 +2324,26 @@ class DataProvidersTest { @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombineAsync_firstProviderThrowsException_deliversFailure() { - val baseProvider1 = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) + val baseProvider1 = createThrowingDataProvider( + BASE_PROVIDER_ID_0, + IllegalStateException("Base 1 failure") + ) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -2145,37 +2351,54 @@ class DataProvidersTest { @ExperimentalCoroutinesApi fun testCombineAsync_secondProviderThrowsException_deliversFailure() { val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) - val baseProvider2 = createThrowingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider2 = createThrowingDataProvider( + BASE_PROVIDER_ID_1, + IllegalStateException("Base 2 failure") + ) + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @InternalCoroutinesApi @ExperimentalCoroutinesApi fun testCombineAsync_bothProvidersThrowExceptions_deliversFailure() { - val baseProvider1 = createThrowingDataProvider(BASE_PROVIDER_ID_0, IllegalStateException("Base 1 failure")) - val baseProvider2 = createThrowingDataProvider(BASE_PROVIDER_ID_1, IllegalStateException("Base 2 failure")) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val baseProvider1 = createThrowingDataProvider( + BASE_PROVIDER_ID_0, + IllegalStateException("Base 1 failure") + ) + val baseProvider2 = createThrowingDataProvider( + BASE_PROVIDER_ID_1, + IllegalStateException("Base 2 failure") + ) + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) testCoroutineDispatchers.advanceUntilIdle() verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(AsyncResult.ChainedFailureException::class.java) - assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat().isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + AsyncResult.ChainedFailureException::class.java + ) + assertThat(stringResultCaptor.value.getErrorOrNull()).hasCauseThat() + .isInstanceOf(IllegalStateException::class.java) } @Test @@ -2185,11 +2408,12 @@ class DataProvidersTest { // Block the first provider. val baseProvider1 = createBlockingDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - // Note that this doesn't use combineStringsAsync since that relies on the blocked - // backgroundTestCoroutineDispatcher. - AsyncResult.success(combineStrings(v1, v2)) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + // Note that this doesn't use combineStringsAsync since that relies on the blocked + // backgroundTestCoroutineDispatcher. + AsyncResult.success(combineStrings(v1, v2)) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -2204,11 +2428,12 @@ class DataProvidersTest { // Block the first provider. val baseProvider1 = createBlockingDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - // Note that this doesn't use combineStringsAsync since that relies on the blocked - // backgroundTestCoroutineDispatcher. - AsyncResult.success(combineStrings(v1, v2)) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + // Note that this doesn't use combineStringsAsync since that relies on the blocked + // backgroundTestCoroutineDispatcher. + AsyncResult.success(combineStrings(v1, v2)) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) // Resume the test thread after registration. @@ -2227,11 +2452,12 @@ class DataProvidersTest { // Block the second provider. val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createBlockingDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - // Note that this doesn't use combineStringsAsync since that relies on the blocked - // backgroundTestCoroutineDispatcher. - AsyncResult.success(combineStrings(v1, v2)) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + // Note that this doesn't use combineStringsAsync since that relies on the blocked + // backgroundTestCoroutineDispatcher. + AsyncResult.success(combineStrings(v1, v2)) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -2246,11 +2472,12 @@ class DataProvidersTest { // Block first provider. val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createBlockingDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - // Note that this doesn't use combineStringsAsync since that relies on the blocked - // backgroundTestCoroutineDispatcher. - AsyncResult.success(combineStrings(v1, v2)) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + // Note that this doesn't use combineStringsAsync since that relies on the blocked + // backgroundTestCoroutineDispatcher. + AsyncResult.success(combineStrings(v1, v2)) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) // Resume the test thread after registration. @@ -2269,9 +2496,10 @@ class DataProvidersTest { // Block combineStringsAsync(). val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> - combineStringsAsync(v1, v2) - } + val dataProvider = + dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + combineStringsAsync(v1, v2) + } dataProviders.convertToLiveData(dataProvider).observeForever(mockStringLiveDataObserver) @@ -2286,7 +2514,9 @@ class DataProvidersTest { // Block combineStringsAsync(). val baseProvider1 = createSuccessfulDataProvider(BASE_PROVIDER_ID_0, STR_VALUE_0) val baseProvider2 = createSuccessfulDataProvider(BASE_PROVIDER_ID_1, STR_VALUE_1) - val dataProvider = dataProviders.combineAsync(COMBINED_PROVIDER_ID, baseProvider1, baseProvider2) { v1, v2 -> + val dataProvider = dataProviders.combineAsync( + COMBINED_PROVIDER_ID, baseProvider1, baseProvider2 + ) { v1, v2 -> combineStringsAsync(v1, v2) } @@ -2336,7 +2566,9 @@ class DataProvidersTest { verify(mockStringLiveDataObserver).onChanged(stringResultCaptor.capture()) assertThat(stringResultCaptor.value.isFailure()).isTrue() - assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf(IllegalStateException::class.java) + assertThat(stringResultCaptor.value.getErrorOrNull()).isInstanceOf( + IllegalStateException::class.java + ) } @Test @@ -2949,14 +3181,16 @@ class DataProvidersTest { private fun createPendingDataProvider(id: Any): DataProvider { return dataProviders.createInMemoryDataProviderAsync(id) { - @Suppress("RemoveExplicitTypeArguments") // Android Studio incorrectly suggests to remove the explicit argument. + // Android Studio incorrectly suggests to remove the explicit argument. + @Suppress("RemoveExplicitTypeArguments") AsyncResult.pending() } } private fun createFailingDataProvider(id: Any, failure: Exception): DataProvider { return dataProviders.createInMemoryDataProviderAsync(id) { - @Suppress("RemoveExplicitTypeArguments") // Android Studio incorrectly suggests to remove the explicit argument. + // Android Studio incorrectly suggests to remove the explicit argument. + @Suppress("RemoveExplicitTypeArguments") AsyncResult.failed(failure) } } @@ -2994,7 +3228,12 @@ class DataProvidersTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestDispatcherModule::class, TestModule::class, TestLogReportingModule::class]) + @Component( + modules = [ + TestDispatcherModule::class, TestModule::class, + TestLogReportingModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/utility/src/test/java/org/oppia/util/data/InMemoryBlockingCacheTest.kt b/utility/src/test/java/org/oppia/util/data/InMemoryBlockingCacheTest.kt index 9930dbb43a9..0cab43ec01a 100644 --- a/utility/src/test/java/org/oppia/util/data/InMemoryBlockingCacheTest.kt +++ b/utility/src/test/java/org/oppia/util/data/InMemoryBlockingCacheTest.kt @@ -38,7 +38,8 @@ private const val UPDATED_ASYNC_VALUE = "updated async value" @RunWith(AndroidJUnit4::class) @Config(manifest = Config.NONE) class InMemoryBlockingCacheTest { - @Inject lateinit var cacheFactory: InMemoryBlockingCache.Factory + @Inject + lateinit var cacheFactory: InMemoryBlockingCache.Factory @ExperimentalCoroutinesApi @Inject @@ -131,13 +132,14 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testCreateIfAbsent_withoutInitialValue_returnsCreatedValue() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create() + fun testCreateIfAbsent_withoutInitialValue_returnsCreatedValue() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create() - val createResult = cache.createIfAbsentAsync { CREATED_ASYNC_VALUE } + val createResult = cache.createIfAbsentAsync { CREATED_ASYNC_VALUE } - assertThat(awaitCompletion(createResult)).isEqualTo(CREATED_ASYNC_VALUE) - } + assertThat(awaitCompletion(createResult)).isEqualTo(CREATED_ASYNC_VALUE) + } @Test @ExperimentalCoroutinesApi @@ -151,54 +153,60 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testCreateIfAbsent_withInitialValue_returnsCurrentCacheValue() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testCreateIfAbsent_withInitialValue_returnsCurrentCacheValue() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - val createResult = cache.createIfAbsentAsync { CREATED_ASYNC_VALUE } + val createResult = cache.createIfAbsentAsync { CREATED_ASYNC_VALUE } - // Because the cache is already initialized, it's not recreated. - assertThat(awaitCompletion(createResult)).isEqualTo(INITIALIZED_CACHE_VALUE) - } + // Because the cache is already initialized, it's not recreated. + assertThat(awaitCompletion(createResult)).isEqualTo(INITIALIZED_CACHE_VALUE) + } @Test @ExperimentalCoroutinesApi - fun testCreateIfAbsent_withInitialValue_doesNotChangeCacheValue() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testCreateIfAbsent_withInitialValue_doesNotChangeCacheValue() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - doNotAwaitCompletion(cache.createIfAbsentAsync { CREATED_ASYNC_VALUE }) + doNotAwaitCompletion(cache.createIfAbsentAsync { CREATED_ASYNC_VALUE }) - // Because the cache is already initialized, it's not recreated. - assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) - } + // Because the cache is already initialized, it's not recreated. + assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) + } @Test @ExperimentalCoroutinesApi - fun testCreateIfAbsent_emptyCache_blockingFunction_createIsNotComplete() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create() - backgroundTestCoroutineDispatcher.pauseDispatcher() + fun testCreateIfAbsent_emptyCache_blockingFunction_createIsNotComplete() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create() + backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { CREATED_ASYNC_VALUE } - val createOperation = cache.createIfAbsentAsync { blockingOperation.await() } + val blockingOperation = backgroundTestCoroutineScope.async { CREATED_ASYNC_VALUE } + val createOperation = cache.createIfAbsentAsync { blockingOperation.await() } - // The blocking operation should also block creation. - assertThat(createOperation.isCompleted).isFalse() - } + // The blocking operation should also block creation. + assertThat(createOperation.isCompleted).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testCreateIfAbsent_emptyCache_blockingFunction_completed_createCompletes() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create() - backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { CREATED_ASYNC_VALUE } - val createOperation = cache.createIfAbsentAsync { blockingOperation.await() } + fun testCreateIfAbsent_emptyCache_blockingFunction_completed_createCompletes() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create() + backgroundTestCoroutineDispatcher.pauseDispatcher() + val blockingOperation = backgroundTestCoroutineScope.async { CREATED_ASYNC_VALUE } + val createOperation = cache.createIfAbsentAsync { blockingOperation.await() } - backgroundTestCoroutineDispatcher.advanceUntilIdle() + backgroundTestCoroutineDispatcher.advanceUntilIdle() - // Completing the blocking operation should complete creation. - assertThat(createOperation.isCompleted).isTrue() - } + // Completing the blocking operation should complete creation. + assertThat(createOperation.isCompleted).isTrue() + } @Test @ExperimentalCoroutinesApi @@ -228,8 +236,10 @@ class InMemoryBlockingCacheTest { val deferredRead = cache.readIfPresentAsync() - val exception = assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredRead) } - assertThat(exception).hasMessageThat().contains("Expected to read the cache only after it's been created") + val exception = + assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredRead) } + assertThat(exception).hasMessageThat() + .contains("Expected to read the cache only after it's been created") } @Test @@ -275,7 +285,8 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi fun testUpdateCache_blockingFunction_blocksUpdate() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() val cache = cacheFactory.create() backgroundTestCoroutineDispatcher.pauseDispatcher() @@ -288,18 +299,20 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testUpdateCache_blockingFunction_completed_updateCompletes() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create() - backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } - val updateOperation = cache.updateAsync { blockingOperation.await() } + fun testUpdateCache_blockingFunction_completed_updateCompletes() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create() + backgroundTestCoroutineDispatcher.pauseDispatcher() + val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } + val updateOperation = cache.updateAsync { blockingOperation.await() } - backgroundTestCoroutineDispatcher.advanceUntilIdle() + backgroundTestCoroutineDispatcher.advanceUntilIdle() - // Completing the blocking operation should complete updating. - assertThat(updateOperation.isCompleted).isTrue() - } + // Completing the blocking operation should complete updating. + assertThat(updateOperation.isCompleted).isTrue() + } @Test @ExperimentalCoroutinesApi @@ -331,38 +344,44 @@ class InMemoryBlockingCacheTest { val deferredUpdate = cache.updateIfPresentAsync { UPDATED_ASYNC_VALUE } // The operation should fail since the method expects the cache to be initialized. - val exception = assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredUpdate) } - assertThat(exception).hasMessageThat().contains("Expected to update the cache only after it's been created") + val exception = + assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredUpdate) } + assertThat(exception).hasMessageThat() + .contains("Expected to update the cache only after it's been created") } @Test @ExperimentalCoroutinesApi - fun testUpdateIfPresent_initedCache_blockingFunction_blocksUpdate() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - backgroundTestCoroutineDispatcher.pauseDispatcher() + fun testUpdateIfPresent_initedCache_blockingFunction_blocksUpdate() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } - val updateOperation = cache.updateIfPresentAsync { blockingOperation.await() } + val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } + val updateOperation = cache.updateIfPresentAsync { blockingOperation.await() } - // The blocking operation should also block updating. - assertThat(updateOperation.isCompleted).isFalse() - } + // The blocking operation should also block updating. + assertThat(updateOperation.isCompleted).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testUpdateIfPresent_initedCache_blockingFunction_completed_updateCompletes() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } - val updateOperation = cache.updateIfPresentAsync { blockingOperation.await() } + fun testUpdateIfPresent_initedCache_blockingFunction_completed_updateCompletes() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + backgroundTestCoroutineDispatcher.pauseDispatcher() + val blockingOperation = backgroundTestCoroutineScope.async { UPDATED_ASYNC_VALUE } + val updateOperation = cache.updateIfPresentAsync { blockingOperation.await() } - backgroundTestCoroutineDispatcher.advanceUntilIdle() + backgroundTestCoroutineDispatcher.advanceUntilIdle() - // Completing the blocking operation should complete updating. - assertThat(updateOperation.isCompleted).isTrue() - } + // Completing the blocking operation should complete updating. + assertThat(updateOperation.isCompleted).isTrue() + } @Test @ExperimentalCoroutinesApi @@ -461,8 +480,10 @@ class InMemoryBlockingCacheTest { val deferredRead = cache.readIfPresentAsync() // Deleting the cache should result in readIfPresent()'s expectations to fail. - val exception = assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredRead) } - assertThat(exception).hasMessageThat().contains("Expected to read the cache only after it's been created") + val exception = + assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredRead) } + assertThat(exception).hasMessageThat() + .contains("Expected to read the cache only after it's been created") } @Test @@ -496,8 +517,10 @@ class InMemoryBlockingCacheTest { val deferredUpdate = cache.updateIfPresentAsync { UPDATED_ASYNC_VALUE } // The operation should fail since the method expects the cache to be initialized. - val exception = assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredUpdate) } - assertThat(exception).hasMessageThat().contains("Expected to update the cache only after it's been created") + val exception = + assertThrowsAsync(IllegalStateException::class) { awaitCompletion(deferredUpdate) } + assertThat(exception).hasMessageThat() + .contains("Expected to update the cache only after it's been created") } @Test @@ -535,25 +558,27 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testMaybeDelete_nonEmptyCache_falsePredicate_returnsFalse() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeDelete_nonEmptyCache_falsePredicate_returnsFalse() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - val maybeDeleteResult = cache.maybeDeleteAsync { false } + val maybeDeleteResult = cache.maybeDeleteAsync { false } - // The predicate's false return value should be piped up to the deletion result. - assertThat(awaitCompletion(maybeDeleteResult)).isFalse() - } + // The predicate's false return value should be piped up to the deletion result. + assertThat(awaitCompletion(maybeDeleteResult)).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testMaybeDelete_nonEmptyCache_falsePredicate_keepsCacheNonEmpty() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeDelete_nonEmptyCache_falsePredicate_keepsCacheNonEmpty() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - doNotAwaitCompletion(cache.maybeDeleteAsync { false }) + doNotAwaitCompletion(cache.maybeDeleteAsync { false }) - // The cache should retain its value since the deletion predicate indicated it shouldn't be cleared. - assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) - } + // The cache should retain its value since the deletion predicate indicated it shouldn't be cleared. + assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) + } @Test @ExperimentalCoroutinesApi @@ -580,7 +605,8 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi fun testMaybeDelete_blockingFunction_blocksDeletion() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) backgroundTestCoroutineDispatcher.pauseDispatcher() @@ -593,41 +619,45 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testMaybeDelete_blockingFunction_completed_deletionCompletes() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { true } - val deleteOperation = cache.maybeDeleteAsync { blockingOperation.await() } + fun testMaybeDelete_blockingFunction_completed_deletionCompletes() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + backgroundTestCoroutineDispatcher.pauseDispatcher() + val blockingOperation = backgroundTestCoroutineScope.async { true } + val deleteOperation = cache.maybeDeleteAsync { blockingOperation.await() } - backgroundTestCoroutineDispatcher.advanceUntilIdle() + backgroundTestCoroutineDispatcher.advanceUntilIdle() - // Completing the blocking operation should complete deletion. - assertThat(deleteOperation.isCompleted).isTrue() - } + // Completing the blocking operation should complete deletion. + assertThat(deleteOperation.isCompleted).isTrue() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_emptyCache_falsePredicate_returnsFalse() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create() + fun testMaybeForceDelete_emptyCache_falsePredicate_returnsFalse() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create() - val maybeDeleteResult = cache.maybeForceDeleteAsync { false } + val maybeDeleteResult = cache.maybeForceDeleteAsync { false } - // An empty cache cannot be deleted. - assertThat(awaitCompletion(maybeDeleteResult)).isFalse() - } + // An empty cache cannot be deleted. + assertThat(awaitCompletion(maybeDeleteResult)).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_emptyCache_truePredicate_returnsTrue() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create() + fun testMaybeForceDelete_emptyCache_truePredicate_returnsTrue() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create() - val maybeDeleteResult = cache.maybeForceDeleteAsync { true } + val maybeDeleteResult = cache.maybeForceDeleteAsync { true } - // An empty cache cannot be deleted, but with force deletion the state of the cache is not checked. It's assumed - // that the cache was definitely cleared. - assertThat(awaitCompletion(maybeDeleteResult)).isTrue() - } + // An empty cache cannot be deleted, but with force deletion the state of the cache is not checked. It's assumed + // that the cache was definitely cleared. + assertThat(awaitCompletion(maybeDeleteResult)).isTrue() + } @Test @ExperimentalCoroutinesApi @@ -642,82 +672,93 @@ class InMemoryBlockingCacheTest { @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_nonEmptyCache_falsePredicate_returnsFalse() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeForceDelete_nonEmptyCache_falsePredicate_returnsFalse() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - val maybeDeleteResult = cache.maybeForceDeleteAsync { false } + val maybeDeleteResult = cache.maybeForceDeleteAsync { false } - // The predicate's false return value should be piped up to the deletion result. - assertThat(awaitCompletion(maybeDeleteResult)).isFalse() - } + // The predicate's false return value should be piped up to the deletion result. + assertThat(awaitCompletion(maybeDeleteResult)).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_nonEmptyCache_falsePredicate_keepsCacheNonEmpty() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeForceDelete_nonEmptyCache_falsePredicate_keepsCacheNonEmpty() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - doNotAwaitCompletion(cache.maybeForceDeleteAsync { false }) + doNotAwaitCompletion(cache.maybeForceDeleteAsync { false }) - // The cache should retain its value since the deletion predicate indicated it shouldn't be cleared. - assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) - } + // The cache should retain its value since the deletion predicate indicated it shouldn't be cleared. + assertThat(awaitCompletion(cache.readAsync())).isEqualTo(INITIALIZED_CACHE_VALUE) + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_nonEmptyCache_truePredicate_returnsTrue() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeForceDelete_nonEmptyCache_truePredicate_returnsTrue() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - val maybeDeleteResult = cache.maybeForceDeleteAsync { true } + val maybeDeleteResult = cache.maybeForceDeleteAsync { true } - // The predicate's true return value should be piped up to the deletion result. - assertThat(awaitCompletion(maybeDeleteResult)).isTrue() - } + // The predicate's true return value should be piped up to the deletion result. + assertThat(awaitCompletion(maybeDeleteResult)).isTrue() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_nonEmptyCache_truePredicate_emptiesCache() = runBlockingTest(testDispatcher) { - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + fun testMaybeForceDelete_nonEmptyCache_truePredicate_emptiesCache() = + runBlockingTest(testDispatcher) { + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - doNotAwaitCompletion(cache.maybeForceDeleteAsync { true }) + doNotAwaitCompletion(cache.maybeForceDeleteAsync { true }) - // The cache should be emptied as indicated by the deletion predicate. - assertThat(awaitCompletion(cache.readAsync())).isNull() - } + // The cache should be emptied as indicated by the deletion predicate. + assertThat(awaitCompletion(cache.readAsync())).isNull() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_blockingFunction_blocksDeletion() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - backgroundTestCoroutineDispatcher.pauseDispatcher() + fun testMaybeForceDelete_blockingFunction_blocksDeletion() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { true } - val deleteOperation = cache.maybeForceDeleteAsync { blockingOperation.await() } + val blockingOperation = backgroundTestCoroutineScope.async { true } + val deleteOperation = cache.maybeForceDeleteAsync { blockingOperation.await() } - // The blocking operation should also block deletion. - assertThat(deleteOperation.isCompleted).isFalse() - } + // The blocking operation should also block deletion. + assertThat(deleteOperation.isCompleted).isFalse() + } @Test @ExperimentalCoroutinesApi - fun testMaybeForceDelete_blockingFunction_completed_deletionCompletes() = runBlockingTest(testDispatcher) { - testDispatcher.resumeDispatcher() // Keep the test dispatcher active since this test is verifying blocking behavior. - val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) - backgroundTestCoroutineDispatcher.pauseDispatcher() - val blockingOperation = backgroundTestCoroutineScope.async { true } - val deleteOperation = cache.maybeForceDeleteAsync { blockingOperation.await() } + fun testMaybeForceDelete_blockingFunction_completed_deletionCompletes() = + runBlockingTest(testDispatcher) { + // Keep the test dispatcher active since this test is verifying blocking behavior. + testDispatcher.resumeDispatcher() + val cache = cacheFactory.create(INITIALIZED_CACHE_VALUE) + backgroundTestCoroutineDispatcher.pauseDispatcher() + val blockingOperation = backgroundTestCoroutineScope.async { true } + val deleteOperation = cache.maybeForceDeleteAsync { blockingOperation.await() } - backgroundTestCoroutineDispatcher.advanceUntilIdle() + backgroundTestCoroutineDispatcher.advanceUntilIdle() - // Completing the blocking operation should complete deletion. - assertThat(deleteOperation.isCompleted).isTrue() - } + // Completing the blocking operation should complete deletion. + assertThat(deleteOperation.isCompleted).isTrue() + } /** * Silences the warning that [Deferred] is unused. This is okay for tests that ensure await() is called at the end of * the test since the cache guarantees sequential execution. */ - private fun doNotAwaitCompletion(@Suppress("UNUSED_PARAMETER") deferred: Deferred) {} + private fun doNotAwaitCompletion( + @Suppress("UNUSED_PARAMETER") deferred: Deferred + ) { + } /** * Waits for the specified deferred to execute after advancing test dispatcher. Without this function, results cannot @@ -731,7 +772,10 @@ class InMemoryBlockingCacheTest { // TODO(#89): Move to a common test library. /** A replacement to JUnit5's assertThrows() with Kotlin suspend coroutine support. */ - private suspend fun assertThrowsAsync(type: KClass, operation: suspend () -> Unit): T { + private suspend fun assertThrowsAsync( + type: KClass, + operation: suspend () -> Unit + ): T { try { operation() fail("Expected to encounter exception of $type") @@ -751,7 +795,8 @@ class InMemoryBlockingCacheTest { .inject(this) } - @Qualifier annotation class TestDispatcher + @Qualifier + annotation class TestDispatcher // TODO(#89): Move this to a common test application component. @Module @@ -774,7 +819,9 @@ class InMemoryBlockingCacheTest { @Singleton @Provides @BlockingDispatcher - fun provideBlockingDispatcher(@TestDispatcher testDispatcher: TestCoroutineDispatcher): CoroutineDispatcher { + fun provideBlockingDispatcher( + @TestDispatcher testDispatcher: TestCoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } } diff --git a/utility/src/test/java/org/oppia/util/datetime/DateTimeUtilTest.kt b/utility/src/test/java/org/oppia/util/datetime/DateTimeUtilTest.kt index 802fac8751a..092278eaa3e 100644 --- a/utility/src/test/java/org/oppia/util/datetime/DateTimeUtilTest.kt +++ b/utility/src/test/java/org/oppia/util/datetime/DateTimeUtilTest.kt @@ -115,14 +115,18 @@ class DateTimeUtilTest { @Singleton @Provides @BackgroundDispatcher - fun provideBackgroundDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBackgroundDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } @Singleton @Provides @BlockingDispatcher - fun provideBlockingDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBlockingDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } diff --git a/utility/src/test/java/org/oppia/util/networking/NetworkConnectionUtilTest.kt b/utility/src/test/java/org/oppia/util/networking/NetworkConnectionUtilTest.kt index 21138e8d937..757e49e7df2 100644 --- a/utility/src/test/java/org/oppia/util/networking/NetworkConnectionUtilTest.kt +++ b/utility/src/test/java/org/oppia/util/networking/NetworkConnectionUtilTest.kt @@ -76,66 +76,90 @@ class NetworkConnectionUtilTest { @Test fun testGetCurrentConnectionStatus_activeWifiConnection_returnsWifi() { setNetworkConnectionStatus(ConnectivityManager.TYPE_WIFI, true) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.LOCAL) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.LOCAL + ) } @Test fun testGetCurrentConnectionStatus_nonActiveWifiConnection_returnsNone() { setNetworkConnectionStatus(ConnectivityManager.TYPE_WIFI, false) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } @Test fun testGetCurrentConnectionStatus_activeEthernetConnection_returnsWifi() { setNetworkConnectionStatus(ConnectivityManager.TYPE_ETHERNET, true) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.LOCAL) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.LOCAL + ) } @Test fun testGetCurrentConnectionStatus_nonActiveEthernetConnection_returnsNone() { setNetworkConnectionStatus(ConnectivityManager.TYPE_ETHERNET, false) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } @Test fun testGetCurrentConnectionStatus_activeCellularConnection_returnsCellular() { setNetworkConnectionStatus(ConnectivityManager.TYPE_MOBILE, true) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.CELLULAR) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.CELLULAR + ) } @Test fun testGetCurrentConnectionStatus_nonActiveCellularConnection_returnsNone() { setNetworkConnectionStatus(ConnectivityManager.TYPE_MOBILE, false) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } @Test fun testGetCurrentConnectionStatus_activeWimaxConnection_returnsCellular() { setNetworkConnectionStatus(ConnectivityManager.TYPE_WIMAX, true) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.CELLULAR) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.CELLULAR + ) } @Test fun testGetCurrentConnectionStatus_nonActiveWimaxConnection_returnsNone() { setNetworkConnectionStatus(ConnectivityManager.TYPE_WIMAX, false) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } @Test fun testGetCurrentConnectionStatus_noActiveNetworkConnection_returnsNone() { setNetworkConnectionStatus(NO_CONNECTION, false) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } @Test fun testGetCurrentConnectionStatus_activeBluetoothConnection_returnsNone() { setNetworkConnectionStatus(ConnectivityManager.TYPE_BLUETOOTH, true) - assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo(NetworkConnectionUtil.ConnectionStatus.NONE) + assertThat(networkConnectionUtil.getCurrentConnectionStatus()).isEqualTo( + NetworkConnectionUtil.ConnectionStatus.NONE + ) } private fun setNetworkConnectionStatus(status: Int, isConnected: Boolean) { shadowOf(context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager) - .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, status, 0, /* isAvailable= */ true, isConnected)) + .setActiveNetworkInfo( + ShadowNetworkInfo.newInstance( + null, status, 0, /* isAvailable= */ true, isConnected + ) + ) } @Qualifier @@ -161,14 +185,18 @@ class NetworkConnectionUtilTest { @Singleton @Provides @BackgroundDispatcher - fun provideBackgroundDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBackgroundDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } @Singleton @Provides @BlockingDispatcher - fun provideBlockingDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBlockingDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } diff --git a/utility/src/test/java/org/oppia/util/profile/DirectoryManagementUtilTest.kt b/utility/src/test/java/org/oppia/util/profile/DirectoryManagementUtilTest.kt index 1a6e685abbb..a73b26c7db8 100644 --- a/utility/src/test/java/org/oppia/util/profile/DirectoryManagementUtilTest.kt +++ b/utility/src/test/java/org/oppia/util/profile/DirectoryManagementUtilTest.kt @@ -185,14 +185,18 @@ class DirectoryManagementUtilTest { @Singleton @Provides @BackgroundDispatcher - fun provideBackgroundDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBackgroundDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher } @Singleton @Provides @BlockingDispatcher - fun provideBlockingDispatcher(@TestDispatcher testDispatcher: CoroutineDispatcher): CoroutineDispatcher { + fun provideBlockingDispatcher( + @TestDispatcher testDispatcher: CoroutineDispatcher + ): CoroutineDispatcher { return testDispatcher }