Skip to content

Commit

Permalink
Handle download count round up to 1E+3K for when 999,500 <= count <=9…
Browse files Browse the repository at this point in the history
…99,999 (#4255)

* Fix formatting includes E exponential.

* Add localization of format.
  • Loading branch information
erdembayar authored Sep 14, 2021
1 parent b4ffeca commit 0d46dd8
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 25 deletions.
36 changes: 36 additions & 0 deletions src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1005,4 +1005,20 @@ Please see https://aka.ms/troubleshoot_nuget_cache for more help.</value>
<value>This package version is deprecated. Use {0} instead.</value>
<comment>{0} is a NuGet package id (string)</comment>
</data>
<data name="Billion" xml:space="preserve">
<value>{0:G3}B</value>
<comment>American billions in short format notation</comment>
</data>
<data name="Million" xml:space="preserve">
<value>{0:G3}M</value>
<comment>Millions in short format notation</comment>
</data>
<data name="Thousand" xml:space="preserve">
<value>{0:G3}K</value>
<comment>Thousands in short format notation</comment>
</data>
<data name="Trillion" xml:space="preserve">
<value>{0:G3}T</value>
<comment>American trillions in short format notation</comment>
</data>
</root>
47 changes: 28 additions & 19 deletions src/NuGet.Clients/NuGet.PackageManagement.UI/Utility/UIUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,42 @@ private static bool IsHttpUrl(Uri uri)
return (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
}

private static readonly string[] _scalingFactor = new string[] {
String.Empty,
"K", // kilo
"M", // mega, million
"G", // giga, billion
"T" // tera, trillion
};

// Convert numbers into strings like "1.2K", "33.4M" etc.
// Precondition: number > 0.
public static string NumberToString(long number, IFormatProvider culture)
{
double v = (double)number;
int exp = 0;
double RoundDown(double num, long precision)
{
double val = num / precision;
return val > 999 ? 999 : val;
}

const long thousand = 1_000L;
const long million = 1_000_000L;
const long billion = 1_000_000_000L;
const long trillion = 1_000_000_000_000L;

if (number < thousand)
{
return number.ToString("G0", culture);
}

if (number < million)
{
return string.Format(culture, Resources.Thousand, RoundDown(number, thousand));
}

if (number < billion)
{
return string.Format(culture, Resources.Million, RoundDown(number, million));
}

while (v >= 1000)
if (number < trillion)
{
v /= 1000;
++exp;
return string.Format(culture, Resources.Billion, RoundDown(number, billion));
}

var s = string.Format(
culture,
"{0:G3}{1}",
v,
_scalingFactor[exp]);
return s;
return string.Format(culture, Resources.Trillion, RoundDown(number, trillion));
}

public static string CreateSearchQuery(string query)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public class ConverterTests
{
[Theory]
[InlineData(1, "1")]
[InlineData(90, "90")]
[InlineData(451, "451")]
[InlineData(550, "550")]
[InlineData(998, "998")]
[InlineData(999, "999")]
[InlineData(1000, "1K")]
[InlineData(1200, "1.2K")]
Expand All @@ -21,14 +25,48 @@ public class ConverterTests

// there is rounding
[InlineData(1239, "1.24K")]
[InlineData(9056, "9.06K")]
[InlineData(19_056, "19.1K")]
[InlineData(19_556, "19.6K")]
[InlineData(99_056, "99.1K")]
[InlineData(99_556, "99.6K")]

[InlineData(123400, "123K")]
[InlineData(1234000, "1.23M")]
[InlineData(12340000, "12.3M")]
[InlineData(1234000000, "1.23G")]
public void DownloadCountToStringTest(int num, string expected)
[InlineData(123_400, "123K")]
[InlineData(899_560, "900K")]
[InlineData(998_999, "999K")]
[InlineData(999_001, "999K")]
[InlineData(999_560, "999K")]
[InlineData(1_234_000, "1.23M")]
[InlineData(1_299_560, "1.3M")]
[InlineData(9_995_650, "10M")]
[InlineData(12_340_000, "12.3M")]
[InlineData(19_991_250, "20M")]
[InlineData(19_999_850, "20M")]
[InlineData(99_156_050, "99.2M")]
[InlineData(99_999_650, "100M")]
[InlineData(999_560_050, "999M")]
[InlineData(999_999_050, "999M")]
[InlineData(1_000_000_001, "1B")]
[InlineData(1_234_000_000, "1.23B")]
[InlineData(2_100_999_050, "2.1B")]
[InlineData(9_234_000_000, "9.23B")]
[InlineData(9_999_900_000, "10B")]
[InlineData(99_199_199_650, "99.2B")]
[InlineData(99_999_999_650, "100B")]
[InlineData(999_999_999_650, "999B")]
[InlineData(9_999_999_999_650, "10T")]
[InlineData(19_999_999_999_050, "20T")]
[InlineData(99_999_999_999_650, "100T")]

// there is localization
[InlineData(1939, "1.94K", "en-US")]
[InlineData(1939, "1,94K", "da-DK")]
[InlineData(9456, "9.46K", "en-US")]
[InlineData(9456, "9,46K", "da-DK")]
public void DownloadCountToStringTest(long num, string expected, string culture = null)
{
var s = UIUtility.NumberToString(num, CultureInfo.InvariantCulture); // force '.' decimal separator
CultureInfo localCulture = string.IsNullOrWhiteSpace(culture) ? CultureInfo.InvariantCulture : new CultureInfo(culture); // Here CultureInfo.InvariantCulture forces '.' decimal separator
var s = UIUtility.NumberToString(num, localCulture);
Assert.Equal(expected, s);
}
}
Expand Down

0 comments on commit 0d46dd8

Please sign in to comment.