Skip to content

Change to a chain-able RenderTester API #16

Closed
@bencochran

Description

@bencochran

As described in square/workflow#702, we should move to a chain-able RenderTester API.

Benefits:

  1. 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).

  2. 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 of expectWorkflow(type:…).

  3. 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

  1. 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.

  2. Our WorkflowActionTester uses assert in its method names. Kotlin’s RenderTester uses verify. We should probably consolidate all of these to either assert or verify across the board.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions