diff --git a/build.gradle b/build.gradle index af65e9c4bce..30208819267 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,8 @@ import com.google.firebase.gradle.MultiProjectReleasePlugin buildscript { ext.kotlinVersion = '1.7.10' + ext.coroutinesVersion = '1.6.4' + repositories { google() mavenCentral() diff --git a/firebase-common/ktx/ktx.gradle b/firebase-common/ktx/ktx.gradle index fac922882f5..2d15573ab83 100644 --- a/firebase-common/ktx/ktx.gradle +++ b/firebase-common/ktx/ktx.gradle @@ -42,8 +42,13 @@ dependencies { implementation project(':firebase-components') implementation 'androidx.annotation:annotation:1.1.0' + // We're exposing this library as a transitive dependency so developers can + // get Kotlin Coroutines support out-of-the-box for methods that return a Task + api "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion" + testImplementation "org.robolectric:robolectric:$robolectricVersion" testImplementation 'junit:junit:4.12' testImplementation "com.google.truth:truth:$googleTruthVersion" testImplementation 'androidx.test:core:1.2.0' + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion" } diff --git a/firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt b/firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt index 62a2d757169..45bcaece248 100644 --- a/firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt +++ b/firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt @@ -15,10 +15,14 @@ package com.google.firebase.ktx import androidx.test.core.app.ApplicationProvider +import com.google.android.gms.tasks.Tasks import com.google.common.truth.Truth.assertThat import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseOptions import com.google.firebase.platforminfo.UserAgentPublisher +import kotlinx.coroutines.tasks.await +import kotlinx.coroutines.test.runTest +import org.junit.Assert.fail import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -36,6 +40,8 @@ fun withApp(name: String, block: FirebaseApp.() -> Unit) { } } +class TestException(message: String) : Exception(message) + @RunWith(RobolectricTestRunner::class) class VersionTests { @Test @@ -101,3 +107,33 @@ class KtxTests { } } } + +class CoroutinesPlayServicesTests { + // We are only interested in the await() function offered by kotlinx-coroutines-play-services + // So we're not testing the other functions provided by that library. + + @Test + fun `Task#await() resolves to the same result as Task#getResult()`() = runTest { + val task = Tasks.forResult(21) + + val expected = task.result + val actual = task.await() + + assertThat(actual).isEqualTo(expected) + assertThat(task.isSuccessful).isTrue() + assertThat(task.exception).isNull() + } + + @Test + fun `Task#await() throws an Exception for failing Tasks`() = runTest { + val task = Tasks.forException(TestException("some error happened")) + + try { + task.await() + fail("Task#await should throw an Exception") + } catch (e: Exception) { + assertThat(e).isInstanceOf(TestException::class.java) + assertThat(task.isSuccessful).isFalse() + } + } +} diff --git a/firebase-firestore/ktx/ktx.gradle b/firebase-firestore/ktx/ktx.gradle index a520029398a..04e58cf4d5c 100644 --- a/firebase-firestore/ktx/ktx.gradle +++ b/firebase-firestore/ktx/ktx.gradle @@ -57,7 +57,7 @@ dependencies { implementation project(':firebase-common:ktx') implementation project(':firebase-firestore') implementation 'androidx.annotation:annotation:1.1.0' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" implementation 'com.google.android.gms:play-services-basement:18.1.0' testImplementation project(':firebase-database-collection') testImplementation 'org.mockito:mockito-core:2.25.0'