Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/libraries/System.Runtime.Numerics/tests/BigInteger/parse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,5 +1382,91 @@ public static void RegressionIssueRuntime94610(string text)
parseTest.RegressionIssueRuntime94610(text);
}));
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_TestData()
{
// Basic BigInteger parsing with trailing invalid characters
yield return new object[] { "123abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(123), 3 };
yield return new object[] { "456789xyz", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(456789), 6 };
yield return new object[] { "0abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, BigInteger.Zero, 1 };

// With leading whitespace
yield return new object[] { " 123abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(123), 5 };

// With signs
yield return new object[] { "+123abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(123), 4 };
yield return new object[] { "-456xyz", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(-456), 4 };

// HexNumber with trailing invalid characters
yield return new object[] { "ABCDEFxyz", NumberStyles.HexNumber | NumberStyles.AllowTrailingInvalidCharacters, null, BigInteger.Parse("ABCDEF", NumberStyles.HexNumber), 6 };
yield return new object[] { "FFGHxyz", NumberStyles.HexNumber | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(0xFF), 2 };

// BinaryNumber with trailing invalid characters
yield return new object[] { "101010abc", NumberStyles.BinaryNumber | NumberStyles.AllowTrailingInvalidCharacters, null, BigInteger.Parse("101010", NumberStyles.BinaryNumber), 6 };
yield return new object[] { "1112", NumberStyles.BinaryNumber | NumberStyles.AllowTrailingInvalidCharacters, null, BigInteger.Parse("111", NumberStyles.BinaryNumber), 3 };

// Large numbers with trailing characters
yield return new object[] { "123456789012345678901234567890abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, BigInteger.Parse("123456789012345678901234567890"), 30 };

// Valid number without trailing characters
yield return new object[] { "123456", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, new BigInteger(123456), 6 };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_TestData))]
public static void Parse_AllowTrailingInvalidCharacters(string value, NumberStyles style, IFormatProvider provider, BigInteger expectedValue, int expectedCharsConsumed)
{
BigInteger result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.True(BigInteger.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.True(BigInteger.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test UTF-8 overload with bytesConsumed
byte[] utf8Bytes = Encoding.UTF8.GetBytes(value);
int bytesConsumed;
Assert.True(BigInteger.TryParse(utf8Bytes.AsSpan(), style, provider, out result, out bytesConsumed));
Assert.Equal(expectedValue, result);
// For ASCII characters, bytes consumed should equal chars consumed
if (value.All(c => c < 128))
{
Assert.Equal(expectedCharsConsumed, bytesConsumed);
}
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_Invalid_TestData()
{
// Empty string
yield return new object[] { "", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null };

// Only invalid characters (no valid number)
yield return new object[] { "abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null };
yield return new object[] { "xyz", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_Invalid_TestData))]
public static void Parse_AllowTrailingInvalidCharacters_Invalid(string value, NumberStyles style, IFormatProvider provider)
{
BigInteger result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.False(BigInteger.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(BigInteger.Zero, result);
Assert.Equal(0, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.False(BigInteger.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(BigInteger.Zero, result);
Assert.Equal(0, charsConsumed);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Xunit;

Expand Down Expand Up @@ -429,5 +430,40 @@ public static void Parse_Utf8Span_InvalidUtf8()
[MemberData(nameof(ToString_TestData))]
public static void TryFormat(byte i, string format, IFormatProvider provider, string expected) =>
NumberFormatTestHelper.TryFormatNumberTest(i, format, provider, expected);

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_TestData()
{
yield return new object[] { "123abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)123, 3 };
yield return new object[] { "12xyz", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)12, 2 };
yield return new object[] { "0abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)0, 1 };
yield return new object[] { "255abc", NumberStyles.Integer | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)255, 3 };
yield return new object[] { "FFxyz", NumberStyles.HexNumber | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)0xFF, 2 };
yield return new object[] { "ABGxyz", NumberStyles.HexNumber | NumberStyles.AllowTrailingInvalidCharacters, null, (byte)0xAB, 2 };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_TestData))]
public static void Parse_AllowTrailingInvalidCharacters(string value, NumberStyles style, IFormatProvider provider, byte expectedValue, int expectedCharsConsumed)
{
byte result;
int charsConsumed;

Assert.True(byte.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

Assert.True(byte.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

byte[] utf8Bytes = Encoding.UTF8.GetBytes(value);
int bytesConsumed;
Assert.True(byte.TryParse(utf8Bytes.AsSpan(), style, provider, out result, out bytesConsumed));
Assert.Equal(expectedValue, result);
if (value.All(c => c < 128))
{
Assert.Equal(expectedCharsConsumed, bytesConsumed);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2444,5 +2444,93 @@ public static void TryFormat()
}
}
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_TestData()
{
// Basic decimal parsing with trailing invalid characters
yield return new object[] { "123.45abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45m, 6 };
yield return new object[] { "456.78xyz", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 456.78m, 6 };
yield return new object[] { "0.123abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 0.123m, 5 };

// With leading whitespace
yield return new object[] { " 123.45abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45m, 8 };

// With signs
yield return new object[] { "+123.45abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45m, 7 };
yield return new object[] { "-456.78xyz", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, -456.78m, 7 };

// Integer without decimal point
yield return new object[] { "123abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 123m, 3 };

// With thousands separator
NumberFormatInfo customFormat = new NumberFormatInfo() { NumberGroupSeparator = "," };
yield return new object[] { "1,234abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, customFormat, 1234m, 5 };

// Max and min values with trailing characters
yield return new object[] { "79228162514264337593543950335abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 79228162514264337593543950335m, 29 };
yield return new object[] { "-79228162514264337593543950335xyz", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, -79228162514264337593543950335m, 30 };

// Valid number without trailing characters
yield return new object[] { "123.45", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45m, 6 };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_TestData))]
public static void Parse_AllowTrailingInvalidCharacters(string value, NumberStyles style, IFormatProvider provider, decimal expectedValue, int expectedCharsConsumed)
{
decimal result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.True(decimal.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.True(decimal.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(expectedValue, result);
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test UTF-8 overload with bytesConsumed
byte[] utf8Bytes = Encoding.UTF8.GetBytes(value);
int bytesConsumed;
Assert.True(decimal.TryParse(utf8Bytes.AsSpan(), style, provider, out result, out bytesConsumed));
Assert.Equal(expectedValue, result);
// For ASCII characters, bytes consumed should equal chars consumed
if (value.All(c => c < 128))
{
Assert.Equal(expectedCharsConsumed, bytesConsumed);
}
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_Invalid_TestData()
{
// Empty string
yield return new object[] { "", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null };

// Only invalid characters (no valid number)
yield return new object[] { "abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null };

// Overflow
yield return new object[] { "79228162514264337593543950336abc", NumberStyles.Number | NumberStyles.AllowTrailingInvalidCharacters, null };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_Invalid_TestData))]
public static void Parse_AllowTrailingInvalidCharacters_Invalid(string value, NumberStyles style, IFormatProvider provider)
{
decimal result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.False(decimal.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(0m, result);
Assert.Equal(0, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.False(decimal.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(0m, result);
Assert.Equal(0, charsConsumed);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1536,5 +1536,120 @@ public static void RadiansToDegreesTest(double value, double expectedResult, dou
AssertExtensions.Equal(-expectedResult, double.RadiansToDegrees(-value), allowedVariance);
AssertExtensions.Equal(+expectedResult, double.RadiansToDegrees(+value), allowedVariance);
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_TestData()
{
// Basic floating point parsing with trailing invalid characters
yield return new object[] { "123.45abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45, 6 };
yield return new object[] { "456.78xyz", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 456.78, 6 };
yield return new object[] { "0.123abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 0.123, 5 };

// With leading whitespace
yield return new object[] { " 123.45abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45, 8 };

// With signs
yield return new object[] { "+123.45abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45, 7 };
yield return new object[] { "-456.78xyz", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, -456.78, 7 };

// With exponent
yield return new object[] { "1.23e10abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 1.23e10, 7 };
yield return new object[] { "4.56E-5xyz", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 4.56E-5, 7 };
yield return new object[] { "1E10abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 1E10, 4 };

// Integer without decimal point
yield return new object[] { "123abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.0, 3 };
yield return new object[] { "456xyz", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 456.0, 3 };

// Special values
yield return new object[] { "Infinityabc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, double.PositiveInfinity, 8 };
yield return new object[] { "-Infinityxyz", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, double.NegativeInfinity, 9 };
yield return new object[] { "NaNabc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, double.NaN, 3 };

// Valid number without trailing characters
yield return new object[] { "123.45", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.45, 6 };

// Stop at invalid exponent
yield return new object[] { "123eabc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null, 123.0, 3 };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_TestData))]
public static void Parse_AllowTrailingInvalidCharacters(string value, NumberStyles style, IFormatProvider provider, double expectedValue, int expectedCharsConsumed)
{
double result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.True(double.TryParse(value, style, provider, out result, out charsConsumed));
if (double.IsNaN(expectedValue))
{
Assert.True(double.IsNaN(result));
}
else
{
Assert.Equal(expectedValue, result);
}
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.True(double.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
if (double.IsNaN(expectedValue))
{
Assert.True(double.IsNaN(result));
}
else
{
Assert.Equal(expectedValue, result);
}
Assert.Equal(expectedCharsConsumed, charsConsumed);

// Test UTF-8 overload with bytesConsumed
byte[] utf8Bytes = Encoding.UTF8.GetBytes(value);
int bytesConsumed;
Assert.True(double.TryParse(utf8Bytes.AsSpan(), style, provider, out result, out bytesConsumed));
if (double.IsNaN(expectedValue))
{
Assert.True(double.IsNaN(result));
}
else
{
Assert.Equal(expectedValue, result);
}
// For ASCII characters, bytes consumed should equal chars consumed
if (value.All(c => c < 128))
{
Assert.Equal(expectedCharsConsumed, bytesConsumed);
}
}

public static IEnumerable<object[]> Parse_AllowTrailingInvalidCharacters_Invalid_TestData()
{
// Empty string
yield return new object[] { "", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null };

// Only invalid characters (no valid number)
yield return new object[] { "abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null };

// Invalid start characters
yield return new object[] { ".abc", NumberStyles.Float | NumberStyles.AllowTrailingInvalidCharacters, null };
}

[Theory]
[MemberData(nameof(Parse_AllowTrailingInvalidCharacters_Invalid_TestData))]
public static void Parse_AllowTrailingInvalidCharacters_Invalid(string value, NumberStyles style, IFormatProvider provider)
{
double result;
int charsConsumed;

// Test string overload with charsConsumed
Assert.False(double.TryParse(value, style, provider, out result, out charsConsumed));
Assert.Equal(0.0, result);
Assert.Equal(0, charsConsumed);

// Test ReadOnlySpan<char> overload with charsConsumed
Assert.False(double.TryParse(value.AsSpan(), style, provider, out result, out charsConsumed));
Assert.Equal(0.0, result);
Assert.Equal(0, charsConsumed);
}
}
}
Loading