Skip to content

Commit 660a546

Browse files
committed
fix: remove contextType usage
Since enzyme `shallow` doesn't support `contextType` yet, this creates issues in upstream consumer tests. Using Provider/Consumer seems to work though
1 parent 4c87136 commit 660a546

File tree

13 files changed

+259
-67
lines changed

13 files changed

+259
-67
lines changed

jest.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
module.exports = {
22
preset: 'ts-jest/presets/js-with-babel',
33
testRegex: ['/test/(functional|unit)/.*\\.(ts|tsx)'],
4-
testPathIgnorePatterns: ['test/functional/support', '/test/unit/testUtils'],
4+
testPathIgnorePatterns: [
5+
'test/functional/support',
6+
'/test/unit/testUtils',
7+
'__snapshots__',
8+
],
59
collectCoverageFrom: ['src/**/*.{ts,tsx}'],
610
coverageReporters: ['lcov', 'text', 'text-summary', 'html'],
711
transformIgnorePatterns: [
@@ -27,4 +31,5 @@ module.exports = {
2731
diagnostics: false,
2832
},
2933
},
34+
snapshotSerializers: ['enzyme-to-json/serializer'],
3035
};

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"cross-env": "^5.2.0",
6767
"enzyme": "^3.6.0",
6868
"enzyme-adapter-react-16": "^1.5.0",
69+
"enzyme-to-json": "^3.4.0",
6970
"eslint": "^6.1.0",
7071
"eslint-plugin-react": "^7.14.3",
7172
"fs-extra": "^8.1.0",

src/components/createFormattedComponent.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import {IntlShape, FormatDateOptions, FormatNumberOptions} from '../types';
3-
import withIntl from './injectIntl';
3+
import withIntl, {WrappedComponentProps} from './injectIntl';
44

55
export default function createFormattedComponent<
66
T extends 'formatDate' | 'formatTime' | 'formatNumber'
@@ -11,11 +11,11 @@ export default function createFormattedComponent<
1111
? FormatDateOptions
1212
: FormatNumberOptions;
1313
type FormatFn = IntlShape[T];
14-
type Props = FormatOptions<T> & {
15-
value: Parameters<FormatFn>[0];
16-
intl: IntlShape;
17-
children?(val: string): React.ReactElement | null;
18-
};
14+
type Props = FormatOptions<T> &
15+
WrappedComponentProps & {
16+
value: Parameters<FormatFn>[0];
17+
children?(val: string): React.ReactElement | null;
18+
};
1919
const Component: React.FC<Props> = props => {
2020
const {
2121
value,

src/components/html-message.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@
55
*/
66

77
import * as React from 'react';
8-
import FormattedMessage from './message';
8+
99
import {PrimitiveType} from 'intl-messageformat';
10+
import {BaseFormattedMessage} from './message';
11+
import injectIntl from './injectIntl';
1012

11-
export default class FormattedHTMLMessage extends FormattedMessage<
13+
export class BaseFormattedHTMLMessage extends BaseFormattedMessage<
1214
Record<string, PrimitiveType>
1315
> {
1416
static defaultProps = {
15-
...FormattedMessage.defaultProps,
17+
...BaseFormattedMessage.defaultProps,
1618
tagName: 'span' as 'span',
1719
};
1820
render() {
19-
const {formatHTMLMessage, textComponent: Text} = this.context;
21+
const {formatHTMLMessage, textComponent: Text} = this.props.intl;
2022

2123
const {
2224
id,
@@ -47,3 +49,5 @@ export default class FormattedHTMLMessage extends FormattedMessage<
4749
return <Component dangerouslySetInnerHTML={html} />;
4850
}
4951
}
52+
53+
export default injectIntl(BaseFormattedHTMLMessage, {enforceContext: false});

src/components/message.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import * as React from 'react';
8-
import {Context} from './injectIntl';
8+
import injectIntl, {WrappedComponentProps} from './injectIntl';
99
import {MessageDescriptor} from '../types';
1010
const shallowEquals = require('shallow-equal/objects');
1111

@@ -43,13 +43,13 @@ const defaultFormatMessage = (
4343

4444
export interface Props<
4545
V extends Record<string, any> = Record<string, React.ReactNode>
46-
> extends MessageDescriptor {
46+
> extends MessageDescriptor, WrappedComponentProps {
4747
values?: V;
4848
tagName?: React.ElementType<any>;
4949
children?(...nodes: React.ReactNodeArray): React.ReactNode;
5050
}
5151

52-
export default class FormattedMessage<
52+
export class BaseFormattedMessage<
5353
V extends Record<string, any> = Record<
5454
string,
5555
PrimitiveType | React.ReactElement | FormatXMLElementFn
@@ -59,13 +59,11 @@ export default class FormattedMessage<
5959
values: {},
6060
};
6161
static displayName = 'FormattedMessage';
62-
static contextType = Context;
63-
context!: React.ContextType<typeof Context>;
6462

65-
constructor(props: Props<V>, context: React.ContextType<typeof Context>) {
63+
constructor(props: Props<V>) {
6664
super(props);
6765
if (!props.defaultMessage) {
68-
invariantIntlContext(context);
66+
invariantIntlContext(props.intl);
6967
}
7068
}
7169

@@ -82,7 +80,7 @@ export default class FormattedMessage<
8280
const {
8381
formatMessage = defaultFormatMessage,
8482
textComponent: Text = React.Fragment,
85-
} = this.context || {};
83+
} = this.props.intl || {};
8684
const {
8785
id,
8886
description,
@@ -114,3 +112,5 @@ export default class FormattedMessage<
114112
return nodes;
115113
}
116114
}
115+
116+
export default injectIntl(BaseFormattedMessage, {enforceContext: false});

src/components/relative.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import * as React from 'react';
8-
import {Context} from './injectIntl';
8+
import injectIntl, {WrappedComponentProps} from './injectIntl';
99
import {FormatRelativeTimeOptions} from '../types';
1010
import {Unit} from '@formatjs/intl-relativetimeformat';
1111
import * as invariant_ from 'invariant';
@@ -60,7 +60,9 @@ function valueToSeconds(value?: number, unit?: Unit): number {
6060
}
6161
}
6262

63-
export interface Props extends FormatRelativeTimeOptions {
63+
export interface Props
64+
extends FormatRelativeTimeOptions,
65+
WrappedComponentProps {
6466
value?: number;
6567
unit?: Unit;
6668
updateIntervalInSeconds?: number;
@@ -85,7 +87,7 @@ function verifyProps(updateIntervalInSeconds?: number, unit?: Unit) {
8587
);
8688
}
8789

88-
export default class FormattedRelativeTime extends React.PureComponent<
90+
export class BaseFormattedRelativeTime extends React.PureComponent<
8991
Props,
9092
State
9193
> {
@@ -96,8 +98,6 @@ export default class FormattedRelativeTime extends React.PureComponent<
9698
value: 0,
9799
unit: 'second',
98100
};
99-
static contextType = Context;
100-
context!: React.ContextType<typeof Context>;
101101
state: State = {
102102
prevUnit: this.props.unit,
103103
prevValue: this.props.value,
@@ -106,9 +106,9 @@ export default class FormattedRelativeTime extends React.PureComponent<
106106
: 0,
107107
};
108108

109-
constructor(props: Props, context: React.ContextType<typeof Context>) {
109+
constructor(props: Props) {
110110
super(props);
111-
invariantIntlContext(context);
111+
invariantIntlContext(props.intl);
112112
verifyProps(props.updateIntervalInSeconds, props.unit);
113113
}
114114

@@ -177,7 +177,7 @@ export default class FormattedRelativeTime extends React.PureComponent<
177177
}
178178

179179
render() {
180-
const {formatRelativeTime, textComponent: Text} = this.context;
180+
const {formatRelativeTime, textComponent: Text} = this.props.intl;
181181
const {children, value, unit, updateIntervalInSeconds} = this.props;
182182
const {currentValueInSeconds} = this.state;
183183
let currentValue = value || 0;
@@ -210,3 +210,5 @@ export default class FormattedRelativeTime extends React.PureComponent<
210210
return formattedRelativeTime;
211211
}
212212
}
213+
214+
export default injectIntl(BaseFormattedRelativeTime);

test/setup.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import {configure} from 'enzyme';
2-
import * as React from 'react';
32
import 'intl-pluralrules';
43
import '@formatjs/intl-relativetimeformat/polyfill-locales';
5-
6-
let reactMajorVersion = Number.parseInt(React.version.slice(0, 2));
7-
if (reactMajorVersion === 0) {
8-
reactMajorVersion = React.version.slice(2, 4);
9-
}
10-
const Adapter = require(`enzyme-adapter-react-${reactMajorVersion}`);
4+
import * as Adapter from 'enzyme-adapter-react-16';
115

126
configure({adapter: new Adapter()});
137

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`<FormattedMessage> should work with mount enzyme 1`] = `
4+
<span>
5+
<injectIntl(FormattedMessage)
6+
id="foo"
7+
>
8+
<FormattedMessage
9+
id="foo"
10+
intl={
11+
Object {
12+
"defaultFormats": Object {},
13+
"defaultLocale": "en",
14+
"formatDate": [Function],
15+
"formatHTMLMessage": [Function],
16+
"formatMessage": [Function],
17+
"formatNumber": [Function],
18+
"formatPlural": [Function],
19+
"formatRelativeTime": [Function],
20+
"formatTime": [Function],
21+
"formats": Object {},
22+
"formatters": Object {
23+
"getDateTimeFormat": [Function],
24+
"getMessageFormat": [Function],
25+
"getNumberFormat": [Function],
26+
"getPluralRules": [Function],
27+
"getRelativeTimeFormat": [Function],
28+
},
29+
"locale": "en",
30+
"messages": Object {
31+
"foo": "hello foo",
32+
},
33+
"onError": [Function],
34+
"textComponent": Symbol(react.fragment),
35+
"timeZone": undefined,
36+
}
37+
}
38+
values={Object {}}
39+
>
40+
hello foo
41+
</FormattedMessage>
42+
</injectIntl(FormattedMessage)>
43+
</span>
44+
`;
45+
46+
exports[`<FormattedMessage> should work with shallow enzyme 1`] = `
47+
<ContextConsumer>
48+
<Component />
49+
</ContextConsumer>
50+
`;
51+
52+
exports[`<FormattedMessage> should work with shallow enzyme 2`] = `
53+
<FormattedMessage
54+
id="foo"
55+
intl={
56+
Object {
57+
"defaultFormats": Object {},
58+
"defaultLocale": "en",
59+
"formatDate": [Function],
60+
"formatHTMLMessage": [Function],
61+
"formatMessage": [Function],
62+
"formatNumber": [Function],
63+
"formatPlural": [Function],
64+
"formatRelativeTime": [Function],
65+
"formatTime": [Function],
66+
"formats": Object {},
67+
"formatters": Object {
68+
"getDateTimeFormat": [Function],
69+
"getMessageFormat": [Function],
70+
"getNumberFormat": [Function],
71+
"getPluralRules": [Function],
72+
"getRelativeTimeFormat": [Function],
73+
},
74+
"locale": "en",
75+
"messages": Object {
76+
"foo": "hello foo",
77+
},
78+
"onError": [Function],
79+
"textComponent": Symbol(react.fragment),
80+
"timeZone": undefined,
81+
}
82+
}
83+
values={Object {}}
84+
/>
85+
`;
86+
87+
exports[`<FormattedMessage> should work with shallow enzyme 3`] = `
88+
<Fragment>
89+
hello foo
90+
</Fragment>
91+
`;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`<FormattedRelativeTime> supports function-as-child pattern 1`] = `
4+
<injectIntl(FormattedRelativeTime)
5+
value={0}
6+
>
7+
<FormattedRelativeTime
8+
intl={
9+
Object {
10+
"defaultFormats": Object {},
11+
"defaultLocale": "en",
12+
"formatDate": [Function],
13+
"formatHTMLMessage": [Function],
14+
"formatMessage": [Function],
15+
"formatNumber": [Function],
16+
"formatPlural": [Function],
17+
"formatRelativeTime": [Function],
18+
"formatTime": [Function],
19+
"formats": Object {},
20+
"formatters": Object {
21+
"getDateTimeFormat": [Function],
22+
"getMessageFormat": [Function],
23+
"getNumberFormat": [Function],
24+
"getPluralRules": [Function],
25+
"getRelativeTimeFormat": [Function],
26+
},
27+
"locale": "en",
28+
"messages": Object {},
29+
"onError": [Function],
30+
"textComponent": Symbol(react.fragment),
31+
"timeZone": undefined,
32+
}
33+
}
34+
unit="second"
35+
value={0}
36+
>
37+
<b>
38+
Jest
39+
</b>
40+
</FormattedRelativeTime>
41+
</injectIntl(FormattedRelativeTime)>
42+
`;

0 commit comments

Comments
 (0)