test_localeService_negotiateLanguages.js (6161B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const localeService = Services.locale; 6 7 const data = { 8 filtering: { 9 "exact match": [ 10 [["en"], ["en"], ["en"]], 11 [["en-US"], ["en-US"], ["en-US"]], 12 [["en-Latn-US"], ["en-Latn-US"], ["en-Latn-US"]], 13 [["en-Latn-US-windows"], ["en-Latn-US-windows"], ["en-Latn-US-windows"]], 14 [["fr-FR"], ["de", "it", "fr-FR"], ["fr-FR"]], 15 [ 16 ["fr", "pl", "de-DE"], 17 ["pl", "en-US", "de-DE"], 18 ["pl", "de-DE"], 19 ], 20 ], 21 "available as range": [ 22 [["en-US"], ["en"], ["en"]], 23 [["en-Latn-US"], ["en-US"], ["en-US"]], 24 [["en-US-windows"], ["en-US"], ["en-US"]], 25 [ 26 ["fr-CA", "de-DE"], 27 ["fr", "it", "de"], 28 ["fr", "de"], 29 ], 30 [["ja-JP-windows"], ["ja"], ["ja"]], 31 [ 32 ["en-Latn-GB", "en-Latn-IN"], 33 ["en-IN", "en-GB"], 34 ["en-GB", "en-IN"], 35 ], 36 ], 37 "should match on likely subtag": [ 38 [["en"], ["en-GB", "de", "en-US"], ["en-US", "en-GB"]], 39 [ 40 ["en"], 41 ["en-Latn-GB", "de", "en-Latn-US"], 42 ["en-Latn-US", "en-Latn-GB"], 43 ], 44 [["fr"], ["fr-CA", "fr-FR"], ["fr-FR", "fr-CA"]], 45 [["az-IR"], ["az-Latn", "az-Arab"], ["az-Arab"]], 46 [["sr-RU"], ["sr-Cyrl", "sr-Latn"], ["sr-Latn"]], 47 [["sr"], ["sr-Latn", "sr-Cyrl"], ["sr-Cyrl"]], 48 [["zh-GB"], ["zh-Hans", "zh-Hant"], ["zh-Hant"]], 49 [["sr", "ru"], ["sr-Latn", "ru"], ["ru"]], 50 [["sr-RU"], ["sr-Latn-RO", "sr-Cyrl"], ["sr-Latn-RO"]], 51 ], 52 "should match likelySubtag region over other regions": [ 53 [["en-CA"], ["en-ZA", "en-GB", "en-US"], ["en-US", "en-ZA", "en-GB"]], 54 ], 55 "should match cross-region": [ 56 [["en"], ["en-US"], ["en-US"]], 57 [["en-US"], ["en-GB"], ["en-GB"]], 58 [["en-Latn-US"], ["en-Latn-GB"], ["en-Latn-GB"]], 59 ], 60 "should match cross-variant": [ 61 [["en-US-linux"], ["en-US-windows"], ["en-US-windows"]], 62 ], 63 "should prioritize properly": [ 64 // exact match first 65 [ 66 ["en-US"], 67 ["en-US-windows", "en", "en-US"], 68 ["en-US", "en", "en-US-windows"], 69 ], 70 // available as range second 71 [["en-Latn-US"], ["en-GB", "en-US"], ["en-US", "en-GB"]], 72 // likely subtags third 73 [["en"], ["en-Cyrl-US", "en-Latn-US"], ["en-Latn-US"]], 74 // variant range fourth 75 [ 76 ["en-US-macos"], 77 ["en-US-windows", "en-GB-macos"], 78 ["en-US-windows", "en-GB-macos"], 79 ], 80 // regional range fifth 81 [["en-US-macos"], ["en-GB-windows"], ["en-GB-windows"]], 82 [["en-US"], ["en-GB", "en"], ["en", "en-GB"]], 83 [ 84 ["fr-CA-macos", "de-DE"], 85 ["de-DE", "fr-FR-windows"], 86 ["fr-FR-windows", "de-DE"], 87 ], 88 ], 89 "should handle default locale properly": [ 90 [["fr"], ["de", "it"], []], 91 [["fr"], ["de", "it"], "en-US", ["en-US"]], 92 [["fr"], ["de", "en-US"], "en-US", ["en-US"]], 93 [ 94 ["fr", "de-DE"], 95 ["de-DE", "fr-CA"], 96 "en-US", 97 ["fr-CA", "de-DE", "en-US"], 98 ], 99 ], 100 "should handle all matches on the 1st higher than any on the 2nd": [ 101 [ 102 ["fr-CA-macos", "de-DE"], 103 ["de-DE", "fr-FR-windows"], 104 ["fr-FR-windows", "de-DE"], 105 ], 106 ], 107 "should handle cases and underscores, returning the form given in the 'available' list": 108 [ 109 [["fr_FR"], ["fr-FR"], ["fr-FR"]], 110 [["fr_fr"], ["fr-FR"], ["fr-FR"]], 111 [["fr_Fr"], ["fr-fR"], ["fr-fR"]], 112 [["fr_lAtN_fr"], ["fr-Latn-FR"], ["fr-Latn-FR"]], 113 [["fr_FR"], ["fr_FR"], ["fr_FR"]], 114 [["fr-FR"], ["fr_FR"], ["fr_FR"]], 115 [["fr_Cyrl_FR_macos"], ["fr_Cyrl_fr-macos"], ["fr_Cyrl_fr-macos"]], 116 ], 117 "should handle mozilla specific 3-letter variants": [ 118 [ 119 ["ja-JP-mac", "de-DE"], 120 ["ja-JP-mac", "de-DE"], 121 ["ja-JP-mac", "de-DE"], 122 ], 123 ], 124 "should not crash on invalid input": [ 125 [["fą-FŻ"], ["ór_Fń"], []], 126 [["2"], ["ąóżł"], []], 127 [[[""]], ["fr-FR"], []], 128 ], 129 "should not match on invalid input": [[["en"], ["ťŮ"], []]], 130 }, 131 matching: { 132 "should match only one per requested": [ 133 [ 134 ["fr", "en"], 135 ["en-US", "fr-FR", "en", "fr"], 136 null, 137 localeService.langNegStrategyMatching, 138 ["fr", "en"], 139 ], 140 ], 141 }, 142 lookup: { 143 "should match only one": [ 144 [ 145 ["fr-FR", "en"], 146 ["en-US", "fr-FR", "en", "fr"], 147 "en-US", 148 localeService.langNegStrategyLookup, 149 ["fr-FR"], 150 ], 151 ], 152 }, 153 }; 154 155 function run_test() { 156 const nl = localeService.negotiateLanguages; 157 158 const json = JSON.stringify; 159 for (const strategy in data) { 160 for (const groupName in data[strategy]) { 161 const group = data[strategy][groupName]; 162 for (const test of group) { 163 const requested = test[0]; 164 const available = test[1]; 165 const defaultLocale = test.length > 3 ? test[2] : undefined; 166 const strategyInner = test.length > 4 ? test[3] : undefined; 167 const supported = test[test.length - 1]; 168 169 const result = nl(test[0], test[1], defaultLocale, strategyInner); 170 deepEqual( 171 result, 172 supported, 173 `\nExpected ${json(requested)} * ${json(available)} = ${json( 174 supported 175 )}.\n` 176 ); 177 } 178 } 179 } 180 181 // Verify that we error out when requested or available is not an array. 182 for (const [req, avail] in [ 183 [null, ["fr-FR"]], 184 [undefined, ["fr-FR"]], 185 [2, ["fr-FR"]], 186 ["fr-FR", ["fr-FR"]], 187 [["fr-FR"], null], 188 [["fr-FR"], undefined], 189 [["fr-FR"], 2], 190 [["fr-FR"], "fr-FR"], 191 [[null], []], 192 [[undefined], []], 193 [[undefined], [null]], 194 [[undefined], [undefined]], 195 [[null], [null]], 196 [[[]], [[2]]], 197 ]) { 198 Assert.throws( 199 () => { 200 nl(req, avail); 201 }, 202 err => err.result == Cr.NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY 203 ); 204 } 205 }