1/** 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License") 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const fakeLocale = "er-or" 17 18function main() throws { 19 testSelect() 20 testResolvedOptions() 21 testSelectWithOptions() 22 testSupportedLocalesOf() 23} 24 25function runSelectTest(locale: string, value: number, expected: string, options?: Intl.PluralRulesOptions) { 26 const rules = new Intl.PluralRules(locale, options) 27 const result = rules.select(value) 28 assertEQ(result, expected) 29} 30 31function testSelect() { 32 runSelectTest("en", 1, "one") 33 runSelectTest("en", 2, "other") 34 runSelectTest("en", 0, "other") 35 36 runSelectTest("ru", 1, "one") 37 runSelectTest("ru", 2, "few") 38 runSelectTest("ru", 5, "many") 39 runSelectTest("ru", 21, "one") 40 runSelectTest("ru", 102, "few") 41 runSelectTest("ru", 1005, "many") 42 43 runSelectTest("fr", 1, "one") 44 runSelectTest("fr", 2, "other") 45 runSelectTest("fr", 0, "one") 46 47 runSelectTest("zh", 1, "other") 48 runSelectTest("zh", 100, "other") 49 runSelectTest("zh", 0, "other") 50 51 runSelectTest("ja", 1, "other") 52 runSelectTest("ja", 5, "other") 53 54 runSelectTest(fakeLocale, 1, "one") 55 runSelectTest(fakeLocale, 2, "other") 56} 57 58function testResolvedOptions() { 59 { 60 const rules = new Intl.PluralRules("en") 61 const result = rules.resolvedOptions() 62 assertEQ(result.minimumIntegerDigits, 1) 63 assertEQ(result.minimumFractionDigits, 0) 64 assertEQ(result.maximumFractionDigits, 3) 65 assertEQ(result.minimumSignificantDigits, undefined) 66 assertEQ(result.maximumSignificantDigits, undefined) 67 assertEQ(result.type, "cardinal") 68 } 69 { 70 const rules = new Intl.PluralRules("en", { type: "ordinal" } as Intl.PluralRulesOptions) 71 const result = rules.resolvedOptions() 72 assertEQ(result.type, "ordinal") 73 } 74 { 75 const rules = new Intl.PluralRules("en", { minimumFractionDigits: 2 } as Intl.PluralRulesOptions) 76 const result = rules.resolvedOptions() 77 assertEQ(result.minimumFractionDigits, 2) 78 } 79 { 80 const rules = new Intl.PluralRules("en", { maximumFractionDigits: 4 } as Intl.PluralRulesOptions) 81 const result = rules.resolvedOptions() 82 assertEQ(result.maximumFractionDigits, 4) 83 } 84 { 85 const rules = new Intl.PluralRules("en", { minimumSignificantDigits: 3 } as Intl.PluralRulesOptions) 86 const result = rules.resolvedOptions() 87 assertEQ(result.minimumSignificantDigits, 3) 88 } 89} 90 91function runTestWithOptions(locale: string, value: number, options: Intl.PluralRulesOptions, expected: string) { 92 const rules = new Intl.PluralRules(locale, options) 93 const result = rules.select(value) 94 assertEQ(result, expected) 95} 96 97function testSelectWithOptions() { 98 runTestWithOptions("en", 1, { type: "cardinal" }, "one") 99 runTestWithOptions("en", 2, { type: "cardinal" }, "other") 100 runTestWithOptions("en", 1, { type: "ordinal" }, "one") 101 runTestWithOptions("en", 2, { type: "ordinal" }, "two") 102 runTestWithOptions("en", 3, { type: "ordinal" }, "few") 103 runTestWithOptions("en", 4, { type: "ordinal" }, "other") 104 105 runTestWithOptions("fr", 1, { localeMatcher: "lookup" }, "one") 106 runTestWithOptions("fr", 1, { localeMatcher: "best fit" }, "one") 107 108 runTestWithOptions("fr", 0, { minimumFractionDigits: 2 }, "one") 109 runTestWithOptions("fr", 0.5, { maximumFractionDigits: 1 }, "one") 110 runTestWithOptions("fr", 1.5, { minimumFractionDigits: 2, maximumFractionDigits: 2 }, "one") 111 runTestWithOptions("en", 1.99, { minimumFractionDigits: 1, maximumFractionDigits: 2 }, "other") 112 runTestWithOptions("en", 2.5, { minimumFractionDigits: 1 }, "other") 113 114 runTestWithOptions("de", 1, { minimumIntegerDigits: 2 }, "one") 115 runTestWithOptions("de", 9, { minimumIntegerDigits: 3 }, "other") 116 117 runTestWithOptions("ru", 1, { minimumSignificantDigits: 2 }, "other") 118 runTestWithOptions("ru", 12, { minimumSignificantDigits: 2, maximumSignificantDigits: 3 }, "many") 119 runTestWithOptions("ru", 1234, { minimumSignificantDigits: 3, maximumSignificantDigits: 5 }, "few") 120 runTestWithOptions("ru", 0.0005, { minimumSignificantDigits: 1, maximumSignificantDigits: 2 }, "other") 121 122 runTestWithOptions("ja", 0, {}, "other") 123 runTestWithOptions("zh", 2, {}, "other") 124 runTestWithOptions("ar", 0, {}, "zero") 125 runTestWithOptions("ar", 1, {}, "one") 126 runTestWithOptions("ar", 2, {}, "two") 127 runTestWithOptions("ar", 3, {}, "few") 128 runTestWithOptions("ar", 11, {}, "many") 129 runTestWithOptions("ar", 100, {}, "other") 130 131 runTestWithOptions( 132 "fr", 133 1234.567, 134 { 135 localeMatcher: "best fit", 136 type: "cardinal", 137 minimumIntegerDigits: 3, 138 minimumFractionDigits: 2, 139 maximumFractionDigits: 4, 140 minimumSignificantDigits: 3, 141 maximumSignificantDigits: 5 142 }, 143 "other" 144 ) 145 runTestWithOptions( 146 "fr", 147 1.0, 148 { 149 localeMatcher: "lookup", 150 type: "cardinal", 151 minimumIntegerDigits: 1, 152 minimumFractionDigits: 0, 153 maximumFractionDigits: 2, 154 minimumSignificantDigits: 1, 155 maximumSignificantDigits: 3 156 }, 157 "one" 158 ) 159 runTestWithOptions( 160 "ar", 161 2, 162 { 163 localeMatcher: "best fit", 164 type: "cardinal", 165 minimumIntegerDigits: 1, 166 minimumFractionDigits: 0, 167 maximumFractionDigits: 3, 168 minimumSignificantDigits: 1, 169 maximumSignificantDigits: 5 170 }, 171 "two" 172 ) 173 runTestWithOptions( 174 "en", 175 3, 176 { 177 localeMatcher: "lookup", 178 type: "ordinal", 179 minimumIntegerDigits: 1, 180 minimumFractionDigits: 0, 181 maximumFractionDigits: 2, 182 minimumSignificantDigits: 1, 183 maximumSignificantDigits: 3 184 }, 185 "few" 186 ) 187} 188 189function runSupportedLocalesTest( 190 locales: string | FixedArray<string>, 191 options: Intl.SupportedLocalesOfOptions | undefined, 192 expected: string[]) 193{ 194 const result = Intl.PluralRules.supportedLocalesOf(locales, options) 195 assertEQ(result.length, expected.length) 196 for (let i = 0; i < result.length; i++) { 197 assertEQ(result[i], expected[i]) 198 } 199} 200 201function testSupportedLocalesOf() { 202 runSupportedLocalesTest( 203 "en", 204 undefined, 205 intlBestFitLocales("en") 206 ) 207 runSupportedLocalesTest( 208 fakeLocale, 209 undefined, 210 intlBestFitLocales(fakeLocale) 211 ) 212 runSupportedLocalesTest( 213 ["fr", fakeLocale, "ru"], 214 undefined, 215 intlBestFitLocales(["fr", fakeLocale, "ru"]) 216 ) 217 runSupportedLocalesTest( 218 ["ru-RU", "zh-CN", "en-US"], 219 undefined, 220 intlBestFitLocales(["ru-RU", "zh-CN", "en-US"]) 221 ) 222 runSupportedLocalesTest( 223 ["ru-RU", "zh-CN", "en-US"], 224 { localeMatcher: "best fit" } as Intl.SupportedLocalesOfOptions, 225 intlBestFitLocales(["ru-RU", "zh-CN", "en-US"]) 226 ) 227 228 runSupportedLocalesTest( 229 "en", 230 { localeMatcher: "lookup" } as Intl.SupportedLocalesOfOptions, 231 intlLookUpLocales("en") 232 ) 233 runSupportedLocalesTest( 234 fakeLocale, 235 { localeMatcher: "lookup" } as Intl.SupportedLocalesOfOptions, 236 intlLookUpLocales(fakeLocale) 237 ) 238 239 runSupportedLocalesTest( 240 ["ru-RU", "zh-CN", fakeLocale, "en-US"], 241 { localeMatcher: "lookup" } as Intl.SupportedLocalesOfOptions, 242 intlLookUpLocales(["ru-RU", "zh-CN", fakeLocale, "en-US"]) 243 ) 244} 245