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");
 }
Beispiel #2
0
 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());
 }
Beispiel #4
0
 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);
 }
Beispiel #7
0
 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');
 }
Beispiel #8
0
 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');
 }
Beispiel #9
0
 public void Match_StringOverLongStringToMatch()
 {
     var value = new ValueCursor("x");
     Assert.True(value.MoveNext());
     Assert.False(value.Match("long string"));
     ValidateCurrentCharacter(value, 0, 'x');
 }
Beispiel #10
0
 public void Match_StringNotMatched()
 {
     var value = new ValueCursor("xabcdef");
     Assert.True(value.MoveNext(), "GetNext() 1");
     Assert.False(value.Match("abc"));
     ValidateCurrentCharacter(value, 0, 'x');
 }
Beispiel #11
0
 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');
 }
Beispiel #12
0
 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);
 }
Beispiel #13
0
 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);
 }
Beispiel #14
0
 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');
 }
Beispiel #15
0
 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);
 }
Beispiel #16
0
 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);
 }
Beispiel #17
0
            // 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()));
            }
Beispiel #18
0
 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);
 }
Beispiel #19
0
 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');
 }
Beispiel #20
0
 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);
 }
Beispiel #21
0
 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');
 }
Beispiel #22
0
 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));
 }
Beispiel #23
0
 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');
 }
Beispiel #24
0
 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);
 }
Beispiel #25
0
 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);
 }
Beispiel #26
0
 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));
 }
Beispiel #27
0
 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');
 }
Beispiel #28
0
            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()));
            }
Beispiel #29
0
 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);
 }
Beispiel #30
0
 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');
 }
Beispiel #31
0
 public void Match_StringPartial()
 {
     var value = new ValueCursor("abcdef");
     Assert.True(value.MoveNext(), "GetNext() 1");
     Assert.True(value.Match("abc"));
     ValidateCurrentCharacter(value, 3, 'd');
 }
Beispiel #32
0
 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');
 }