Skip to content

Commit

Permalink
feat(react-intl): support react 17 (#2301)
Browse files Browse the repository at this point in the history
fix #2298
  • Loading branch information
longlho committed Nov 10, 2020
1 parent eebacc6 commit 782eabe
Show file tree
Hide file tree
Showing 23 changed files with 1,073 additions and 1,311 deletions.
9 changes: 4 additions & 5 deletions package.json
Expand Up @@ -38,6 +38,8 @@
"@rollup/plugin-json": "^4.0.3",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-replace": "^2.3.3",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^11.1.1",
"@types/babel__core": "^7.1.7",
"@types/emoji-regex": "^8.0.0",
"@types/enzyme": "^3.10.5",
Expand Down Expand Up @@ -65,9 +67,6 @@
"cldr-units-full": "^37.0.0",
"commander": "^6.0.0",
"core-js": "^3.6.5",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.5.0",
"eslint": "^7.4.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
Expand Down Expand Up @@ -95,8 +94,8 @@
"pegjs": "^0.10.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.0.5",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react": "^16.3.0 || 17",
"react-dom": "^16.3.0 || 17",
"rimraf": "^3.0.2",
"rollup": "^2.7.2",
"schema-utils": "^3.0.0",
Expand Down
11 changes: 7 additions & 4 deletions packages/react-intl/BUILD
Expand Up @@ -55,10 +55,13 @@ TESTS = glob([

TEST_DEPS = SRC_DEPS + [
"//packages/intl-numberformat:dist",
"@npm//enzyme-to-json",
"@npm//enzyme",
"@npm//@types/enzyme",
"@npm//enzyme-adapter-react-16",
"//packages/intl-listformat:types",
"//packages/intl-displaynames:types",
"//packages/ecma402-abstract:types",
"//packages/intl:types",
"//packages/intl-messageformat:types",
"@npm//@testing-library/react",
"@npm//@testing-library/jest-dom",
"@npm//react-dom",
]

Expand Down
3 changes: 1 addition & 2 deletions packages/react-intl/jest.config.js
Expand Up @@ -2,7 +2,7 @@ module.exports = {
preset: 'ts-jest',
globals: {
'ts-jest': {
tsConfig: 'tsconfig.json',
tsconfig: 'tsconfig.json',
diagnostics: false,
},
},
Expand All @@ -23,5 +23,4 @@ module.exports = {
statements: 95,
},
},
snapshotSerializers: ['enzyme-to-json/serializer'],
};
2 changes: 1 addition & 1 deletion packages/react-intl/package.json
Expand Up @@ -142,7 +142,7 @@
"tslib": "^2.0.1"
},
"peerDependencies": {
"react": "^16.3.0",
"react": "^16.3.0 || 17",
"typescript": "4"
},
"peerDependenciesMeta": {
Expand Down
82 changes: 54 additions & 28 deletions packages/react-intl/tests/functional/support/format.tsx
@@ -1,8 +1,10 @@
import * as React from 'react';
import {mount} from 'enzyme';

import * as IReactIntl from '../../../';
import {parse} from 'intl-messageformat-parser';
import {render, screen} from '@testing-library/react';

export default function (ReactIntl, noParser?: boolean) {
export default function (ReactIntl: typeof IReactIntl, noParser?: boolean) {
describe('format', () => {
const {
IntlProvider,
Expand All @@ -13,74 +15,98 @@ export default function (ReactIntl, noParser?: boolean) {
FormattedMessage,
} = ReactIntl;

const renderWithIntlProvider = (Element, providerProps = {}) =>
mount(
const renderWithIntlProvider = (Element: JSX.Element, providerProps = {}) =>
render(
<IntlProvider locale="en" {...providerProps}>
{Element}
</IntlProvider>
);

it('formats dates', () => {
const date = new Date();
const el = <FormattedDate id="test" value={date} month="numeric" />;
const el = (
<span data-testid="test">
<FormattedDate value={date} month="numeric" />
</span>
);

const rendered = renderWithIntlProvider(el);
expect(rendered.text()).toBe(String(date.getMonth() + 1));
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent(
String(date.getMonth() + 1)
);
});

it('formats times', () => {
const date = new Date();
const el = <FormattedTime id="test" value={date} />;
const el = (
<span data-testid="test">
<FormattedTime value={date} />
</span>
);

const hours = date.getHours();
const minutes = date.getMinutes();

const rendered = renderWithIntlProvider(el);
expect(rendered.text()).toBe(
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent(
`${hours > 12 ? hours % 12 : hours || '12'}:` +
`${minutes < 10 ? `0${minutes}` : minutes} ` +
`${hours < 12 ? 'AM' : 'PM'}`
);
});

it('formats relative time', () => {
const el = <FormattedRelativeTime id="test" value={-1} />;
const el = (
<span data-testid="test">
<FormattedRelativeTime value={-1} />
</span>
);

const rendered = renderWithIntlProvider(el);
expect(rendered.text()).toBe('1 second ago');
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent('1 second ago');
});

it('formats numbers with thousands separators', () => {
const el = <FormattedNumber id="test" value={1000} />;
const el = (
<span data-testid="test">
<FormattedNumber value={1000} />
</span>
);

const rendered = renderWithIntlProvider(el);
expect(rendered.text()).toBe('1,000');
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent('1,000');
});

it('formats numbers with decimal separators', () => {
const el = (
<FormattedNumber id="test" value={0.1} minimumFractionDigits={2} />
<span data-testid="test">
<FormattedNumber value={0.1} minimumFractionDigits={2} />
</span>
);

const rendered = renderWithIntlProvider(el);
expect(rendered.text()).toBe('0.10');
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent('0.10');
});

it('pluralizes labels in strings', () => {
const message =
'You have {emails, plural, one {# email} other {# emails}}.';
const el = (
<FormattedMessage
id="test"
defaultMessage={noParser ? parse(message) : message}
values={{
emails: 1000,
}}
/>
<span data-testid="test">
<FormattedMessage
id="foo"
defaultMessage={noParser ? parse(message) : message}
values={{
emails: 1000,
}}
/>
</span>
);

const rendered = renderWithIntlProvider(el, {onError: console.error});
expect(rendered.text()).toBe('You have 1,000 emails.');
renderWithIntlProvider(el);
expect(screen.getByTestId('test')).toHaveTextContent(
'You have 1,000 emails.'
);
});
});
}
6 changes: 2 additions & 4 deletions packages/react-intl/tests/setup.js
@@ -1,4 +1,3 @@
const {configure} = require('enzyme');
if (process.version.startsWith('v12')) {
// delete Intl.PluralRules;
// delete Intl.RelativeTimeFormat;
Expand All @@ -11,6 +10,5 @@ require('@formatjs/intl-displaynames/polyfill-locales');
require('@formatjs/intl-numberformat/polyfill');
require('@formatjs/intl-numberformat/locale-data/en');
require('@formatjs/intl-numberformat/locale-data/es');
const Adapter = require('enzyme-adapter-react-16');

configure({adapter: new Adapter()});
// add custom jest matchers from jest-dom
require('@testing-library/jest-dom/extend-expect');
@@ -1,18 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<FormattedDisplayName /> accepts Intl.DisplayNames options 1`] = `
<FormattedDisplayName
type="currency"
value="CNY"
>
Chinese Yuan
</FormattedDisplayName>
<div>
<span
data-testid="comp"
>
Chinese Yuan
</span>
</div>
`;

exports[`<FormattedDisplayName /> renders an empty <> when the underlying DisplayNames would return undefined 1`] = `
<FormattedDisplayName
fallback="none"
type="language"
value="xx-XX"
/>
<div>
<span
data-testid="comp"
/>
</div>
`;
@@ -1,75 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<FormattedMessage> accepts string as \`tagName\` prop 1`] = `
<div>
<span
data-testid="comp"
>
<p>
Hello, World!
</p>
</span>
</div>
`;
exports[`<FormattedMessage> rich text supports rich-text message formatting w/ nested tag 1`] = `
<FormattedMessage
defaultMessage="Hello, <b>{name}<i>!</i></b>"
id="hello"
values={
Object {
"b": [Function],
"i": [Function],
"name": "Jest",
}
}
<span
data-testid="comp"
>
Hello,
<b
key=".1"
>
<b>
Jest
<i
key=".1"
>
<i>
!
</i>
</b>
</FormattedMessage>
</span>
`;
exports[`<FormattedMessage> rich text supports rich-text message formatting w/ nested tag, chunks merged 1`] = `
<FormattedMessage
defaultMessage="Hello, <b>{name}<i>!</i></b>"
id="hello"
values={
Object {
"b": [Function],
"i": [Function],
"name": "Jest",
}
}
<span
data-testid="comp"
>
Hello,
<b
key=".1"
>
<b>
Jest
<i
key=".1"
>
<i>
!
</i>
</b>
</FormattedMessage>
`;
exports[`<FormattedMessage> should work with mount enzyme 1`] = `
<span>
<FormattedMessage
id="foo"
>
hello foo
</FormattedMessage>
</span>
`;
exports[`<FormattedMessage> should work with shallow enzyme 1`] = `
<ContextConsumer>
<Component />
</ContextConsumer>
`;
exports[`<FormattedMessage> should work with shallow enzyme 2`] = `
<Fragment>
hello foo
</Fragment>
`;
@@ -1,14 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<FormattedRelativeTime> supports function-as-child pattern 1`] = `
<FormattedRelativeTime
unit="second"
value={0}
<span
data-testid="comp"
>
<b>
Jest
</b>
</FormattedRelativeTime>
</span>
`;
exports[`<FormattedRelativeTime> throws an error for invalid unit 1`] = `"FORMAT_ERROR"`;

0 comments on commit 782eabe

Please sign in to comment.