public void StartOnInstantiation()
    {
        TestStateMachine stateMachine = new TestStateMachine();

        stateMachine.StartOnInstantiation = true;

        Assert.Throws <StateMachineStoppedException>(() => stateMachine.GetState());
        Assert.That(stateMachine.IsStarted(), Is.EqualTo(false));
        stateMachine.Start();
        Assert.That(stateMachine.GetState(), Is.EqualTo(StateMachineTestStates.Initial));
        Assert.That(stateMachine.IsStarted(), Is.EqualTo(true));
    }
    public void ChangeState()
    {
        TestStateMachine stateMachine = new TestStateMachine();

        stateMachine.Start();
        stateMachine.StartMachine();
        Assert.That(stateMachine.GetState(), Is.EqualTo(StateMachineTestStates.Initial));
        stateMachine.ChangeState(StateMachineTestStates.State);
        Assert.That(stateMachine.GetState(), Is.EqualTo(StateMachineTestStates.State));
        stateMachine.StopMachine();
        stateMachine.StartMachine();
        Assert.That(stateMachine.GetState(), Is.EqualTo(StateMachineTestStates.Initial));
    }
        public void StateHistoryTrim()
        {
            var sm = new TestStateMachine();

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<CountingState>();
            sm.State<CountingState>()
                .On(TelephoneTrigger.HangingUp).GoesTo<IdleState>();

            sm.Start();

            // Transition a lot of times
            for (int a = 0;a<1000;a++)
            {
                sm.Trigger(TelephoneTrigger.PickingUpPhone);
                sm.Trigger(TelephoneTrigger.HangingUp);
            }

            // The state history should be 90-100 items
            Assert.IsTrue((sm.StateHistory.Length >= 90) && (sm.StateHistory.Length <= 100),
                          string.Format("{0} states in history", sm.StateHistory.Length));

            sm.StateHistoryTrimThreshold = 50;

            // The state history should be 45-50 items
            Assert.IsTrue((sm.StateHistory.Length >= 45) && (sm.StateHistory.Length <= 50),
                          string.Format("{0} states in history", sm.StateHistory.Length));
        }
        public void StopCallsExit()
        {
            var sm = new TestStateMachine();

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<CountingState>();
            sm.State<CountingState>()
                .On(TelephoneTrigger.HangingUp).GoesTo<IdleState>();

            sm.Start();

            sm.Trigger(TelephoneTrigger.PickingUpPhone);
            sm.Trigger(TelephoneTrigger.HangingUp);
            sm.Trigger(TelephoneTrigger.PickingUpPhone);

            Assert.IsTrue((sm.EnteringCount == 2) && (sm.ExitingCount == 1), "Unexpected EnteringCount / ExitingCount!");

            sm.Stop();

            Assert.IsTrue((sm.EnteringCount == 2) && (sm.ExitingCount == 2), "Unexpected EnteringCount / ExitingCount on Stop!");
        }
        public void InstantiateStatePerTransition()
        {
            var sm = new TestStateMachine();
            sm.StateInstantiationMode = StateInstantiationMode.PerTransition;

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<CountingState>();
            sm.State<CountingState>()
                .On(TelephoneTrigger.HangingUp).GoesTo<IdleState>();

            sm.Start();

            // Goto CountingState
            sm.Trigger(TelephoneTrigger.PickingUpPhone);
            // Go back
            sm.Trigger(TelephoneTrigger.HangingUp);
            // Goto CountingState again
            sm.Trigger(TelephoneTrigger.PickingUpPhone);

            // The CurrentState should have been freshly created, meaning that CountingState.EnteringSelfCount should be 1
            Assert.IsTrue(
                (sm.CurrentState is CountingState) && ((sm.CurrentState as CountingState).EnteringSelfCount == 1),
                string.Format("Unexpected EnteringSelfCount!"));

        }
        public void VerifyStateSingletons()
        {
            var sm = new TestStateMachine();
            // No setting of the value here, Singleton should be the default.

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<CountingState>();
            sm.State<CountingState>()
                .On(TelephoneTrigger.HangingUp).GoesTo<IdleState>();

            sm.Start();

            // Goto CountingState
            sm.Trigger(TelephoneTrigger.PickingUpPhone);
            // Go back
            sm.Trigger(TelephoneTrigger.HangingUp);
            // Goto CountingState again
            sm.Trigger(TelephoneTrigger.PickingUpPhone);

            // The CurrentState should have been freshly created, meaning that CountingState.EnteringSelfCount should be 1
            Assert.IsTrue(
                (sm.CurrentState is CountingState) && ((sm.CurrentState as CountingState).EnteringSelfCount == 2),
                string.Format("Unexpected EnteringSelfCount!"));

        }
        public void ConfigurationReentrantState()
        {
            var sm = new TestStateMachine();

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<CountingState>();

            sm.State<CountingState>()
                .On(TelephoneTrigger.DialedNumber).GoesTo<CountingState>()
                .On(TelephoneTrigger.HangingUp).GoesTo<IdleState>();

            sm.Start();

            // Goto CountingState, EnteringCount should be 1
            sm.Trigger(TelephoneTrigger.PickingUpPhone);
            Assert.IsTrue(sm.EnteringCount == 1, "EnteringCount != 1");

            // Reentry
            sm.Trigger(TelephoneTrigger.DialedNumber);
            Assert.IsTrue((sm.EnteringCount == 2) && (sm.ExitingCount == 1), "EnteringCount != 2 || ExitingCount != 1");

            // Back to Idle
            sm.Trigger(TelephoneTrigger.HangingUp);
            Assert.IsTrue((sm.EnteringCount == 2) && (sm.ExitingCount == 2), "EnteringCount != 2 || ExitingCount != 2");
        }
        public void UsingImplicitContext()
        {
            var sm = new TestStateMachine();
            sm.CurrentDate = DateTime.MinValue.Date;

            sm.State<IdleState>()
                .On(TelephoneTrigger.PickingUpPhone).GoesTo<DateReportingState>();
            sm.Start();

            sm.Trigger(TelephoneTrigger.PickingUpPhone);

            // The state should've been able to use the default context (the state machine) to set its CurrentDate property
            Assert.IsTrue(sm.CurrentDate.Equals(DateTime.Now.Date), "Wrong date in state machine!");
        }