Skip to content

Commit

Permalink
[chore]: clarify some testing behaviors (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamieQ authored Oct 13, 2022
1 parent 998c080 commit 37f52d7
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 8 deletions.
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
20 changes: 20 additions & 0 deletions WorkflowReactiveSwift/Testing/SignalProducerWorkflowTesting.swift
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

0 comments on commit 37f52d7

Please sign in to comment.