From 4eb89fd732f7e789bfb6301a6170b1ce52ed5795 Mon Sep 17 00:00:00 2001 From: cartland Date: Fri, 22 Aug 2025 16:07:38 -0700 Subject: [PATCH 1/3] Add snippets for testing Kotlin Flows This commit adds a series of snippets from the Kotlin Flow testing documentation. It includes examples of how to test Repositories and ViewModels that expose Flows and StateFlows. The snippets are organized into two new test files: - RepositoryTest.kt - ViewModelTest.kt A MainDispatcherRule is also introduced to handle setting the main dispatcher in tests. Region-Tag: android_snippets_kotlin_flow_test_fake_repository Region-Tag: android_snippets_kotlin_flow_test_my_test Region-Tag: android_snippets_kotlin_flow_test_repository_test_first Region-Tag: android_snippets_kotlin_flow_test_repository_test_to_list Region-Tag: android_snippets_kotlin_flow_test_repository_and_datasource Region-Tag: android_snippets_kotlin_flow_test_continuously_collect Region-Tag: android_snippets_kotlin_flow_test_using_turbine Region-Tag: android_snippets_kotlin_flow_test_my_view_model Region-Tag: android_snippets_kotlin_flow_test_fake_repository_viewmodel Region-Tag: android_snippets_kotlin_flow_test_hot_fake_repository Region-Tag: android_snippets_kotlin_flow_test_my_view_model_with_state_in Region-Tag: android_snippets_kotlin_flow_test_lazily_sharing_view_model --- gradle/libs.versions.toml | 2 + kotlin/build.gradle.kts | 1 + .../example/flow/test/MainDispatcherRule.kt | 39 +++++ .../example/flow/test/RepositoryTest.kt | 155 ++++++++++++++++++ .../example/flow/test/ViewModelTest.kt | 126 ++++++++++++++ 5 files changed, 323 insertions(+) create mode 100644 kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt create mode 100644 kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt create mode 100644 kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 77f80c6d1..491008758 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -77,6 +77,7 @@ wearComposeMaterial3 = "1.5.0-rc02" wearOngoing = "1.0.0" wearToolingPreview = "1.0.0" webkit = "1.14.0" +turbine = "0.13.0" [libraries] accompanist-adaptive = "com.google.accompanist:accompanist-adaptive:0.37.3" @@ -189,6 +190,7 @@ play-services-wearable = { module = "com.google.android.gms:play-services-wearab validator-push = { module = "com.google.android.wearable.watchface.validator:validator-push", version.ref = "validatorPush" } wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" } wear-compose-material3 = { module = "androidx.wear.compose:compose-material3", version.ref = "wearComposeMaterial3" } +turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } [plugins] android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts index 12feddf2d..d5e091dbb 100644 --- a/kotlin/build.gradle.kts +++ b/kotlin/build.gradle.kts @@ -58,4 +58,5 @@ dependencies { implementation(libs.kotlinx.coroutines.android) testImplementation(libs.kotlinx.coroutines.test) testImplementation(libs.junit) + testImplementation(libs.turbine) } diff --git a/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt b/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt new file mode 100644 index 000000000..856ab9150 --- /dev/null +++ b/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.flow.test + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@ExperimentalCoroutinesApi +class MainDispatcherRule( + val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(), +) : TestWatcher() { + override fun starting(description: Description) { + Dispatchers.setMain(testDispatcher) + } + + override fun finished(description: Description) { + Dispatchers.resetMain() + } +} diff --git a/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt new file mode 100644 index 000000000..3c0af1b85 --- /dev/null +++ b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.flow.test + +import app.cash.turbine.test +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Test + +private const val ITEM_1 = "item1" +private val ALL_MESSAGES = listOf("message1", "message2") + +interface MyRepository { + fun observeCount(): Flow + fun observeChatMessages(): Flow> +} + +// [START android_snippets_kotlin_flow_test_fake_repository] +class MyFakeRepository : MyRepository { + override fun observeCount() = flow { + emit(ITEM_1) + } + + override fun observeChatMessages(): Flow> = flow { + emit(ALL_MESSAGES) + } +} +// [END android_snippets_kotlin_flow_test_fake_repository] + +class MyUnitUnderTest(private val myRepository: MyRepository) + +class RepositoryTest { + + @Test + fun myTest() { + // [START android_snippets_kotlin_flow_test_my_test] + // Given a class with fake dependencies: + val sut = MyUnitUnderTest(MyFakeRepository()) + // Trigger and verify + // ... + // [END android_snippets_kotlin_flow_test_my_test] + } + + @Test + fun myRepositoryTest_first() = runTest { + // [START android_snippets_kotlin_flow_test_repository_test_first] + // Given a repository that combines values from two data sources: + val repository = MyFakeRepository() + + // When the repository emits a value + val firstItem = repository.observeCount().first() // Returns the first item in the flow + + // Then check it's the expected item + assertEquals(ITEM_1, firstItem) + // [END android_snippets_kotlin_flow_test_repository_test_first] + } + + @Test + fun myRepositoryTest_toList() = runTest { + // [START android_snippets_kotlin_flow_test_repository_test_to_list] + // Given a repository with a fake data source that emits ALL_MESSAGES + val repository = MyFakeRepository() + val messages = repository.observeChatMessages().toList() + + // When all messages are emitted then they should be ALL_MESSAGES + assertEquals(ALL_MESSAGES, messages[0]) + // [END android_snippets_kotlin_flow_test_repository_test_to_list] + } +} + +// [START android_snippets_kotlin_flow_test_repository_and_datasource] +interface DataSource { + fun counts(): Flow +} + +class Repository(private val dataSource: DataSource) { + fun scores(): Flow { + return dataSource.counts().map { it * 10 } + } +} + +class FakeDataSource : DataSource { + private val flow = MutableSharedFlow() + suspend fun emit(value: Int) = flow.emit(value) + override fun counts(): Flow = flow +} +// [END android_snippets_kotlin_flow_test_repository_and_datasource] + +@OptIn(ExperimentalCoroutinesApi::class) +class ContinuousCollectionTest { + @Test + fun continuouslyCollect() = runTest { + // [START android_snippets_kotlin_flow_test_continuously_collect] + val dataSource = FakeDataSource() + val repository = Repository(dataSource) + + val values = mutableListOf() + backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { + repository.scores().toList(values) + } + + dataSource.emit(1) + assertEquals(10, values[0]) // Assert on the list contents + + dataSource.emit(2) + dataSource.emit(3) + assertEquals(30, values[2]) + + assertEquals(3, values.size) // Assert the number of items collected + // [END android_snippets_kotlin_flow_test_continuously_collect] + } + + @Test + fun usingTurbine() = runTest { + // [START android_snippets_kotlin_flow_test_using_turbine] + val dataSource = FakeDataSource() + val repository = Repository(dataSource) + + repository.scores().test { + // Make calls that will trigger value changes only within test{} + dataSource.emit(1) + assertEquals(10, awaitItem()) + + dataSource.emit(2) + awaitItem() // Ignore items if needed, can also use skip(n) + + dataSource.emit(3) + assertEquals(30, awaitItem()) + } + // [END android_snippets_kotlin_flow_test_using_turbine] + } +} diff --git a/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt new file mode 100644 index 000000000..127e09e7b --- /dev/null +++ b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.flow.test + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +interface MyRepositoryVM { + fun scores(): Flow +} + +// [START android_snippets_kotlin_flow_test_my_view_model] +class MyViewModel(private val myRepository: MyRepositoryVM) : ViewModel() { + private val _score = MutableStateFlow(0) + val score: StateFlow = _score.asStateFlow() + + fun initialize() { + viewModelScope.launch { + myRepository.scores().collect { score -> + _score.value = score + } + } + } +} +// [END android_snippets_kotlin_flow_test_my_view_model] + +// [START android_snippets_kotlin_flow_test_fake_repository_viewmodel] +class FakeRepository : MyRepositoryVM { + private val flow = MutableSharedFlow() + suspend fun emit(value: Int) = flow.emit(value) + override fun scores(): Flow = flow +} +// [END android_snippets_kotlin_flow_test_fake_repository_viewmodel] + +@OptIn(ExperimentalCoroutinesApi::class) +class ViewModelTest { + @get:Rule + val mainDispatcherRule = MainDispatcherRule() + + @Test + fun testHotFakeRepository() = runTest { + // [START android_snippets_kotlin_flow_test_hot_fake_repository] + val fakeRepository = FakeRepository() + val viewModel = MyViewModel(fakeRepository) + + assertEquals(0, viewModel.score.value) // Assert on the initial value + + // Start collecting values from the Repository + viewModel.initialize() + + // Then we can send in values one by one, which the ViewModel will collect + fakeRepository.emit(1) + assertEquals(1, viewModel.score.value) + + fakeRepository.emit(2) + fakeRepository.emit(3) + assertEquals(3, viewModel.score.value) // Assert on the latest value + // [END android_snippets_kotlin_flow_test_hot_fake_repository] + } +} + +// [START android_snippets_kotlin_flow_test_my_view_model_with_state_in] +class MyViewModelWithStateIn(myRepository: MyRepositoryVM) : ViewModel() { + val score: StateFlow = myRepository.scores() + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), 0) +} +// [END android_snippets_kotlin_flow_test_my_view_model_with_state_in] + +typealias HotFakeRepository = FakeRepository + +@OptIn(ExperimentalCoroutinesApi::class) +class LazilySharingViewModelTest { + @get:Rule + val mainDispatcherRule = MainDispatcherRule() + + @Test + fun testLazilySharingViewModel() = runTest { + // [START android_snippets_kotlin_flow_test_lazily_sharing_view_model] + val fakeRepository = HotFakeRepository() + val viewModel = MyViewModelWithStateIn(fakeRepository) + + // Create an empty collector for the StateFlow + backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { + viewModel.score.collect {} + } + + assertEquals(0, viewModel.score.value) // Can assert initial value + + // Trigger-assert like before + fakeRepository.emit(1) + assertEquals(1, viewModel.score.value) + + fakeRepository.emit(2) + fakeRepository.emit(3) + assertEquals(3, viewModel.score.value) + // [END android_snippets_kotlin_flow_test_lazily_sharing_view_model] + } +} From 3b78d8a1f3aaa708533a3b0d461d37f4a14388ee Mon Sep 17 00:00:00 2001 From: cartland Date: Fri, 22 Aug 2025 16:17:38 -0700 Subject: [PATCH 2/3] Refactor: Move Turbine test to a separate file This commit refactors the Flow testing snippets by moving the Turbine test to its own file. To avoid code duplication, the and classes were moved to a new file, so they can be shared between tests. --- .../example/flow/test/RepositoryTest.kt | 67 ------------------- .../android/example/flow/test/TurbineTest.kt | 44 ++++++++++++ .../example/flow/test/ViewModelTest.kt | 8 +-- .../com/android/example/flow/test/fakes.kt | 39 +++++++++++ 4 files changed, 87 insertions(+), 71 deletions(-) create mode 100644 kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt create mode 100644 kotlin/src/test/java/com/android/example/flow/test/fakes.kt diff --git a/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt index 3c0af1b85..c60115f1a 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt @@ -16,16 +16,10 @@ package com.android.example.flow.test -import app.cash.turbine.test -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Test @@ -91,65 +85,4 @@ class RepositoryTest { } } -// [START android_snippets_kotlin_flow_test_repository_and_datasource] -interface DataSource { - fun counts(): Flow -} - -class Repository(private val dataSource: DataSource) { - fun scores(): Flow { - return dataSource.counts().map { it * 10 } - } -} - -class FakeDataSource : DataSource { - private val flow = MutableSharedFlow() - suspend fun emit(value: Int) = flow.emit(value) - override fun counts(): Flow = flow -} -// [END android_snippets_kotlin_flow_test_repository_and_datasource] - -@OptIn(ExperimentalCoroutinesApi::class) -class ContinuousCollectionTest { - @Test - fun continuouslyCollect() = runTest { - // [START android_snippets_kotlin_flow_test_continuously_collect] - val dataSource = FakeDataSource() - val repository = Repository(dataSource) - val values = mutableListOf() - backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { - repository.scores().toList(values) - } - - dataSource.emit(1) - assertEquals(10, values[0]) // Assert on the list contents - - dataSource.emit(2) - dataSource.emit(3) - assertEquals(30, values[2]) - - assertEquals(3, values.size) // Assert the number of items collected - // [END android_snippets_kotlin_flow_test_continuously_collect] - } - - @Test - fun usingTurbine() = runTest { - // [START android_snippets_kotlin_flow_test_using_turbine] - val dataSource = FakeDataSource() - val repository = Repository(dataSource) - - repository.scores().test { - // Make calls that will trigger value changes only within test{} - dataSource.emit(1) - assertEquals(10, awaitItem()) - - dataSource.emit(2) - awaitItem() // Ignore items if needed, can also use skip(n) - - dataSource.emit(3) - assertEquals(30, awaitItem()) - } - // [END android_snippets_kotlin_flow_test_using_turbine] - } -} diff --git a/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt b/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt new file mode 100644 index 000000000..b7f675f04 --- /dev/null +++ b/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.flow.test + +import app.cash.turbine.test +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Test + +class TurbineTest { + @Test + fun usingTurbine() = runTest { + // [START android_snippets_kotlin_flow_test_using_turbine] + val dataSource = FakeDataSource() + val repository = Repository(dataSource) + + repository.scores().test { + // Make calls that will trigger value changes only within test{} + dataSource.emit(1) + assertEquals(10, awaitItem()) + + dataSource.emit(2) + awaitItem() // Ignore items if needed, can also use skip(n) + + dataSource.emit(3) + assertEquals(30, awaitItem()) + } + // [END android_snippets_kotlin_flow_test_using_turbine] + } +} diff --git a/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt index 127e09e7b..637cdfe30 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt @@ -65,9 +65,9 @@ class ViewModelTest { @get:Rule val mainDispatcherRule = MainDispatcherRule() + // [START android_snippets_kotlin_flow_test_hot_fake_repository] @Test fun testHotFakeRepository() = runTest { - // [START android_snippets_kotlin_flow_test_hot_fake_repository] val fakeRepository = FakeRepository() val viewModel = MyViewModel(fakeRepository) @@ -83,8 +83,8 @@ class ViewModelTest { fakeRepository.emit(2) fakeRepository.emit(3) assertEquals(3, viewModel.score.value) // Assert on the latest value - // [END android_snippets_kotlin_flow_test_hot_fake_repository] } + // [END android_snippets_kotlin_flow_test_hot_fake_repository] } // [START android_snippets_kotlin_flow_test_my_view_model_with_state_in] @@ -101,9 +101,9 @@ class LazilySharingViewModelTest { @get:Rule val mainDispatcherRule = MainDispatcherRule() + // [START android_snippets_kotlin_flow_test_lazily_sharing_view_model] @Test fun testLazilySharingViewModel() = runTest { - // [START android_snippets_kotlin_flow_test_lazily_sharing_view_model] val fakeRepository = HotFakeRepository() val viewModel = MyViewModelWithStateIn(fakeRepository) @@ -121,6 +121,6 @@ class LazilySharingViewModelTest { fakeRepository.emit(2) fakeRepository.emit(3) assertEquals(3, viewModel.score.value) - // [END android_snippets_kotlin_flow_test_lazily_sharing_view_model] } + // [END android_snippets_kotlin_flow_test_lazily_sharing_view_model] } diff --git a/kotlin/src/test/java/com/android/example/flow/test/fakes.kt b/kotlin/src/test/java/com/android/example/flow/test/fakes.kt new file mode 100644 index 000000000..1d4cbd6f1 --- /dev/null +++ b/kotlin/src/test/java/com/android/example/flow/test/fakes.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.example.flow.test + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.map + +// [START android_snippets_kotlin_flow_test_repository_and_datasource] +interface DataSource { + fun counts(): Flow +} + +class Repository(private val dataSource: DataSource) { + fun scores(): Flow { + return dataSource.counts().map { it * 10 } + } +} + +class FakeDataSource : DataSource { + private val flow = MutableSharedFlow() + suspend fun emit(value: Int) = flow.emit(value) + override fun counts(): Flow = flow +} +// [END android_snippets_kotlin_flow_test_repository_and_datasource] From 784e75c0acf019d9be411d47f508c8780923406c Mon Sep 17 00:00:00 2001 From: cartland <846051+cartland@users.noreply.github.com> Date: Fri, 22 Aug 2025 23:35:55 +0000 Subject: [PATCH 3/3] Apply Spotless --- .../com/android/example/flow/test/MainDispatcherRule.kt | 4 ++-- .../java/com/android/example/flow/test/RepositoryTest.kt | 6 ++---- .../test/java/com/android/example/flow/test/TurbineTest.kt | 4 ++-- .../java/com/android/example/flow/test/ViewModelTest.kt | 4 ++-- kotlin/src/test/java/com/android/example/flow/test/fakes.kt | 4 ++-- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt b/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt index 856ab9150..6b27af9d2 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/MainDispatcherRule.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2025 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt index c60115f1a..272487ba3 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/RepositoryTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2025 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -84,5 +84,3 @@ class RepositoryTest { // [END android_snippets_kotlin_flow_test_repository_test_to_list] } } - - diff --git a/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt b/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt index b7f675f04..c8e8205bc 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/TurbineTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2025 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt index 637cdfe30..aa36234c1 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/ViewModelTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2025 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/kotlin/src/test/java/com/android/example/flow/test/fakes.kt b/kotlin/src/test/java/com/android/example/flow/test/fakes.kt index 1d4cbd6f1..9973288bb 100644 --- a/kotlin/src/test/java/com/android/example/flow/test/fakes.kt +++ b/kotlin/src/test/java/com/android/example/flow/test/fakes.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2025 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS,