Skip to content

Commit 042245e

Browse files
committed
♻️🧪Use CultureScope in tests to revert CurrentCulture changes
Use `CultureScope` instead of try-catch, simpler syntax. Add `CultureScope` to some test cases that previously did not revert their changes to CurrentCulture, to avoid flaky tests.
1 parent 350d5eb commit 042245e

File tree

7 files changed

+58
-42
lines changed

7 files changed

+58
-42
lines changed

CodeGen/Generators/UnitsNetGen/UnitTestBaseClassGenerator.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -597,20 +597,13 @@ public void BaseDimensionsShouldNeverBeNull()
597597
[Fact]
598598
public void ToString_ReturnsValueAndUnitAbbreviationInCurrentCulture()
599599
{{
600-
var prevCulture = Thread.CurrentThread.CurrentCulture;
601-
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(""en-US"");
602-
try {{");
600+
using var _ = new CultureScope(""en-US"");");
603601
foreach (var unit in _quantity.Units)
604602
{
605603
Writer.WL($@"
606-
Assert.Equal(""1{GetEnglishAbbreviation(unit)}"", new {_quantity.Name}(1, {GetUnitFullName(unit)}).ToString());");
604+
Assert.Equal(""1{GetEnglishAbbreviation(unit)}"", new {_quantity.Name}(1, {GetUnitFullName(unit)}).ToString());");
607605
}
608606
Writer.WL($@"
609-
}}
610-
finally
611-
{{
612-
Thread.CurrentThread.CurrentCulture = prevCulture;
613-
}}
614607
}}
615608
616609
[Fact]
@@ -630,19 +623,11 @@ public void ToString_WithSwedishCulture_ReturnsUnitAbbreviationForEnglishCulture
630623
[Fact]
631624
public void ToString_SFormat_FormatsNumberWithGivenDigitsAfterRadixForCurrentCulture()
632625
{{
633-
var oldCulture = CultureInfo.CurrentCulture;
634-
try
635-
{{
636-
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
637-
Assert.Equal(""0.1{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s1""));
638-
Assert.Equal(""0.12{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s2""));
639-
Assert.Equal(""0.123{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s3""));
640-
Assert.Equal(""0.1235{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s4""));
641-
}}
642-
finally
643-
{{
644-
CultureInfo.CurrentCulture = oldCulture;
645-
}}
626+
var _ = new CultureScope(CultureInfo.InvariantCulture);
627+
Assert.Equal(""0.1{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s1""));
628+
Assert.Equal(""0.12{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s2""));
629+
Assert.Equal(""0.123{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s3""));
630+
Assert.Equal(""0.1235{_baseUnitEnglishAbbreviation}"", new {_quantity.Name}(0.123456{_numberSuffix}, {_baseUnitFullName}).ToString(""s4""));
646631
}}
647632
648633
[Fact]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ var oneKg = Mass.FromKilograms(1);
9898

9999
// ToString() uses CurrentCulture for abbreviation language number formatting. This is consistent with the behavior of the .NET Framework,
100100
// where DateTime.ToString() uses CurrentCulture for the whole string, likely because mixing an english date format with a russian month name might be confusing.
101-
Thread.CurrentThread.CurrentCulture = russian;
101+
CultureInfo.CurrentCulture = russian;
102102
string kgRu = oneKg.ToString(); // "1 кг"
103103
104104
// ToString() with specific culture and custom string format pattern
@@ -362,7 +362,7 @@ double convertedValue = UnitConverter.Convert(
362362
### Example: WPF app using IValueConverter to parse input
363363

364364
Src: [Samples/MvvmSample.Wpf](https://github.com/angularsen/UnitsNet/tree/master/Samples/MvvmSample.Wpf)
365-
365+
366366
![wpfmvvmsample_219w](https://user-images.githubusercontent.com/787816/34913417-094332e2-f8fd-11e7-9d8a-92db105fbbc9.png)
367367
368368
The purpose of this app is to show how to create an `IValueConverter` in order to bind XAML to quantities.

UnitsNet.Tests/CustomCode/StonePoundsTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System.Globalization;
5+
using UnitsNet.Tests.Helpers;
56
using Xunit;
67

78
namespace UnitsNet.Tests
@@ -33,7 +34,7 @@ public void StonePoundsRoundTrip()
3334
[Fact]
3435
public void StonePoundsToString_FormatsNumberInCurrentCulture()
3536
{
36-
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
37+
using var _ = new CultureScope("en-US");
3738
StonePounds stonePounds = Mass.FromStonePounds(3500, 1).StonePounds;
3839

3940
Assert.Equal("3,500 st 1 lb", stonePounds.ToString());
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
2+
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
3+
4+
using System;
5+
using System.Globalization;
6+
7+
namespace UnitsNet.Tests.Helpers;
8+
9+
public sealed class CultureScope : IDisposable
10+
{
11+
private readonly CultureInfo _originalCulture;
12+
private readonly CultureInfo _originalUiCulture;
13+
14+
public CultureScope(string cultureName) : this(CultureInfo.GetCultureInfo(cultureName))
15+
{
16+
}
17+
18+
public CultureScope(CultureInfo culture) : this(culture, culture)
19+
{
20+
}
21+
22+
public CultureScope(CultureInfo culture, CultureInfo uiCulture)
23+
{
24+
_originalCulture = CultureInfo.CurrentCulture;
25+
_originalUiCulture = CultureInfo.CurrentUICulture;
26+
27+
CultureInfo.CurrentCulture = culture;
28+
CultureInfo.CurrentUICulture = uiCulture;
29+
}
30+
31+
public void Dispose()
32+
{
33+
CultureInfo.CurrentCulture = _originalCulture;
34+
CultureInfo.CurrentUICulture = _originalUiCulture;
35+
}
36+
}

UnitsNet.Tests/QuantityTests.ToString.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Globalization;
6+
using UnitsNet.Tests.Helpers;
67
using UnitsNet.Units;
78
using Xunit;
89

@@ -31,18 +32,10 @@ public void ReturnsTheOriginalValueAndUnit()
3132
[Fact]
3233
public void FormatsNumberUsingGivenCulture()
3334
{
34-
var oldCulture = CultureInfo.CurrentCulture;
35-
try
36-
{
37-
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
38-
Assert.Equal("0.05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString((IFormatProvider?)null));
39-
Assert.Equal("0.05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString(CultureInfo.InvariantCulture));
40-
Assert.Equal("0,05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString(CultureInfo.GetCultureInfo("nb-NO")));
41-
}
42-
finally
43-
{
44-
CultureInfo.CurrentCulture = oldCulture;
45-
}
35+
using var _ = new CultureScope(CultureInfo.InvariantCulture);
36+
Assert.Equal("0.05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString((IFormatProvider?)null));
37+
Assert.Equal("0.05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString(CultureInfo.InvariantCulture));
38+
Assert.Equal("0,05 m", Length.FromCentimeters(5).ToUnit(LengthUnit.Meter).ToString(CultureInfo.GetCultureInfo("nb-NO")));
4639
}
4740
}
4841
}

UnitsNet.Tests/QuantityTypeConverterTest.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,12 @@ public void ConvertTo_GivenSomeQuantityAndContextWithDisplayAsUnitAttributes_Ret
242242
});
243243
Length length = Length.FromMeters(1);
244244

245-
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
246-
245+
// Act
246+
using var _ = new CultureScope(Culture);
247247
string convertedQuantityCurrentCulture = (string)converter.ConvertTo(length, typeof(string))!;
248248
string convertedQuantitySpecificCulture = (string)converter.ConvertTo(context, Culture, length, typeof(string))!;
249249

250+
// Assert
250251
Assert.Equal("1 m", convertedQuantityCurrentCulture);
251252
Assert.Equal("10 dm", convertedQuantitySpecificCulture);
252253
}
@@ -259,8 +260,9 @@ public void ConvertTo_GivenCurrentCulture_ReturnValueFormattedAccordingToGivenCu
259260
QuantityTypeConverter<Length> converter = new();
260261
var attributes = useDisplayAsAttribute ? new Attribute[] { new DisplayAsUnitAttribute(Units.LengthUnit.Meter) } : Array.Empty<Attribute>();
261262
ITypeDescriptorContext context = new TypeDescriptorContext("SomeMemberName", attributes);
262-
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("de-AT"); // uses comma as decimal separator
263-
CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture; // uses dot as decimal separator
263+
using var _ = new CultureScope(
264+
culture: CultureInfo.GetCultureInfo("de-AT"), // uses comma as decimal separator
265+
uiCulture: CultureInfo.InvariantCulture); // uses dot as decimal separator
264266
Length length = Length.FromMeters(1.5);
265267
string expectedResult = length.ToString(CultureInfo.CurrentCulture);
266268

UnitsNet.Tests/UnitAbbreviationsCacheTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ public void GetDefaultAbbreviationFallsBackToUsEnglishCulture()
217217
// CurrentCulture also affects localization of unit abbreviations.
218218
// Zulu (South Africa)
219219
var zuluCulture = CultureInfo.GetCultureInfo("zu-ZA");
220-
// CultureInfo.CurrentCulture = zuluCulture;
221220

222221
var abbreviationsCache = new UnitAbbreviationsCache();
223222
abbreviationsCache.MapUnitToAbbreviation(CustomUnit.Unit1, AmericanCulture, "US english abbreviation for Unit1");

0 commit comments

Comments
 (0)