react-intl 6.0.3 → 6.0.6
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.
- package/BUILD +130 -0
- package/CHANGELOG.md +1384 -0
- package/LICENSE.md +0 -0
- package/README.md +0 -0
- package/example-sandboxes/rescripts/.rescriptsrc.js +28 -0
- package/example-sandboxes/rescripts/package-lock.json +18035 -0
- package/example-sandboxes/rescripts/package.json +35 -0
- package/example-sandboxes/rescripts/public/index.html +42 -0
- package/example-sandboxes/rescripts/src/App.tsx +16 -0
- package/example-sandboxes/rescripts/src/index.tsx +5 -0
- package/example-sandboxes/rescripts/src/react-app-env.d.ts +1 -0
- package/example-sandboxes/rescripts/src/styles.css +4 -0
- package/example-sandboxes/rescripts/tsconfig.json +20 -0
- package/example-sandboxes/strict-locale-type/.env +1 -0
- package/example-sandboxes/strict-locale-type/package-lock.json +14595 -0
- package/example-sandboxes/strict-locale-type/package.json +35 -0
- package/example-sandboxes/strict-locale-type/src/App.tsx +48 -0
- package/example-sandboxes/strict-locale-type/src/index.html +28 -0
- package/example-sandboxes/strict-locale-type/src/index.tsx +7 -0
- package/example-sandboxes/strict-locale-type/src/styles.css +4 -0
- package/example-sandboxes/strict-locale-type/tsconfig.json +7 -0
- package/example-sandboxes/strict-message-types/.env +1 -0
- package/example-sandboxes/strict-message-types/package-lock.json +14596 -0
- package/example-sandboxes/strict-message-types/package.json +35 -0
- package/example-sandboxes/strict-message-types/src/App.tsx +31 -0
- package/example-sandboxes/strict-message-types/src/index.html +28 -0
- package/example-sandboxes/strict-message-types/src/index.tsx +7 -0
- package/example-sandboxes/strict-message-types/src/styles.css +4 -0
- package/example-sandboxes/strict-message-types/tsconfig.json +7 -0
- package/examples/BUILD +70 -0
- package/examples/Bug2727.tsx +37 -0
- package/examples/HandleChange.tsx +48 -0
- package/examples/Hooks.tsx +126 -0
- package/examples/Injected.tsx +41 -0
- package/examples/Messages.tsx +82 -0
- package/examples/StaticTypeSafetyAndCodeSplitting/StaticTypeSafetyAndCodeSplitting.tsx +44 -0
- package/examples/StaticTypeSafetyAndCodeSplitting/en.json +3 -0
- package/examples/StaticTypeSafetyAndCodeSplitting/intlHelpers.tsx +39 -0
- package/examples/StaticTypeSafetyAndCodeSplitting/it.json +3 -0
- package/examples/TimeZone.tsx +44 -0
- package/examples/advanced/Advanced.tsx +68 -0
- package/examples/advanced/compiled-lang/en.json +77 -0
- package/examples/advanced/compiled-lang/fr.json +77 -0
- package/examples/index.html +20 -0
- package/examples/index.tsx +44 -0
- package/examples/package.json +20 -0
- package/index.ts +127 -0
- package/jest.config.js +27 -0
- package/package.json +12 -8
- package/src/components/createFormattedComponent.tsx +123 -0
- package/src/components/dateTimeRange.tsx +26 -0
- package/src/components/injectIntl.tsx +111 -0
- package/src/components/message.tsx +73 -0
- package/src/components/plural.tsx +45 -0
- package/src/components/provider.tsx +196 -0
- package/src/components/relative.tsx +192 -0
- package/src/components/useIntl.ts +10 -0
- package/src/types.ts +29 -0
- package/src/utils.ts +77 -0
- package/tests/functional/index.ts +18 -0
- package/tests/functional/support/build.ts +16 -0
- package/tests/functional/support/format.tsx +112 -0
- package/tests/perf/index.tsx +196 -0
- package/tests/setup.js +10 -0
- package/tests/unit/components/__snapshots__/displayName.tsx.snap +19 -0
- package/tests/unit/components/__snapshots__/message.tsx.snap +41 -0
- package/tests/unit/components/__snapshots__/relative.tsx.snap +11 -0
- package/tests/unit/components/__snapshots__/useIntl.tsx.snap +25 -0
- package/tests/unit/components/date.tsx +233 -0
- package/tests/unit/components/dateTimeRange.tsx +103 -0
- package/tests/unit/components/displayName.tsx +57 -0
- package/tests/unit/components/message.tsx +509 -0
- package/tests/unit/components/number.tsx +198 -0
- package/tests/unit/components/plural.tsx +116 -0
- package/tests/unit/components/provider.tsx +215 -0
- package/tests/unit/components/relative.tsx +263 -0
- package/tests/unit/components/time.tsx +242 -0
- package/tests/unit/components/useIntl.tsx +64 -0
- package/tests/unit/components/withIntl.tsx +66 -0
- package/tests/unit/react-intl.ts +88 -0
- package/tests/unit/testUtils.tsx +42 -0
- package/tsconfig.json +5 -0
- package/index.d.ts +0 -43
- package/index.d.ts.map +0 -1
- package/index.js +0 -51
- package/lib/index.d.ts +0 -43
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -26
- package/lib/src/components/createFormattedComponent.d.ts +0 -29
- package/lib/src/components/createFormattedComponent.d.ts.map +0 -1
- package/lib/src/components/createFormattedComponent.js +0 -62
- package/lib/src/components/dateTimeRange.d.ts +0 -11
- package/lib/src/components/dateTimeRange.d.ts.map +0 -1
- package/lib/src/components/dateTimeRange.js +0 -15
- package/lib/src/components/injectIntl.d.ts +0 -22
- package/lib/src/components/injectIntl.d.ts.map +0 -1
- package/lib/src/components/injectIntl.js +0 -29
- package/lib/src/components/message.d.ts +0 -12
- package/lib/src/components/message.d.ts.map +0 -1
- package/lib/src/components/message.js +0 -35
- package/lib/src/components/plural.d.ts +0 -15
- package/lib/src/components/plural.d.ts.map +0 -1
- package/lib/src/components/plural.js +0 -26
- package/lib/src/components/provider.d.ts +0 -35
- package/lib/src/components/provider.d.ts.map +0 -1
- package/lib/src/components/provider.js +0 -108
- package/lib/src/components/relative.d.ts +0 -12
- package/lib/src/components/relative.d.ts.map +0 -1
- package/lib/src/components/relative.js +0 -129
- package/lib/src/components/useIntl.d.ts +0 -3
- package/lib/src/components/useIntl.d.ts.map +0 -1
- package/lib/src/components/useIntl.js +0 -8
- package/lib/src/types.d.ts +0 -12
- package/lib/src/types.d.ts.map +0 -1
- package/lib/src/types.js +0 -1
- package/lib/src/utils.d.ts +0 -14
- package/lib/src/utils.d.ts.map +0 -1
- package/lib/src/utils.js +0 -43
- package/react-intl.iife.js +0 -7485
- package/src/components/createFormattedComponent.d.ts +0 -29
- package/src/components/createFormattedComponent.d.ts.map +0 -1
- package/src/components/createFormattedComponent.js +0 -69
- package/src/components/dateTimeRange.d.ts +0 -11
- package/src/components/dateTimeRange.d.ts.map +0 -1
- package/src/components/dateTimeRange.js +0 -17
- package/src/components/injectIntl.d.ts +0 -22
- package/src/components/injectIntl.d.ts.map +0 -1
- package/src/components/injectIntl.js +0 -33
- package/src/components/message.d.ts +0 -12
- package/src/components/message.d.ts.map +0 -1
- package/src/components/message.js +0 -37
- package/src/components/plural.d.ts +0 -15
- package/src/components/plural.d.ts.map +0 -1
- package/src/components/plural.js +0 -29
- package/src/components/provider.d.ts +0 -35
- package/src/components/provider.d.ts.map +0 -1
- package/src/components/provider.js +0 -112
- package/src/components/relative.d.ts +0 -12
- package/src/components/relative.d.ts.map +0 -1
- package/src/components/relative.js +0 -131
- package/src/components/useIntl.d.ts +0 -3
- package/src/components/useIntl.d.ts.map +0 -1
- package/src/components/useIntl.js +0 -12
- package/src/types.d.ts +0 -12
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -2
- package/src/utils.d.ts +0 -14
- package/src/utils.d.ts.map +0 -1
- package/src/utils.js +0 -49
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import {FormattedDate, FormattedDateParts} from '../../../'
|
|
3
|
+
import {mountFormattedComponentWithProvider} from '../testUtils'
|
|
4
|
+
import {createIntl} from '../../../src/components/provider'
|
|
5
|
+
import {IntlShape} from '../../../'
|
|
6
|
+
import {render} from '@testing-library/react'
|
|
7
|
+
|
|
8
|
+
const mountWithProvider = mountFormattedComponentWithProvider(FormattedDate)
|
|
9
|
+
const mountPartsWithProvider =
|
|
10
|
+
mountFormattedComponentWithProvider(FormattedDateParts)
|
|
11
|
+
|
|
12
|
+
describe('<FormattedDate>', () => {
|
|
13
|
+
let intl: IntlShape
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
intl = createIntl({
|
|
16
|
+
locale: 'en',
|
|
17
|
+
onError: () => {},
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('has a `displayName`', () => {
|
|
22
|
+
expect(typeof FormattedDate.displayName).toBe('string')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('throws when <IntlProvider> is missing from ancestry', () => {
|
|
26
|
+
// So it doesn't spam the console
|
|
27
|
+
jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
28
|
+
expect(() => render(<FormattedDate value={Date.now()} />)).toThrow(Error)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('requires a finite `value` prop', () => {
|
|
32
|
+
const value = Date.now()
|
|
33
|
+
const onError = jest.fn()
|
|
34
|
+
mountWithProvider({value}, {...intl, onError})
|
|
35
|
+
expect(isFinite(value)).toBe(true)
|
|
36
|
+
expect(onError).toHaveBeenCalledTimes(0)
|
|
37
|
+
|
|
38
|
+
mountWithProvider({value: NaN}, {...intl, onError})
|
|
39
|
+
expect(onError).toHaveBeenCalledTimes(1)
|
|
40
|
+
expect(onError.mock.calls[0][0].code).toBe('FORMAT_ERROR')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders a formatted date in a <>', () => {
|
|
44
|
+
const date = Date.now()
|
|
45
|
+
|
|
46
|
+
const {getByTestId} = mountWithProvider({value: date}, intl)
|
|
47
|
+
|
|
48
|
+
expect(getByTestId('comp')).toHaveTextContent(intl.formatDate(date))
|
|
49
|
+
})
|
|
50
|
+
it('renders a formatted date w/o textComponent', () => {
|
|
51
|
+
const date = Date.now()
|
|
52
|
+
|
|
53
|
+
const {getByTestId} = mountWithProvider(
|
|
54
|
+
{value: date},
|
|
55
|
+
{...intl, textComponent: '' as any}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
expect(getByTestId('comp')).toHaveTextContent(intl.formatDate(date))
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('accepts valid Intl.DateTimeFormat options as props', () => {
|
|
62
|
+
const date = new Date()
|
|
63
|
+
const options: Intl.DateTimeFormatOptions = {year: 'numeric'}
|
|
64
|
+
|
|
65
|
+
const {getByTestId} = mountWithProvider({value: date, ...options}, intl)
|
|
66
|
+
|
|
67
|
+
expect(getByTestId('comp')).toHaveTextContent(
|
|
68
|
+
intl.formatDate(date, options)
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('falls back and warns on invalid Intl.DateTimeFormat options', () => {
|
|
73
|
+
const date = new Date()
|
|
74
|
+
const onError = jest.fn()
|
|
75
|
+
const {getByTestId} = mountWithProvider(
|
|
76
|
+
// @ts-expect-error invalid value for testing
|
|
77
|
+
{value: date, year: 'invalid'},
|
|
78
|
+
{...intl, onError}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expect(getByTestId('comp')).toHaveTextContent(String(date))
|
|
82
|
+
expect(onError).toHaveBeenCalled()
|
|
83
|
+
expect(onError.mock.calls[0][0].code).toBe('FORMAT_ERROR')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('accepts `format` prop', () => {
|
|
87
|
+
intl = createIntl({
|
|
88
|
+
onError: () => {},
|
|
89
|
+
locale: 'en',
|
|
90
|
+
formats: {
|
|
91
|
+
date: {
|
|
92
|
+
'year-only': {year: 'numeric'},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const date = new Date()
|
|
98
|
+
const format = 'year-only'
|
|
99
|
+
|
|
100
|
+
const {getByTestId} = mountWithProvider({value: date, format}, intl)
|
|
101
|
+
|
|
102
|
+
expect(getByTestId('comp')).toHaveTextContent(
|
|
103
|
+
intl.formatDate(date, {format})
|
|
104
|
+
)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('supports function-as-child pattern', () => {
|
|
108
|
+
const date = Date.now()
|
|
109
|
+
|
|
110
|
+
const spyChildren = jest
|
|
111
|
+
.fn()
|
|
112
|
+
.mockImplementation(() => <b data-testid="b">Jest</b>)
|
|
113
|
+
const {getByTestId} = mountWithProvider(
|
|
114
|
+
{
|
|
115
|
+
value: date,
|
|
116
|
+
children: spyChildren,
|
|
117
|
+
},
|
|
118
|
+
intl
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
expect(spyChildren).toHaveBeenCalledTimes(1)
|
|
122
|
+
expect(spyChildren.mock.calls[0]).toEqual([intl.formatDate(date)])
|
|
123
|
+
|
|
124
|
+
expect(getByTestId('b')).toHaveTextContent('Jest')
|
|
125
|
+
expect(getByTestId('b').tagName).toBe('B')
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
describe('<FormattedDateParts>', () => {
|
|
130
|
+
let intl: IntlShape
|
|
131
|
+
const children = jest.fn(
|
|
132
|
+
parts => (Array.isArray(parts) && parts[0] && parts[0].value) || null
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
intl = createIntl({
|
|
137
|
+
locale: 'en',
|
|
138
|
+
onError: () => {},
|
|
139
|
+
})
|
|
140
|
+
children.mockClear()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('has a `displayName`', () => {
|
|
144
|
+
expect(FormattedDateParts.displayName).toBe('FormattedDateParts')
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('throws when <IntlProvider> is missing from ancestry', () => {
|
|
148
|
+
// So it doesn't spam the console
|
|
149
|
+
jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
150
|
+
expect(() =>
|
|
151
|
+
render(<FormattedDateParts children={children} value={Date.now()} />)
|
|
152
|
+
).toThrow(
|
|
153
|
+
'[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.'
|
|
154
|
+
)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('requires a finite `value` prop', () => {
|
|
158
|
+
const value = Date.now()
|
|
159
|
+
const onError = jest.fn()
|
|
160
|
+
mountPartsWithProvider({value, children}, {...intl, onError})
|
|
161
|
+
expect(isFinite(value)).toBe(true)
|
|
162
|
+
expect(onError).toHaveBeenCalledTimes(0)
|
|
163
|
+
|
|
164
|
+
mountPartsWithProvider({value: NaN, children}, {...intl, onError})
|
|
165
|
+
expect(onError).toHaveBeenCalledTimes(1)
|
|
166
|
+
expect(onError.mock.calls[0][0].code).toBe('FORMAT_ERROR')
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('accepts valid Intl.DateTimeFormat options as props', () => {
|
|
170
|
+
const date = new Date(1567130870626)
|
|
171
|
+
const options: Intl.DateTimeFormatOptions = {year: 'numeric'}
|
|
172
|
+
|
|
173
|
+
mountPartsWithProvider({value: date, children, ...options}, intl)
|
|
174
|
+
|
|
175
|
+
expect(children.mock.calls[0][0]).toEqual(
|
|
176
|
+
intl.formatDateToParts(date, options)
|
|
177
|
+
)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('falls back and warns on invalid Intl.DateTimeFormat options', () => {
|
|
181
|
+
const date = new Date(1567130870626)
|
|
182
|
+
const onError = jest.fn()
|
|
183
|
+
mountPartsWithProvider(
|
|
184
|
+
// @ts-expect-error invalid value for testing
|
|
185
|
+
{value: date, year: 'invalid', children},
|
|
186
|
+
{...intl, onError}
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
expect(children.mock.calls[0][0]).toEqual(
|
|
190
|
+
// @ts-expect-error invalid value for testing
|
|
191
|
+
intl.formatDateToParts(date, {year: 'invalid'})
|
|
192
|
+
)
|
|
193
|
+
expect(onError).toHaveBeenCalled()
|
|
194
|
+
expect(onError.mock.calls[0][0].code).toBe('FORMAT_ERROR')
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('renders a string date', () => {
|
|
198
|
+
const date = new Date()
|
|
199
|
+
|
|
200
|
+
mountPartsWithProvider({value: date + '', children}, intl)
|
|
201
|
+
|
|
202
|
+
expect(children.mock.calls[0][0]).toEqual(intl.formatDateToParts(date))
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it('renders date 0 if value is ""', () => {
|
|
206
|
+
const date = new Date(0)
|
|
207
|
+
|
|
208
|
+
mountPartsWithProvider({value: '', children}, intl)
|
|
209
|
+
|
|
210
|
+
expect(children.mock.calls[0][0]).toEqual(intl.formatDateToParts(date))
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('accepts `format` prop', () => {
|
|
214
|
+
intl = createIntl({
|
|
215
|
+
onError: () => {},
|
|
216
|
+
locale: 'en',
|
|
217
|
+
formats: {
|
|
218
|
+
date: {
|
|
219
|
+
'year-only': {year: 'numeric'},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
const date = new Date(1567130870626)
|
|
225
|
+
const format = 'year-only'
|
|
226
|
+
|
|
227
|
+
mountPartsWithProvider({value: date, format, children}, intl)
|
|
228
|
+
|
|
229
|
+
expect(children.mock.calls[0][0]).toEqual(
|
|
230
|
+
intl.formatDateToParts(date, {format})
|
|
231
|
+
)
|
|
232
|
+
})
|
|
233
|
+
})
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import {FormattedDateTimeRange} from '../../../'
|
|
3
|
+
import {mountFormattedComponentWithProvider} from '../testUtils'
|
|
4
|
+
import {createIntl} from '../../../src/components/provider'
|
|
5
|
+
import {IntlShape} from '../../../'
|
|
6
|
+
import {render} from '@testing-library/react'
|
|
7
|
+
const mountWithProvider = mountFormattedComponentWithProvider(
|
|
8
|
+
FormattedDateTimeRange
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
describe('<FormattedDateTimeRange>', () => {
|
|
12
|
+
let intl: IntlShape
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
intl = createIntl({
|
|
15
|
+
onError: () => {},
|
|
16
|
+
locale: 'en',
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('has a `displayName`', () => {
|
|
21
|
+
expect(typeof FormattedDateTimeRange.displayName).toBe('string')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('throws when <IntlProvider> is missing from ancestry', () => {
|
|
25
|
+
// So it doesn't spam the console
|
|
26
|
+
jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
27
|
+
expect(() =>
|
|
28
|
+
render(<FormattedDateTimeRange from={Date.now()} to={Date.now()} />)
|
|
29
|
+
).toThrow(Error)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('renders a formatted date in a <>', () => {
|
|
33
|
+
const from = new Date('2020-1-1')
|
|
34
|
+
const to = new Date('2020-1-15')
|
|
35
|
+
|
|
36
|
+
const {getByTestId} = mountWithProvider({from, to}, intl)
|
|
37
|
+
|
|
38
|
+
expect(getByTestId('comp')).toHaveTextContent(
|
|
39
|
+
intl.formatDateTimeRange(from, to)
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
it('renders a formatted date w/o textComponent', () => {
|
|
43
|
+
const from = new Date('2020-1-1')
|
|
44
|
+
const to = new Date('2020-1-15')
|
|
45
|
+
const {getByTestId} = mountWithProvider(
|
|
46
|
+
{from, to},
|
|
47
|
+
{...intl, textComponent: '' as any}
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
expect(getByTestId('comp')).toHaveTextContent('1/1/2020 – 1/15/2020')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('accepts valid Intl.DateTimeFormat options as props', () => {
|
|
54
|
+
const from = new Date('2020-1-1')
|
|
55
|
+
const to = new Date('2020-1-15')
|
|
56
|
+
const options: Intl.DateTimeFormatOptions = {year: 'numeric'}
|
|
57
|
+
|
|
58
|
+
const {getByTestId} = mountWithProvider({from, to, ...options}, intl)
|
|
59
|
+
|
|
60
|
+
expect(getByTestId('comp')).toHaveTextContent(
|
|
61
|
+
intl.formatDateTimeRange(from, to, options)
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('falls back and warns on invalid Intl.DateTimeFormat options', () => {
|
|
66
|
+
const from = new Date()
|
|
67
|
+
const onError = jest.fn()
|
|
68
|
+
const {getByTestId} = mountWithProvider(
|
|
69
|
+
// @ts-expect-error invalid for testing
|
|
70
|
+
{from, to: undefined, year: 'invalid'},
|
|
71
|
+
{...intl, onError}
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
expect(getByTestId('comp')).toHaveTextContent(String(from))
|
|
75
|
+
expect(onError).toHaveBeenCalled()
|
|
76
|
+
expect(onError.mock.calls[0][0].code).toBe('FORMAT_ERROR')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('supports function-as-child pattern', () => {
|
|
80
|
+
const from = new Date('2020-1-1')
|
|
81
|
+
const to = new Date('2020-1-15')
|
|
82
|
+
const spyChildren = jest
|
|
83
|
+
.fn()
|
|
84
|
+
.mockImplementation(() => <b data-testid="b">Jest</b>)
|
|
85
|
+
const {getByTestId} = mountWithProvider(
|
|
86
|
+
{
|
|
87
|
+
from,
|
|
88
|
+
to,
|
|
89
|
+
children: spyChildren,
|
|
90
|
+
},
|
|
91
|
+
intl
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
expect(spyChildren).toHaveBeenCalledTimes(1)
|
|
95
|
+
expect(spyChildren.mock.calls[0]).toEqual([
|
|
96
|
+
intl.formatDateTimeRange(from, to),
|
|
97
|
+
])
|
|
98
|
+
|
|
99
|
+
const rendered = getByTestId('b')
|
|
100
|
+
expect(rendered.tagName).toBe('B')
|
|
101
|
+
expect(rendered).toHaveTextContent('Jest')
|
|
102
|
+
})
|
|
103
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import {FormattedDisplayName} from '../../../'
|
|
4
|
+
import {mountFormattedComponentWithProvider} from '../testUtils'
|
|
5
|
+
import {render} from '@testing-library/react'
|
|
6
|
+
const mountWithProvider =
|
|
7
|
+
mountFormattedComponentWithProvider(FormattedDisplayName)
|
|
8
|
+
|
|
9
|
+
const intlConfig = {locale: 'en'}
|
|
10
|
+
|
|
11
|
+
describe('<FormattedDisplayName />', () => {
|
|
12
|
+
it('has a `displayName`', () => {
|
|
13
|
+
expect(FormattedDisplayName.displayName).toBe('FormattedDisplayName')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('throws when <IntlProvider> is missing from ancestry', () => {
|
|
17
|
+
// So it doesn't spam the console
|
|
18
|
+
jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
19
|
+
expect(() =>
|
|
20
|
+
render(<FormattedDisplayName type="language" value="zh-Hans" />)
|
|
21
|
+
).toThrow(
|
|
22
|
+
'[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.'
|
|
23
|
+
)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('accepts Intl.DisplayNames options', () => {
|
|
27
|
+
const {container} = mountWithProvider(
|
|
28
|
+
{
|
|
29
|
+
type: 'currency',
|
|
30
|
+
value: 'CNY',
|
|
31
|
+
},
|
|
32
|
+
intlConfig
|
|
33
|
+
)
|
|
34
|
+
expect(container).toMatchSnapshot()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('renders an empty <> when the underlying DisplayNames would return undefined', () => {
|
|
38
|
+
// When fallback is none, it will return undefined if no display name is available.
|
|
39
|
+
const displayNames = new (Intl as any).DisplayNames('en', {
|
|
40
|
+
type: 'language',
|
|
41
|
+
fallback: 'none',
|
|
42
|
+
})
|
|
43
|
+
expect(displayNames.of('xx-XX')).toBeUndefined()
|
|
44
|
+
|
|
45
|
+
// Now let's do the same with <FormattedDisplayNames />
|
|
46
|
+
const {container} = mountWithProvider(
|
|
47
|
+
{
|
|
48
|
+
type: 'language',
|
|
49
|
+
fallback: 'none',
|
|
50
|
+
value: 'xx-XX',
|
|
51
|
+
},
|
|
52
|
+
intlConfig
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
expect(container).toMatchSnapshot()
|
|
56
|
+
})
|
|
57
|
+
})
|