Пример #1
0
        public void TestLessAndGreater()
        {
            ArgumentToken <int> token = new ArgumentToken <int> .Builder().Name("arg").Parser(int.TryParse).Build();

            TokenMatchResult result1 = new TokenMatchResult(token, "12345", "12345", MatchOutcome.Full, 5, 1);

            TokenMatchResult result2 = new TokenMatchResult(token, "123", "123", MatchOutcome.Full, 3, 1);

            TokenMatchResult result3 = new TokenMatchResult(token, "12345", "12345", MatchOutcome.Partial, 3, 1);


            TokenMatchResult result4 = new TokenMatchResult(token, "123 45", "123 45", MatchOutcome.Full, 5, 2);

            //Chars matched
            Assert.False(result1 <= result2);
            Assert.False(result1 < result2);
            Assert.True(result1 > result2);
            Assert.True(result1 >= result2);

            //Outcome
            Assert.True(result1 > result3);
            Assert.True(result2 > result3);

            //Tokens Matched
            Assert.True(result1 < result4);
            Assert.True(result4 > result1);
        }
Пример #2
0
        public static bool TryMatchYesterday(ArgumentToken token, DateTime currentDate, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            //Yesterday
            if (inputTokens[startIdx].Equals("yesterday", StringComparison.CurrentCultureIgnoreCase))
            {
                DateTime output = currentDate.Subtract(new TimeSpan(1, 0, 0, 0));
                result = new TokenMatchResult(token, inputTokens[startIdx], inputTokens[startIdx], MatchOutcome.Full, inputTokens[startIdx].Length, 1);
                result.SetArgValue(token, output);
                return(true);
            }

            result = TokenMatchResult.None;
            return(false);
        }
        [InlineData(new [] { "a" }, 0, MatchOutcome.Partial, 0)]                        //not enough
        public void TestOptionWithArgumentsMatches(string[] input, int startIdx, MatchOutcome expMatchLength, int expNumMatchTokens)
        {
            ArgumentToken arg1 = new ArgumentToken <int> .Builder().Name("arg1").Parser(int.TryParse).Build();

            var token = new OptionWithArgumentToken.Builder()
                        .Name("option", "alt1", "alt2")
                        .WithArgument(arg1)
                        .Build();

            TokenMatchResult matchResult = token.Matches(input, startIdx);

            Assert.True(expMatchLength == matchResult.MatchOutcome, $"Failed in case \"{input}\"");
            Assert.Equal(expNumMatchTokens, matchResult.TokensMatched);
        }
Пример #4
0
        public void TestTryGetValueByString()
        {
            ArgumentToken <int> token = new ArgumentToken <int> .Builder().Name("arg").Parser(int.TryParse).Build();

            TokenMatchResult result = new TokenMatchResult(token, "123", "123", MatchOutcome.Full, 3, 1);

            result.SetArgValue(token, 123);

            int  argValue;
            bool hasValue = result.TryGetArgValue("arg", out argValue);

            Assert.True(hasValue);
            Assert.Equal(123, argValue);
        }
Пример #5
0
        public static bool TryMatchExplicitDate(ArgumentToken token, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            DateTime output;

            //Explicit date
            if (DateTime.TryParse(inputTokens[startIdx], out output))
            {
                result = new TokenMatchResult(token, inputTokens[startIdx], inputTokens[startIdx], MatchOutcome.Full, inputTokens[startIdx].Length, 1);
                result.SetArgValue(token, output);
                return(true);
            }

            result = TokenMatchResult.None;
            return(false);
        }
Пример #6
0
        [InlineData(new [] { "1234", "b", "c", "d" }, 2, false, 0)]        //Match is before the start token
        public void TestArgumentMatches(string[] input, int startIdx, bool expMatches, int expMatchLength)
        {
            var token = new ArgumentToken <int> .Builder().Name("arg1").IsOptional(false).Parser(int.TryParse).Build();

            TokenMatchResult matchResult = token.Matches(input, startIdx);

            if (expMatches)
            {
                Assert.True(matchResult.MatchOutcome == MatchOutcome.Full, $"Failed in case \"{input}\"");
            }
            else
            {
                Assert.False(matchResult.MatchOutcome == MatchOutcome.Full, $"Failed in case \"{input}\"");
            }
            Assert.Equal(expMatchLength, matchResult.TokensMatched);
        }
        [InlineData(new [] { "a", "b", "c", "d" }, 0, false, 0)]           //No match
        public void TestStandAloneOptionMatches(string[] input, int startIdx, bool expMatches, int expMatchLength)
        {
            var token = new StandAloneOptionToken(new Name("option", "alt1", "alt2"));

            TokenMatchResult matchResult = token.Matches(input, startIdx);

            if (expMatches)
            {
                Assert.True(matchResult.MatchOutcome == MatchOutcome.Full, $"Failed in case \"{input}\"");
            }
            else
            {
                Assert.False(matchResult.MatchOutcome == MatchOutcome.Full, $"Failed in case \"{input}\"");
            }
            Assert.Equal(expMatchLength, matchResult.TokensMatched);
        }
Пример #8
0
        public void TestEqualAndHashCode()
        {
            ArgumentToken <int> token = new ArgumentToken <int> .Builder().Name("arg").Parser(int.TryParse).Build();

            TokenMatchResult result1 = new TokenMatchResult(token, "123", "123", MatchOutcome.Full, 3, 1);

            TokenMatchResult result2 = new TokenMatchResult(token, "123", "123", MatchOutcome.Full, 3, 1);

            Assert.Equal(result1, result2);
            Assert.True(result1 == result2);
            Assert.False(result1 != result2);
            Assert.True(result1 <= result2);
            Assert.True(result1 >= result2);
            Assert.False(result1.Equals(null));
            Assert.True(result1.Equals((object)result2));
            Assert.False(result1.Equals("not the same type"));
            Assert.Equal(result1.GetHashCode(), result2.GetHashCode());
        }
Пример #9
0
        public static bool TryMatchLastDayOfWeek(ArgumentToken token, DateTime currentDate, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            //last <day-of-week>
            if (inputTokens.Length > startIdx + 1)
            {
                DayOfWeek dayOfWeek;
                if (DateParser.TryParseDayOfWeek(inputTokens[startIdx + 1], out dayOfWeek))
                {
                    DateTime output    = DateUtil.GetRelativeDateDayOfWeek(currentDate, dayOfWeek);
                    string   matchText = TokenUtils.GetMatchText(inputTokens, startIdx, 2);
                    result = new TokenMatchResult(token, matchText, matchText, MatchOutcome.Full, matchText.Length, 2);
                    result.SetArgValue(token, output);
                    return(true);
                }
            }

            result = TokenMatchResult.None;
            return(false);
        }
Пример #10
0
        public static bool TryMatchLastDayOfMonth(ArgumentToken token, DateTime currentDate, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            //last <month> <day-of-month>
            if (inputTokens.Length > startIdx + 2)
            {
                int month;
                int day;
                if (DateParser.TryParseMonth(inputTokens[startIdx + 1], out month) &&
                    DateParser.TryParseDayOfMonth(inputTokens[startIdx + 2], currentDate.Year - 1, month, out day))
                {
                    DateTime output    = new DateTime(currentDate.Year - 1, month, day);
                    string   matchText = TokenUtils.GetMatchText(inputTokens, startIdx, 3);
                    result = new TokenMatchResult(token, matchText, matchText, MatchOutcome.Full, matchText.Length, 3);
                    result.SetArgValue(token, output);
                    return(true);
                }
            }

            result = TokenMatchResult.None;
            return(false);
        }
Пример #11
0
        public static bool TryMatchRelativeDate(ArgumentToken token, DateTime currentDate, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            //<number> <time-unit> ago
            if (inputTokens.Length > startIdx + 2 &&
                inputTokens[startIdx + 2].Equals("ago", StringComparison.CurrentCultureIgnoreCase))
            {
                int      number;
                TimeUnit unit;
                if (int.TryParse(inputTokens[startIdx], out number) &&
                    DateParser.TryParseTimeUnit(inputTokens[startIdx + 1], out unit))
                {
                    DateTime output    = DateUtil.GetRelativeDate(currentDate, -number, unit);
                    string   matchText = TokenUtils.GetMatchText(inputTokens, startIdx, 3);
                    result = new TokenMatchResult(token, matchText, matchText, MatchOutcome.Full, matchText.Length, 3);
                    result.SetArgValue(token, output);
                    return(true);
                }
            }

            result = TokenMatchResult.None;
            return(false);
        }
Пример #12
0
        public static bool TryMatchDate(ArgumentToken token, DateTime currentDate, string[] inputTokens, int startIdx, out TokenMatchResult result)
        {
            if (TryMatchExplicitDate(token, inputTokens, startIdx, out result))
            {
                return(true);
            }
            else if (TryMatchYesterday(token, currentDate, inputTokens, startIdx, out result))
            {
                return(true);
            }
            else if (startIdx == inputTokens.Length - 1)
            {
                //End of tokens, cannot match anything else
                result = TokenMatchResult.None;
                return(false);
            }
            else if (inputTokens[startIdx].Equals("last", StringComparison.CurrentCultureIgnoreCase))
            {
                if (TryMatchLastDayOfWeek(token, currentDate, inputTokens, startIdx, out result))
                {
                    return(true);
                }
                else if (TryMatchLastDayOfMonth(token, currentDate, inputTokens, startIdx, out result))
                {
                    return(true);
                }

                result = TokenMatchResult.None;
                return(false);
            }
            else if (TryMatchRelativeDate(token, currentDate, inputTokens, startIdx, out result))
            {
                return(true);
            }

            result = TokenMatchResult.None;
            return(false);
        }
Пример #13
0
 public void AddAllArgumentValues(TokenMatchResult result)
 {
     _argumentValues.AddAll(result.ArgumentValues);
 }
Пример #14
0
 public ParserTokenMatch(int tokenIdx, TokenMatchResult tokenMatchResult)
 {
     TokenIdx         = tokenIdx;
     TokenMatchResult = tokenMatchResult;
 }
Пример #15
0
        public static TokenMatchCollection Match(ICommandToken[] commandTokens, string input)
        {
            string[]   inputTokens           = Tokenize(input);
            int        inputTokenIdx         = 0;
            int        commandTokensIdx      = 0;
            List <int> matchableTokenIndexes = new List <int>();

            TokenMatchCollection matchCollection = new TokenMatchCollection(input, commandTokens);

            while (inputTokenIdx < inputTokens.Length)
            {
                //Take another token from the usage to consider
                if (commandTokensIdx < commandTokens.Length)
                {
                    matchableTokenIndexes.Add(commandTokensIdx);
                    commandTokensIdx++;
                }

                bool areAllTokensOptional = true;
                //Find the next token match. Greedy search prefers tokens with lowest index
                TokenMatchResult bestMatch = TokenMatchResult.None;
                int bestMatchIdx           = -1;
                foreach (var tokenIdx in matchableTokenIndexes)
                {
                    ICommandToken token = commandTokens[tokenIdx];
                    areAllTokensOptional &= token.IsOptional;
                    TokenMatchResult matchResult = token.Matches(inputTokens, inputTokenIdx);
                    int tokenMatchLength         = matchResult.TokensMatched;

                    if (matchResult.IsBetterMatchThan(bestMatch))
                    {
                        bestMatch    = matchResult;
                        bestMatchIdx = tokenIdx;
                    }

                    if (matchResult.MatchOutcome == MatchOutcome.Full)
                    {
                        //match!
                        List <string> matchedTokensStrs = inputTokens.Skip(inputTokenIdx).Take(tokenMatchLength).ToList();
                        string        matchText         = string.Join(" ", matchedTokensStrs);
                        matchCollection.With(new ParserTokenMatch(tokenIdx, matchResult));

                        matchCollection.AddAllArgumentValues(matchResult);

                        matchableTokenIndexes.Remove(tokenIdx);
                        inputTokenIdx += tokenMatchLength;

                        if (!token.IsOptional)
                        {
                            //All optional tokens until this required one are no longer viable
                            matchableTokenIndexes.Clear();
                        }

                        break;
                    }
                }

                if (bestMatch.MatchOutcome < MatchOutcome.Full)
                {
                    //No match found!
                    if (!areAllTokensOptional || commandTokensIdx == commandTokens.Length)
                    {
                        //We couldn't match a required token OR
                        //considering all tokens, no more matches could be found
                        //...so that's the end of the match

                        if (bestMatch.MatchOutcome != MatchOutcome.None)
                        {
                            //Add a partial match for whatever last failed to match
                            matchCollection.With(new ParserTokenMatch(bestMatchIdx, bestMatch));
                        }
                        return(matchCollection);
                    }
                }
            }

            return(matchCollection);
        }