mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-16 14:57:54 +00:00
[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,
|
requestState: RequestState,
|
||||||
slotState: SlotState,
|
slotState: SlotState,
|
||||||
restoredFromChain: bool): SalesAgent =
|
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(@[
|
let agent = SalesAgent.new(@[
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleUnknown(),
|
saleUnknown,
|
||||||
SaleDownloading.new(),
|
saleDownloading,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
let agent = SalesAgent(m)
|
let agent = SalesAgent(m)
|
||||||
agent.requestState.value == RequestState.New and
|
agent.requestState.value == RequestState.New and
|
||||||
@ -25,25 +35,25 @@ proc newSalesAgent*(sales: Sales,
|
|||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
@[
|
@[
|
||||||
SaleUnknown(),
|
saleUnknown,
|
||||||
SaleDownloading(),
|
saleDownloading,
|
||||||
SaleProving(),
|
saleProving,
|
||||||
SaleFilling(),
|
saleFilling,
|
||||||
SaleFilled()
|
saleFilled
|
||||||
],
|
],
|
||||||
SaleCancelled.new(),
|
saleCancelled,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
SalesAgent(m).requestState.value == RequestState.Cancelled
|
SalesAgent(m).requestState.value == RequestState.Cancelled
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
@[
|
@[
|
||||||
SaleUnknown.new(),
|
saleUnknown,
|
||||||
SaleDownloading.new(),
|
saleDownloading,
|
||||||
SaleProving.new(),
|
saleProving,
|
||||||
SaleFilling.new(),
|
saleFilling,
|
||||||
SaleFilled.new()
|
saleFilled
|
||||||
],
|
],
|
||||||
SaleFailed.new(),
|
saleFailed,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
let agent = SalesAgent(m)
|
let agent = SalesAgent(m)
|
||||||
agent.requestState.value == RequestState.Failed or
|
agent.requestState.value == RequestState.Failed or
|
||||||
@ -51,22 +61,22 @@ proc newSalesAgent*(sales: Sales,
|
|||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
@[
|
@[
|
||||||
SaleUnknown.new(),
|
saleUnknown,
|
||||||
SaleDownloading.new(),
|
saleDownloading,
|
||||||
SaleFilling.new(),
|
saleFilling,
|
||||||
SaleProving.new()
|
saleProving
|
||||||
],
|
],
|
||||||
SaleFilled.new(),
|
saleFilled,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
SalesAgent(m).slotState.value == SlotState.Filled
|
SalesAgent(m).slotState.value == SlotState.Filled
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
@[
|
@[
|
||||||
SaleUnknown.new(),
|
saleUnknown,
|
||||||
SaleDownloading.new(),
|
saleDownloading,
|
||||||
SaleFilling.new(),
|
saleFilling,
|
||||||
SaleFilled.new(),
|
saleFilled,
|
||||||
SaleProving.new()
|
saleProving
|
||||||
],
|
],
|
||||||
SaleFinished.new(),
|
SaleFinished.new(),
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
@ -76,24 +86,24 @@ proc newSalesAgent*(sales: Sales,
|
|||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
AnyState.new(),
|
AnyState.new(),
|
||||||
SaleErrored.new(),
|
saleErrored,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
SalesAgent(m).errored.value
|
SalesAgent(m).errored.value
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleDownloading.new(),
|
saleDownloading,
|
||||||
SaleProving.new(),
|
saleProving,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
SalesAgent(m).downloaded.value
|
SalesAgent(m).downloaded.value
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleProving.new(),
|
saleProving,
|
||||||
SaleFilling.new(),
|
saleFilling,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
SalesAgent(m).proof.value.len > 0 # TODO: proof validity check?
|
SalesAgent(m).proof.value.len > 0 # TODO: proof validity check?
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleFilled.new(),
|
saleFilled,
|
||||||
SaleFinished.new(),
|
SaleFinished.new(),
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
let agent = SalesAgent(m)
|
let agent = SalesAgent(m)
|
||||||
@ -102,8 +112,8 @@ proc newSalesAgent*(sales: Sales,
|
|||||||
host == agent.me
|
host == agent.me
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleFilled.new(),
|
saleFilled,
|
||||||
SaleErrored.new(),
|
saleErrored,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
let agent = SalesAgent(m)
|
let agent = SalesAgent(m)
|
||||||
without host =? agent.slotHost.value:
|
without host =? agent.slotHost.value:
|
||||||
@ -115,8 +125,8 @@ proc newSalesAgent*(sales: Sales,
|
|||||||
else: return false
|
else: return false
|
||||||
),
|
),
|
||||||
Transition.new(
|
Transition.new(
|
||||||
SaleUnknown.new(),
|
saleUnknown,
|
||||||
SaleErrored.new(),
|
saleErrored,
|
||||||
proc(m: Machine, s: State): bool =
|
proc(m: Machine, s: State): bool =
|
||||||
let agent = SalesAgent(m)
|
let agent = SalesAgent(m)
|
||||||
if agent.restoredFromChain and agent.slotState.value == SlotState.Free:
|
if agent.restoredFromChain and agent.slotState.value == SlotState.Free:
|
||||||
|
@ -60,7 +60,7 @@ proc checkTransitions(machine: Machine) =
|
|||||||
if transition.trigger(machine, machine.state) and
|
if transition.trigger(machine, machine.state) and
|
||||||
machine.state != transition.nextState and # avoid transitioning to self
|
machine.state != transition.nextState and # avoid transitioning to self
|
||||||
(machine.state == nil or
|
(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)):
|
transition.prevStates.any(proc (s: State): bool = s of AnyState)):
|
||||||
machine.schedule(Event.transition(machine.state, transition.nextState))
|
machine.schedule(Event.transition(machine.state, transition.nextState))
|
||||||
|
|
||||||
|
@ -206,3 +206,32 @@ suite "async state machines":
|
|||||||
check machine.state of State4
|
check machine.state of State4
|
||||||
check checked
|
check checked
|
||||||
#3->5 transition was checked but not run because state had already moved to 4
|
#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…
x
Reference in New Issue
Block a user