From 4c2289e3445c05909bd8c7a1ff98d4dfc4ac432d Mon Sep 17 00:00:00 2001 From: Stephen Edwards Date: Fri, 14 Apr 2023 15:50:34 -0400 Subject: [PATCH] WIP: Keep the same RenderContext through Interceptor --- .../squareup/workflow1/StatelessWorkflow.kt | 6 +- .../squareup/workflow1/WorkflowInterceptor.kt | 13 ++- .../workflow1/internal/SubtreeManager.kt | 5 +- .../workflow1/internal/WorkflowChildNode.kt | 3 - .../workflow1/internal/WorkflowNode.kt | 61 ++++------ .../workflow1/internal/WorkflowRunner.kt | 4 +- .../workflow1/WorkflowOperatorsTest.kt | 11 +- .../workflow1/internal/WorkflowNodeTest.kt | 104 +++++++++--------- 8 files changed, 101 insertions(+), 106 deletions(-) diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt index 68848afe9..1bfd0ec0c 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt @@ -3,7 +3,6 @@ package com.squareup.workflow1 -import kotlin.LazyThreadSafetyMode.NONE import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName @@ -33,7 +32,6 @@ public abstract class StatelessWorkflow ) : BaseRenderContext<@UnsafeVariance PropsT, Nothing, @UnsafeVariance OutputT> by baseContext as BaseRenderContext - @Suppress("UNCHECKED_CAST") private val statefulWorkflow = Workflow.stateful( initialState = { Unit }, render = { props, _ -> render(props, RenderContext(this, this@StatelessWorkflow)) } @@ -122,7 +120,7 @@ public fun Workflow.Companion.rendering( * @param update Function that defines the workflow update. */ public fun -StatelessWorkflow.action( + StatelessWorkflow.action( name: String = "", update: WorkflowAction.Updater.() -> Unit ): WorkflowAction = action({ name }, update) @@ -137,7 +135,7 @@ StatelessWorkflow.action( * @param update Function that defines the workflow update. */ public fun -StatelessWorkflow.action( + StatelessWorkflow.action( name: () -> String, update: WorkflowAction.Updater.() -> Unit ): WorkflowAction = object : WorkflowAction() { diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/WorkflowInterceptor.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/WorkflowInterceptor.kt index ed2427839..c5e05ba23 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/WorkflowInterceptor.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/WorkflowInterceptor.kt @@ -263,6 +263,10 @@ internal fun WorkflowInterceptor.intercept( workflow } else { object : StatefulWorkflow() { + + private lateinit var interceptedContext: BaseRenderContext + private lateinit var concreteRenderContext: StatefulWorkflow.RenderContext + override fun initialState( props: P, snapshot: Snapshot? @@ -283,9 +287,12 @@ internal fun WorkflowInterceptor.intercept( renderState, context, proceed = { props, state, interceptor -> - val interceptedContext = interceptor?.let { InterceptedRenderContext(context, it) } - ?: context - workflow.render(props, state, RenderContext(interceptedContext, this)) + if (!this::interceptedContext.isInitialized) { + interceptedContext = interceptor?.let { InterceptedRenderContext(context, it) } + ?: context + concreteRenderContext = RenderContext(interceptedContext, this) + } + workflow.render(props, state, concreteRenderContext) }, session = workflowSession, ) diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/SubtreeManager.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/SubtreeManager.kt index bbcb099ba..b955db1c9 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/SubtreeManager.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/SubtreeManager.kt @@ -129,7 +129,7 @@ internal class SubtreeManager( create = { createChildNode(child, props, key, handler) } ) stagedChild.setHandler(handler) - return stagedChild.render(child.asStatefulWorkflow(), props) + return stagedChild.render(props) } /** @@ -151,8 +151,7 @@ internal class SubtreeManager( fun createChildSnapshots(): Map { val snapshots = mutableMapOf() children.forEachActive { child -> - val childWorkflow = child.workflow.asStatefulWorkflow() - snapshots[child.id] = child.workflowNode.snapshot(childWorkflow) + snapshots[child.id] = child.workflowNode.snapshot() } return snapshots } diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowChildNode.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowChildNode.kt index b6a833a95..52b906fdd 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowChildNode.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowChildNode.kt @@ -1,6 +1,5 @@ package com.squareup.workflow1.internal -import com.squareup.workflow1.StatefulWorkflow import com.squareup.workflow1.Workflow import com.squareup.workflow1.WorkflowAction import com.squareup.workflow1.internal.InlineLinkedList.InlineListNode @@ -48,12 +47,10 @@ internal class WorkflowChildNode< * Wrapper around [WorkflowNode.render] that allows calling it with erased types. */ fun render( - workflow: StatefulWorkflow<*, *, *, *>, props: Any? ): R { @Suppress("UNCHECKED_CAST") return workflowNode.render( - workflow as StatefulWorkflow, props as ChildPropsT ) as R } diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowNode.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowNode.kt index 54829a631..91606432b 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowNode.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowNode.kt @@ -81,12 +81,12 @@ internal class WorkflowNode( eventActionsChannel = eventActionsChannel ) private val context = RenderContext(baseRenderContext, workflow) + private val interceptedWorkflow = interceptor.intercept(workflow, this) init { interceptor.onSessionStarted(this, this) - state = interceptor.intercept(workflow, this) - .initialState(initialProps, snapshot?.workflowSnapshot) + state = interceptedWorkflow.initialState(initialProps, snapshot?.workflowSnapshot) } override fun toString(): String { @@ -104,23 +104,34 @@ internal class WorkflowNode( * [RenderContext][com.squareup.workflow1.BaseRenderContext] to give its children a chance to * render themselves and aggregate those child renderings. */ - @Suppress("UNCHECKED_CAST") fun render( - workflow: StatefulWorkflow, - input: PropsT - ): RenderingT = - renderWithStateType(workflow as StatefulWorkflow, input) + props: PropsT + ): RenderingT { + updatePropsAndState(props) + + baseRenderContext.unfreeze() + val rendering = interceptedWorkflow + .render(props, state, context) + baseRenderContext.freeze() + + // Tear down workflows and workers that are obsolete. + subtreeManager.commitRenderedChildren() + // Side effect jobs are launched lazily, since they can send actions to the sink, and can only + // be started after context is frozen. + sideEffects.forEachStaging { it.job.start() } + sideEffects.commitStaging { it.job.cancel() } + + return rendering + } /** * Walk the tree of state machines again, this time gathering snapshots and aggregating them * automatically. */ - fun snapshot(workflow: StatefulWorkflow<*, *, *, *>): TreeSnapshot { - @Suppress("UNCHECKED_CAST") - val typedWorkflow = workflow as StatefulWorkflow + fun snapshot(): TreeSnapshot { return interceptor.onSnapshotStateWithChildren({ val childSnapshots = subtreeManager.createChildSnapshots() - val rootSnapshot = interceptor.intercept(typedWorkflow, this) + val rootSnapshot = interceptedWorkflow .snapshotState(state) TreeSnapshot( workflowSnapshot = rootSnapshot, @@ -188,37 +199,11 @@ internal class WorkflowNode( coroutineContext.cancel(cause) } - /** - * Contains the actual logic for [render], after we've casted the passed-in [Workflow]'s - * state type to our `StateT`. - */ - private fun renderWithStateType( - workflow: StatefulWorkflow, - props: PropsT - ): RenderingT { - updatePropsAndState(workflow, props) - - baseRenderContext.unfreeze() - val rendering = interceptor.intercept(workflow, this) - .render(props, state, context) - baseRenderContext.freeze() - - // Tear down workflows and workers that are obsolete. - subtreeManager.commitRenderedChildren() - // Side effect jobs are launched lazily, since they can send actions to the sink, and can only - // be started after context is frozen. - sideEffects.forEachStaging { it.job.start() } - sideEffects.commitStaging { it.job.cancel() } - - return rendering - } - private fun updatePropsAndState( - workflow: StatefulWorkflow, newProps: PropsT ) { if (newProps != lastProps) { - val newState = interceptor.intercept(workflow, this) + val newState = interceptedWorkflow .onPropsChanged(lastProps, newProps, state) state = newState } diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowRunner.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowRunner.kt index 8a4121a73..8a8d1cbf6 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowRunner.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowRunner.kt @@ -66,8 +66,8 @@ internal class WorkflowRunner( */ fun nextRendering(): RenderingAndSnapshot { return interceptor.onRenderAndSnapshot(currentProps, { props -> - val rendering = rootNode.render(workflow, props) - val snapshot = rootNode.snapshot(workflow) + val rendering = rootNode.render(props) + val snapshot = rootNode.snapshot() RenderingAndSnapshot(rendering, snapshot) }, rootNode) } diff --git a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/WorkflowOperatorsTest.kt b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/WorkflowOperatorsTest.kt index c62bc8c0b..aaee9c2df 100644 --- a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/WorkflowOperatorsTest.kt +++ b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/WorkflowOperatorsTest.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.plus import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -157,6 +158,10 @@ class WorkflowOperatorsTest { val childWorkflow = object : StateFlowWorkflow("child", trigger) {} val parentWorkflow = Workflow.stateless { props -> when (props) { + // I don't understand this test. [mapRendering] defers to its wrapped Workflow for the identifier + // which is equivalent - but we are relying on the fact that we pass in the Workflow each time we render + // so we pull out the *same* child WorkflowNode (starts = 1) but give it a new Workflow to render. + // Why? 0 -> renderChild(childWorkflow.mapRendering { "rendering1: $it" }) 1 -> renderChild(childWorkflow.mapRendering { "rendering2: $it" }) else -> fail() @@ -164,12 +169,13 @@ class WorkflowOperatorsTest { } val props = MutableStateFlow(0) - runTest(UnconfinedTestDispatcher()) { + runTest { val renderings = mutableListOf() val workflowJob = Job(coroutineContext[Job]) renderWorkflowIn(parentWorkflow, this + workflowJob, props) {} .onEach { renderings += it.rendering } .launchIn(this + workflowJob) + runCurrent() assertEquals( listOf( "rendering1: initial" @@ -179,6 +185,7 @@ class WorkflowOperatorsTest { assertEquals(1, childWorkflow.starts) trigger.value = "foo" + runCurrent() assertEquals(1, childWorkflow.starts) assertEquals( listOf( @@ -189,7 +196,9 @@ class WorkflowOperatorsTest { ) props.value = 1 + runCurrent() trigger.value = "bar" + runCurrent() assertEquals(1, childWorkflow.starts) assertEquals( listOf( diff --git a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt index 48000956d..1512ed4de 100644 --- a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt +++ b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE", "DEPRECATION") +@file:Suppress("EXPERIMENTAL_API_USAGE") @file:OptIn(ExperimentalCoroutinesApi::class) package com.squareup.workflow1.internal @@ -106,7 +106,7 @@ internal class WorkflowNodeTest { } val node = WorkflowNode(workflow.id(), workflow, "old", null, context) - node.render(workflow, "new") + node.render("new") assertEquals(listOf("old" to "new"), oldAndNewProps) } @@ -119,7 +119,7 @@ internal class WorkflowNodeTest { } val node = WorkflowNode(workflow.id(), workflow, "old", null, context) - node.render(workflow, "old") + node.render("old") assertTrue(oldAndNewProps.isEmpty()) } @@ -130,7 +130,7 @@ internal class WorkflowNodeTest { } val node = WorkflowNode(workflow.id(), workflow, "foo", null, context) - val rendering = node.render(workflow, "foo2") + val rendering = node.render("foo2") assertEquals( """ @@ -140,7 +140,7 @@ internal class WorkflowNodeTest { rendering ) - val rendering2 = node.render(workflow, "foo3") + val rendering2 = node.render("foo3") assertEquals( """ @@ -177,7 +177,7 @@ internal class WorkflowNodeTest { context, emitOutputToParent = { WorkflowOutput("tick:$it") } ) - node.render(workflow, "")("event") + node.render("")("event") runTest { val result = withTimeout(10) { @@ -215,7 +215,7 @@ internal class WorkflowNodeTest { context, emitOutputToParent = { WorkflowOutput("tick:$it") } ) - val sink = node.render(workflow, "") + val sink = node.render("") sink("event") sink("event2") @@ -254,7 +254,7 @@ internal class WorkflowNodeTest { } val node = WorkflowNode(workflow.id(), workflow, "", null, context) - node.render(workflow, "") + node.render("") sink.send(action { setOutput("event") }) // Should not throw. @@ -278,7 +278,7 @@ internal class WorkflowNodeTest { ) runTest { - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) assertTrue(started) } } @@ -298,7 +298,7 @@ internal class WorkflowNodeTest { baseContext = context ) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) assertEquals(WorkflowNodeId(workflow).toString(), node.coroutineContext[CoroutineName]!!.name) assertEquals( "sideEffect[the key] for ${WorkflowNodeId(workflow)}", @@ -319,7 +319,7 @@ internal class WorkflowNodeTest { snapshot = null, baseContext = context ) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) runTest { // Result should be available instantly, any delay at all indicates something is broken. @@ -353,12 +353,12 @@ internal class WorkflowNodeTest { ) runTest { - node.render(workflow.asStatefulWorkflow(), true) + node.render(true) assertNull(cancellationException) // Stop running the side effect. isRunning.value = false - node.render(workflow.asStatefulWorkflow(), false) + node.render(false) assertTrue(cancellationException is CancellationException) } @@ -382,7 +382,7 @@ internal class WorkflowNodeTest { ) runTest { - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) assertNull(cancellationException) node.cancel() @@ -411,11 +411,11 @@ internal class WorkflowNodeTest { ) runTest { - node.render(workflow.asStatefulWorkflow(), 0) + node.render(0) assertFalse(cancelled) assertEquals(1, renderPasses) - node.render(workflow.asStatefulWorkflow(), 1) + node.render(1) assertFalse(cancelled) assertEquals(2, renderPasses) } @@ -439,11 +439,11 @@ internal class WorkflowNodeTest { ) runTest { - node.render(workflow.asStatefulWorkflow(), 0) + node.render(0) assertEquals(listOf(0), seenProps) assertEquals(1, renderPasses) - node.render(workflow.asStatefulWorkflow(), 1) + node.render(1) assertEquals(listOf(0), seenProps) assertEquals(2, renderPasses) } @@ -463,7 +463,7 @@ internal class WorkflowNodeTest { ) val error = assertFailsWith { - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) } assertEquals("Expected side effect keys to be unique: \"same\"", error.message) } @@ -493,22 +493,22 @@ internal class WorkflowNodeTest { baseContext = context ) - node.render(workflow, 0) + node.render(0) assertEquals(listOf("started"), events1) assertEquals(emptyList(), events2) assertEquals(emptyList(), events3) - node.render(workflow, 1) + node.render(1) assertEquals(listOf("started"), events1) assertEquals(listOf("started"), events2) assertEquals(emptyList(), events3) - node.render(workflow, 2) + node.render(2) assertEquals(listOf("started"), events1) assertEquals(listOf("started", "cancelled"), events2) assertEquals(listOf("started"), events3) - node.render(workflow, 3) + node.render(3) assertEquals(listOf("started", "cancelled"), events1) assertEquals(listOf("started", "cancelled"), events2) assertEquals(listOf("started", "cancelled"), events3) @@ -531,7 +531,7 @@ internal class WorkflowNodeTest { assertFalse(started1) assertFalse(started2) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) assertTrue(started1) assertTrue(started2) } @@ -559,8 +559,8 @@ internal class WorkflowNodeTest { baseContext = Unconfined ) - assertEquals("initial props", originalNode.render(workflow, "foo")) - val snapshot = originalNode.snapshot(workflow) + assertEquals("initial props", originalNode.render("foo")) + val snapshot = originalNode.snapshot() assertNotEquals(0, snapshot.toByteString().size) val restoredNode = WorkflowNode( @@ -571,7 +571,7 @@ internal class WorkflowNodeTest { snapshot = snapshot, baseContext = Unconfined ) - assertEquals("initial props", restoredNode.render(workflow, "foo")) + assertEquals("initial props", restoredNode.render("foo")) } @Test fun snapshots_empty_without_children() { @@ -588,8 +588,8 @@ internal class WorkflowNodeTest { baseContext = Unconfined ) - assertEquals("initial props", originalNode.render(workflow, "foo")) - val snapshot = originalNode.snapshot(workflow) + assertEquals("initial props", originalNode.render("foo")) + val snapshot = originalNode.snapshot() assertNotEquals(0, snapshot.toByteString().size) val restoredNode = WorkflowNode( @@ -600,7 +600,7 @@ internal class WorkflowNodeTest { snapshot = snapshot, baseContext = Unconfined ) - assertEquals("restored", restoredNode.render(workflow, "foo")) + assertEquals("restored", restoredNode.render("foo")) } @Test fun snapshots_non_empty_with_children() { @@ -645,8 +645,8 @@ internal class WorkflowNodeTest { baseContext = Unconfined ) - assertEquals("initial props|child props", originalNode.render(parentWorkflow, "foo")) - val snapshot = originalNode.snapshot(parentWorkflow) + assertEquals("initial props|child props", originalNode.render("foo")) + val snapshot = originalNode.snapshot() assertNotEquals(0, snapshot.toByteString().size) val restoredNode = WorkflowNode( @@ -657,7 +657,7 @@ internal class WorkflowNodeTest { snapshot = snapshot, baseContext = Unconfined ) - assertEquals("initial props|child props", restoredNode.render(parentWorkflow, "foo")) + assertEquals("initial props|child props", restoredNode.render("foo")) assertEquals("child props", restoredChildState) assertEquals("initial props", restoredParentState) } @@ -686,7 +686,7 @@ internal class WorkflowNodeTest { assertEquals(0, snapshotWrites) assertEquals(0, restoreCalls) - val snapshot = node.snapshot(workflow) + val snapshot = node.snapshot() assertEquals(1, snapshotCalls) assertEquals(0, snapshotWrites) @@ -725,8 +725,8 @@ internal class WorkflowNodeTest { baseContext = Unconfined ) - assertEquals("initial props", originalNode.render(workflow, "foo")) - val snapshot = originalNode.snapshot(workflow) + assertEquals("initial props", originalNode.render("foo")) + val snapshot = originalNode.snapshot() assertNotEquals(0, snapshot.toByteString().size) val restoredNode = WorkflowNode( @@ -736,7 +736,7 @@ internal class WorkflowNodeTest { snapshot = snapshot, baseContext = Unconfined ) - assertEquals("props:new props|state:initial props", restoredNode.render(workflow, "foo")) + assertEquals("props:new props|state:initial props", restoredNode.render("foo")) } @Test fun toString_formats_as_WorkflowInstance_without_parent() { @@ -891,7 +891,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, parent = TestSession(42) ) - val rendering = node.render(workflow, "new") + val rendering = node.render("new") assertEquals("old", interceptedOld) assertEquals("new", interceptedNew) @@ -937,7 +937,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, parent = TestSession(42) ) - val rendering = node.render(workflow, "props") + val rendering = node.render("props") assertEquals("props", interceptedProps) assertEquals("state", interceptedState) @@ -979,7 +979,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, parent = TestSession(42) ) - val snapshot = node.snapshot(workflow) + val snapshot = node.snapshot() assertEquals("state", interceptedState) assertEquals(Snapshot.of("snapshot(state)"), interceptedSnapshot) @@ -1020,7 +1020,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, parent = TestSession(42) ) - val snapshot = node.snapshot(workflow) + val snapshot = node.snapshot() assertEquals("state", interceptedState) assertNull(interceptedSnapshot) @@ -1062,7 +1062,7 @@ internal class WorkflowNodeTest { parent = TestSession(42), idCounter = IdCounter() ) - val rendering = node.render(rootWorkflow.asStatefulWorkflow(), "props") + val rendering = node.render("props") assertEquals("[root([leaf([[props]], [[props]])])]", rendering) } @@ -1081,7 +1081,7 @@ internal class WorkflowNodeTest { ) val error = assertFailsWith { - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) } assertTrue( error.message!!.startsWith( @@ -1109,7 +1109,7 @@ internal class WorkflowNodeTest { ) val error = assertFailsWith { - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) } assertEquals( "Expected sink to not be sent to until after the render pass. " + @@ -1134,7 +1134,7 @@ internal class WorkflowNodeTest { snapshot = null, baseContext = Unconfined ) - val (_, sink) = node.render(workflow.asStatefulWorkflow(), Unit) + val (_, sink) = node.render(Unit) sink.send("hello") @@ -1142,7 +1142,7 @@ internal class WorkflowNodeTest { node.onNextAction(this) } as WorkflowOutput? - val (state, _) = node.render(workflow.asStatefulWorkflow(), Unit) + val (state, _) = node.render(Unit) assertEquals("initial->hello", state) } @@ -1158,7 +1158,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, emitOutputToParent = { WorkflowOutput("output:$it") } ) - val rendering = node.render(workflow.asStatefulWorkflow(), Unit) + val rendering = node.render(Unit) rendering.send("hello") @@ -1182,7 +1182,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, emitOutputToParent = { WorkflowOutput(it) } ) - val rendering = node.render(workflow.asStatefulWorkflow(), Unit) + val rendering = node.render(Unit) rendering.send("hello") @@ -1211,13 +1211,13 @@ internal class WorkflowNodeTest { snapshot = null, baseContext = Unconfined ) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) select { node.onNextAction(this) } as WorkflowOutput? - val state = node.render(workflow.asStatefulWorkflow(), Unit) + val state = node.render(Unit) assertEquals("initial->hello", state) } @@ -1235,7 +1235,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, emitOutputToParent = { WorkflowOutput("output:$it") } ) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) runTest { val output = select { @@ -1259,7 +1259,7 @@ internal class WorkflowNodeTest { baseContext = Unconfined, emitOutputToParent = { WorkflowOutput(it) } ) - node.render(workflow.asStatefulWorkflow(), Unit) + node.render(Unit) runTest { val output = select {