private static void ValidateParser <T>(ParserTestData <T> testData)
        {
            ValidateParserHelper(testData);

            if (testData.ExpectedSuccess)
            {
                // Add several bytes of junk after the real text to ensure the parser successfully ignores it. By adding lots of junk, this also
                // exercises the "string is too long to rule out overflow based on length" paths of the integer parsers.
                ParserTestData <T> testDataWithExtraCharacter = new ParserTestData <T>(testData.Text + "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", testData.ExpectedValue, testData.FormatSymbol, expectedSuccess: true)
                {
                    ExpectedBytesConsumed = testData.ExpectedBytesConsumed
                };
                ValidateParserHelper(testDataWithExtraCharacter);
            }
        }
        private static void ValidateParserHelper <T>(ParserTestData <T> testData)
        {
            ReadOnlySpan <byte> utf8Text = testData.Text.ToUtf8Span();
            bool success = TryParseUtf8 <T>(utf8Text, out T value, out int bytesConsumed, testData.FormatSymbol);

            if (testData.ExpectedSuccess)
            {
                if (!success)
                {
                    throw new TestException($"This parse attempt {testData} was expected to succeed: instead, it failed.");
                }

                T expected = testData.ExpectedValue;
                T actual   = value;
                if (!IsParsedValueEqual <T>(expected: expected, actual: actual))
                {
                    string expectedString = expected.DisplayString();
                    string actualString   = actual.DisplayString();
                    throw new TestException($"This parse attempt {testData} succeeded as expected but parsed to the wrong value:\n  Expected: {expectedString}\n  Actual:   {actualString}\n");
                }

                int expectedBytesConsumed = testData.ExpectedBytesConsumed;
                if (expectedBytesConsumed != bytesConsumed)
                {
                    throw new TestException($"This parse attempt {testData} returned the correct value but the wrong `bytesConsumed` value:\n  Expected: {expectedBytesConsumed}\n  Actual:   {bytesConsumed}\n");
                }
            }
            else
            {
                if (success)
                {
                    throw new TestException($"This parse attempt {testData} was expected to fail: instead, it succeeded and returned {value}.");
                }

                if (bytesConsumed != 0)
                {
                    throw new TestException($"This parse attempt {testData} failed as expected but did not set `bytesConsumed` to 0");
                }

                if (!(value.Equals(default(T))))
                {
                    throw new TestException($"This parse attempt {testData} failed as expected but did not set `value` to default(T)");
                }
            }
        }
 public static void TestParserSingle(ParserTestData <float> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserGuid(ParserTestData <Guid> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserDecimal(ParserTestData <decimal> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserDouble(ParserTestData <double> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserUInt32(ParserTestData <uint> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserUInt64(ParserTestData <ulong> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserUInt16(ParserTestData <ushort> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserByte(ParserTestData <byte> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserBoolean(ParserTestData <bool> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserTimeSpan(ParserTestData <TimeSpan> testData)
 {
     ValidateParser(testData);
 }
 public static void TestParserDateTimeOffset(ParserTestData <DateTimeOffset> testData)
 {
     ValidateParser(testData);
 }