11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors. 21cb0ef41Sopenharmony_ci// 31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a 41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the 51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including 61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish, 71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit 81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the 91cb0ef41Sopenharmony_ci// following conditions: 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included 121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software. 131cb0ef41Sopenharmony_ci// 141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE. 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci'use strict'; 231cb0ef41Sopenharmony_ciconst common = require('../common'); 241cb0ef41Sopenharmony_ciconst assert = require('assert'); 251cb0ef41Sopenharmony_ciconst { execFile } = require('child_process'); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci// Does node think that i18n was enabled? 281cb0ef41Sopenharmony_cilet enablei18n = process.config.variables.v8_enable_i18n_support; 291cb0ef41Sopenharmony_ciif (enablei18n === undefined) { 301cb0ef41Sopenharmony_ci enablei18n = 0; 311cb0ef41Sopenharmony_ci} 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci// Returns true if no specific locale ids were configured (i.e. "all") 341cb0ef41Sopenharmony_ci// Else, returns true if loc is in the configured list 351cb0ef41Sopenharmony_ci// Else, returns false 361cb0ef41Sopenharmony_cifunction haveLocale(loc) { 371cb0ef41Sopenharmony_ci const locs = process.config.variables.icu_locales.split(','); 381cb0ef41Sopenharmony_ci return locs.includes(loc); 391cb0ef41Sopenharmony_ci} 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci// Always run these. They should always pass, even if the locale 421cb0ef41Sopenharmony_ci// param is ignored. 431cb0ef41Sopenharmony_ciassert.strictEqual('Ç'.toLocaleLowerCase('el'), 'ç'); 441cb0ef41Sopenharmony_ciassert.strictEqual('Ç'.toLocaleLowerCase('tr'), 'ç'); 451cb0ef41Sopenharmony_ciassert.strictEqual('Ç'.toLowerCase(), 'ç'); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciassert.strictEqual('ç'.toLocaleUpperCase('el'), 'Ç'); 481cb0ef41Sopenharmony_ciassert.strictEqual('ç'.toLocaleUpperCase('tr'), 'Ç'); 491cb0ef41Sopenharmony_ciassert.strictEqual('ç'.toUpperCase(), 'Ç'); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ciif (!common.hasIntl) { 521cb0ef41Sopenharmony_ci const erMsg = 531cb0ef41Sopenharmony_ci `"Intl" object is NOT present but v8_enable_i18n_support is ${enablei18n}`; 541cb0ef41Sopenharmony_ci assert.strictEqual(enablei18n, 0, erMsg); 551cb0ef41Sopenharmony_ci common.skip('Intl tests because Intl object not present.'); 561cb0ef41Sopenharmony_ci} else { 571cb0ef41Sopenharmony_ci const erMsg = 581cb0ef41Sopenharmony_ci `"Intl" object is present but v8_enable_i18n_support is ${ 591cb0ef41Sopenharmony_ci enablei18n}. Is this test out of date?`; 601cb0ef41Sopenharmony_ci assert.strictEqual(enablei18n, 1, erMsg); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci // Construct a new date at the beginning of Unix time 631cb0ef41Sopenharmony_ci const date0 = new Date(0); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci // Use the GMT time zone 661cb0ef41Sopenharmony_ci const GMT = 'Etc/GMT'; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci // Construct an English formatter. Should format to "Jan 70" 691cb0ef41Sopenharmony_ci const dtf = new Intl.DateTimeFormat(['en'], { 701cb0ef41Sopenharmony_ci timeZone: GMT, 711cb0ef41Sopenharmony_ci month: 'short', 721cb0ef41Sopenharmony_ci year: '2-digit' 731cb0ef41Sopenharmony_ci }); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // If list is specified and doesn't contain 'en' then return. 761cb0ef41Sopenharmony_ci if (process.config.variables.icu_locales && !haveLocale('en')) { 771cb0ef41Sopenharmony_ci common.printSkipMessage( 781cb0ef41Sopenharmony_ci 'detailed Intl tests because English is not listed as supported.'); 791cb0ef41Sopenharmony_ci // Smoke test. Does it format anything, or fail? 801cb0ef41Sopenharmony_ci console.log(`Date(0) formatted to: ${dtf.format(date0)}`); 811cb0ef41Sopenharmony_ci return; 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci // Check casing 851cb0ef41Sopenharmony_ci { 861cb0ef41Sopenharmony_ci assert.strictEqual('I'.toLocaleLowerCase('tr'), 'ı'); 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci // Check with toLocaleString 901cb0ef41Sopenharmony_ci { 911cb0ef41Sopenharmony_ci const localeString = dtf.format(date0); 921cb0ef41Sopenharmony_ci assert.strictEqual(localeString, 'Jan 70'); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci // Options to request GMT 951cb0ef41Sopenharmony_ci const optsGMT = { timeZone: GMT }; 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci // Test format 981cb0ef41Sopenharmony_ci { 991cb0ef41Sopenharmony_ci const localeString = date0.toLocaleString(['en'], optsGMT); 1001cb0ef41Sopenharmony_ci assert.strictEqual(localeString, '1/1/1970, 12:00:00 AM'); 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci // number format 1031cb0ef41Sopenharmony_ci { 1041cb0ef41Sopenharmony_ci const numberFormat = new Intl.NumberFormat(['en']).format(12345.67890); 1051cb0ef41Sopenharmony_ci assert.strictEqual(numberFormat, '12,345.679'); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci // If list is specified and doesn't contain 'en-US' then return. 1081cb0ef41Sopenharmony_ci if (process.config.variables.icu_locales && !haveLocale('en-US')) { 1091cb0ef41Sopenharmony_ci common.printSkipMessage('detailed Intl tests because American English is ' + 1101cb0ef41Sopenharmony_ci 'not listed as supported.'); 1111cb0ef41Sopenharmony_ci return; 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci // Number format resolved options 1141cb0ef41Sopenharmony_ci { 1151cb0ef41Sopenharmony_ci const numberFormat = new Intl.NumberFormat('en-US', { style: 'percent' }); 1161cb0ef41Sopenharmony_ci const resolvedOptions = numberFormat.resolvedOptions(); 1171cb0ef41Sopenharmony_ci assert.strictEqual(resolvedOptions.locale, 'en-US'); 1181cb0ef41Sopenharmony_ci assert.strictEqual(resolvedOptions.style, 'percent'); 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci // Significant Digits 1211cb0ef41Sopenharmony_ci { 1221cb0ef41Sopenharmony_ci const loc = ['en-US']; 1231cb0ef41Sopenharmony_ci const opts = { maximumSignificantDigits: 4 }; 1241cb0ef41Sopenharmony_ci const num = 10.001; 1251cb0ef41Sopenharmony_ci const numberFormat = new Intl.NumberFormat(loc, opts).format(num); 1261cb0ef41Sopenharmony_ci assert.strictEqual(numberFormat, '10'); 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci const collOpts = { sensitivity: 'base', ignorePunctuation: true }; 1301cb0ef41Sopenharmony_ci const coll = new Intl.Collator(['en'], collOpts); 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci // Ignore punctuation 1331cb0ef41Sopenharmony_ci assert.strictEqual(coll.compare('blackbird', 'black-bird'), 0); 1341cb0ef41Sopenharmony_ci // Compare less 1351cb0ef41Sopenharmony_ci assert.strictEqual(coll.compare('blackbird', 'red-bird'), -1); 1361cb0ef41Sopenharmony_ci // Compare greater 1371cb0ef41Sopenharmony_ci assert.strictEqual(coll.compare('bluebird', 'blackbird'), 1); 1381cb0ef41Sopenharmony_ci // Ignore case 1391cb0ef41Sopenharmony_ci assert.strictEqual(coll.compare('Bluebird', 'bluebird'), 0); 1401cb0ef41Sopenharmony_ci // `ffi` ligature (contraction) 1411cb0ef41Sopenharmony_ci assert.strictEqual(coll.compare('\ufb03', 'ffi'), 0); 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci { 1441cb0ef41Sopenharmony_ci // Regression test for https://github.com/nodejs/node/issues/27379 1451cb0ef41Sopenharmony_ci const env = { ...process.env, LC_ALL: 'ja' }; 1461cb0ef41Sopenharmony_ci execFile( 1471cb0ef41Sopenharmony_ci process.execPath, ['-p', 'new Date().toLocaleString()'], 1481cb0ef41Sopenharmony_ci { env }, 1491cb0ef41Sopenharmony_ci common.mustSucceed() 1501cb0ef41Sopenharmony_ci ); 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci { 1541cb0ef41Sopenharmony_ci // Regression test for https://github.com/nodejs/node/issues/27418 1551cb0ef41Sopenharmony_ci const env = { ...process.env, LC_ALL: 'fr@EURO' }; 1561cb0ef41Sopenharmony_ci execFile( 1571cb0ef41Sopenharmony_ci process.execPath, 1581cb0ef41Sopenharmony_ci ['-p', 'new Intl.NumberFormat().resolvedOptions().locale'], 1591cb0ef41Sopenharmony_ci { env }, 1601cb0ef41Sopenharmony_ci common.mustSucceed() 1611cb0ef41Sopenharmony_ci ); 1621cb0ef41Sopenharmony_ci } 1631cb0ef41Sopenharmony_ci} 164