From d052ccd39e022ff95eaa57494d823b16d8b5abf7 Mon Sep 17 00:00:00 2001 From: Jeremy Mawson Date: Wed, 23 Oct 2024 07:33:07 +1000 Subject: [PATCH] Add kdoc to transitioner and $value to invalid state transition error messages --- .../kotlin/app/cash/kfsm/InvalidStateTransition.kt | 2 +- lib/src/main/kotlin/app/cash/kfsm/Transitioner.kt | 10 ++++++++++ .../kotlin/app/cash/kfsm/InvalidStateTransitionTest.kt | 4 ++-- .../test/kotlin/app/cash/kfsm/TransitionerAsyncTest.kt | 2 +- lib/src/test/kotlin/app/cash/kfsm/TransitionerTest.kt | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/src/main/kotlin/app/cash/kfsm/InvalidStateTransition.kt b/lib/src/main/kotlin/app/cash/kfsm/InvalidStateTransition.kt index d4399ee..4197b14 100644 --- a/lib/src/main/kotlin/app/cash/kfsm/InvalidStateTransition.kt +++ b/lib/src/main/kotlin/app/cash/kfsm/InvalidStateTransition.kt @@ -3,5 +3,5 @@ package app.cash.kfsm class InvalidStateTransition(transition: Transition<*, *>, value: Value<*, *>) : Exception( "Value cannot transition ${ transition.from.set.toList().sortedBy { it.toString() }.joinToString(", ", prefix = "{", postfix = "}") - } to ${transition.to}, because it is currently ${value.state}" + } to ${transition.to}, because it is currently ${value.state}. [value=$value]" ) diff --git a/lib/src/main/kotlin/app/cash/kfsm/Transitioner.kt b/lib/src/main/kotlin/app/cash/kfsm/Transitioner.kt index b714c5b..de3d972 100644 --- a/lib/src/main/kotlin/app/cash/kfsm/Transitioner.kt +++ b/lib/src/main/kotlin/app/cash/kfsm/Transitioner.kt @@ -2,12 +2,22 @@ package app.cash.kfsm abstract class Transitioner, V : Value, S : State> { + /** Will be executed prior to the transition effect. Failure here will terminate the transition */ open fun preHook(value: V, via: T): Result = Result.success(Unit) + /** Will be executed after the transition effect. Use this to persist the value. */ open fun persist(value: V, via: T): Result = Result.success(value) + /** Will be executed after the transition effect & value persistence. Use this to perform side effects such as notifications. */ open fun postHook(from: S, value: V, via: T): Result = Result.success(Unit) + /** + * Execute the given transition on the given value. + * + * If the target state is already present, then this is a no-op. + * If the provided transition cannot apply to the value's state, then this is a failure. + * Otherwise, the transition is applied and the state is updated in the returned value. + */ fun transition( value: V, transition: T diff --git a/lib/src/test/kotlin/app/cash/kfsm/InvalidStateTransitionTest.kt b/lib/src/test/kotlin/app/cash/kfsm/InvalidStateTransitionTest.kt index fb0a958..769ee79 100644 --- a/lib/src/test/kotlin/app/cash/kfsm/InvalidStateTransitionTest.kt +++ b/lib/src/test/kotlin/app/cash/kfsm/InvalidStateTransitionTest.kt @@ -6,11 +6,11 @@ import io.kotest.matchers.shouldBe class InvalidStateTransitionTest : StringSpec({ "with single from-state has correct message" { InvalidStateTransition(LetterTransition(A, B), Letter(E)).message shouldBe - "Value cannot transition {A} to B, because it is currently E" + "Value cannot transition {A} to B, because it is currently E. [value=Letter(state=E)]" } "with many from-states has correct message" { InvalidStateTransition(LetterTransition(States(C, B), D), Letter(E)).message shouldBe - "Value cannot transition {B, C} to D, because it is currently E" + "Value cannot transition {B, C} to D, because it is currently E. [value=Letter(state=E)]" } }) diff --git a/lib/src/test/kotlin/app/cash/kfsm/TransitionerAsyncTest.kt b/lib/src/test/kotlin/app/cash/kfsm/TransitionerAsyncTest.kt index 7a50126..103c997 100644 --- a/lib/src/test/kotlin/app/cash/kfsm/TransitionerAsyncTest.kt +++ b/lib/src/test/kotlin/app/cash/kfsm/TransitionerAsyncTest.kt @@ -61,7 +61,7 @@ class TransitionerAsyncTest : StringSpec({ val transitioner = transitioner() transitioner.transition(Letter(C), transition).shouldBeFailure() - .shouldHaveMessage("Value cannot transition {A} to B, because it is currently C") + .shouldHaveMessage("Value cannot transition {A} to B, because it is currently C. [value=Letter(state=C)]") transitioner.preHookExecuted shouldBe 0 transition.effected shouldBe 0 diff --git a/lib/src/test/kotlin/app/cash/kfsm/TransitionerTest.kt b/lib/src/test/kotlin/app/cash/kfsm/TransitionerTest.kt index 1160960..085ea09 100644 --- a/lib/src/test/kotlin/app/cash/kfsm/TransitionerTest.kt +++ b/lib/src/test/kotlin/app/cash/kfsm/TransitionerTest.kt @@ -61,7 +61,7 @@ class TransitionerTest : StringSpec({ val transitioner = transitioner() transitioner.transition(Letter(C), transition).shouldBeFailure() - .shouldHaveMessage("Value cannot transition {A} to B, because it is currently C") + .shouldHaveMessage("Value cannot transition {A} to B, because it is currently C. [value=Letter(state=C)]") transitioner.preHookExecuted shouldBe 0 transition.effected shouldBe 0