Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Fixed BigInteger test failure for uk-UA (#15587)
Browse files Browse the repository at this point in the history
* Fixed BigInteger test failure for uk-UA

BigInteger string parsing test was faulty for cultures that use 0xA0
as the group separator. The fixed test does not expect an exception
anymore if:
 - The trailing whitespace is 0x20 characters only AND
 - Grouping is allowed (NumberStyles.AllowThousands) AND
 - Currency symbol is allowed and currency group separator is 0xA0 OR
   Currency symbol is not allowed and number group separator is 0xA0

Fix #1642

* Additional inline code documentation

Added comment to FailureNotExpectedForTrailingWhite(NumberStyles, bool)
in System.Numerics.Tests.parseTest explaining the need for/function of
that method.

Fix #1642
  • Loading branch information
dennisdietrich authored and danmoseley committed Jan 31, 2017
1 parent be912d4 commit a882c66
Showing 1 changed file with 105 additions and 54 deletions.
159 changes: 105 additions & 54 deletions src/System.Runtime.Numerics/tests/BigInteger/parse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,63 +4,89 @@

using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using Xunit;

namespace System.Numerics.Tests
{
public class parseTest
{
private static int s_samples = 10;
private static Random s_random = new Random(100);
private readonly static int s_samples = 10;
private readonly static Random s_random = new Random(100);

[Fact]
// Invariant culture is commonly used for (de-)serialization and similar to en-US
// Ukrainian (Ukraine) added to catch regressions (issue #1642)
// Current cultue to get additional value out of glob/loc test runs
public static IEnumerable<object[]> Cultures
{
get
{
yield return new object[] { CultureInfo.InvariantCulture };
yield return new object[] { new CultureInfo("uk-UA") };

if (CultureInfo.CurrentCulture.ToString() != "uk-UA")
yield return new object[] { CultureInfo.CurrentCulture };
}
}

[Theory]
[MemberData(nameof(Cultures))]
[OuterLoop]
[ActiveIssue(1642)]
public static void RunParseToStringTests()
public static void RunParseToStringTests(CultureInfo culture)
{
byte[] tempByteArray1 = new byte[0];

//default style

VerifyDefaultParse(s_random);

//single NumberStyles
VerifyNumberStyles(NumberStyles.None, s_random);
VerifyNumberStyles(NumberStyles.AllowLeadingWhite, s_random);
VerifyNumberStyles(NumberStyles.AllowTrailingWhite, s_random);
VerifyNumberStyles(NumberStyles.AllowLeadingSign, s_random);
VerifyNumberStyles(NumberStyles.AllowTrailingSign, s_random);
VerifyNumberStyles(NumberStyles.AllowParentheses, s_random);
VerifyNumberStyles(NumberStyles.AllowDecimalPoint, s_random);
VerifyNumberStyles(NumberStyles.AllowThousands, s_random);
VerifyNumberStyles(NumberStyles.AllowExponent, s_random);
VerifyNumberStyles(NumberStyles.AllowCurrencySymbol, s_random);
VerifyNumberStyles(NumberStyles.AllowHexSpecifier, s_random);

//composite NumberStyles
VerifyNumberStyles(NumberStyles.Integer, s_random);
VerifyNumberStyles(NumberStyles.HexNumber, s_random);
VerifyNumberStyles(NumberStyles.Number, s_random);
VerifyNumberStyles(NumberStyles.Float, s_random);
VerifyNumberStyles(NumberStyles.Currency, s_random);
VerifyNumberStyles(NumberStyles.Any, s_random);

//invalid number style
// ******InvalidNumberStyles
NumberStyles invalid = (NumberStyles)0x7c00;
Assert.Throws<ArgumentException>(() =>
{
BigInteger.Parse("1", invalid).ToString("d");
});
Assert.Throws<ArgumentException>(() =>
{
BigInteger junk;
BigInteger.TryParse("1", invalid, null, out junk);
Assert.Equal(junk.ToString("d"), "1");
});

//FormatProvider tests
RunFormatProviderParseStrings();
CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

try
{
byte[] tempByteArray1 = new byte[0];

Thread.CurrentThread.CurrentCulture = culture;

//default style
VerifyDefaultParse(s_random);

//single NumberStyles
VerifyNumberStyles(NumberStyles.None, s_random);
VerifyNumberStyles(NumberStyles.AllowLeadingWhite, s_random);
VerifyNumberStyles(NumberStyles.AllowTrailingWhite, s_random);
VerifyNumberStyles(NumberStyles.AllowLeadingSign, s_random);
VerifyNumberStyles(NumberStyles.AllowTrailingSign, s_random);
VerifyNumberStyles(NumberStyles.AllowParentheses, s_random);
VerifyNumberStyles(NumberStyles.AllowDecimalPoint, s_random);
VerifyNumberStyles(NumberStyles.AllowThousands, s_random);
VerifyNumberStyles(NumberStyles.AllowExponent, s_random);
VerifyNumberStyles(NumberStyles.AllowCurrencySymbol, s_random);
VerifyNumberStyles(NumberStyles.AllowHexSpecifier, s_random);

//composite NumberStyles
VerifyNumberStyles(NumberStyles.Integer, s_random);
VerifyNumberStyles(NumberStyles.HexNumber, s_random);
VerifyNumberStyles(NumberStyles.Number, s_random);
VerifyNumberStyles(NumberStyles.Float, s_random);
VerifyNumberStyles(NumberStyles.Currency, s_random);
VerifyNumberStyles(NumberStyles.Any, s_random);

//invalid number style
// ******InvalidNumberStyles
NumberStyles invalid = (NumberStyles)0x7c00;
Assert.Throws<ArgumentException>(() =>
{
BigInteger.Parse("1", invalid).ToString("d");
});
Assert.Throws<ArgumentException>(() =>
{
BigInteger junk;
BigInteger.TryParse("1", invalid, null, out junk);
Assert.Equal(junk.ToString("d"), "1");
});

//FormatProvider tests
RunFormatProviderParseStrings();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
}
}

private static void RunFormatProviderParseStrings()
Expand Down Expand Up @@ -241,12 +267,12 @@ public static void VerifyNumberStyles(NumberStyles ns, Random random)
// Trailing White
for (int i = 0; i < s_samples; i++)
{
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u0009\u0009\u0009", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000A\u000A\u000A", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000B\u000B\u000B", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000C\u000C\u000C", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000D\u000D\u000D", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u0020\u0020\u0020", ns, ((ns & NumberStyles.AllowTrailingWhite) != 0));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u0009\u0009\u0009", ns, FailureNotExpectedForTrailingWhite(ns, false));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000A\u000A\u000A", ns, FailureNotExpectedForTrailingWhite(ns, false));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000B\u000B\u000B", ns, FailureNotExpectedForTrailingWhite(ns, false));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000C\u000C\u000C", ns, FailureNotExpectedForTrailingWhite(ns, false));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u000D\u000D\u000D", ns, FailureNotExpectedForTrailingWhite(ns, false));
VerifyParseToString(GetDigitSequence(1, 100, random) + "\u0020\u0020\u0020", ns, FailureNotExpectedForTrailingWhite(ns, true));
}

// Leading Sign
Expand Down Expand Up @@ -694,6 +720,31 @@ private static NumberFormatInfo MarkUp(NumberFormatInfo nfi)
return nfi;
}

// We need to account for cultures like fr-FR and uk-UA that use the no-break space (NBSP, 0xA0)
// character as the group separator. Because NBSP cannot be (easily) entered by the end user we
// accept regular spaces (SP, 0x20) as group separators for those cultures which means that
// trailing SP characters will be interpreted as group separators rather than whitespace.
//
// See also System.Globalization.FormatProvider+Number.MatchChars(char*, char*)
private static bool FailureNotExpectedForTrailingWhite(NumberStyles ns, bool spaceOnlyTrail)
{
if (spaceOnlyTrail && (ns & NumberStyles.AllowThousands) != 0)
{
if ((ns & NumberStyles.AllowCurrencySymbol) != 0)
{
if (CultureInfo.CurrentCulture.NumberFormat.CurrencyGroupSeparator == "\u00A0")
return true;
}
else
{
if (CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator == "\u00A0")
return true;
}
}

return (ns & NumberStyles.AllowTrailingWhite) != 0;
}

public static void Eval(BigInteger x, String expected)
{
bool IsPos = (x >= 0);
Expand Down

0 comments on commit a882c66

Please sign in to comment.