public void DateParserLexer_PeekToken_CallsNextTokenIfCacheIsNull() { var dateParserLexer = new DateParserLexer("100"); dateParserLexer.TokenCache = null; var token = dateParserLexer.PeekToken(); Assert.Equal(LexerTokenKindEnum.TOK_INT, token.Kind); Assert.Equal(100, token.Value.GetValue <int>()); Assert.Equal(token, dateParserLexer.TokenCache); }
/// <summary> /// Ported from draft_t::parse_args /// </summary> protected void ParseArgs(Value args) { Match what = Match.Empty; bool checkForDate = true; Tmpl = new DraftXactTemplate(); DayOfWeek? weekday; DraftXactPostTemplate post = null; IList <Value> argsSequence = args.AsSequence; Value endVal = argsSequence.LastOrDefault(); for (int index = 0; index < argsSequence.Count; index++) { Value val = argsSequence[index]; if (checkForDate && (what = DateMask.Match(val.AsString)).Length > 0) { Tmpl.Date = TimesCommon.Current.ParseDate(what.Value); checkForDate = false; } else if (checkForDate && (weekday = DateParserLexer.StringToDayOfWeek(what.Value)).HasValue) { Date date = TimesCommon.Current.CurrentDate.AddDays(-1); while (date.DayOfWeek != weekday) { date = date.AddDays(-1); } Tmpl.Date = date; checkForDate = false; } else { string arg = val.AsString; if (arg == "at") { if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } Tmpl.PayeeMask = new Mask(argsSequence[++index].AsString); } else if (arg == "to" || arg == "from") { if (post == null || post.AccountMask != null) { Tmpl.Posts.Add(post = new DraftXactPostTemplate()); } if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } post.AccountMask = new Mask(argsSequence[++index].AsString); post.From = arg == "from"; } else if (arg == "on") { if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } Tmpl.Date = TimesCommon.Current.ParseDate(argsSequence[++index].AsString); checkForDate = false; } else if (arg == "code") { if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } Tmpl.Code = argsSequence[++index].AsString; } else if (arg == "note") { if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } Tmpl.Note = argsSequence[++index].AsString; } else if (arg == "rest") { // just ignore this argument } else if (arg == "@" || arg == "@@") { Amount cost = new Amount(); post.CostOperator = arg; if (val == endVal) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } arg = argsSequence[++index].AsString; if (!cost.Parse(ref arg, AmountParseFlagsEnum.PARSE_SOFT_FAIL | AmountParseFlagsEnum.PARSE_NO_MIGRATE)) { throw new RuntimeError(RuntimeError.ErrorMessageInvalidXactCommandArguments); } post.Cost = cost; } else { // Without a preposition, it is either: // // A payee, if we have not seen one // An account or an amount, if we have // An account if an amount has just been seen // An amount if an account has just been seen if (Tmpl.PayeeMask == null) { Tmpl.PayeeMask = new Mask(arg); } else { Amount amt = new Amount(); Mask account = null; string argToParse = arg; if (!amt.Parse(ref argToParse, AmountParseFlagsEnum.PARSE_SOFT_FAIL | AmountParseFlagsEnum.PARSE_NO_MIGRATE)) { account = new Mask(arg); } if (post == null || (account != null && post.AccountMask != null) || (account == null && post.Amount != null)) { Tmpl.Posts.Add(post = new DraftXactPostTemplate()); } if (account != null) { post.AccountMask = account; } else { post.Amount = amt; post = null; // an amount concludes this posting } } } } } if (Tmpl.Posts.Any()) { // A single account at the end of the line is the "from" account if (Tmpl.Posts.Count > 1 && Tmpl.Posts.Last().AccountMask != null && !(bool)Tmpl.Posts.Last().Amount) { Tmpl.Posts.Last().From = true; } bool hasOnlyFrom = !Tmpl.Posts.Any(p => !p.From); bool hasOnlyTo = !Tmpl.Posts.Any(p => p.From); if (hasOnlyFrom) { Tmpl.Posts.Insert(0, new DraftXactPostTemplate()); } else if (hasOnlyTo) { Tmpl.Posts.Add(new DraftXactPostTemplate() { From = true }); } } }