Skip to content

Commit 3e103af

Browse files
feat(DecimalFormatter): Implement FormatDouble and ParseDouble
1 parent c3ff19c commit 3e103af

File tree

23 files changed

+703
-315
lines changed

23 files changed

+703
-315
lines changed

src/SamplesApp/SamplesApp.UITests/Microsoft_UI_Xaml_Controls/NumberBoxTests/Given_NumberBox.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ public void UpDownTest()
6767
Assert.AreEqual(55, numBox.GetDependencyPropertyValue<double>("Value"));
6868
}
6969

70+
[Test]
71+
[AutoRetry]
72+
public void DecimalFormatterTest()
73+
{
74+
Run("UITests.Shared.Microsoft_UI_Xaml_Controls.NumberBoxTests.MUX_Test");
75+
76+
var numBox = _app.Marked("TestNumberBox");
77+
Assert.AreEqual(0, numBox.GetDependencyPropertyValue<double>("Value"));
78+
79+
_app.FastTap("MinCheckBox");
80+
_app.FastTap("MaxCheckBox");
81+
_app.Marked("CustomFormatterButton").FastTap();
82+
83+
numBox.ClearText();
84+
numBox.EnterText("۱٫۷");
85+
_app.PressEnter();
86+
87+
Assert.AreEqual("۱٫۷۵", numBox.GetDependencyPropertyValue<string>("Text"));
88+
Assert.AreEqual(1.75, numBox.GetDependencyPropertyValue<double>("Value"));
89+
}
90+
7091
[Test]
7192
[AutoRetry]
7293
public void MinMaxTest()

src/SamplesApp/UITests.Shared/Microsoft_UI_Xaml_Controls/NumberBoxTests/MUX_Test.xaml.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,12 @@ private void NumberBoxValueChanged(object sender, Microsoft.UI.Xaml.Controls.Num
101101

102102
private void CustomFormatterButton_Click(object sender, RoutedEventArgs e)
103103
{
104-
List<string> languages = new List<string>() { "fr-FR" };
105-
DecimalFormatter formatter = new DecimalFormatter(languages, "FR");
104+
DecimalFormatter formatter = new DecimalFormatter();
106105
formatter.IntegerDigits = 1;
107106
formatter.FractionDigits = 2;
107+
formatter.NumeralSystem = "ArabExt";
108+
formatter.NumberRounder = new IncrementNumberRounder { Increment = 0.25 };
109+
108110
TestNumberBox.NumberFormatter = formatter;
109111
}
110112

src/Uno.UI.RuntimeTests/UnitTestsImport.props

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929
<Compile Include="$(MSBuildThisFileDirectory)..\Uno.UI.Tests\Windows_Globalization\Given_NumeralSystemTranslator.cs">
3030
<Link>UnitTests\Windows_Globalization\%(RecursiveDir)%(FileName)%(Extension)</Link>
3131
</Compile>
32+
<Compile Include="$(MSBuildThisFileDirectory)..\Uno.UI.Tests\Windows_Globalization\Given_DecimalFormatter.cs">
33+
<Link>UnitTests\Windows_Globalization\%(RecursiveDir)%(FileName)%(Extension)</Link>
34+
</Compile>
35+
<Compile Include="$(MSBuildThisFileDirectory)..\Uno.UI.Tests\Windows_Globalization\Given_PercentFormatter.cs">
36+
<Link>UnitTests\Windows_Globalization\%(RecursiveDir)%(FileName)%(Extension)</Link>
37+
</Compile>
38+
<Compile Include="$(MSBuildThisFileDirectory)..\Uno.UI.Tests\Windows_Globalization\Given_PermilleFormatter.cs">
39+
<Link>UnitTests\Windows_Globalization\%(RecursiveDir)%(FileName)%(Extension)</Link>
40+
</Compile>
3241
</ItemGroup>
3342

3443

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+

2+
using System;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Windows.Globalization.NumberFormatting;
5+
6+
namespace Uno.UI.Tests.Windows_Globalization
7+
{
8+
[TestClass]
9+
public class Given_DecimalFormatter
10+
{
11+
[DataTestMethod]
12+
[DataRow(double.PositiveInfinity, "∞")]
13+
[DataRow(double.NegativeInfinity, "-∞")]
14+
[DataRow(double.NaN, "NaN")]
15+
public void When_FormatSpecialDouble(double value, string expected)
16+
{
17+
DecimalFormatter df = new DecimalFormatter();
18+
var actual = df.FormatDouble(value);
19+
20+
Assert.AreEqual(expected, actual);
21+
}
22+
23+
[DataTestMethod]
24+
[DataRow(1.5d, 1, 2, "1.50")]
25+
[DataRow(1.567d, 1, 2, "1.567")]
26+
[DataRow(1.5602d, 1, 2, "1.5602")]
27+
[DataRow(0d, 0, 0, "0")]
28+
[DataRow(-0d, 0, 0, "0")]
29+
[DataRow(0d, 0, 2, ".00")]
30+
[DataRow(-0d, 0, 2, ".00")]
31+
[DataRow(0d, 2, 0, "00")]
32+
[DataRow(-0d, 2, 0, "00")]
33+
[DataRow(0d, 3, 1, "000.0")]
34+
[DataRow(-0d, 3, 1, "000.0")]
35+
public void When_FormatDouble(double value, int integerDigits, int fractionDigits, string expected)
36+
{
37+
DecimalFormatter df = new DecimalFormatter();
38+
df.IntegerDigits = integerDigits;
39+
df.FractionDigits = fractionDigits;
40+
41+
var formatted = df.FormatDouble(value);
42+
Assert.AreEqual(expected, formatted);
43+
}
44+
45+
[DataTestMethod]
46+
[DataRow(1234, 2, 0, "1,234")]
47+
[DataRow(1234, 6, 0, "001,234")]
48+
[DataRow(1234.56, 2, 2, "1,234.56")]
49+
[DataRow(1234.0, 6, 2, "001,234.00")]
50+
[DataRow(1234.0, 6, 0, "001,234")]
51+
public void When_FormatDoubleWithIsGroupSetTrue(double value, int integerDigits, int fractionDigits, string expected)
52+
{
53+
DecimalFormatter df = new DecimalFormatter();
54+
df.IntegerDigits = integerDigits;
55+
df.FractionDigits = fractionDigits;
56+
df.IsGrouped = true;
57+
58+
var formatted = df.FormatDouble(value);
59+
Assert.AreEqual(expected, formatted);
60+
}
61+
62+
[DataTestMethod]
63+
[DataRow(0, 0, "-0")]
64+
[DataRow(0, 2, "-.00")]
65+
[DataRow(2, 0, "-00")]
66+
[DataRow(3, 1, "-000.0")]
67+
public void When_FormatDoubleMinusZeroWithIsZeroSignedSetTrue(int integerDigits, int fractionDigits, string expected)
68+
{
69+
DecimalFormatter df = new DecimalFormatter();
70+
df.IntegerDigits = integerDigits;
71+
df.FractionDigits = fractionDigits;
72+
df.IsZeroSigned = true;
73+
74+
var formatted = df.FormatDouble(-0d);
75+
Assert.AreEqual(expected, formatted);
76+
}
77+
78+
[DataTestMethod]
79+
[DataRow(0, 0, "0")]
80+
[DataRow(0, 2, ".00")]
81+
[DataRow(2, 0, "00")]
82+
[DataRow(3, 1, "000.0")]
83+
public void When_FormatDoubleZeroWithIsZeroSignedSetTrue(int integerDigits, int fractionDigits, string expected)
84+
{
85+
DecimalFormatter df = new DecimalFormatter();
86+
df.IntegerDigits = integerDigits;
87+
df.FractionDigits = fractionDigits;
88+
df.IsZeroSigned = true;
89+
90+
var formatted = df.FormatDouble(0d);
91+
Assert.AreEqual(expected, formatted);
92+
}
93+
94+
[DataTestMethod]
95+
[DataRow(1d, "1.")]
96+
public void When_FormatDoubleWithIsDecimalPointerAlwaysDisplayedSetTrue(double value, string expected)
97+
{
98+
DecimalFormatter df = new DecimalFormatter();
99+
df.IsDecimalPointAlwaysDisplayed = true;
100+
df.FractionDigits = 0;
101+
df.IntegerDigits = 0;
102+
103+
var formatted = df.FormatDouble(value);
104+
Assert.AreEqual(expected, formatted);
105+
}
106+
107+
[DataTestMethod]
108+
[DataRow(123.4567d, 5, 1, 2, "123.4567")]
109+
[DataRow(123.4567d, 10, 1, 2, "123.4567000")]
110+
[DataRow(123.4567d, 2, 1, 2, "123.4567")]
111+
[DataRow(12.3d, 4, 1, 2, "12.30")]
112+
[DataRow(12.3d, 4, 1, 0, "12.30")]
113+
public void When_FormatDoubleWithSpecificSignificantDigits(double value, int significantDigits, int integerDigits, int fractionDigits, string expected)
114+
{
115+
DecimalFormatter df = new DecimalFormatter();
116+
df.SignificantDigits = significantDigits;
117+
df.IntegerDigits = integerDigits;
118+
df.FractionDigits = fractionDigits;
119+
120+
var formatted = df.FormatDouble(value);
121+
Assert.AreEqual(expected, formatted);
122+
}
123+
124+
[TestMethod]
125+
public void When_FormatDoubleUsingIncrementNumberRounder()
126+
{
127+
DecimalFormatter df = new DecimalFormatter();
128+
IncrementNumberRounder rounder = new IncrementNumberRounder();
129+
rounder.Increment = 0.5;
130+
df.NumberRounder = rounder;
131+
var formatted = df.FormatDouble(1.8);
132+
133+
Assert.AreEqual("2.00", formatted);
134+
}
135+
136+
[TestMethod]
137+
public void When_FormatDoubleUsingSignificantDigitsNumberRounder()
138+
{
139+
DecimalFormatter df = new DecimalFormatter();
140+
SignificantDigitsNumberRounder rounder = new SignificantDigitsNumberRounder();
141+
rounder.SignificantDigits = 1;
142+
df.NumberRounder = rounder;
143+
var formatted = df.FormatDouble(1.8);
144+
145+
Assert.AreEqual("2.00", formatted);
146+
}
147+
148+
[TestMethod]
149+
public void When_Initialize()
150+
{
151+
DecimalFormatter df = new DecimalFormatter();
152+
153+
Assert.AreEqual(0, df.SignificantDigits);
154+
Assert.AreEqual(1, df.IntegerDigits);
155+
Assert.AreEqual(2, df.FractionDigits);
156+
Assert.AreEqual(false, df.IsGrouped);
157+
Assert.AreEqual(false, df.IsZeroSigned);
158+
Assert.AreEqual(false, df.IsDecimalPointAlwaysDisplayed);
159+
Assert.AreEqual("en-US", df.ResolvedLanguage);
160+
Assert.IsNull(df.NumberRounder);
161+
/*
162+
FractionDigits 2 int
163+
GeographicRegion "US" string
164+
IntegerDigits 1 int
165+
IsDecimalPointAlwaysDisplayed false bool
166+
IsGrouped false bool
167+
IsZeroSigned false bool
168+
NumberRounder null WindoGlobalization.NumberFormatting.INumberRounder
169+
NumeralSystem "Latn" string
170+
ResolvedGeographicRegion "ZZ" string
171+
ResolvedLanguage "en-US" string
172+
SignificantDigits 0 int
173+
174+
*/
175+
}
176+
177+
[DataTestMethod]
178+
[DataRow("1.2", 1.2)]
179+
[DataRow("1.20", 1.2)]
180+
[DataRow("12,34.2", null)]
181+
[DataRow("0", 0d)]
182+
public void When_ParseDouble(string value, double? expected)
183+
{
184+
DecimalFormatter df = new DecimalFormatter();
185+
df.FractionDigits = 2;
186+
187+
var actual = df.ParseDouble(value);
188+
Assert.AreEqual(expected, actual);
189+
}
190+
191+
[DataTestMethod]
192+
[DataRow("1234.2", 1234.2)]
193+
[DataRow("1,234.2", 1234.2)]
194+
[DataRow("12,34.2", null)]
195+
public void When_ParseDoubleAndIsGroupSetTrue(string value, double? expected)
196+
{
197+
DecimalFormatter df = new DecimalFormatter();
198+
df.FractionDigits = 2;
199+
df.IsGrouped = true;
200+
201+
var actual = df.ParseDouble(value);
202+
Assert.AreEqual(expected, actual);
203+
}
204+
205+
[DataTestMethod]
206+
[DataRow("1", 1d)]
207+
[DataRow("1.", 1d)]
208+
public void When_ParseDoubleAndIsDecimalPointAlwaysDisplayedSetTrue(string value, double? expected)
209+
{
210+
DecimalFormatter df = new DecimalFormatter();
211+
df.FractionDigits = 2;
212+
df.IsDecimalPointAlwaysDisplayed = true;
213+
214+
var actual = df.ParseDouble(value);
215+
Assert.AreEqual(expected, actual);
216+
}
217+
218+
[TestMethod]
219+
public void When_ParseDoubleMinusZero()
220+
{
221+
DecimalFormatter df = new DecimalFormatter();
222+
var actual = df.ParseDouble("-0");
223+
bool isNegative = false;
224+
225+
if (actual.HasValue)
226+
{
227+
isNegative = BitConverter.DoubleToInt64Bits(actual.Value) < 0;
228+
}
229+
230+
Assert.AreEqual(true, isNegative);
231+
}
232+
233+
[DataTestMethod]
234+
[DataRow("Arab")]
235+
[DataRow("ArabExt")]
236+
[DataRow("Bali")]
237+
[DataRow("Beng")]
238+
[DataRow("Cham")]
239+
[DataRow("Deva")]
240+
[DataRow("FullWide")]
241+
[DataRow("Gujr")]
242+
[DataRow("Guru")]
243+
[DataRow("Java")]
244+
[DataRow("Kali")]
245+
[DataRow("Khmr")]
246+
[DataRow("Knda")]
247+
[DataRow("Lana")]
248+
[DataRow("LanaTham")]
249+
[DataRow("Laoo")]
250+
[DataRow("Latn")]
251+
[DataRow("Lepc")]
252+
[DataRow("Limb")]
253+
[DataRow("Mlym")]
254+
[DataRow("Mong")]
255+
[DataRow("Mtei")]
256+
[DataRow("Mymr")]
257+
[DataRow("MymrShan")]
258+
[DataRow("Nkoo")]
259+
[DataRow("Olck")]
260+
[DataRow("Orya")]
261+
[DataRow("Saur")]
262+
[DataRow("Sund")]
263+
[DataRow("Talu")]
264+
[DataRow("TamlDec")]
265+
[DataRow("Telu")]
266+
[DataRow("Thai")]
267+
[DataRow("Tibt")]
268+
[DataRow("Vaii")]
269+
public void When_ParseDoubleUsingSpeceficNumeralSystem(string numeralSystem)
270+
{
271+
DecimalFormatter df = new DecimalFormatter();
272+
df.NumeralSystem = numeralSystem;
273+
274+
var translator = new NumeralSystemTranslator { NumeralSystem = numeralSystem };
275+
var translated = translator.TranslateNumerals("1234.56789");
276+
277+
var actual = df.ParseDouble(translated);
278+
Assert.AreEqual(1234.56789, actual);
279+
}
280+
281+
[TestMethod]
282+
public void When_ParseNotValidDouble()
283+
{
284+
DecimalFormatter df = new DecimalFormatter();
285+
286+
var actual = df.ParseDouble("a12");
287+
Assert.AreEqual(null, actual);
288+
}
289+
}
290+
}

0 commit comments

Comments
 (0)