1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Reflection; 7 using Xunit; 8 9 namespace System.Globalization.Tests 10 { 11 public class CompareInfoTests 12 { 13 [Theory] 14 [InlineData("")] 15 [InlineData("en-US")] 16 [InlineData("fr-FR")] 17 [InlineData("en")] 18 [InlineData("zh-Hans")] 19 [InlineData("zh-Hant")] GetCompareInfo(string name)20 public void GetCompareInfo(string name) 21 { 22 CompareInfo compare = CompareInfo.GetCompareInfo(name); 23 Assert.Equal(name, compare.Name); 24 } 25 26 [Fact] GetCompareInfo_Null_ThrowsArgumentNullException()27 public void GetCompareInfo_Null_ThrowsArgumentNullException() 28 { 29 AssertExtensions.Throws<ArgumentNullException>("name", () => CompareInfo.GetCompareInfo(null)); 30 } 31 Equals_TestData()32 public static IEnumerable<object[]> Equals_TestData() 33 { 34 yield return new object[] { CultureInfo.InvariantCulture.CompareInfo, CultureInfo.InvariantCulture.CompareInfo, true }; 35 yield return new object[] { CultureInfo.InvariantCulture.CompareInfo, CompareInfo.GetCompareInfo(""), true }; 36 yield return new object[] { new CultureInfo("en-US").CompareInfo, CompareInfo.GetCompareInfo("en-US"), true }; 37 yield return new object[] { new CultureInfo("en-US").CompareInfo, CompareInfo.GetCompareInfo("fr-FR"), false }; 38 yield return new object[] { new CultureInfo("en-US").CompareInfo, new object(), false }; 39 } 40 41 [Theory] 42 [MemberData(nameof(Equals_TestData))] Equals(CompareInfo compare1, object value, bool expected)43 public void Equals(CompareInfo compare1, object value, bool expected) 44 { 45 Assert.Equal(expected, compare1.Equals(value)); 46 if (value is CompareInfo) 47 { 48 Assert.Equal(expected, compare1.GetHashCode().Equals(value.GetHashCode())); 49 } 50 } 51 52 [Theory] 53 [InlineData("abc", CompareOptions.OrdinalIgnoreCase, "ABC", CompareOptions.OrdinalIgnoreCase, true)] 54 [InlineData("abc", CompareOptions.Ordinal, "ABC", CompareOptions.Ordinal, false)] 55 [InlineData("abc", CompareOptions.Ordinal, "abc", CompareOptions.Ordinal, true)] 56 [InlineData("abc", CompareOptions.None, "abc", CompareOptions.None, true)] GetHashCode(string source1, CompareOptions options1, string source2, CompareOptions options2, bool expected)57 public void GetHashCode(string source1, CompareOptions options1, string source2, CompareOptions options2, bool expected) 58 { 59 CompareInfo invariantCompare = CultureInfo.InvariantCulture.CompareInfo; 60 Assert.Equal(expected, invariantCompare.GetHashCode(source1, options1).Equals(invariantCompare.GetHashCode(source2, options2))); 61 } 62 63 [Fact] GetHashCode_EmptyString()64 public void GetHashCode_EmptyString() 65 { 66 Assert.Equal(0, CultureInfo.InvariantCulture.CompareInfo.GetHashCode("", CompareOptions.None)); 67 } 68 69 [Fact] GetHashCode_Invalid()70 public void GetHashCode_Invalid() 71 { 72 AssertExtensions.Throws<ArgumentNullException>("source", () => CultureInfo.InvariantCulture.CompareInfo.GetHashCode(null, CompareOptions.None)); 73 74 AssertExtensions.Throws<ArgumentException>("options", () => CultureInfo.InvariantCulture.CompareInfo.GetHashCode("Test", CompareOptions.StringSort)); 75 AssertExtensions.Throws<ArgumentException>("options", () => CultureInfo.InvariantCulture.CompareInfo.GetHashCode("Test", CompareOptions.Ordinal | CompareOptions.IgnoreSymbols)); 76 AssertExtensions.Throws<ArgumentException>("options", () => CultureInfo.InvariantCulture.CompareInfo.GetHashCode("Test", (CompareOptions)(-1))); 77 } 78 79 [Theory] 80 [InlineData("", "CompareInfo - ")] 81 [InlineData("en-US", "CompareInfo - en-US")] 82 [InlineData("EN-US", "CompareInfo - en-US")] ToString(string name, string expected)83 public void ToString(string name, string expected) 84 { 85 Assert.Equal(expected, new CultureInfo(name).CompareInfo.ToString()); 86 } 87 CompareInfo_TestData()88 public static IEnumerable<object[]> CompareInfo_TestData() 89 { 90 yield return new object[] { "en-US" , 0x0409 }; 91 yield return new object[] { "ar-SA" , 0x0401 }; 92 yield return new object[] { "ja-JP" , 0x0411 }; 93 yield return new object[] { "zh-CN" , 0x0804 }; 94 yield return new object[] { "en-GB" , 0x0809 }; 95 yield return new object[] { "tr-TR" , 0x041f }; 96 } 97 98 // On Windows, hiragana characters sort after katakana. 99 // On ICU, it is the opposite 100 private static int s_expectedHiraganaToKatakanaCompare = PlatformDetection.IsWindows ? 1 : -1; 101 102 // On Windows, all halfwidth characters sort before fullwidth characters. 103 // On ICU, half and fullwidth characters that aren't in the "Halfwidth and fullwidth forms" block U+FF00-U+FFEF 104 // sort before the corresponding characters that are in the block U+FF00-U+FFEF 105 private static int s_expectedHalfToFullFormsComparison = PlatformDetection.IsWindows ? -1 : 1; 106 107 private static CompareInfo s_invariantCompare = CultureInfo.InvariantCulture.CompareInfo; 108 private static CompareInfo s_turkishCompare = new CultureInfo("tr-TR").CompareInfo; 109 SortKey_TestData()110 public static IEnumerable<object[]> SortKey_TestData() 111 { 112 CompareOptions ignoreKanaIgnoreWidthIgnoreCase = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase; 113 yield return new object[] { s_invariantCompare, "\u3042", "\u30A2", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 114 yield return new object[] { s_invariantCompare, "\u3042", "\uFF71", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 115 116 yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 117 yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 118 yield return new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 119 yield return new object[] { s_invariantCompare, "\u3044", "I", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 120 121 yield return new object[] { s_invariantCompare, "a", "A", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 122 yield return new object[] { s_invariantCompare, "a", "\uFF41", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 123 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 124 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 125 yield return new object[] { s_invariantCompare, "ABCDE", "a\uFF22\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 126 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 127 128 yield return new object[] { s_invariantCompare, "\u6FA4", "\u6CA2", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 129 130 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 131 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 132 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 133 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 134 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 135 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 136 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3079\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 137 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 138 yield return new object[] { s_invariantCompare, "\u3071\u3074\u30D7\u307A", "\uFF8B\uFF9F\uFF8C\uFF9F", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 139 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3070\uFF8E\uFF9E\u30D6", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 140 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C\u3079\u307C", "\u3079\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 141 yield return new object[] { s_invariantCompare, "\u3070\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 142 143 yield return new object[] { s_invariantCompare, "ABDDE", "D", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 144 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF43D", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 145 yield return new object[] { s_invariantCompare, "ABCDE", "c", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 146 yield return new object[] { s_invariantCompare, "\u3060", "\u305F", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 147 yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 148 yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 149 150 yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9\u30B9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 151 yield return new object[] { s_invariantCompare, "\u30C7", "\uFF83\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 152 yield return new object[] { s_invariantCompare, "\u30C7\u30BF", "\uFF83\uFF9E\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 153 yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 154 yield return new object[] { s_invariantCompare, "\u30BF", "\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 155 156 yield return new object[] { s_invariantCompare, "\uFF83\uFF9E\uFF70\uFF80\uFF8D\uFF9E\uFF70\uFF7D", "\u3067\u30FC\u305F\u3079\u30FC\u3059", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 157 yield return new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 158 yield return new object[] { s_invariantCompare, "\u68EE\u9DD7\u5916", "\u68EE\u9DD7\u5916", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 159 yield return new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 160 yield return new object[] { s_invariantCompare, "\u2019", "'", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 161 yield return new object[] { s_invariantCompare, "", "'", ignoreKanaIgnoreWidthIgnoreCase, -1 }; 162 yield return new object[] { s_invariantCompare, "\u4E00", "\uFF11", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 163 yield return new object[] { s_invariantCompare, "\u2160", "\uFF11", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 164 165 yield return new object[] { s_invariantCompare, "0", "\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 166 yield return new object[] { s_invariantCompare, "10", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 167 yield return new object[] { s_invariantCompare, "9999\uFF1910", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 168 yield return new object[] { s_invariantCompare, "9999\uFF191010", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 169 170 yield return new object[] { s_invariantCompare, "'\u3000'", "' '", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 171 yield return new object[] { s_invariantCompare, "\uFF1B", ";", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 172 yield return new object[] { s_invariantCompare, "\uFF08", "(", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 173 yield return new object[] { s_invariantCompare, "\u30FC", "\uFF70", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 174 yield return new object[] { s_invariantCompare, "\u30FC", "\uFF0D", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 175 yield return new object[] { s_invariantCompare, "\u30FC", "\u30FC", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 176 yield return new object[] { s_invariantCompare, "\u30FC", "\u2015", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 177 yield return new object[] { s_invariantCompare, "\u30FC", "\u2010", ignoreKanaIgnoreWidthIgnoreCase, 1 }; 178 179 yield return new object[] { s_invariantCompare, "/", "\uFF0F", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 180 yield return new object[] { s_invariantCompare, "'", "\uFF07", ignoreKanaIgnoreWidthIgnoreCase, PlatformDetection.IsWindows7 ? -1 : 0}; 181 yield return new object[] { s_invariantCompare, "\"", "\uFF02", ignoreKanaIgnoreWidthIgnoreCase, 0 }; 182 183 yield return new object[] { s_invariantCompare, "\u3042", "\u30A1", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 184 yield return new object[] { s_invariantCompare, "\u3042", "\u30A2", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 185 yield return new object[] { s_invariantCompare, "\u3042", "\uFF71", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 186 yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 187 yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 188 189 yield return new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", CompareOptions.None, -1 }; 190 yield return new object[] { s_invariantCompare, "\u3044", "I", CompareOptions.None, 1 }; 191 yield return new object[] { s_invariantCompare, "a", "A", CompareOptions.None, -1 }; 192 yield return new object[] { s_invariantCompare, "a", "\uFF41", CompareOptions.None, -1 }; 193 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", CompareOptions.None, -1 }; 194 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", CompareOptions.None, -1 }; 195 yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5554) + "b", CompareOptions.None, -1 }; 196 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", CompareOptions.None, 1 }; 197 yield return new object[] { s_invariantCompare, "\u6FA4", "\u6CA2", CompareOptions.None, 1 }; 198 199 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 200 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 201 yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 202 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 203 204 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", CompareOptions.None, -1 }; 205 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3079\uFF8E\uFF9E", CompareOptions.None, -1 }; 206 yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", CompareOptions.None, -1 }; 207 yield return new object[] { s_invariantCompare, "\u3071\u3074\u30D7\u307A", "\uFF8B\uFF9F\uFF8C\uFF9F", CompareOptions.None, -1 }; 208 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3070\uFF8E\uFF9E\u30D6", CompareOptions.None, 1 }; 209 yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C\u3079\u307C", "\u3079\uFF8E\uFF9E", CompareOptions.None, -1 }; 210 yield return new object[] { s_invariantCompare, "\u3070\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", CompareOptions.None, -1 }; 211 212 yield return new object[] { s_invariantCompare, "ABDDE", "D", CompareOptions.None, -1 }; 213 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF43D\uFF25", CompareOptions.None, -1 }; 214 yield return new object[] { s_invariantCompare, "ABCDE", "\uFF43D", CompareOptions.None, -1 }; 215 yield return new object[] { s_invariantCompare, "ABCDE", "c", CompareOptions.None, -1 }; 216 yield return new object[] { s_invariantCompare, "\u3060", "\u305F", CompareOptions.None, 1 }; 217 yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 218 yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.None, s_expectedHiraganaToKatakanaCompare }; 219 yield return new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", CompareOptions.None, -1 }; 220 yield return new object[] { s_invariantCompare, "\u68EE\u9DD7\u5916", "\u68EE\u9DD7\u5916", CompareOptions.None, 0 }; 221 222 yield return new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 }; 223 yield return new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 }; 224 yield return new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 }; 225 yield return new object[] { s_invariantCompare, "\u2019", "'", CompareOptions.None, 1 }; 226 yield return new object[] { s_invariantCompare, "", "'", CompareOptions.None, -1 }; 227 228 yield return new object[] { s_invariantCompare, "\u4E00", "\uFF11", CompareOptions.None, 1 }; 229 yield return new object[] { s_invariantCompare, "\u2160", "\uFF11", CompareOptions.None, 1 }; 230 yield return new object[] { s_invariantCompare, "0", "\uFF10", CompareOptions.None, -1 }; 231 yield return new object[] { s_invariantCompare, "10", "1\uFF10", CompareOptions.None, -1 }; 232 yield return new object[] { s_invariantCompare, "1\uFF10", "1\uFF10", CompareOptions.None, 0 }; 233 yield return new object[] { s_invariantCompare, "9999\uFF1910", "1\uFF10", CompareOptions.None, 1 }; 234 yield return new object[] { s_invariantCompare, "9999\uFF191010", "1\uFF10", CompareOptions.None, 1 }; 235 236 yield return new object[] { s_invariantCompare, "'\u3000'", "' '", CompareOptions.None, 1 }; 237 yield return new object[] { s_invariantCompare, "\uFF1B", ";", CompareOptions.None, 1 }; 238 yield return new object[] { s_invariantCompare, "\uFF08", "(", CompareOptions.None, 1 }; 239 yield return new object[] { s_invariantCompare, "\u30FC", "\uFF0D", CompareOptions.None, 1 }; 240 yield return new object[] { s_invariantCompare, "\u30FC", "\u30FC", CompareOptions.None, 0 }; 241 yield return new object[] { s_invariantCompare, "\u30FC", "\u2015", CompareOptions.None, 1 }; 242 yield return new object[] { s_invariantCompare, "\u30FC", "\u2010", CompareOptions.None, 1 }; 243 244 yield return new object[] { s_invariantCompare, "/", "\uFF0F", CompareOptions.None, -1 }; 245 yield return new object[] { s_invariantCompare, "'", "\uFF07", CompareOptions.None, -1 }; 246 yield return new object[] { s_invariantCompare, "\"", "\uFF02", CompareOptions.None, -1 }; 247 248 // Turkish 249 yield return new object[] { s_turkishCompare, "i", "I", CompareOptions.None, 1 }; 250 yield return new object[] { s_turkishCompare, "i", "I", CompareOptions.IgnoreCase, 1 }; 251 yield return new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.None, -1 }; 252 yield return new object[] { s_turkishCompare, "i", "\u0130", CompareOptions.IgnoreCase, 0 }; 253 yield return new object[] { s_invariantCompare, "i", "I", CompareOptions.None, -1 }; 254 yield return new object[] { s_invariantCompare, "i", "I", CompareOptions.IgnoreCase, 0 }; 255 yield return new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.None, -1 }; 256 yield return new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.IgnoreCase, -1 }; 257 258 yield return new object[] { s_invariantCompare, "\u00C0", "A\u0300", CompareOptions.None, 0 }; 259 yield return new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.None, 1 }; 260 yield return new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.IgnoreCase, 0 }; 261 yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, 0 }; 262 263 yield return new object[] { s_invariantCompare, "Test's", "Tests", CompareOptions.IgnoreSymbols, 0 }; 264 yield return new object[] { s_invariantCompare, "Test's", "Tests", CompareOptions.StringSort, -1 }; 265 266 yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5555), CompareOptions.None, 0 }; 267 yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase, 0 }; 268 yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, -1 }; 269 270 yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreNonSpace, 0 }; 271 yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreCase, 0 }; 272 yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreWidth, 0 }; 273 yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreCase, -1 }; 274 yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.None, -1 }; 275 yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreSymbols, 0 }; 276 yield return new object[] { s_invariantCompare, "\u00A2", "\uFFE0", CompareOptions.IgnoreSymbols, 0 }; 277 yield return new object[] { s_invariantCompare, "$", "&", CompareOptions.IgnoreSymbols, 0 }; 278 yield return new object[] { s_invariantCompare, "\uFF65", "\u30FB", CompareOptions.IgnoreSymbols, 0 }; 279 yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreWidth, 0 }; 280 yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.None, -1 }; 281 yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreWidth, 0 }; 282 283 yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreSymbols, s_expectedHalfToFullFormsComparison }; 284 yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreCase, s_expectedHalfToFullFormsComparison }; 285 yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreNonSpace, s_expectedHalfToFullFormsComparison }; 286 yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.None, s_expectedHalfToFullFormsComparison }; 287 288 yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreKanaType, 0 }; 289 yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreCase, s_expectedHiraganaToKatakanaCompare }; 290 yield return new object[] { s_invariantCompare, "c", "C", CompareOptions.IgnoreKanaType, -1 }; 291 292 // Spanish 293 yield return new object[] { new CultureInfo("es-ES").CompareInfo, "llegar", "lugar", CompareOptions.None, -1 }; 294 } 295 IndexOf_TestData()296 public static IEnumerable<object[]> IndexOf_TestData() 297 { 298 yield return new object[] { s_invariantCompare, "foo", "", 0, 0, 0 }; 299 yield return new object[] { s_invariantCompare, "", "", 0, 0, 0 }; 300 yield return new object[] { s_invariantCompare, "Hello", "l", 0, 2, -1 }; 301 yield return new object[] { s_invariantCompare, "Hello", "l", 3, 3, 3 }; 302 yield return new object[] { s_invariantCompare, "Hello", "l", 2, 2, 2 }; 303 yield return new object[] { s_invariantCompare, "Hello", "L", 0, -1, -1 }; 304 yield return new object[] { s_invariantCompare, "Hello", "h", 0, -1, -1 }; 305 } 306 IsSortable_TestData()307 public static IEnumerable<object[]> IsSortable_TestData() 308 { 309 yield return new object[] { "", false, false }; 310 yield return new object[] { "abcdefg", false, true }; 311 yield return new object[] { "\uD800\uDC00", true, true }; 312 yield return new object[] { "\uD800\uD800", true, false }; 313 } 314 315 [Theory] 316 [MemberData(nameof(CompareInfo_TestData))] LcidTest(string cultureName, int lcid)317 public static void LcidTest(string cultureName, int lcid) 318 { 319 var ci = CompareInfo.GetCompareInfo(lcid); 320 Assert.Equal(cultureName, ci.Name); 321 Assert.Equal(lcid, ci.LCID); 322 323 Assembly assembly = typeof(string).Assembly; 324 325 ci = CompareInfo.GetCompareInfo(lcid, assembly); 326 Assert.Equal(cultureName, ci.Name); 327 Assert.Equal(lcid, ci.LCID); 328 329 ci = CompareInfo.GetCompareInfo(cultureName, assembly); 330 Assert.Equal(cultureName, ci.Name); 331 Assert.Equal(lcid, ci.LCID); 332 } 333 334 [Theory] 335 [MemberData(nameof(SortKey_TestData))] SortKeyTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expected)336 public void SortKeyTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expected) 337 { 338 SortKey sk1 = compareInfo.GetSortKey(string1, options); 339 SortKey sk2 = compareInfo.GetSortKey(string2, options); 340 341 Assert.Equal(expected, SortKey.Compare(sk1, sk2)); 342 Assert.Equal(string1, sk1.OriginalString); 343 Assert.Equal(string2, sk2.OriginalString); 344 } 345 346 [Fact] SortKeyMiscTest()347 public void SortKeyMiscTest() 348 { 349 CompareInfo ci = new CultureInfo("en-US").CompareInfo; 350 string s1 = "abc"; 351 string s2 = "ABC"; 352 353 SortKey sk1 = ci.GetSortKey(s1); 354 SortKey sk2 = ci.GetSortKey(s1); 355 356 SortKey sk3 = ci.GetSortKey(s2); 357 SortKey sk4 = ci.GetSortKey(s2, CompareOptions.IgnoreCase); 358 SortKey sk5 = ci.GetSortKey(s1, CompareOptions.IgnoreCase); 359 360 Assert.Equal(sk2, sk1); 361 Assert.Equal(sk2.GetHashCode(), sk1.GetHashCode()); 362 Assert.Equal(sk2.KeyData, sk1.KeyData); 363 364 Assert.NotEqual(sk3, sk1); 365 Assert.NotEqual(sk3.GetHashCode(), sk1.GetHashCode()); 366 Assert.NotEqual(sk3.KeyData, sk1.KeyData); 367 368 Assert.NotEqual(sk4, sk3); 369 Assert.NotEqual(sk4.GetHashCode(), sk3.GetHashCode()); 370 Assert.NotEqual(sk4.KeyData, sk3.KeyData); 371 372 Assert.Equal(sk4, sk5); 373 Assert.Equal(sk4.GetHashCode(), sk5.GetHashCode()); 374 Assert.Equal(sk4.KeyData, sk5.KeyData); 375 376 AssertExtensions.Throws<ArgumentNullException>("source", () => ci.GetSortKey(null)); 377 AssertExtensions.Throws<ArgumentException>("options", () => ci.GetSortKey(s1, CompareOptions.Ordinal)); 378 } 379 380 [Theory] 381 [MemberData(nameof(IndexOf_TestData))] IndexOfTest(CompareInfo compareInfo, string source, string value, int startIndex, int indexOfExpected, int lastIndexOfExpected)382 public void IndexOfTest(CompareInfo compareInfo, string source, string value, int startIndex, int indexOfExpected, int lastIndexOfExpected) 383 { 384 Assert.Equal(indexOfExpected, compareInfo.IndexOf(source, value, startIndex)); 385 if (value.Length > 0) 386 { 387 Assert.Equal(indexOfExpected, compareInfo.IndexOf(source, value[0], startIndex)); 388 } 389 390 Assert.Equal(lastIndexOfExpected, compareInfo.LastIndexOf(source, value, startIndex)); 391 if (value.Length > 0) 392 { 393 Assert.Equal(lastIndexOfExpected, compareInfo.LastIndexOf(source, value[0], startIndex)); 394 } 395 } 396 397 [Theory] 398 [MemberData(nameof(IsSortable_TestData))] IsSortableTest(string source, bool hasSurrogate, bool expected)399 public void IsSortableTest(string source, bool hasSurrogate, bool expected) 400 { 401 Assert.Equal(expected, CompareInfo.IsSortable(source)); 402 403 bool charExpectedResults = hasSurrogate ? false : expected; 404 foreach (char c in source) 405 Assert.Equal(charExpectedResults, CompareInfo.IsSortable(c)); 406 } 407 408 [Fact] VersionTest()409 public void VersionTest() 410 { 411 SortVersion sv1 = CultureInfo.GetCultureInfo("en-US").CompareInfo.Version; 412 SortVersion sv2 = CultureInfo.GetCultureInfo("ja-JP").CompareInfo.Version; 413 SortVersion sv3 = CultureInfo.GetCultureInfo("en").CompareInfo.Version; 414 415 Assert.Equal(sv1.FullVersion, sv3.FullVersion); 416 Assert.NotEqual(sv1.SortId, sv2.SortId); 417 } 418 } 419 } 420