예제 #1
0
        public void ReturnsValue_WhenValueIsSetInConstructor()
        {
            var testee = new Missable <string>(Value);

            testee.Value
            .Should().Be(Value);
        }
예제 #2
0
        protected void DoFire(TEvent eventId, object eventArgument)
        {
            this.AssertThatStateMachineIsInitialized();

            var fired = false;

            foreach (var pair in GetTransitionsToFire(eventId, eventArgument))
            {
                var transition = pair.Item1;
                var context    = pair.Item2;

                DoFire(transition, context);

                fired = true;
            }

            if (!fired)
            {
                var missableEventId = new Missable <TEvent>(eventId);

                foreach (
                    var context in
                    this.currentStates.Select(
                        state => this.factory.CreateTransitionContext(state, missableEventId, eventArgument)))
                {
                    this.OnTransitionDeclined(context);
                }
            }
        }
예제 #3
0
        private IEnumerable <Tuple <ITransition <TState, TEvent>, ITransitionContext <TState, TEvent> > > GetTransitionsToFire
            (TEvent eventId, object eventArgument)
        {
            var missableEventId = new Missable <TEvent>(eventId);

            var stateArray    = this.currentStates.OrderByDescending(s => s.Level).ThenBy(s => s.Id).ToArray();
            var levels        = stateArray.Select(s => s == null ? 0 : s.Level).ToArray();
            var eventConsumed = stateArray.Select(s => false).ToArray();
            var contexts      =
                stateArray.Select(s => this.factory.CreateTransitionContext(s, missableEventId, eventArgument))
                .ToArray();

            var start = 0;
            var end   = stateArray.Count() - 1;

            for (var targetLevel = levels[start] - 1;
                 start <= end && targetLevel >= 0;
                 targetLevel--)
            {
                // Invariant: At this point, the states list, from index "start",
                // is ordered by descending level and then by state id.

                // Delete duplicates at the start of the list.
                while (start < end && stateArray[start] == stateArray[start + 1])
                {
                    eventConsumed[start + 1] = eventConsumed[start] || eventConsumed[start + 1];
                    start++;
                }

                // Invariant: At this point, the states list, from index "start",
                // is still ordered by descending level and then by state id.

                // For the first state and all the states at the same level,
                // visit the state and replace it in the list with its superstate.
                for (var index = start;
                     index <= end && levels[index] == targetLevel + 1;
                     index++)
                {
                    var currentState = stateArray[index];

                    if (!eventConsumed[index])
                    {
                        var newTransition = GetTransitionToFire(currentState, contexts[index]);
                        if (newTransition != null)
                        {
                            eventConsumed[index] = true;
                            yield return(Tuple.Create(newTransition, contexts[index]));
                        }
                    }

                    stateArray[index] = currentState.SuperState;
                    levels[index]--;
                }

                // Invariant: At this point, the states list, from index "start",
                // is ordered by descending level and then by state id.
            }
        }
예제 #4
0
        public void ThrowsExceptionOnAccessingValue_WhenValueIsNotSet()
        {
            var testee = new Missable <string>();

            // ReSharper disable once UnusedVariable
            Action action = () => { string v = testee.Value; };

            action.ShouldThrow <InvalidOperationException>()
            .WithMessage("*missing*");
        }
예제 #5
0
 public virtual ITransitionContext <TState, TEvent> CreateTransitionContext(IState <TState, TEvent> state, Missable <TEvent> eventId, object eventArgument, INotifier <TState, TEvent> notifier)
 {
     return(new TransitionContext <TState, TEvent>(state, eventId, eventArgument, notifier));
 }
예제 #6
0
        public void ReturnsNotMissing_WhenValueIsSetInConstructor()
        {
            var testee = new Missable <string>(Value);

            testee.IsMissing.Should().BeFalse();
        }
예제 #7
0
        public void ReturnsMissing_WhenNoValueIsSet()
        {
            var testee = new Missable <string>();

            testee.IsMissing.Should().BeTrue();
        }