func (s *StateMachineSuite) TestActionPreventingStatusChange(c *C) { stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, func(args []interface{}) bool { return false }) }) c.Assert(stateMachine.Trigger(eventOpen), Equals, false) }
func (s *StateMachineSuite) TestSingleTransitionEventsNoAction(c *C) { stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, sm.NoAction) b.Event(eventClose, statusOpened, statusClosed, sm.NoAction) }) c.Assert(stateMachine.Trigger(eventOpen), Equals, true) c.Assert(stateMachine.Status(), Equals, statusOpened) c.Assert(stateMachine.Trigger(eventClose), Equals, true) c.Assert(stateMachine.Status(), Equals, statusClosed) }
func (s *StateMachineSuite) TestSetTriggerValidator(c *C) { stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, sm.NoAction) b.Event(eventClose, statusOpened, statusClosed, sm.NoAction) }) stateMachine.SetTriggerValidator(func(oldStatus, newStatus sm.Status, args ...interface{}) bool { return args[0].(bool) }) c.Assert(stateMachine.Trigger(eventOpen, false), Equals, false) c.Assert(stateMachine.Status(), Equals, statusClosed) c.Assert(stateMachine.Trigger(eventClose, true), Equals, false) }
func (s *StateMachineSuite) TestMultiTransitionEvents(c *C) { stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, sm.NoAction) b.Event(eventClose, statusOpened, statusClosed, sm.NoAction) b.Event(eventLock, func(b sm.Builder) { b.Transition(statusClosed, statusLocked, sm.NoAction) b.Transition(statusOpened, statusLockedOpen, sm.NoAction) }) }) c.Assert(stateMachine.Trigger(eventLock), Equals, true) c.Assert(stateMachine.Status(), Equals, statusLocked) }
func setupTeammateStateMachine(teammate *Teammate, status sm.Status) *sm.StateMachine { // trigger arguments: <teammate>, [taskUid] stateMachine := sm.NewStateMachine(status, func(b sm.Builder) { b.Event(EventSignIn, StatusSignedOut, StatusOnBreak, sm.NoAction) b.Event(EventGoOnBreak, func(b sm.Builder) { b.Transition(StatusWaiting, StatusOnBreak, sm.NoAction) b.Transition(StatusWrappingUp, StatusOnBreak, sm.NoAction) b.Transition(StatusOffered, StatusOnBreak, sm.NoAction) b.Transition(StatusOtherWork, StatusOnBreak, sm.NoAction) }) b.Event(EventSignOut, func(b sm.Builder) { b.Transition(StatusOnBreak, StatusSignedOut, sm.NoAction) b.Transition(StatusWaiting, StatusSignedOut, sm.NoAction) }) b.Event(EventMakeAvailable, StatusOnBreak, StatusWaiting, sm.NoAction) b.Event(EventOfferTask, StatusWaiting, StatusOffered, func(args []interface{}) bool { teammate, taskUid := args[0].(*Teammate), args[1].(string) teammate.Update("TaskUid", taskUid) return true }) b.Event(EventAcceptTask, StatusOffered, StatusBusy, func(args []interface{}) bool { teammate, taskUid := args[0].(*Teammate), args[1].(string) if taskUid != teammate.TaskUid() { return false } return true }) wrapupTask := func(args []interface{}) bool { teammate, taskUid := args[0].(*Teammate), args[1].(string) if taskUid != teammate.TaskUid() { return false } teammate.Update("TaskUid", "") return true } b.Event(EventRejectTask, StatusOffered, StatusWaiting, wrapupTask) b.Event(EventFinishTask, StatusBusy, StatusWrappingUp, wrapupTask) b.Event(EventStartOtherWork, func(b sm.Builder) { b.Transition(StatusOnBreak, StatusOtherWork, sm.NoAction) b.Transition(StatusWaiting, StatusOtherWork, sm.NoAction) b.Transition(StatusWrappingUp, StatusOtherWork, sm.NoAction) }) }) stateMachine.SetTriggerValidator(func(oldStatus, newStatus sm.Status, args ...interface{}) bool { teammate := args[0].(*Teammate) accepted := teammate.store.SetStatus(KindTeammate, teammate.Uid(), oldStatus, newStatus) return accepted }) return stateMachine }
func (s *StateMachineSuite) TestTriggeringWithArguments(c *C) { var hello string var fortyTwo int stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, func(args []interface{}) bool { hello = args[0].(string) fortyTwo = args[1].(int) return true }) }) c.Assert(stateMachine.Trigger(eventOpen, "hello", 42), Equals, true) c.Assert(hello, Equals, "hello") c.Assert(fortyTwo, Equals, 42) }
func setupTaksStateMachine(task *Task, status sm.Status) *sm.StateMachine { stateMachine := sm.NewStateMachine(status, func(b sm.Builder) { b.Event(EventEnqueue, StatusCreated, StatusQueued, func(args []interface{}) bool { task, queueUid := args[0].(*Task), args[1].(string) task.Update("QueueUid", queueUid) task.Update("Created", time.Now().Unix()) return true }) b.Event(EventDequeue, StatusQueued, StatusCreated, func(args []interface{}) bool { task, queueUid := args[0].(*Task), args[1].(string) if queueUid != task.QueueUid() { return false } task.Update("QueueUid", "") task.Update("Created", int64(0)) return true }) b.Event(EventOffer, StatusQueued, StatusOffered, func(args []interface{}) bool { task, teammateUid := args[0].(*Task), args[1].(string) task.Update("TeammateUid", teammateUid) return true }) b.Event(EventRequeue, StatusOffered, StatusQueued, func(args []interface{}) bool { task := args[0].(*Task) task.Update("TeammateUid", "") return true }) b.Event(EventAssign, StatusOffered, StatusAssigned, func(args []interface{}) bool { task, teammateUid := args[0].(*Task), args[1].(string) if teammateUid != task.TeammateUid() { return false } return true }) b.Event(EventComplete, StatusAssigned, StatusCompleted, func(args []interface{}) bool { task := args[0].(*Task) task.Update("QueueUid", "") task.Update("TeammateUid", "") return true }) }) stateMachine.SetTriggerValidator(func(oldStatus, newStatus sm.Status, args ...interface{}) bool { task := args[0].(*Task) accepted := task.store.SetStatus(KindTask, task.Uid(), oldStatus, newStatus) return accepted }) return stateMachine }
func (s *StateMachineSuite) TestUniTransitionEventsWithAction(c *C) { state := "not set" stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) { b.Event(eventOpen, statusClosed, statusOpened, func(args []interface{}) bool { state = "opened" return true }) b.Event(eventClose, statusOpened, statusClosed, func(args []interface{}) bool { state = "closed" return true }) }) c.Assert(stateMachine.Trigger(eventOpen), Equals, true) c.Assert(state, Equals, "opened") c.Assert(stateMachine.Trigger(eventClose), Equals, true) c.Assert(state, Equals, "closed") }
func (s *StateMachineSuite) TestCreateStateMachineSetsInitialStatus(c *C) { stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) {}) c.Assert(stateMachine.Status(), Equals, statusClosed) }