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
1 change: 1 addition & 0 deletions workflow-testing/api/workflow-testing.api
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public abstract class com/squareup/workflow1/testing/RenderTester {
public static synthetic fun expectSideEffect$default (Lcom/squareup/workflow1/testing/RenderTester;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow1/testing/RenderTester;
public abstract fun render (Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow1/testing/RenderTestResult;
public static synthetic fun render$default (Lcom/squareup/workflow1/testing/RenderTester;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow1/testing/RenderTestResult;
public abstract fun requireExplicitSideEffectExpectations ()Lcom/squareup/workflow1/testing/RenderTester;
public abstract fun requireExplicitWorkerExpectations ()Lcom/squareup/workflow1/testing/RenderTester;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ internal class RealRenderTester<PropsT, StateT, OutputT, RenderingT>(
}

private var explicitWorkerExpectationsRequired: Boolean = false
private var explicitSideEffectExpectationsRequired: Boolean = false
override val actionSink: Sink<WorkflowAction<PropsT, StateT, OutputT>> get() = this

override fun expectWorkflow(
Expand Down Expand Up @@ -125,6 +126,11 @@ internal class RealRenderTester<PropsT, StateT, OutputT, RenderingT>(
expectWorker(description = "unexpected worker", exactMatch = false) { _, _, _ -> true }
}

if (!explicitSideEffectExpectationsRequired) {
// Allow unexpected side effects.
expectSideEffect(description = "unexpected side effect", exactMatch = false) { true }
}

// Clone the expectations to run a "dry" render pass.
val noopContext = deepCloneForRender()
workflow.render(props, state, RenderContext(noopContext, workflow))
Expand Down Expand Up @@ -251,6 +257,11 @@ internal class RealRenderTester<PropsT, StateT, OutputT, RenderingT>(
explicitWorkerExpectationsRequired = true
}

override fun requireExplicitSideEffectExpectations():
RenderTester<PropsT, StateT, OutputT, RenderingT> = this.apply {
explicitSideEffectExpectationsRequired = true
}

override fun send(value: WorkflowAction<PropsT, StateT, OutputT>) {
checkNoOutputs()
check(processedAction == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ public abstract class RenderTester<PropsT, StateT, OutputT, RenderingT> {
public abstract fun requireExplicitWorkerExpectations():
RenderTester<PropsT, StateT, OutputT, RenderingT>

public abstract fun requireExplicitSideEffectExpectations():
RenderTester<PropsT, StateT, OutputT, RenderingT>

/**
* Describes a call to
* [RenderContext.renderChild][com.squareup.workflow1.BaseRenderContext.renderChild].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ internal class RealRenderTesterTest {
runningSideEffect("the key") {}
}
val tester = workflow.testRender(Unit)
.requireExplicitSideEffectExpectations()
.expectSideEffect(key = "the key")
.expectSideEffect(description = "duplicate match") { it == "the key" }

Expand Down Expand Up @@ -326,7 +327,7 @@ internal class RealRenderTesterTest {
val workflow = Workflow.stateless<Unit, Nothing, Unit> {
runningSideEffect("effect") {}
}
val tester = workflow.testRender(Unit)
val tester = workflow.testRender(Unit).requireExplicitSideEffectExpectations()

val error = assertFailsWith<AssertionError> {
tester.render()
Expand All @@ -340,6 +341,7 @@ internal class RealRenderTesterTest {
runningSideEffect("unexpected") {}
}
val tester = workflow.testRender(Unit)
.requireExplicitSideEffectExpectations()
.expectSideEffect("expected")

val error = assertFailsWith<AssertionError> {
Expand All @@ -353,6 +355,7 @@ internal class RealRenderTesterTest {
runningSideEffect("effect") {}
}
val tester = workflow.testRender(Unit)
.requireExplicitSideEffectExpectations()
.expectSideEffect("effect")
.expectSideEffect(description = "custom", exactMatch = true) { key -> "effect" in key }

Expand Down Expand Up @@ -546,6 +549,30 @@ internal class RealRenderTesterTest {
tester.render()
}

@Test fun `runningSideEffect doesn't throw when none expected`() {
val workflow = Workflow.stateless<Unit, Nothing, Unit> {
runningSideEffect(key = "foo") { }
}
val tester = workflow.testRender(Unit)
tester.render()
}

@Test fun `runningSideEffect does throw when none expected and require explicit side effect is set`() { // ktlint-disable max-line-length
val key = "foo"
val workflow = Workflow.stateless<Unit, Nothing, Unit> {
runningSideEffect(key = key) { }
}
val tester = workflow.testRender(Unit).requireExplicitSideEffectExpectations()
val error = assertFailsWith<AssertionError> {
tester.render()
}

assertEquals(
"Tried to run unexpected side effect with key \"$key\"",
error.message
)
}

@Test fun `runningWorker does throw when none expected and require explicit workers is set`() {
class MySpecialWorker : Worker<Nothing> {
override fun doesSameWorkAs(otherWorker: Worker<*>): Boolean = true
Expand Down