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); }
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); }
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); }
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); }
[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); }
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()); }
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); }
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); }
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); }
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); }
public void AddAllArgumentValues(TokenMatchResult result) { _argumentValues.AddAll(result.ArgumentValues); }
public ParserTokenMatch(int tokenIdx, TokenMatchResult tokenMatchResult) { TokenIdx = tokenIdx; TokenMatchResult = tokenMatchResult; }
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); }