From 54bb9c03a8a5fa797ecb109c0cdb3be1cacbb902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 2 Oct 2024 16:55:59 +0200 Subject: [PATCH] Fix more and more issues --- .../appnav/loggedin/LoggedInPresenterTest.kt | 11 +- features/cachecleaner/api/build.gradle.kts | 5 +- .../call/ui/CallScreenPresenterTest.kt | 7 +- features/enterprise/impl/build.gradle.kts | 5 +- features/ftue/test/build.gradle.kts | 5 +- features/licenses/impl/build.gradle.kts | 1 - .../WebViewMessageInterceptor.kt | 2 +- features/migration/impl/build.gradle.kts | 5 +- features/roomdirectory/impl/build.gradle.kts | 1 - gradle/libs.versions.toml | 2 +- .../bottomsheet/CustomSheetState.kt | 5 - libraries/mediapickers/api/build.gradle.kts | 5 +- libraries/mediapickers/test/build.gradle.kts | 5 +- .../push/test/test/FakePushHandler.kt | 2 +- .../VectorFirebaseMessagingServiceTest.kt | 5 +- .../VectorUnifiedPushMessagingReceiverTest.kt | 9 +- .../roomselect/impl/RoomSelectPresenter.kt | 4 +- .../main/kotlin/extension/CommonExtension.kt | 4 +- ...ent.android-compose-application.gradle.kts | 2 +- ...element.android-compose-library.gradle.kts | 2 +- .../tests/testutils/lambda/LambdaRecorder.kt | 198 +++++++++++++++++- tools/detekt/detekt.yml | 2 +- tools/lint/lint.xml | 4 + 23 files changed, 251 insertions(+), 40 deletions(-) diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt index 519cceddfe..4419066b9c 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt @@ -43,6 +43,7 @@ import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.lambdaSuspendRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first @@ -145,7 +146,7 @@ class LoggedInPresenterTest { @Test fun `present - ensure default pusher is registered with default provider`() = runTest { - val lambda = lambdaRecorder> { _, _, _ -> + val lambda = lambdaSuspendRecorder> { _, _, _ -> Result.success(Unit) } val sessionVerificationService = FakeSessionVerificationService( @@ -178,7 +179,7 @@ class LoggedInPresenterTest { @Test fun `present - ensure default pusher is registered with default provider - fail to register`() = runTest { - val lambda = lambdaRecorder> { _, _, _ -> + val lambda = lambdaSuspendRecorder> { _, _, _ -> Result.failure(AN_EXCEPTION) } val sessionVerificationService = FakeSessionVerificationService( @@ -211,7 +212,7 @@ class LoggedInPresenterTest { @Test fun `present - ensure current provider is registered with current distributor`() = runTest { - val lambda = lambdaRecorder> { _, _, _ -> + val lambda = lambdaSuspendRecorder> { _, _, _ -> Result.success(Unit) } val sessionVerificationService = FakeSessionVerificationService( @@ -256,7 +257,7 @@ class LoggedInPresenterTest { @Test fun `present - if current push provider does not have current distributor, the first one is used`() = runTest { - val lambda = lambdaRecorder> { _, _, _ -> + val lambda = lambdaSuspendRecorder> { _, _, _ -> Result.success(Unit) } val sessionVerificationService = FakeSessionVerificationService( @@ -422,7 +423,7 @@ class LoggedInPresenterTest { @Test fun `present - case two push providers but first one does not have distributor - second one will be used`() = runTest { - val lambda = lambdaRecorder> { _, _, _ -> + val lambda = lambdaSuspendRecorder> { _, _, _ -> Result.success(Unit) } val sessionVerificationService = FakeSessionVerificationService( diff --git a/features/cachecleaner/api/build.gradle.kts b/features/cachecleaner/api/build.gradle.kts index ebe4fe0dd7..30dfd6d42c 100644 --- a/features/cachecleaner/api/build.gradle.kts +++ b/features/cachecleaner/api/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2023, 2024 New Vector Ltd. * @@ -7,13 +9,14 @@ plugins { id("io.element.android-library") - alias(libs.plugins.anvil) } android { namespace = "io.element.android.features.cachecleaner.api" } +setupAnvil() + dependencies { implementation(projects.libraries.architecture) implementation(libs.androidx.startup) diff --git a/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt b/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt index 7390b5fde9..f0e5708db3 100644 --- a/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt +++ b/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt @@ -109,12 +109,7 @@ class CallScreenPresenterTest { assertThat(initialState.isInWidgetMode).isTrue() assertThat(widgetProvider.getWidgetCalled).isTrue() assertThat(widgetDriver.runCalledCount).isEqualTo(1) - // Called several times because of the recomposition - analyticsLambda.assertions().isCalledExactly(2) - .withSequence( - listOf(value(MobileScreen.ScreenName.RoomCall)), - listOf(value(MobileScreen.ScreenName.RoomCall)) - ) + analyticsLambda.assertions().isCalledOnce().with(value(MobileScreen.ScreenName.RoomCall)) sendCallNotificationIfNeededLambda.assertions().isCalledOnce() } } diff --git a/features/enterprise/impl/build.gradle.kts b/features/enterprise/impl/build.gradle.kts index fa03bd48e7..5e4ce5c387 100644 --- a/features/enterprise/impl/build.gradle.kts +++ b/features/enterprise/impl/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2024 New Vector Ltd. * @@ -6,13 +8,14 @@ */ plugins { id("io.element.android-library") - alias(libs.plugins.anvil) } android { namespace = "io.element.android.features.enterprise.impl" } +setupAnvil() + dependencies { implementation(projects.anvilannotations) api(projects.features.enterprise.api) diff --git a/features/ftue/test/build.gradle.kts b/features/ftue/test/build.gradle.kts index 989c3382d6..223b5c855a 100644 --- a/features/ftue/test/build.gradle.kts +++ b/features/ftue/test/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2024 New Vector Ltd. * @@ -7,7 +9,6 @@ plugins { id("io.element.android-compose-library") - alias(libs.plugins.anvil) id("kotlin-parcelize") } @@ -15,6 +16,8 @@ android { namespace = "io.element.android.features.ftue.test" } +setupAnvil() + dependencies { implementation(projects.features.ftue.api) implementation(projects.tests.testutils) diff --git a/features/licenses/impl/build.gradle.kts b/features/licenses/impl/build.gradle.kts index 36bbd7ef34..9b86cb94a6 100644 --- a/features/licenses/impl/build.gradle.kts +++ b/features/licenses/impl/build.gradle.kts @@ -10,7 +10,6 @@ import extension.setupAnvil plugins { id("io.element.android-compose-library") id("kotlin-parcelize") - alias(libs.plugins.anvil) alias(libs.plugins.kotlin.serialization) } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt index 6dfe903b09..fedc288855 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt @@ -51,7 +51,7 @@ class WebViewMessageInterceptor( } override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { - request ?: return super.shouldOverrideUrlLoading(view, request) + request ?: return false // Load the URL in a Chrome Custom Tab, and return true to cancel the load onOpenExternalUrl(request.url.toString()) return true diff --git a/features/migration/impl/build.gradle.kts b/features/migration/impl/build.gradle.kts index 30e1b0c331..c89af9115d 100644 --- a/features/migration/impl/build.gradle.kts +++ b/features/migration/impl/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2024 New Vector Ltd. * @@ -7,13 +9,14 @@ plugins { id("io.element.android-compose-library") - alias(libs.plugins.anvil) } android { namespace = "io.element.android.features.migration.impl" } +setupAnvil() + dependencies { implementation(projects.features.migration.api) implementation(projects.libraries.architecture) diff --git a/features/roomdirectory/impl/build.gradle.kts b/features/roomdirectory/impl/build.gradle.kts index 6d05cad8e3..3fec2f0bb7 100644 --- a/features/roomdirectory/impl/build.gradle.kts +++ b/features/roomdirectory/impl/build.gradle.kts @@ -9,7 +9,6 @@ import extension.setupAnvil plugins { id("io.element.android-compose-library") - alias(libs.plugins.anvil) id("kotlin-parcelize") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3683b65e49..0eb9963118 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ # Project android_gradle_plugin = "8.7.0" kotlin = "2.0.20" -kotlinpoetKsp = "1.17.0" +kotlinpoetKsp = "1.18.1" ksp = "2.0.20-1.0.25" firebaseAppDistribution = "5.0.0" diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt index ac02787c3f..694674621a 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt @@ -7,7 +7,6 @@ package io.element.android.libraries.designsystem.theme.components.bottomsheet -import androidx.compose.animation.core.DecayAnimationSpec import androidx.compose.animation.core.SpringSpec import androidx.compose.animation.core.exponentialDecay import androidx.compose.foundation.ExperimentalFoundationApi @@ -296,13 +295,9 @@ internal object AnchoredDraggableDefaults { /** * The default animation used by [AnchoredDraggableState]. */ - @get:ExperimentalMaterial3Api - @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET") @ExperimentalMaterial3Api val SnapAnimationSpec = SpringSpec() - @get:ExperimentalMaterial3Api - @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET") @ExperimentalMaterial3Api val DecayAnimationSpec = exponentialDecay() } diff --git a/libraries/mediapickers/api/build.gradle.kts b/libraries/mediapickers/api/build.gradle.kts index 24a556d10f..edb9e9263b 100644 --- a/libraries/mediapickers/api/build.gradle.kts +++ b/libraries/mediapickers/api/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2023, 2024 New Vector Ltd. * @@ -7,9 +9,10 @@ plugins { id("io.element.android-compose-library") - alias(libs.plugins.anvil) } +setupAnvil() + android { namespace = "io.element.android.libraries.mediapickers.api" diff --git a/libraries/mediapickers/test/build.gradle.kts b/libraries/mediapickers/test/build.gradle.kts index 6316465538..689fc0d8eb 100644 --- a/libraries/mediapickers/test/build.gradle.kts +++ b/libraries/mediapickers/test/build.gradle.kts @@ -1,3 +1,5 @@ +import extension.setupAnvil + /* * Copyright 2023, 2024 New Vector Ltd. * @@ -7,9 +9,10 @@ plugins { id("io.element.android-compose-library") - alias(libs.plugins.anvil) } +setupAnvil() + android { namespace = "io.element.android.libraries.mediapickers.test" diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/test/FakePushHandler.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/test/FakePushHandler.kt index 9b85271c28..0bec9685cf 100644 --- a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/test/FakePushHandler.kt +++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/test/FakePushHandler.kt @@ -12,7 +12,7 @@ import io.element.android.libraries.pushproviders.api.PushHandler import io.element.android.tests.testutils.lambda.lambdaError class FakePushHandler( - private val handleResult: (PushData) -> Unit = { lambdaError() } + private val handleResult: suspend (PushData) -> Unit = { lambdaError() } ) : PushHandler { override suspend fun handle(pushData: PushData) { handleResult(pushData) diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt index aa9f23850d..21fc74dc63 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/VectorFirebaseMessagingServiceTest.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.push.test.test.FakePushHandler import io.element.android.libraries.pushproviders.api.PushData import io.element.android.libraries.pushproviders.api.PushHandler import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.lambdaSuspendRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -31,7 +32,7 @@ import org.robolectric.RobolectricTestRunner class VectorFirebaseMessagingServiceTest { @Test fun `test receiving invalid data`() = runTest { - val lambda = lambdaRecorder(ensureNeverCalled = true) { } + val lambda = lambdaSuspendRecorder(ensureNeverCalled = true) { } val vectorFirebaseMessagingService = createVectorFirebaseMessagingService( pushHandler = FakePushHandler(handleResult = lambda) ) @@ -40,7 +41,7 @@ class VectorFirebaseMessagingServiceTest { @Test fun `test receiving valid data`() = runTest { - val lambda = lambdaRecorder { } + val lambda = lambdaSuspendRecorder { } val vectorFirebaseMessagingService = createVectorFirebaseMessagingService( pushHandler = FakePushHandler(handleResult = lambda) ) diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt index be5f66e0f0..afea987679 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.pushproviders.api.PushHandler import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.lambdaSuspendRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -50,7 +51,7 @@ class VectorUnifiedPushMessagingReceiverTest { @Test fun `onMessage valid invoke the push handler`() = runTest { val context = InstrumentationRegistry.getInstrumentation().context - val pushHandlerResult = lambdaRecorder {} + val pushHandlerResult = lambdaSuspendRecorder {} val vectorUnifiedPushMessagingReceiver = createVectorUnifiedPushMessagingReceiver( pushHandler = FakePushHandler( handleResult = pushHandlerResult @@ -75,7 +76,7 @@ class VectorUnifiedPushMessagingReceiverTest { @Test fun `onMessage invalid does not invoke the push handler`() = runTest { val context = InstrumentationRegistry.getInstrumentation().context - val pushHandlerResult = lambdaRecorder {} + val pushHandlerResult = lambdaSuspendRecorder {} val vectorUnifiedPushMessagingReceiver = createVectorUnifiedPushMessagingReceiver( pushHandler = FakePushHandler( handleResult = pushHandlerResult @@ -97,7 +98,7 @@ class VectorUnifiedPushMessagingReceiverTest { storeUpEndpointResult = storeUpEndpointResult, ) val endpointRegistrationHandler = EndpointRegistrationHandler() - val handleResult = lambdaRecorder> { _, _, _ -> Result.success(Unit) } + val handleResult = lambdaSuspendRecorder> { _, _, _ -> Result.success(Unit) } val unifiedPushNewGatewayHandler = FakeUnifiedPushNewGatewayHandler( handleResult = handleResult ) @@ -137,7 +138,7 @@ class VectorUnifiedPushMessagingReceiverTest { storeUpEndpointResult = storeUpEndpointResult, ) val endpointRegistrationHandler = EndpointRegistrationHandler() - val handleResult = lambdaRecorder> { _, _, _ -> Result.failure(AN_EXCEPTION) } + val handleResult = lambdaSuspendRecorder> { _, _, _ -> Result.failure(AN_EXCEPTION) } val unifiedPushNewGatewayHandler = FakeUnifiedPushNewGatewayHandler( handleResult = handleResult ) diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt index 74911c3f03..2aecef4788 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.roomselect.impl import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -22,6 +23,7 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.roomselect.api.RoomSelectMode +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -50,7 +52,7 @@ class RoomSelectPresenter @AssistedInject constructor( val roomSummaryDetailsList by dataSource.roomSummaries.collectAsState(initial = persistentListOf()) - val searchResults by remember { + val searchResults by remember>>> { derivedStateOf { when { roomSummaryDetailsList.isNotEmpty() -> SearchBarResultState.Results(roomSummaryDetailsList.toImmutableList()) diff --git a/plugins/src/main/kotlin/extension/CommonExtension.kt b/plugins/src/main/kotlin/extension/CommonExtension.kt index 66c2e8860e..4f3f23d707 100644 --- a/plugins/src/main/kotlin/extension/CommonExtension.kt +++ b/plugins/src/main/kotlin/extension/CommonExtension.kt @@ -10,7 +10,6 @@ package extension import Versions import com.android.build.api.dsl.CommonExtension import isEnterpriseBuild -import org.gradle.accessors.dm.LibrariesForLibs import org.gradle.api.Project import java.io.File @@ -44,12 +43,13 @@ fun CommonExtension<*, *, *, *, *, *>.androidConfig(project: Project) { } checkDependencies = false abortOnError = true + ignoreTestSources = true ignoreTestFixturesSources = true checkGeneratedSources = false } } -fun CommonExtension<*, *, *, *, *, *>.composeConfig(libs: LibrariesForLibs) { +fun CommonExtension<*, *, *, *, *, *>.composeConfig() { buildFeatures { compose = true diff --git a/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts b/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts index 873b242148..967e4fd707 100644 --- a/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts +++ b/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts @@ -24,7 +24,7 @@ plugins { android { androidConfig(project) - composeConfig(libs) + composeConfig() compileOptions { isCoreLibraryDesugaringEnabled = true } diff --git a/plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts b/plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts index f9d7f81218..b4d7fe650a 100644 --- a/plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts +++ b/plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts @@ -24,7 +24,7 @@ plugins { android { androidConfig(project) - composeConfig(libs) + composeConfig() compileOptions { isCoreLibraryDesugaringEnabled = true } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/lambda/LambdaRecorder.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/lambda/LambdaRecorder.kt index c4e5222060..b0edda40cc 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/lambda/LambdaRecorder.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/lambda/LambdaRecorder.kt @@ -27,6 +27,26 @@ abstract class LambdaRecorder internal constructor( } } +/** + * A recorder that can be used to record the parameters of a suspend lambda invocation. + */ +abstract class LambdaSuspendRecorder internal constructor( + private val assertNoInvocation: Boolean, +) { + private val parametersSequence: MutableList> = mutableListOf() + + internal suspend fun onInvoke(vararg params: Any?) { + if (assertNoInvocation) { + lambdaError() + } + parametersSequence.add(params.toList()) + } + + fun assertions(): LambdaRecorderAssertions { + return LambdaRecorderAssertions(parametersSequence = parametersSequence) + } +} + inline fun lambdaRecorder( ensureNeverCalled: Boolean = false, noinline block: () -> R @@ -90,6 +110,71 @@ inline fun lambdaAnyRecorder( return LambdaListAnyParamsRecorder(ensureNeverCalled, block) } +// Suspend versions + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: () -> R +): LambdaNoParamRecorder { + return LambdaNoParamRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T) -> R +): LambdaOneParamSuspendRecorder { + return LambdaOneParamSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2) -> R +): LambdaTwoParamsSuspendRecorder { + return LambdaTwoParamsSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2, T3) -> R +): LambdaSuspendThreeParamsRecorder { + return LambdaSuspendThreeParamsRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2, T3, T4) -> R +): LambdaFourParamsSuspendRecorder { + return LambdaFourParamsSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2, T3, T4, T5) -> R +): LambdaFiveParamsSuspendRecorder { + return LambdaFiveParamsSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2, T3, T4, T5, T6) -> R +): LambdaSixParamsSuspendRecorder { + return LambdaSixParamsSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (T1, T2, T3, T4, T5, T6, T7) -> R +): LambdaSevenParamsSuspendRecorder { + return LambdaSevenParamsSuspendRecorder(ensureNeverCalled, block) +} + +inline fun lambdaSuspendAnyRecorder( + ensureNeverCalled: Boolean = false, + noinline block: suspend (List) -> R +): LambdaListAnyParamsSuspendRecorder { + return LambdaListAnyParamsSuspendRecorder(ensureNeverCalled, block) +} + class LambdaNoParamRecorder(ensureNeverCalled: Boolean, val block: () -> R) : LambdaRecorder(ensureNeverCalled), () -> R { override fun invoke(): R { onInvoke() @@ -97,6 +182,13 @@ class LambdaNoParamRecorder(ensureNeverCalled: Boolean, val block: () -> } } +class LambdaNoParamSuspendRecorder(ensureNeverCalled: Boolean, val block: suspend () -> R) : LambdaRecorder(ensureNeverCalled), suspend () -> R { + override suspend fun invoke(): R { + onInvoke() + return block() + } +} + class LambdaOneParamRecorder(ensureNeverCalled: Boolean, val block: (T) -> R) : LambdaRecorder(ensureNeverCalled), (T) -> R { override fun invoke(p: T): R { onInvoke(p) @@ -104,6 +196,15 @@ class LambdaOneParamRecorder(ensureNeverCalled: Boolean, val block: } } +class LambdaOneParamSuspendRecorder(ensureNeverCalled: Boolean, val block: suspend (T) -> R) : LambdaRecorder( + ensureNeverCalled +), suspend (T) -> R { + override suspend fun invoke(p: T): R { + onInvoke(p) + return block(p) + } +} + class LambdaTwoParamsRecorder(ensureNeverCalled: Boolean, val block: (T1, T2) -> R) : LambdaRecorder(ensureNeverCalled), (T1, T2) -> R { override fun invoke(p1: T1, p2: T2): R { onInvoke(p1, p2) @@ -111,6 +212,15 @@ class LambdaTwoParamsRecorder(ensureNeverCalled: Boolean, v } } +class LambdaTwoParamsSuspendRecorder(ensureNeverCalled: Boolean, val block: suspend (T1, T2) -> R) : LambdaRecorder( + ensureNeverCalled +), suspend (T1, T2) -> R { + override suspend fun invoke(p1: T1, p2: T2): R { + onInvoke(p1, p2) + return block(p1, p2) + } +} + class LambdaThreeParamsRecorder(ensureNeverCalled: Boolean, val block: (T1, T2, T3) -> R) : LambdaRecorder( ensureNeverCalled ), (T1, T2, T3) -> R { @@ -120,6 +230,15 @@ class LambdaThreeParamsRecorder(ensureNeverCalled: B } } +class LambdaSuspendThreeParamsRecorder(ensureNeverCalled: Boolean, val block: suspend (T1, T2, T3) -> R) : LambdaSuspendRecorder( + ensureNeverCalled +), suspend (T1, T2, T3) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3): R { + onInvoke(p1, p2, p3) + return block(p1, p2, p3) + } +} + class LambdaFourParamsRecorder(ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4) -> R) : LambdaRecorder( ensureNeverCalled ), (T1, T2, T3, T4) -> R { @@ -129,7 +248,22 @@ class LambdaFourParamsRecorder(ensureNeverCal } } -class LambdaFiveParamsRecorder(ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4, T5) -> R) : LambdaRecorder( +class LambdaFourParamsSuspendRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4) -> R +) : LambdaRecorder( + ensureNeverCalled +), suspend (T1, T2, T3, T4) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4): R { + onInvoke(p1, p2, p3, p4) + return block(p1, p2, p3, p4) + } +} + +class LambdaFiveParamsRecorder( + ensureNeverCalled: Boolean, + val block: (T1, T2, T3, T4, T5) -> R, +) : LambdaRecorder( ensureNeverCalled ), (T1, T2, T3, T4, T5) -> R { override fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5): R { @@ -138,6 +272,18 @@ class LambdaFiveParamsRecorder(ensureN } } +class LambdaFiveParamsSuspendRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4, T5) -> R +) : LambdaRecorder( + ensureNeverCalled +), suspend (T1, T2, T3, T4, T5) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5): R { + onInvoke(p1, p2, p3, p4, p5) + return block(p1, p2, p3, p4, p5) + } +} + class LambdaSixParamsRecorder( ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4, T5, T6) -> R, @@ -148,6 +294,16 @@ class LambdaSixParamsRecorder( } } +class LambdaSixParamsSuspendRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4, T5, T6) -> R, +) : LambdaRecorder(ensureNeverCalled), suspend (T1, T2, T3, T4, T5, T6) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5, p6: T6): R { + onInvoke(p1, p2, p3, p4, p5, p6) + return block(p1, p2, p3, p4, p5, p6) + } +} + class LambdaSevenParamsRecorder( ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4, T5, T6, T7) -> R, @@ -158,6 +314,16 @@ class LambdaSevenParamsRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4, T5, T6, T7) -> R, +) : LambdaRecorder(ensureNeverCalled), suspend (T1, T2, T3, T4, T5, T6, T7) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5, p6: T6, p7: T7): R { + onInvoke(p1, p2, p3, p4, p5, p6, p7) + return block(p1, p2, p3, p4, p5, p6, p7) + } +} + class LambdaEightParamsRecorder( ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4, T5, T6, T7, T8) -> R, @@ -168,6 +334,16 @@ class LambdaEightParamsRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R, +) : LambdaRecorder(ensureNeverCalled), suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5, p6: T6, p7: T7, p8: T8): R { + onInvoke(p1, p2, p3, p4, p5, p6, p7, p8) + return block(p1, p2, p3, p4, p5, p6, p7, p8) + } +} + class LambdaNineParamsRecorder( ensureNeverCalled: Boolean, val block: (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R, @@ -178,6 +354,16 @@ class LambdaNineParamsRecorder( + ensureNeverCalled: Boolean, + val block: suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R, +) : LambdaRecorder(ensureNeverCalled), suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R { + override suspend fun invoke(p1: T1, p2: T2, p3: T3, p4: T4, p5: T5, p6: T6, p7: T7, p8: T8, p9: T9): R { + onInvoke(p1, p2, p3, p4, p5, p6, p7, p8, p9) + return block(p1, p2, p3, p4, p5, p6, p7, p8, p9) + } +} + class LambdaListAnyParamsRecorder( ensureNeverCalled: Boolean, val block: (List) -> R, @@ -187,3 +373,13 @@ class LambdaListAnyParamsRecorder( return block(p) } } + +class LambdaListAnyParamsSuspendRecorder( + ensureNeverCalled: Boolean, + val block: suspend (List) -> R, +) : LambdaSuspendRecorder(ensureNeverCalled), suspend (List) -> R { + override suspend fun invoke(p: List): R { + onInvoke(*p.toTypedArray()) + return block(p) + } +} diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 263b2e9683..1e73ef425d 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -3,7 +3,7 @@ style: AlsoCouldBeApply: active: true - OptionalWhenBraces: + BracesOnWhenStatements: active: false CascadingCallWrapping: active: true diff --git a/tools/lint/lint.xml b/tools/lint/lint.xml index 57b2ab0750..7638025905 100644 --- a/tools/lint/lint.xml +++ b/tools/lint/lint.xml @@ -117,4 +117,8 @@ + + + +