Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions workflow-testing/api/workflow-testing.api
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,12 @@ public final class com/squareup/workflow1/testing/WorkflowTestRuntimeKt {
public static final fun launchForTestingFromStartWith (Lcom/squareup/workflow1/Workflow;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static synthetic fun launchForTestingFromStartWith$default (Lcom/squareup/workflow1/Workflow;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun launchForTestingFromStartWith$default (Lcom/squareup/workflow1/Workflow;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun launchForTestingFromStateWith (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)V
public static final fun launchForTestingFromStateWith (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun launchForTestingFromStateWith (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun launchForTestingFromStateWith (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)V
public static synthetic fun launchForTestingFromStateWith$default (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
public static synthetic fun launchForTestingFromStateWith$default (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun launchForTestingFromStateWith$default (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/lang/Object;
public static synthetic fun launchForTestingFromStateWith$default (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
public static final fun launchForTestingWith (Lcom/squareup/workflow1/StatefulWorkflow;Ljava/lang/Object;Lcom/squareup/workflow1/testing/WorkflowTestParams;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,36 @@ public fun <T, PropsT, StateT, OutputT, RenderingT>
initialState: StateT,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend WorkflowTestRuntime<PropsT, OutputT, RenderingT>.() -> T
): T = launchForTestingFromStateWith(
props = props,
initialState = initialState,
testParams = WorkflowTestParams(),
context = context,
block = block,
)

/**
* Creates a [WorkflowTestRuntime] to run this workflow for unit testing.
* If the workflow is [stateful][StatefulWorkflow], [initialState][StatefulWorkflow.initialState]
* is not called. Instead, the workflow is started from the given [initialState].
*
* The [startFrom][WorkflowTestParams.startFrom] value in [testParams] is ignored. This function
* always starts from [initialState].
*
* All workflow-related coroutines are cancelled when the block exits.
*/
@Deprecated("Use renderForTest and WorkflowTurbine instead.")
@TestOnly
public fun <T, PropsT, StateT, OutputT, RenderingT>
StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.launchForTestingFromStateWith(
props: PropsT,
initialState: StateT,
testParams: WorkflowTestParams<StateT>,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend WorkflowTestRuntime<PropsT, OutputT, RenderingT>.() -> T
): T = launchForTestingWith(
props,
WorkflowTestParams(StartFromState(initialState)),
testParams.withStartState(initialState),
context,
block
)
Expand All @@ -251,7 +278,43 @@ public fun <StateT, OutputT, RenderingT>
initialState: StateT,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend WorkflowTestRuntime<Unit, OutputT, RenderingT>.() -> Unit
): Unit = launchForTestingFromStateWith(Unit, initialState, context, block)
): Unit = launchForTestingFromStateWith(
initialState = initialState,
testParams = WorkflowTestParams(),
context = context,
block = block,
)

/**
* Creates a [WorkflowTestRuntime] to run this workflow for unit testing.
* If the workflow is [stateful][StatefulWorkflow], [initialState][StatefulWorkflow.initialState]
* is not called. Instead, the workflow is started from the given [initialState].
*
* The [startFrom][WorkflowTestParams.startFrom] value in [testParams] is ignored. This function
* always starts from [initialState].
*
* All workflow-related coroutines are cancelled when the block exits.
*/
@Deprecated("Use renderForTest and WorkflowTurbine instead.")
@TestOnly
public fun <StateT, OutputT, RenderingT>
StatefulWorkflow<Unit, StateT, OutputT, RenderingT>.launchForTestingFromStateWith(
initialState: StateT,
testParams: WorkflowTestParams<StateT>,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend WorkflowTestRuntime<Unit, OutputT, RenderingT>.() -> Unit
): Unit = launchForTestingFromStateWith(Unit, initialState, testParams, context, block)

private fun <StateT> WorkflowTestParams<StateT>.withStartState(initialState: StateT): WorkflowTestParams<StateT> =
WorkflowTestParams(
startFrom = StartFromState(initialState),
checkRenderIdempotence = checkRenderIdempotence,
runtimeConfig = runtimeConfig,
deprecatedLaunchSchedulerMode = deprecatedLaunchSchedulerMode,
autoAdvanceOnStartup = autoAdvanceOnStartup,
autoAdvanceBeforeAwait = autoAdvanceBeforeAwait,
autoAdvanceBeforeHasCheck = autoAdvanceBeforeHasCheck,
)

/**
* Creates a [WorkflowTestRuntime] to run this workflow for unit testing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,49 @@ internal class WorkflowTestRuntimeTest {
}
}

@Test fun `fromStateWith props overload forwards testParams`() {
var renderCount = 0
val workflow = Workflow.stateful<String, Int, Nothing, Int>(
initialState = { _, _ -> fail("Should start from explicit initialState") },
render = { props, state ->
renderCount++
state + props.length
},
snapshot = { null }
)

workflow.launchForTestingFromStateWith(
props = "abc",
initialState = 10,
testParams = WorkflowTestParams(checkRenderIdempotence = false)
) {
assertEquals(13, awaitNextRendering())
}

assertEquals(1, renderCount)
}

@Test fun `fromStateWith unit overload forwards testParams`() {
var renderCount = 0
val workflow = Workflow.stateful<Unit, Int, Nothing, Int>(
initialState = { _, _ -> fail("Should start from explicit initialState") },
render = { _, state ->
renderCount++
state
},
snapshot = { null }
)

workflow.launchForTestingFromStateWith(
initialState = 77,
testParams = WorkflowTestParams(checkRenderIdempotence = false)
) {
assertEquals(77, awaitNextRendering())
}

assertEquals(1, renderCount)
}

@Test fun `detects render side effects`() {
var renderCount = 0
val workflow = Workflow.stateless<Unit, Nothing, Unit> {
Expand Down
Loading