Skip to content

Commit

Permalink
Minor refactoring by sonarcloud warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
nsk90 committed Feb 10, 2024
1 parent 2c393ae commit 9c718c6
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 109 deletions.
2 changes: 0 additions & 2 deletions buildSrc/src/main/kotlin/ru/nsk/Versions.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import org.gradle.api.JavaVersion

object Versions {
// library
const val libraryMavenCentralGroup = "io.github.nsk90"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,7 @@ open class BaseStateImpl(override val name: String?, override val childMode: Chi

when (childMode) {
EXCLUSIVE -> {
val initialState = checkNotNull(initialState) {
"Initial state is not set, call setInitialState() first"
}
val initialState = requireInitialState() as InternalState
setCurrentState(initialState, transitionParams)
if (initialState !is StateMachine) // inner state machine manages its internal state by its own
initialState.recursiveEnterInitialStates(transitionParams)
Expand Down Expand Up @@ -255,8 +253,6 @@ open class BaseStateImpl(override val name: String?, override val childMode: Chi
data.states.forEachState { it.recursiveAfterTransitionComplete(transitionParams) }
}

private fun requireCurrentState() = requireNotNull(data.currentState) { "Current state is not set" }

override fun getCurrentStates() = when (childMode) {
EXCLUSIVE -> listOfNotNull(data.currentState)
PARALLEL -> data.states.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ inline fun <reified E : Event> TransitionBuilder<E>.isEqual() = object : EventMa
}

fun finishedEventMatcher(state: IState) = object : EventMatcher<FinishedEvent>(FinishedEvent::class) {
override suspend fun match(value: Event) = if (value is FinishedEvent) value.state === state else false
override suspend fun match(value: Event) = value is FinishedEvent && value.state === state
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ interface HistoryState : PseudoState {

typealias StateBlock<S> = S.() -> Unit

fun IState.requireInitialState() = checkNotNull(initialState) {
"Initial state is not set, call setInitialState() first"
}

/**
* Set of states that the state is currently in. Including state itself if [selfIncluding] is true.
* Internal states of nested machines are not included.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ internal class StateMachineImpl(
check(!isRunning) { "$this is already started" }
check(!isProcessingEvent) { "$this is already processing event, this is internal error, please report a bug" }
if (childMode == ChildMode.EXCLUSIVE)
checkNotNull(initialState) { "Initial state is not set, call setInitialState() first" }
requireInitialState()
}

/** To be called only from [runCheckingExceptions] */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ private suspend fun EventAndArgument<*>.recursiveResolveTargetState(targetState:
}
}

/**
* Internal use only. TODO remove it when possible
*/
internal fun unresolvedTargetState(targetState: IState): TransitionDirection = TargetState(setOf(targetState))

/**
Expand Down Expand Up @@ -154,9 +151,7 @@ private fun IState.findInitialPseudoState(): PseudoState? {
if (states.isEmpty()) return null
when (childMode) {
ChildMode.EXCLUSIVE -> {
val initialState = checkNotNull(initialState) {
"Initial state is not set, call setInitialState() first"
}
val initialState = requireInitialState()
return if (initialState !is StateMachine) // inner state machine manages its internal state by its own
initialState.findInitialPseudoState()
else
Expand All @@ -173,7 +168,7 @@ private fun IState.findInitialPseudoState(): PseudoState? {
return if (initialStates.isEmpty())
null
else
initialStates.first() // fixme take first or other else??
initialStates.first() // take first or other else?
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,51 @@ state1 --> state222
@enduml
"""

private fun makeNestedMachine(coroutineStarterType: CoroutineStarterType): StateMachine {
return createTestStateMachine(coroutineStarterType, name = "Nested states") {
val state1 = initialState("State1")
val state3 = finalState("State3")

val state2 = state("State2") {
transition<SwitchEvent> { targetState = state3 }
transition<SwitchEvent>("back") { targetState = state1 }

val finalSubState = finalState("Final subState")
initialState("Initial subState") {
transition<SwitchEvent> { targetState = finalSubState }
}
}

state1 {
transition<SwitchEvent>("to ${state2.name}") { targetState = state2 }
transition<SwitchEvent> { targetState = this@state1 }
transition<SwitchEvent>()
}
}
}

private fun makeChoiceMachine(coroutineStarterType: CoroutineStarterType): StateMachine {
return createTestStateMachine(coroutineStarterType, enableUndo = true) {
val state1 = initialState("state1")

val state2 = state("state2") {
initialState("state21") {
initialState("state211")
}
state("state22")
}
val shallowHistory = state2.historyState("shallow history")
val deepHistory = state2.historyState("deep history", historyType = DEEP)

state("state3") {
transition<FirstEvent>(targetState = shallowHistory)
transition<SecondEvent>(targetState = deepHistory)
}
choiceState("choice") { state1 }
finalState("final")
}
}

class ExportToPlantUmlTest : StringSpec({
CoroutineStarterType.entries.forEach { coroutineStarterType ->
table(
Expand All @@ -194,53 +239,13 @@ class ExportToPlantUmlTest : StringSpec({
row(true, PLANTUML_NESTED_STATES_SHOW_EVENT_LABELS_RESULT),
).forAll { showEventLabels, result ->
"plantUml export nested states" {
val machine = createTestStateMachine(coroutineStarterType, name = "Nested states") {
val state1 = initialState("State1")
val state3 = finalState("State3")

val state2 = state("State2") {
transition<SwitchEvent> { targetState = state3 }
transition<SwitchEvent>("back") { targetState = state1 }

val finalSubState = finalState("Final subState")
initialState("Initial subState") {
transition<SwitchEvent> { targetState = finalSubState }
}
}

state1 {
transition<SwitchEvent>("to ${state2.name}") { targetState = state2 }
transition<SwitchEvent> { targetState = this@state1 }
transition<SwitchEvent>()
}
}

val machine = makeNestedMachine(coroutineStarterType)
machine.exportToPlantUml(showEventLabels) shouldBe result
}
}

"Mermaid export nested states" {
val machine = createTestStateMachine(coroutineStarterType, name = "Nested states") {
val state1 = initialState("State1")
val state3 = finalState("State3")

val state2 = state("State2") {
transition<SwitchEvent> { targetState = state3 }
transition<SwitchEvent>("back") { targetState = state1 }

val finalSubState = finalState("Final subState")
initialState("Initial subState") {
transition<SwitchEvent> { targetState = finalSubState }
}
}

state1 {
transition<SwitchEvent>("to ${state2.name}") { targetState = state2 }
transition<SwitchEvent> { targetState = this@state1 }
transition<SwitchEvent>()
}
}

val machine = makeNestedMachine(coroutineStarterType)
machine.exportToMermaid() shouldBe MERMAID_NESTED_STATES_RESULT
}

Expand Down Expand Up @@ -276,50 +281,12 @@ class ExportToPlantUmlTest : StringSpec({
}

"plantUml export with pseudo states" {
val machine = createTestStateMachine(coroutineStarterType, enableUndo = true) {
val state1 = initialState("state1")

val state2 = state("state2") {
initialState("state21") {
initialState("state211")
}
state("state22")
}
val shallowHistory = state2.historyState("shallow history")
val deepHistory = state2.historyState("deep history", historyType = DEEP)

state("state3") {
transition<FirstEvent>(targetState = shallowHistory)
transition<SecondEvent>(targetState = deepHistory)
}
choiceState("choice") { state1 }
finalState("final")
}

val machine = makeChoiceMachine(coroutineStarterType)
machine.exportToPlantUml() shouldBe PLANTUML_PSEUDO_STATES_RESULT
}

"plantUml unsafe export with pseudo states" {
val machine = createTestStateMachine(coroutineStarterType, enableUndo = true) {
val state1 = initialState("state1")

val state2 = state("state2") {
initialState("state21") {
initialState("state211")
}
state("state22")
}
val shallowHistory = state2.historyState("shallow history")
val deepHistory = state2.historyState("deep history", historyType = DEEP)

state("state3") {
transition<FirstEvent>(targetState = shallowHistory)
transition<SecondEvent>(targetState = deepHistory)
}
choiceState("choice") { state1 }
finalState("final")
}

val machine = makeChoiceMachine(coroutineStarterType)
machine.exportToPlantUml(unsafeCallConditionalLambdas = true) shouldBe PLANTUML_UNSAFE_PSEUDO_STATES_RESULT
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ListenerExceptionHandlerTest : StringSpec({
logger = StateMachine.Logger { println(it()) }

initialState {
onEntry { testError("test exception") }
onEntry { testError() }
}
}
}
Expand All @@ -23,7 +23,7 @@ class ListenerExceptionHandlerTest : StringSpec({
"default ListenerExceptionHandler rethrows exception from state onEntry() on manual start() call" {
val machine = createTestStateMachine(coroutineStarterType, start = false) {
initialState {
onEntry { testError("test exception") }
onEntry { testError() }
}
}

Expand All @@ -38,7 +38,7 @@ class ListenerExceptionHandlerTest : StringSpec({
val machine = createTestStateMachine(coroutineStarterType, start = false) {
onStarted { callbacks.onStarted(this) }
callbacks.listen(this)
onEntry { testError("test exception") }
onEntry { testError() }

state1 = initialState {
callbacks.listen(this)
Expand All @@ -56,7 +56,7 @@ class ListenerExceptionHandlerTest : StringSpec({
"default ListenerExceptionHandler rethrows exception from onStarted() on start() call" {
shouldThrow<TestException> {
createTestStateMachine(coroutineStarterType) {
onStarted { testError("test exception") }
onStarted { testError() }

initialState()
}
Expand All @@ -68,7 +68,7 @@ class ListenerExceptionHandlerTest : StringSpec({
val machine = createTestStateMachine(coroutineStarterType, start = false) {
initialState()
state2 = state {
onEntry { testError("test exception") }
onEntry { testError() }
}
}

Expand All @@ -79,7 +79,7 @@ class ListenerExceptionHandlerTest : StringSpec({
"default ListenerExceptionHandler rethrows exception from stop()" {
val machine = createTestStateMachine(coroutineStarterType) {
initialState()
onStopped { testError("test exception") }
onStopped { testError() }
}

shouldThrow<TestException> { machine.stopBlocking() }
Expand All @@ -94,7 +94,7 @@ class ListenerExceptionHandlerTest : StringSpec({
listenerExceptionHandler = handlerMock

initialState {
onEntry { testError("test exception") }
onEntry { testError() }
}
}

Expand All @@ -113,7 +113,7 @@ class ListenerExceptionHandlerTest : StringSpec({
val state2 = state()
initialState {
transition<SwitchEvent> {
guard = { testError("test exception") }
guard = { testError() }
targetState = state2
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.collections.containExactlyInAnyOrder
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.should
import io.mockk.verify
import io.mockk.verifySequence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import io.kotest.data.headers
import io.kotest.data.row
import io.kotest.data.table
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
import io.kotest.matchers.comparables.shouldBeLessThan
import io.kotest.matchers.shouldBe
import io.mockk.called
import io.mockk.verify
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fun verifySequenceAndClear(mock: Any, verifyBlock: MockKVerificationScope.() ->
clearMocks(mock, answers = false)
}

fun testError(message: String): Nothing {
fun testError(message: String = "test exception"): Nothing {
throw TestException(message)
}

Expand Down

0 comments on commit 9c718c6

Please sign in to comment.