From 164db20fd5b9d946ee6b921b2cc4e22a23dd1d20 Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 8 Jan 2021 23:06:23 -0500 Subject: [PATCH 01/23] [wasm] Throw exception if culture data does not exist in icu --- .../src/System/Globalization/CultureInfo.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 5a071799bbb05..3ffa51a289f27 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -170,7 +170,6 @@ public CultureInfo(string name, bool useUserOverride) // Get our data providing record CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride); - if (cultureData == null) { throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); @@ -197,7 +196,6 @@ private CultureInfo(CultureData cultureData, bool isReadOnly = false) { return null; } - return new CultureInfo(cultureData); } @@ -290,6 +288,7 @@ private static CultureInfo GetCultureByName(string name) public static CultureInfo CreateSpecificCulture(string name) { CultureInfo? culture; + IcuGetPredefinedCultureInfo(name); try { @@ -330,7 +329,6 @@ public static CultureInfo CreateSpecificCulture(string name) { return culture; } - return new CultureInfo(culture._cultureData.SpecificCultureName); } @@ -1093,7 +1091,6 @@ public static CultureInfo GetCultureInfo(string name) return result; } } - result = CreateCultureInfoNoThrow(name, useUserOverride: false) ?? throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); result._isReadOnly = true; From fd96d0cd4c09a48fb0680735197294c83bcb8e58 Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 8 Jan 2021 23:14:39 -0500 Subject: [PATCH 02/23] add lines --- .../src/System/Globalization/CultureInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 3ffa51a289f27..4981781aebe3e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -170,6 +170,7 @@ public CultureInfo(string name, bool useUserOverride) // Get our data providing record CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride); + if (cultureData == null) { throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); @@ -196,6 +197,7 @@ private CultureInfo(CultureData cultureData, bool isReadOnly = false) { return null; } + return new CultureInfo(cultureData); } @@ -329,6 +331,7 @@ public static CultureInfo CreateSpecificCulture(string name) { return culture; } + return new CultureInfo(culture._cultureData.SpecificCultureName); } @@ -1091,6 +1094,7 @@ public static CultureInfo GetCultureInfo(string name) return result; } } + result = CreateCultureInfoNoThrow(name, useUserOverride: false) ?? throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); result._isReadOnly = true; From 68a4fa3c4b6ce45f690bccc470c432e955a46be5 Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 8 Jan 2021 23:14:39 -0500 Subject: [PATCH 03/23] add lines --- .../src/System/Globalization/CultureInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 3ffa51a289f27..accb152abf226 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -170,6 +170,7 @@ public CultureInfo(string name, bool useUserOverride) // Get our data providing record CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride); + if (cultureData == null) { throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); @@ -196,6 +197,7 @@ private CultureInfo(CultureData cultureData, bool isReadOnly = false) { return null; } + return new CultureInfo(cultureData); } @@ -329,6 +331,7 @@ public static CultureInfo CreateSpecificCulture(string name) { return culture; } + return new CultureInfo(culture._cultureData.SpecificCultureName); } @@ -1091,6 +1094,7 @@ public static CultureInfo GetCultureInfo(string name) return result; } } + result = CreateCultureInfoNoThrow(name, useUserOverride: false) ?? throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); result._isReadOnly = true; From d92afab4239d442ac177136feaaaa7ec0e5f478e Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 22 Jan 2021 17:02:57 -0500 Subject: [PATCH 04/23] Add check for culture data in ICU Add PredefinedOnly GlobalizationMode Modified tests if Culture Data not found --- .../Common/tests/Tests/System/StringTests.cs | 10 ++++++++- .../src/System/Globalization/CultureData.cs | 8 +++++++ .../src/System/Globalization/CultureInfo.cs | 1 - .../Globalization/GlobalizationMode.Unix.cs | 2 ++ .../tests/System/DateTimeTests.cs | 22 ++++++++++++++++--- src/mono/wasm/runtime/library_mono.js | 3 +++ 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index 305c0efc6b450..115ff1882215d 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -2567,8 +2567,16 @@ public void Equals_Encyclopaedia_ReturnsExpected(StringComparison comparison, bo { string source = "encyclop\u00e6dia"; string target = "encyclopaedia"; + ThreadCultureChange culture; + if (PlatformDetection.IsBrowser) + { + culture = new ThreadCultureChange("pl-PL"); + } else + { + culture = new ThreadCultureChange("se-SE"); + } - using (new ThreadCultureChange("se-SE")) + using (culture) { Assert.Equal(expected, string.Equals(source, target, comparison)); Assert.Equal(expected, source.AsSpan().Equals(target.AsSpan(), comparison)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 76e95e087dd3a..ab0d9fb2d33dd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -803,6 +803,14 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return CultureData.Invariant; } + if (GlobalizationMode.PredefinedOnly) + { + if (!Interop.Globalization.IsPredefinedLocale(cultureName)) + { + throw new CultureNotFoundException(nameof(cultureName), SR.Format(SR.Argument_InvalidPredefinedCultureName, cultureName)); + } + } + CultureData culture = new CultureData(); culture._sRealName = cultureName; culture._bUseOverridesUserSetting = useUserOverride; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index accb152abf226..5a071799bbb05 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -290,7 +290,6 @@ private static CultureInfo GetCultureByName(string name) public static CultureInfo CreateSpecificCulture(string name) { CultureInfo? culture; - IcuGetPredefinedCultureInfo(name); try { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index 7d91ed4713a1f..de2120c451d61 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -11,6 +11,8 @@ internal static partial class GlobalizationMode internal static bool UseNls => false; + internal static bool PredefinedOnly { get; } = GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); + private static bool GetGlobalizationInvariantMode() { bool invariantEnabled = GetInvariantSwitchValue(); diff --git a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs index 9a222860a3fd4..6014be6d194b1 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs @@ -1551,7 +1551,15 @@ public static void TryParseExact_EmptyAMPMDesignator() [Fact] public static void ParseExact_EscapedSingleQuotes() { - var formatInfo = DateTimeFormatInfo.GetInstance(new CultureInfo("mt-MT")); + DateTimeFormatInfo formatInfo; + if (PlatformDetection.IsBrowser) + { + formatInfo = DateTimeFormatInfo.GetInstance(new CultureInfo("id-ID")); + } + else + { + formatInfo = DateTimeFormatInfo.GetInstance(new CultureInfo("mt-MT")); + } const string format = @"dddd, d' ta\' 'MMMM yyyy"; DateTime expected = new DateTime(1999, 2, 28, 17, 00, 01); @@ -1735,8 +1743,16 @@ public static IEnumerable Parse_ValidInput_Succeeds_MemberData() hebrewCulture.DateTimeFormat.Calendar = new HebrewCalendar(); yield return new object[] { today.ToString(hebrewCulture), hebrewCulture, today }; - var mongolianCulture = new CultureInfo("mn-MN"); - yield return new object[] { today.ToString(mongolianCulture), mongolianCulture, today }; + CultureInfo culture; + if (PlatformDetection.IsBrowser) + { + culture = new CultureInfo("pl-PL"); + } + else + { + culture = new CultureInfo("mn-MN"); + } + yield return new object[] { today.ToString(culture), culture, today }; } } diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 47b454a8cdcfc..55481146ac4cf 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1904,6 +1904,9 @@ var MonoSupportLib = { if (invariantMode) this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1"); + + // Set globalization mode to PredefinedOnly + this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY", "1"); }, // Used by the debugger to enumerate loaded dlls and pdbs From df4d910604f9eeb397d2eb8ff6db82fd53972de5 Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 22 Jan 2021 17:33:21 -0500 Subject: [PATCH 05/23] include documentation link in exception message --- .../src/System/Globalization/CultureData.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index ab0d9fb2d33dd..0071d467b4975 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -807,7 +807,8 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) { if (!Interop.Globalization.IsPredefinedLocale(cultureName)) { - throw new CultureNotFoundException(nameof(cultureName), SR.Format(SR.Argument_InvalidPredefinedCultureName, cultureName)); + throw new CultureNotFoundException(nameof(cultureName), SR.Format(SR.Argument_InvalidPredefinedCultureName, cultureName), + message: "View https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#blazor-webassembly to load a new culture"); } } From 71670476fba72c4bf6257e74acf63adb05193e7f Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 22 Jan 2021 17:49:53 -0500 Subject: [PATCH 06/23] Add PredefinedOnly to Windows --- .../src/System/Globalization/GlobalizationMode.Unix.cs | 2 +- .../src/System/Globalization/GlobalizationMode.Windows.cs | 2 ++ .../src/System/Globalization/GlobalizationMode.cs | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index de2120c451d61..40a48240a62ae 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -11,7 +11,7 @@ internal static partial class GlobalizationMode internal static bool UseNls => false; - internal static bool PredefinedOnly { get; } = GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); + internal static bool PredefinedOnly { get; } = GetPredefinedOnly(); private static bool GetGlobalizationInvariantMode() { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs index 1a0bf66c42e56..0c258916274a5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs @@ -9,6 +9,8 @@ internal static partial class GlobalizationMode // So we need Invariant to be initialized first. internal static bool Invariant { get; } = GetInvariantSwitchValue(); + internal static bool PredefinedOnly { get; } = GetPredefinedOnly(); + internal static bool UseNls { get; } = !Invariant && (GetSwitchValue("System.Globalization.UseNls", "DOTNET_SYSTEM_GLOBALIZATION_USENLS") || !LoadIcu()); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 6b90460a2e2b6..48a940b7d0507 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -14,6 +14,9 @@ private static bool GetInvariantSwitchValue() => private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) => TryGetStringValue("System.Globalization.AppLocalIcu", "DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", out value); + internal static bool GetPredefinedOnly() => + GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); + private static bool GetSwitchValue(string switchName, string envVariable) { if (!AppContext.TryGetSwitch(switchName, out bool ret)) From 7c677dc689f5588d56f3d80fc7c40c4773481060 Mon Sep 17 00:00:00 2001 From: tqiu8 Date: Fri, 22 Jan 2021 18:06:46 -0500 Subject: [PATCH 07/23] move checks outside of CultureData.cs --- .../System/Globalization/CultureData.Icu.cs | 18 +++++++++++++----- .../System/Globalization/CultureData.Nls.cs | 12 ++++++++++++ .../src/System/Globalization/CultureData.cs | 9 ++++++--- .../Globalization/GlobalizationMode.Unix.cs | 1 - .../Globalization/GlobalizationMode.Windows.cs | 2 -- .../System/Globalization/GlobalizationMode.cs | 3 +-- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index 8be3854e3b672..15f5acd84af91 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; namespace System.Globalization { @@ -63,11 +64,8 @@ private bool InitIcuCultureDataCore() { _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED; } - _bNeutral = TwoLetterISOCountryName.Length == 0; - _sSpecificCulture = _bNeutral ? IcuLocaleData.GetSpecificCultureName(_sRealName) : _sRealName; - // Remove the sort from sName unless custom culture if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage)) { @@ -110,7 +108,6 @@ private string IcuGetLocaleInfo(LocaleStringData type) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); - Debug.Assert(_sWindowsName != null, "[CultureData.IcuGetLocaleInfo] Expected _sWindowsName to be populated already"); return IcuGetLocaleInfo(_sWindowsName, type); } @@ -138,7 +135,6 @@ private unsafe string IcuGetLocaleInfo(string localeName, LocaleStringData type) Debug.Fail("[CultureData.IcuGetLocaleInfo(LocaleStringData)] Failed"); return string.Empty; } - return new string(buffer); } @@ -226,6 +222,18 @@ private static string IcuGetLanguageDisplayName(string cultureName) return null; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void IcuIsEnsurePredefinedLocaleName(string name) + { + Debug.Assert(!GlobalizationMode.UseNls); + + if (!Interop.Globalization.IsPredefinedLocale(name)) + { + throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name), + message: "View https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#blazor-webassembly to load a new culture"); + } + } + private static string ConvertIcuTimeFormatString(ReadOnlySpan icuFormatString) { Debug.Assert(icuFormatString.Length < ICU_ULOC_FULLNAME_CAPACITY); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 9738d5a289464..17f0f77e74fbb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text; +using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -85,6 +86,17 @@ private int[] NlsGetLocaleInfo(LocaleGroupingData type) return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, _bUseOverrides)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void NlsIsEnsurePredefinedLocaleName(string name) + { + Debug.Assert(GlobalizationMode.UseNls); + + if (CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1) + { + throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); + } + } + private string? NlsGetTimeFormatString() { Debug.Assert(ShouldUseUserOverrideNlsData); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 0071d467b4975..9964539d5b517 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -805,10 +805,13 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) if (GlobalizationMode.PredefinedOnly) { - if (!Interop.Globalization.IsPredefinedLocale(cultureName)) + if (GlobalizationMode.UseNls) { - throw new CultureNotFoundException(nameof(cultureName), SR.Format(SR.Argument_InvalidPredefinedCultureName, cultureName), - message: "View https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#blazor-webassembly to load a new culture"); + NlsIsEnsurePredefinedLocaleName(cultureName); + } + else + { + IcuIsEnsurePredefinedLocaleName(cultureName); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index 40a48240a62ae..0a9fddbed4ca8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -11,7 +11,6 @@ internal static partial class GlobalizationMode internal static bool UseNls => false; - internal static bool PredefinedOnly { get; } = GetPredefinedOnly(); private static bool GetGlobalizationInvariantMode() { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs index 0c258916274a5..1a0bf66c42e56 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.cs @@ -9,8 +9,6 @@ internal static partial class GlobalizationMode // So we need Invariant to be initialized first. internal static bool Invariant { get; } = GetInvariantSwitchValue(); - internal static bool PredefinedOnly { get; } = GetPredefinedOnly(); - internal static bool UseNls { get; } = !Invariant && (GetSwitchValue("System.Globalization.UseNls", "DOTNET_SYSTEM_GLOBALIZATION_USENLS") || !LoadIcu()); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 48a940b7d0507..706b95daf2abc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -14,8 +14,7 @@ private static bool GetInvariantSwitchValue() => private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) => TryGetStringValue("System.Globalization.AppLocalIcu", "DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", out value); - internal static bool GetPredefinedOnly() => - GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); + internal static bool PredefinedOnly { get; } = GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); private static bool GetSwitchValue(string switchName, string envVariable) { From 53151f88c446824ac4283651412354a2b6255fcc Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Mon, 25 Jan 2021 15:48:33 -0500 Subject: [PATCH 08/23] Add test for predefined culture env var Modify Globalization tests to catch unsupported locales Change var names --- .../tests/CultureInfo/CultureInfoAll.cs | 20 +++++++ .../CultureInfo/CultureInfoCurrentCulture.cs | 58 ++++++++++++++----- .../System/Globalization/TextInfoTests.cs | 17 +++++- .../src/System/Globalization/CultureData.cs | 2 +- .../System/Globalization/CultureInfo.Icu.cs | 5 +- .../System/Globalization/CultureInfo.Nls.cs | 5 +- .../System/Globalization/GlobalizationMode.cs | 3 +- src/mono/wasm/runtime/library_mono.js | 4 +- 8 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index 659126b4aeb82..a10436fb4d813 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -809,5 +809,25 @@ public void CultureNotFoundExceptionTest() e = AssertExtensions.Throws("culture", () => new CultureInfo(0x1000)); Assert.Equal(0x1000, e.InvalidCultureId); } + + [Theory] + [InlineData("1", "xx-XY")] + [InlineData("1", "zx-ZY")] + [InlineData("0", "xx-XY")] + [InlineData("0", "zx-ZY")] + public void PredefinedCulturesOnlyEnvVarTest(string predefinedCulturesOnlyEnvVar, string cultureName) + { + Environment.SetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCulturesOnlyEnvVar); + + if (predefinedCulturesOnlyEnvVar == "1") + { + AssertExtensions.Throws(() => new CultureInfo(cultureName)); + } + else + { + CultureInfo ci = new CultureInfo(cultureName); + Assert.Equal(cultureName, ci.Name); + } + } } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs index 4831424e45da9..89fedc78efdec 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -16,17 +16,32 @@ public class CurrentCultureTests [Fact] public void CurrentCulture() { - var newCulture = new CultureInfo(CultureInfo.CurrentCulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); - using (new ThreadCultureChange(newCulture)) + CultureInfo newCulture; + try { - Assert.Equal(CultureInfo.CurrentCulture, newCulture); + newCulture = new CultureInfo(CultureInfo.CurrentCulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); + using (new ThreadCultureChange(newCulture)) + { + Assert.Equal(CultureInfo.CurrentCulture, newCulture); + } + } + catch (CultureNotFoundException) + { + return; } - newCulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(newCulture)) + try + { + newCulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(newCulture)) + { + Assert.Equal(CultureInfo.CurrentCulture, newCulture); + Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); + } + } + catch (CultureNotFoundException) { - Assert.Equal(CultureInfo.CurrentCulture, newCulture); - Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); + return; } } @@ -39,17 +54,32 @@ public void CurrentCulture_Set_Null_ThrowsArgumentNullException() [Fact] public void CurrentUICulture() { - var newUICulture = new CultureInfo(CultureInfo.CurrentUICulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); - using (new ThreadCultureChange(null, newUICulture)) + CultureInfo newUICulture; + try { - Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); + newUICulture = new CultureInfo(CultureInfo.CurrentUICulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); + using (new ThreadCultureChange(null, newUICulture)) + { + Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); + } + } + catch (CultureNotFoundException) + { + return; } - newUICulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(null, newUICulture)) + try + { + newUICulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(null, newUICulture)) + { + Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); + Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); + } + } + catch (CultureNotFoundException) { - Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); - Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); + return; } } diff --git a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index f0c56f385c146..dda1a63976f66 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs @@ -307,7 +307,13 @@ private static void TestToLower(string name, string str, string expected) [MemberData(nameof(ToLower_TestData))] public void ToLower(string name, string str, string expected) { - TestToLower(name, str, expected); + try{ + TestToLower(name, str, expected); + } + catch (CultureNotFoundException) + { + return; + } } [Theory] @@ -430,7 +436,14 @@ private static void TestToUpper(string name, string str, string expected) [MemberData(nameof(ToUpper_TestData))] public void ToUpper(string name, string str, string expected) { - TestToUpper(name, str, expected); + try + { + TestToUpper(name, str, expected); + } + catch (CultureNotFoundException) + { + return; + } } [Theory] diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 9964539d5b517..cad32ae1371ec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -803,7 +803,7 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return CultureData.Invariant; } - if (GlobalizationMode.PredefinedOnly) + if (GlobalizationMode.GetPredefinedCulturesOnly()) { if (GlobalizationMode.UseNls) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs index 6b79b44afba6f..18038e2b0b38c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs @@ -11,10 +11,7 @@ private static CultureInfo IcuGetPredefinedCultureInfo(string name) { Debug.Assert(!GlobalizationMode.UseNls); - if (!Interop.Globalization.IsPredefinedLocale(name)) - { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); - } + CultureData.IcuIsEnsurePredefinedLocaleName(name); return GetCultureInfo(name); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs index b5313130732ab..d8a5badf5363f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs @@ -11,10 +11,7 @@ private static CultureInfo NlsGetPredefinedCultureInfo(string name) { Debug.Assert(GlobalizationMode.UseNls); - if (CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1) - { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); - } + CultureData.NlsIsEnsurePredefinedLocaleName(name); return GetCultureInfo(name); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 706b95daf2abc..4f04c9b99ed76 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -14,7 +14,8 @@ private static bool GetInvariantSwitchValue() => private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) => TryGetStringValue("System.Globalization.AppLocalIcu", "DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", out value); - internal static bool PredefinedOnly { get; } = GetSwitchValue("System.Globalization.PredefinedOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY"); + internal static bool GetPredefinedCulturesOnly() => + GetSwitchValue("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY"); private static bool GetSwitchValue(string switchName, string envVariable) { diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 55481146ac4cf..8ea48beafe72d 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1905,8 +1905,8 @@ var MonoSupportLib = { if (invariantMode) this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1"); - // Set globalization mode to PredefinedOnly - this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_ONLY", "1"); + // Set globalization mode to PredefinedCulturesOnly + this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", "1"); }, // Used by the debugger to enumerate loaded dlls and pdbs From 42c85fbea1e5065a8ff2236d3f360996a22ee484 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Mon, 25 Jan 2021 17:23:13 -0500 Subject: [PATCH 09/23] switch test to remoteexecutor --- .../tests/CultureInfo/CultureInfoAll.cs | 27 ++++++++++++------- .../src/System/Globalization/CultureData.cs | 2 +- .../Globalization/GlobalizationMode.Unix.cs | 1 - .../System/Globalization/GlobalizationMode.cs | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index a10436fb4d813..bb17652c148cf 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -7,6 +7,7 @@ using System.Runtime.InteropServices; using Microsoft.DotNet.RemoteExecutor; using System.Text; +using System.Diagnostics; using Xunit; namespace System.Globalization.Tests @@ -810,24 +811,30 @@ public void CultureNotFoundExceptionTest() Assert.Equal(0x1000, e.InvalidCultureId); } - [Theory] + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData("1", "xx-XY")] [InlineData("1", "zx-ZY")] [InlineData("0", "xx-XY")] [InlineData("0", "zx-ZY")] public void PredefinedCulturesOnlyEnvVarTest(string predefinedCulturesOnlyEnvVar, string cultureName) { - Environment.SetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCulturesOnlyEnvVar); + var psi = new ProcessStartInfo(); + psi.Environment.Clear(); - if (predefinedCulturesOnlyEnvVar == "1") - { - AssertExtensions.Throws(() => new CultureInfo(cultureName)); - } - else + psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCulturesOnlyEnvVar); + + RemoteExecutor.Invoke((culture, predefined) => { - CultureInfo ci = new CultureInfo(cultureName); - Assert.Equal(cultureName, ci.Name); - } + if (predefined == "1") + { + AssertExtensions.Throws(() => new CultureInfo(culture)); + } + else + { + CultureInfo ci = new CultureInfo(culture); + Assert.Equal(culture, ci.Name); + } + }, cultureName, predefinedCulturesOnlyEnvVar, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index cad32ae1371ec..6981fb1a3a551 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -803,7 +803,7 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return CultureData.Invariant; } - if (GlobalizationMode.GetPredefinedCulturesOnly()) + if (GlobalizationMode.PredefinedCulturesOnly) { if (GlobalizationMode.UseNls) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index 0a9fddbed4ca8..7d91ed4713a1f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -11,7 +11,6 @@ internal static partial class GlobalizationMode internal static bool UseNls => false; - private static bool GetGlobalizationInvariantMode() { bool invariantEnabled = GetInvariantSwitchValue(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 4f04c9b99ed76..7183786cf0d22 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -14,7 +14,7 @@ private static bool GetInvariantSwitchValue() => private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) => TryGetStringValue("System.Globalization.AppLocalIcu", "DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", out value); - internal static bool GetPredefinedCulturesOnly() => + internal static bool PredefinedCulturesOnly { get; } = GetSwitchValue("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY"); private static bool GetSwitchValue(string switchName, string envVariable) From e0f14e81fad40d5ae0a199831fa82353572f450d Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 27 Jan 2021 15:59:43 -0500 Subject: [PATCH 10/23] try catch for all culture not supported exceptions --- .../Common/tests/Tests/System/StringTests.cs | 11 +--- .../CultureInfo/CultureInfoCurrentCulture.cs | 62 +++++-------------- .../tests/CultureInfo/GetCultureInfo.cs | 2 +- .../System/Globalization/TextInfoTests.cs | 21 ++----- .../System/Globalization/CultureData.Icu.cs | 3 +- 5 files changed, 23 insertions(+), 76 deletions(-) diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index 115ff1882215d..4c79d008e84ff 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -2567,16 +2567,7 @@ public void Equals_Encyclopaedia_ReturnsExpected(StringComparison comparison, bo { string source = "encyclop\u00e6dia"; string target = "encyclopaedia"; - ThreadCultureChange culture; - if (PlatformDetection.IsBrowser) - { - culture = new ThreadCultureChange("pl-PL"); - } else - { - culture = new ThreadCultureChange("se-SE"); - } - - using (culture) + using (new ThreadCultureChange(PlatformDetection.IsBrowser ?"pl-PL" : "se-SE")) { Assert.Equal(expected, string.Equals(source, target, comparison)); Assert.Equal(expected, source.AsSpan().Equals(target.AsSpan(), comparison)); diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs index 89fedc78efdec..458dff8113f4d 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -13,35 +13,20 @@ namespace System.Globalization.Tests { public class CurrentCultureTests { - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void CurrentCulture() { - CultureInfo newCulture; - try - { - newCulture = new CultureInfo(CultureInfo.CurrentCulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); - using (new ThreadCultureChange(newCulture)) - { - Assert.Equal(CultureInfo.CurrentCulture, newCulture); - } - } - catch (CultureNotFoundException) + var newCulture = new CultureInfo(CultureInfo.CurrentCulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); + using (new ThreadCultureChange(newCulture)) { - return; + Assert.Equal(CultureInfo.CurrentCulture, newCulture); } - try - { - newCulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(newCulture)) - { - Assert.Equal(CultureInfo.CurrentCulture, newCulture); - Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); - } - } - catch (CultureNotFoundException) + newCulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(newCulture)) { - return; + Assert.Equal(CultureInfo.CurrentCulture, newCulture); + Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); } } @@ -51,35 +36,20 @@ public void CurrentCulture_Set_Null_ThrowsArgumentNullException() AssertExtensions.Throws("value", () => CultureInfo.CurrentCulture = null); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void CurrentUICulture() { - CultureInfo newUICulture; - try - { - newUICulture = new CultureInfo(CultureInfo.CurrentUICulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); - using (new ThreadCultureChange(null, newUICulture)) - { - Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); - } - } - catch (CultureNotFoundException) + var newUICulture = new CultureInfo(CultureInfo.CurrentUICulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); + using (new ThreadCultureChange(null, newUICulture)) { - return; + Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); } - try - { - newUICulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(null, newUICulture)) - { - Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); - Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); - } - } - catch (CultureNotFoundException) + newUICulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(null, newUICulture)) { - return; + Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); + Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs index cde9df0ab644a..cb0baab07f0fd 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs @@ -8,7 +8,7 @@ namespace System.Globalization.Tests { public class GetCultureInfoTests { - public static bool PlatformSupportsFakeCulture => !PlatformDetection.IsWindows || (PlatformDetection.WindowsVersion >= 10 && !PlatformDetection.IsNetFramework); + public static bool PlatformSupportsFakeCulture => !PlatformDetection.IsWindows || (PlatformDetection.WindowsVersion >= 10 && !PlatformDetection.IsNetFramework) || !PlatformDetection.IsBrowser; public static IEnumerable GetCultureInfoTestData() { diff --git a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index dda1a63976f66..ba80c85c0240a 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs @@ -303,17 +303,11 @@ private static void TestToLower(string name, string str, string expected) } } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [MemberData(nameof(ToLower_TestData))] public void ToLower(string name, string str, string expected) { - try{ - TestToLower(name, str, expected); - } - catch (CultureNotFoundException) - { - return; - } + TestToLower(name, str, expected); } [Theory] @@ -432,18 +426,11 @@ private static void TestToUpper(string name, string str, string expected) } } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [MemberData(nameof(ToUpper_TestData))] public void ToUpper(string name, string str, string expected) { - try - { - TestToUpper(name, str, expected); - } - catch (CultureNotFoundException) - { - return; - } + TestToUpper(name, str, expected); } [Theory] diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index 15f5acd84af91..02d509e0b2b56 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -229,8 +229,7 @@ internal static void IcuIsEnsurePredefinedLocaleName(string name) if (!Interop.Globalization.IsPredefinedLocale(name)) { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name), - message: "View https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#blazor-webassembly to load a new culture"); + throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); } } From bb3f356dfe0d764adb14dd24c221950fadad3a49 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Mon, 8 Feb 2021 12:06:21 -0500 Subject: [PATCH 11/23] Fix test failures: Check for RegionInfo first before creating culture to avoid throwing exception --- .../TestUtilities/System/PlatformDetection.cs | 9 +- .../CompareInfo/CompareInfoTests.Compare.cs | 7 +- .../tests/CultureInfo/CultureInfoAll.cs | 128 +++++++++--------- .../tests/CultureInfo/CultureInfoCtor.cs | 17 ++- .../tests/CultureInfo/CultureInfoParent.cs | 18 ++- .../tests/CultureInfo/GetCultureInfo.cs | 2 +- .../System/Globalization/RegionInfoTests.cs | 13 +- .../System/Globalization/CultureData.Icu.cs | 3 +- .../System/Globalization/CultureData.Nls.cs | 2 +- .../src/System/Globalization/CultureData.cs | 29 +++- 10 files changed, 140 insertions(+), 88 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 53b02129328bf..93732cf5e2494 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -178,14 +178,15 @@ public static string GetDistroVersionString() } } - private static readonly Lazy m_isInvariant = new Lazy(GetIsInvariantGlobalization); + private static readonly Lazy m_isInvariant = new Lazy(() => GetGlobalizationMode ("Invariant")); + private static readonly Lazy m_isPredefinedCulturesOnly = new Lazy(() => GetGlobalizationMode ("PredefinedCulturesOnly")); - private static bool GetIsInvariantGlobalization() + private static bool GetGlobalizationMode(string mode) { Type globalizationMode = Type.GetType("System.Globalization.GlobalizationMode"); if (globalizationMode != null) { - MethodInfo methodInfo = globalizationMode.GetProperty("Invariant", BindingFlags.NonPublic | BindingFlags.Static)?.GetMethod; + MethodInfo methodInfo = globalizationMode.GetProperty(mode, BindingFlags.NonPublic | BindingFlags.Static)?.GetMethod; if (methodInfo != null) { return (bool)methodInfo.Invoke(null, null); @@ -202,6 +203,8 @@ private static bool GetIsInvariantGlobalization() public static bool IsNotInvariantGlobalization => !IsInvariantGlobalization; public static bool IsIcuGlobalization => ICUVersion > new Version(0,0,0,0); public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization; + public static bool IsPredefinedCulturesOnly => m_isPredefinedCulturesOnly.Value; + public static bool IsNotPredefinedCulturesOnly => !IsPredefinedCulturesOnly; private static Version GetICUVersion() { diff --git a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.Compare.cs b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.Compare.cs index 98890c0c4fdbf..76a5556609961 100644 --- a/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.Compare.cs +++ b/src/libraries/System.Globalization/tests/CompareInfo/CompareInfoTests.Compare.cs @@ -254,8 +254,11 @@ public static IEnumerable Compare_TestData() yield return new object[] { s_hungarianCompare, "dzsdzs", "ddzs", CompareOptions.None, useNls ? 0 : -1 }; yield return new object[] { s_invariantCompare, "Test's", "Tests", CompareOptions.None, useNls ? 1 : -1 }; yield return new object[] { new CultureInfo("de-DE").CompareInfo, "\u00DC", "UE", CompareOptions.None, -1 }; - yield return new object[] { new CultureInfo("de-DE_phoneb").CompareInfo, "\u00DC", "UE", CompareOptions.None, useNls ? 0 : -1 }; - yield return new object[] { new CultureInfo("es-ES_tradnl").CompareInfo, "llegar", "lugar", CompareOptions.None, useNls ? 1 : -1 }; + if (PlatformDetection.IsNotBrowser) + { + yield return new object[] { new CultureInfo("de-DE_phoneb").CompareInfo, "\u00DC", "UE", CompareOptions.None, useNls ? 0 : -1 }; + yield return new object[] { new CultureInfo("es-ES_tradnl").CompareInfo, "llegar", "lugar", CompareOptions.None, useNls ? 1 : -1 }; + } } // There is a regression in Windows 190xx version with the Kana comparison. Avoid running this test there. diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index bb17652c148cf..da6eb62365f6d 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -660,72 +660,78 @@ public static IEnumerable CultureInfo_TestData() [MemberData(nameof(CultureInfo_TestData))] public void LcidTest(int lcid, string[] cultureNames, string specificCultureName, string threeLetterISOLanguageName, string threeLetterWindowsLanguageName, string alternativeCultureName, string consoleUICultureName) { - _ = alternativeCultureName; + try + { + _ = alternativeCultureName; - CultureInfo ci = new CultureInfo(lcid); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + CultureInfo ci = new CultureInfo(lcid); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - if (ci.LCID == 0x1000) - { - // Unsupported culture. - return; - } + if (ci.LCID == 0x1000) + { + // Unsupported culture. + return; + } - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.True(ci.UseUserOverride, "UseUserOverride for lcid created culture expected to be true"); - Assert.False(ci.IsReadOnly, "IsReadOnly for lcid created culture expected to be false"); - if (ci.ThreeLetterISOLanguageName != "") - { - Assert.Equal(threeLetterISOLanguageName, ci.ThreeLetterISOLanguageName); - } - if (ci.ThreeLetterWindowsLanguageName != "ZZZ") - { - Assert.True((threeLetterWindowsLanguageName == ci.ThreeLetterWindowsLanguageName) || (threeLetterWindowsLanguageName == "CHT" && ci.ThreeLetterWindowsLanguageName == "ZHH")); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.True(ci.UseUserOverride, "UseUserOverride for lcid created culture expected to be true"); + Assert.False(ci.IsReadOnly, "IsReadOnly for lcid created culture expected to be false"); + if (ci.ThreeLetterISOLanguageName != "") + { + Assert.Equal(threeLetterISOLanguageName, ci.ThreeLetterISOLanguageName); + } + if (ci.ThreeLetterWindowsLanguageName != "ZZZ") + { + Assert.True((threeLetterWindowsLanguageName == ci.ThreeLetterWindowsLanguageName) || (threeLetterWindowsLanguageName == "CHT" && ci.ThreeLetterWindowsLanguageName == "ZHH")); + } + ci = new CultureInfo(cultureNames[0]); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.True(ci.UseUserOverride, "UseUserOverride for named created culture expected to be true"); + Assert.False(ci.IsReadOnly, "IsReadOnly for named created culture expected to be false"); + + ci = new CultureInfo(lcid, false); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.False(ci.UseUserOverride, "UseUserOverride with false user override culture expected to be false"); + Assert.False(ci.IsReadOnly, "IsReadOnly with false user override culture expected to be false"); + + ci = CultureInfo.GetCultureInfo(lcid); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and lcid expected to be false"); + Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and lcid expected to be true"); + + ci = CultureInfo.GetCultureInfo(cultureNames[0]); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and name expected to be false"); + Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and name expected to be true"); + + ci = CultureInfo.GetCultureInfo(cultureNames[0], ""); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); + Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and sort name expected to be false"); + Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and sort name expected to be true"); + Assert.Equal(CultureInfo.InvariantCulture.TextInfo, ci.TextInfo); + Assert.Equal(CultureInfo.InvariantCulture.CompareInfo, ci.CompareInfo); + + ci = CultureInfo.CreateSpecificCulture(cultureNames[0]); + TestCultureName(specificCultureName, ci.Name); + + ci = CultureInfo.GetCultureInfoByIetfLanguageTag(cultureNames[0]); + Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); + TestCultureName(ci.Name, ci.IetfLanguageTag); + Assert.True(lcid == ci.KeyboardLayoutId || (ushort)lcid == (ushort)ci.KeyboardLayoutId); + + if (ci.GetConsoleFallbackUICulture().Name != "") + { + Assert.Equal(consoleUICultureName, ci.GetConsoleFallbackUICulture().Name); + } } - - ci = new CultureInfo(cultureNames[0]); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.True(ci.UseUserOverride, "UseUserOverride for named created culture expected to be true"); - Assert.False(ci.IsReadOnly, "IsReadOnly for named created culture expected to be false"); - - ci = new CultureInfo(lcid, false); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.False(ci.UseUserOverride, "UseUserOverride with false user override culture expected to be false"); - Assert.False(ci.IsReadOnly, "IsReadOnly with false user override culture expected to be false"); - - ci = CultureInfo.GetCultureInfo(lcid); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and lcid expected to be false"); - Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and lcid expected to be true"); - - ci = CultureInfo.GetCultureInfo(cultureNames[0]); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and name expected to be false"); - Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and name expected to be true"); - - ci = CultureInfo.GetCultureInfo(cultureNames[0], ""); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - Assert.True(lcid == ci.LCID || (ushort)lcid == (ushort)ci.LCID); - Assert.False(ci.UseUserOverride, "UseUserOverride with Culture created by GetCultureInfo and sort name expected to be false"); - Assert.True(ci.IsReadOnly, "IsReadOnly with Culture created by GetCultureInfo and sort name expected to be true"); - Assert.Equal(CultureInfo.InvariantCulture.TextInfo, ci.TextInfo); - Assert.Equal(CultureInfo.InvariantCulture.CompareInfo, ci.CompareInfo); - - ci = CultureInfo.CreateSpecificCulture(cultureNames[0]); - TestCultureName(specificCultureName, ci.Name); - - ci = CultureInfo.GetCultureInfoByIetfLanguageTag(cultureNames[0]); - Assert.Contains(ci.Name, cultureNames, StringComparer.OrdinalIgnoreCase); - TestCultureName(ci.Name, ci.IetfLanguageTag); - Assert.True(lcid == ci.KeyboardLayoutId || (ushort)lcid == (ushort)ci.KeyboardLayoutId); - - if (ci.GetConsoleFallbackUICulture().Name != "") + catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) { - Assert.Equal(consoleUICultureName, ci.GetConsoleFallbackUICulture().Name); + AssertExtensions.Throws(() => new CultureInfo(lcid)); } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs index 9db444be85bd6..8e198b6cf99b7 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs @@ -387,12 +387,19 @@ public static IEnumerable Ctor_String_TestData() [MemberData(nameof(Ctor_String_TestData))] public void Ctor_String(string name, string[] expectedNames) { - CultureInfo culture = new CultureInfo(name); - string cultureName = culture.Name; - Assert.Contains(cultureName, expectedNames, StringComparer.OrdinalIgnoreCase); + try + { + CultureInfo culture = new CultureInfo(name); + string cultureName = culture.Name; + Assert.Contains(cultureName, expectedNames, StringComparer.OrdinalIgnoreCase); - culture = new CultureInfo(cultureName); - Assert.Equal(cultureName, culture.ToString(), ignoreCase: true); + culture = new CultureInfo(cultureName); + Assert.Equal(cultureName, culture.ToString(), ignoreCase: true); + } + catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) + { + Assert.Throws(() => new CultureInfo(name)); + } } [Fact] diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs index b9d6be536f48d..37ba49bcca953 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs @@ -35,10 +35,20 @@ public void Parent(string name, string expectedParentName) [Fact] public void Parent_ParentChain() { - CultureInfo myExpectParentCulture = new CultureInfo("uz-Cyrl-UZ"); - Assert.Equal("uz-Cyrl", myExpectParentCulture.Parent.Name); - Assert.Equal("uz", myExpectParentCulture.Parent.Parent.Name); - Assert.Equal("", myExpectParentCulture.Parent.Parent.Parent.Name); + if (PlatformDetection.IsNotPredefinedCulturesOnly) + { + CultureInfo myExpectParentCulture = new CultureInfo("uz-Cyrl-UZ"); + Assert.Equal("uz-Cyrl", myExpectParentCulture.Parent.Name); + Assert.Equal("uz", myExpectParentCulture.Parent.Parent.Name); + Assert.Equal("", myExpectParentCulture.Parent.Parent.Parent.Name); + } + else + { + CultureInfo myExpectParentCulture = new CultureInfo("zh-Hans-CN"); + Assert.Equal("zh-Hans", myExpectParentCulture.Parent.Name); + Assert.Equal("zh", myExpectParentCulture.Parent.Parent.Name); + Assert.Equal("", myExpectParentCulture.Parent.Parent.Parent.Name); + } } } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs index cde9df0ab644a..4894a38dea35f 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs @@ -8,7 +8,7 @@ namespace System.Globalization.Tests { public class GetCultureInfoTests { - public static bool PlatformSupportsFakeCulture => !PlatformDetection.IsWindows || (PlatformDetection.WindowsVersion >= 10 && !PlatformDetection.IsNetFramework); + public static bool PlatformSupportsFakeCulture => (!PlatformDetection.IsWindows || (PlatformDetection.WindowsVersion >= 10 && !PlatformDetection.IsNetFramework)) && PlatformDetection.IsNotBrowser; public static IEnumerable GetCultureInfoTestData() { diff --git a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs index 4fa32f5127936..c6ac55075725b 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs @@ -57,9 +57,16 @@ public void CurrentRegion_Unix() { using (new ThreadCultureChange("en-US")) { - RegionInfo ri = new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName); - Assert.True(RegionInfo.CurrentRegion.Equals(ri) || RegionInfo.CurrentRegion.Equals(new RegionInfo(CultureInfo.CurrentCulture.Name))); - Assert.Same(RegionInfo.CurrentRegion, RegionInfo.CurrentRegion); + try + { + RegionInfo ri = new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName); + Assert.True(RegionInfo.CurrentRegion.Equals(ri) || RegionInfo.CurrentRegion.Equals(new RegionInfo(CultureInfo.CurrentCulture.Name))); + Assert.Same(RegionInfo.CurrentRegion, RegionInfo.CurrentRegion); + } + catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) + { + AssertExtensions.Throws(() => new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName)); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index 15f5acd84af91..1d16ec83845da 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -229,8 +229,7 @@ internal static void IcuIsEnsurePredefinedLocaleName(string name) if (!Interop.Globalization.IsPredefinedLocale(name)) { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name), - message: "View https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#blazor-webassembly to load a new culture"); + throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 17f0f77e74fbb..74ae84eda4805 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -93,7 +93,7 @@ internal static void NlsIsEnsurePredefinedLocaleName(string name) if (CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1) { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); + throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 6981fb1a3a551..1a3d95a84f6af 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -422,12 +422,30 @@ internal partial class CultureData { return CultureData.Invariant; } - - // First check if GetCultureData() can find it (ie: its a real culture) - CultureData? retVal = GetCultureData(cultureName, useUserOverride); - if (retVal != null && !retVal.IsNeutralCulture) + CultureData? retVal = null; + try { - return retVal; + // First check if GetCultureData() can find it (ie: its a real culture) + retVal = GetCultureData(cultureName, useUserOverride); + if (retVal != null && !retVal.IsNeutralCulture) + { + return retVal; + } + } + catch (CultureNotFoundException) when (GlobalizationMode.PredefinedCulturesOnly) + { + // Catching this exception because GetCultureData will throw if the region name is not defined yet + // If not a valid mapping from the registry we'll have to try the hard coded table + if (retVal == null || retVal.IsNeutralCulture) + { + // Not a valid mapping, try the hard coded table + if (RegionNames.TryGetValue(cultureName, out string? name)) + { + // Make sure we can get culture data for it + retVal = GetCultureData(name, useUserOverride); + return retVal; + } + } } // Not a specific culture, perhaps it's region-only name @@ -698,7 +716,6 @@ private static CultureData CreateCultureWithInvariantData() return retVal; } } - // Not found in the hash table, need to see if we can build one that works for us CultureData? culture = CreateCultureData(cultureName, useUserOverride); if (culture == null) From e894382eca599ddf8e56f27953145457c83a7a47 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Mon, 8 Feb 2021 17:19:42 -0500 Subject: [PATCH 12/23] add another condition to env var test --- .../tests/CultureInfo/CultureInfoAll.cs | 26 ----------------- .../tests/CultureInfo/GetCultureInfo.cs | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index da6eb62365f6d..fe0074e2c283a 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -816,31 +816,5 @@ public void CultureNotFoundExceptionTest() e = AssertExtensions.Throws("culture", () => new CultureInfo(0x1000)); Assert.Equal(0x1000, e.InvalidCultureId); } - - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [InlineData("1", "xx-XY")] - [InlineData("1", "zx-ZY")] - [InlineData("0", "xx-XY")] - [InlineData("0", "zx-ZY")] - public void PredefinedCulturesOnlyEnvVarTest(string predefinedCulturesOnlyEnvVar, string cultureName) - { - var psi = new ProcessStartInfo(); - psi.Environment.Clear(); - - psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCulturesOnlyEnvVar); - - RemoteExecutor.Invoke((culture, predefined) => - { - if (predefined == "1") - { - AssertExtensions.Throws(() => new CultureInfo(culture)); - } - else - { - CultureInfo ci = new CultureInfo(culture); - Assert.Equal(culture, ci.Name); - } - }, cultureName, predefinedCulturesOnlyEnvVar, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); - } } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs index 4894a38dea35f..4679c2c85d8e7 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using Microsoft.DotNet.RemoteExecutor; +using System.Diagnostics; using Xunit; namespace System.Globalization.Tests @@ -110,5 +112,31 @@ public void TestFakeCultureNames(string name) Assert.Equal(name, CultureInfo.GetCultureInfo(name, predefinedOnly: false).Name); Assert.Throws(() => CultureInfo.GetCultureInfo(name, predefinedOnly: true)); } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported), nameof(PlatformSupportsFakeCulture))] + [InlineData("1", "xx-XY")] + [InlineData("1", "zx-ZY")] + [InlineData("0", "xx-XY")] + [InlineData("0", "zx-ZY")] + public void PredefinedCulturesOnlyEnvVarTest(string predefinedCulturesOnlyEnvVar, string cultureName) + { + var psi = new ProcessStartInfo(); + psi.Environment.Clear(); + + psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", predefinedCulturesOnlyEnvVar); + + RemoteExecutor.Invoke((culture, predefined) => + { + if (predefined == "1") + { + AssertExtensions.Throws(() => new CultureInfo(culture)); + } + else + { + CultureInfo ci = new CultureInfo(culture); + Assert.Equal(culture, ci.Name); + } + }, cultureName, predefinedCulturesOnlyEnvVar, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); + } } } From 462f7ad2ecace428d70ea543e5dd588c67ad9f3e Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 9 Feb 2021 12:08:13 -0500 Subject: [PATCH 13/23] fix conditional theory --- .../System.Globalization/tests/CultureInfo/GetCultureInfo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs index 4679c2c85d8e7..0b4bdd5708992 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs @@ -11,6 +11,7 @@ namespace System.Globalization.Tests public class GetCultureInfoTests { public static bool PlatformSupportsFakeCulture => (!PlatformDetection.IsWindows || (PlatformDetection.WindowsVersion >= 10 && !PlatformDetection.IsNetFramework)) && PlatformDetection.IsNotBrowser; + public static bool PlatformSupportsFakeCultureAndRemoteExecutor => PlatformSupportsFakeCulture && RemoteExecutor.IsSupported; public static IEnumerable GetCultureInfoTestData() { @@ -113,7 +114,7 @@ public void TestFakeCultureNames(string name) Assert.Throws(() => CultureInfo.GetCultureInfo(name, predefinedOnly: true)); } - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported), nameof(PlatformSupportsFakeCulture))] + [ConditionalTheory(nameof(PlatformSupportsFakeCultureAndRemoteExecutor))] [InlineData("1", "xx-XY")] [InlineData("1", "zx-ZY")] [InlineData("0", "xx-XY")] From 18faed16cd4e49ad677bbe0600e96571a014c426 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 10 Feb 2021 18:36:58 -0500 Subject: [PATCH 14/23] fix TypeConverter test failures --- .../tests/CultureInfoConverterTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs index 3523e7c4c5b1f..2cfb7d8b5b30d 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs @@ -33,8 +33,10 @@ public override IEnumerable ConvertFromTestData() yield return ConvertTest.Valid("nl-B", new CultureInfo("nl--B"), CultureInfo.InvariantCulture); yield return ConvertTest.Valid("nl-B", new CultureInfo("nl--B"), new CultureInfo("en-US")); } - - yield return ConvertTest.Valid("Afrikaans", new CultureInfo("af")); + if (PlatformDetection.IsNotPredefinedCulturesOnly) + { + yield return ConvertTest.Valid("Afrikaans", new CultureInfo("af")); + } yield return ConvertTest.CantConvertFrom(CultureInfo.CurrentCulture); yield return ConvertTest.CantConvertFrom(1); From ef75159bc2c3053d155730cce0a1f6498f945fd7 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 16 Feb 2021 12:28:18 -0500 Subject: [PATCH 15/23] change assembly test data to pl-PL to avoid culturenotfound exception --- .../tests/src/TestUtils/TestData.cs | 2 +- .../tests/src/Tests/Assembly/AssemblyTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestData.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestData.cs index 6ed8b08660902..0d6721275be3c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestData.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestData.cs @@ -985,7 +985,7 @@ internal static class TestData "ABYAAAEAAAACAAAAAQAAAAIAAAACAAAAAQAAAAMAAAAAAG4AAQAAAAAABgAqAAoABgBQAAoAAAAAAAEAAAAAAAEAAQAJAEoAAQARAEoABgAuAAsAEwAuABMA" + "HAAEgAAAAAAAAAAAAAAAAAAAAAChAAAABAAAAAAAAAAAAAAACgCIAAAAAAAAAAAAAAAAAAAAAAAAAJEAAAAAAAEAAgADAAQAAAAAAAAAlgCbAAAAAAAAPE1v" + "ZHVsZT4AU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAC5jdG9yAFJ1bnRpbWVDb21wYXRp" + - "YmlsaXR5QXR0cmlidXRlAEFzc2VtYmx5UmVmZXJlbmNlVGVzdC5kbGwAbXNjb3JsaWIAZGVwMQBkZXAyAGFyLUxZAEFzc2VtYmx5UmVmZXJlbmNlVGVzdAAA" + + "YmlsaXR5QXR0cmlidXRlAEFzc2VtYmx5UmVmZXJlbmNlVGVzdC5kbGwAbXNjb3JsaWIAZGVwMQBkZXAyAHBsLVBMAEFzc2VtYmx5UmVmZXJlbmNlVGVzdAAA" + "AAMgAAAAAAD+latRaKErR6lFRbe04zMTAAQgAQEIAyAAAQi3elxWGTTgiQgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEAtCIAAAAA" + "AAAAAAAAziIAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAiAAAAAAAAAAAAAAAAX0NvckRsbE1haW4AbXNjb3JlZS5kbGwAAAAAAP8lACAAEAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs index fd3397f53807c..adca9a9b4b102 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs @@ -170,8 +170,8 @@ public static void AssemblyGetReferencedAssemblies() { Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyReferencesTestImage); AssemblyName[] ans = a.GetReferencedAssemblies(); + Console.WriteLine("GET ASSEMBLY TESTS 3"); Assert.Equal(3, ans.Length); - { AssemblyName an = ans.Single(an2 => an2.Name == "mscorlib"); Assert.Equal(default(AssemblyNameFlags), an.Flags); @@ -211,7 +211,7 @@ public static void AssemblyGetReferencedAssemblies() Assert.Equal(2, v.Minor); Assert.Equal(3, v.Build); Assert.Equal(4, v.Revision); - Assert.Equal("ar-LY", an.CultureName); + Assert.Equal("pl-PL", an.CultureName); Assert.Null(an.GetPublicKey()); Assert.Equal(0, an.GetPublicKeyToken().Length); } From 84b8429fba84ee68b4f5bf90ee236a741954d096 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 2 Mar 2021 16:16:23 -0500 Subject: [PATCH 16/23] remove exception filters from tests and add additional parameter to test data to indicate whether or not that locale is expected to throw exception on browser --- .../TestUtilities/System/PlatformDetection.cs | 25 +- .../tests/CultureInfo/CultureInfoAll.cs | 74 +-- .../tests/CultureInfo/CultureInfoCtor.cs | 470 +++++++++--------- .../CultureInfo/CultureInfoCurrentCulture.cs | 26 +- .../tests/CultureInfo/CultureInfoParent.cs | 2 +- .../System/Globalization/RegionInfoTests.cs | 13 +- .../System/Globalization/TextInfoTests.cs | 8 +- 7 files changed, 313 insertions(+), 305 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 93732cf5e2494..4e02843b71d51 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -28,6 +28,7 @@ public static partial class PlatformDetection public static bool IsNetBSD => RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")); public static bool IsiOS => RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")); public static bool IstvOS => RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")); + public static bool IsMacCatalyst => RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACCATALYST")); public static bool Isillumos => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ILLUMOS")); public static bool IsSolaris => RuntimeInformation.IsOSPlatform(OSPlatform.Create("SOLARIS")); public static bool IsBrowser => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); @@ -49,6 +50,9 @@ public static partial class PlatformDetection public static bool IsThreadingSupported => !IsBrowser; public static bool IsBinaryFormatterSupported => !IsBrowser; + public static bool IsSpeedOptimized => !IsSizeOptimized; + public static bool IsSizeOptimized => IsBrowser || IsAndroid || IsiOS || IstvOS; + public static bool IsBrowserDomSupported => GetIsBrowserDomSupported(); public static bool IsNotBrowserDomSupported => !IsBrowserDomSupported; @@ -132,7 +136,7 @@ public static bool IsNonZeroLowerBoundArraySupported (IsOpenSslSupported && (OpenSslVersion.Major >= 1 && (OpenSslVersion.Minor >= 1 || OpenSslVersion.Build >= 2))); - public static bool SupportsClientAlpn => SupportsAlpn || IsOSX || IsiOS || IstvOS; + public static bool SupportsClientAlpn => SupportsAlpn || IsOSX || IsMacCatalyst || IsiOS || IstvOS; private static Lazy s_supportsTls10 = new Lazy(GetTls10Support); private static Lazy s_supportsTls11 = new Lazy(GetTls11Support); @@ -178,15 +182,14 @@ public static string GetDistroVersionString() } } - private static readonly Lazy m_isInvariant = new Lazy(() => GetGlobalizationMode ("Invariant")); - private static readonly Lazy m_isPredefinedCulturesOnly = new Lazy(() => GetGlobalizationMode ("PredefinedCulturesOnly")); + private static readonly Lazy m_isInvariant = new Lazy(GetIsInvariantGlobalization); - private static bool GetGlobalizationMode(string mode) + private static bool GetIsInvariantGlobalization() { Type globalizationMode = Type.GetType("System.Globalization.GlobalizationMode"); if (globalizationMode != null) { - MethodInfo methodInfo = globalizationMode.GetProperty(mode, BindingFlags.NonPublic | BindingFlags.Static)?.GetMethod; + MethodInfo methodInfo = globalizationMode.GetProperty("Invariant", BindingFlags.NonPublic | BindingFlags.Static)?.GetMethod; if (methodInfo != null) { return (bool)methodInfo.Invoke(null, null); @@ -203,8 +206,6 @@ private static bool GetGlobalizationMode(string mode) public static bool IsNotInvariantGlobalization => !IsInvariantGlobalization; public static bool IsIcuGlobalization => ICUVersion > new Version(0,0,0,0); public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization; - public static bool IsPredefinedCulturesOnly => m_isPredefinedCulturesOnly.Value; - public static bool IsNotPredefinedCulturesOnly => !IsPredefinedCulturesOnly; private static Version GetICUVersion() { @@ -283,8 +284,8 @@ private static bool OpenSslGetTlsSupport(SslProtocols protocol) private static bool GetTls10Support() { - // on Windows and macOS TLS1.0/1.1 are supported. - if (IsWindows || IsOSXLike) + // on Windows, macOS, and Android TLS1.0/1.1 are supported. + if (IsWindows || IsOSXLike || IsAndroid) { return true; } @@ -294,13 +295,13 @@ private static bool GetTls10Support() private static bool GetTls11Support() { - // on Windows and macOS TLS1.0/1.1 are supported. + // on Windows, macOS, and Android TLS1.0/1.1 are supported. // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default. if (IsWindows) { return !IsWindows7; } - else if (IsOSXLike) + else if (IsOSXLike || IsAndroid) { return true; } @@ -342,7 +343,7 @@ private static bool GetTls13Support() // The build number is approximation. return IsWindows10Version2004Build19573OrGreater; } - else if (IsOSX || IsiOS || IstvOS) + else if (IsOSX || IsMacCatalyst || IsiOS || IstvOS) { // [ActiveIssue("https://github.com/dotnet/runtime/issues/1979")] return false; diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index fe0074e2c283a..ccef468681d66 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -529,7 +529,7 @@ public static IEnumerable CultureInfo_TestData() yield return new object[] { 0x0001, new [] { "ar" }, "ar-SA", "ara", "ARA", "ar", "en-US" }; yield return new object[] { 0x0002, new [] { "bg" }, "bg-BG", "bul", "BGR", "bg", "bg-BG" }; yield return new object[] { 0x0003, new [] { "ca" }, "ca-ES", "cat", "CAT", "ca", "ca-ES" }; - yield return new object[] { 0x0004, new [] { "zh-chs", "zh-hans" }, "zh-CN", "zho", "CHS", "zh-Hans", "zh-CN" }; + yield return new object[] { 0x0004, new [] { "zh-chs", "zh-hans" }, "zh-CN", "zho", "CHS", "zh-Hans", "zh-CN", true }; yield return new object[] { 0x0005, new [] { "cs" }, "cs-CZ", "ces", "CSY", "cs", "cs-CZ" }; yield return new object[] { 0x0006, new [] { "da" }, "da-DK", "dan", "DAN", "da", "da-DK" }; yield return new object[] { 0x0007, new [] { "de" }, "de-DE", "deu", "DEU", "de", "de-DE" }; @@ -644,23 +644,23 @@ public static IEnumerable CultureInfo_TestData() yield return new object[] { 0x6c1a, new [] { "sr-cyrl" }, "sr-Cyrl-RS", "srp", "SRO", "sr-Cyrl", "sr-Cyrl-RS" }; yield return new object[] { 0x701a, new [] { "sr-latn" }, "sr-Latn-RS", "srp", "SRM", "sr-Latn", "sr-Latn-RS" }; yield return new object[] { 0x7804, new [] { "zh" }, "zh-CN", "zho", "CHS", "zh", "zh-CN" }; - yield return new object[] { 0x7c04, new [] { "zh-cht", "zh-hant" }, "zh-HK", "zho", "CHT", "zh-Hant", "zh-HK" }; + yield return new object[] { 0x7c04, new [] { "zh-cht", "zh-hant" }, "zh-HK", "zho", "CHT", "zh-Hant", "zh-HK", true }; yield return new object[] { 0x7c1a, new [] { "sr" }, "sr-Latn-RS", "srp", "SRB", "sr", "sr-Latn-RS" }; - yield return new object[] { 0x10407, new [] { "de-de_phoneb", "de-de" }, "de-DE", "deu", "DEU", "de-DE", "de-DE" }; - yield return new object[] { 0x1040e, new [] { "hu-hu_technl", "hu-hu" }, "hu-HU", "hun", "HUN", "hu-HU", "hu-HU" }; - yield return new object[] { 0x20804, new [] { "zh-cn_stroke", "zh-cn" }, "zh-CN", "zho", "CHS", "zh-Hans-CN", "zh-CN" }; - yield return new object[] { 0x21004, new [] { "zh-sg_stroke", "zh-sg" }, "zh-SG", "zho", "ZHI", "zh-Hans-SG", "zh-SG" }; - yield return new object[] { 0x30404, new [] { "zh-tw_pronun", "zh-tw" }, "zh-TW", "zho", "CHT", "zh-Hant-TW", "zh-TW" }; - yield return new object[] { 0x40404, new [] { "zh-tw_radstr", "zh-tw" }, "zh-TW", "zho", "CHT", "zh-Hant-TW", "zh-TW" }; - yield return new object[] { 0x40411, new [] { "ja-jp_radstr", "ja-jp" }, "ja-JP", "jpn", "JPN", "ja-JP", "ja-JP" }; - yield return new object[] { 0x40c04, new [] { "zh-hk_radstr", "zh-hk" }, "zh-HK", "zho", "ZHH", "zh-Hant-HK", "zh-HK" }; + yield return new object[] { 0x10407, new [] { "de-de_phoneb", "de-de" }, "de-DE", "deu", "DEU", "de-DE", "de-DE", true }; + yield return new object[] { 0x1040e, new [] { "hu-hu_technl", "hu-hu" }, "hu-HU", "hun", "HUN", "hu-HU", "hu-HU", true }; + yield return new object[] { 0x20804, new [] { "zh-cn_stroke", "zh-cn" }, "zh-CN", "zho", "CHS", "zh-Hans-CN", "zh-CN", true }; + yield return new object[] { 0x21004, new [] { "zh-sg_stroke", "zh-sg" }, "zh-SG", "zho", "ZHI", "zh-Hans-SG", "zh-SG", true }; + yield return new object[] { 0x30404, new [] { "zh-tw_pronun", "zh-tw" }, "zh-TW", "zho", "CHT", "zh-Hant-TW", "zh-TW", true }; + yield return new object[] { 0x40404, new [] { "zh-tw_radstr", "zh-tw" }, "zh-TW", "zho", "CHT", "zh-Hant-TW", "zh-TW", true }; + yield return new object[] { 0x40411, new [] { "ja-jp_radstr", "ja-jp" }, "ja-JP", "jpn", "JPN", "ja-JP", "ja-JP", true }; + yield return new object[] { 0x40c04, new [] { "zh-hk_radstr", "zh-hk" }, "zh-HK", "zho", "ZHH", "zh-Hant-HK", "zh-HK", true }; } [Theory] [MemberData(nameof(CultureInfo_TestData))] - public void LcidTest(int lcid, string[] cultureNames, string specificCultureName, string threeLetterISOLanguageName, string threeLetterWindowsLanguageName, string alternativeCultureName, string consoleUICultureName) + public void LcidTest(int lcid, string[] cultureNames, string specificCultureName, string threeLetterISOLanguageName, string threeLetterWindowsLanguageName, string alternativeCultureName, string consoleUICultureName, bool expectToThrowOnBrowser = false) { - try + if (!expectToThrowOnBrowser || PlatformDetection.IsNotBrowser) { _ = alternativeCultureName; @@ -729,11 +729,12 @@ public void LcidTest(int lcid, string[] cultureNames, string specificCultureName Assert.Equal(consoleUICultureName, ci.GetConsoleFallbackUICulture().Name); } } - catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) + else { - AssertExtensions.Throws(() => new CultureInfo(lcid)); + AssertExtensions.Throws("name", () => new CultureInfo(lcid)); } - } + + } private static string[] hans = new[] { "zh-CN", "zh-CHS", "zh-Hans" }; private static string[] hant = new[] { "zh-HK", "zh-CHT", "zh-Hant" }; @@ -767,27 +768,34 @@ public void InstalledUICultureTest() [Theory] [MemberData(nameof(CultureInfo_TestData))] - public void GetCulturesTest(int lcid, string[] cultureNames, string specificCultureName, string threeLetterISOLanguageName, string threeLetterWindowsLanguageName, string alternativeCultureName, string consoleUICultureName) + public void GetCulturesTest(int lcid, string[] cultureNames, string specificCultureName, string threeLetterISOLanguageName, string threeLetterWindowsLanguageName, string alternativeCultureName, string consoleUICultureName, bool expectToThrowOnBrowser = false) { - _ = lcid; - _ = specificCultureName; - _ = threeLetterISOLanguageName; - _ = threeLetterWindowsLanguageName; - _ = consoleUICultureName; - - bool found = false; - Assert.All(CultureInfo.GetCultures(CultureTypes.NeutralCultures), - c => Assert.True( (c.IsNeutralCulture && ((c.CultureTypes & CultureTypes.NeutralCultures) != 0)) || c.Equals(CultureInfo.InvariantCulture))); - found = CultureInfo.GetCultures(CultureTypes.NeutralCultures).Any(c => cultureNames.Contains(c.Name, StringComparer.OrdinalIgnoreCase) || - c.Name.Equals(alternativeCultureName, StringComparison.OrdinalIgnoreCase)); - Assert.All(CultureInfo.GetCultures(CultureTypes.SpecificCultures), c => Assert.True(!c.IsNeutralCulture && ((c.CultureTypes & CultureTypes.SpecificCultures) != 0))); - if (!found) + if (!expectToThrowOnBrowser || PlatformDetection.IsNotBrowser) { - found = CultureInfo.GetCultures(CultureTypes.SpecificCultures).Any(c => cultureNames.Contains(c.Name, StringComparer.OrdinalIgnoreCase) || - c.Name.Equals(alternativeCultureName, StringComparison.OrdinalIgnoreCase)); - } + _ = lcid; + _ = specificCultureName; + _ = threeLetterISOLanguageName; + _ = threeLetterWindowsLanguageName; + _ = consoleUICultureName; + + bool found = false; + Assert.All(CultureInfo.GetCultures(CultureTypes.NeutralCultures), + c => Assert.True( (c.IsNeutralCulture && ((c.CultureTypes & CultureTypes.NeutralCultures) != 0)) || c.Equals(CultureInfo.InvariantCulture))); + found = CultureInfo.GetCultures(CultureTypes.NeutralCultures).Any(c => cultureNames.Contains(c.Name, StringComparer.OrdinalIgnoreCase) || + c.Name.Equals(alternativeCultureName, StringComparison.OrdinalIgnoreCase)); + Assert.All(CultureInfo.GetCultures(CultureTypes.SpecificCultures), c => Assert.True(!c.IsNeutralCulture && ((c.CultureTypes & CultureTypes.SpecificCultures) != 0))); + if (!found) + { + found = CultureInfo.GetCultures(CultureTypes.SpecificCultures).Any(c => cultureNames.Contains(c.Name, StringComparer.OrdinalIgnoreCase) || + c.Name.Equals(alternativeCultureName, StringComparison.OrdinalIgnoreCase)); + } - Assert.True(found, $"Expected to find the culture {cultureNames[0]} in the enumerated list"); + Assert.True(found, $"Expected to find the culture {cultureNames[0]} in the enumerated list"); + } + else + { + AssertExtensions.Throws("name", () => new CultureInfo(lcid)); + } } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs index 8e198b6cf99b7..787f9e37f719d 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCtor.cs @@ -11,79 +11,79 @@ public class CultureInfoConstructor public static IEnumerable Ctor_String_TestData() { yield return new object[] { "", new [] { "" } }; - yield return new object[] { "af", new [] { "af" } }; - yield return new object[] { "af-ZA", new [] { "af-ZA" } }; + yield return new object[] { "af", new [] { "af" }, true }; + yield return new object[] { "af-ZA", new [] { "af-ZA" }, true }; yield return new object[] { "am", new [] { "am" } }; yield return new object[] { "am-ET", new [] { "am-ET" } }; yield return new object[] { "ar", new [] { "ar" } }; - yield return new object[] { "ar-AE", new [] { "ar-AE" } }; - yield return new object[] { "ar-BH", new [] { "ar-BH" } }; - yield return new object[] { "ar-DZ", new [] { "ar-DZ" } }; - yield return new object[] { "ar-EG", new [] { "ar-EG" } }; - yield return new object[] { "ar-IQ", new [] { "ar-IQ" } }; - yield return new object[] { "ar-JO", new [] { "ar-JO" } }; - yield return new object[] { "ar-KW", new [] { "ar-KW" } }; - yield return new object[] { "ar-LB", new [] { "ar-LB" } }; - yield return new object[] { "ar-LY", new [] { "ar-LY" } }; - yield return new object[] { "ar-MA", new [] { "ar-MA" } }; - yield return new object[] { "ar-OM", new [] { "ar-OM" } }; - yield return new object[] { "ar-QA", new [] { "ar-QA" } }; + yield return new object[] { "ar-AE", new [] { "ar-AE" }, true }; + yield return new object[] { "ar-BH", new [] { "ar-BH" }, true }; + yield return new object[] { "ar-DZ", new [] { "ar-DZ" }, true }; + yield return new object[] { "ar-EG", new [] { "ar-EG" }, true }; + yield return new object[] { "ar-IQ", new [] { "ar-IQ" }, true }; + yield return new object[] { "ar-JO", new [] { "ar-JO" }, true }; + yield return new object[] { "ar-KW", new [] { "ar-KW" }, true }; + yield return new object[] { "ar-LB", new [] { "ar-LB" }, true }; + yield return new object[] { "ar-LY", new [] { "ar-LY" }, true }; + yield return new object[] { "ar-MA", new [] { "ar-MA" }, true }; + yield return new object[] { "ar-OM", new [] { "ar-OM" }, true }; + yield return new object[] { "ar-QA", new [] { "ar-QA" }, true }; yield return new object[] { "ar-SA", new [] { "ar-SA" } }; - yield return new object[] { "ar-SY", new [] { "ar-SY" } }; - yield return new object[] { "ar-TN", new [] { "ar-TN" } }; - yield return new object[] { "ar-YE", new [] { "ar-YE" } }; - yield return new object[] { "arn", new [] { "arn" } }; - yield return new object[] { "arn-CL", new [] { "arn-CL" } }; - yield return new object[] { "as", new [] { "as" } }; - yield return new object[] { "as-IN", new [] { "as-IN" } }; - yield return new object[] { "az", new [] { "az" } }; - yield return new object[] { "az-Cyrl", new [] { "az-Cyrl" } }; - yield return new object[] { "az-Cyrl-AZ", new [] { "az-Cyrl-AZ" } }; - yield return new object[] { "az-Latn", new [] { "az-Latn" } }; - yield return new object[] { "az-Latn-AZ", new [] { "az-Latn-AZ" } }; - yield return new object[] { "ba", new [] { "ba" } }; - yield return new object[] { "ba-RU", new [] { "ba-RU" } }; - yield return new object[] { "be", new [] { "be" } }; - yield return new object[] { "be-BY", new [] { "be-BY" } }; + yield return new object[] { "ar-SY", new [] { "ar-SY" }, true }; + yield return new object[] { "ar-TN", new [] { "ar-TN" }, true }; + yield return new object[] { "ar-YE", new [] { "ar-YE" }, true }; + yield return new object[] { "arn", new [] { "arn" }, true }; + yield return new object[] { "arn-CL", new [] { "arn-CL" }, true }; + yield return new object[] { "as", new [] { "as" }, true }; + yield return new object[] { "as-IN", new [] { "as-IN" }, true }; + yield return new object[] { "az", new [] { "az" }, true }; + yield return new object[] { "az-Cyrl", new [] { "az-Cyrl" }, true }; + yield return new object[] { "az-Cyrl-AZ", new [] { "az-Cyrl-AZ" }, true }; + yield return new object[] { "az-Latn", new [] { "az-Latn" }, true }; + yield return new object[] { "az-Latn-AZ", new [] { "az-Latn-AZ" }, true }; + yield return new object[] { "ba", new [] { "ba" }, true }; + yield return new object[] { "ba-RU", new [] { "ba-RU" }, true }; + yield return new object[] { "be", new [] { "be" }, true }; + yield return new object[] { "be-BY", new [] { "be-BY" }, true }; yield return new object[] { "bg", new [] { "bg" } }; yield return new object[] { "bg-BG", new [] { "bg-BG" } }; yield return new object[] { "bn", new [] { "bn" } }; yield return new object[] { "bn-BD", new [] { "bn-BD" } }; yield return new object[] { "bn-IN", new [] { "bn-IN" } }; - yield return new object[] { "bo", new [] { "bo" } }; - yield return new object[] { "bo-CN", new [] { "bo-CN" } }; - yield return new object[] { "br", new [] { "br" } }; - yield return new object[] { "br-FR", new [] { "br-FR" } }; - yield return new object[] { "bs", new [] { "bs" } }; - yield return new object[] { "bs-Cyrl", new [] { "bs-Cyrl" } }; - yield return new object[] { "bs-Cyrl-BA", new [] { "bs-Cyrl-BA" } }; - yield return new object[] { "bs-Latn", new [] { "bs-Latn" } }; - yield return new object[] { "bs-Latn-BA", new [] { "bs-Latn-BA" } }; + yield return new object[] { "bo", new [] { "bo" }, true }; + yield return new object[] { "bo-CN", new [] { "bo-CN" }, true }; + yield return new object[] { "br", new [] { "br" }, true }; + yield return new object[] { "br-FR", new [] { "br-FR" }, true }; + yield return new object[] { "bs", new [] { "bs" }, true }; + yield return new object[] { "bs-Cyrl", new [] { "bs-Cyrl" }, true }; + yield return new object[] { "bs-Cyrl-BA", new [] { "bs-Cyrl-BA" }, true }; + yield return new object[] { "bs-Latn", new [] { "bs-Latn" }, true }; + yield return new object[] { "bs-Latn-BA", new [] { "bs-Latn-BA" }, true }; yield return new object[] { "ca", new [] { "ca" } }; yield return new object[] { "ca-ES", new [] { "ca-ES" } }; - yield return new object[] { "co", new [] { "co" } }; - yield return new object[] { "co-FR", new [] { "co-FR" } }; + yield return new object[] { "co", new [] { "co" }, true }; + yield return new object[] { "co-FR", new [] { "co-FR" }, true }; yield return new object[] { "cs", new [] { "cs" } }; yield return new object[] { "cs-CZ", new [] { "cs-CZ" } }; - yield return new object[] { "cy", new [] { "cy" } }; - yield return new object[] { "cy-GB", new [] { "cy-GB" } }; + yield return new object[] { "cy", new [] { "cy" }, true }; + yield return new object[] { "cy-GB", new [] { "cy-GB" }, true }; yield return new object[] { "da", new [] { "da" } }; yield return new object[] { "da-DK", new [] { "da-DK" } }; yield return new object[] { "de", new [] { "de" } }; yield return new object[] { "de-AT", new [] { "de-AT" } }; yield return new object[] { "de-CH", new [] { "de-CH" } }; yield return new object[] { "de-DE", new [] { "de-DE" } }; - yield return new object[] { "de-DE_phoneb", new [] { "de-DE", "de-DE_phoneb" } }; + yield return new object[] { "de-DE_phoneb", new [] { "de-DE", "de-DE_phoneb" }, true }; yield return new object[] { "de-LI", new [] { "de-LI" } }; yield return new object[] { "de-LU", new [] { "de-LU" } }; - yield return new object[] { "dsb", new [] { "dsb" } }; - yield return new object[] { "dsb-DE", new [] { "dsb-DE" } }; - yield return new object[] { "dv", new [] { "dv" } }; - yield return new object[] { "dv-MV", new [] { "dv-MV" } }; + yield return new object[] { "dsb", new [] { "dsb" }, true }; + yield return new object[] { "dsb-DE", new [] { "dsb-DE" }, true }; + yield return new object[] { "dv", new [] { "dv" }, true }; + yield return new object[] { "dv-MV", new [] { "dv-MV" }, true }; yield return new object[] { "el", new [] { "el" } }; yield return new object[] { "el-GR", new [] { "el-GR" } }; yield return new object[] { "en", new [] { "en" } }; - yield return new object[] { "en-029", new [] { "en-029" } }; + yield return new object[] { "en-029", new [] { "en-029" }, true }; yield return new object[] { "en-AU", new [] { "en-AU" } }; yield return new object[] { "en-BZ", new [] { "en-BZ" } }; yield return new object[] { "en-CA", new [] { "en-CA" } }; @@ -100,61 +100,61 @@ public static IEnumerable Ctor_String_TestData() yield return new object[] { "en-ZA", new [] { "en-ZA" } }; yield return new object[] { "en-ZW", new [] { "en-ZW" } }; yield return new object[] { "es", new [] { "es" } }; - yield return new object[] { "es-AR", new [] { "es-AR" } }; - yield return new object[] { "es-BO", new [] { "es-BO" } }; - yield return new object[] { "es-CL", new [] { "es-CL" } }; - yield return new object[] { "es-CO", new [] { "es-CO" } }; - yield return new object[] { "es-CR", new [] { "es-CR" } }; - yield return new object[] { "es-DO", new [] { "es-DO" } }; - yield return new object[] { "es-EC", new [] { "es-EC" } }; + yield return new object[] { "es-AR", new [] { "es-AR" }, true }; + yield return new object[] { "es-BO", new [] { "es-BO" }, true }; + yield return new object[] { "es-CL", new [] { "es-CL" }, true }; + yield return new object[] { "es-CO", new [] { "es-CO" }, true }; + yield return new object[] { "es-CR", new [] { "es-CR" }, true }; + yield return new object[] { "es-DO", new [] { "es-DO" }, true }; + yield return new object[] { "es-EC", new [] { "es-EC" }, true }; yield return new object[] { "es-ES", new [] { "es-ES" } }; - yield return new object[] { "es-ES_tradnl", new [] { "es-ES", "es-ES_tradnl" } }; - yield return new object[] { "es-GT", new [] { "es-GT" } }; - yield return new object[] { "es-HN", new [] { "es-HN" } }; + yield return new object[] { "es-ES_tradnl", new [] { "es-ES", "es-ES_tradnl" }, true }; + yield return new object[] { "es-GT", new [] { "es-GT" }, true }; + yield return new object[] { "es-HN", new [] { "es-HN" }, true }; yield return new object[] { "es-MX", new [] { "es-MX" } }; - yield return new object[] { "es-NI", new [] { "es-NI" } }; - yield return new object[] { "es-PA", new [] { "es-PA" } }; - yield return new object[] { "es-PE", new [] { "es-PE" } }; - yield return new object[] { "es-PR", new [] { "es-PR" } }; - yield return new object[] { "es-PY", new [] { "es-PY" } }; - yield return new object[] { "es-SV", new [] { "es-SV" } }; - yield return new object[] { "es-US", new [] { "es-US" } }; - yield return new object[] { "es-UY", new [] { "es-UY" } }; - yield return new object[] { "es-VE", new [] { "es-VE" } }; + yield return new object[] { "es-NI", new [] { "es-NI" }, true }; + yield return new object[] { "es-PA", new [] { "es-PA" }, true }; + yield return new object[] { "es-PE", new [] { "es-PE" }, true }; + yield return new object[] { "es-PR", new [] { "es-PR" }, true }; + yield return new object[] { "es-PY", new [] { "es-PY" }, true }; + yield return new object[] { "es-SV", new [] { "es-SV" }, true }; + yield return new object[] { "es-US", new [] { "es-US" }, true }; + yield return new object[] { "es-UY", new [] { "es-UY" }, true }; + yield return new object[] { "es-VE", new [] { "es-VE" }, true }; yield return new object[] { "et", new [] { "et" } }; yield return new object[] { "et-EE", new [] { "et-EE" } }; - yield return new object[] { "eu", new [] { "eu" } }; - yield return new object[] { "eu-ES", new [] { "eu-ES" } }; + yield return new object[] { "eu", new [] { "eu" }, true }; + yield return new object[] { "eu-ES", new [] { "eu-ES" }, true }; yield return new object[] { "fa", new [] { "fa" } }; yield return new object[] { "fa-IR", new [] { "fa-IR" } }; yield return new object[] { "fi", new [] { "fi" } }; yield return new object[] { "fi-FI", new [] { "fi-FI" } }; yield return new object[] { "fil", new [] { "fil" } }; yield return new object[] { "fil-PH", new [] { "fil-PH" } }; - yield return new object[] { "fo", new [] { "fo" } }; - yield return new object[] { "fo-FO", new [] { "fo-FO" } }; + yield return new object[] { "fo", new [] { "fo" }, true }; + yield return new object[] { "fo-FO", new [] { "fo-FO" }, true }; yield return new object[] { "fr", new [] { "fr" } }; yield return new object[] { "fr-BE", new [] { "fr-BE" } }; yield return new object[] { "fr-CA", new [] { "fr-CA" } }; yield return new object[] { "fr-CH", new [] { "fr-CH" } }; yield return new object[] { "fr-FR", new [] { "fr-FR" } }; - yield return new object[] { "fr-LU", new [] { "fr-LU" } }; - yield return new object[] { "fr-MC", new [] { "fr-MC" } }; - yield return new object[] { "fy", new [] { "fy" } }; - yield return new object[] { "fy-NL", new [] { "fy-NL" } }; - yield return new object[] { "ga", new [] { "ga" } }; - yield return new object[] { "ga-IE", new [] { "ga-IE" } }; - yield return new object[] { "gd", new [] { "gd" } }; - yield return new object[] { "gd-GB", new [] { "gd-GB" } }; - yield return new object[] { "gl", new [] { "gl" } }; - yield return new object[] { "gl-ES", new [] { "gl-ES" } }; - yield return new object[] { "gsw", new [] { "gsw" } }; - yield return new object[] { "gsw-FR", new [] { "gsw-FR" } }; + yield return new object[] { "fr-LU", new [] { "fr-LU" }, true }; + yield return new object[] { "fr-MC", new [] { "fr-MC" }, true }; + yield return new object[] { "fy", new [] { "fy" }, true }; + yield return new object[] { "fy-NL", new [] { "fy-NL" }, true }; + yield return new object[] { "ga", new [] { "ga" }, true }; + yield return new object[] { "ga-IE", new [] { "ga-IE" }, true }; + yield return new object[] { "gd", new [] { "gd" }, true }; + yield return new object[] { "gd-GB", new [] { "gd-GB" }, true }; + yield return new object[] { "gl", new [] { "gl" }, true }; + yield return new object[] { "gl-ES", new [] { "gl-ES" }, true }; + yield return new object[] { "gsw", new [] { "gsw" }, true }; + yield return new object[] { "gsw-FR", new [] { "gsw-FR" }, true }; yield return new object[] { "gu", new [] { "gu" } }; yield return new object[] { "gu-IN", new [] { "gu-IN" } }; - yield return new object[] { "ha", new [] { "ha" } }; - yield return new object[] { "ha-Latn", new [] { "ha-Latn" } }; - yield return new object[] { "ha-Latn-NG", new [] { "ha-Latn-NG" } }; + yield return new object[] { "ha", new [] { "ha" }, true }; + yield return new object[] { "ha-Latn", new [] { "ha-Latn" }, true }; + yield return new object[] { "ha-Latn-NG", new [] { "ha-Latn-NG" }, true }; yield return new object[] { "he", new [] { "he" } }; yield return new object[] { "he-IL", new [] { "he-IL" } }; yield return new object[] { "hi", new [] { "hi" } }; @@ -162,221 +162,221 @@ public static IEnumerable Ctor_String_TestData() yield return new object[] { "hr", new [] { "hr" } }; yield return new object[] { "hr-BA", new [] { "hr-BA" } }; yield return new object[] { "hr-HR", new [] { "hr-HR" } }; - yield return new object[] { "hsb", new [] { "hsb" } }; - yield return new object[] { "hsb-DE", new [] { "hsb-DE" } }; + yield return new object[] { "hsb", new [] { "hsb" }, true}; + yield return new object[] { "hsb-DE", new [] { "hsb-DE" }, true }; yield return new object[] { "hu", new [] { "hu" } }; yield return new object[] { "hu-HU", new [] { "hu-HU" } }; - yield return new object[] { "hu-HU_technl", new [] { "hu-HU", "hu-HU_technl" } }; - yield return new object[] { "hy", new [] { "hy" } }; - yield return new object[] { "hy-AM", new [] { "hy-AM" } }; + yield return new object[] { "hu-HU_technl", new [] { "hu-HU", "hu-HU_technl" }, true }; + yield return new object[] { "hy", new [] { "hy" }, true }; + yield return new object[] { "hy-AM", new [] { "hy-AM" }, true }; yield return new object[] { "id", new [] { "id" } }; yield return new object[] { "id-ID", new [] { "id-ID" } }; - yield return new object[] { "ig", new [] { "ig" } }; - yield return new object[] { "ig-NG", new [] { "ig-NG" } }; - yield return new object[] { "ii", new [] { "ii" } }; - yield return new object[] { "ii-CN", new [] { "ii-CN" } }; - yield return new object[] { "is", new [] { "is" } }; - yield return new object[] { "is-IS", new [] { "is-IS" } }; + yield return new object[] { "ig", new [] { "ig" }, true }; + yield return new object[] { "ig-NG", new [] { "ig-NG" }, true }; + yield return new object[] { "ii", new [] { "ii" }, true }; + yield return new object[] { "ii-CN", new [] { "ii-CN" }, true }; + yield return new object[] { "is", new [] { "is" }, true }; + yield return new object[] { "is-IS", new [] { "is-IS" }, true }; yield return new object[] { "it", new [] { "it" } }; yield return new object[] { "it-CH", new [] { "it-CH" } }; yield return new object[] { "it-IT", new [] { "it-IT" } }; - yield return new object[] { "iu", new [] { "iu" } }; - yield return new object[] { "iu-Cans", new [] { "iu-Cans" } }; - yield return new object[] { "iu-Cans-CA", new [] { "iu-Cans-CA" } }; - yield return new object[] { "iu-Latn", new [] { "iu-Latn" } }; - yield return new object[] { "iu-Latn-CA", new [] { "iu-Latn-CA" } }; + yield return new object[] { "iu", new [] { "iu" }, true }; + yield return new object[] { "iu-Cans", new [] { "iu-Cans" }, true }; + yield return new object[] { "iu-Cans-CA", new [] { "iu-Cans-CA" }, true }; + yield return new object[] { "iu-Latn", new [] { "iu-Latn" }, true }; + yield return new object[] { "iu-Latn-CA", new [] { "iu-Latn-CA" }, true }; yield return new object[] { "ja", new [] { "ja" } }; yield return new object[] { "ja-JP", new [] { "ja-JP" } }; - yield return new object[] { "ja-JP_radstr", new [] { "ja-JP", "ja-JP_radstr" } }; - yield return new object[] { "ka", new [] { "ka" } }; - yield return new object[] { "ka-GE", new [] { "ka-GE" } }; - yield return new object[] { "ka-GE_modern", new [] { "ka-GE", "ka-GE_modern" } }; - yield return new object[] { "kk", new [] { "kk" } }; - yield return new object[] { "kk-KZ", new [] { "kk-KZ" } }; - yield return new object[] { "kl", new [] { "kl" } }; - yield return new object[] { "kl-GL", new [] { "kl-GL" } }; - yield return new object[] { "km", new [] { "km" } }; - yield return new object[] { "km-KH", new [] { "km-KH" } }; + yield return new object[] { "ja-JP_radstr", new [] { "ja-JP", "ja-JP_radstr" }, true }; + yield return new object[] { "ka", new [] { "ka" }, true }; + yield return new object[] { "ka-GE", new [] { "ka-GE" }, true }; + yield return new object[] { "ka-GE_modern", new [] { "ka-GE", "ka-GE_modern" }, true }; + yield return new object[] { "kk", new [] { "kk" }, true }; + yield return new object[] { "kk-KZ", new [] { "kk-KZ" }, true }; + yield return new object[] { "kl", new [] { "kl" }, true }; + yield return new object[] { "kl-GL", new [] { "kl-GL" }, true }; + yield return new object[] { "km", new [] { "km" }, true }; + yield return new object[] { "km-KH", new [] { "km-KH" }, true }; yield return new object[] { "kn", new [] { "kn" } }; yield return new object[] { "kn-IN", new [] { "kn-IN" } }; yield return new object[] { "ko", new [] { "ko" } }; yield return new object[] { "ko-KR", new [] { "ko-KR" } }; - yield return new object[] { "kok", new [] { "kok" } }; - yield return new object[] { "kok-IN", new [] { "kok-IN" } }; - yield return new object[] { "ky", new [] { "ky" } }; - yield return new object[] { "ky-KG", new [] { "ky-KG" } }; - yield return new object[] { "lb", new [] { "lb" } }; - yield return new object[] { "lb-LU", new [] { "lb-LU" } }; - yield return new object[] { "lo", new [] { "lo" } }; - yield return new object[] { "lo-LA", new [] { "lo-LA" } }; + yield return new object[] { "kok", new [] { "kok" }, true }; + yield return new object[] { "kok-IN", new [] { "kok-IN" }, true }; + yield return new object[] { "ky", new [] { "ky" }, true }; + yield return new object[] { "ky-KG", new [] { "ky-KG" }, true }; + yield return new object[] { "lb", new [] { "lb" }, true }; + yield return new object[] { "lb-LU", new [] { "lb-LU" }, true }; + yield return new object[] { "lo", new [] { "lo" }, true }; + yield return new object[] { "lo-LA", new [] { "lo-LA" }, true }; yield return new object[] { "lt", new [] { "lt" } }; yield return new object[] { "lt-LT", new [] { "lt-LT" } }; yield return new object[] { "lv", new [] { "lv" } }; yield return new object[] { "lv-LV", new [] { "lv-LV" } }; - yield return new object[] { "mi", new [] { "mi" } }; - yield return new object[] { "mi-NZ", new [] { "mi-NZ" } }; - yield return new object[] { "mk", new [] { "mk" } }; - yield return new object[] { "mk-MK", new [] { "mk-MK" } }; + yield return new object[] { "mi", new [] { "mi" }, true }; + yield return new object[] { "mi-NZ", new [] { "mi-NZ" }, true }; + yield return new object[] { "mk", new [] { "mk" }, true }; + yield return new object[] { "mk-MK", new [] { "mk-MK" }, true }; yield return new object[] { "ml", new [] { "ml" } }; yield return new object[] { "ml-IN", new [] { "ml-IN" } }; - yield return new object[] { "mn", new [] { "mn" } }; - yield return new object[] { "mn-Cyrl", new [] { "mn-Cyrl" } }; - yield return new object[] { "mn-MN", new [] { "mn-MN" } }; - yield return new object[] { "mn-Mong", new [] { "mn-Mong" } }; - yield return new object[] { "mn-Mong-CN", new [] { "mn-Mong-CN" } }; - yield return new object[] { "moh", new [] { "moh" } }; - yield return new object[] { "moh-CA", new [] { "moh-CA" } }; + yield return new object[] { "mn", new [] { "mn" }, true }; + yield return new object[] { "mn-Cyrl", new [] { "mn-Cyrl" }, true }; + yield return new object[] { "mn-MN", new [] { "mn-MN" }, true }; + yield return new object[] { "mn-Mong", new [] { "mn-Mong" }, true }; + yield return new object[] { "mn-Mong-CN", new [] { "mn-Mong-CN" }, true }; + yield return new object[] { "moh", new [] { "moh" }, true }; + yield return new object[] { "moh-CA", new [] { "moh-CA" }, true }; yield return new object[] { "mr", new [] { "mr" } }; yield return new object[] { "mr-IN", new [] { "mr-IN" } }; yield return new object[] { "ms", new [] { "ms" } }; yield return new object[] { "ms-BN", new [] { "ms-BN" } }; yield return new object[] { "ms-MY", new [] { "ms-MY" } }; - yield return new object[] { "mt", new [] { "mt" } }; - yield return new object[] { "mt-MT", new [] { "mt-MT" } }; - yield return new object[] { "nb", new [] { "nb" } }; - yield return new object[] { "nb-NO", new [] { "nb-NO" } }; - yield return new object[] { "ne", new [] { "ne" } }; - yield return new object[] { "ne-NP", new [] { "ne-NP" } }; + yield return new object[] { "mt", new [] { "mt" }, true }; + yield return new object[] { "mt-MT", new [] { "mt-MT" }, true }; + yield return new object[] { "nb", new [] { "nb" }, true }; + yield return new object[] { "nb-NO", new [] { "nb-NO" }, true }; + yield return new object[] { "ne", new [] { "ne" }, true }; + yield return new object[] { "ne-NP", new [] { "ne-NP" }, true }; yield return new object[] { "nl", new [] { "nl" } }; yield return new object[] { "nl-BE", new [] { "nl-BE" } }; yield return new object[] { "nl-NL", new [] { "nl-NL" } }; - yield return new object[] { "nn", new [] { "nn" } }; - yield return new object[] { "nn-NO", new [] { "nn-NO" } }; - yield return new object[] { "no", new [] { "no" } }; - yield return new object[] { "nso", new [] { "nso" } }; - yield return new object[] { "nso-ZA", new [] { "nso-ZA" } }; - yield return new object[] { "oc", new [] { "oc" } }; - yield return new object[] { "oc-FR", new [] { "oc-FR" } }; - yield return new object[] { "or", new [] { "or" } }; - yield return new object[] { "or-IN", new [] { "or-IN" } }; - yield return new object[] { "pa", new [] { "pa" } }; - yield return new object[] { "pa-IN", new [] { "pa-IN" } }; + yield return new object[] { "nn", new [] { "nn" }, true }; + yield return new object[] { "nn-NO", new [] { "nn-NO" }, true }; + yield return new object[] { "no", new [] { "no" }, true }; + yield return new object[] { "nso", new [] { "nso" }, true }; + yield return new object[] { "nso-ZA", new [] { "nso-ZA" }, true }; + yield return new object[] { "oc", new [] { "oc" }, true }; + yield return new object[] { "oc-FR", new [] { "oc-FR" }, true }; + yield return new object[] { "or", new [] { "or" }, true }; + yield return new object[] { "or-IN", new [] { "or-IN" }, true }; + yield return new object[] { "pa", new [] { "pa" }, true }; + yield return new object[] { "pa-IN", new [] { "pa-IN" }, true }; yield return new object[] { "pl", new [] { "pl" } }; yield return new object[] { "pl-PL", new [] { "pl-PL" } }; - yield return new object[] { "prs", new [] { "prs" } }; - yield return new object[] { "prs-AF", new [] { "prs-AF" } }; - yield return new object[] { "ps", new [] { "ps" } }; - yield return new object[] { "ps-AF", new [] { "ps-AF" } }; + yield return new object[] { "prs", new [] { "prs" }, true }; + yield return new object[] { "prs-AF", new [] { "prs-AF" }, true }; + yield return new object[] { "ps", new [] { "ps" }, true }; + yield return new object[] { "ps-AF", new [] { "ps-AF" }, true }; yield return new object[] { "pt", new [] { "pt" } }; yield return new object[] { "pt-BR", new [] { "pt-BR" } }; yield return new object[] { "pt-PT", new [] { "pt-PT" } }; - yield return new object[] { "quz", new [] { "quz" } }; - yield return new object[] { "quz-BO", new [] { "quz-BO" } }; - yield return new object[] { "quz-EC", new [] { "quz-EC" } }; - yield return new object[] { "quz-PE", new [] { "quz-PE" } }; - yield return new object[] { "rm", new [] { "rm" } }; - yield return new object[] { "rm-CH", new [] { "rm-CH" } }; + yield return new object[] { "quz", new [] { "quz" }, true }; + yield return new object[] { "quz-BO", new [] { "quz-BO" }, true }; + yield return new object[] { "quz-EC", new [] { "quz-EC" }, true }; + yield return new object[] { "quz-PE", new [] { "quz-PE" }, true }; + yield return new object[] { "rm", new [] { "rm" }, true }; + yield return new object[] { "rm-CH", new [] { "rm-CH" }, true }; yield return new object[] { "ro", new [] { "ro" } }; yield return new object[] { "ro-RO", new [] { "ro-RO" } }; yield return new object[] { "ru", new [] { "ru" } }; yield return new object[] { "ru-RU", new [] { "ru-RU" } }; - yield return new object[] { "rw", new [] { "rw" } }; - yield return new object[] { "rw-RW", new [] { "rw-RW" } }; - yield return new object[] { "sa", new [] { "sa" } }; - yield return new object[] { "sa-IN", new [] { "sa-IN" } }; - yield return new object[] { "sah", new [] { "sah" } }; - yield return new object[] { "sah-RU", new [] { "sah-RU" } }; - yield return new object[] { "se", new [] { "se" } }; - yield return new object[] { "se-FI", new [] { "se-FI" } }; - yield return new object[] { "se-NO", new [] { "se-NO" } }; - yield return new object[] { "se-SE", new [] { "se-SE" } }; - yield return new object[] { "si", new [] { "si" } }; - yield return new object[] { "si-LK", new [] { "si-LK" } }; + yield return new object[] { "rw", new [] { "rw" }, true }; + yield return new object[] { "rw-RW", new [] { "rw-RW" }, true }; + yield return new object[] { "sa", new [] { "sa" }, true }; + yield return new object[] { "sa-IN", new [] { "sa-IN" }, true }; + yield return new object[] { "sah", new [] { "sah" }, true }; + yield return new object[] { "sah-RU", new [] { "sah-RU" }, true }; + yield return new object[] { "se", new [] { "se" }, true }; + yield return new object[] { "se-FI", new [] { "se-FI" }, true }; + yield return new object[] { "se-NO", new [] { "se-NO" }, true }; + yield return new object[] { "se-SE", new [] { "se-SE" }, true }; + yield return new object[] { "si", new [] { "si" }, true }; + yield return new object[] { "si-LK", new [] { "si-LK" }, true }; yield return new object[] { "sk", new [] { "sk" } }; yield return new object[] { "sk-SK", new [] { "sk-SK" } }; yield return new object[] { "sl", new [] { "sl" } }; yield return new object[] { "sl-SI", new [] { "sl-SI" } }; - yield return new object[] { "sma", new [] { "sma" } }; - yield return new object[] { "sma-NO", new [] { "sma-NO" } }; - yield return new object[] { "sma-SE", new [] { "sma-SE" } }; - yield return new object[] { "smj", new [] { "smj" } }; - yield return new object[] { "smj-NO", new [] { "smj-NO" } }; - yield return new object[] { "smj-SE", new [] { "smj-SE" } }; - yield return new object[] { "smn", new [] { "smn" } }; - yield return new object[] { "smn-FI", new [] { "smn-FI" } }; - yield return new object[] { "sms", new [] { "sms" } }; - yield return new object[] { "sms-FI", new [] { "sms-FI" } }; - yield return new object[] { "sq", new [] { "sq" } }; - yield return new object[] { "sq-AL", new [] { "sq-AL" } }; + yield return new object[] { "sma", new [] { "sma" }, true }; + yield return new object[] { "sma-NO", new [] { "sma-NO" }, true }; + yield return new object[] { "sma-SE", new [] { "sma-SE" }, true }; + yield return new object[] { "smj", new [] { "smj" }, true }; + yield return new object[] { "smj-NO", new [] { "smj-NO" }, true }; + yield return new object[] { "smj-SE", new [] { "smj-SE" }, true }; + yield return new object[] { "smn", new [] { "smn" }, true }; + yield return new object[] { "smn-FI", new [] { "smn-FI" }, true }; + yield return new object[] { "sms", new [] { "sms" }, true }; + yield return new object[] { "sms-FI", new [] { "sms-FI" }, true }; + yield return new object[] { "sq", new [] { "sq" }, true }; + yield return new object[] { "sq-AL", new [] { "sq-AL" }, true }; yield return new object[] { "sr", new [] { "sr" } }; yield return new object[] { "sr-Cyrl", new [] { "sr-Cyrl" } }; - yield return new object[] { "sr-Cyrl-BA", new [] { "sr-Cyrl-BA" } }; - yield return new object[] { "sr-Cyrl-CS", new [] { "sr-Cyrl-CS" } }; - yield return new object[] { "sr-Cyrl-ME", new [] { "sr-Cyrl-ME" } }; + yield return new object[] { "sr-Cyrl-BA", new [] { "sr-Cyrl-BA" }, true }; + yield return new object[] { "sr-Cyrl-CS", new [] { "sr-Cyrl-CS" }, true }; + yield return new object[] { "sr-Cyrl-ME", new [] { "sr-Cyrl-ME" }, true }; yield return new object[] { "sr-Cyrl-RS", new [] { "sr-Cyrl-RS" } }; yield return new object[] { "sr-Latn", new [] { "sr-Latn" } }; - yield return new object[] { "sr-Latn-BA", new [] { "sr-Latn-BA" } }; - yield return new object[] { "sr-Latn-CS", new [] { "sr-Latn-CS" } }; - yield return new object[] { "sr-Latn-ME", new [] { "sr-Latn-ME" } }; + yield return new object[] { "sr-Latn-BA", new [] { "sr-Latn-BA" }, true }; + yield return new object[] { "sr-Latn-CS", new [] { "sr-Latn-CS" }, true }; + yield return new object[] { "sr-Latn-ME", new [] { "sr-Latn-ME" }, true }; yield return new object[] { "sr-Latn-RS", new [] { "sr-Latn-RS" } }; yield return new object[] { "sv", new [] { "sv" } }; - yield return new object[] { "sv-FI", new [] { "sv-FI" } }; + yield return new object[] { "sv-FI", new [] { "sv-FI" }, true }; yield return new object[] { "sv-SE", new [] { "sv-SE" } }; yield return new object[] { "sw", new [] { "sw" } }; yield return new object[] { "sw-KE", new [] { "sw-KE" } }; - yield return new object[] { "syr", new [] { "syr" } }; - yield return new object[] { "syr-SY", new [] { "syr-SY" } }; + yield return new object[] { "syr", new [] { "syr" }, true }; + yield return new object[] { "syr-SY", new [] { "syr-SY" }, true }; yield return new object[] { "ta", new [] { "ta" } }; yield return new object[] { "ta-IN", new [] { "ta-IN" } }; yield return new object[] { "te", new [] { "te" } }; yield return new object[] { "te-IN", new [] { "te-IN" } }; - yield return new object[] { "tg", new [] { "tg" } }; - yield return new object[] { "tg-Cyrl", new [] { "tg-Cyrl" } }; - yield return new object[] { "tg-Cyrl-TJ", new [] { "tg-Cyrl-TJ" } }; + yield return new object[] { "tg", new [] { "tg" }, true }; + yield return new object[] { "tg-Cyrl", new [] { "tg-Cyrl" }, true }; + yield return new object[] { "tg-Cyrl-TJ", new [] { "tg-Cyrl-TJ" }, true }; yield return new object[] { "th", new [] { "th" } }; yield return new object[] { "th-TH", new [] { "th-TH" } }; - yield return new object[] { "tk", new [] { "tk" } }; - yield return new object[] { "tk-TM", new [] { "tk-TM" } }; - yield return new object[] { "tn", new [] { "tn" } }; - yield return new object[] { "tn-ZA", new [] { "tn-ZA" } }; + yield return new object[] { "tk", new [] { "tk" }, true }; + yield return new object[] { "tk-TM", new [] { "tk-TM" }, true }; + yield return new object[] { "tn", new [] { "tn" }, true }; + yield return new object[] { "tn-ZA", new [] { "tn-ZA" }, true }; yield return new object[] { "tr", new [] { "tr" } }; yield return new object[] { "tr-TR", new [] { "tr-TR" } }; - yield return new object[] { "tt", new [] { "tt" } }; - yield return new object[] { "tt-RU", new [] { "tt-RU" } }; - yield return new object[] { "tzm", new [] { "tzm" } }; - yield return new object[] { "tzm-Latn", new [] { "tzm-Latn" } }; - yield return new object[] { "tzm-Latn-DZ", new [] { "tzm-Latn-DZ" } }; - yield return new object[] { "ug", new [] { "ug" } }; - yield return new object[] { "ug-CN", new [] { "ug-CN" } }; + yield return new object[] { "tt", new [] { "tt" }, true }; + yield return new object[] { "tt-RU", new [] { "tt-RU" }, true }; + yield return new object[] { "tzm", new [] { "tzm" }, true }; + yield return new object[] { "tzm-Latn", new [] { "tzm-Latn" }, true }; + yield return new object[] { "tzm-Latn-DZ", new [] { "tzm-Latn-DZ" }, true }; + yield return new object[] { "ug", new [] { "ug" }, true }; + yield return new object[] { "ug-CN", new [] { "ug-CN" }, true }; yield return new object[] { "uk", new [] { "uk" } }; yield return new object[] { "uk-UA", new [] { "uk-UA" } }; - yield return new object[] { "ur", new [] { "ur" } }; - yield return new object[] { "ur-PK", new [] { "ur-PK" } }; - yield return new object[] { "uz", new [] { "uz" } }; - yield return new object[] { "uz-Cyrl", new [] { "uz-Cyrl" } }; - yield return new object[] { "uz-Cyrl-UZ", new [] { "uz-Cyrl-UZ" } }; - yield return new object[] { "uz-Latn", new [] { "uz-Latn" } }; - yield return new object[] { "uz-Latn-UZ", new [] { "uz-Latn-UZ" } }; + yield return new object[] { "ur", new [] { "ur" }, true }; + yield return new object[] { "ur-PK", new [] { "ur-PK" }, true }; + yield return new object[] { "uz", new [] { "uz" }, true }; + yield return new object[] { "uz-Cyrl", new [] { "uz-Cyrl" }, true }; + yield return new object[] { "uz-Cyrl-UZ", new [] { "uz-Cyrl-UZ" }, true }; + yield return new object[] { "uz-Latn", new [] { "uz-Latn" }, true }; + yield return new object[] { "uz-Latn-UZ", new [] { "uz-Latn-UZ" }, true }; yield return new object[] { "vi", new [] { "vi" } }; yield return new object[] { "vi-VN", new [] { "vi-VN" } }; - yield return new object[] { "wo", new [] { "wo" } }; - yield return new object[] { "wo-SN", new [] { "wo-SN" } }; - yield return new object[] { "xh", new [] { "xh" } }; - yield return new object[] { "xh-ZA", new [] { "xh-ZA" } }; - yield return new object[] { "yo", new [] { "yo" } }; - yield return new object[] { "yo-NG", new [] { "yo-NG" } }; + yield return new object[] { "wo", new [] { "wo" }, true }; + yield return new object[] { "wo-SN", new [] { "wo-SN" }, true }; + yield return new object[] { "xh", new [] { "xh" }, true }; + yield return new object[] { "xh-ZA", new [] { "xh-ZA" }, true }; + yield return new object[] { "yo", new [] { "yo" }, true }; + yield return new object[] { "yo-NG", new [] { "yo-NG" }, true }; yield return new object[] { "zh", new [] { "zh" } }; - yield return new object[] { "zh-CHS", new [] { "zh-CHS", "zh-Hans" } }; - yield return new object[] { "zh-CHT", new [] { "zh-CHT", "zh-Hant" } }; + yield return new object[] { "zh-CHS", new [] { "zh-CHS", "zh-Hans" }, true }; + yield return new object[] { "zh-CHT", new [] { "zh-CHT", "zh-Hant" }, true }; yield return new object[] { "zh-CN", new [] { "zh-CN" } }; - yield return new object[] { "zh-CN_stroke", new [] { "zh-CN", "zh-CN_stroke" } }; + yield return new object[] { "zh-CN_stroke", new [] { "zh-CN", "zh-CN_stroke" }, true }; yield return new object[] { "zh-Hans", new [] { "zh-Hans" } }; yield return new object[] { "zh-Hant", new [] { "zh-Hant" } }; yield return new object[] { "zh-HK", new [] { "zh-HK" } }; - yield return new object[] { "zh-HK_radstr", new [] { "zh-HK", "zh-HK_radstr" } }; - yield return new object[] { "zh-MO", new [] { "zh-MO" } }; - yield return new object[] { "zh-MO_radstr", new [] { "zh-MO", "zh-MO_radstr" } }; - yield return new object[] { "zh-MO_stroke", new [] { "zh-MO", "zh-MO_stroke" } }; + yield return new object[] { "zh-HK_radstr", new [] { "zh-HK", "zh-HK_radstr" }, true }; + yield return new object[] { "zh-MO", new [] { "zh-MO" }, true }; + yield return new object[] { "zh-MO_radstr", new [] { "zh-MO", "zh-MO_radstr" }, true }; + yield return new object[] { "zh-MO_stroke", new [] { "zh-MO", "zh-MO_stroke" }, true }; yield return new object[] { "zh-SG", new [] { "zh-SG" } }; - yield return new object[] { "zh-SG_stroke", new [] { "zh-SG", "zh-SG_stroke" } }; + yield return new object[] { "zh-SG_stroke", new [] { "zh-SG", "zh-SG_stroke" }, true }; yield return new object[] { "zh-TW", new [] { "zh-TW" } }; - yield return new object[] { "zh-TW_pronun", new [] { "zh-TW", "zh-TW_pronun" } }; - yield return new object[] { "zh-TW_radstr", new [] { "zh-TW", "zh-TW_radstr" } }; - yield return new object[] { "zu", new [] { "zu" } }; - yield return new object[] { "zu-ZA", new [] { "zu-ZA" } }; + yield return new object[] { "zh-TW_pronun", new [] { "zh-TW", "zh-TW_pronun" }, true }; + yield return new object[] { "zh-TW_radstr", new [] { "zh-TW", "zh-TW_radstr" }, true }; + yield return new object[] { "zu", new [] { "zu" }, true }; + yield return new object[] { "zu-ZA", new [] { "zu-ZA" }, true }; yield return new object[] { CultureInfo.CurrentCulture.Name, new [] { CultureInfo.CurrentCulture.Name } }; - if (!PlatformDetection.IsWindows || PlatformDetection.WindowsVersion >= 10) + if ((!PlatformDetection.IsWindows || PlatformDetection.WindowsVersion >= 10) && (PlatformDetection.IsNotBrowser)) { yield return new object[] { "en-US-CUSTOM", new [] { "en-US-CUSTOM", "en-US-custom" } }; yield return new object[] { "xx-XX", new [] { "xx-XX" } }; @@ -385,9 +385,9 @@ public static IEnumerable Ctor_String_TestData() [Theory] [MemberData(nameof(Ctor_String_TestData))] - public void Ctor_String(string name, string[] expectedNames) + public void Ctor_String(string name, string[] expectedNames, bool expectToThrowOnBrowser = false) { - try + if (!expectToThrowOnBrowser || PlatformDetection.IsNotBrowser) { CultureInfo culture = new CultureInfo(name); string cultureName = culture.Name; @@ -396,7 +396,7 @@ public void Ctor_String(string name, string[] expectedNames) culture = new CultureInfo(cultureName); Assert.Equal(cultureName, culture.ToString(), ignoreCase: true); } - catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) + else { Assert.Throws(() => new CultureInfo(name)); } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs index 458dff8113f4d..9215095756e98 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -13,7 +13,7 @@ namespace System.Globalization.Tests { public class CurrentCultureTests { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [Fact] public void CurrentCulture() { var newCulture = new CultureInfo(CultureInfo.CurrentCulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); @@ -22,11 +22,14 @@ public void CurrentCulture() Assert.Equal(CultureInfo.CurrentCulture, newCulture); } - newCulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(newCulture)) + if (PlatformDetection.IsNotBrowser) { - Assert.Equal(CultureInfo.CurrentCulture, newCulture); - Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); + newCulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(newCulture)) + { + Assert.Equal(CultureInfo.CurrentCulture, newCulture); + Assert.Equal("de-DE_phoneb", newCulture.CompareInfo.Name); + } } } @@ -36,7 +39,7 @@ public void CurrentCulture_Set_Null_ThrowsArgumentNullException() AssertExtensions.Throws("value", () => CultureInfo.CurrentCulture = null); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [Fact] public void CurrentUICulture() { var newUICulture = new CultureInfo(CultureInfo.CurrentUICulture.Name.Equals("ja-JP", StringComparison.OrdinalIgnoreCase) ? "ar-SA" : "ja-JP"); @@ -45,11 +48,14 @@ public void CurrentUICulture() Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); } - newUICulture = new CultureInfo("de-DE_phoneb"); - using (new ThreadCultureChange(null, newUICulture)) + if (PlatformDetection.IsNotBrowser) { - Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); - Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); + newUICulture = new CultureInfo("de-DE_phoneb"); + using (new ThreadCultureChange(null, newUICulture)) + { + Assert.Equal(CultureInfo.CurrentUICulture, newUICulture); + Assert.Equal("de-DE_phoneb", newUICulture.CompareInfo.Name); + } } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs index 37ba49bcca953..8aa897a17a106 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoParent.cs @@ -35,7 +35,7 @@ public void Parent(string name, string expectedParentName) [Fact] public void Parent_ParentChain() { - if (PlatformDetection.IsNotPredefinedCulturesOnly) + if (PlatformDetection.IsNotBrowser) { CultureInfo myExpectParentCulture = new CultureInfo("uz-Cyrl-UZ"); Assert.Equal("uz-Cyrl", myExpectParentCulture.Parent.Name); diff --git a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs index c6ac55075725b..4fa32f5127936 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs @@ -57,16 +57,9 @@ public void CurrentRegion_Unix() { using (new ThreadCultureChange("en-US")) { - try - { - RegionInfo ri = new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName); - Assert.True(RegionInfo.CurrentRegion.Equals(ri) || RegionInfo.CurrentRegion.Equals(new RegionInfo(CultureInfo.CurrentCulture.Name))); - Assert.Same(RegionInfo.CurrentRegion, RegionInfo.CurrentRegion); - } - catch (CultureNotFoundException) when (PlatformDetection.IsPredefinedCulturesOnly) - { - AssertExtensions.Throws(() => new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName)); - } + RegionInfo ri = new RegionInfo(new RegionInfo(CultureInfo.CurrentCulture.Name).TwoLetterISORegionName); + Assert.True(RegionInfo.CurrentRegion.Equals(ri) || RegionInfo.CurrentRegion.Equals(new RegionInfo(CultureInfo.CurrentCulture.Name))); + Assert.Same(RegionInfo.CurrentRegion, RegionInfo.CurrentRegion); } } diff --git a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index ba80c85c0240a..8da8cdb6aa93f 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs @@ -288,7 +288,7 @@ public static IEnumerable ToLower_TestData() // ICU has special tailoring for the en-US-POSIX locale which treats "i" and "I" as different letters // instead of two letters with a case difference during collation. Make sure this doesn't confuse our // casing implementation, which uses collation to understand if we need to do Turkish casing or not. - if (!PlatformDetection.IsWindows) + if (!PlatformDetection.IsWindows && PlatformDetection.IsNotBrowser) { yield return new object[] { "en-US-POSIX", "I", "i" }; } @@ -303,7 +303,7 @@ private static void TestToLower(string name, string str, string expected) } } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [Theory] [MemberData(nameof(ToLower_TestData))] public void ToLower(string name, string str, string expected) { @@ -411,7 +411,7 @@ public static IEnumerable ToUpper_TestData() // ICU has special tailoring for the en-US-POSIX locale which treats "i" and "I" as different letters // instead of two letters with a case difference during collation. Make sure this doesn't confuse our // casing implementation, which uses collation to understand if we need to do Turkish casing or not. - if (!PlatformDetection.IsWindows) + if (!PlatformDetection.IsWindows && PlatformDetection.IsNotBrowser) { yield return new object[] { "en-US-POSIX", "i", "I" }; } @@ -426,7 +426,7 @@ private static void TestToUpper(string name, string str, string expected) } } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [Theory] [MemberData(nameof(ToUpper_TestData))] public void ToUpper(string name, string str, string expected) { From f8163f70008848e589dc2e9b33b2ae76820b201e Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Thu, 4 Mar 2021 12:25:16 -0500 Subject: [PATCH 17/23] move exception out of CreateCulturedata --- .../tests/CultureInfo/CultureInfoAll.cs | 4 ++-- .../System/Globalization/CultureData.Icu.cs | 8 ++------ .../System/Globalization/CultureData.Nls.cs | 8 ++------ .../src/System/Globalization/CultureData.cs | 18 ++++++------------ .../src/System/Globalization/CultureInfo.cs | 11 ++++++++--- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs index ccef468681d66..c89088b7119b6 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoAll.cs @@ -731,7 +731,7 @@ public void LcidTest(int lcid, string[] cultureNames, string specificCultureName } else { - AssertExtensions.Throws("name", () => new CultureInfo(lcid)); + AssertExtensions.Throws(() => new CultureInfo(lcid)); } } @@ -794,7 +794,7 @@ public void GetCulturesTest(int lcid, string[] cultureNames, string specificCult } else { - AssertExtensions.Throws("name", () => new CultureInfo(lcid)); + AssertExtensions.Throws(() => new CultureInfo(lcid)); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index 1d16ec83845da..cbc4a301c39ce 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -223,14 +223,10 @@ private static string IcuGetLanguageDisplayName(string cultureName) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void IcuIsEnsurePredefinedLocaleName(string name) + internal static bool IcuIsEnsurePredefinedLocaleName(string name) { Debug.Assert(!GlobalizationMode.UseNls); - - if (!Interop.Globalization.IsPredefinedLocale(name)) - { - throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); - } + return Interop.Globalization.IsPredefinedLocale(name); } private static string ConvertIcuTimeFormatString(ReadOnlySpan icuFormatString) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 74ae84eda4805..24f0301e856ac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -87,14 +87,10 @@ private int[] NlsGetLocaleInfo(LocaleGroupingData type) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void NlsIsEnsurePredefinedLocaleName(string name) + internal static bool NlsIsEnsurePredefinedLocaleName(string name) { Debug.Assert(GlobalizationMode.UseNls); - - if (CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1) - { - throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); - } + return CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1; } private string? NlsGetTimeFormatString() diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 1a3d95a84f6af..ceb087317cfec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -694,6 +694,12 @@ private static CultureData CreateCultureWithInvariantData() return CultureData.Invariant; } + if (GlobalizationMode.PredefinedCulturesOnly) + { + if (GlobalizationMode.UseNls ? !NlsIsEnsurePredefinedLocaleName(cultureName): !IcuIsEnsurePredefinedLocaleName(cultureName)) + return null; + } + // Try the hash table first string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*'); Dictionary? tempHashTable = s_cachedCultures; @@ -820,18 +826,6 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return CultureData.Invariant; } - if (GlobalizationMode.PredefinedCulturesOnly) - { - if (GlobalizationMode.UseNls) - { - NlsIsEnsurePredefinedLocaleName(cultureName); - } - else - { - IcuIsEnsurePredefinedLocaleName(cultureName); - } - } - CultureData culture = new CultureData(); culture._sRealName = cultureName; culture._bUseOverridesUserSetting = useUserOverride; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 5a071799bbb05..f8f7909f640c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -1168,9 +1168,14 @@ public static CultureInfo GetCultureInfo(string name, bool predefinedOnly) if (predefinedOnly && !GlobalizationMode.Invariant) { - return GlobalizationMode.UseNls ? - NlsGetPredefinedCultureInfo(name) : - IcuGetPredefinedCultureInfo(name); + if (GlobalizationMode.UseNls ? !CultureData.NlsIsEnsurePredefinedLocaleName(name): !CultureData.IcuIsEnsurePredefinedLocaleName(name)) + { + throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); + } + else + { + return GlobalizationMode.UseNls ? NlsGetPredefinedCultureInfo(name) : IcuGetPredefinedCultureInfo(name); + } } return GetCultureInfo(name); From 451a3ad25d83cebb631605ae0d81de9b2b035c8f Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Thu, 4 Mar 2021 12:58:55 -0500 Subject: [PATCH 18/23] remove else block --- .../src/System/Globalization/CultureInfo.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index f8f7909f640c1..74badb19fbe4e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -1172,10 +1172,7 @@ public static CultureInfo GetCultureInfo(string name, bool predefinedOnly) { throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); } - else - { - return GlobalizationMode.UseNls ? NlsGetPredefinedCultureInfo(name) : IcuGetPredefinedCultureInfo(name); - } + return GlobalizationMode.UseNls ? NlsGetPredefinedCultureInfo(name) : IcuGetPredefinedCultureInfo(name); } return GetCultureInfo(name); From 0bc3a5caa187b4e9997ca2d3ba2b7de8d7aba22b Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Thu, 4 Mar 2021 13:53:56 -0500 Subject: [PATCH 19/23] remove redundant methods --- .../System.Private.CoreLib.Shared.projitems | 2 -- .../System/Globalization/CultureInfo.Icu.cs | 19 ------------------- .../System/Globalization/CultureInfo.Nls.cs | 19 ------------------- .../src/System/Globalization/CultureInfo.cs | 1 - 4 files changed, 41 deletions(-) delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 642ff0d671a92..8320e24fe58af 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -297,8 +297,6 @@ - - diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs deleted file mode 100644 index 18038e2b0b38c..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; - -namespace System.Globalization -{ - public partial class CultureInfo : IFormatProvider - { - private static CultureInfo IcuGetPredefinedCultureInfo(string name) - { - Debug.Assert(!GlobalizationMode.UseNls); - - CultureData.IcuIsEnsurePredefinedLocaleName(name); - - return GetCultureInfo(name); - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs deleted file mode 100644 index d8a5badf5363f..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; - -namespace System.Globalization -{ - public partial class CultureInfo : IFormatProvider - { - private static CultureInfo NlsGetPredefinedCultureInfo(string name) - { - Debug.Assert(GlobalizationMode.UseNls); - - CultureData.NlsIsEnsurePredefinedLocaleName(name); - - return GetCultureInfo(name); - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 74badb19fbe4e..d2d51bc6294d5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -1172,7 +1172,6 @@ public static CultureInfo GetCultureInfo(string name, bool predefinedOnly) { throw new CultureNotFoundException(nameof(name), name, SR.Format(SR.Argument_InvalidPredefinedCultureName, name)); } - return GlobalizationMode.UseNls ? NlsGetPredefinedCultureInfo(name) : IcuGetPredefinedCultureInfo(name); } return GetCultureInfo(name); From c40d61023ddb7d36d14e75f94e5427cd45099885 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Thu, 4 Mar 2021 14:01:32 -0500 Subject: [PATCH 20/23] revert logic in nls --- .../src/System/Globalization/CultureData.Nls.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 24f0301e856ac..207ea8109f662 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -90,7 +90,7 @@ private int[] NlsGetLocaleInfo(LocaleGroupingData type) internal static bool NlsIsEnsurePredefinedLocaleName(string name) { Debug.Assert(GlobalizationMode.UseNls); - return CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1; + return CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) != 1; } private string? NlsGetTimeFormatString() From eeeda5f0aa2261b276262524555c19a25633d080 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Fri, 5 Mar 2021 11:36:22 -0500 Subject: [PATCH 21/23] Update src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs Co-authored-by: Larry Ewing --- .../tests/src/Tests/Assembly/AssemblyTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs index adca9a9b4b102..43179d98a0a56 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Assembly/AssemblyTests.cs @@ -170,7 +170,6 @@ public static void AssemblyGetReferencedAssemblies() { Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyReferencesTestImage); AssemblyName[] ans = a.GetReferencedAssemblies(); - Console.WriteLine("GET ASSEMBLY TESTS 3"); Assert.Equal(3, ans.Length); { AssemblyName an = ans.Single(an2 => an2.Name == "mscorlib"); From 0aab18e46c2eb2b9541fb68bcf8b7a2325f07b70 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 9 Mar 2021 11:00:29 -0500 Subject: [PATCH 22/23] fix invariant tests --- .../src/System/Globalization/CultureData.cs | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index ceb087317cfec..b390d2fff38b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -423,33 +423,12 @@ internal partial class CultureData return CultureData.Invariant; } CultureData? retVal = null; - try + // First check if GetCultureData() can find it (ie: its a real culture) + retVal = GetCultureData(cultureName, useUserOverride); + if (retVal != null && !retVal.IsNeutralCulture) { - // First check if GetCultureData() can find it (ie: its a real culture) - retVal = GetCultureData(cultureName, useUserOverride); - if (retVal != null && !retVal.IsNeutralCulture) - { - return retVal; - } + return retVal; } - catch (CultureNotFoundException) when (GlobalizationMode.PredefinedCulturesOnly) - { - // Catching this exception because GetCultureData will throw if the region name is not defined yet - // If not a valid mapping from the registry we'll have to try the hard coded table - if (retVal == null || retVal.IsNeutralCulture) - { - // Not a valid mapping, try the hard coded table - if (RegionNames.TryGetValue(cultureName, out string? name)) - { - // Make sure we can get culture data for it - retVal = GetCultureData(name, useUserOverride); - return retVal; - } - } - } - - // Not a specific culture, perhaps it's region-only name - // (Remember this isn't a core clr path where that's not supported) // If it was neutral remember that so that RegionInfo() can throw the right exception CultureData? neutral = retVal; @@ -694,7 +673,7 @@ private static CultureData CreateCultureWithInvariantData() return CultureData.Invariant; } - if (GlobalizationMode.PredefinedCulturesOnly) + if (GlobalizationMode.PredefinedCulturesOnly && !GlobalizationMode.Invariant) { if (GlobalizationMode.UseNls ? !NlsIsEnsurePredefinedLocaleName(cultureName): !IcuIsEnsurePredefinedLocaleName(cultureName)) return null; From 23842eedb87e3ef85960d543fcd37f092dc061cb Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 9 Mar 2021 21:21:02 -0500 Subject: [PATCH 23/23] remove aggressive inlining --- .../src/System/Globalization/CultureData.Icu.cs | 2 -- .../src/System/Globalization/CultureData.Nls.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index cbc4a301c39ce..de0bee85720ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; namespace System.Globalization { @@ -222,7 +221,6 @@ private static string IcuGetLanguageDisplayName(string cultureName) return null; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool IcuIsEnsurePredefinedLocaleName(string name) { Debug.Assert(!GlobalizationMode.UseNls); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 207ea8109f662..5997990dd9690 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text; -using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -86,7 +85,6 @@ private int[] NlsGetLocaleInfo(LocaleGroupingData type) return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, _bUseOverrides)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool NlsIsEnsurePredefinedLocaleName(string name) { Debug.Assert(GlobalizationMode.UseNls);