Beispiel #1
0
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)
}
Beispiel #2
0
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)
}
Beispiel #3
0
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)
}
Beispiel #4
0
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)
}
Beispiel #5
0
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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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
}
Beispiel #8
0
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")
}
Beispiel #9
0
func (s *StateMachineSuite) TestCreateStateMachineSetsInitialStatus(c *C) {
	stateMachine := sm.NewStateMachine(statusClosed, func(b sm.Builder) {})
	c.Assert(stateMachine.Status(), Equals, statusClosed)
}