diff --git a/samples/dungeon/timemachine/src/test/java/com/squareup/sample/timemachine/TimeMachineWorkflowTest.kt b/samples/dungeon/timemachine/src/test/java/com/squareup/sample/timemachine/TimeMachineWorkflowTest.kt index 1c5d02d445..de0406e030 100644 --- a/samples/dungeon/timemachine/src/test/java/com/squareup/sample/timemachine/TimeMachineWorkflowTest.kt +++ b/samples/dungeon/timemachine/src/test/java/com/squareup/sample/timemachine/TimeMachineWorkflowTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.sample.timemachine import com.google.common.truth.Truth.assertThat diff --git a/samples/tictactoe/common/src/test/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflowTest.kt b/samples/tictactoe/common/src/test/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflowTest.kt index ea2afb738a..ca73a29308 100644 --- a/samples/tictactoe/common/src/test/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflowTest.kt +++ b/samples/tictactoe/common/src/test/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflowTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.sample.gameworkflow import com.google.common.truth.Truth.assertThat diff --git a/samples/tictactoe/common/src/test/java/com/squareup/sample/mainworkflow/TicTacToeWorkflowTest.kt b/samples/tictactoe/common/src/test/java/com/squareup/sample/mainworkflow/TicTacToeWorkflowTest.kt index 52a349bca2..ecacf2f768 100644 --- a/samples/tictactoe/common/src/test/java/com/squareup/sample/mainworkflow/TicTacToeWorkflowTest.kt +++ b/samples/tictactoe/common/src/test/java/com/squareup/sample/mainworkflow/TicTacToeWorkflowTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.sample.mainworkflow import com.google.common.truth.Truth.assertThat diff --git a/workflow-rx2/src/test/java/com/squareup/workflow1/rx2/PublisherWorkerTest.kt b/workflow-rx2/src/test/java/com/squareup/workflow1/rx2/PublisherWorkerTest.kt index 55cd6584a9..996e7da352 100644 --- a/workflow-rx2/src/test/java/com/squareup/workflow1/rx2/PublisherWorkerTest.kt +++ b/workflow-rx2/src/test/java/com/squareup/workflow1/rx2/PublisherWorkerTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.workflow1.rx2 import com.squareup.workflow1.Worker diff --git a/workflow-testing/api/workflow-testing.api b/workflow-testing/api/workflow-testing.api index e37c1e5d0d..63fd45a7f6 100644 --- a/workflow-testing/api/workflow-testing.api +++ b/workflow-testing/api/workflow-testing.api @@ -1,10 +1,3 @@ -public final class com/squareup/workflow1/testing/HeadlessIntegrationTestKt { - public static final fun headlessIntegrationTest (Lcom/squareup/workflow1/Workflow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;)V - public static final fun headlessIntegrationTest (Lcom/squareup/workflow1/Workflow;Lkotlinx/coroutines/flow/StateFlow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;)V - public static synthetic fun headlessIntegrationTest$default (Lcom/squareup/workflow1/Workflow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static synthetic fun headlessIntegrationTest$default (Lcom/squareup/workflow1/Workflow;Lkotlinx/coroutines/flow/StateFlow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V -} - public final class com/squareup/workflow1/testing/RenderIdempotencyChecker : com/squareup/workflow1/WorkflowInterceptor { public static final field INSTANCE Lcom/squareup/workflow1/testing/RenderIdempotencyChecker; public fun onInitialState (Ljava/lang/Object;Lcom/squareup/workflow1/Snapshot;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;Lcom/squareup/workflow1/WorkflowInterceptor$WorkflowSession;)Ljava/lang/Object; @@ -212,3 +205,10 @@ public final class com/squareup/workflow1/testing/WorkflowTurbine { public final class com/squareup/workflow1/testing/WorkflowTurbine$Companion { } +public final class com/squareup/workflow1/testing/WorkflowTurbineKt { + public static final fun renderForTest (Lcom/squareup/workflow1/Workflow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;)V + public static final fun renderForTest (Lcom/squareup/workflow1/Workflow;Lkotlinx/coroutines/flow/StateFlow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;)V + public static synthetic fun renderForTest$default (Lcom/squareup/workflow1/Workflow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static synthetic fun renderForTest$default (Lcom/squareup/workflow1/Workflow;Lkotlinx/coroutines/flow/StateFlow;Lkotlin/coroutines/CoroutineContext;Ljava/util/List;Ljava/util/Set;Lkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V +} + diff --git a/workflow-testing/src/main/java/com/squareup/workflow1/testing/RenderTester.kt b/workflow-testing/src/main/java/com/squareup/workflow1/testing/RenderTester.kt index 88062084ba..3fd5a5d8c8 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow1/testing/RenderTester.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow1/testing/RenderTester.kt @@ -112,6 +112,14 @@ public fun * - It is a test failure if no workflow or worker emitted an output, no rendering event was * invoked, and any of the action verification methods on [RenderTestResult] is called. * + * ## Testing Application + * + * Note that by providing the values for all child workflows, workers, and side effects, the test + * is extremely focused on the logic of the `render()` method. Everything else is essentially + * 'mocked'. If you do not have complex logic within `render()` that needs to be directly unit + * tested, then you may be better served by using a [WorkflowTurbine] and [renderForResult] as this + * will actually run your workflow (and any children, fake or not) in the runtime. + * * ## Examples * * ### Worker output diff --git a/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTestRuntime.kt b/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTestRuntime.kt index 619ec4d302..febcb04853 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTestRuntime.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTestRuntime.kt @@ -1,5 +1,5 @@ @file:OptIn(ExperimentalCoroutinesApi::class) -@file:Suppress("ktlint:standard:indent") +@file:Suppress("ktlint:standard:indent", "DEPRECATION") package com.squareup.workflow1.testing @@ -53,6 +53,7 @@ import kotlin.coroutines.EmptyCoroutineContext * - [sendProps] * - Send a new [PropsT] to the root workflow. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") public class WorkflowTestRuntime @TestOnly internal constructor( private val props: MutableStateFlow, private val renderingsAndSnapshotsFlow: Flow>, @@ -173,6 +174,7 @@ public class WorkflowTestRuntime @TestOnly internal * * All workflow-related coroutines are cancelled when the block exits. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") @TestOnly public fun Workflow.launchForTestingFromStartWith( @@ -187,6 +189,7 @@ public fun * * All workflow-related coroutines are cancelled when the block exits. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") @TestOnly public fun Workflow.launchForTestingFromStartWith( @@ -202,6 +205,7 @@ public fun * * All workflow-related coroutines are cancelled when the block exits. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") @TestOnly public fun StatefulWorkflow.launchForTestingFromStateWith( @@ -223,6 +227,7 @@ public fun * * All workflow-related coroutines are cancelled when the block exits. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") @TestOnly public fun StatefulWorkflow.launchForTestingFromStateWith( @@ -236,6 +241,7 @@ public fun * * All workflow-related coroutines are cancelled when the block exits. */ +@Deprecated("Use renderForTest and WorkflowTurbine instead.") @TestOnly public fun StatefulWorkflow.launchForTestingWith( diff --git a/workflow-testing/src/main/java/com/squareup/workflow1/testing/HeadlessIntegrationTest.kt b/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTurbine.kt similarity index 89% rename from workflow-testing/src/main/java/com/squareup/workflow1/testing/HeadlessIntegrationTest.kt rename to workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTurbine.kt index 0014d72474..4d7f0f1201 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow1/testing/HeadlessIntegrationTest.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow1/testing/WorkflowTurbine.kt @@ -3,9 +3,9 @@ package com.squareup.workflow1.testing import app.cash.turbine.ReceiveTurbine import app.cash.turbine.test import com.squareup.workflow1.RuntimeConfig -import com.squareup.workflow1.RuntimeConfigOptions import com.squareup.workflow1.Workflow import com.squareup.workflow1.WorkflowInterceptor +import com.squareup.workflow1.config.JvmTestRuntimeConfigTools import com.squareup.workflow1.renderWorkflowIn import com.squareup.workflow1.testing.WorkflowTurbine.Companion.WORKFLOW_TEST_DEFAULT_TIMEOUT_MS import kotlinx.coroutines.CoroutineScope @@ -22,8 +22,8 @@ import kotlin.coroutines.CoroutineContext import kotlin.time.Duration.Companion.milliseconds /** - * This is a test harness to run integration tests for a Workflow tree. The parameters passed here are - * the same as those to start a Workflow runtime with [renderWorkflowIn] except for ignoring + * This is a test harness to run turbine like tests for a Workflow tree. The parameters passed here + * are the same as those to start a Workflow runtime with [renderWorkflowIn] except for ignoring * state persistence as that is not needed for this style of test. * * The [coroutineContext] rather than a [CoroutineScope] is passed so that this harness handles the @@ -35,13 +35,15 @@ import kotlin.time.Duration.Companion.milliseconds * This will start the Workflow runtime (with params as passed) rooted at whatever Workflow * it is called on and then create a [WorkflowTurbine] for its renderings and run [testCase] on that. * [testCase] can thus drive the test scenario and assert against renderings. + * + * The default [RuntimeConfig] will be the one specified via [JvmTestRuntimeConfigTools]. */ @OptIn(ExperimentalCoroutinesApi::class) -public fun Workflow.headlessIntegrationTest( +public fun Workflow.renderForTest( props: StateFlow, coroutineContext: CoroutineContext = UnconfinedTestDispatcher(), interceptors: List = emptyList(), - runtimeConfig: RuntimeConfig = RuntimeConfigOptions.DEFAULT_CONFIG, + runtimeConfig: RuntimeConfig = JvmTestRuntimeConfigTools.getTestRuntimeConfig(), onOutput: suspend (OutputT) -> Unit = {}, testTimeout: Long = WORKFLOW_TEST_DEFAULT_TIMEOUT_MS, testCase: suspend WorkflowTurbine.() -> Unit @@ -82,18 +84,18 @@ public fun Workflow.h } /** - * Version of [headlessIntegrationTest] that does not require props. For Workflows that have [Unit] + * Version of [renderForTest] that does not require props. For Workflows that have [Unit] * props type. */ @OptIn(ExperimentalCoroutinesApi::class) -public fun Workflow.headlessIntegrationTest( +public fun Workflow.renderForTest( coroutineContext: CoroutineContext = UnconfinedTestDispatcher(), interceptors: List = emptyList(), - runtimeConfig: RuntimeConfig = RuntimeConfigOptions.DEFAULT_CONFIG, + runtimeConfig: RuntimeConfig = JvmTestRuntimeConfigTools.getTestRuntimeConfig(), onOutput: suspend (OutputT) -> Unit = {}, testTimeout: Long = WORKFLOW_TEST_DEFAULT_TIMEOUT_MS, testCase: suspend WorkflowTurbine.() -> Unit -): Unit = headlessIntegrationTest( +): Unit = renderForTest( props = MutableStateFlow(Unit).asStateFlow(), coroutineContext = coroutineContext, interceptors = interceptors, diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/SnapshottingIntegrationTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/SnapshottingIntegrationTest.kt index 307d999078..9f35543abb 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/SnapshottingIntegrationTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/SnapshottingIntegrationTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.workflow1 import com.squareup.workflow1.WorkflowAction.Companion.noAction diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowEventHandlerTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowEventHandlerTest.kt index 90fb6057ca..f8ec707789 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowEventHandlerTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowEventHandlerTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("JUnitMalformedDeclaration") +@file:Suppress("JUnitMalformedDeclaration", "DEPRECATION") package com.squareup.workflow1 diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowSafeEventHandlerTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowSafeEventHandlerTest.kt index 6b58b8ecf9..bf6d32782a 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowSafeEventHandlerTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/StatefulWorkflowSafeEventHandlerTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.workflow1 import com.squareup.workflow1.StatefulWorkflowSafeEventHandlerTest.State.Able diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/StatelessWorkflowEventHandlerTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/StatelessWorkflowEventHandlerTest.kt index 7be50b0b17..4a4f6586cc 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/StatelessWorkflowEventHandlerTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/StatelessWorkflowEventHandlerTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("JUnitMalformedDeclaration") +@file:Suppress("JUnitMalformedDeclaration", "DEPRECATION") package com.squareup.workflow1 diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/WorkerCompositionIntegrationTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/WorkerCompositionIntegrationTest.kt index c37c91e678..2d671f8428 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/WorkerCompositionIntegrationTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/WorkerCompositionIntegrationTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") +@file:Suppress("EXPERIMENTAL_API_USAGE", "DEPRECATION") package com.squareup.workflow1 diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowCompositionIntegrationTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowCompositionIntegrationTest.kt index 26e67f9ec3..cc94886a62 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowCompositionIntegrationTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowCompositionIntegrationTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.squareup.workflow1 import com.squareup.workflow1.testing.WorkerSink diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowsLifecycleTests.kt b/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowsLifecycleTests.kt index c4efa65506..08c43bf2c9 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowsLifecycleTests.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/WorkflowsLifecycleTests.kt @@ -7,7 +7,7 @@ import com.squareup.workflow1.RuntimeConfigOptions.CONFLATE_STALE_RENDERINGS import com.squareup.workflow1.RuntimeConfigOptions.Companion.RuntimeOptions import com.squareup.workflow1.RuntimeConfigOptions.Companion.RuntimeOptions.NONE import com.squareup.workflow1.RuntimeConfigOptions.DRAIN_EXCLUSIVE_ACTIONS -import com.squareup.workflow1.testing.headlessIntegrationTest +import com.squareup.workflow1.testing.renderForTest import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.awaitCancellation @@ -84,7 +84,7 @@ class WorkflowsLifecycleTests( } @Test fun sideEffectsStartedWhenExpected() { - workflowWithSideEffects.headlessIntegrationTest( + workflowWithSideEffects.renderForTest( runtimeConfig = runtimeConfig ) { // One time starts but does not stop the side effect. @@ -98,7 +98,7 @@ class WorkflowsLifecycleTests( } @Test fun sideEffectsStoppedWhenExpected() { - workflowWithSideEffects.headlessIntegrationTest( + workflowWithSideEffects.renderForTest( runtimeConfig = runtimeConfig ) { // Twice will start and stop the side effect. @@ -112,7 +112,7 @@ class WorkflowsLifecycleTests( } @Test fun childSessionWorkflowStartedWhenExpected() { - workflowWithChildSession.headlessIntegrationTest( + workflowWithChildSession.renderForTest( runtimeConfig = runtimeConfig ) { // One time starts but does not stop the child session workflow. @@ -139,7 +139,7 @@ class WorkflowsLifecycleTests( @Test fun sideEffectsStartAndStoppedWhenHandledSynchronously() { val dispatcher = UnconfinedTestDispatcher() - workflowWithSideEffects.headlessIntegrationTest( + workflowWithSideEffects.renderForTest( coroutineContext = dispatcher, runtimeConfig = runtimeConfig ) { @@ -163,7 +163,7 @@ class WorkflowsLifecycleTests( } @Test fun childSessionWorkflowStoppedWhenExpected() { - workflowWithChildSession.headlessIntegrationTest( + workflowWithChildSession.renderForTest( runtimeConfig = runtimeConfig ) { // Twice will start and stop the child session workflow. @@ -185,7 +185,7 @@ class WorkflowsLifecycleTests( @Test fun childSessionWorkflowStartAndStoppedWhenHandledSynchronously() { val dispatcher = UnconfinedTestDispatcher() - workflowWithChildSession.headlessIntegrationTest( + workflowWithChildSession.renderForTest( coroutineContext = dispatcher, runtimeConfig = runtimeConfig ) { diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/testing/WorkflowTestRuntimeTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/testing/WorkflowTestRuntimeTest.kt index d718923d26..0eb5d6f08d 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/testing/WorkflowTestRuntimeTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/testing/WorkflowTestRuntimeTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") +@file:Suppress("EXPERIMENTAL_API_USAGE", "DEPRECATION") package com.squareup.workflow1.testing