diff --git a/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemListWorkflow.kt b/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemListWorkflow.kt index 63841520d4..b529f8cb48 100644 --- a/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemListWorkflow.kt +++ b/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemListWorkflow.kt @@ -27,7 +27,7 @@ object PoemListWorkflow : StatelessWorkflow, Int, PoemListRendering>( override fun render( props: List, - context: RenderContext + context: RenderContext, Nothing, Int> ): PoemListRendering { // A sink that emits the given index as the result of this workflow. val sink = context.makeEventSink { index: Int -> setOutput(index) } diff --git a/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemsBrowserWorkflow.kt b/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemsBrowserWorkflow.kt index 26d8c0676b..6ddd6186b7 100644 --- a/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemsBrowserWorkflow.kt +++ b/samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoemsBrowserWorkflow.kt @@ -40,7 +40,7 @@ object PoemsBrowserWorkflow : override fun render( props: List, state: SelectedPoem, - context: RenderContext + context: RenderContext, SelectedPoem, Nothing> ): OverviewDetailScreen { val poems: OverviewDetailScreen = context.renderChild(PoemListWorkflow, props) { selected -> choosePoem(selected) } diff --git a/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/AreYouSureWorkflow.kt b/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/AreYouSureWorkflow.kt index 8f419c7ee6..3ced51abbd 100644 --- a/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/AreYouSureWorkflow.kt +++ b/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/AreYouSureWorkflow.kt @@ -52,7 +52,7 @@ object AreYouSureWorkflow : StatefulWorkflow + context: RenderContext ): AlertContainerScreen<*> { val ableBakerCharlie = context.renderChild(HelloBackButtonWorkflow, Unit) { noAction() } diff --git a/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/HelloBackButtonWorkflow.kt b/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/HelloBackButtonWorkflow.kt index a83ea7fda0..ea8b77af5a 100644 --- a/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/HelloBackButtonWorkflow.kt +++ b/samples/containers/hello-back-button/src/main/java/com/squareup/sample/hellobackbutton/HelloBackButtonWorkflow.kt @@ -46,7 +46,7 @@ object HelloBackButtonWorkflow : StatefulWorkflow + context: RenderContext ): Rendering { return Rendering( message = "$state", diff --git a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/PoemWorkflow.kt b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/PoemWorkflow.kt index c163f6aebb..e452f8ca87 100644 --- a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/PoemWorkflow.kt +++ b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/PoemWorkflow.kt @@ -56,7 +56,7 @@ object PoemWorkflow : StatefulWorkflow + context: RenderContext ): OverviewDetailScreen { val previousStanzas: List = if (state == -1) emptyList() @@ -105,7 +105,7 @@ object PoemWorkflow : StatefulWorkflow { + private sealed class Action : WorkflowAction { object ClearSelection : Action() object SelectPrevious : Action() object SelectNext : Action() diff --git a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaListWorkflow.kt b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaListWorkflow.kt index 12b5e12c41..b95c19a9e8 100644 --- a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaListWorkflow.kt +++ b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaListWorkflow.kt @@ -29,7 +29,7 @@ object StanzaListWorkflow : StatelessWorkflow() override fun render( props: Poem, - context: RenderContext + context: RenderContext ): StanzaListRendering { // A sink that emits the given index as the result of this workflow. val sink = context.makeEventSink { index: Int -> setOutput(index) } diff --git a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaWorkflow.kt b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaWorkflow.kt index 7110424ee8..4af230cd9e 100644 --- a/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaWorkflow.kt +++ b/samples/containers/poetry/src/main/java/com/squareup/sample/poetry/StanzaWorkflow.kt @@ -41,7 +41,7 @@ object StanzaWorkflow : StatelessWorkflow() { override fun render( props: Props, - context: RenderContext + context: RenderContext ): StanzaRendering { with(props) { val sink: Sink = context.makeEventSink { setOutput(it) } diff --git a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/DungeonAppWorkflow.kt b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/DungeonAppWorkflow.kt index 7e53c5cdfc..cbe020fec8 100644 --- a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/DungeonAppWorkflow.kt +++ b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/DungeonAppWorkflow.kt @@ -54,7 +54,7 @@ class DungeonAppWorkflow( override fun render( props: Props, state: State, - context: RenderContext + context: RenderContext ): AlertContainerScreen = when (state) { LoadingBoardList -> { diff --git a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/GameSessionWorkflow.kt b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/GameSessionWorkflow.kt index 6db07225c2..f548acef76 100644 --- a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/GameSessionWorkflow.kt +++ b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/GameSessionWorkflow.kt @@ -65,7 +65,7 @@ class GameSessionWorkflow( override fun render( props: Props, state: State, - context: RenderContext + context: RenderContext ): AlertContainerScreen = when (state) { Loading -> { @@ -98,8 +98,8 @@ class GameSessionWorkflow( override fun snapshotState(state: State): Snapshot = Snapshot.EMPTY - private class StartRunning(val board: Board) : WorkflowAction { - override fun Updater.apply() { + private class StartRunning(val board: Board) : WorkflowAction { + override fun Updater.apply() { state = Running(board) } } diff --git a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/TimeMachineAppWorkflow.kt b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/TimeMachineAppWorkflow.kt index f417feb331..5787d3ebfa 100644 --- a/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/TimeMachineAppWorkflow.kt +++ b/samples/dungeon/app/src/main/java/com/squareup/sample/dungeon/TimeMachineAppWorkflow.kt @@ -43,7 +43,7 @@ class TimeMachineAppWorkflow( override fun render( props: BoardPath, - context: RenderContext + context: RenderContext ): ShakeableTimeMachineRendering { val propsFactory = PropsFactory { recording -> Props(paused = !recording) diff --git a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/AiWorkflow.kt b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/AiWorkflow.kt index 8ce1fe2e5f..d6b9289cf1 100644 --- a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/AiWorkflow.kt +++ b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/AiWorkflow.kt @@ -67,7 +67,7 @@ class AiWorkflow( override fun render( props: ActorProps, state: State, - context: RenderContext + context: RenderContext ): ActorRendering { context.runningWorker(state.directionTicker) { updateDirection } diff --git a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/GameWorkflow.kt b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/GameWorkflow.kt index 9ec49408e7..bf9f9c923b 100644 --- a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/GameWorkflow.kt +++ b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/GameWorkflow.kt @@ -105,7 +105,7 @@ class GameWorkflow( override fun render( props: Props, state: State, - context: RenderContext + context: RenderContext ): GameRendering { val running = !props.paused && !state.game.isPlayerEaten // Stop actors from ticking if the game is paused or finished. diff --git a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/PlayerWorkflow.kt b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/PlayerWorkflow.kt index ef66a3eb6d..6a804b4043 100644 --- a/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/PlayerWorkflow.kt +++ b/samples/dungeon/common/src/main/java/com/squareup/sample/dungeon/PlayerWorkflow.kt @@ -35,16 +35,16 @@ class PlayerWorkflow( private val cellsPerSecond: Float = 15f ) : StatefulWorkflow() { - sealed class Action : WorkflowAction { + sealed class Action : WorkflowAction { class StartMoving(private val direction: Direction) : Action() { - override fun Updater.apply() { + override fun Updater.apply() { state += direction } } class StopMoving(private val direction: Direction) : Action() { - override fun Updater.apply() { + override fun Updater.apply() { state -= direction } } @@ -64,7 +64,7 @@ class PlayerWorkflow( override fun render( props: ActorProps, state: Movement, - context: RenderContext + context: RenderContext ): Rendering = Rendering( actorRendering = ActorRendering(avatar = avatar, movement = state), onStartMoving = { context.actionSink.send(StartMoving(it)) }, diff --git a/samples/dungeon/timemachine-shakeable/src/main/java/com/squareup/sample/timemachine/shakeable/ShakeableTimeMachineWorkflow.kt b/samples/dungeon/timemachine-shakeable/src/main/java/com/squareup/sample/timemachine/shakeable/ShakeableTimeMachineWorkflow.kt index 7d8b48ef90..b51b0c5fdd 100644 --- a/samples/dungeon/timemachine-shakeable/src/main/java/com/squareup/sample/timemachine/shakeable/ShakeableTimeMachineWorkflow.kt +++ b/samples/dungeon/timemachine-shakeable/src/main/java/com/squareup/sample/timemachine/shakeable/ShakeableTimeMachineWorkflow.kt @@ -69,7 +69,7 @@ class ShakeableTimeMachineWorkflow( override fun render( props: PropsFactory

, state: State, - context: RenderContext + context: RenderContext, State, O> ): ShakeableTimeMachineRendering { // Only listen to shakes when recording. if (state === Recording) context.runningWorker(shakeWorker) { onShake } @@ -123,14 +123,14 @@ class ShakeableTimeMachineWorkflow( private inner class SeekAction( private val newPosition: Duration - ) : WorkflowAction { - override fun Updater.apply() { + ) : WorkflowAction, State, O> { + override fun Updater, State, O>.apply() { state = PlayingBack(newPosition) } } - private inner class ResumeRecordingAction : WorkflowAction { - override fun Updater.apply() { + private inner class ResumeRecordingAction : WorkflowAction, State, O> { + override fun Updater, State, O>.apply() { state = Recording } } diff --git a/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/RecorderWorkflow.kt b/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/RecorderWorkflow.kt index d6ad04dfcb..fcfc49c5c8 100644 --- a/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/RecorderWorkflow.kt +++ b/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/RecorderWorkflow.kt @@ -92,7 +92,7 @@ internal class RecorderWorkflow( override fun render( props: RecorderProps, state: Recording, - context: RenderContext, Nothing> + context: RenderContext, Recording, Nothing> ): TimeMachineRendering { val value = when (props) { is RecordValue -> props.value diff --git a/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/TimeMachineWorkflow.kt b/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/TimeMachineWorkflow.kt index 44d9377d59..0f3cb74f2d 100644 --- a/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/TimeMachineWorkflow.kt +++ b/samples/dungeon/timemachine/src/main/java/com/squareup/sample/timemachine/TimeMachineWorkflow.kt @@ -38,7 +38,7 @@ import kotlin.time.TimeSource * * @param delegateWorkflow The [Workflow] whose renderings to record. This workflow will be rendered * continuously as long as the `TimeMachineWorkflow` is being rendered. - * @param clock The [Clock] to use to assign timestamps to recorded values. + * @param clock The [TimeSource] to use to assign timestamps to recorded values. */ @ExperimentalTime class TimeMachineWorkflow( @@ -84,7 +84,7 @@ class TimeMachineWorkflow( override fun render( props: TimeMachineProps

, - context: RenderContext + context: RenderContext, Nothing, O> ): TimeMachineRendering { // Always render the delegate, even if in playback mode, to keep it alive. val delegateRendering = diff --git a/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/BlinkingCursorWorkflow.kt b/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/BlinkingCursorWorkflow.kt index 06c3d5b85d..b53d9e4e96 100644 --- a/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/BlinkingCursorWorkflow.kt +++ b/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/BlinkingCursorWorkflow.kt @@ -50,7 +50,7 @@ class BlinkingCursorWorkflow( override fun render( props: Unit, state: Boolean, - context: RenderContext + context: RenderContext ): String { context.runningWorker(intervalWorker) { setCursorShowing(it) } return if (state) cursorString else "" diff --git a/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/HelloTerminalWorkflow.kt b/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/HelloTerminalWorkflow.kt index 08d3ac121d..b025100f4f 100644 --- a/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/HelloTerminalWorkflow.kt +++ b/samples/hello-terminal/hello-terminal-app/src/main/java/com/squareup/sample/helloterminal/HelloTerminalWorkflow.kt @@ -30,7 +30,7 @@ import com.squareup.workflow.WorkflowAction import com.squareup.workflow.action import com.squareup.workflow.renderChild -private typealias HelloTerminalAction = WorkflowAction +private typealias HelloTerminalAction = WorkflowAction class HelloTerminalWorkflow : TerminalWorkflow, StatefulWorkflow() { @@ -52,7 +52,7 @@ class HelloTerminalWorkflow : TerminalWorkflow, override fun render( props: TerminalProps, state: State, - context: RenderContext + context: RenderContext ): TerminalRendering { val (rows, columns) = props.size val header = """ diff --git a/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/EditTextWorkflow.kt b/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/EditTextWorkflow.kt index 90bc6907b0..fae55f160d 100644 --- a/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/EditTextWorkflow.kt +++ b/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/EditTextWorkflow.kt @@ -47,7 +47,7 @@ class EditTextWorkflow : StatefulWorkflow + context: RenderContext ): String { context.runningWorker(props.terminalProps.keyStrokes) { key -> onKeystroke(props, key) } diff --git a/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/TodoWorkflow.kt b/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/TodoWorkflow.kt index 6d76951be1..ef7659b796 100644 --- a/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/TodoWorkflow.kt +++ b/samples/hello-terminal/todo-terminal-app/src/main/java/com/squareup/sample/hellotodo/TodoWorkflow.kt @@ -32,7 +32,7 @@ import com.squareup.workflow.StatefulWorkflow import com.squareup.workflow.WorkflowAction import com.squareup.workflow.action -private typealias TodoAction = WorkflowAction +private typealias TodoAction = WorkflowAction class TodoWorkflow : TerminalWorkflow, StatefulWorkflow() { @@ -75,14 +75,14 @@ class TodoWorkflow : TerminalWorkflow, override fun render( props: TerminalProps, state: TodoList, - context: RenderContext + context: RenderContext ): TerminalRendering { context.runningWorker(props.keyStrokes) { onKeystroke(it) } return TerminalRendering(buildString { @Suppress("UNCHECKED_CAST") - appendln(state.renderTitle(props, context as RenderContext)) + appendln(state.renderTitle(props, context as RenderContext)) appendln(renderSelection(state.titleSeparator, false)) appendln(state.renderItems(props, context)) }) @@ -117,7 +117,7 @@ private fun setLabel( private fun TodoList.renderTitle( props: TerminalProps, - context: RenderContext + context: RenderContext ): String { val isSelected = focusedField == TITLE_FIELD_INDEX val titleString = if (isSelected) { @@ -136,7 +136,7 @@ private val TodoList.titleSeparator get() = "–".repeat(title.length + 1) private fun TodoList.renderItems( props: TerminalProps, - context: RenderContext + context: RenderContext ): String = items .mapIndexed { index, item -> diff --git a/samples/hello-workflow-fragment/src/main/java/com/squareup/sample/helloworkflowfragment/HelloWorkflow.kt b/samples/hello-workflow-fragment/src/main/java/com/squareup/sample/helloworkflowfragment/HelloWorkflow.kt index 664b270c83..3c4efb3aed 100644 --- a/samples/hello-workflow-fragment/src/main/java/com/squareup/sample/helloworkflowfragment/HelloWorkflow.kt +++ b/samples/hello-workflow-fragment/src/main/java/com/squareup/sample/helloworkflowfragment/HelloWorkflow.kt @@ -45,7 +45,7 @@ object HelloWorkflow : StatefulWorkflow() { override fun render( props: Unit, state: State, - context: RenderContext + context: RenderContext ): Rendering { return Rendering( message = state.name, diff --git a/samples/hello-workflow/src/main/java/com/squareup/sample/helloworkflow/HelloWorkflow.kt b/samples/hello-workflow/src/main/java/com/squareup/sample/helloworkflow/HelloWorkflow.kt index ef569bc0b5..c168bf6e80 100644 --- a/samples/hello-workflow/src/main/java/com/squareup/sample/helloworkflow/HelloWorkflow.kt +++ b/samples/hello-workflow/src/main/java/com/squareup/sample/helloworkflow/HelloWorkflow.kt @@ -45,7 +45,7 @@ object HelloWorkflow : StatefulWorkflow() { override fun render( props: Unit, state: State, - context: RenderContext + context: RenderContext ): Rendering { return Rendering( message = state.name, diff --git a/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/AppWorkflow.kt b/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/AppWorkflow.kt index 64d266e921..9791af9d6f 100644 --- a/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/AppWorkflow.kt +++ b/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/AppWorkflow.kt @@ -74,11 +74,11 @@ object AppWorkflow : StatefulWorkflow() { get() = listOfNotNull(popup) } - private sealed class Action : WorkflowAction { + private sealed class Action : WorkflowAction { object ShowAddRowAction : Action() data class CommitNewRowAction(val index: Int) : Action() - override fun Updater.apply() { + override fun Updater.apply() { state = when (this@Action) { ShowAddRowAction -> ChooseNewRow(state.rows) is CommitNewRowAction -> ShowList(state.rows + allRowTypes[index]) @@ -94,7 +94,7 @@ object AppWorkflow : StatefulWorkflow() { override fun render( props: Unit, state: State, - context: RenderContext + context: RenderContext ): Rendering { val listRendering = context.renderChild(EditableListWorkflow, Props(state.rows)) val baseScreen = BaseScreen( diff --git a/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/editablelistworkflow/EditableListWorkflow.kt b/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/editablelistworkflow/EditableListWorkflow.kt index f4389104aa..774056ea24 100644 --- a/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/editablelistworkflow/EditableListWorkflow.kt +++ b/samples/recyclerview/src/main/java/com/squareup/sample/recyclerview/editablelistworkflow/EditableListWorkflow.kt @@ -61,7 +61,7 @@ object EditableListWorkflow : StatefulWorkflow override fun render( props: Props, state: State, - context: RenderContext + context: RenderContext ): Rendering { return Rendering( rowValues = state.rowValues, diff --git a/samples/tictactoe/common/src/main/java/com/squareup/sample/authworkflow/AuthWorkflow.kt b/samples/tictactoe/common/src/main/java/com/squareup/sample/authworkflow/AuthWorkflow.kt index 0ca6c643ad..c8bb59072a 100644 --- a/samples/tictactoe/common/src/main/java/com/squareup/sample/authworkflow/AuthWorkflow.kt +++ b/samples/tictactoe/common/src/main/java/com/squareup/sample/authworkflow/AuthWorkflow.kt @@ -69,7 +69,7 @@ sealed class AuthResult { object Canceled : AuthResult() } -internal sealed class Action : WorkflowAction { +internal sealed class Action : WorkflowAction { class SubmitLogin( val email: String, val password: String @@ -91,7 +91,7 @@ internal sealed class Action : WorkflowAction { val response: AuthResponse ) : Action() - final override fun Updater.apply() { + final override fun Updater.apply() { when (this@Action) { is SubmitLogin -> { state = when { @@ -146,7 +146,7 @@ class RealAuthWorkflow(private val authService: AuthService) : AuthWorkflow, override fun render( props: Unit, state: AuthState, - context: RenderContext + context: RenderContext ): BackStackScreen = when (state) { is LoginPrompt -> { BackStackScreen( diff --git a/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/RunGameWorkflow.kt b/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/RunGameWorkflow.kt index 890aa418d4..ffd06cd903 100644 --- a/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/RunGameWorkflow.kt +++ b/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/RunGameWorkflow.kt @@ -68,7 +68,7 @@ typealias RunGameScreen = AlertContainerScreen> */ typealias RunGameWorkflow = Workflow -sealed class Action : WorkflowAction { +sealed class Action : WorkflowAction { object CancelNewGame : Action() class StartGame( @@ -99,7 +99,7 @@ sealed class Action : WorkflowAction { // signal that this workflow is too big, and should be refactored into something // like one workflow per screen. - override fun Updater.apply() { + override fun Updater.apply() { when (this@Action) { CancelNewGame -> setOutput(CanceledStart) @@ -178,7 +178,7 @@ class RealRunGameWorkflow( override fun render( props: Unit, state: RunGameState, - context: RenderContext + context: RenderContext ): RunGameScreen = when (state) { is NewGame -> { val emptyGameScreen = GamePlayScreen() diff --git a/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflow.kt b/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflow.kt index 038660e605..04c9e85c75 100644 --- a/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflow.kt +++ b/samples/tictactoe/common/src/main/java/com/squareup/sample/gameworkflow/TakeTurnsWorkflow.kt @@ -52,12 +52,12 @@ class TakeTurnsProps private constructor( class RealTakeTurnsWorkflow : TakeTurnsWorkflow, StatefulWorkflow() { - sealed class Action : WorkflowAction { + sealed class Action : WorkflowAction { class TakeSquare( private val row: Int, private val col: Int ) : Action() { - override fun Updater.apply() { + override fun Updater.apply() { val newBoard = state.board.takeSquare(row, col, state.playing) when { @@ -72,7 +72,7 @@ class RealTakeTurnsWorkflow : TakeTurnsWorkflow, } object Quit : Action() { - override fun Updater.apply() { + override fun Updater.apply() { setOutput(CompletedGame(Quitted, state)) } } @@ -86,7 +86,7 @@ class RealTakeTurnsWorkflow : TakeTurnsWorkflow, override fun render( props: TakeTurnsProps, state: Turn, - context: RenderContext + context: RenderContext ): GamePlayScreen = GamePlayScreen( playerInfo = props.playerInfo, gameState = state, diff --git a/samples/tictactoe/common/src/main/java/com/squareup/sample/mainworkflow/MainWorkflow.kt b/samples/tictactoe/common/src/main/java/com/squareup/sample/mainworkflow/MainWorkflow.kt index 2c74155c34..03107b23b3 100644 --- a/samples/tictactoe/common/src/main/java/com/squareup/sample/mainworkflow/MainWorkflow.kt +++ b/samples/tictactoe/common/src/main/java/com/squareup/sample/mainworkflow/MainWorkflow.kt @@ -65,7 +65,7 @@ class MainWorkflow( override fun render( props: Unit, state: MainState, - context: RenderContext + context: RenderContext ): RunGameScreen = when (state) { is Authenticating -> { val authScreen = context.renderChild(authWorkflow) { handleAuthResult(it) } diff --git a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoEditorWorkflow.kt b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoEditorWorkflow.kt index 36b42beb1e..3242532095 100644 --- a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoEditorWorkflow.kt +++ b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoEditorWorkflow.kt @@ -38,7 +38,7 @@ data class TodoRow( val done: Boolean = false ) -sealed class TodoAction : WorkflowAction { +sealed class TodoAction : WorkflowAction { object GoBackClicked : TodoAction() sealed class ListAction : TodoAction() { @@ -66,7 +66,7 @@ sealed class TodoAction : WorkflowAction { ) : ListAction() } - override fun Updater.apply() { + override fun Updater.apply() { when (this@TodoAction) { is GoBackClicked -> Done is TitleChanged -> ListUpdated(list.copy(title = newTitle)) @@ -95,7 +95,7 @@ class TodoEditorWorkflow : StatelessWorkflow + context: RenderContext ): TodoRendering { // Make event handling idempotent until https://github.com/square/workflow/issues/541 is fixed. var eventFired = false diff --git a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsAppWorkflow.kt b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsAppWorkflow.kt index 975f0964cd..efe6f84243 100644 --- a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsAppWorkflow.kt +++ b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsAppWorkflow.kt @@ -28,7 +28,7 @@ import com.squareup.workflow.WorkflowAction import com.squareup.workflow.action import com.squareup.workflow.ui.backstack.BackStackScreen -private typealias TodoListsAction = WorkflowAction +private typealias TodoListsAction = WorkflowAction sealed class TodoListsAppState { abstract val lists: List @@ -80,7 +80,7 @@ object TodoListsAppWorkflow : override fun render( props: Unit, state: TodoListsAppState, - context: RenderContext + context: RenderContext ): OverviewDetailScreen { val listOfLists: TodoListsScreen = context.renderChild( listsWorkflow, diff --git a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsWorkflow.kt b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsWorkflow.kt index 9957ab13ec..7b753e4395 100644 --- a/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsWorkflow.kt +++ b/samples/todo-android/common/src/main/java/com/squareup/sample/todo/TodoListsWorkflow.kt @@ -23,7 +23,7 @@ import com.squareup.workflow.makeEventSink class TodoListsWorkflow : StatelessWorkflow, Int, TodoListsScreen>() { override fun render( props: List, - context: RenderContext + context: RenderContext, Nothing, Int> ): TodoListsScreen { // A sink that emits the given index as the output of this workflow. val sink: Sink = context.makeEventSink { index: Int -> setOutput(index) } diff --git a/workflow-core/api/workflow-core.api b/workflow-core/api/workflow-core.api index ce684944e0..cc67daae77 100644 --- a/workflow-core/api/workflow-core.api +++ b/workflow-core/api/workflow-core.api @@ -162,7 +162,8 @@ public final class com/squareup/workflow/WorkflowAction$Mutator { } public final class com/squareup/workflow/WorkflowAction$Updater { - public fun (Ljava/lang/Object;)V + public fun (Ljava/lang/Object;Ljava/lang/Object;)V + public final fun getProps ()Ljava/lang/Object; public final fun getState ()Ljava/lang/Object; public final fun setOutput (Ljava/lang/Object;)V public final fun setState (Ljava/lang/Object;)V @@ -198,7 +199,7 @@ public final class com/squareup/workflow/Workflows { public static synthetic fun action$default (Lcom/squareup/workflow/StatefulWorkflow;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow/WorkflowAction; public static synthetic fun action$default (Lcom/squareup/workflow/StatelessWorkflow;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow/WorkflowAction; public static synthetic fun action$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow/WorkflowAction; - public static final fun applyTo (Lcom/squareup/workflow/WorkflowAction;Ljava/lang/Object;)Lkotlin/Pair; + public static final fun applyTo (Lcom/squareup/workflow/WorkflowAction;Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair; public static final fun collectToSink (Lkotlinx/coroutines/flow/Flow;Lcom/squareup/workflow/Sink;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun contraMap (Lcom/squareup/workflow/Sink;Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow/Sink; public static final fun getIdentifier (Lcom/squareup/workflow/Workflow;)Lcom/squareup/workflow/WorkflowIdentifier; diff --git a/workflow-core/src/main/java/com/squareup/workflow/RenderContext.kt b/workflow-core/src/main/java/com/squareup/workflow/RenderContext.kt index 17cc73e3c6..d515cca15a 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/RenderContext.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/RenderContext.kt @@ -53,18 +53,18 @@ import com.squareup.workflow.WorkflowAction.Updater * * See [renderChild]. */ -interface RenderContext { +interface RenderContext { /** * Accepts a single [WorkflowAction], invokes that action by calling [WorkflowAction.apply] * to update the current state, and optionally emits the returned output value if it is non-null. */ - val actionSink: Sink> + val actionSink: Sink> @Deprecated("Use RenderContext.actionSink.") @Suppress("DEPRECATION") fun onEvent( - handler: (EventT) -> WorkflowAction + handler: (EventT) -> WorkflowAction ): (EventT) -> Unit = EventHandler { event -> // Run the handler synchronously, so we only have to emit the resulting action and don't // need the update channel to be generic on each event type. @@ -79,7 +79,7 @@ interface RenderContext { */ @Suppress("UNCHECKED_CAST", "DeprecatedCallableAddReplaceWith") @Deprecated("Use RenderContext.actionSink.") - fun > makeActionSink(): Sink = actionSink + fun > makeActionSink(): Sink = actionSink /** * Ensures [child] is running as a child of this workflow, and returns the result of its @@ -106,7 +106,7 @@ interface RenderContext { child: Workflow, props: ChildPropsT, key: String = "", - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT /** @@ -119,7 +119,7 @@ interface RenderContext { fun runningWorker( worker: Worker, key: String = "", - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) /** @@ -152,34 +152,33 @@ interface RenderContext { * Convenience alias of [RenderContext.renderChild] for workflows that don't take props. */ /* ktlint-disable parameter-list-wrapping */ -fun - RenderContext.renderChild( +fun + RenderContext.renderChild( child: Workflow, key: String = "", - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT = renderChild(child, Unit, key, handler) /* ktlint-enable parameter-list-wrapping */ /** - * Convenience alias of [RenderContext.renderChild] for workflows that don't take props or emit - * output. + * Convenience alias of [RenderContext.renderChild] for workflows that don't emit output. */ /* ktlint-disable parameter-list-wrapping */ -fun - RenderContext.renderChild( - child: Workflow, - props: PropsT, +fun + RenderContext.renderChild( + child: Workflow, + props: ChildPropsT, key: String = "" ): ChildRenderingT = renderChild(child, props, key) { noAction() } /* ktlint-enable parameter-list-wrapping */ /** - * Convenience alias of [RenderContext.renderChild] for workflows that don't take props or emit + * Convenience alias of [RenderContext.renderChild] for children that don't take props or emit * output. */ /* ktlint-disable parameter-list-wrapping */ -fun - RenderContext.renderChild( +fun + RenderContext.renderChild( child: Workflow, key: String = "" ): ChildRenderingT = renderChild(child, Unit, key) { noAction() } @@ -193,7 +192,7 @@ fun * * @param key An optional string key that is used to distinguish between identical [Worker]s. */ -fun RenderContext.runningWorker( +fun RenderContext.runningWorker( worker: Worker, key: String = "" ) { @@ -207,8 +206,8 @@ fun RenderContext.runningWorker( * Alternative to [RenderContext.actionSink] that allows externally defined * event types to be mapped to anonymous [WorkflowAction]s. */ -fun RenderContext.makeEventSink( - update: Updater.(EventT) -> Unit +fun RenderContext.makeEventSink( + update: Updater.(EventT) -> Unit ): Sink = actionSink.contraMap { event -> action({ "eventSink($event)" }) { update(event) } } @@ -224,8 +223,8 @@ fun RenderContext.makeEventSink( "Use runningWorker", ReplaceWith("runningWorker(worker, key, handler)", "com.squareup.workflow.runningWorker") ) -fun RenderContext.onWorkerOutput( +fun RenderContext.onWorkerOutput( worker: Worker, key: String = "", - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) = runningWorker(worker, key, handler) diff --git a/workflow-core/src/main/java/com/squareup/workflow/Sink.kt b/workflow-core/src/main/java/com/squareup/workflow/Sink.kt index d85e0d4ed0..8325291e52 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/Sink.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/Sink.kt @@ -58,7 +58,7 @@ fun Sink.contraMap(transform: (T2) -> T1): Sink { /** * Collects from a [Flow] by converting each item into a [WorkflowAction] and then sending them - * to the [actionSink]. This operator propagates backpressure from the workflow runtime, so if there + * to the [actionSink]. This operator propagates back pressure from the workflow runtime, so if there * is a lot of contention on the workflow runtime the flow will be suspended while the action is * queued. * @@ -74,9 +74,9 @@ fun Sink.contraMap(transform: (T2) -> T1): Sink { * ``` */ @ExperimentalWorkflowApi -suspend fun Flow.collectToSink( - actionSink: Sink>, - handler: (T) -> WorkflowAction +suspend fun Flow.collectToSink( + actionSink: Sink>, + handler: (T) -> WorkflowAction ) { collect { // Don't process the emission until the last emission has had its action executed by the @@ -88,7 +88,7 @@ suspend fun Flow.collectToSink( /** * Sends [action] to this [Sink] and suspends until after [action]'s [WorkflowAction.apply] method * has been invoked. Since a [Sink] may be backed by an unbounded buffer, this method can be used - * to apply backpressure to the caller when there are a lot events being sent to the workflow + * to apply back pressure to the caller when there are a lot events being sent to the workflow * runtime. * * If this coroutine is cancelled before the action gets applied, the action will not be applied. @@ -96,11 +96,15 @@ suspend fun Flow.collectToSink( * This method is intended to be used from [RenderContext.runningSideEffect]. */ @ExperimentalWorkflowApi -suspend fun Sink>.sendAndAwaitApplication( - action: WorkflowAction -) { +suspend fun < + PropsT, + StateT, + OutputT + > Sink>.sendAndAwaitApplication( + action: WorkflowAction + ) { suspendCancellableCoroutine { continuation -> - val resumingAction = action({ "sendAndAwaitExecution($action)" }) { + val resumingAction = action({ "sendAndAwaitExecution($action)" }) { // Don't execute anything if the caller was cancelled while we were in the queue. if (!continuation.isActive) return@action diff --git a/workflow-core/src/main/java/com/squareup/workflow/StatefulWorkflow.kt b/workflow-core/src/main/java/com/squareup/workflow/StatefulWorkflow.kt index 70c27c0596..0db354714f 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/StatefulWorkflow.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/StatefulWorkflow.kt @@ -137,7 +137,7 @@ abstract class StatefulWorkflow< abstract fun render( props: PropsT, state: StateT, - context: RenderContext + context: RenderContext ): RenderingT /** @@ -168,7 +168,7 @@ abstract class StatefulWorkflow< */ inline fun Workflow.Companion.stateful( crossinline initialState: (PropsT, Snapshot?) -> StateT, - crossinline render: RenderContext.(props: PropsT, state: StateT) -> RenderingT, + crossinline render: RenderContext.(props: PropsT, state: StateT) -> RenderingT, crossinline snapshot: (StateT) -> Snapshot?, crossinline onPropsChanged: ( old: PropsT, @@ -191,7 +191,7 @@ inline fun Workflow.Companion.stateful( override fun render( props: PropsT, state: StateT, - context: RenderContext + context: RenderContext ): RenderingT = render(context, props, state) override fun snapshotState(state: StateT) = snapshot(state) @@ -202,7 +202,7 @@ inline fun Workflow.Companion.stateful( */ inline fun Workflow.Companion.stateful( crossinline initialState: (Snapshot?) -> StateT, - crossinline render: RenderContext.(state: StateT) -> RenderingT, + crossinline render: RenderContext.(state: StateT) -> RenderingT, crossinline snapshot: (StateT) -> Snapshot? ): StatefulWorkflow = stateful( { _, initialSnapshot -> initialState(initialSnapshot) }, @@ -217,7 +217,7 @@ inline fun Workflow.Companion.stateful( */ inline fun Workflow.Companion.stateful( crossinline initialState: (PropsT) -> StateT, - crossinline render: RenderContext.(props: PropsT, state: StateT) -> RenderingT, + crossinline render: RenderContext.(props: PropsT, state: StateT) -> RenderingT, crossinline onPropsChanged: ( old: PropsT, new: PropsT, @@ -237,7 +237,7 @@ inline fun Workflow.Companion.stateful( */ inline fun Workflow.Companion.stateful( initialState: StateT, - crossinline render: RenderContext.(state: StateT) -> RenderingT + crossinline render: RenderContext.(state: StateT) -> RenderingT ): StatefulWorkflow = stateful( { initialState }, { _, state -> render(state) } @@ -254,7 +254,7 @@ inline fun Workflow.Companion.stateful( fun StatefulWorkflow.action( name: String = "", - update: Updater.() -> Unit + update: Updater.() -> Unit ) = action({ name }, update) /** @@ -269,9 +269,9 @@ fun fun StatefulWorkflow.action( name: () -> String, - update: Updater.() -> Unit - ): WorkflowAction = object : WorkflowAction { - override fun Updater.apply() = update.invoke(this) + update: Updater.() -> Unit + ): WorkflowAction = object : WorkflowAction { + override fun Updater.apply() = update.invoke(this) override fun toString(): String = "action(${name()})-${this@action}" } @@ -300,7 +300,7 @@ fun StatefulWorkflow.workflowAction( name: () -> String, block: Mutator.() -> OutputT? - ): WorkflowAction = object : WorkflowAction { + ): WorkflowAction = object : WorkflowAction { override fun Mutator.apply() = block.invoke(this) override fun toString(): String = "workflowAction(${name()})-${this@workflowAction}" } diff --git a/workflow-core/src/main/java/com/squareup/workflow/StatelessWorkflow.kt b/workflow-core/src/main/java/com/squareup/workflow/StatelessWorkflow.kt index d22f16f8a1..beb183ca32 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/StatelessWorkflow.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/StatelessWorkflow.kt @@ -43,7 +43,7 @@ abstract class StatelessWorkflow : @Suppress("UNCHECKED_CAST") private val statefulWorkflow = Workflow.stateful( initialState = { Unit }, - render = { props, _ -> render(props, this as RenderContext) } + render = { props, _ -> render(props, this as RenderContext) } ) /** @@ -62,7 +62,7 @@ abstract class StatelessWorkflow : */ abstract fun render( props: PropsT, - context: RenderContext + context: RenderContext ): RenderingT /** @@ -86,12 +86,12 @@ abstract class StatelessWorkflow : * their own internal state. */ inline fun Workflow.Companion.stateless( - crossinline render: RenderContext.(props: PropsT) -> RenderingT + crossinline render: RenderContext.(props: PropsT) -> RenderingT ): Workflow = object : StatelessWorkflow() { override fun render( props: PropsT, - context: RenderContext + context: RenderContext ): RenderingT = render(context, props) } @@ -114,7 +114,7 @@ fun Workflow.Companion.rendering( fun StatelessWorkflow.action( name: String = "", - update: Updater.() -> Unit + update: Updater.() -> Unit ) = action({ name }, update) /** @@ -129,8 +129,8 @@ fun fun StatelessWorkflow.action( name: () -> String, - update: Updater.() -> Unit -): WorkflowAction = object : WorkflowAction { - override fun Updater.apply() = update.invoke(this) + update: Updater.() -> Unit +): WorkflowAction = object : WorkflowAction { + override fun Updater.apply() = update.invoke(this) override fun toString(): String = "action(${name()})-${this@action}" } diff --git a/workflow-core/src/main/java/com/squareup/workflow/Workflow.kt b/workflow-core/src/main/java/com/squareup/workflow/Workflow.kt index f4a4e4cd65..cfbc7244db 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/Workflow.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/Workflow.kt @@ -138,7 +138,7 @@ fun override fun render( props: PropsT, - context: RenderContext + context: RenderContext ): ToRenderingT { val rendering = context.renderChild(this@mapRendering, props) { output -> action({ "mapRendering" }) { setOutput(output) } diff --git a/workflow-core/src/main/java/com/squareup/workflow/WorkflowAction.kt b/workflow-core/src/main/java/com/squareup/workflow/WorkflowAction.kt index 8bf5e5b039..a4c35e9474 100644 --- a/workflow-core/src/main/java/com/squareup/workflow/WorkflowAction.kt +++ b/workflow-core/src/main/java/com/squareup/workflow/WorkflowAction.kt @@ -24,7 +24,7 @@ import com.squareup.workflow.WorkflowAction.Updater /** * An atomic operation that updates the state of a [Workflow], and also optionally emits an output. */ -interface WorkflowAction { +interface WorkflowAction { @Deprecated("Use Updater") class Mutator(var state: S) @@ -34,7 +34,10 @@ interface WorkflowAction { * * @param state the state that the workflow should move to. Default is the current state. */ - class Updater(var state: S) { + class Updater( + val props: P, + var state: S + ) { internal var output: WorkflowOutput<@UnsafeVariance O>? = null private set @@ -52,7 +55,7 @@ interface WorkflowAction { * setting the [OutputT] to emit. */ @Suppress("DEPRECATION") - fun Updater.apply() { + fun Updater.apply() { val mutator = Mutator(state) mutator.apply() ?.let { setOutput(it) } @@ -73,12 +76,12 @@ interface WorkflowAction { * Use this to, for example, ignore the output of a child workflow or worker. */ @Suppress("UNCHECKED_CAST") - fun noAction(): WorkflowAction = - NO_ACTION as WorkflowAction + fun noAction(): WorkflowAction = + NO_ACTION as WorkflowAction /** - * Convenience function that returns a [WorkflowAction] that will just set the state to [newState] - * (without considering the current state) and optionally emit an output. + * Convenience function that returns a [WorkflowAction] that will just set the state to + * [newState] (without considering the current state) and optionally emit an output. */ @Deprecated( message = "Use action", @@ -90,15 +93,15 @@ interface WorkflowAction { fun enterState( newState: StateT, emittingOutput: OutputT? = null - ): WorkflowAction = + ): WorkflowAction = action({ "enterState($newState, $emittingOutput)" }) { state = newState emittingOutput?.let { setOutput(it) } } /** - * Convenience function that returns a [WorkflowAction] that will just set the state to [newState] - * (without considering the current state) and optionally emit an output. + * Convenience function that returns a [WorkflowAction] that will just set the state to + * [newState] (without considering the current state) and optionally emit an output. */ @Deprecated( message = "Use action", @@ -111,7 +114,7 @@ interface WorkflowAction { name: String, newState: StateT, emittingOutput: OutputT? = null - ): WorkflowAction = + ): WorkflowAction = action({ "enterState($name, $newState, $emittingOutput)" }) { state = newState emittingOutput?.let { setOutput(it) } @@ -131,7 +134,7 @@ interface WorkflowAction { name: () -> String, emittingOutput: OutputT? = null, modify: (StateT) -> StateT - ): WorkflowAction = + ): WorkflowAction = action({ "modifyState(${name()}, $emittingOutput)" }) { state = modify(state) emittingOutput?.let { setOutput(it) } @@ -147,7 +150,7 @@ interface WorkflowAction { imports = arrayOf("com.squareup.workflow.action") ) ) - fun emitOutput(output: OutputT): WorkflowAction = + fun emitOutput(output: OutputT): WorkflowAction = action({ "emitOutput($output)" }) { setOutput(output) } /** @@ -160,13 +163,13 @@ interface WorkflowAction { imports = arrayOf("com.squareup.workflow.action") ) ) - fun emitOutput( + fun emitOutput( name: String, output: OutputT - ): WorkflowAction = + ): WorkflowAction = action({ "emitOutput($name, $output)" }) { setOutput(output) } - private val NO_ACTION = action({ "noAction" }) { } + private val NO_ACTION = action({ "noAction" }) { } } } @@ -183,9 +186,9 @@ interface WorkflowAction { * @see StatelessWorkflow.action * @see StatefulWorkflow.action */ -inline fun action( +inline fun action( name: String = "", - crossinline apply: Updater.() -> Unit + crossinline apply: Updater.() -> Unit ) = action({ name }, apply) /** @@ -201,20 +204,22 @@ inline fun action( * @see StatelessWorkflow.action * @see StatefulWorkflow.action */ -inline fun action( +inline fun action( crossinline name: () -> String, - crossinline apply: Updater.() -> Unit -): WorkflowAction = object : WorkflowAction { - override fun Updater.apply() = apply.invoke(this) + crossinline apply: Updater.() -> Unit +): WorkflowAction = object : WorkflowAction { + override fun Updater<@UnsafeVariance PropsT, StateT, OutputT>.apply() = apply.invoke(this) + override fun toString(): String = "WorkflowAction(${name()})@${hashCode()}" } /** Applies this [WorkflowAction] to [state]. */ @ExperimentalWorkflowApi -fun WorkflowAction.applyTo( +fun WorkflowAction.applyTo( + props: PropsT, state: StateT ): Pair?> { - val updater = Updater(state) + val updater = Updater(props, state) updater.apply() return Pair(updater.state, updater.output) } diff --git a/workflow-core/src/test/java/com/squareup/workflow/SinkTest.kt b/workflow-core/src/test/java/com/squareup/workflow/SinkTest.kt index 3309b82ece..68fffae7f3 100644 --- a/workflow-core/src/test/java/com/squareup/workflow/SinkTest.kt +++ b/workflow-core/src/test/java/com/squareup/workflow/SinkTest.kt @@ -41,7 +41,7 @@ class SinkTest { val collector = launch { flow.collectToSink(sink) { action { - state = "$state $it" + state = "$props $state $it" setOutput("output: $it") } } @@ -51,8 +51,8 @@ class SinkTest { assertEquals(1, sink.actions.size) sink.actions.removeFirst() .let { action -> - val (newState, output) = action.applyTo("state") - assertEquals("state 1", newState) + val (newState, output) = action.applyTo("props", "state") + assertEquals("props state 1", newState) assertEquals("output: 1", output?.value) } assertTrue(sink.actions.isEmpty()) @@ -62,8 +62,8 @@ class SinkTest { assertEquals(1, sink.actions.size) sink.actions.removeFirst() .let { action -> - val (newState, output) = action.applyTo("state") - assertEquals("state 2", newState) + val (newState, output) = action.applyTo("props", "state") + assertEquals("props state 2", newState) assertEquals("output: 2", output?.value) } @@ -73,9 +73,9 @@ class SinkTest { @Test fun `sendAndAwaitApplication applies action`() { var applications = 0 - val action = action { + val action = action { applications++ - state = "$state applied" + state = "$props $state applied" setOutput("output") } @@ -84,9 +84,9 @@ class SinkTest { advanceUntilIdle() val enqueuedAction = sink.actions.removeFirst() - val (newState, output) = enqueuedAction.applyTo("state") + val (newState, output) = enqueuedAction.applyTo("props", "state") assertEquals(1, applications) - assertEquals("state applied", newState) + assertEquals("props state applied", newState) assertEquals("output", output?.value) } } @@ -94,7 +94,7 @@ class SinkTest { @Test fun `sendAndAwaitApplication suspends until after applied`() { runBlockingTest { var resumed = false - val action = action { + val action = action { assertFalse(resumed) } launch { @@ -107,7 +107,7 @@ class SinkTest { val enqueuedAction = sink.actions.removeFirst() pauseDispatcher() - enqueuedAction.applyTo("state") + enqueuedAction.applyTo("props", "state") assertFalse(resumed) resumeDispatcher() @@ -119,7 +119,7 @@ class SinkTest { @Test fun `sendAndAwaitApplication doesn't apply action when cancelled while suspended`() { runBlockingTest { var applied = false - val action = action { + val action = action { applied = true fail() } @@ -131,18 +131,18 @@ class SinkTest { val enqueuedAction = sink.actions.removeFirst() sendJob.cancel() advanceUntilIdle() - val (newState, output) = enqueuedAction.applyTo("ignored") + val (newState, output) = enqueuedAction.applyTo("unused props", "state") assertFalse(applied) - assertEquals("ignored", newState) + assertEquals("state", newState) assertNull(output) } } - private class RecordingSink : Sink> { - val actions = mutableListOf>() + private class RecordingSink : Sink> { + val actions = mutableListOf>() - override fun send(value: WorkflowAction) { + override fun send(value: WorkflowAction) { actions += value } } diff --git a/workflow-core/src/test/java/com/squareup/workflow/WorkflowActionTest.kt b/workflow-core/src/test/java/com/squareup/workflow/WorkflowActionTest.kt index ceafb0e6a6..d259dc446c 100644 --- a/workflow-core/src/test/java/com/squareup/workflow/WorkflowActionTest.kt +++ b/workflow-core/src/test/java/com/squareup/workflow/WorkflowActionTest.kt @@ -25,38 +25,38 @@ import kotlin.test.assertNull class WorkflowActionTest { @Test fun `applyTo works when no output is set`() { - val action = object : WorkflowAction { - override fun Updater.apply() { - state = "state: $state" + val action = object : WorkflowAction { + override fun Updater.apply() { + state = "state: $state, props: $props" } } - val (state, output) = action.applyTo("state") - assertEquals("state: state", state) + val (state, output) = action.applyTo("props", "state") + assertEquals("state: state, props: props", state) assertNull(output) } @Test fun `applyTo works when null output is set`() { - val action = object : WorkflowAction { - override fun Updater.apply() { - state = "state: $state" + val action = object : WorkflowAction { + override fun Updater.apply() { + state = "state: $state, props: $props" setOutput(null) } } - val (state, output) = action.applyTo("state") - assertEquals("state: state", state) + val (state, output) = action.applyTo("props", "state") + assertEquals("state: state, props: props", state) assertNotNull(output) assertNull(output.value) } @Test fun `applyTo works when non-null output is set`() { - val action = object : WorkflowAction { - override fun Updater.apply() { - state = "state: $state" + val action = object : WorkflowAction { + override fun Updater.apply() { + state = "state: $state, props: $props" setOutput("output") } } - val (state, output) = action.applyTo("state") - assertEquals("state: state", state) + val (state, output) = action.applyTo("props", "state") + assertEquals("state: state, props: props", state) assertNotNull(output) assertEquals("output", output.value) } diff --git a/workflow-runtime/src/jmh/java/com/squareup/workflow/WorkflowNodeBenchmark.kt b/workflow-runtime/src/jmh/java/com/squareup/workflow/WorkflowNodeBenchmark.kt index 36540b3961..05c6c4e3f3 100644 --- a/workflow-runtime/src/jmh/java/com/squareup/workflow/WorkflowNodeBenchmark.kt +++ b/workflow-runtime/src/jmh/java/com/squareup/workflow/WorkflowNodeBenchmark.kt @@ -164,7 +164,7 @@ private class FractalWorkflow( override fun render( props: Props, state: Unit, - context: RenderContext + context: RenderContext ) { if (childWorkflow != null && (props.renderLeaves || !areChildrenLeaves)) { for (i in 0 until childCount) { diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/SimpleLoggingWorkflowInterceptor.kt b/workflow-runtime/src/main/java/com/squareup/workflow/SimpleLoggingWorkflowInterceptor.kt index 55a3cecd87..d8f801ae1b 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/SimpleLoggingWorkflowInterceptor.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/SimpleLoggingWorkflowInterceptor.kt @@ -56,8 +56,8 @@ open class SimpleLoggingWorkflowInterceptor : WorkflowInterceptor { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R = logMethod("onRender", props, state, session) { proceed(props, state, context) diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/WorkflowInterceptor.kt b/workflow-runtime/src/main/java/com/squareup/workflow/WorkflowInterceptor.kt index e631f33211..a6bde4a5a3 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/WorkflowInterceptor.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/WorkflowInterceptor.kt @@ -96,8 +96,8 @@ interface WorkflowInterceptor { fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R = proceed(props, state, context) @@ -167,7 +167,7 @@ internal fun WorkflowInterceptor.intercept( override fun render( props: P, state: S, - context: RenderContext + context: RenderContext ): R = onRender(props, state, context, workflow::render, workflowSession) override fun snapshotState(state: S) = diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/ChainedWorkflowInterceptor.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/ChainedWorkflowInterceptor.kt index c4ac1aed33..dc10cad31b 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/ChainedWorkflowInterceptor.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/ChainedWorkflowInterceptor.kt @@ -75,8 +75,8 @@ internal class ChainedWorkflowInterceptor( override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R { val chainedProceed = interceptors.foldRight(proceed) { workflowInterceptor, proceedAcc -> diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/RealRenderContext.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/RealRenderContext.kt index da08ef3cf5..8a33c690a9 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/RealRenderContext.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/RealRenderContext.kt @@ -24,27 +24,27 @@ import com.squareup.workflow.Workflow import com.squareup.workflow.WorkflowAction import kotlinx.coroutines.channels.SendChannel -class RealRenderContext( - private val renderer: Renderer, - private val workerRunner: WorkerRunner, +class RealRenderContext( + private val renderer: Renderer, + private val workerRunner: WorkerRunner, private val sideEffectRunner: SideEffectRunner, - private val eventActionsChannel: SendChannel> -) : RenderContext, Sink> { + private val eventActionsChannel: SendChannel> +) : RenderContext, Sink> { - interface Renderer { + interface Renderer { fun render( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT } - interface WorkerRunner { + interface WorkerRunner { fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) } @@ -64,9 +64,9 @@ class RealRenderContext( */ private var frozen = false - override val actionSink: Sink> get() = this + override val actionSink: Sink> get() = this - override fun send(value: WorkflowAction) { + override fun send(value: WorkflowAction) { if (!frozen) { throw UnsupportedOperationException( "Expected sink to not be sent to until after the render pass. Received action: $value" @@ -79,7 +79,7 @@ class RealRenderContext( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT { checkNotFrozen() return renderer.render(child, props, key, handler) @@ -88,7 +88,7 @@ class RealRenderContext( override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { checkNotFrozen() workerRunner.runningWorker(worker, key, handler) diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/SubtreeManager.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/SubtreeManager.kt index 9ffed1be63..1bd4a269f2 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/SubtreeManager.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/SubtreeManager.kt @@ -96,15 +96,15 @@ import kotlin.coroutines.EmptyCoroutineContext * @param snapshotCache */ @OptIn(ExperimentalWorkflowApi::class) -internal class SubtreeManager( +internal class SubtreeManager( snapshotCache: Map, private val contextForChildren: CoroutineContext, - private val emitActionToParent: (WorkflowAction) -> WorkflowOutput?, + private val emitActionToParent: (WorkflowAction) -> Any?, private val workflowSession: WorkflowSession? = null, private val interceptor: WorkflowInterceptor = NoopWorkflowInterceptor, private val idCounter: IdCounter? = null, private val workerContext: CoroutineContext = EmptyCoroutineContext -) : RealRenderContext.Renderer { +) : RealRenderContext.Renderer { /** * When this manager's node is restored from a snapshot, its children snapshots are extracted into @@ -113,7 +113,7 @@ internal class SubtreeManager( */ private val snapshotCache = snapshotCache.toMutableMap() - private var children = ActiveStagingList>() + private var children = ActiveStagingList>() /** * Moves all the nodes that have been accumulated in the staging list to the active list, making @@ -135,7 +135,7 @@ internal class SubtreeManager( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT { /* ktlint-enable parameter-list-wrapping */ @@ -178,12 +178,12 @@ internal class SubtreeManager( child: Workflow, initialProps: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction - ): WorkflowChildNode { + handler: (ChildOutputT) -> WorkflowAction + ): WorkflowChildNode { val id = child.id(key) - lateinit var node: WorkflowChildNode + lateinit var node: WorkflowChildNode - fun acceptChildOutput(output: ChildOutputT): WorkflowOutput? { + fun acceptChildOutput(output: ChildOutputT): Any? { val action = node.acceptChildOutput(output) return emitActionToParent(action) } diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkerChildNode.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkerChildNode.kt index 6f39d85ddb..7ceb36655b 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkerChildNode.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkerChildNode.kt @@ -34,26 +34,26 @@ import kotlinx.coroutines.channels.ReceiveChannel * after the worker finishes so that they aren't immediately restarted on the next render pass. This * flag indicates that the channel should not be polled on the next tick. */ -internal class WorkerChildNode( +internal class WorkerChildNode( val worker: Worker, val key: String, val channel: ReceiveChannel>, var tombstone: Boolean = false, - private var handler: (T) -> WorkflowAction -) : InlineListNode> { + private var handler: (T) -> WorkflowAction +) : InlineListNode> { - override var nextListNode: WorkerChildNode<*, *, *>? = null + override var nextListNode: WorkerChildNode<*, *, *, *>? = null /** * Updates the handler function that will be invoked by [acceptUpdate]. */ - fun setHandler(newHandler: (T2) -> WorkflowAction) { + fun setHandler(newHandler: (T2) -> WorkflowAction) { @Suppress("UNCHECKED_CAST") - handler = newHandler as (T) -> WorkflowAction + handler = newHandler as (T) -> WorkflowAction } @Suppress("UNCHECKED_CAST") - fun acceptUpdate(value: Any?): WorkflowAction = + fun acceptUpdate(value: Any?): WorkflowAction = handler(value as T) /** diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowChildNode.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowChildNode.kt index 369e8eb045..896fa6e651 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowChildNode.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowChildNode.kt @@ -30,16 +30,17 @@ import com.squareup.workflow.internal.InlineLinkedList.InlineListNode internal class WorkflowChildNode< ChildPropsT, ChildOutputT, + ParentPropsT, ParentStateT, ParentOutputT >( val workflow: Workflow<*, ChildOutputT, *>, - private var handler: (ChildOutputT) -> WorkflowAction, + private var handler: (ChildOutputT) -> WorkflowAction, val workflowNode: WorkflowNode -) : InlineListNode> { +) : InlineListNode> { /* ktlint-enable parameter-list-wrapping */ - override var nextListNode: WorkflowChildNode<*, *, *, *>? = null + override var nextListNode: WorkflowChildNode<*, *, *, *, *>? = null /** The [WorkflowNode]'s [WorkflowNodeId]. */ val id get() = workflowNode.id @@ -55,9 +56,10 @@ internal class WorkflowChildNode< /** * Updates the handler function that will be invoked by [acceptChildOutput]. */ - fun setHandler(newHandler: (CO) -> WorkflowAction) { + fun setHandler(newHandler: (CO) -> WorkflowAction) { @Suppress("UNCHECKED_CAST") - handler = newHandler as (ChildOutputT) -> WorkflowAction + handler = + newHandler as (ChildOutputT) -> WorkflowAction } /** @@ -78,6 +80,6 @@ internal class WorkflowChildNode< * Wrapper around [handler] that allows calling it with erased types. */ @Suppress("UNCHECKED_CAST") - fun acceptChildOutput(output: Any?): WorkflowAction = + fun acceptChildOutput(output: Any?): WorkflowAction = handler(output as ChildOutputT) } diff --git a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowNode.kt b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowNode.kt index 5632919b8f..cb277d103a 100644 --- a/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowNode.kt +++ b/workflow-runtime/src/main/java/com/squareup/workflow/internal/WorkflowNode.kt @@ -61,12 +61,12 @@ internal class WorkflowNode( initialProps: PropsT, snapshot: TreeSnapshot, baseContext: CoroutineContext, - private val emitOutputToParent: (OutputT) -> WorkflowOutput? = { WorkflowOutput(it) }, + private val emitOutputToParent: (OutputT) -> Any? = { WorkflowOutput(it) }, override val parent: WorkflowSession? = null, private val interceptor: WorkflowInterceptor = NoopWorkflowInterceptor, idCounter: IdCounter? = null, private val workerContext: CoroutineContext = EmptyCoroutineContext -) : CoroutineScope, WorkerRunner, SideEffectRunner, WorkflowSession { +) : CoroutineScope, WorkerRunner, SideEffectRunner, WorkflowSession { /** * Context that has a job that will live as long as this node. @@ -79,7 +79,7 @@ internal class WorkflowNode( override val renderKey: String get() = id.name override val sessionId: Long = idCounter.createId() - private val subtreeManager = SubtreeManager( + private val subtreeManager = SubtreeManager( snapshotCache = snapshot.childTreeSnapshots, contextForChildren = coroutineContext, emitActionToParent = ::applyAction, @@ -88,17 +88,18 @@ internal class WorkflowNode( idCounter = idCounter, workerContext = workerContext ) - private val workers = ActiveStagingList>() + private val workers = ActiveStagingList>() private val sideEffects = ActiveStagingList() private var lastProps: PropsT = initialProps - private val eventActionsChannel = Channel>(capacity = UNLIMITED) + private val eventActionsChannel = + Channel>(capacity = UNLIMITED) private var state: StateT init { interceptor.onSessionStarted(this, this) state = interceptor.intercept(workflow, this) - .initialState(initialProps, snapshot.workflowSnapshot) + .initialState(initialProps, snapshot.workflowSnapshot) } override fun toString(): String { @@ -143,7 +144,7 @@ internal class WorkflowNode( override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { // Prevent duplicate workers with the same key. workers.forEachStaging { @@ -203,7 +204,7 @@ internal class WorkflowNode( } else { val update = child.acceptUpdate(valueOrDone.value) @Suppress("UNCHECKED_CAST") - return@onReceive applyAction(update as WorkflowAction) + return@onReceive applyAction(update as WorkflowAction) } } } @@ -278,18 +279,18 @@ internal class WorkflowNode( * Applies [action] to this workflow's [state] and * [emits an output to its parent][emitOutputToParent] if necessary. */ - private fun applyAction(action: WorkflowAction): WorkflowOutput? { - val (newState, tickResult) = action.applyTo(state) + private fun applyAction(action: WorkflowAction): T? { + val (newState, tickResult) = action.applyTo(lastProps, state) state = newState @Suppress("UNCHECKED_CAST") - return tickResult?.let { emitOutputToParent(it.value) } as WorkflowOutput? + return tickResult?.let { emitOutputToParent(it.value) } as T? } private fun createWorkerNode( worker: Worker, key: String, - handler: (T) -> WorkflowAction - ): WorkerChildNode { + handler: (T) -> WorkflowAction + ): WorkerChildNode { val workerChannel = launchWorker(worker, key, workerContext) return WorkerChildNode(worker, key, workerChannel, handler = handler) } diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowInterceptorTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowInterceptorTest.kt index f6b09f13e1..106b853cbd 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowInterceptorTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowInterceptorTest.kt @@ -57,20 +57,20 @@ class WorkflowInterceptorTest { @Test fun `intercept() intercepts calls to render()`() { val recorder = RecordingWorkflowInterceptor() val intercepted = recorder.intercept(TestWorkflow, TestWorkflow.session) - val fakeContext = object : RenderContext { - override val actionSink: Sink> get() = fail() + val fakeContext = object : RenderContext { + override val actionSink: Sink> get() = fail() override fun renderChild( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT = fail() override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ): Unit = fail() override fun runningSideEffect( @@ -120,7 +120,7 @@ class WorkflowInterceptorTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String = "$props|$state" override fun snapshotState(state: String): Snapshot = Snapshot.of(state) diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowOperatorsTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowOperatorsTest.kt index e1b2385343..c163a9de5a 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowOperatorsTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/WorkflowOperatorsTest.kt @@ -38,7 +38,7 @@ class WorkflowOperatorsTest { override fun toString(): String = "ChildWorkflow" override fun render( props: Unit, - context: RenderContext + context: RenderContext ): Nothing = fail() } val mappedWorkflow = workflow.mapRendering { fail() } @@ -230,7 +230,7 @@ class WorkflowOperatorsTest { override fun render( props: Unit, - context: RenderContext + context: RenderContext ): T { // Listen to the flow to trigger a re-render when it updates. context.runningWorker(rerenderWorker) { WorkflowAction.noAction() } diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/internal/ChainedWorkflowInterceptorTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/internal/ChainedWorkflowInterceptorTest.kt index 6ef6e6d336..82d9bb8f35 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/internal/ChainedWorkflowInterceptorTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/internal/ChainedWorkflowInterceptorTest.kt @@ -189,35 +189,35 @@ class ChainedWorkflowInterceptorTest { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R = ("r1: " + proceed( "props1: $props" as P, "state1: $state" as S, - FakeRenderContext("context1: $context") as RenderContext + FakeRenderContext("context1: $context") as RenderContext )) as R } val interceptor2 = object : WorkflowInterceptor { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R = ("r2: " + proceed( "props2: $props" as P, "state2: $state" as S, - FakeRenderContext("context2: $context") as RenderContext + FakeRenderContext("context2: $context") as RenderContext )) as R } val chained = listOf(interceptor1, interceptor2).chained() fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String = "($props|$state|$context)" val finalRendering = @@ -255,17 +255,17 @@ class ChainedWorkflowInterceptorTest { private fun Snapshot?.readUtf8() = this?.bytes?.parse { it.readUtf8() } - private class FakeRenderContext(private val name: String) : RenderContext { + private class FakeRenderContext(private val name: String) : RenderContext { override fun toString(): String = name - override val actionSink: Sink> + override val actionSink: Sink> get() = fail() override fun renderChild( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT { fail() } @@ -273,7 +273,7 @@ class ChainedWorkflowInterceptorTest { override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { fail() } diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/internal/RealRenderContextTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/internal/RealRenderContextTest.kt index 029608e812..1e2de2819d 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/internal/RealRenderContextTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/internal/RealRenderContextTest.kt @@ -49,13 +49,13 @@ import kotlin.test.fail @OptIn(ExperimentalWorkflowApi::class) class RealRenderContextTest { - private class TestRenderer : Renderer { + private class TestRenderer : Renderer { data class Rendering( val child: Workflow<*, *, *>, val props: Any?, val key: String, - val handler: (Any) -> WorkflowAction + val handler: (Any) -> WorkflowAction ) @Suppress("UNCHECKED_CAST") @@ -63,20 +63,20 @@ class RealRenderContextTest { child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT = Rendering( child, props, key, - handler as (Any) -> WorkflowAction + handler as (Any) -> WorkflowAction ) as ChildRenderingT } - private class TestRunner : WorkerRunner, SideEffectRunner { + private class TestRunner : WorkerRunner, SideEffectRunner { override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { // No-op } @@ -98,7 +98,7 @@ class RealRenderContextTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): Rendering { fail("This shouldn't actually be called.") } @@ -106,20 +106,20 @@ class RealRenderContextTest { override fun snapshotState(state: String): Snapshot = fail() } - private class PoisonRenderer : Renderer { + private class PoisonRenderer : Renderer { override fun render( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT = fail() } - private class PoisonRunner : WorkerRunner, SideEffectRunner { + private class PoisonRunner : WorkerRunner, SideEffectRunner { override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { fail() } @@ -132,11 +132,11 @@ class RealRenderContextTest { } } - private val eventActionsChannel = Channel>(capacity = UNLIMITED) + private val eventActionsChannel = Channel>(capacity = UNLIMITED) @Test fun `onEvent completes update`() { val context = createdPoisonedContext() - val expectedUpdate = noAction() + val expectedUpdate = noAction() @Suppress("DEPRECATION") val handler = context.onEvent { _: String -> expectedUpdate } @@ -152,8 +152,8 @@ class RealRenderContextTest { @Test fun `onEvent allows multiple invocations`() { val context = createdPoisonedContext() - fun expectedUpdate(msg: String) = object : WorkflowAction { - override fun Updater.apply() = Unit + fun expectedUpdate(msg: String) = object : WorkflowAction { + override fun Updater.apply() = Unit override fun toString(): String = "action($msg)" } @@ -168,7 +168,7 @@ class RealRenderContextTest { @Test fun `send completes update`() { val context = createdPoisonedContext() - val stringAction = action({ "stringAction" }) { } + val stringAction = action({ "stringAction" }) { } // Enable sink sends. context.freeze() @@ -184,12 +184,12 @@ class RealRenderContextTest { @Test fun `send allows multiple sends`() { val context = createdPoisonedContext() - val firstAction = object : WorkflowAction { - override fun Updater.apply() = Unit + val firstAction = object : WorkflowAction { + override fun Updater.apply() = Unit override fun toString(): String = "firstAction" } - val secondAction = object : WorkflowAction { - override fun Updater.apply() = Unit + val secondAction = object : WorkflowAction { + override fun Updater.apply() = Unit override fun toString(): String = "secondAction" } // Enable sink sends. @@ -203,8 +203,8 @@ class RealRenderContextTest { @Test fun `send throws before render returns`() { val context = createdPoisonedContext() - val action = object : WorkflowAction { - override fun Updater.apply() = Unit + val action = object : WorkflowAction { + override fun Updater.apply() = Unit override fun toString(): String = "action" } @@ -226,7 +226,7 @@ class RealRenderContextTest { sink.send("foo") val update = eventActionsChannel.poll()!! - val (state, output) = update.applyTo("state") + val (state, output) = update.applyTo("props", "state") assertEquals("state", state) assertEquals("foo", output?.value) } @@ -244,7 +244,7 @@ class RealRenderContextTest { assertEquals("key", key) val (state, output) = handler.invoke("output") - .applyTo("state") + .applyTo("props", "state") assertEquals("state", state) assertEquals("output:output", output?.value) } @@ -260,12 +260,12 @@ class RealRenderContextTest { assertFailsWith { context.freeze() } } - private fun createdPoisonedContext(): RealRenderContext { - val workerRunner = PoisonRunner() + private fun createdPoisonedContext(): RealRenderContext { + val workerRunner = PoisonRunner() return RealRenderContext(PoisonRenderer(), workerRunner, workerRunner, eventActionsChannel) } - private fun createTestContext(): RealRenderContext { + private fun createTestContext(): RealRenderContext { val workerRunner = TestRunner() return RealRenderContext(TestRenderer(), workerRunner, workerRunner, eventActionsChannel) } diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/internal/SubtreeManagerTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/internal/SubtreeManagerTest.kt index d8f478a84b..abf6a66f77 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/internal/SubtreeManagerTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/internal/SubtreeManagerTest.kt @@ -38,7 +38,7 @@ import kotlin.test.assertFailsWith import kotlin.test.assertFalse import kotlin.test.fail -private typealias StringHandler = (String) -> WorkflowAction +private typealias StringHandler = (String) -> WorkflowAction @OptIn(ExperimentalWorkflowApi::class) class SubtreeManagerTest { @@ -64,7 +64,7 @@ class SubtreeManagerTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): Rendering { val sink: Sink = context.makeEventSink { setOutput(it) } return Rendering(props, state) { sink.send("workflow output:$it") } @@ -87,7 +87,7 @@ class SubtreeManagerTest { override fun render( props: Unit, state: Unit, - context: RenderContext + context: RenderContext ) { } @@ -102,7 +102,7 @@ class SubtreeManagerTest { private val context = Unconfined @Test fun `render starts new child`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() manager.render(workflow, "props", key = "", handler = { fail() }) @@ -110,7 +110,7 @@ class SubtreeManagerTest { } @Test fun `render doesn't start existing child`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() fun render() = manager.render(workflow, "props", key = "", handler = { fail() }) .also { manager.commitRenderedChildren() } @@ -122,7 +122,7 @@ class SubtreeManagerTest { } @Test fun `render restarts child after tearing down`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() fun render() = manager.render(workflow, "props", key = "", handler = { fail() }) .also { manager.commitRenderedChildren() } @@ -138,7 +138,7 @@ class SubtreeManagerTest { } @Test fun `render throws on duplicate key`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() manager.render(workflow, "props", "foo", handler = { fail() }) @@ -152,7 +152,7 @@ class SubtreeManagerTest { } @Test fun `render returns child rendering`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() val (composeProps, composeState) = manager.render( @@ -163,7 +163,7 @@ class SubtreeManagerTest { } @Test fun `tick children handles child output`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() val handler: StringHandler = { output -> action { setOutput("case output:$output") } @@ -181,13 +181,13 @@ class SubtreeManagerTest { eventHandler("event!") val update = tickOutput.await()!!.value - val (_, output) = update.applyTo("state") + val (_, output) = update.applyTo("props", "state") assertEquals("case output:workflow output:event!", output?.value) } } @Test fun `render updates child's output handler`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = TestWorkflow() fun render(handler: StringHandler) = manager.render(workflow, "props", key = "", handler = handler) @@ -199,7 +199,7 @@ class SubtreeManagerTest { .let { rendering -> rendering.eventHandler("initial output") val initialAction = manager.tickAction()!!.value - val (_, initialOutput) = initialAction.applyTo("") + val (_, initialOutput) = initialAction.applyTo("", "") assertEquals("initial handler: workflow output:initial output", initialOutput?.value) } @@ -208,7 +208,7 @@ class SubtreeManagerTest { .let { rendering -> rendering.eventHandler("second output") val secondAction = manager.tickAction()!!.value - val (_, secondOutput) = secondAction.applyTo("") + val (_, secondOutput) = secondAction.applyTo("", "") assertEquals("second handler: workflow output:second output", secondOutput?.value) } } @@ -216,7 +216,7 @@ class SubtreeManagerTest { // See https://github.com/square/workflow/issues/404 @Test fun `createChildSnapshot snapshots eagerly`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = SnapshotTestWorkflow() assertEquals(0, workflow.snapshots) @@ -229,7 +229,7 @@ class SubtreeManagerTest { // See https://github.com/square/workflow/issues/404 @Test fun `createChildSnapshot serializes lazily`() { - val manager = subtreeManagerForTest() + val manager = subtreeManagerForTest() val workflow = SnapshotTestWorkflow() assertEquals(0, workflow.serializes) @@ -244,9 +244,9 @@ class SubtreeManagerTest { assertEquals(1, workflow.serializes) } - private suspend fun SubtreeManager.tickAction() = - select>?> { tickChildren(this) } + private suspend fun SubtreeManager.tickAction() = + select>?> { tickChildren(this) } - private fun subtreeManagerForTest() = - SubtreeManager(emptyMap(), context, emitActionToParent = { WorkflowOutput(it) }) + private fun subtreeManagerForTest() = + SubtreeManager(emptyMap(), context, emitActionToParent = { WorkflowOutput(it) }) } diff --git a/workflow-runtime/src/test/java/com/squareup/workflow/internal/WorkflowNodeTest.kt b/workflow-runtime/src/test/java/com/squareup/workflow/internal/WorkflowNodeTest.kt index 9cfee7a3cd..be0b1efddd 100644 --- a/workflow-runtime/src/test/java/com/squareup/workflow/internal/WorkflowNodeTest.kt +++ b/workflow-runtime/src/test/java/com/squareup/workflow/internal/WorkflowNodeTest.kt @@ -102,7 +102,7 @@ class WorkflowNodeTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { return """ props:$props @@ -182,7 +182,7 @@ class WorkflowNodeTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { sink = context.makeEventSink { setOutput(it) } return "" @@ -220,7 +220,7 @@ class WorkflowNodeTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { sink = context.makeEventSink { setOutput(it) } return "" @@ -247,7 +247,7 @@ class WorkflowNodeTest { } @Test fun `send allows subsequent events on same rendering`() { - lateinit var sink: Sink> + lateinit var sink: Sink> val workflow = object : StringWorkflow() { override fun initialState( props: String, @@ -260,7 +260,7 @@ class WorkflowNodeTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { sink = context.actionSink return "" @@ -290,7 +290,7 @@ class WorkflowNodeTest { override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { context.runningWorker(channel.asWorker()) { check(update == null) @@ -344,18 +344,18 @@ class WorkflowNodeTest { return props } - fun update(value: String) = action { + fun update(value: String) = action { setOutput("update:$value") } - val finish = action { + val finish = action { state = "finished" } override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): String { when (state) { "listen" -> { @@ -1057,15 +1057,15 @@ class WorkflowNodeTest { @Test fun `interceptor handles render()`() { lateinit var interceptedProps: String lateinit var interceptedState: String - lateinit var interceptedContext: RenderContext<*, *> + lateinit var interceptedContext: RenderContext<*, *, *> lateinit var interceptedRendering: String lateinit var interceptedSession: WorkflowSession val interceptor = object : WorkflowInterceptor { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R { interceptedProps = props as String @@ -1190,8 +1190,8 @@ class WorkflowNodeTest { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R = "[${proceed("[$props]" as P, "[$state]" as S, context)}]" as R } @@ -1245,8 +1245,8 @@ class WorkflowNodeTest { } @Test fun `send fails before render pass completed`() { - class TestAction : WorkflowAction { - override fun Updater.apply() = fail("Expected sink send to fail.") + class TestAction : WorkflowAction { + override fun Updater.apply() = fail("Expected sink send to fail.") override fun toString(): String = "TestAction()" } diff --git a/workflow-rx2/src/test/java/com/squareup/workflow/rx2/PublisherWorkerTest.kt b/workflow-rx2/src/test/java/com/squareup/workflow/rx2/PublisherWorkerTest.kt index 8b2d3bb961..48b068b9ac 100644 --- a/workflow-rx2/src/test/java/com/squareup/workflow/rx2/PublisherWorkerTest.kt +++ b/workflow-rx2/src/test/java/com/squareup/workflow/rx2/PublisherWorkerTest.kt @@ -36,7 +36,7 @@ class PublisherWorkerTest { override fun doesSameWorkAs(otherWorker: Worker<*>): Boolean = otherWorker === this } - fun action(value: String) = action { setOutput(value) } + fun action(value: String) = action { setOutput(value) } val workflow = Workflow.stateless { runningWorker(worker) { action(it) } } diff --git a/workflow-testing/src/main/java/com/squareup/workflow/testing/RealRenderTester.kt b/workflow-testing/src/main/java/com/squareup/workflow/testing/RealRenderTester.kt index 741340a669..36e1128f84 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow/testing/RealRenderTester.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow/testing/RealRenderTester.kt @@ -38,11 +38,11 @@ internal class RealRenderTester( private val expectations: MutableList> = mutableListOf(), private val consumedExpectations: MutableList> = mutableListOf(), private var childWillEmitOutput: Boolean = false, - private var processedAction: WorkflowAction? = null + private var processedAction: WorkflowAction? = null ) : RenderTester, - RenderContext, - RenderTestResult, - Sink> { + RenderContext, + RenderTestResult, + Sink> { internal sealed class Expectation { open val output: WorkflowOutput? = null @@ -64,7 +64,7 @@ internal class RealRenderTester( data class ExpectedSideEffect(val key: String) : Expectation() } - override val actionSink: Sink> get() = this + override val actionSink: Sink> get() = this override fun expectWorkflow( workflowType: KClass>, @@ -106,7 +106,7 @@ internal class RealRenderTester( return this } - override fun render(block: (RenderingT) -> Unit): RenderTestResult { + override fun render(block: (RenderingT) -> Unit): RenderTestResult { // Clone the expectations to run a "dry" render pass. val noopContext = deepCloneForRender() workflow.render(props, state, noopContext) @@ -129,7 +129,7 @@ internal class RealRenderTester( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT { val expected = consumeExpectedChildWorkflow>( predicate = { it.workflowType.isInstance(child) && it.key == key }, @@ -156,7 +156,7 @@ internal class RealRenderTester( override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { val expected = consumeExpectedWorker>( predicate = { it.matchesWhen(worker) && it.key == key }, @@ -182,7 +182,7 @@ internal class RealRenderTester( consumeExpectedSideEffect(key) { "sideEffect with key \"$key\"" } } - override fun send(value: WorkflowAction) { + override fun send(value: WorkflowAction) { checkNoOutputs() check(processedAction == null) { "Tried to send action to sink after another action was already processed:\n" + @@ -192,14 +192,14 @@ internal class RealRenderTester( processedAction = value } - override fun verifyAction(block: (WorkflowAction) -> Unit) { + override fun verifyAction(block: (WorkflowAction) -> Unit) { val action = processedAction ?: noAction() block(action) } override fun verifyActionResult(block: (newState: StateT, output: WorkflowOutput?) -> Unit) { verifyAction { - val (state, output) = it.applyTo(state) + val (state, output) = it.applyTo(props, state) block(state, output) } } @@ -274,7 +274,7 @@ internal class RealRenderTester( } } - private fun deepCloneForRender(): RenderContext = RealRenderTester( + private fun deepCloneForRender(): RenderContext = RealRenderTester( workflow, props, state, // Copy the list of expectations since it's mutable. expectations = ArrayList(expectations), diff --git a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderIdempotencyChecker.kt b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderIdempotencyChecker.kt index 73f8d26319..776fea3d9c 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderIdempotencyChecker.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderIdempotencyChecker.kt @@ -37,8 +37,8 @@ object RenderIdempotencyChecker : WorkflowInterceptor { override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R { val recordingContext = RecordingRenderContext(context) @@ -59,9 +59,9 @@ object RenderIdempotencyChecker : WorkflowInterceptor { * A [RenderContext] that can record the result of rendering children over a render pass, and then * play them back over a second render pass that doesn't actually perform any actions. */ -private class RecordingRenderContext( - private val delegate: RenderContext -) : RenderContext { +private class RecordingRenderContext( + private val delegate: RenderContext +) : RenderContext { private var replaying = false @@ -75,9 +75,9 @@ private class RecordingRenderContext( replaying = false } - override val actionSink: Sink> = - object : Sink> { - override fun send(value: WorkflowAction) { + override val actionSink: Sink> = + object : Sink> { + override fun send(value: WorkflowAction) { if (!replaying) { delegate.actionSink.send(value) } // Else noop @@ -90,7 +90,7 @@ private class RecordingRenderContext( child: Workflow, props: ChildPropsT, key: String, - handler: (ChildOutputT) -> WorkflowAction + handler: (ChildOutputT) -> WorkflowAction ): ChildRenderingT = if (!replaying) { delegate.renderChild(child, props, key, handler) .also { childRenderings.addFirst(it) } @@ -102,7 +102,7 @@ private class RecordingRenderContext( override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { if (!replaying) { delegate.runningWorker(worker, key, handler) diff --git a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTestResult.kt b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTestResult.kt index 63e4218c3d..9cc04c5746 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTestResult.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTestResult.kt @@ -25,7 +25,7 @@ import com.squareup.workflow.WorkflowOutput * @see verifyAction * @see verifyActionResult */ -interface RenderTestResult { +interface RenderTestResult { /** * Asserts that the render pass handled either a workflow/worker output or a rendering event, and @@ -36,7 +36,7 @@ interface RenderTestResult { * This is useful if your actions are a sealed class or enum. If you need to test an anonymous * action, use [verifyActionResult]. */ - fun verifyAction(block: (WorkflowAction) -> Unit) + fun verifyAction(block: (WorkflowAction) -> Unit) /** * Asserts that the render pass handled either a workflow/worker output or a rendering event, diff --git a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTester.kt b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTester.kt index 04de6ced3b..d9b09ed34a 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTester.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow/testing/RenderTester.kt @@ -280,7 +280,7 @@ interface RenderTester { * @return A [RenderTestResult] that can be used to verify the [WorkflowAction] that was used to * handle a workflow or worker output or a rendering event. */ - fun render(block: (rendering: RenderingT) -> Unit = {}): RenderTestResult + fun render(block: (rendering: RenderingT) -> Unit = {}): RenderTestResult } /** diff --git a/workflow-testing/src/test/java/com/squareup/workflow/TreeWorkflow.kt b/workflow-testing/src/test/java/com/squareup/workflow/TreeWorkflow.kt index 7b9f083bc7..acce3ea5be 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow/TreeWorkflow.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow/TreeWorkflow.kt @@ -53,7 +53,7 @@ internal class TreeWorkflow( override fun render( props: String, state: String, - context: RenderContext + context: RenderContext ): Rendering { val childRenderings = children .mapIndexed { index, child -> diff --git a/workflow-testing/src/test/java/com/squareup/workflow/WorkerCompositionIntegrationTest.kt b/workflow-testing/src/test/java/com/squareup/workflow/WorkerCompositionIntegrationTest.kt index 4ad718b995..438c7830d2 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow/WorkerCompositionIntegrationTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow/WorkerCompositionIntegrationTest.kt @@ -196,7 +196,7 @@ class WorkerCompositionIntegrationTest { @Test fun `runningWorker handler closes over latest state`() { val triggerOutput = WorkerSink("") - val incrementState = action { + val incrementState = action { state += 1 } diff --git a/workflow-testing/src/test/java/com/squareup/workflow/WorkerStressTest.kt b/workflow-testing/src/test/java/com/squareup/workflow/WorkerStressTest.kt index 0c867bce85..d3b06155d5 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow/WorkerStressTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow/WorkerStressTest.kt @@ -32,7 +32,7 @@ class WorkerStressTest { .asWorker() .transform { it.onCompletion { emit(Unit) } } } - val action = action { setOutput(Unit) } + val action = action { setOutput(Unit) } val workflow = Workflow.stateless { // Run lots of workers that will all see the same close event. workers.forEachIndexed { i, worker -> @@ -72,7 +72,7 @@ class WorkerStressTest { @Suppress("DEPRECATION") val workers = List(WORKER_COUNT) { channel.asWorker() } - val action = action { setOutput(1) } + val action = action { setOutput(1) } val workflow = Workflow.stateless { // Run lots of workers that will all see the same conflated channel value. workers.forEachIndexed { i, worker -> @@ -101,7 +101,7 @@ class WorkerStressTest { @Suppress("DEPRECATION") val workers = List(WORKER_COUNT) { flow.asWorker() } - val action = action { setOutput(1) } + val action = action { setOutput(1) } val workflow = Workflow.stateless { // Run lots of workers that will all see the same conflated channel value. workers.forEachIndexed { i, worker -> diff --git a/workflow-testing/src/test/java/com/squareup/workflow/WorkflowCompositionIntegrationTest.kt b/workflow-testing/src/test/java/com/squareup/workflow/WorkflowCompositionIntegrationTest.kt index 3db302688b..1d519e9b18 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow/WorkflowCompositionIntegrationTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow/WorkflowCompositionIntegrationTest.kt @@ -106,7 +106,7 @@ class WorkflowCompositionIntegrationTest { val child = Workflow.stateless { runningWorker(triggerChildOutput) { action { setOutput(Unit) } } } - val incrementState = action { + val incrementState = action { state += 1 } val workflow = Workflow.stateful Unit>( diff --git a/workflow-testing/src/test/java/com/squareup/workflow/testing/RealRenderTesterTest.kt b/workflow-testing/src/test/java/com/squareup/workflow/testing/RealRenderTesterTest.kt index 80e0a19b6d..71542d598d 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow/testing/RealRenderTesterTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow/testing/RealRenderTesterTest.kt @@ -235,8 +235,8 @@ class RealRenderTesterTest { } @Test fun `sending to sink throws when called multiple times`() { - class TestAction(private val name: String) : WorkflowAction { - override fun Updater.apply() {} + class TestAction(private val name: String) : WorkflowAction { + override fun Updater.apply() {} override fun toString(): String = "TestAction($name)" } @@ -264,8 +264,8 @@ class RealRenderTesterTest { } @Test fun `sending to sink throws when child output expected`() { - class TestAction : WorkflowAction { - override fun Updater.apply() {} + class TestAction : WorkflowAction { + override fun Updater.apply() {} } val workflow = Workflow.stateful>( @@ -389,7 +389,7 @@ class RealRenderTesterTest { class Child : OutputNothingChild, StatelessWorkflow() { override fun render( props: Unit, - context: RenderContext + context: RenderContext ) { // Nothing to do. } @@ -571,7 +571,7 @@ class RealRenderTesterTest { val child = object : OutputNothingChild, StatelessWorkflow() { override fun render( props: Unit, - context: RenderContext + context: RenderContext ) { // Do nothing. } @@ -603,8 +603,8 @@ class RealRenderTesterTest { assertEquals("bad props: wrong props", error.message) } - private class TestAction(val name: String) : WorkflowAction { - override fun Updater.apply() {} + private class TestAction(val name: String) : WorkflowAction { + override fun Updater.apply() {} override fun toString(): String = "TestAction($name)" } @@ -705,8 +705,8 @@ class RealRenderTesterTest { } @Test fun `verifyActionResult handles new state and output`() { - class TestAction : WorkflowAction { - override fun Updater.apply() { + class TestAction : WorkflowAction { + override fun Updater.apply() { state = "new state" setOutput("output") } diff --git a/workflow-tracing/src/main/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptor.kt b/workflow-tracing/src/main/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptor.kt index 37ceb3f480..548fff5eaf 100644 --- a/workflow-tracing/src/main/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptor.kt +++ b/workflow-tracing/src/main/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptor.kt @@ -220,8 +220,8 @@ class TracingWorkflowInterceptor internal constructor( override fun onRender( props: P, state: S, - context: RenderContext, - proceed: (P, S, RenderContext) -> R, + context: RenderContext, + proceed: (P, S, RenderContext) -> R, session: WorkflowSession ): R { if (session.parent == null) { @@ -442,7 +442,7 @@ class TracingWorkflowInterceptor internal constructor( private fun onSinkReceived( workflowId: Long, - action: WorkflowAction<*, *> + action: WorkflowAction<*, *, *> ) { val name = workflowNamesById.getValue(workflowId) logger?.log( @@ -497,7 +497,7 @@ class TracingWorkflowInterceptor internal constructor( private fun onWorkflowAction( workflowId: Long, - action: WorkflowAction<*, *>, + action: WorkflowAction<*, *, *>, oldState: Any?, newState: Any?, output: WorkflowOutput? @@ -549,13 +549,13 @@ class TracingWorkflowInterceptor internal constructor( workerIdCounter++.toLong() .shl(32) xor session.sessionId - private inner class TracingRenderContext( - private val delegate: RenderContext, + private inner class TracingRenderContext( + private val delegate: RenderContext, private val session: WorkflowSession - ) : RenderContext by delegate, Sink> { - override val actionSink: Sink> get() = this + ) : RenderContext by delegate, Sink> { + override val actionSink: Sink> get() = this - override fun send(value: WorkflowAction) { + override fun send(value: WorkflowAction) { onSinkReceived(session.sessionId, value) val wrapperAction = TracingAction(value, session) delegate.actionSink.send(wrapperAction) @@ -564,7 +564,7 @@ class TracingWorkflowInterceptor internal constructor( override fun runningWorker( worker: Worker, key: String, - handler: (T) -> WorkflowAction + handler: (T) -> WorkflowAction ) { val wrappedWorker = TracingWorker(session, worker, key) delegate.runningWorker(wrappedWorker, key) { output -> @@ -573,13 +573,13 @@ class TracingWorkflowInterceptor internal constructor( } } - private inner class TracingAction( - private val delegate: WorkflowAction, + private inner class TracingAction( + private val delegate: WorkflowAction, private val session: WorkflowSession - ) : WorkflowAction { - override fun Updater.apply() { + ) : WorkflowAction { + override fun Updater.apply() { val oldState = state - val (newState, output) = delegate.applyTo(state) + val (newState, output) = delegate.applyTo(props, state) state = newState output?.let { setOutput(it.value) } onWorkflowAction( diff --git a/workflow-tracing/src/test/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptorTest.kt b/workflow-tracing/src/test/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptorTest.kt index 3908fef091..982f14559f 100644 --- a/workflow-tracing/src/test/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptorTest.kt +++ b/workflow-tracing/src/test/java/com/squareup/workflow/diagnostic/tracing/TracingWorkflowInterceptorTest.kt @@ -159,7 +159,7 @@ class TracingWorkflowInterceptorTest { override fun render( props: Int, state: String, - context: RenderContext + context: RenderContext ): String { if (props == 0) return "initial" if (props in 1..6) context.renderChild(this, 0) { bubbleUp(it) }