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
package/src/utils.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {ResolvedIntlConfig} from './types'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import {FormatXMLElementFn} from 'intl-messageformat'
|
|
4
|
+
import {invariant} from '@formatjs/ecma402-abstract'
|
|
5
|
+
|
|
6
|
+
import {DEFAULT_INTL_CONFIG as CORE_DEFAULT_INTL_CONFIG} from '@formatjs/intl'
|
|
7
|
+
|
|
8
|
+
export function invariantIntlContext(intl?: any): asserts intl {
|
|
9
|
+
invariant(
|
|
10
|
+
intl,
|
|
11
|
+
'[React Intl] Could not find required `intl` object. ' +
|
|
12
|
+
'<IntlProvider> needs to exist in the component ancestry.'
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_INTL_CONFIG: Pick<
|
|
17
|
+
ResolvedIntlConfig,
|
|
18
|
+
| 'fallbackOnEmptyString'
|
|
19
|
+
| 'formats'
|
|
20
|
+
| 'messages'
|
|
21
|
+
| 'timeZone'
|
|
22
|
+
| 'textComponent'
|
|
23
|
+
| 'defaultLocale'
|
|
24
|
+
| 'defaultFormats'
|
|
25
|
+
| 'onError'
|
|
26
|
+
> = {
|
|
27
|
+
...CORE_DEFAULT_INTL_CONFIG,
|
|
28
|
+
textComponent: React.Fragment,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Takes a `formatXMLElementFn`, and composes it in function, which passes
|
|
33
|
+
* argument `parts` through, assigning unique key to each part, to prevent
|
|
34
|
+
* "Each child in a list should have a unique "key"" React error.
|
|
35
|
+
* @param formatXMLElementFn
|
|
36
|
+
*/
|
|
37
|
+
export function assignUniqueKeysToParts(
|
|
38
|
+
formatXMLElementFn: FormatXMLElementFn<React.ReactNode>
|
|
39
|
+
): FormatXMLElementFn<React.ReactNode> {
|
|
40
|
+
return function (parts: any) {
|
|
41
|
+
// eslint-disable-next-line prefer-rest-params
|
|
42
|
+
return formatXMLElementFn(React.Children.toArray(parts)) as any
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function shallowEqual<
|
|
47
|
+
T extends Record<string, unknown> = Record<string, unknown>
|
|
48
|
+
>(objA?: T, objB?: T) {
|
|
49
|
+
if (objA === objB) {
|
|
50
|
+
return true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!objA || !objB) {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var aKeys = Object.keys(objA)
|
|
58
|
+
var bKeys = Object.keys(objB)
|
|
59
|
+
var len = aKeys.length
|
|
60
|
+
|
|
61
|
+
if (bKeys.length !== len) {
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (var i = 0; i < len; i++) {
|
|
66
|
+
var key = aKeys[i]
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
objA[key] !== objB[key] ||
|
|
70
|
+
!Object.prototype.hasOwnProperty.call(objB, key)
|
|
71
|
+
) {
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return true
|
|
77
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as p from 'path'
|
|
2
|
+
import buildTests from './support/build'
|
|
3
|
+
import formatTests from './support/format'
|
|
4
|
+
|
|
5
|
+
import {main} from '../../package.json'
|
|
6
|
+
const Main = p.resolve(__dirname, '../../', main)
|
|
7
|
+
const builds = {
|
|
8
|
+
Main,
|
|
9
|
+
// 'IIFE-dev': p.join(p.dirname(Main), 'react-intl.iife.js'),
|
|
10
|
+
// 'IIFE-no-parser-dev': p.join(p.dirname(Main), 'react-intl-no-parser.iife.js'),
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
Object.keys(builds).forEach(name => {
|
|
14
|
+
describe(name, () => {
|
|
15
|
+
buildTests(builds[name])
|
|
16
|
+
formatTests(require(builds[name]), name.includes('no-parser'))
|
|
17
|
+
})
|
|
18
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as ReactIntl from '../../../'
|
|
2
|
+
|
|
3
|
+
export default function (buildPath) {
|
|
4
|
+
describe('build', () => {
|
|
5
|
+
it('evaluates', () => {
|
|
6
|
+
expect(require(buildPath)).toBeDefined()
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
Object.keys(ReactIntl).forEach(name =>
|
|
10
|
+
it(name, function () {
|
|
11
|
+
const ReactIntlBuild = require(buildPath)
|
|
12
|
+
expect(typeof ReactIntlBuild[name]).toBe(typeof ReactIntl[name])
|
|
13
|
+
})
|
|
14
|
+
)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import * as IReactIntl from '../../../'
|
|
4
|
+
import {parse} from '@formatjs/icu-messageformat-parser'
|
|
5
|
+
import {render, screen} from '@testing-library/react'
|
|
6
|
+
|
|
7
|
+
export default function (ReactIntl: typeof IReactIntl, noParser?: boolean) {
|
|
8
|
+
describe('format', () => {
|
|
9
|
+
const {
|
|
10
|
+
IntlProvider,
|
|
11
|
+
FormattedDate,
|
|
12
|
+
FormattedTime,
|
|
13
|
+
FormattedRelativeTime,
|
|
14
|
+
FormattedNumber,
|
|
15
|
+
FormattedMessage,
|
|
16
|
+
} = ReactIntl
|
|
17
|
+
|
|
18
|
+
const renderWithIntlProvider = (Element: JSX.Element, providerProps = {}) =>
|
|
19
|
+
render(
|
|
20
|
+
<IntlProvider locale="en" {...providerProps}>
|
|
21
|
+
{Element}
|
|
22
|
+
</IntlProvider>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
it('formats dates', () => {
|
|
26
|
+
const date = new Date()
|
|
27
|
+
const el = (
|
|
28
|
+
<span data-testid="test">
|
|
29
|
+
<FormattedDate value={date} month="numeric" />
|
|
30
|
+
</span>
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
renderWithIntlProvider(el)
|
|
34
|
+
expect(screen.getByTestId('test')).toHaveTextContent(
|
|
35
|
+
String(date.getMonth() + 1)
|
|
36
|
+
)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('formats times', () => {
|
|
40
|
+
const date = new Date()
|
|
41
|
+
const el = (
|
|
42
|
+
<span data-testid="test">
|
|
43
|
+
<FormattedTime value={date} />
|
|
44
|
+
</span>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
const hours = date.getHours()
|
|
48
|
+
const minutes = date.getMinutes()
|
|
49
|
+
|
|
50
|
+
renderWithIntlProvider(el)
|
|
51
|
+
expect(screen.getByTestId('test')).toHaveTextContent(
|
|
52
|
+
`${hours > 12 ? hours % 12 : hours || '12'}:` +
|
|
53
|
+
`${minutes < 10 ? `0${minutes}` : minutes} ` +
|
|
54
|
+
`${hours < 12 ? 'AM' : 'PM'}`
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('formats relative time', () => {
|
|
59
|
+
const el = (
|
|
60
|
+
<span data-testid="test">
|
|
61
|
+
<FormattedRelativeTime value={-1} />
|
|
62
|
+
</span>
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
renderWithIntlProvider(el)
|
|
66
|
+
expect(screen.getByTestId('test')).toHaveTextContent('1 second ago')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('formats numbers with thousands separators', () => {
|
|
70
|
+
const el = (
|
|
71
|
+
<span data-testid="test">
|
|
72
|
+
<FormattedNumber value={1000} />
|
|
73
|
+
</span>
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
renderWithIntlProvider(el)
|
|
77
|
+
expect(screen.getByTestId('test')).toHaveTextContent('1,000')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('formats numbers with decimal separators', () => {
|
|
81
|
+
const el = (
|
|
82
|
+
<span data-testid="test">
|
|
83
|
+
<FormattedNumber value={0.1} minimumFractionDigits={2} />
|
|
84
|
+
</span>
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
renderWithIntlProvider(el)
|
|
88
|
+
expect(screen.getByTestId('test')).toHaveTextContent('0.10')
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('pluralizes labels in strings', () => {
|
|
92
|
+
const message =
|
|
93
|
+
'You have {emails, plural, one {# email} other {# emails}}.'
|
|
94
|
+
const el = (
|
|
95
|
+
<span data-testid="test">
|
|
96
|
+
<FormattedMessage
|
|
97
|
+
id="foo"
|
|
98
|
+
defaultMessage={noParser ? parse(message) : message}
|
|
99
|
+
values={{
|
|
100
|
+
emails: 1000,
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
</span>
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
renderWithIntlProvider(el)
|
|
107
|
+
expect(screen.getByTestId('test')).toHaveTextContent(
|
|
108
|
+
'You have 1,000 emails.'
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {Suite} from 'benchmark'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import * as ReactDOMServer from 'react-dom/server'
|
|
4
|
+
const {
|
|
5
|
+
IntlProvider,
|
|
6
|
+
FormattedNumber,
|
|
7
|
+
FormattedDate,
|
|
8
|
+
FormattedMessage,
|
|
9
|
+
// FormattedRelativeTime,
|
|
10
|
+
} = require('../../dist/react-intl')
|
|
11
|
+
import {parse, MessageFormatElement} from '@formatjs/icu-messageformat-parser'
|
|
12
|
+
|
|
13
|
+
const suite = new Suite('renderToString', {
|
|
14
|
+
onCycle: function (e: any) {
|
|
15
|
+
console.log(String(e.target))
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
suite.on('error', function (e: any) {
|
|
20
|
+
console.log(e)
|
|
21
|
+
throw e.target.error
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
suite.add('<div>', function () {
|
|
25
|
+
ReactDOMServer.renderToString(<div />)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
suite.add('100 x <div/>', function () {
|
|
29
|
+
const divs = []
|
|
30
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
31
|
+
divs.push(<div key={i} />)
|
|
32
|
+
}
|
|
33
|
+
ReactDOMServer.renderToString(<IntlProvider locale="en">{divs}</IntlProvider>)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
suite.add('100 x <FormattedNumber>', function () {
|
|
37
|
+
let formattedNumbers = []
|
|
38
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
39
|
+
formattedNumbers.push(<FormattedNumber value={i} key={i} />)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
ReactDOMServer.renderToString(
|
|
43
|
+
<IntlProvider locale="en">{formattedNumbers}</IntlProvider>
|
|
44
|
+
)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
suite.add('100 x <FormattedDate>', function () {
|
|
48
|
+
let now = Date.now()
|
|
49
|
+
let formattedDates = []
|
|
50
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
51
|
+
formattedDates.push(<FormattedDate value={now - 1000 * 60 * i} key={i} />)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ReactDOMServer.renderToString(
|
|
55
|
+
<IntlProvider locale="en">{formattedDates}</IntlProvider>
|
|
56
|
+
)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
suite.add('100 x <FormattedMessage>', function () {
|
|
60
|
+
let messages: Record<number, string> = {}
|
|
61
|
+
let formattedMessages = []
|
|
62
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
63
|
+
messages[i] = `message ${i}`
|
|
64
|
+
formattedMessages.push(<FormattedMessage id={`${i}`} key={i} />)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ReactDOMServer.renderToString(
|
|
68
|
+
<IntlProvider locale="en" messages={messages}>
|
|
69
|
+
{formattedMessages}
|
|
70
|
+
</IntlProvider>
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
suite.add('100 x <FormattedMessage> with placeholder', function () {
|
|
75
|
+
let messages: Record<number, string> = {}
|
|
76
|
+
let formattedMessages = []
|
|
77
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
78
|
+
const varName = `var${i}`
|
|
79
|
+
messages[i] = `{${varName}, plural,
|
|
80
|
+
zero {{${varName}, number} message}
|
|
81
|
+
one {{${varName}, number} message}
|
|
82
|
+
few {{${varName}, number} message}
|
|
83
|
+
many {{${varName}, number} message}
|
|
84
|
+
other {{${varName}, number} messages}
|
|
85
|
+
}`
|
|
86
|
+
formattedMessages.push(
|
|
87
|
+
<FormattedMessage id={`${i}`} values={{[varName]: i}} key={i} />
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
ReactDOMServer.renderToString(
|
|
92
|
+
<IntlProvider locale="en" messages={messages}>
|
|
93
|
+
{formattedMessages}
|
|
94
|
+
</IntlProvider>
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
let messageAsts: Record<number, MessageFormatElement[]> = {}
|
|
99
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
100
|
+
const varName = `var${i}`
|
|
101
|
+
messageAsts[i] = parse(
|
|
102
|
+
`{${varName}, plural,
|
|
103
|
+
zero {{${varName}, number} message}
|
|
104
|
+
one {{${varName}, number} message}
|
|
105
|
+
few {{${varName}, number} message}
|
|
106
|
+
many {{${varName}, number} message}
|
|
107
|
+
other {{${varName}, number} messages}
|
|
108
|
+
}`
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
suite.add('100 x <FormattedMessage> with placeholder in AST form', function () {
|
|
113
|
+
let formattedMessages = []
|
|
114
|
+
|
|
115
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
116
|
+
const varName = `var${i}`
|
|
117
|
+
formattedMessages.push(
|
|
118
|
+
<FormattedMessage id={`${i}`} values={{[varName]: i}} key={i} />
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
ReactDOMServer.renderToString(
|
|
123
|
+
<IntlProvider locale="en" messages={messageAsts}>
|
|
124
|
+
{formattedMessages}
|
|
125
|
+
</IntlProvider>
|
|
126
|
+
)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
suite.add('100 x <FormattedMessage> with placeholder, cached', function () {
|
|
130
|
+
let messages: Record<number, string> = {}
|
|
131
|
+
let formattedMessages = []
|
|
132
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
133
|
+
messages[i] = `{var0, plural,
|
|
134
|
+
zero {{var0, number} message}
|
|
135
|
+
one {{var0, number} message}
|
|
136
|
+
few {{var0, number} message}
|
|
137
|
+
many {{var0, number} message}
|
|
138
|
+
other {{var0, number} messages}
|
|
139
|
+
}`
|
|
140
|
+
formattedMessages.push(
|
|
141
|
+
<FormattedMessage id={`${i}`} values={{var0: i}} key={i} />
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
ReactDOMServer.renderToString(
|
|
146
|
+
<IntlProvider locale="en" messages={messages}>
|
|
147
|
+
{formattedMessages}
|
|
148
|
+
</IntlProvider>
|
|
149
|
+
)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const cachedAst = parse(
|
|
153
|
+
`{var0, plural,
|
|
154
|
+
zero {{var0, number} message}
|
|
155
|
+
one {{var0, number} message}
|
|
156
|
+
few {{var0, number} message}
|
|
157
|
+
many {{var0, number} message}
|
|
158
|
+
other {{var0, number} messages}
|
|
159
|
+
}`
|
|
160
|
+
)
|
|
161
|
+
suite.add(
|
|
162
|
+
'100 x <FormattedMessage> with placeholder, cached in AST form',
|
|
163
|
+
function () {
|
|
164
|
+
let messages: Record<number, MessageFormatElement[]> = {}
|
|
165
|
+
let formattedMessages = []
|
|
166
|
+
for (let i = 0, len = 100; i < len; i += 1) {
|
|
167
|
+
messages[i] = cachedAst
|
|
168
|
+
formattedMessages.push(
|
|
169
|
+
<FormattedMessage id={`${i}`} values={{var0: i}} key={i} />
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
ReactDOMServer.renderToString(
|
|
174
|
+
<IntlProvider locale="en" messages={messages}>
|
|
175
|
+
{formattedMessages}
|
|
176
|
+
</IntlProvider>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// suite.add('100 x <FormattedRelative>', function() {
|
|
182
|
+
// let formattedRelativeTimes = [];
|
|
183
|
+
// for (let i = 0, len = 100; i < len; i += 1) {
|
|
184
|
+
// formattedRelativeTimes.push(
|
|
185
|
+
// <FormattedRelativeTime value={-60 * i} key={i} />
|
|
186
|
+
// );
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// ReactDOMServer.renderToString(
|
|
190
|
+
// <IntlProvider locale="en">
|
|
191
|
+
// <div>{formattedRelativeTimes}</div>
|
|
192
|
+
// </IntlProvider>
|
|
193
|
+
// );
|
|
194
|
+
// });
|
|
195
|
+
|
|
196
|
+
suite.run()
|
package/tests/setup.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
if (process.version.startsWith('v12')) {
|
|
2
|
+
delete Intl.NumberFormat
|
|
3
|
+
}
|
|
4
|
+
require('@formatjs/intl-displaynames/polyfill')
|
|
5
|
+
require('@formatjs/intl-displaynames/locale-data/en')
|
|
6
|
+
require('@formatjs/intl-numberformat/polyfill')
|
|
7
|
+
require('@formatjs/intl-numberformat/locale-data/en')
|
|
8
|
+
require('@formatjs/intl-numberformat/locale-data/es')
|
|
9
|
+
// add custom jest matchers from jest-dom
|
|
10
|
+
require('@testing-library/jest-dom/extend-expect')
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<FormattedDisplayName /> accepts Intl.DisplayNames options 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<span
|
|
6
|
+
data-testid="comp"
|
|
7
|
+
>
|
|
8
|
+
Chinese Yuan
|
|
9
|
+
</span>
|
|
10
|
+
</div>
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
exports[`<FormattedDisplayName /> renders an empty <> when the underlying DisplayNames would return undefined 1`] = `
|
|
14
|
+
<div>
|
|
15
|
+
<span
|
|
16
|
+
data-testid="comp"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<FormattedMessage> accepts string as \`tagName\` prop 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<span
|
|
6
|
+
data-testid="comp"
|
|
7
|
+
>
|
|
8
|
+
<p>
|
|
9
|
+
Hello, World!
|
|
10
|
+
</p>
|
|
11
|
+
</span>
|
|
12
|
+
</div>
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
exports[`<FormattedMessage> rich text supports rich-text message formatting w/ nested tag 1`] = `
|
|
16
|
+
<span
|
|
17
|
+
data-testid="comp"
|
|
18
|
+
>
|
|
19
|
+
Hello,
|
|
20
|
+
<b>
|
|
21
|
+
Jest
|
|
22
|
+
<i>
|
|
23
|
+
!
|
|
24
|
+
</i>
|
|
25
|
+
</b>
|
|
26
|
+
</span>
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
exports[`<FormattedMessage> rich text supports rich-text message formatting w/ nested tag, chunks merged 1`] = `
|
|
30
|
+
<span
|
|
31
|
+
data-testid="comp"
|
|
32
|
+
>
|
|
33
|
+
Hello,
|
|
34
|
+
<b>
|
|
35
|
+
Jest
|
|
36
|
+
<i>
|
|
37
|
+
!
|
|
38
|
+
</i>
|
|
39
|
+
</b>
|
|
40
|
+
</span>
|
|
41
|
+
`;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`useIntl() hook should work when switching locale on provider 1`] = `
|
|
4
|
+
<span
|
|
5
|
+
data-testid="comp"
|
|
6
|
+
>
|
|
7
|
+
$10,000.00
|
|
8
|
+
</span>
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
exports[`useIntl() hook should work when switching locale on provider 2`] = `
|
|
12
|
+
<span
|
|
13
|
+
data-testid="comp"
|
|
14
|
+
>
|
|
15
|
+
10.000,00 US$
|
|
16
|
+
</span>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
exports[`useIntl() hook should work when switching locale on provider 3`] = `
|
|
20
|
+
<span
|
|
21
|
+
data-testid="comp"
|
|
22
|
+
>
|
|
23
|
+
$10,000.00
|
|
24
|
+
</span>
|
|
25
|
+
`;
|