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