From 128c757a3ac580829d08c2a60aa205559ccde8f9 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 10 Mar 2021 17:59:22 -0500 Subject: [PATCH] [wasm] Throw exception if culture data does not exist in icu (#47301) * Add check for culture data in ICU Add PredefinedOnly GlobalizationMode Modified tests if Culture Data not found * Add test for predefined culture env var * change assembly test data to pl-PL to avoid culturenotfound exception Co-authored-by: Larry Ewing --- .../Common/tests/Tests/System/StringTests.cs | 3 +- .../tests/CultureInfoConverterTests.cs | 6 +- .../CompareInfo/CompareInfoTests.Compare.cs | 7 +- .../tests/CultureInfo/CultureInfoAll.cs | 197 +++---- .../tests/CultureInfo/CultureInfoCtor.cs | 483 +++++++++--------- .../CultureInfo/CultureInfoCurrentCulture.cs | 22 +- .../tests/CultureInfo/CultureInfoParent.cs | 18 +- .../tests/CultureInfo/GetCultureInfo.cs | 31 +- .../System/Globalization/TextInfoTests.cs | 4 +- .../System.Private.CoreLib.Shared.projitems | 2 - .../System/Globalization/CultureData.Icu.cs | 11 +- .../System/Globalization/CultureData.Nls.cs | 6 + .../src/System/Globalization/CultureData.cs | 14 +- .../System/Globalization/CultureInfo.Icu.cs | 22 - .../System/Globalization/CultureInfo.Nls.cs | 22 - .../src/System/Globalization/CultureInfo.cs | 7 +- .../System/Globalization/GlobalizationMode.cs | 3 + .../tests/src/TestUtils/TestData.cs | 2 +- .../tests/src/Tests/Assembly/AssemblyTests.cs | 3 +- .../tests/System/DateTimeTests.cs | 22 +- src/mono/wasm/runtime/library_mono.js | 3 + 21 files changed, 472 insertions(+), 416 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/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index 305c0efc6b450..4c79d008e84ff 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -2567,8 +2567,7 @@ public void Equals_Encyclopaedia_ReturnsExpected(StringComparison comparison, bo { string source = "encyclop\u00e6dia"; string target = "encyclopaedia"; - - using (new ThreadCultureChange("se-SE")) + 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.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs index 3523e7c4c5b1f..bbe51686b1ec8 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.IsNotBrowser) + { + yield return ConvertTest.Valid("Afrikaans", new CultureInfo("af")); + } yield return ConvertTest.CantConvertFrom(CultureInfo.CurrentCulture); yield return ConvertTest.CantConvertFrom(1); 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 659126b4aeb82..c89088b7119b6 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 @@ -528,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" }; @@ -643,90 +644,97 @@ 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) { - _ = alternativeCultureName; + if (!expectToThrowOnBrowser || PlatformDetection.IsNotBrowser) + { + _ = 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 != "") + else { - Assert.Equal(consoleUICultureName, ci.GetConsoleFallbackUICulture().Name); + AssertExtensions.Throws(() => 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" }; @@ -760,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(() => 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 9db444be85bd6..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,14 +385,21 @@ 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) { - CultureInfo culture = new CultureInfo(name); - string cultureName = culture.Name; - Assert.Contains(cultureName, expectedNames, StringComparer.OrdinalIgnoreCase); + if (!expectToThrowOnBrowser || PlatformDetection.IsNotBrowser) + { + 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); + } + else + { + Assert.Throws(() => new CultureInfo(name)); + } } [Fact] diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs index 4831424e45da9..9215095756e98 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -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); + } } } @@ -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 b9d6be536f48d..8aa897a17a106 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.IsNotBrowser) + { + 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..0b4bdd5708992 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/GetCultureInfo.cs @@ -2,13 +2,16 @@ // 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 { 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 bool PlatformSupportsFakeCultureAndRemoteExecutor => PlatformSupportsFakeCulture && RemoteExecutor.IsSupported; public static IEnumerable GetCultureInfoTestData() { @@ -110,5 +113,31 @@ public void TestFakeCultureNames(string name) Assert.Equal(name, CultureInfo.GetCultureInfo(name, predefinedOnly: false).Name); Assert.Throws(() => CultureInfo.GetCultureInfo(name, predefinedOnly: true)); } + + [ConditionalTheory(nameof(PlatformSupportsFakeCultureAndRemoteExecutor))] + [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/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index 72e155fab597a..dfa19bdf7e411 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" }; } @@ -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" }; } 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 a6b2c16f6a37c..d9900d80412cd 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 @@ -307,8 +307,6 @@ - - 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..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 @@ -63,11 +63,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 +107,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 +134,6 @@ private unsafe string IcuGetLocaleInfo(string localeName, LocaleStringData type) Debug.Fail("[CultureData.IcuGetLocaleInfo(LocaleStringData)] Failed"); return string.Empty; } - return new string(buffer); } @@ -226,6 +221,12 @@ private static string IcuGetLanguageDisplayName(string cultureName) return null; } + internal static bool IcuIsEnsurePredefinedLocaleName(string name) + { + Debug.Assert(!GlobalizationMode.UseNls); + return Interop.Globalization.IsPredefinedLocale(name); + } + 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..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 @@ -85,6 +85,12 @@ private int[] NlsGetLocaleInfo(LocaleGroupingData type) return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, _bUseOverrides)); } + internal static bool NlsIsEnsurePredefinedLocaleName(string name) + { + Debug.Assert(GlobalizationMode.UseNls); + return CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) != 1; + } + 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 76e95e087dd3a..b390d2fff38b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -422,17 +422,14 @@ internal partial class CultureData { return CultureData.Invariant; } - + CultureData? retVal = null; // First check if GetCultureData() can find it (ie: its a real culture) - CultureData? retVal = GetCultureData(cultureName, useUserOverride); + retVal = GetCultureData(cultureName, useUserOverride); if (retVal != null && !retVal.IsNeutralCulture) { 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; @@ -676,6 +673,12 @@ private static CultureData CreateCultureWithInvariantData() return CultureData.Invariant; } + if (GlobalizationMode.PredefinedCulturesOnly && !GlobalizationMode.Invariant) + { + if (GlobalizationMode.UseNls ? !NlsIsEnsurePredefinedLocaleName(cultureName): !IcuIsEnsurePredefinedLocaleName(cultureName)) + return null; + } + // Try the hash table first string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*'); Dictionary? tempHashTable = s_cachedCultures; @@ -698,7 +701,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) 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 6b79b44afba6f..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Icu.cs +++ /dev/null @@ -1,22 +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); - - if (!Interop.Globalization.IsPredefinedLocale(name)) - { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, 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 b5313130732ab..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Nls.cs +++ /dev/null @@ -1,22 +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); - - if (CultureData.GetLocaleInfoExInt(name, Interop.Kernel32.LOCALE_ICONSTRUCTEDLOCALE) == 1) - { - throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_InvalidPredefinedCultureName, 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 311d9b955ead0..729119c8c163a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -1169,9 +1169,10 @@ 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)); + } } 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 6b90460a2e2b6..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,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 PredefinedCulturesOnly { get; } = + GetSwitchValue("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY"); + private static bool GetSwitchValue(string switchName, string envVariable) { if (!AppContext.TryGetSwitch(switchName, out bool ret)) 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..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 @@ -171,7 +171,6 @@ public static void AssemblyGetReferencedAssemblies() Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyReferencesTestImage); AssemblyName[] ans = a.GetReferencedAssemblies(); Assert.Equal(3, ans.Length); - { AssemblyName an = ans.Single(an2 => an2.Name == "mscorlib"); Assert.Equal(default(AssemblyNameFlags), an.Flags); @@ -211,7 +210,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); } diff --git a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs index f0da337f157b2..4803a880bfb64 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs @@ -1544,7 +1544,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); @@ -1728,8 +1736,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..8ea48beafe72d 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 PredefinedCulturesOnly + this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", "1"); }, // Used by the debugger to enumerate loaded dlls and pdbs