@formatjs/intl 2.3.2 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/index.d.ts +17 -0
  2. package/index.d.ts.map +1 -0
  3. package/index.js +40 -0
  4. package/lib/index.d.ts +17 -0
  5. package/lib/index.d.ts.map +1 -0
  6. package/lib/index.js +17 -0
  7. package/lib/src/create-intl.d.ts +11 -0
  8. package/lib/src/create-intl.d.ts.map +1 -0
  9. package/lib/src/create-intl.js +55 -0
  10. package/lib/src/dateTime.d.ts +38 -0
  11. package/lib/src/dateTime.d.ts.map +1 -0
  12. package/lib/src/dateTime.js +117 -0
  13. package/lib/src/displayName.d.ts +6 -0
  14. package/lib/src/displayName.d.ts.map +1 -0
  15. package/lib/src/displayName.js +22 -0
  16. package/lib/src/error.d.ts +34 -0
  17. package/lib/src/error.d.ts.map +1 -0
  18. package/lib/src/error.js +88 -0
  19. package/lib/src/list.d.ts +11 -0
  20. package/lib/src/list.d.ts.map +1 -0
  21. package/lib/src/list.js +61 -0
  22. package/lib/src/message.d.ts +16 -0
  23. package/lib/src/message.d.ts.map +1 -0
  24. package/lib/src/message.js +103 -0
  25. package/lib/src/number.d.ts +17 -0
  26. package/lib/src/number.d.ts.map +1 -0
  27. package/lib/src/number.js +54 -0
  28. package/lib/src/plural.d.ts +7 -0
  29. package/lib/src/plural.d.ts.map +1 -0
  30. package/lib/src/plural.js +19 -0
  31. package/lib/src/relativeTime.d.ts +7 -0
  32. package/lib/src/relativeTime.d.ts.map +1 -0
  33. package/lib/src/relativeTime.js +29 -0
  34. package/lib/src/types.d.ts +103 -0
  35. package/lib/src/types.d.ts.map +1 -0
  36. package/lib/src/types.js +1 -0
  37. package/lib/src/utils.d.ts +12 -0
  38. package/lib/src/utils.d.ts.map +1 -0
  39. package/lib/src/utils.js +162 -0
  40. package/package.json +10 -10
  41. package/src/create-intl.d.ts +11 -0
  42. package/src/create-intl.d.ts.map +1 -0
  43. package/src/create-intl.js +59 -0
  44. package/src/dateTime.d.ts +38 -0
  45. package/src/dateTime.d.ts.map +1 -0
  46. package/src/dateTime.js +126 -0
  47. package/src/displayName.d.ts +6 -0
  48. package/src/displayName.d.ts.map +1 -0
  49. package/src/displayName.js +26 -0
  50. package/src/error.d.ts +34 -0
  51. package/src/error.d.ts.map +1 -0
  52. package/src/error.js +91 -0
  53. package/src/list.d.ts +11 -0
  54. package/src/list.d.ts.map +1 -0
  55. package/src/list.js +66 -0
  56. package/src/message.d.ts +16 -0
  57. package/src/message.d.ts.map +1 -0
  58. package/src/message.js +107 -0
  59. package/src/number.d.ts +17 -0
  60. package/src/number.d.ts.map +1 -0
  61. package/src/number.js +60 -0
  62. package/src/plural.d.ts +7 -0
  63. package/src/plural.d.ts.map +1 -0
  64. package/src/plural.js +23 -0
  65. package/src/relativeTime.d.ts +7 -0
  66. package/src/relativeTime.d.ts.map +1 -0
  67. package/src/relativeTime.js +33 -0
  68. package/src/types.d.ts +103 -0
  69. package/src/types.d.ts.map +1 -0
  70. package/src/types.js +2 -0
  71. package/src/utils.d.ts +12 -0
  72. package/src/utils.d.ts.map +1 -0
  73. package/src/utils.js +169 -0
  74. package/BUILD +0 -79
  75. package/CHANGELOG.md +0 -537
  76. package/index.ts +0 -38
  77. package/src/create-intl.ts +0 -159
  78. package/src/dateTime.ts +0 -204
  79. package/src/displayName.ts +0 -54
  80. package/src/error.ts +0 -106
  81. package/src/list.ts +0 -119
  82. package/src/message.ts +0 -246
  83. package/src/number.ts +0 -101
  84. package/src/plural.ts +0 -45
  85. package/src/relativeTime.ts +0 -74
  86. package/src/types.ts +0 -234
  87. package/src/utils.ts +0 -177
  88. package/tests/__snapshots__/formatDate.test.ts.snap +0 -13
  89. package/tests/__snapshots__/formatMessage.test.ts.snap +0 -45
  90. package/tests/__snapshots__/formatNumber.test.ts.snap +0 -13
  91. package/tests/__snapshots__/formatRelativeTime.test.ts.snap +0 -19
  92. package/tests/__snapshots__/formatTime.test.ts.snap +0 -13
  93. package/tests/create-intl.test.ts +0 -60
  94. package/tests/error.test.ts +0 -25
  95. package/tests/formatDate.test.ts +0 -167
  96. package/tests/formatDisplayNames.test.ts +0 -63
  97. package/tests/formatList.test.ts +0 -51
  98. package/tests/formatMessage.test.ts +0 -495
  99. package/tests/formatNumber.test.ts +0 -172
  100. package/tests/formatPlural.test.ts +0 -119
  101. package/tests/formatRelativeTime.test.ts +0 -145
  102. package/tests/formatTime.test.ts +0 -234
  103. package/tests/global.d.ts +0 -7
  104. package/tsconfig.json +0 -5
@@ -1,495 +0,0 @@
1
- /* eslint-disable @typescript-eslint/camelcase */
2
- import '@formatjs/intl-numberformat/polyfill'
3
- import '@formatjs/intl-numberformat/locale-data/en'
4
- import '@formatjs/intl-numberformat/locale-data/es'
5
- import IntlMessageFormat from 'intl-messageformat'
6
- import {parse} from '@formatjs/icu-messageformat-parser'
7
- import {formatMessage as baseFormatMessage} from '../src/message'
8
- import {Formatters, IntlConfig, IntlFormatters} from '../src/types'
9
-
10
- describe('format API', () => {
11
- const {NODE_ENV} = process.env
12
-
13
- let config: IntlConfig<any>
14
- let state: Formatters
15
-
16
- beforeEach(() => {
17
- config = {
18
- locale: 'en',
19
-
20
- messages: {
21
- no_args: 'Hello, World!',
22
- with_arg: 'Hello, {name}!',
23
- with_named_format: 'It is {now, date, year_only}',
24
- with_html: 'Hello, <b>{name}</b>!',
25
-
26
- missing: undefined as any,
27
- empty: '',
28
- invalid: 'invalid {}',
29
- missing_value: 'missing {arg_missing}',
30
- missing_named_format: 'missing {now, date, format_missing}',
31
- richText: 'rich <b>text</b>',
32
- ast_simple: parse('hello world'),
33
- ast_var: parse('hello there, {name}'),
34
- } as Record<string, any>,
35
-
36
- formats: {
37
- date: {
38
- 'year-only': {
39
- year: 'numeric',
40
- },
41
- missing: undefined,
42
- },
43
-
44
- time: {
45
- 'hour-only': {
46
- hour: '2-digit',
47
- hour12: false,
48
- },
49
- missing: undefined,
50
- },
51
-
52
- relative: {
53
- seconds: {
54
- style: 'narrow',
55
- },
56
- missing: undefined,
57
- },
58
-
59
- number: {
60
- percent: {
61
- style: 'percent',
62
- minimumFractionDigits: 2,
63
- },
64
- missing: undefined,
65
- },
66
- } as any,
67
-
68
- defaultLocale: 'en',
69
- defaultFormats: {},
70
-
71
- onError: jest.fn(),
72
- }
73
-
74
- state = {
75
- getDateTimeFormat: jest
76
- .fn()
77
- .mockImplementation((...args) => new Intl.DateTimeFormat(...args)),
78
- getNumberFormat: jest
79
- .fn()
80
- .mockImplementation((...args) => new Intl.NumberFormat(...args)),
81
- getMessageFormat: jest
82
- .fn()
83
- .mockImplementation(
84
- (msg, ...args) => new IntlMessageFormat(msg, ...args)
85
- ),
86
- getRelativeTimeFormat: jest
87
- .fn()
88
- .mockImplementation((...args) => new Intl.RelativeTimeFormat(...args)),
89
- getPluralRules: jest
90
- .fn()
91
- .mockImplementation((...args) => new Intl.PluralRules(...args)),
92
- getListFormat: jest
93
- .fn()
94
- .mockImplementation((...args) => new Intl.ListFormat(...args)),
95
- getDisplayNames: jest
96
- .fn()
97
- .mockImplementation(
98
- (...args) => new (Intl as any).DisplayNames(...args)
99
- ),
100
- }
101
- })
102
-
103
- afterEach(() => {
104
- process.env.NODE_ENV = NODE_ENV
105
- })
106
-
107
- describe('formatMessage()', () => {
108
- let formatMessage: IntlFormatters['formatMessage']
109
-
110
- beforeEach(() => {
111
- // @ts-ignore
112
- formatMessage = baseFormatMessage.bind(null, config, state)
113
- })
114
- it('should hot path message without values', function () {
115
- ;(state.getMessageFormat as jest.Mock).mockClear()
116
- expect(formatMessage({id: 'no_args'})).toBe('Hello, World!')
117
- expect(state.getMessageFormat).not.toHaveBeenCalled()
118
- expect(formatMessage({id: 'with_arg'}, {name: 'foo'})).toBe('Hello, foo!')
119
- expect(state.getMessageFormat).toHaveBeenCalled()
120
- })
121
- it('should hot path message without values', function () {
122
- ;(state.getMessageFormat as jest.Mock).mockClear()
123
- const err = jest.spyOn(console, 'error')
124
- expect(formatMessage({id: 'no_args'})).toBe('Hello, World!')
125
- expect(err).not.toHaveBeenCalled()
126
- })
127
- it('should not crash of messages does not have Object.prototype', function () {
128
- const messages = Object.create(null)
129
- messages!.no_args = 'Hello'
130
- // @ts-ignore
131
- formatMessage = baseFormatMessage.bind(
132
- null,
133
- {
134
- ...config,
135
- messages,
136
- },
137
- state
138
- )
139
- expect(() => formatMessage({id: 'no_args'})).not.toThrow()
140
- expect(formatMessage({id: 'no_args'})).toBe('Hello')
141
- })
142
- ;[`Hello, World!'{foo}'`, `'\ud83d'\udc04`].forEach(msg =>
143
- it(`should render escaped msg ${msg} properly in production`, () => {
144
- process.env.NODE_ENV = 'production'
145
-
146
- const descriptor = {
147
- id: 'hello',
148
- defaultMessage: msg,
149
- }
150
-
151
- const mf = new IntlMessageFormat(msg, 'en')
152
-
153
- expect(formatMessage(descriptor)).toBe(mf.format())
154
- })
155
- )
156
-
157
- it('throws when no Message Descriptor is provided', () => {
158
- // @ts-ignore
159
- expect(() => formatMessage()).toThrow(
160
- '[@formatjs/intl] An `id` must be provided to format a message.'
161
- )
162
- })
163
-
164
- it('throws when Message Descriptor `id` is missing or falsy', () => {
165
- expect(() => formatMessage({})).toThrow(
166
- '[@formatjs/intl] An `id` must be provided to format a message.'
167
- )
168
- ;[undefined, null, false, 0, ''].forEach(id => {
169
- // @ts-ignore
170
- expect(() => formatMessage({id})).toThrow(
171
- '[@formatjs/intl] An `id` must be provided to format a message.'
172
- )
173
- })
174
- })
175
-
176
- it('formats basic messages', () => {
177
- const {locale, messages} = config
178
- const mf = new IntlMessageFormat(messages!.no_args, locale)
179
-
180
- expect(formatMessage({id: 'no_args'})).toBe(mf.format())
181
- })
182
-
183
- it('formats basic message with preparsed defaultMessage', () => {
184
- const {locale, messages} = config
185
- const mf = new IntlMessageFormat(messages!.ast_var, locale)
186
-
187
- expect(
188
- formatMessage(
189
- {id: 'foo', defaultMessage: messages!.ast_var},
190
- {
191
- name: 'hey',
192
- }
193
- )
194
- ).toBe(
195
- mf.format({
196
- name: 'hey',
197
- })
198
- )
199
- })
200
-
201
- it('formats message with ID as a method in Object.prototype, GH issue #1885', () => {
202
- expect(formatMessage({id: 'toString'})).toBe('toString')
203
- expect(formatMessage({id: '__proto__'})).toBe('__proto__')
204
- })
205
-
206
- it('formats legacy HTML messages', () => {
207
- const {locale, messages} = config
208
- const mf = new IntlMessageFormat(messages!.richText, locale)
209
- const values = {
210
- b: (s: string) => `<foobar>${s}</foobar>`,
211
- }
212
- expect(formatMessage({id: 'richText'}, values)).toBe(
213
- // @ts-ignore
214
- mf.format<string>(values)
215
- )
216
- })
217
-
218
- it('formats basic AST messages', () => {
219
- const {locale, messages} = config
220
- const mf = new IntlMessageFormat(messages!.ast_simple, locale)
221
-
222
- expect(formatMessage({id: 'ast_simple'})).toBe(mf.format())
223
- })
224
-
225
- it('formats basic AST messages in prod', () => {
226
- const {locale, messages} = config
227
- const mf = new IntlMessageFormat(messages!.ast_simple, locale)
228
- process.env.NODE_ENV = 'production'
229
- expect(formatMessage({id: 'ast_simple'})).toBe(mf.format())
230
- })
231
-
232
- it('formats messages with placeholders', () => {
233
- const {locale, messages} = config
234
- const mf = new IntlMessageFormat(messages!.with_arg, locale)
235
- const values = {name: 'Eric'}
236
-
237
- expect(formatMessage({id: 'with_arg'}, values)).toBe(mf.format(values))
238
- })
239
-
240
- it('formats AST message with placeholders', () => {
241
- const {locale, messages} = config
242
- const mf = new IntlMessageFormat(messages!.ast_var, locale)
243
- const values = {name: 'Eric'}
244
-
245
- expect(formatMessage({id: 'ast_var'}, values)).toBe(mf.format(values))
246
- })
247
-
248
- it('formats messages with named formats', () => {
249
- const {locale, messages, formats} = config
250
- const mf = new IntlMessageFormat(
251
- messages!.with_named_format,
252
- locale,
253
- formats
254
- )
255
- const values = {now: Date.now()}
256
-
257
- expect(formatMessage({id: 'with_named_format'}, values)).toBe(
258
- mf.format(values)
259
- )
260
- })
261
-
262
- describe('fallbacks', () => {
263
- it('formats message with missing named formats', () => {
264
- const {locale, messages} = config
265
- const mf = new IntlMessageFormat(messages!.missing_named_format, locale)
266
- const values = {now: Date.now()}
267
-
268
- expect(formatMessage({id: 'missing_named_format'}, values)).toBe(
269
- mf.format(values)
270
- )
271
- })
272
-
273
- it('formats `defaultMessage` when message is missing', () => {
274
- const {locale, messages} = config
275
- const mf = new IntlMessageFormat(messages!.with_arg, locale)
276
- const id = 'missing'
277
- const values = {name: 'Eric'}
278
-
279
- expect(
280
- formatMessage(
281
- {
282
- id: id,
283
- defaultMessage: messages!.with_arg,
284
- },
285
- values
286
- )
287
- ).toBe(mf.format(values))
288
- })
289
-
290
- it('warns when `message` is missing and locales are different', () => {
291
- config.locale = 'fr'
292
-
293
- const {locale, messages, defaultLocale} = config
294
- const mf = new IntlMessageFormat(messages!.with_arg, locale)
295
- const id = 'missing'
296
- const values = {name: 'Eric'}
297
-
298
- expect(locale).not.toEqual(defaultLocale)
299
-
300
- expect(
301
- formatMessage(
302
- {
303
- id,
304
- defaultMessage: messages!.with_arg,
305
- },
306
- values
307
- )
308
- ).toBe(mf.format(values))
309
-
310
- expect((config.onError as jest.Mock).mock.calls.map(c => c[0].code))
311
- .toMatchInlineSnapshot(`
312
- Array [
313
- "MISSING_TRANSLATION",
314
- ]
315
- `)
316
- })
317
-
318
- it('warns when `message` and `defaultMessage` are missing', () => {
319
- const {messages} = config
320
- const id = 'missing'
321
- const values = {name: 'Eric'}
322
-
323
- expect(
324
- formatMessage(
325
- {
326
- id: id,
327
- defaultMessage: messages!.missing,
328
- },
329
- values
330
- )
331
- ).toBe(id)
332
-
333
- expect((config.onError as jest.Mock).mock.calls.map(c => c[0].code))
334
- .toMatchInlineSnapshot(`
335
- Array [
336
- "MISSING_TRANSLATION",
337
- ]
338
- `)
339
- })
340
-
341
- it('formats `defaultMessage` when message has a syntax error', () => {
342
- const {locale, messages} = config
343
- const mf = new IntlMessageFormat(messages!.with_arg, locale)
344
- const id = 'invalid'
345
- const values = {name: 'Eric'}
346
-
347
- expect(
348
- formatMessage(
349
- {
350
- id: id,
351
- defaultMessage: messages!.with_arg,
352
- },
353
- values
354
- )
355
- ).toBe(mf.format(values))
356
-
357
- expect(
358
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
359
- ).toMatchSnapshot()
360
- })
361
-
362
- it('formats `defaultMessage` when message has missing values', () => {
363
- const {locale, messages} = config
364
- const mf = new IntlMessageFormat(messages!.with_arg, locale)
365
- const id = 'missing_value'
366
- const values = {name: 'Eric'}
367
-
368
- expect(
369
- formatMessage(
370
- {
371
- id: id,
372
- defaultMessage: messages!.with_arg,
373
- },
374
- values
375
- )
376
- ).toBe(mf.format(values))
377
-
378
- expect(
379
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
380
- ).toMatchSnapshot()
381
- })
382
-
383
- it('returns message source when message and `defaultMessage` have formatting errors', () => {
384
- const {messages} = config
385
- const id = 'missing_value'
386
-
387
- expect(
388
- formatMessage(
389
- {
390
- id,
391
- defaultMessage: messages!.invalid,
392
- },
393
- {
394
- foo: 1,
395
- }
396
- )
397
- ).toBe(messages![id])
398
- expect(
399
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
400
- ).toMatchSnapshot()
401
- })
402
-
403
- it('returns message source when formatting error and missing `defaultMessage`', () => {
404
- const {messages} = config
405
- const id = 'missing_value'
406
-
407
- expect(
408
- formatMessage(
409
- {
410
- id,
411
- defaultMessage: messages!.missing,
412
- },
413
- {foo: 1}
414
- )
415
- ).toBe(messages![id])
416
- expect(
417
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
418
- ).toMatchSnapshot()
419
- })
420
-
421
- it('returns `defaultMessage` source when formatting errors and missing message', () => {
422
- config.locale = 'en-US'
423
-
424
- const {messages} = config
425
- const id = 'missing'
426
-
427
- expect(
428
- formatMessage({
429
- id,
430
- defaultMessage: messages!.invalid,
431
- })
432
- ).toBe(messages!.invalid)
433
-
434
- expect(
435
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
436
- ).toMatchSnapshot()
437
- })
438
-
439
- it('returns message `id` when message and `defaultMessage` are missing', () => {
440
- const id = 'missing'
441
-
442
- expect(formatMessage({id})).toBe(id)
443
-
444
- expect(
445
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
446
- ).toMatchSnapshot()
447
- })
448
-
449
- it('returns an empty string when `fallbackOnEmptyString` is false', () => {
450
- config.fallbackOnEmptyString = false
451
- const id = 'empty'
452
-
453
- expect(formatMessage({id})).toBe('')
454
- })
455
-
456
- it('does not return an empty string when `fallbackOnEmptyString` is true', () => {
457
- config.fallbackOnEmptyString = true
458
- const id = 'empty'
459
-
460
- expect(formatMessage({id})).toBe(id)
461
- })
462
-
463
- it('returns message `id` when message and `defaultMessage` are empty', () => {
464
- const {messages} = config
465
- const id = 'empty'
466
-
467
- expect(
468
- formatMessage({
469
- id: id,
470
- defaultMessage: messages![id],
471
- })
472
- ).toBe(id)
473
-
474
- expect(
475
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
476
- ).toMatchSnapshot()
477
- })
478
-
479
- it('allow passing Intl.MessageFormat opts in', function () {
480
- const {locale, messages, formats} = config
481
- const opts = {
482
- ignoreTag: true,
483
- }
484
- const mf = new IntlMessageFormat(
485
- messages!.richText,
486
- locale,
487
- formats,
488
- opts
489
- )
490
-
491
- expect(formatMessage({id: 'richText'}, opts)).toBe(mf.format())
492
- })
493
- })
494
- })
495
- })
@@ -1,172 +0,0 @@
1
- /* eslint-disable @typescript-eslint/camelcase */
2
- import '@formatjs/intl-numberformat/polyfill'
3
- import '@formatjs/intl-numberformat/locale-data/en'
4
- import '@formatjs/intl-numberformat/locale-data/es'
5
- import {formatNumber as formatNumberFn} from '../src/number'
6
- import {IntlConfig} from '../src/types'
7
-
8
- describe('format API', () => {
9
- const {NODE_ENV} = process.env
10
-
11
- let config: IntlConfig<any>
12
-
13
- let getNumberFormat: any
14
- beforeEach(() => {
15
- config = {
16
- locale: 'en',
17
-
18
- messages: {},
19
-
20
- formats: {
21
- date: {
22
- 'year-only': {
23
- year: 'numeric',
24
- },
25
- missing: undefined,
26
- },
27
-
28
- time: {
29
- 'hour-only': {
30
- hour: '2-digit',
31
- hour12: false,
32
- },
33
- missing: undefined,
34
- },
35
-
36
- relative: {
37
- seconds: {
38
- style: 'narrow',
39
- },
40
- missing: undefined,
41
- },
42
-
43
- number: {
44
- percent: {
45
- style: 'percent',
46
- minimumFractionDigits: 2,
47
- },
48
- missing: undefined,
49
- },
50
- } as any,
51
-
52
- defaultLocale: 'en',
53
- defaultFormats: {},
54
-
55
- onError: jest.fn(),
56
- }
57
-
58
- getNumberFormat = jest
59
- .fn()
60
- .mockImplementation((...args) => new Intl.NumberFormat(...args))
61
- })
62
-
63
- afterEach(() => {
64
- process.env.NODE_ENV = NODE_ENV
65
- })
66
-
67
- describe('formatNumber()', () => {
68
- let nf: any
69
- let formatNumber: any
70
-
71
- beforeEach(() => {
72
- nf = new Intl.NumberFormat(config.locale)
73
- // @ts-ignore
74
- formatNumber = formatNumberFn.bind(null, config, getNumberFormat)
75
- })
76
-
77
- it('returns "NaN" when no value is provided', () => {
78
- expect(nf.format()).toBe('NaN')
79
- expect(formatNumber()).toBe('NaN')
80
- })
81
-
82
- it('returns "NaN" when a non-number value is provided', () => {
83
- expect(nf.format(NaN)).toBe('NaN')
84
- expect(formatNumber(NaN)).toBe('NaN')
85
- })
86
-
87
- it('formats falsy values', () => {
88
- expect(formatNumber(false)).toBe(nf.format(false))
89
- expect(formatNumber(null)).toBe(nf.format(null))
90
- expect(formatNumber('')).toBe(nf.format(''))
91
- expect(formatNumber(0)).toBe(nf.format(0))
92
- })
93
-
94
- it('formats number values', () => {
95
- expect(formatNumber(1000)).toBe(nf.format(1000))
96
- expect(formatNumber(1.1)).toBe(nf.format(1.1))
97
- })
98
-
99
- it('formats string values parsed as numbers', () => {
100
- expect(Number('1000')).toBe(1000)
101
- expect(formatNumber('1000')).toBe(nf.format('1000'))
102
- expect(Number('1.10')).toBe(1.1)
103
- expect(formatNumber('1.10')).toBe(nf.format('1.10'))
104
- })
105
-
106
- describe('options', () => {
107
- it('accepts empty options', () => {
108
- expect(formatNumber(1000, {})).toBe(nf.format(1000))
109
- })
110
-
111
- it('accepts valid Intl.NumberFormat options', () => {
112
- expect(() => formatNumber(0, {style: 'percent'})).not.toThrow()
113
- })
114
-
115
- it('falls back and warns on invalid Intl.NumberFormat options', () => {
116
- expect(formatNumber(0, {style: 'invalid'})).toBe(String(0))
117
- expect(
118
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
119
- ).toMatchSnapshot()
120
- })
121
-
122
- it('uses configured named formats', () => {
123
- const num = 0.505
124
- const format = 'percent'
125
-
126
- const {locale, formats} = config
127
- nf = new Intl.NumberFormat(
128
- locale,
129
- formats!.number![format] as Intl.NumberFormatOptions
130
- )
131
-
132
- expect(formatNumber(num, {format})).toBe(nf.format(num))
133
- })
134
-
135
- it('uses named formats as defaults', () => {
136
- const num = 0.500059
137
- const opts = {maximumFractionDigits: 3}
138
- const format = 'percent'
139
-
140
- const {locale, formats} = config
141
- nf = new Intl.NumberFormat(locale, {
142
- ...opts,
143
- ...formats!.number![format],
144
- } as Intl.NumberFormatOptions)
145
-
146
- expect(formatNumber(num, {...opts, format})).toBe(nf.format(num))
147
- })
148
-
149
- it('handles missing named formats and warns', () => {
150
- const num = 1000
151
- const format = 'missing'
152
-
153
- nf = new Intl.NumberFormat(config.locale)
154
-
155
- expect(formatNumber(num, {format})).toBe(nf.format(num))
156
- expect(
157
- (config.onError as jest.Mock).mock.calls.map(c => c[0].code)
158
- ).toMatchSnapshot()
159
- })
160
-
161
- it('uses provided numberingSystem', () => {
162
- const num = 0.1
163
- const numberingSystem = 'arab'
164
- const style = 'percent'
165
- // @ts-ignore
166
- nf = new Intl.NumberFormat(config.locale, {numberingSystem, style})
167
-
168
- expect(formatNumber(num, {numberingSystem, style})).toBe(nf.format(num))
169
- })
170
- })
171
- })
172
- })