[statemachine] add additional tests
- test for multiple source states - test for not allowing transition to self
This commit is contained in:
parent
c80e3e5e2c
commit
24ad3fdea9
|
@ -14,10 +14,20 @@ proc newSalesAgent*(sales: Sales,
|
|||
requestState: RequestState,
|
||||
slotState: SlotState,
|
||||
restoredFromChain: bool): SalesAgent =
|
||||
|
||||
let saleUnknown = SaleUnknown.new()
|
||||
let saleDownloading = SaleDownloading.new()
|
||||
let saleProving = SaleProving.new()
|
||||
let saleFilling = SaleFilling.new()
|
||||
let saleFilled = SaleFilled.new()
|
||||
let saleCancelled = SaleCancelled.new()
|
||||
let saleFailed = SaleFailed.new()
|
||||
let saleErrored = SaleErrored.new()
|
||||
|
||||
let agent = SalesAgent.new(@[
|
||||
Transition.new(
|
||||
SaleUnknown(),
|
||||
SaleDownloading.new(),
|
||||
saleUnknown,
|
||||
saleDownloading,
|
||||
proc(m: Machine, s: State): bool =
|
||||
let agent = SalesAgent(m)
|
||||
agent.requestState.value == RequestState.New and
|
||||
|
@ -25,25 +35,25 @@ proc newSalesAgent*(sales: Sales,
|
|||
),
|
||||
Transition.new(
|
||||
@[
|
||||
SaleUnknown(),
|
||||
SaleDownloading(),
|
||||
SaleProving(),
|
||||
SaleFilling(),
|
||||
SaleFilled()
|
||||
saleUnknown,
|
||||
saleDownloading,
|
||||
saleProving,
|
||||
saleFilling,
|
||||
saleFilled
|
||||
],
|
||||
SaleCancelled.new(),
|
||||
saleCancelled,
|
||||
proc(m: Machine, s: State): bool =
|
||||
SalesAgent(m).requestState.value == RequestState.Cancelled
|
||||
),
|
||||
Transition.new(
|
||||
@[
|
||||
SaleUnknown.new(),
|
||||
SaleDownloading.new(),
|
||||
SaleProving.new(),
|
||||
SaleFilling.new(),
|
||||
SaleFilled.new()
|
||||
saleUnknown,
|
||||
saleDownloading,
|
||||
saleProving,
|
||||
saleFilling,
|
||||
saleFilled
|
||||
],
|
||||
SaleFailed.new(),
|
||||
saleFailed,
|
||||
proc(m: Machine, s: State): bool =
|
||||
let agent = SalesAgent(m)
|
||||
agent.requestState.value == RequestState.Failed or
|
||||
|
@ -51,22 +61,22 @@ proc newSalesAgent*(sales: Sales,
|
|||
),
|
||||
Transition.new(
|
||||
@[
|
||||
SaleUnknown.new(),
|
||||
SaleDownloading.new(),
|
||||
SaleFilling.new(),
|
||||
SaleProving.new()
|
||||
saleUnknown,
|
||||
saleDownloading,
|
||||
saleFilling,
|
||||
saleProving
|
||||
],
|
||||
SaleFilled.new(),
|
||||
saleFilled,
|
||||
proc(m: Machine, s: State): bool =
|
||||
SalesAgent(m).slotState.value == SlotState.Filled
|
||||
),
|
||||
Transition.new(
|
||||
@[
|
||||
SaleUnknown.new(),
|
||||
SaleDownloading.new(),
|
||||
SaleFilling.new(),
|
||||
SaleFilled.new(),
|
||||
SaleProving.new()
|
||||
saleUnknown,
|
||||
saleDownloading,
|
||||
saleFilling,
|
||||
saleFilled,
|
||||
saleProving
|
||||
],
|
||||
SaleFinished.new(),
|
||||
proc(m: Machine, s: State): bool =
|
||||
|
@ -76,24 +86,24 @@ proc newSalesAgent*(sales: Sales,
|
|||
),
|
||||
Transition.new(
|
||||
AnyState.new(),
|
||||
SaleErrored.new(),
|
||||
saleErrored,
|
||||
proc(m: Machine, s: State): bool =
|
||||
SalesAgent(m).errored.value
|
||||
),
|
||||
Transition.new(
|
||||
SaleDownloading.new(),
|
||||
SaleProving.new(),
|
||||
saleDownloading,
|
||||
saleProving,
|
||||
proc(m: Machine, s: State): bool =
|
||||
SalesAgent(m).downloaded.value
|
||||
),
|
||||
Transition.new(
|
||||
SaleProving.new(),
|
||||
SaleFilling.new(),
|
||||
saleProving,
|
||||
saleFilling,
|
||||
proc(m: Machine, s: State): bool =
|
||||
SalesAgent(m).proof.value.len > 0 # TODO: proof validity check?
|
||||
),
|
||||
Transition.new(
|
||||
SaleFilled.new(),
|
||||
saleFilled,
|
||||
SaleFinished.new(),
|
||||
proc(m: Machine, s: State): bool =
|
||||
let agent = SalesAgent(m)
|
||||
|
@ -102,8 +112,8 @@ proc newSalesAgent*(sales: Sales,
|
|||
host == agent.me
|
||||
),
|
||||
Transition.new(
|
||||
SaleFilled.new(),
|
||||
SaleErrored.new(),
|
||||
saleFilled,
|
||||
saleErrored,
|
||||
proc(m: Machine, s: State): bool =
|
||||
let agent = SalesAgent(m)
|
||||
without host =? agent.slotHost.value:
|
||||
|
@ -115,8 +125,8 @@ proc newSalesAgent*(sales: Sales,
|
|||
else: return false
|
||||
),
|
||||
Transition.new(
|
||||
SaleUnknown.new(),
|
||||
SaleErrored.new(),
|
||||
saleUnknown,
|
||||
saleErrored,
|
||||
proc(m: Machine, s: State): bool =
|
||||
let agent = SalesAgent(m)
|
||||
if agent.restoredFromChain and agent.slotState.value == SlotState.Free:
|
||||
|
|
|
@ -60,7 +60,7 @@ proc checkTransitions(machine: Machine) =
|
|||
if transition.trigger(machine, machine.state) and
|
||||
machine.state != transition.nextState and # avoid transitioning to self
|
||||
(machine.state == nil or
|
||||
machine.state in transition.prevStates or
|
||||
machine.state in transition.prevStates or # state instance, multiple
|
||||
transition.prevStates.any(proc (s: State): bool = s of AnyState)):
|
||||
machine.schedule(Event.transition(machine.state, transition.nextState))
|
||||
|
||||
|
|
|
@ -206,3 +206,32 @@ suite "async state machines":
|
|||
check machine.state of State4
|
||||
check checked
|
||||
#3->5 transition was checked but not run because state had already moved to 4
|
||||
|
||||
test "allows source transition to include multiple states":
|
||||
machine = MyMachine.new(@[
|
||||
Transition.new(
|
||||
@[
|
||||
state3,
|
||||
state4
|
||||
],
|
||||
state5,
|
||||
proc(m: Machine, s: State): bool = true
|
||||
)]
|
||||
)
|
||||
machine.start(state3)
|
||||
check eventually runs == [0, 0, 1, 0, 1]
|
||||
machine.schedule(Event.transition(state5, state4))
|
||||
check eventually runs == [0, 0, 1, 1, 2]
|
||||
check machine.state of State5
|
||||
|
||||
test "does not allow transitioning to the state it's already on":
|
||||
machine = MyMachine.new(@[
|
||||
Transition.new(
|
||||
AnyState.new(),
|
||||
state4,
|
||||
proc(m: Machine, s: State): bool = true
|
||||
)]
|
||||
)
|
||||
machine.start(state4)
|
||||
check eventually runs == [0, 0, 0, 0, 0]
|
||||
check machine.state.isNil
|
||||
|
|
Loading…
Reference in New Issue