Description
As described in square/workflow#702, we should move to a chain-able RenderTester API.
Benefits:
-
Separate expectations during the render from verification of post-render state of the world
Our current
ExpectedState
is the trickiest of this IMO. It’s unclear from the API if this is asserts the state before the render or after it (it’s after). -
Extensibility
The current model, all expectations being passed in a single method, leaves us in an extensibility trap. When Workers become Workflows, it’s natural that ExpectedWorker is actually a wrapper around ExpectedWorkflow. We can do that from the same module without breaking the API, but if we move Worker out of the core module, we have to move worker expectations with it. By making expectations expressed as method calls, we can move the
expect(worker:…)
method to an extension and build it on top ofexpectWorkflow(type:…)
. -
Personally, I think it reads nicer
A chained API reads more easily as a story down a single column than what we have today where the actual types being expected are nested a few layers deep in a single call. (It also throws all of its implementation detail onto the API surface)
Example
NameLoadingWorkflow()
.renderTester(initialState: .init(state: .loading, token: "user-token"))
.expect(
worker: LoadingWorker(token: "user-token"),
producingOutput: .success("Ben Cochran")
)
.expectSideEffect(key: "some-extra-side-effect-just-for-fun")
.render { rendering in
XCTAssertEqual(rendering.title, "Loading")
}
.verify(
action: MyWorkflow.Action.loadSuccess(name: "Ben Cochran")
)
.verify(
output: .complete
)
Open Questions
-
Today, Swift’s RenderTester can be used across multiple renders (it updates its internal workflow state according to the actions produced in each render). Kotlin’s RenderTester does not allow this. We should probably decide which model we like and converge.
-
Our WorkflowActionTester uses
assert
in its method names. Kotlin’s RenderTester usesverify
. We should probably consolidate all of these to eitherassert
orverify
across the board.