diff --git a/swift/Workflow/Sources/WorkflowHost.swift b/swift/Workflow/Sources/WorkflowHost.swift index 0924068af..fa128704a 100644 --- a/swift/Workflow/Sources/WorkflowHost.swift +++ b/swift/Workflow/Sources/WorkflowHost.swift @@ -53,6 +53,19 @@ public final class WorkflowHost { } + /// Update the input for the workflow. Will cause a render pass. + public func update(workflow: WorkflowType) { + rootNode.update(workflow: workflow) + + // Treat the update as an "output" from the workflow as an external event to force a render pass. + let output = WorkflowNode.Output( + outputEvent: nil, + debugInfo: WorkflowUpdateDebugInfo( + workflowType: "\(WorkflowType.self)", + kind: .didUpdate(source: .external))) + handle(output: output) + } + private func handle(output: WorkflowNode.Output) { mutableRendering.value = rootNode.render() diff --git a/swift/Workflow/Tests/WorkflowHostTests.swift b/swift/Workflow/Tests/WorkflowHostTests.swift new file mode 100644 index 000000000..b8993baa8 --- /dev/null +++ b/swift/Workflow/Tests/WorkflowHostTests.swift @@ -0,0 +1,43 @@ +import XCTest +import Workflow + + +final class WorkflowHostTests: XCTestCase { + + func test_updatedInputCausesRenderPass() { + let host = WorkflowHost(workflow: TestWorkflow(step: .first)) + + XCTAssertEqual(1, host.rendering.value) + + host.update(workflow: TestWorkflow(step: .second)) + + XCTAssertEqual(2, host.rendering.value) + } + + fileprivate struct TestWorkflow: Workflow { + var step: Step + enum Step { + case first + case second + } + + struct State {} + func makeInitialState() -> State { + return State() + } + + func workflowDidChange(from previousWorkflow: TestWorkflow, state: inout State) { + } + + typealias Rendering = Int + + func render(state: State, context: RenderContext) -> Rendering { + switch self.step { + case .first: + return 1 + case .second: + return 2 + } + } + } +}