|
| 1 | +'use strict'; |
| 2 | +constcommon=require('../common'); |
| 3 | +constassert=require('assert'); |
| 4 | +const{ execFileSync }=require('child_process'); |
| 5 | + |
| 6 | +// system-icu should not be tested |
| 7 | +consthasBuiltinICU=process.config.variables.icu_gyp_path==='tools/icu/icu-generic.gyp'; |
| 8 | +if(!hasBuiltinICU) |
| 9 | +common.skip('system ICU'); |
| 10 | + |
| 11 | +// small-icu doesn't support non-English locales |
| 12 | +consthasFullICU=(()=>{ |
| 13 | +try{ |
| 14 | +constjanuary=newDate(9e8); |
| 15 | +constspanish=newIntl.DateTimeFormat('es',{month: 'long'}); |
| 16 | +returnspanish.format(january)==='enero'; |
| 17 | +}catch{ |
| 18 | +returnfalse; |
| 19 | +} |
| 20 | +})(); |
| 21 | +if(!hasFullICU) |
| 22 | +common.skip('small ICU'); |
| 23 | + |
| 24 | +consticuVersionMajor=Number(process.config.variables.icu_ver_major??0); |
| 25 | +if(icuVersionMajor<71) |
| 26 | +common.skip('ICU too old'); |
| 27 | + |
| 28 | + |
| 29 | +functionrunEnvOutside(addEnv,code, ...args){ |
| 30 | +returnexecFileSync( |
| 31 | +process.execPath, |
| 32 | +['-e',`process.stdout.write(String(${code}));`], |
| 33 | +{env: { ...process.env, ...addEnv},encoding: 'utf8'} |
| 34 | +); |
| 35 | +} |
| 36 | + |
| 37 | +functionrunEnvInside(addEnv,func, ...args){ |
| 38 | +Object.assign(process.env,addEnv);// side effects! |
| 39 | +returnfunc(...args); |
| 40 | +} |
| 41 | + |
| 42 | +functionisPack(array){ |
| 43 | +constfirstItem=array[0]; |
| 44 | +returnarray.every((item)=>item===firstItem); |
| 45 | +} |
| 46 | + |
| 47 | +functionisSet(array){ |
| 48 | +constdeduped=newSet(array); |
| 49 | +returnarray.length===deduped.size; |
| 50 | +} |
| 51 | + |
| 52 | + |
| 53 | +constlocalesISO639=[ |
| 54 | +'eng','cmn','hin','spa', |
| 55 | +'fra','arb','ben','rus', |
| 56 | +'por','urd','ind','deu', |
| 57 | +'jpn','pcm','mar','tel', |
| 58 | +]; |
| 59 | + |
| 60 | +constlocales=[ |
| 61 | +'en','zh','hi','es', |
| 62 | +'fr','ar','bn','ru', |
| 63 | +'pt','ur','id','de', |
| 64 | +'ja','pcm','mr','te', |
| 65 | +]; |
| 66 | + |
| 67 | +// These must not overlap |
| 68 | +constzones=[ |
| 69 | +'America/New_York', |
| 70 | +'UTC', |
| 71 | +'Asia/Irkutsk', |
| 72 | +'Australia/North', |
| 73 | +'Antarctica/South_Pole', |
| 74 | +]; |
| 75 | + |
| 76 | + |
| 77 | +assert.deepStrictEqual(Intl.getCanonicalLocales(localesISO639),locales); |
| 78 | + |
| 79 | + |
| 80 | +// On some platforms these keep original locale (for example, 'January') |
| 81 | +constenero=runEnvOutside( |
| 82 | +{LANG: 'es'}, |
| 83 | +'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' |
| 84 | +); |
| 85 | +constjanvier=runEnvOutside( |
| 86 | +{LANG: 'fr'}, |
| 87 | +'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' |
| 88 | +); |
| 89 | +constisMockable=enero!==janvier; |
| 90 | + |
| 91 | +// Tests with mocked env |
| 92 | +if(isMockable){ |
| 93 | +assert.strictEqual( |
| 94 | +isSet(zones.map((TZ)=>runEnvOutside({TZ},'new Date(333333333333).toString()'))), |
| 95 | +true |
| 96 | +); |
| 97 | +assert.strictEqual( |
| 98 | +isSet(zones.map((TZ)=>runEnvOutside({TZ},'new Date(333333333333).toLocaleString()'))), |
| 99 | +true |
| 100 | +); |
| 101 | +assert.deepStrictEqual( |
| 102 | +locales.map((LANG)=>runEnvOutside({LANG,TZ: 'Europe/Zurich'},'new Date(333333333333).toString()')), |
| 103 | +[ |
| 104 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Central European Standard Time)', |
| 105 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (中欧标准时间)', |
| 106 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्य यूरोपीय मानक समय)', |
| 107 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (hora estándar de Europa central)', |
| 108 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (heure normale d’Europe centrale)', |
| 109 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (توقيت وسط أوروبا الرسمي)', |
| 110 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (মধ্য ইউরোপীয় মানক সময়)', |
| 111 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Центральная Европа, стандартное время)', |
| 112 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Horário Padrão da Europa Central)', |
| 113 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (وسطی یورپ کا معیاری وقت)', |
| 114 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Waktu Standar Eropa Tengah)', |
| 115 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Mitteleuropäische Normalzeit)', |
| 116 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (中央ヨーロッパ標準時)', |
| 117 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (Mídúl Yúrop Fíksd Taim)', |
| 118 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्य युरोपियन प्रमाण वेळ)', |
| 119 | +'Fri Jul 25 1980 01:35:33 GMT+0100 (సెంట్రల్ యూరోపియన్ ప్రామాణిక సమయం)', |
| 120 | +] |
| 121 | +); |
| 122 | +assert.deepStrictEqual( |
| 123 | +locales.map((LANG)=>runEnvOutside({LANG,TZ: 'Europe/Zurich'},'new Date(333333333333).toLocaleString()')), |
| 124 | +[ |
| 125 | +'7/25/1980, 1:35:33 AM', |
| 126 | +'1980/7/25 01:35:33', |
| 127 | +'25/7/1980, 1:35:33 am', |
| 128 | +'25/7/1980, 1:35:33', |
| 129 | +'25/07/1980 01:35:33', |
| 130 | +'٢٥/٧/١٩٨٠, ١:٣٥:٣٣ ص', |
| 131 | +'২৫/৭/১৯৮০ ১:৩৫:৩৩ AM', |
| 132 | +'25.07.1980, 01:35:33', |
| 133 | +'25/07/1980 01:35:33', |
| 134 | +'25/7/1980 1:35:33 AM', |
| 135 | +'25/7/1980 01.35.33', |
| 136 | +'25.7.1980, 01:35:33', |
| 137 | +'1980/7/25 1:35:33', |
| 138 | +'25/7/1980 01:35:33', |
| 139 | +'२५/७/१९८०, १:३५:३३ AM', |
| 140 | +'25/7/1980 1:35:33 AM', |
| 141 | +] |
| 142 | +); |
| 143 | +assert.strictEqual( |
| 144 | +runEnvOutside({LANG: 'en'},'["z", "ä"].sort(new Intl.Collator().compare)'), |
| 145 | +'ä,z' |
| 146 | +); |
| 147 | +assert.strictEqual( |
| 148 | +runEnvOutside({LANG: 'sv'},'["z", "ä"].sort(new Intl.Collator().compare)'), |
| 149 | +'z,ä' |
| 150 | +); |
| 151 | +assert.deepStrictEqual( |
| 152 | +locales.map( |
| 153 | +(LANG)=>runEnvOutside({LANG,TZ: 'Europe/Zurich'},'new Intl.DateTimeFormat().format(333333333333)') |
| 154 | +), |
| 155 | +[ |
| 156 | +'7/25/1980','1980/7/25', |
| 157 | +'25/7/1980','25/7/1980', |
| 158 | +'25/07/1980','٢٥/٧/١٩٨٠', |
| 159 | +'২৫/৭/১৯৮০','25.07.1980', |
| 160 | +'25/07/1980','25/7/1980', |
| 161 | +'25/7/1980','25.7.1980', |
| 162 | +'1980/7/25','25/7/1980', |
| 163 | +'२५/७/१९८०','25/7/1980', |
| 164 | +] |
| 165 | +); |
| 166 | +assert.deepStrictEqual( |
| 167 | +locales.map((LANG)=>runEnvOutside({LANG},'new Intl.DisplayNames(undefined, { type: "region" }).of("CH")')), |
| 168 | +[ |
| 169 | +'Switzerland','瑞士', |
| 170 | +'स्विट्ज़रलैंड','Suiza', |
| 171 | +'Suisse','سويسرا', |
| 172 | +'সুইজারল্যান্ড','Швейцария', |
| 173 | +'Suíça','سوئٹزر لینڈ', |
| 174 | +'Swiss','Schweiz', |
| 175 | +'スイス','Swítsaland', |
| 176 | +'स्वित्झर्लंड','స్విట్జర్లాండ్', |
| 177 | +] |
| 178 | +); |
| 179 | +assert.deepStrictEqual( |
| 180 | +locales.map((LANG)=>runEnvOutside({LANG},'new Intl.NumberFormat().format(275760.913)')), |
| 181 | +[ |
| 182 | +'275,760.913','275,760.913', |
| 183 | +'2,75,760.913','275.760,913', |
| 184 | +'275 760,913','٢٧٥٬٧٦٠٫٩١٣', |
| 185 | +'২,৭৫,৭৬০.৯১৩','275 760,913', |
| 186 | +'275.760,913','275,760.913', |
| 187 | +'275.760,913','275.760,913', |
| 188 | +'275,760.913','275,760.913', |
| 189 | +'२,७५,७६०.९१३','2,75,760.913', |
| 190 | +] |
| 191 | +); |
| 192 | +assert.deepStrictEqual( |
| 193 | +locales.map((LANG)=>runEnvOutside({LANG},'new Intl.PluralRules().select(0)')), |
| 194 | +[ |
| 195 | +'other','other','one','other', |
| 196 | +'one','zero','one','many', |
| 197 | +'one','other','other','other', |
| 198 | +'other','one','other','other', |
| 199 | +] |
| 200 | +); |
| 201 | +assert.deepStrictEqual( |
| 202 | +locales.map((LANG)=>runEnvOutside({LANG},'new Intl.RelativeTimeFormat().format(-586920.617, "hour")')), |
| 203 | +[ |
| 204 | +'586,920.617 hours ago', |
| 205 | +'586,920.617小时前', |
| 206 | +'5,86,920.617 घंटे पहले', |
| 207 | +'hace 586.920,617 horas', |
| 208 | +'il y a 586 920,617 heures', |
| 209 | +'قبل ٥٨٦٬٩٢٠٫٦١٧ ساعة', |
| 210 | +'৫,৮৬,৯২০.৬১৭ ঘন্টা আগে', |
| 211 | +'586 920,617 часа назад', |
| 212 | +'há 586.920,617 horas', |
| 213 | +'586,920.617 گھنٹے پہلے', |
| 214 | +'586.920,617 jam yang lalu', |
| 215 | +'vor 586.920,617 Stunden', |
| 216 | +'586,920.617 時間前', |
| 217 | +'586,920.617 áwa wé dọ́n pas', |
| 218 | +'५,८६,९२०.६१७ तासांपूर्वी', |
| 219 | +'5,86,920.617 గంటల క్రితం', |
| 220 | +] |
| 221 | +); |
| 222 | +} |
| 223 | + |
| 224 | + |
| 225 | +// Tests with process.env mutated inside |
| 226 | +{ |
| 227 | +// process.env.TZ is not intercepted in Workers |
| 228 | +if(common.isMainThread){ |
| 229 | +assert.strictEqual( |
| 230 | +isSet(zones.map((TZ)=>runEnvInside({TZ},()=>newDate(333333333333).toString()))), |
| 231 | +true |
| 232 | +); |
| 233 | +assert.strictEqual( |
| 234 | +isSet(zones.map((TZ)=>runEnvInside({TZ},()=>newDate(333333333333).toLocaleString()))), |
| 235 | +true |
| 236 | +); |
| 237 | +}else{ |
| 238 | +assert.strictEqual( |
| 239 | +isPack(zones.map((TZ)=>runEnvInside({TZ},()=>newDate(333333333333).toString()))), |
| 240 | +true |
| 241 | +); |
| 242 | +assert.strictEqual( |
| 243 | +isPack(zones.map((TZ)=>runEnvInside({TZ},()=>newDate(333333333333).toLocaleString()))), |
| 244 | +true |
| 245 | +); |
| 246 | +} |
| 247 | + |
| 248 | +assert.strictEqual( |
| 249 | +isPack(locales.map((LANG)=>runEnvInside({LANG,TZ: 'Europe/Zurich'},()=>newDate(333333333333).toString()))), |
| 250 | +true |
| 251 | +); |
| 252 | +assert.strictEqual( |
| 253 | +isPack(locales.map( |
| 254 | +(LANG)=>runEnvInside({LANG,TZ: 'Europe/Zurich'},()=>newDate(333333333333).toLocaleString()) |
| 255 | +)), |
| 256 | +true |
| 257 | +); |
| 258 | +assert.deepStrictEqual( |
| 259 | +runEnvInside({LANG: 'en'},()=>['z','ä'].sort(newIntl.Collator().compare)), |
| 260 | +runEnvInside({LANG: 'sv'},()=>['z','ä'].sort(newIntl.Collator().compare)) |
| 261 | +); |
| 262 | +assert.strictEqual( |
| 263 | +isPack(locales.map( |
| 264 | +(LANG)=>runEnvInside({LANG,TZ: 'Europe/Zurich'},()=>newIntl.DateTimeFormat().format(333333333333)) |
| 265 | +)), |
| 266 | +true |
| 267 | +); |
| 268 | +assert.strictEqual( |
| 269 | +isPack(locales.map( |
| 270 | +(LANG)=>runEnvInside({LANG},()=>newIntl.DisplayNames(undefined,{type: 'region'}).of('CH')) |
| 271 | +)), |
| 272 | +true |
| 273 | +); |
| 274 | +assert.strictEqual( |
| 275 | +isPack(locales.map((LANG)=>runEnvInside({LANG},()=>newIntl.NumberFormat().format(275760.913)))), |
| 276 | +true |
| 277 | +); |
| 278 | +assert.strictEqual( |
| 279 | +isPack(locales.map((LANG)=>runEnvInside({LANG},()=>newIntl.PluralRules().select(0)))), |
| 280 | +true |
| 281 | +); |
| 282 | +assert.strictEqual( |
| 283 | +isPack(locales.map( |
| 284 | +(LANG)=>runEnvInside({LANG},()=>newIntl.RelativeTimeFormat().format(-586920.617,'hour')) |
| 285 | +)), |
| 286 | +true |
| 287 | +); |
| 288 | +} |
0 commit comments