public void TestMatchCaseInsensitive_string() { var value = new ValueCursor("abc"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.MatchCaseInsensitive("AbC", CultureInfo.InvariantCulture.CompareInfo)); Assert.False(value.MoveNext(), "GetNext() end"); }
public void Match_String() { var value = new ValueCursor("abc"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.Match("abc")); Assert.False(value.MoveNext(), "GetNext() end"); }
public void Parse_Partial_Invalid() { var value = new ValueCursor("x17:y"); value.MoveNext(); value.MoveNext(); var result = SimpleOffsetPattern.ParsePartial(value); Assert.Throws<UnparsableValueException>(() => result.GetValueOrThrow()); }
public void Match_Char() { var value = new ValueCursor("abc"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.Match('a'), "First character"); Assert.True(value.Match('b'), "Second character"); Assert.True(value.Match('c'), "Third character"); Assert.False(value.MoveNext(), "GetNext() end"); }
public void ParsePartial_ValidAtEnd() { var value = new ValueCursor("x17:30"); value.MoveNext(); value.MoveNext(); var result = SimpleOffsetPattern.ParsePartial(value); Assert.AreEqual(Offset.FromHoursAndMinutes(17, 30), result.Value); // Finish just after the value, which in this case is at the end. Assert.AreEqual(TextCursor.Nul, value.Current); }
public void ParsePartial_ValidInMiddle() { var value = new ValueCursor("x17:30y"); value.MoveNext(); value.MoveNext(); // Start already looking at the value to parse Assert.AreEqual('1', value.Current); var result = SimpleOffsetPattern.ParsePartial(value); Assert.AreEqual(Offset.FromHoursAndMinutes(17, 30), result.Value); // Finish just after the value Assert.AreEqual('y', value.Current); }
public void MatchCaseInsensitive_MatchAndMove() { var value = new ValueCursor("abcd"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.MatchCaseInsensitive("AbC", CultureInfo.InvariantCulture.CompareInfo, true)); ValidateCurrentCharacter(value, 3, 'd'); }
public void MatchCaseInsensitive_StringNotMatched() { var value = new ValueCursor("xabcdef"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.False(value.MatchCaseInsensitive("abc", CultureInfo.InvariantCulture.CompareInfo, true)); ValidateCurrentCharacter(value, 0, 'x'); }
public void Match_StringOverLongStringToMatch() { var value = new ValueCursor("x"); Assert.True(value.MoveNext()); Assert.False(value.Match("long string")); ValidateCurrentCharacter(value, 0, 'x'); }
public void Match_StringNotMatched() { var value = new ValueCursor("xabcdef"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.False(value.Match("abc")); ValidateCurrentCharacter(value, 0, 'x'); }
public void MatchCaseInsensitive_MatchWithoutMoving() { var value = new ValueCursor("abcd"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.MatchCaseInsensitive("AbC", CultureInfo.InvariantCulture.CompareInfo, false)); // We're still looking at the start ValidateCurrentCharacter(value, 0, 'a'); }
public void ParseInt64_NumberOutOfRange_MinValueLeadingDigits() { var value = new ValueCursor("-9223372036854775809"); Assert.True(value.MoveNext()); long result; Assert.IsNotNull(value.ParseInt64<string>(out result)); // Cursor has not moved Assert.AreEqual(0, value.Index); }
public void ParseInt64_NegativeThenNonDigit() { var value = new ValueCursor("-x"); Assert.True(value.MoveNext()); long result; Assert.IsNotNull(value.ParseInt64<string>(out result)); // Cursor has not moved Assert.AreEqual(0, value.Index); }
public void TestParseDigit_successMinimumNonDigits() { var value = new ValueCursor("1abc"); Assert.True(value.MoveNext()); int actual; Assert.True(value.ParseDigits(1, 2, out actual)); Assert.AreEqual(1, actual); ValidateCurrentCharacter(value, 1, 'a'); }
public void ParseInt64_Negative() { var value = new ValueCursor("-56x"); Assert.True(value.MoveNext()); long result; Assert.IsNull(value.ParseInt64<string>(out result)); Assert.AreEqual(-56L, result); }
public void ParseInt64_Simple() { var value = new ValueCursor("56x"); Assert.True(value.MoveNext()); long result; Assert.IsNull(value.ParseInt64<string>(out result)); Assert.AreEqual(56L, result); // Cursor ends up post-number Assert.AreEqual(2, value.Index); }
// TODO(misc): Tidy this up a *lot*. public ParseResult <Period> Parse(string text) { if (text is null) { return(ParseResult <Period> .ArgumentNull("text")); } if (text.Length == 0) { return(ParseResult <Period> .ValueStringEmpty); } ValueCursor valueCursor = new ValueCursor(text); valueCursor.MoveNext(); if (valueCursor.Current != 'P') { return(ParseResult <Period> .MismatchedCharacter(valueCursor, 'P')); } bool inDate = true; PeriodBuilder builder = new PeriodBuilder(); PeriodUnits unitsSoFar = 0; while (valueCursor.MoveNext()) { if (inDate && valueCursor.Current == 'T') { inDate = false; continue; } bool negative = valueCursor.Current == '-'; var failure = valueCursor.ParseInt64 <Period>(out long unitValue); if (failure != null) { return(failure); } if (valueCursor.Length == valueCursor.Index) { return(ParseResult <Period> .EndOfString(valueCursor)); } // Various failure cases: // - Repeated unit (e.g. P1M2M) // - Time unit is in date part (e.g. P5M) // - Date unit is in time part (e.g. PT1D) // - Unit is in incorrect order (e.g. P5D1Y) // - Unit is invalid (e.g. P5J) // - Unit is missing (e.g. P5) PeriodUnits unit; switch (valueCursor.Current) { case 'Y': unit = PeriodUnits.Years; break; case 'M': unit = inDate ? PeriodUnits.Months : PeriodUnits.Minutes; break; case 'W': unit = PeriodUnits.Weeks; break; case 'D': unit = PeriodUnits.Days; break; case 'H': unit = PeriodUnits.Hours; break; case 'S': unit = PeriodUnits.Seconds; break; case ',': case '.': unit = PeriodUnits.Nanoseconds; break; // Special handling below default: return(InvalidUnit(valueCursor, valueCursor.Current)); } if ((unit & unitsSoFar) != 0) { return(RepeatedUnit(valueCursor, valueCursor.Current)); } // This handles putting months before years, for example. Less significant units // have higher integer representations. if (unit < unitsSoFar) { return(MisplacedUnit(valueCursor, valueCursor.Current)); } // The result of checking "there aren't any time units in this unit" should be // equal to "we're still in the date part". if ((unit & PeriodUnits.AllTimeUnits) == 0 != inDate) { return(MisplacedUnit(valueCursor, valueCursor.Current)); } // Seen a . or , which need special handling. if (unit == PeriodUnits.Nanoseconds) { // Check for already having seen seconds, e.g. PT5S0.5 if ((unitsSoFar & PeriodUnits.Seconds) != 0) { return(MisplacedUnit(valueCursor, valueCursor.Current)); } builder.Seconds = unitValue; if (!valueCursor.MoveNext()) { return(ParseResult <Period> .MissingNumber(valueCursor)); } // Can cope with at most 999999999 nanoseconds if (!valueCursor.ParseFraction(9, 9, out int totalNanoseconds, 1)) { return(ParseResult <Period> .MissingNumber(valueCursor)); } // Use whether or not the seconds value was negative (even if 0) // as the indication of whether this value is negative. if (negative) { totalNanoseconds = -totalNanoseconds; } builder.Milliseconds = (totalNanoseconds / NanosecondsPerMillisecond) % MillisecondsPerSecond; builder.Ticks = (totalNanoseconds / NanosecondsPerTick) % TicksPerMillisecond; builder.Nanoseconds = totalNanoseconds % NanosecondsPerTick; if (valueCursor.Current != 'S') { return(ParseResult <Period> .MismatchedCharacter(valueCursor, 'S')); } if (valueCursor.MoveNext()) { return(ParseResult <Period> .ExpectedEndOfString(valueCursor)); } return(ParseResult <Period> .ForValue(builder.Build())); } builder[unit] = unitValue; unitsSoFar |= unit; } if (unitsSoFar == 0) { return(ParseResult <Period> .ForInvalidValue(valueCursor, TextErrorMessages.EmptyPeriod)); } return(ParseResult <Period> .ForValue(builder.Build())); }
public void TestParseDigit_successMinimum() { var value = new ValueCursor("1"); value.MoveNext(); int actual; Assert.True(value.ParseDigits(1, 2, out actual)); Assert.AreEqual(1, actual); ValidateEndOfString(value); }
public void MatchCaseInsensitive_StringOverLongStringToMatch() { var value = new ValueCursor("x"); Assert.True(value.MoveNext()); Assert.False(value.MatchCaseInsensitive("long string", CultureInfo.InvariantCulture.CompareInfo, true)); ValidateCurrentCharacter(value, 0, 'x'); }
public void ParseInt64Digits_Maximum() { var value = new ValueCursor("12"); Assert.True(value.MoveNext()); long actual; Assert.True(value.ParseInt64Digits(1, 2, out actual)); Assert.AreEqual(12, actual); }
public void ParseInt64Digits_NoNumber() { var value = new ValueCursor("abc"); Assert.True(value.MoveNext()); long actual; Assert.False(value.ParseInt64Digits(1, 2, out actual)); ValidateCurrentCharacter(value, 0, 'a'); }
public void TestParseDigit_nonASCII_NeverMatches() { // Arabic-Indic digits 0 and 1. See // http://www.unicode.org/charts/PDF/U0600.pdf var value = new ValueCursor("\u0660\u0661"); Assert.True(value.MoveNext()); int actual; Assert.False(value.ParseDigits(1, 2, out actual)); }
public void ParseInt64Digits_TooFewDigits() { var value = new ValueCursor("a12b"); Assert.True(value.MoveNext()); ValidateCurrentCharacter(value, 0, 'a'); Assert.True(value.MoveNext()); long actual; Assert.False(value.ParseInt64Digits(3, 3, out actual)); ValidateCurrentCharacter(value, 1, '1'); }
public void ParseInt64_MinValue() { var value = new ValueCursor("-9223372036854775808"); Assert.True(value.MoveNext()); long result; Assert.IsNull(value.ParseInt64<string>(out result)); Assert.AreEqual(long.MinValue, result); }
public void ParseInt64Digits_LargeNumber() { var value = new ValueCursor("9999999999999"); Assert.True(value.MoveNext()); long actual; Assert.True(value.ParseInt64Digits(1, 13, out actual)); Assert.AreEqual(actual, 9999999999999L); Assert.Greater(9999999999999L, int.MaxValue); }
public void ParseFraction_NonAscii_NeverMatches() { // Arabic-Indic digits 0 and 1. See // http://www.unicode.org/charts/PDF/U0600.pdf var value = new ValueCursor("\u0660\u0661"); Assert.True(value.MoveNext()); int actual; Assert.False(value.ParseFraction(2, 2, out actual, 2)); }
public void ParseInt64Digits_MaximumMoreDigits() { var value = new ValueCursor("1234"); Assert.True(value.MoveNext()); long actual; Assert.True(value.ParseInt64Digits(1, 2, out actual)); Assert.AreEqual(12, actual); ValidateCurrentCharacter(value, 2, '3'); }
public ParseResult <Period> Parse(string text) { if (text is null) { return(ParseResult <Period> .ArgumentNull("text")); } if (text.Length == 0) { return(ParseResult <Period> .ValueStringEmpty); } ValueCursor valueCursor = new ValueCursor(text); valueCursor.MoveNext(); if (valueCursor.Current != 'P') { return(ParseResult <Period> .MismatchedCharacter(valueCursor, 'P')); } bool inDate = true; PeriodBuilder builder = new PeriodBuilder(); PeriodUnits unitsSoFar = 0; while (valueCursor.MoveNext()) { if (inDate && valueCursor.Current == 'T') { inDate = false; continue; } var failure = valueCursor.ParseInt64 <Period>(out long unitValue); if (failure != null) { return(failure); } if (valueCursor.Length == valueCursor.Index) { return(ParseResult <Period> .EndOfString(valueCursor)); } // Various failure cases: // - Repeated unit (e.g. P1M2M) // - Time unit is in date part (e.g. P5M) // - Date unit is in time part (e.g. PT1D) // - Unit is in incorrect order (e.g. P5D1Y) // - Unit is invalid (e.g. P5J) // - Unit is missing (e.g. P5) PeriodUnits unit; switch (valueCursor.Current) { case 'Y': unit = PeriodUnits.Years; break; case 'M': unit = inDate ? PeriodUnits.Months : PeriodUnits.Minutes; break; case 'W': unit = PeriodUnits.Weeks; break; case 'D': unit = PeriodUnits.Days; break; case 'H': unit = PeriodUnits.Hours; break; case 'S': unit = PeriodUnits.Seconds; break; case 's': unit = PeriodUnits.Milliseconds; break; case 't': unit = PeriodUnits.Ticks; break; case 'n': unit = PeriodUnits.Nanoseconds; break; default: return(InvalidUnit(valueCursor, valueCursor.Current)); } if ((unit & unitsSoFar) != 0) { return(RepeatedUnit(valueCursor, valueCursor.Current)); } // This handles putting months before years, for example. Less significant units // have higher integer representations. if (unit < unitsSoFar) { return(MisplacedUnit(valueCursor, valueCursor.Current)); } // The result of checking "there aren't any time units in this unit" should be // equal to "we're still in the date part". if ((unit & PeriodUnits.AllTimeUnits) == 0 != inDate) { return(MisplacedUnit(valueCursor, valueCursor.Current)); } builder[unit] = unitValue; unitsSoFar |= unit; } return(ParseResult <Period> .ForValue(builder.Build())); }
public void ParseInt64Digits_Minimum() { var value = new ValueCursor("1"); value.MoveNext(); long actual; Assert.True(value.ParseInt64Digits(1, 2, out actual)); Assert.AreEqual(1, actual); ValidateEndOfString(value); }
public void ParseInt64Digits_MinimumNonDigits() { var value = new ValueCursor("1abc"); Assert.True(value.MoveNext()); long actual; Assert.True(value.ParseInt64Digits(1, 2, out actual)); Assert.AreEqual(1, actual); ValidateCurrentCharacter(value, 1, 'a'); }
public void Match_StringPartial() { var value = new ValueCursor("abcdef"); Assert.True(value.MoveNext(), "GetNext() 1"); Assert.True(value.Match("abc")); ValidateCurrentCharacter(value, 3, 'd'); }
public void TestParseDigit_successMaximumMoreDigits() { var value = new ValueCursor("1234"); Assert.True(value.MoveNext()); int actual; Assert.True(value.ParseDigits(1, 2, out actual)); Assert.AreEqual(12, actual); ValidateCurrentCharacter(value, 2, '3'); }