Пример #1
0
        private static MarbleEventAssertionResultTable FillAssertionResultTable <TEvent>(
            Moment moment,
            Action <string, TEvent> assertion,
            IList <TEvent> received)
        {
            var table = new MarbleEventAssertionResultTable();

            foreach (var m in moment.Marbles)
            {
                var row = new List <MarbleEventAssertionResultTable.Result>();
                foreach (var @event in received)
                {
                    var(succeeded, exception, _, _) = CheckEvent(assertion, m, @event);
                    row.Add(new MarbleEventAssertionResultTable.Result(m, @event,
                                                                       succeeded ? string.Empty : exception.Message));
                }
                table.AddResultsRow(row);
            }
            return(table);
        }
Пример #2
0
        private static ExpectedMarble CreateUnorderedGroupExpectedMarble <TEvent>(
            Moment moment,
            Func <FSharpOption <TEvent> > eventProducer,
            Action <string, TEvent> assertion) =>
        new ExpectedMarble(
            moment.Time,
            moment.ToString(),
            () =>
        {
            var produced = moment.Marbles.Select(_ => eventProducer()).ToList();
            var received = produced.Where(FSharpOption <TEvent> .get_IsSome).Select(t => t.Value).ToList();
            if (received.Count != moment.Marbles.Length)
            {
                throw new Exception(
                    $"At time {moment.Time}, expecting an unordered group {moment} with {moment.Marbles.Length} elements but got {received.Count} events: [{string.Join(" ", received)}]");
            }

            var table   = FillAssertionResultTable(moment, assertion, received);
            var success = table.AllRowsAtLeastOneSuccess() && table.AllColumnsAtLeastOneSuccess();
            if (!success)
            {
                throw new Exception(table.ToString());
            }
        });
Пример #3
0
        private static IEnumerable <ExpectedMarble> CreateLooseExpectations <TEvent>(
            Moment moment,
            Func <FSharpOption <TEvent> > eventProducer,
            Action <string, TEvent> assertion)
        {
            var momentMarbles = new List <ExpectedMarble>();

            switch (moment.Type)
            {
            case Moment.MomentType.Empty:
                break;

            case Moment.MomentType.Single:
                var marble = moment.Marbles[0];
                momentMarbles.Add(CreateSingleLooselyExpectedMarble(moment, eventProducer, assertion, marble));
                break;

            case Moment.MomentType.OrderedGroup:
                momentMarbles.Add(CreateOrderedGroupLooselyExpectedMarble(moment, eventProducer, assertion));
                break;

            case Moment.MomentType.UnorderedGroup:
                momentMarbles.Add(CreateSingleLooselyExpectedMarble(moment, eventProducer, assertion, moment.ToString()));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            momentMarbles.Add(
                new ExpectedMarble(
                    moment.Time,
                    null,
                    () => ExhaustProducer(eventProducer)));
            return(momentMarbles);
        }
Пример #4
0
 private static IEnumerable <InputMarble> CreateInputMarbles(Moment moment, Func <string, Task> whatToDo) =>
 moment.Marbles.Select(marble => new InputMarble(moment.Time, marble, () => whatToDo(marble)));
Пример #5
0
 private static ExpectedMarble CreateOrderedGroupExpectedMarble <TEvent>(
     Moment moment,
     Func <FSharpOption <TEvent> > eventProducer,
     Action <string, TEvent> assertion) =>
Пример #6
0
 private static IEnumerable <ExpectedMarble> CreateAssertionExpectations(
     Moment moment,
     Action <string> assertion) =>
 moment.Marbles.Select(marble => new ExpectedMarble(moment.Time, marble, () => assertion(marble)));
        private static IEnumerable <Moment> ParseSequence(string sequence, out int?timeOffset)
        {
            var retVal    = new List <Moment>();
            var time      = 0;
            var groupTime = 0;

            timeOffset = null;
            List <string> groupMarbles          = null;
            List <string> unorderedGroupMarbles = null;
            var           parsingState          = ParsingState.NotInGroup;
            var           marbleTime            = 0;
            var           marbleBuilder         = new StringBuilder();

            foreach (var character in sequence.Trim())
            {
                if (parsingState == ParsingState.NotInGroup)
                {
                    switch (character)
                    {
                    case ' ':
                    case '-':
                        FlushMarble(marbleBuilder, retVal, marbleTime, time);
                        retVal.Add(Moment.Empty(time));
                        break;

                    case '^':
                        FlushMarble(marbleBuilder, retVal, marbleTime, time);
                        if (timeOffset.HasValue)
                        {
                            throw new ArgumentException("Only one ^ character allowed", nameof(sequence));
                        }
                        timeOffset = -time;
                        retVal.Add(Moment.Single(time, character.ToString()));
                        break;

                    case '(':
                        FlushMarble(marbleBuilder, retVal, marbleTime, time);
                        groupTime    = time;
                        parsingState = ParsingState.InOrderedGroup;
                        groupMarbles = new List <string>();
                        break;

                    case '<':
                        FlushMarble(marbleBuilder, retVal, marbleTime, time);
                        groupTime             = time;
                        parsingState          = ParsingState.InUnorderedGroup;
                        unorderedGroupMarbles = new List <string>();
                        break;

                    case ')':
                        throw new ArgumentException("Closing parentheses without opening parentheses",
                                                    nameof(sequence));

                    case '>':
                        throw new ArgumentException("Closing brace without opening brace",
                                                    nameof(sequence));

                    case ',':
                        throw new ArgumentException("Comma should not occur outside of a group",
                                                    nameof(sequence));

                    default:
                        GrowMarble(marbleBuilder, ref marbleTime, time, character);
                        break;
                    }
                }
                else if (parsingState == ParsingState.InOrderedGroup)
                {
                    switch (character)
                    {
                    case ',':
                    case ' ':
                        FlushMarbleToGroup(marbleBuilder, groupMarbles);
                        break;

                    case '-':
                        throw new ArgumentException("Cannot use - within a group", nameof(sequence));

                    case '^':
                        if (timeOffset.HasValue)
                        {
                            throw new ArgumentException("Only one ^ character allowed", nameof(sequence));
                        }
                        FlushMarbleToGroup(marbleBuilder, groupMarbles);
                        timeOffset = -groupTime;
                        groupMarbles.Add(character.ToString());
                        break;

                    case '(':
                        throw new ArgumentException("Cannot have nested parentheses", nameof(sequence));

                    case ')':
                        FlushMarbleToGroup(marbleBuilder, groupMarbles);
                        if (groupMarbles.Count <= 1)
                        {
                            throw new ArgumentException("Only groups with multiple marbles are allowed", nameof(sequence));
                        }
                        retVal.Add(Moment.OrderedGroup(groupTime, groupMarbles.ToArray()));
                        groupMarbles = null;
                        parsingState = ParsingState.NotInGroup;
                        AddEmptyMoments(retVal, time + 1);
                        break;

                    default:
                        GrowMarble(marbleBuilder, ref marbleTime, groupTime, character);
                        break;
                    }
                }
                else if (parsingState == ParsingState.InUnorderedGroup)
                {
                    switch (character)
                    {
                    case ',':
                    case ' ':
                        FlushMarbleToGroup(marbleBuilder, unorderedGroupMarbles);
                        break;

                    case '-':
                        throw new ArgumentException("Cannot use - within a group", nameof(sequence));

                    case '^':
                        if (timeOffset.HasValue)
                        {
                            throw new ArgumentException("Only one ^ character allowed", nameof(sequence));
                        }
                        FlushMarbleToGroup(marbleBuilder, unorderedGroupMarbles);
                        timeOffset = -groupTime;
                        unorderedGroupMarbles.Add(character.ToString());
                        break;

                    case '>':
                        FlushMarbleToGroup(marbleBuilder, unorderedGroupMarbles);
                        if (unorderedGroupMarbles.Count <= 1)
                        {
                            throw new ArgumentException("Only groups with multiple marbles are allowed", nameof(sequence));
                        }
                        retVal.Add(Moment.UnorderedGroup(groupTime, unorderedGroupMarbles.ToArray()));
                        unorderedGroupMarbles = null;
                        parsingState          = ParsingState.NotInGroup;
                        AddEmptyMoments(retVal, time + 1);
                        break;

                    case '<':
                        throw new ArgumentException("Cannot have braces nested in an unordered group", nameof(sequence));

                    case '(':
                        throw new ArgumentException("Cannot have parentheses nested in an unordered group", nameof(sequence));

                    case ')':
                        throw new ArgumentException("Cannot have parentheses nested in an unordered group", nameof(sequence));

                    default:
                        GrowMarble(marbleBuilder, ref marbleTime, groupTime, character);
                        break;
                    }
                }
                time++;
            }
            FlushMarble(marbleBuilder, retVal, marbleTime, time);
            if (parsingState == ParsingState.InOrderedGroup)
            {
                throw new ArgumentException("Opening parentheses without closing parentheses", nameof(sequence));
            }
            if (parsingState == ParsingState.InUnorderedGroup)
            {
                throw new ArgumentException("Opening brace without closing brace", nameof(sequence));
            }
            return(retVal);
        }