11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst assert = require('assert'); 41cb0ef41Sopenharmony_ciconst { execFileSync } = require('child_process'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci// system-icu should not be tested 71cb0ef41Sopenharmony_ciconst hasBuiltinICU = process.config.variables.icu_gyp_path === 'tools/icu/icu-generic.gyp'; 81cb0ef41Sopenharmony_ciif (!hasBuiltinICU) 91cb0ef41Sopenharmony_ci common.skip('system ICU'); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci// small-icu doesn't support non-English locales 121cb0ef41Sopenharmony_ciconst hasFullICU = (() => { 131cb0ef41Sopenharmony_ci try { 141cb0ef41Sopenharmony_ci const january = new Date(9e8); 151cb0ef41Sopenharmony_ci const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); 161cb0ef41Sopenharmony_ci return spanish.format(january) === 'enero'; 171cb0ef41Sopenharmony_ci } catch { 181cb0ef41Sopenharmony_ci return false; 191cb0ef41Sopenharmony_ci } 201cb0ef41Sopenharmony_ci})(); 211cb0ef41Sopenharmony_ciif (!hasFullICU) 221cb0ef41Sopenharmony_ci common.skip('small ICU'); 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciconst icuVersionMajor = Number(process.config.variables.icu_ver_major ?? 0); 251cb0ef41Sopenharmony_ciif (icuVersionMajor < 71) 261cb0ef41Sopenharmony_ci common.skip('ICU too old'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cifunction runEnvOutside(addEnv, code, ...args) { 301cb0ef41Sopenharmony_ci return execFileSync( 311cb0ef41Sopenharmony_ci process.execPath, 321cb0ef41Sopenharmony_ci ['-e', `process.stdout.write(String(${code}));`], 331cb0ef41Sopenharmony_ci { env: { ...process.env, ...addEnv }, encoding: 'utf8' } 341cb0ef41Sopenharmony_ci ); 351cb0ef41Sopenharmony_ci} 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_cifunction runEnvInside(addEnv, func, ...args) { 381cb0ef41Sopenharmony_ci Object.assign(process.env, addEnv); // side effects! 391cb0ef41Sopenharmony_ci return func(...args); 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_cifunction isPack(array) { 431cb0ef41Sopenharmony_ci const firstItem = array[0]; 441cb0ef41Sopenharmony_ci return array.every((item) => item === firstItem); 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_cifunction isSet(array) { 481cb0ef41Sopenharmony_ci const deduped = new Set(array); 491cb0ef41Sopenharmony_ci return array.length === deduped.size; 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciconst localesISO639 = [ 541cb0ef41Sopenharmony_ci 'eng', 'cmn', 'hin', 'spa', 551cb0ef41Sopenharmony_ci 'fra', 'arb', 'ben', 'rus', 561cb0ef41Sopenharmony_ci 'por', 'urd', 'ind', 'deu', 571cb0ef41Sopenharmony_ci 'jpn', 'pcm', 'mar', 'tel', 581cb0ef41Sopenharmony_ci]; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ciconst locales = [ 611cb0ef41Sopenharmony_ci 'en', 'zh', 'hi', 'es', 621cb0ef41Sopenharmony_ci 'fr', 'ar', 'bn', 'ru', 631cb0ef41Sopenharmony_ci 'pt', 'ur', 'id', 'de', 641cb0ef41Sopenharmony_ci 'ja', 'pcm', 'mr', 'te', 651cb0ef41Sopenharmony_ci]; 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci// These must not overlap 681cb0ef41Sopenharmony_ciconst zones = [ 691cb0ef41Sopenharmony_ci 'America/New_York', 701cb0ef41Sopenharmony_ci 'UTC', 711cb0ef41Sopenharmony_ci 'Asia/Irkutsk', 721cb0ef41Sopenharmony_ci 'Australia/North', 731cb0ef41Sopenharmony_ci 'Antarctica/South_Pole', 741cb0ef41Sopenharmony_ci]; 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ciassert.deepStrictEqual(Intl.getCanonicalLocales(localesISO639), locales); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci// On some platforms these keep original locale (for example, 'January') 811cb0ef41Sopenharmony_ciconst enero = runEnvOutside( 821cb0ef41Sopenharmony_ci { LANG: 'es' }, 831cb0ef41Sopenharmony_ci 'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' 841cb0ef41Sopenharmony_ci); 851cb0ef41Sopenharmony_ciconst janvier = runEnvOutside( 861cb0ef41Sopenharmony_ci { LANG: 'fr' }, 871cb0ef41Sopenharmony_ci 'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' 881cb0ef41Sopenharmony_ci); 891cb0ef41Sopenharmony_ciconst isMockable = enero !== janvier; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci// Tests with mocked env 921cb0ef41Sopenharmony_ciif (isMockable) { 931cb0ef41Sopenharmony_ci assert.strictEqual( 941cb0ef41Sopenharmony_ci isSet(zones.map((TZ) => runEnvOutside({ TZ }, 'new Date(333333333333).toString()'))), 951cb0ef41Sopenharmony_ci true 961cb0ef41Sopenharmony_ci ); 971cb0ef41Sopenharmony_ci assert.strictEqual( 981cb0ef41Sopenharmony_ci isSet(zones.map((TZ) => runEnvOutside({ TZ }, 'new Date(333333333333).toLocaleString()'))), 991cb0ef41Sopenharmony_ci true 1001cb0ef41Sopenharmony_ci ); 1011cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1021cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Date(333333333333).toString()')), 1031cb0ef41Sopenharmony_ci [ 1041cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Central European Standard Time)', 1051cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (中欧标准时间)', 1061cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्य यूरोपीय मानक समय)', 1071cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (hora estándar de Europa central)', 1081cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (heure normale d’Europe centrale)', 1091cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (توقيت وسط أوروبا الرسمي)', 1101cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (মধ্য ইউরোপীয় মানক সময়)', 1111cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Центральная Европа, стандартное время)', 1121cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Horário Padrão da Europa Central)', 1131cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (وسطی یورپ کا معیاری وقت)', 1141cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Waktu Standar Eropa Tengah)', 1151cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Mitteleuropäische Normalzeit)', 1161cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (中央ヨーロッパ標準時)', 1171cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (Mídúl Yúrop Fíksd Taim)', 1181cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्य युरोपियन प्रमाण वेळ)', 1191cb0ef41Sopenharmony_ci 'Fri Jul 25 1980 01:35:33 GMT+0100 (సెంట్రల్ యూరోపియన్ ప్రామాణిక సమయం)', 1201cb0ef41Sopenharmony_ci ] 1211cb0ef41Sopenharmony_ci ); 1221cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1231cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Date(333333333333).toLocaleString()')), 1241cb0ef41Sopenharmony_ci [ 1251cb0ef41Sopenharmony_ci '7/25/1980, 1:35:33 AM', 1261cb0ef41Sopenharmony_ci '1980/7/25 01:35:33', 1271cb0ef41Sopenharmony_ci '25/7/1980, 1:35:33 am', 1281cb0ef41Sopenharmony_ci '25/7/1980, 1:35:33', 1291cb0ef41Sopenharmony_ci '25/07/1980 01:35:33', 1301cb0ef41Sopenharmony_ci '٢٥/٧/١٩٨٠، ١:٣٥:٣٣ ص', 1311cb0ef41Sopenharmony_ci '২৫/৭/১৯৮০, ১:৩৫:৩৩ AM', 1321cb0ef41Sopenharmony_ci '25.07.1980, 01:35:33', 1331cb0ef41Sopenharmony_ci '25/07/1980, 01:35:33', 1341cb0ef41Sopenharmony_ci '25/7/1980، 1:35:33 AM', 1351cb0ef41Sopenharmony_ci '25/7/1980, 01.35.33', 1361cb0ef41Sopenharmony_ci '25.7.1980, 01:35:33', 1371cb0ef41Sopenharmony_ci '1980/7/25 1:35:33', 1381cb0ef41Sopenharmony_ci '25/7/1980 01:35:33', 1391cb0ef41Sopenharmony_ci '२५/७/१९८०, १:३५:३३ AM', 1401cb0ef41Sopenharmony_ci '25/7/1980 1:35:33 AM', 1411cb0ef41Sopenharmony_ci ] 1421cb0ef41Sopenharmony_ci ); 1431cb0ef41Sopenharmony_ci assert.strictEqual( 1441cb0ef41Sopenharmony_ci runEnvOutside({ LANG: 'en' }, '["z", "ä"].sort(new Intl.Collator().compare)'), 1451cb0ef41Sopenharmony_ci 'ä,z' 1461cb0ef41Sopenharmony_ci ); 1471cb0ef41Sopenharmony_ci assert.strictEqual( 1481cb0ef41Sopenharmony_ci runEnvOutside({ LANG: 'sv' }, '["z", "ä"].sort(new Intl.Collator().compare)'), 1491cb0ef41Sopenharmony_ci 'z,ä' 1501cb0ef41Sopenharmony_ci ); 1511cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1521cb0ef41Sopenharmony_ci locales.map( 1531cb0ef41Sopenharmony_ci (LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Intl.DateTimeFormat().format(333333333333)') 1541cb0ef41Sopenharmony_ci ), 1551cb0ef41Sopenharmony_ci [ 1561cb0ef41Sopenharmony_ci '7/25/1980', '1980/7/25', 1571cb0ef41Sopenharmony_ci '25/7/1980', '25/7/1980', 1581cb0ef41Sopenharmony_ci '25/07/1980', '٢٥/٧/١٩٨٠', 1591cb0ef41Sopenharmony_ci '২৫/৭/১৯৮০', '25.07.1980', 1601cb0ef41Sopenharmony_ci '25/07/1980', '25/7/1980', 1611cb0ef41Sopenharmony_ci '25/7/1980', '25.7.1980', 1621cb0ef41Sopenharmony_ci '1980/7/25', '25/7/1980', 1631cb0ef41Sopenharmony_ci '२५/७/१९८०', '25/7/1980', 1641cb0ef41Sopenharmony_ci ] 1651cb0ef41Sopenharmony_ci ); 1661cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1671cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.DisplayNames(undefined, { type: "region" }).of("CH")')), 1681cb0ef41Sopenharmony_ci [ 1691cb0ef41Sopenharmony_ci 'Switzerland', '瑞士', 1701cb0ef41Sopenharmony_ci 'स्विट्ज़रलैंड', 'Suiza', 1711cb0ef41Sopenharmony_ci 'Suisse', 'سويسرا', 1721cb0ef41Sopenharmony_ci 'সুইজারল্যান্ড', 'Швейцария', 1731cb0ef41Sopenharmony_ci 'Suíça', 'سوئٹزر لینڈ', 1741cb0ef41Sopenharmony_ci 'Swiss', 'Schweiz', 1751cb0ef41Sopenharmony_ci 'スイス', 'Swítsaland', 1761cb0ef41Sopenharmony_ci 'स्वित्झर्लंड', 'స్విట్జర్లాండ్', 1771cb0ef41Sopenharmony_ci ] 1781cb0ef41Sopenharmony_ci ); 1791cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1801cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.NumberFormat().format(275760.913)')), 1811cb0ef41Sopenharmony_ci [ 1821cb0ef41Sopenharmony_ci '275,760.913', '275,760.913', 1831cb0ef41Sopenharmony_ci '2,75,760.913', '275.760,913', 1841cb0ef41Sopenharmony_ci '275 760,913', '٢٧٥٬٧٦٠٫٩١٣', 1851cb0ef41Sopenharmony_ci '২,৭৫,৭৬০.৯১৩', '275 760,913', 1861cb0ef41Sopenharmony_ci '275.760,913', '275,760.913', 1871cb0ef41Sopenharmony_ci '275.760,913', '275.760,913', 1881cb0ef41Sopenharmony_ci '275,760.913', '275,760.913', 1891cb0ef41Sopenharmony_ci '२,७५,७६०.९१३', '2,75,760.913', 1901cb0ef41Sopenharmony_ci ] 1911cb0ef41Sopenharmony_ci ); 1921cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1931cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.PluralRules().select(0)')), 1941cb0ef41Sopenharmony_ci [ 1951cb0ef41Sopenharmony_ci 'other', 'other', 'one', 'other', 1961cb0ef41Sopenharmony_ci 'one', 'zero', 'one', 'many', 1971cb0ef41Sopenharmony_ci 'one', 'other', 'other', 'other', 1981cb0ef41Sopenharmony_ci 'other', 'one', 'other', 'other', 1991cb0ef41Sopenharmony_ci ] 2001cb0ef41Sopenharmony_ci ); 2011cb0ef41Sopenharmony_ci assert.deepStrictEqual( 2021cb0ef41Sopenharmony_ci locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.RelativeTimeFormat().format(-586920.617, "hour")')), 2031cb0ef41Sopenharmony_ci [ 2041cb0ef41Sopenharmony_ci '586,920.617 hours ago', 2051cb0ef41Sopenharmony_ci '586,920.617小时前', 2061cb0ef41Sopenharmony_ci '5,86,920.617 घंटे पहले', 2071cb0ef41Sopenharmony_ci 'hace 586.920,617 horas', 2081cb0ef41Sopenharmony_ci 'il y a 586 920,617 heures', 2091cb0ef41Sopenharmony_ci 'قبل ٥٨٦٬٩٢٠٫٦١٧ ساعة', 2101cb0ef41Sopenharmony_ci '৫,৮৬,৯২০.৬১৭ ঘন্টা আগে', 2111cb0ef41Sopenharmony_ci '586 920,617 часа назад', 2121cb0ef41Sopenharmony_ci 'há 586.920,617 horas', 2131cb0ef41Sopenharmony_ci '586,920.617 گھنٹے پہلے', 2141cb0ef41Sopenharmony_ci '586.920,617 jam yang lalu', 2151cb0ef41Sopenharmony_ci 'vor 586.920,617 Stunden', 2161cb0ef41Sopenharmony_ci '586,920.617 時間前', 2171cb0ef41Sopenharmony_ci '586,920.617 áwa wé dọ́n pas', 2181cb0ef41Sopenharmony_ci '५,८६,९२०.६१७ तासांपूर्वी', 2191cb0ef41Sopenharmony_ci '5,86,920.617 గంటల క్రితం', 2201cb0ef41Sopenharmony_ci ] 2211cb0ef41Sopenharmony_ci ); 2221cb0ef41Sopenharmony_ci} 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci// Tests with process.env mutated inside 2261cb0ef41Sopenharmony_ci{ 2271cb0ef41Sopenharmony_ci // process.env.TZ is not intercepted in Workers 2281cb0ef41Sopenharmony_ci if (common.isMainThread) { 2291cb0ef41Sopenharmony_ci assert.strictEqual( 2301cb0ef41Sopenharmony_ci isSet(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toString()))), 2311cb0ef41Sopenharmony_ci true 2321cb0ef41Sopenharmony_ci ); 2331cb0ef41Sopenharmony_ci assert.strictEqual( 2341cb0ef41Sopenharmony_ci isSet(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toLocaleString()))), 2351cb0ef41Sopenharmony_ci true 2361cb0ef41Sopenharmony_ci ); 2371cb0ef41Sopenharmony_ci } else { 2381cb0ef41Sopenharmony_ci assert.strictEqual( 2391cb0ef41Sopenharmony_ci isPack(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toString()))), 2401cb0ef41Sopenharmony_ci true 2411cb0ef41Sopenharmony_ci ); 2421cb0ef41Sopenharmony_ci assert.strictEqual( 2431cb0ef41Sopenharmony_ci isPack(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toLocaleString()))), 2441cb0ef41Sopenharmony_ci true 2451cb0ef41Sopenharmony_ci ); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci assert.strictEqual( 2491cb0ef41Sopenharmony_ci isPack(locales.map((LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Date(333333333333).toString()))), 2501cb0ef41Sopenharmony_ci true 2511cb0ef41Sopenharmony_ci ); 2521cb0ef41Sopenharmony_ci assert.strictEqual( 2531cb0ef41Sopenharmony_ci isPack(locales.map( 2541cb0ef41Sopenharmony_ci (LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Date(333333333333).toLocaleString()) 2551cb0ef41Sopenharmony_ci )), 2561cb0ef41Sopenharmony_ci true 2571cb0ef41Sopenharmony_ci ); 2581cb0ef41Sopenharmony_ci assert.deepStrictEqual( 2591cb0ef41Sopenharmony_ci runEnvInside({ LANG: 'en' }, () => ['z', 'ä'].sort(new Intl.Collator().compare)), 2601cb0ef41Sopenharmony_ci runEnvInside({ LANG: 'sv' }, () => ['z', 'ä'].sort(new Intl.Collator().compare)) 2611cb0ef41Sopenharmony_ci ); 2621cb0ef41Sopenharmony_ci assert.strictEqual( 2631cb0ef41Sopenharmony_ci isPack(locales.map( 2641cb0ef41Sopenharmony_ci (LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Intl.DateTimeFormat().format(333333333333)) 2651cb0ef41Sopenharmony_ci )), 2661cb0ef41Sopenharmony_ci true 2671cb0ef41Sopenharmony_ci ); 2681cb0ef41Sopenharmony_ci assert.strictEqual( 2691cb0ef41Sopenharmony_ci isPack(locales.map( 2701cb0ef41Sopenharmony_ci (LANG) => runEnvInside({ LANG }, () => new Intl.DisplayNames(undefined, { type: 'region' }).of('CH')) 2711cb0ef41Sopenharmony_ci )), 2721cb0ef41Sopenharmony_ci true 2731cb0ef41Sopenharmony_ci ); 2741cb0ef41Sopenharmony_ci assert.strictEqual( 2751cb0ef41Sopenharmony_ci isPack(locales.map((LANG) => runEnvInside({ LANG }, () => new Intl.NumberFormat().format(275760.913)))), 2761cb0ef41Sopenharmony_ci true 2771cb0ef41Sopenharmony_ci ); 2781cb0ef41Sopenharmony_ci assert.strictEqual( 2791cb0ef41Sopenharmony_ci isPack(locales.map((LANG) => runEnvInside({ LANG }, () => new Intl.PluralRules().select(0)))), 2801cb0ef41Sopenharmony_ci true 2811cb0ef41Sopenharmony_ci ); 2821cb0ef41Sopenharmony_ci assert.strictEqual( 2831cb0ef41Sopenharmony_ci isPack(locales.map( 2841cb0ef41Sopenharmony_ci (LANG) => runEnvInside({ LANG }, () => new Intl.RelativeTimeFormat().format(-586920.617, 'hour')) 2851cb0ef41Sopenharmony_ci )), 2861cb0ef41Sopenharmony_ci true 2871cb0ef41Sopenharmony_ci ); 2881cb0ef41Sopenharmony_ci} 289