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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ let package = Package(
dependencies: ["Workflow"],
path: "Workflow/Tests"
),
.testTarget(
name: "WorkflowTestingTests",
dependencies: ["WorkflowTesting"],
path: "WorkflowTesting/Tests"
),
.target(
name: "WorkflowUI",
dependencies: ["Workflow"],
Expand Down Expand Up @@ -116,6 +121,11 @@ let package = Package(
dependencies: ["WorkflowReactiveSwift", "WorkflowTesting"],
path: "WorkflowReactiveSwift/Testing"
),
.testTarget(
name: "WorkflowReactiveSwiftTestingTests",
dependencies: ["WorkflowReactiveSwiftTesting"],
path: "WorkflowReactiveSwift/TestingTests"
),
.target(
name: "WorkflowCombineTesting",
dependencies: ["WorkflowCombine", "WorkflowTesting"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
///
/// `SignalProducerWorkflow` is used to subscribe to `SignalProducer`s and `Signal`s.
///
/// ⚠️ N.B. If you are testing a case in which multiple `SignalProducerWorkflow`s are expected, **only one of them** may have a non-nil `producingOutput` parameter.
///
/// - Parameters:
/// - producingOutput: An output that should be returned when this worker is requested, if any.
/// - key: Key to expect this `Workflow` to be rendered with.
Expand All @@ -41,5 +43,23 @@
assertions: { _ in }
)
}

/// Expect a `SignalProducer` with the specified `outputType` that produces no `Output`.
///
/// - Parameters:
/// - outputType: The `OutputType` of the expected `SignalProducerWorkflow`.
/// - key: Key to expect this `Workflow` to be rendered with.
public func expectSignalProducer<OutputType>(
outputType: OutputType.Type,
key: String = "",
file: StaticString = #file, line: UInt = #line
) -> RenderTester<WorkflowType> {
expectWorkflow(
type: SignalProducerWorkflow<OutputType>.self,
key: key,
producingRendering: (),
assertions: { _ in }
)
}
}
#endif
36 changes: 31 additions & 5 deletions WorkflowReactiveSwift/TestingTests/SignalProducerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,47 @@ import WorkflowReactiveSwiftTesting
import XCTest

class SignalProducerTests: XCTestCase {
func testSignalProducerWorkflow() {
func test_signalProducerWorkflow() {
TestWorkflow()
.renderTester()
.expectSignalProducer(producingOutput: 1, key: "123")
.render {}
}

struct TestWorkflow: Workflow {
func test_multipleChildSignalProducerWorkflows() {
TestWorkflow(childKeys: ["123", "456"])
.renderTester()
.expectSignalProducer(
// value is arbitrary, but needed to specify the output type
producingOutput: 42,
key: "123"
)
.expectSignalProducer(
producingOutput: nil as Int?,
key: "456"
)
.render {}
}

func test_signalProducerWorkflow_noOutput() {
TestWorkflow()
.renderTester()
.expectSignalProducer(outputType: Int.self, key: "123")
.render {}
}

private struct TestWorkflow: Workflow {
typealias State = Void
typealias Rendering = Void

var childKeys: [String] = ["123"]

func render(state: State, context: RenderContext<Self>) -> Rendering {
SignalProducer(value: 1)
.mapOutput { _ in AnyWorkflowAction<TestWorkflow>.noAction }
.running(in: context, key: "123")
for key in childKeys {
SignalProducer(value: 1)
.mapOutput { _ in AnyWorkflowAction<TestWorkflow>.noAction }
.running(in: context, key: key)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@
} else if sameKeyDifferentTypes.count > 1 {
diagnosticMessage = "Found expectations for types \(sameKeyDifferentTypes) with key \"\(key)\"."
} else {
diagnosticMessage = ""
diagnosticMessage = """
If this child Workflow is expected, please add a call to `expectWorkflow(...)` with the appropriate parameters before invoking `render()`.
"""
}
XCTFail("Unexpected workflow of type \(Child.self) with key \"\(key)\". \(diagnosticMessage)", file: file, line: line)

Expand Down
6 changes: 5 additions & 1 deletion WorkflowTesting/Sources/WorkflowRenderTester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@
/// type: ChildWorkflow.self,
/// key: "key",
/// rendering: "rendering",
/// producingOutput: ChildWorkflow.Output.success
/// // ⚠️ N.B. Only one output per call to `render` may be produced,
/// // even if multiple child Workflows are expected in a call
/// // to `render`. This is an invariant enforced by `RenderTester`
/// // and the real runtime.
/// producingOutput: nil
/// )
/// .render { rendering in
/// XCTAssertEqual("expected text on rendering", rendering.text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ final class WorkflowRenderTesterFailureTests: XCTestCase {
let tester = TestWorkflow()
.renderTester(initialState: .voidWorkflow)

expectingFailure(#"Unexpected workflow of type VoidWorkflow with key """#) {
expectingFailure(#"Unexpected workflow of type VoidWorkflow with key "". If this child Workflow is expected, please add a call to `expectWorkflow(...)` with the appropriate parameters before invoking `render()`."#) {
tester.render { _ in }
}
}
Expand Down